routino-3.0/ 40755 233 144 0 12575040001 6201 5routino-3.0/src/ 40755 233 144 0 12575036710 7004 5routino-3.0/src/nodesx.h 644 233 144 12730 12550012612 10500 0/*************************************** A header file for the extended nodes. Part of the Routino routing software. ******************/ /****************** This file Copyright 2008-2015 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #ifndef NODESX_H #define NODESX_H /*+ To stop multiple inclusions. +*/ #include #include "types.h" #include "nodes.h" #include "typesx.h" #include "cache.h" #include "files.h" /* Data structures */ /*+ An extended structure used for processing. +*/ struct _NodeX { node_t id; /*+ The node identifier; initially the OSM value, later the Node index, finally the first segment. +*/ latlong_t latitude; /*+ The node latitude. +*/ latlong_t longitude; /*+ The node longitude. +*/ transports_t allow; /*+ The node allowed traffic. +*/ nodeflags_t flags; /*+ The node flags. +*/ }; /*+ A structure containing a set of nodes (memory format). +*/ struct _NodesX { char *filename; /*+ The name of the intermediate file (for the NodesX). +*/ char *filename_tmp; /*+ The name of the temporary file (for the NodesX). +*/ int fd; /*+ The file descriptor of the open file (for the NodesX). +*/ index_t number; /*+ The number of extended nodes still being considered. +*/ index_t knumber; /*+ The number of extended nodes kept for next time. +*/ #if !SLIM NodeX *data; /*+ The extended node data (when mapped into memory). +*/ #else NodeX cached[3]; /*+ Three cached extended nodes read from the file in slim mode. +*/ index_t incache[3]; /*+ The indexes of the cached extended nodes. +*/ NodeXCache *cache; /*+ A RAM cache of extended nodes read from the file. +*/ #endif node_t *idata; /*+ The extended node IDs (sorted by ID). +*/ index_t *pdata; /*+ The node indexes after pruning. +*/ index_t *gdata; /*+ The final node indexes (sorted geographically). +*/ BitMask *super; /*+ A bit-mask marker for super nodes (same order as sorted nodes). +*/ index_t latbins; /*+ The number of bins containing latitude. +*/ index_t lonbins; /*+ The number of bins containing longitude. +*/ ll_bin_t latzero; /*+ The bin number of the furthest south bin. +*/ ll_bin_t lonzero; /*+ The bin number of the furthest west bin. +*/ }; /* Functions in nodesx.c */ NodesX *NewNodeList(int append,int readonly); void FreeNodeList(NodesX *nodesx,int keep); void AppendNodeList(NodesX *nodesx,node_t id,double latitude,double longitude,transports_t allow,nodeflags_t flags); void FinishNodeList(NodesX *nodesx); index_t IndexNodeX(NodesX *nodesx,node_t id); void SortNodeList(NodesX *nodesx); void RemoveNonHighwayNodes(NodesX *nodesx,WaysX *waysx,int keep); void RemovePrunedNodes(NodesX *nodesx,SegmentsX *segmentsx); void SortNodeListGeographically(NodesX *nodesx); void SaveNodeList(NodesX *nodesx,const char *filename,SegmentsX *segmentsx); /* Macros and inline functions */ #if !SLIM #define LookupNodeX(nodesx,index,position) &(nodesx)->data[index] #define PutBackNodeX(nodesx,nodex) while(0) { /* nop */ } #else /* Prototypes */ static inline NodeX *LookupNodeX(NodesX *nodesx,index_t index,int position); static inline void PutBackNodeX(NodesX *nodesx,NodeX *nodex); CACHE_NEWCACHE_PROTO(NodeX) CACHE_DELETECACHE_PROTO(NodeX) CACHE_FETCHCACHE_PROTO(NodeX) CACHE_REPLACECACHE_PROTO(NodeX) CACHE_INVALIDATECACHE_PROTO(NodeX) /* Data type */ CACHE_STRUCTURE(NodeX) /* Inline functions */ CACHE_NEWCACHE(NodeX) CACHE_DELETECACHE(NodeX) CACHE_FETCHCACHE(NodeX) CACHE_REPLACECACHE(NodeX) CACHE_INVALIDATECACHE(NodeX) /*++++++++++++++++++++++++++++++++++++++ Lookup a particular extended node with the specified id from the file on disk. NodeX *LookupNodeX Returns a pointer to a cached copy of the extended node. NodesX *nodesx The set of nodes to use. index_t index The node index to look for. int position The position in the cache to use. ++++++++++++++++++++++++++++++++++++++*/ static inline NodeX *LookupNodeX(NodesX *nodesx,index_t index,int position) { nodesx->cached[position-1]=*FetchCachedNodeX(nodesx->cache,index,nodesx->fd,0); nodesx->incache[position-1]=index; return(&nodesx->cached[position-1]); } /*++++++++++++++++++++++++++++++++++++++ Put back an extended node's data into the file on disk. NodesX *nodesx The set of nodes to modify. NodeX *nodex The extended node to be put back. ++++++++++++++++++++++++++++++++++++++*/ static inline void PutBackNodeX(NodesX *nodesx,NodeX *nodex) { int position1=nodex-&nodesx->cached[0]; ReplaceCachedNodeX(nodesx->cache,nodex,nodesx->incache[position1],nodesx->fd,0); } #endif /* SLIM */ #endif /* NODESX_H */ routino-3.0/src/nodes.h 644 233 144 12404 12550223461 10314 0/*************************************** A header file for the nodes. Part of the Routino routing software. ******************/ /****************** This file Copyright 2008-2015 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #ifndef NODES_H #define NODES_H /*+ To stop multiple inclusions. +*/ #include #include #include "types.h" #include "cache.h" #include "files.h" #include "profiles.h" /* Data structures */ /*+ A structure containing a single node. +*/ struct _Node { index_t firstseg; /*+ The index of the first segment. +*/ ll_off_t latoffset; /*+ The node latitude offset within its bin. +*/ ll_off_t lonoffset; /*+ The node longitude offset within its bin. +*/ transports_t allow; /*+ The types of transport that are allowed through the node. +*/ nodeflags_t flags; /*+ Flags containing extra information (e.g. super-node, turn restriction). +*/ }; /*+ A structure containing the header from the file. +*/ typedef struct _NodesFile { index_t number; /*+ The number of nodes in total. +*/ index_t snumber; /*+ The number of super-nodes. +*/ ll_bin_t latbins; /*+ The number of bins containing latitude. +*/ ll_bin_t lonbins; /*+ The number of bins containing longitude. +*/ ll_bin_t latzero; /*+ The bin number of the furthest south bin. +*/ ll_bin_t lonzero; /*+ The bin number of the furthest west bin. +*/ } NodesFile; /*+ A structure containing a set of nodes. +*/ struct _Nodes { NodesFile file; /*+ The header data from the file. +*/ #if !SLIM char *data; /*+ The memory mapped data in the file. +*/ index_t *offsets; /*+ A pointer to the array of offsets in the file. +*/ Node *nodes; /*+ A pointer to the array of nodes in the file. +*/ #else int fd; /*+ The file descriptor for the file. +*/ index_t *offsets; /*+ An allocated array with a copy of the file offsets. +*/ offset_t nodesoffset; /*+ The offset of the nodes within the file. +*/ Node cached[6]; /*+ Some cached nodes read from the file in slim mode. +*/ NodeCache *cache; /*+ A RAM cache of nodes read from the file. +*/ #endif }; /* Functions in nodes.c */ Nodes *LoadNodeList(const char *filename); void DestroyNodeList(Nodes *nodes); index_t FindClosestNode(Nodes *nodes,Segments *segments,Ways *ways,double latitude,double longitude, distance_t distance,Profile *profile,distance_t *bestdist); index_t FindClosestSegment(Nodes *nodes,Segments *segments,Ways *ways,double latitude,double longitude, distance_t distance,Profile *profile, distance_t *bestdist, index_t *bestnode1,index_t *bestnode2,distance_t *bestdist1,distance_t *bestdist2); void GetLatLong(Nodes *nodes,index_t index,Node *nodep,double *latitude,double *longitude); /* Macros and inline functions */ /*+ Return true if this is a super-node. +*/ #define IsSuperNode(xxx) (((xxx)->flags)&NODE_SUPER) /*+ Return true if this is a turn restricted node. +*/ #define IsTurnRestrictedNode(xxx) (((xxx)->flags)&NODE_TURNRSTRCT) /*+ Return a Segment index given a Node pointer and a set of segments. +*/ #define FirstSegment(xxx,yyy,ppp) LookupSegment((xxx),(yyy)->firstseg,ppp) /*+ Return the offset of a geographical region given a set of nodes. +*/ #define LookupNodeOffset(xxx,yyy) ((xxx)->offsets[yyy]) #if !SLIM /*+ Return a Node pointer given a set of nodes and an index. +*/ #define LookupNode(xxx,yyy,ppp) (&(xxx)->nodes[yyy]) #else /* Prototypes */ static inline Node *LookupNode(Nodes *nodes,index_t index,int position); CACHE_NEWCACHE_PROTO(Node) CACHE_DELETECACHE_PROTO(Node) CACHE_FETCHCACHE_PROTO(Node) CACHE_INVALIDATECACHE_PROTO(Node) /* Data type */ CACHE_STRUCTURE(Node) /* Inline functions */ CACHE_NEWCACHE(Node) CACHE_DELETECACHE(Node) CACHE_FETCHCACHE(Node) CACHE_INVALIDATECACHE(Node) /*++++++++++++++++++++++++++++++++++++++ Find the Node information for a particular node. Node *LookupNode Returns a pointer to the cached node information. Nodes *nodes The set of nodes to use. index_t index The index of the node. int position The position in the cache to store the value. ++++++++++++++++++++++++++++++++++++++*/ static inline Node *LookupNode(Nodes *nodes,index_t index,int position) { nodes->cached[position-1]=*FetchCachedNode(nodes->cache,index,nodes->fd,nodes->nodesoffset); return(&nodes->cached[position-1]); } #endif #endif /* NODES_H */ routino-3.0/src/queue.c 644 233 144 12331 12167322456 10332 0/*************************************** Queue data type functions. Part of the Routino routing software. ******************/ /****************** This file Copyright 2008-2013 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #include #include #include "results.h" /*+ A queue of results. +*/ struct _Queue { int nincrement; /*+ The amount to increment the queue when full. +*/ int nallocated; /*+ The number of entries allocated. +*/ int noccupied; /*+ The number of entries occupied. +*/ Result **results; /*+ The queue of pointers to results. +*/ }; /*++++++++++++++++++++++++++++++++++++++ Allocate a new queue. Queue *NewQueueList Returns the queue. uint8_t log2bins The base 2 logarithm of the initial number of bins in the queue. ++++++++++++++++++++++++++++++++++++++*/ Queue *NewQueueList(uint8_t log2bins) { Queue *queue; queue=(Queue*)malloc(sizeof(Queue)); queue->nincrement=1<nallocated=queue->nincrement; queue->noccupied=0; queue->results=(Result**)malloc(queue->nallocated*sizeof(Result*)); return(queue); } /*++++++++++++++++++++++++++++++++++++++ Re-use an existing queue. Queue *queue The queue to reset for re-use. ++++++++++++++++++++++++++++++++++++++*/ void ResetQueueList(Queue *queue) { queue->noccupied=0; } /*++++++++++++++++++++++++++++++++++++++ Free a queue. Queue *queue The queue to be freed. ++++++++++++++++++++++++++++++++++++++*/ void FreeQueueList(Queue *queue) { free(queue->results); free(queue); } /*++++++++++++++++++++++++++++++++++++++ Insert a new item into the queue in the right place. The data is stored in a "Binary Heap" http://en.wikipedia.org/wiki/Binary_heap and this operation is adding an item to the heap. Queue *queue The queue to insert the result into. Result *result The result to insert into the queue. score_t score The score to use for sorting the node. ++++++++++++++++++++++++++++++++++++++*/ void InsertInQueue(Queue *queue,Result *result,score_t score) { int index; if(result->queued==NOT_QUEUED) { queue->noccupied++; index=queue->noccupied; if(queue->noccupied==queue->nallocated) { queue->nallocated=queue->nallocated+queue->nincrement; queue->results=(Result**)realloc((void*)queue->results,queue->nallocated*sizeof(Result*)); } queue->results[index]=result; queue->results[index]->queued=index; } else index=result->queued; queue->results[index]->sortby=score; /* Bubble up the new value */ while(index>1) { int newindex; Result *temp; newindex=index/2; if(queue->results[index]->sortby>=queue->results[newindex]->sortby) break; temp=queue->results[index]; queue->results[index]=queue->results[newindex]; queue->results[newindex]=temp; queue->results[index]->queued=index; queue->results[newindex]->queued=newindex; index=newindex; } } /*++++++++++++++++++++++++++++++++++++++ Pop an item from the front of the queue. The data is stored in a "Binary Heap" http://en.wikipedia.org/wiki/Binary_heap and this operation is deleting the root item from the heap. Result *PopFromQueue Returns the top item. Queue *queue The queue to remove the result from. ++++++++++++++++++++++++++++++++++++++*/ Result *PopFromQueue(Queue *queue) { int index; Result *retval; if(queue->noccupied==0) return(NULL); retval=queue->results[1]; retval->queued=NOT_QUEUED; index=1; queue->results[index]=queue->results[queue->noccupied]; queue->noccupied--; /* Bubble down the newly promoted value */ while((2*index)noccupied) { int newindex; Result *temp; newindex=2*index; if(queue->results[newindex]->sortby>queue->results[newindex+1]->sortby) newindex=newindex+1; if(queue->results[index]->sortby<=queue->results[newindex]->sortby) break; temp=queue->results[newindex]; queue->results[newindex]=queue->results[index]; queue->results[index]=temp; queue->results[index]->queued=index; queue->results[newindex]->queued=newindex; index=newindex; } if((2*index)==queue->noccupied) { int newindex; Result *temp; newindex=2*index; if(queue->results[index]->sortby<=queue->results[newindex]->sortby) ; /* break */ else { temp=queue->results[newindex]; queue->results[newindex]=queue->results[index]; queue->results[index]=temp; queue->results[index]->queued=index; queue->results[newindex]->queued=newindex; } } return(retval); } routino-3.0/src/uncompress.c 644 233 144 24015 12535623410 11377 0/*************************************** File uncompression. Part of the Routino routing software. ******************/ /****************** This file Copyright 2012-2015 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #include #if defined(_MSC_VER) #include #define read(fd,address,length) _read(fd,address,(unsigned int)(length)) #define write(fd,address,length) _write(fd,address,(unsigned int)(length)) #define close _close #else #include #endif #include #if defined(USE_BZIP2) && USE_BZIP2 #define BZ_NO_STDIO #include #endif #if defined(USE_GZIP) && USE_GZIP #include #endif #if defined(USE_XZ) && USE_XZ #include #endif #include "logging.h" #include "uncompress.h" /* Local functions */ #if !defined(_MSC_VER) && !defined(__MINGW32__) #if (defined(USE_BZIP2) && USE_BZIP2) || (defined(USE_GZIP) && USE_GZIP) || (defined(USE_XZ) && USE_XZ) static int pipe_and_fork(int filefd,int *pipefd); #endif #if defined(USE_BZIP2) && USE_BZIP2 static void uncompress_bzip2_pipe(int filefd,int pipefd); #endif #if defined(USE_GZIP) && USE_GZIP static void uncompress_gzip_pipe(int filefd,int pipefd); #endif #if defined(USE_XZ) && USE_XZ static void uncompress_xz_pipe(int filefd,int pipefd); #endif #endif /* !defined(_MSC_VER) && !defined(__MINGW32__) */ /*++++++++++++++++++++++++++++++++++++++ Create a child process to uncompress data on a file descriptor as if it were a pipe. int Uncompress_Bzip2 Returns the file descriptor of the uncompressed end of the pipe. int filefd The file descriptor of the compressed end of the pipe. ++++++++++++++++++++++++++++++++++++++*/ int Uncompress_Bzip2(int filefd) { #if defined(USE_BZIP2) && USE_BZIP2 && !defined(_MSC_VER) && !defined(__MINGW32__) int pipefd=-1; if(pipe_and_fork(filefd,&pipefd)) return(pipefd); uncompress_bzip2_pipe(filefd,pipefd); exit(EXIT_SUCCESS); #else /* USE_BZIP2 */ logassert(0,"No bzip2 compression support available (re-compile and try again)"); return(0); #endif /* USE_BZIP2 */ } /*++++++++++++++++++++++++++++++++++++++ Create a child process to uncompress data on a file descriptor as if it were a pipe. int Uncompress_Gzip Returns the file descriptor of the uncompressed end of the pipe. int filefd The file descriptor of the compressed end of the pipe. ++++++++++++++++++++++++++++++++++++++*/ int Uncompress_Gzip(int filefd) { #if defined(USE_GZIP) && USE_GZIP && !defined(_MSC_VER) && !defined(__MINGW32__) int pipefd=-1; if(pipe_and_fork(filefd,&pipefd)) return(pipefd); uncompress_gzip_pipe(filefd,pipefd); exit(EXIT_SUCCESS); #else /* USE_GZIP */ logassert(0,"No gzip compression support available (re-compile and try again)"); return(0); #endif /* USE_GZIP */ } /*++++++++++++++++++++++++++++++++++++++ Create a child process to uncompress data on a file descriptor as if it were a pipe. int Uncompress_Xz Returns the file descriptor of the uncompressed end of the pipe. int filefd The file descriptor of the compressed end of the pipe. ++++++++++++++++++++++++++++++++++++++*/ int Uncompress_Xz(int filefd) { #if defined(USE_XZ) && USE_XZ && !defined(_MSC_VER) && !defined(__MINGW32__) int pipefd=-1; if(pipe_and_fork(filefd,&pipefd)) return(pipefd); uncompress_xz_pipe(filefd,pipefd); exit(EXIT_SUCCESS); #else /* USE_XZ */ logassert(0,"No xz compression support available (re-compile and try again)"); return(0); #endif /* USE_XZ */ } #if !defined(_MSC_VER) && !defined(__MINGW32__) #if (defined(USE_BZIP2) && USE_BZIP2) || (defined(USE_GZIP) && USE_GZIP) || (defined(USE_XZ) && USE_XZ) /*++++++++++++++++++++++++++++++++++++++ Create a pipe and then fork returning in the parent and child with a different end of the pipe. int pipe_and_fork Returns 1 for the reading (parent) end of the pipe and 0 for the writing (child) end. int filefd The file descriptor of the file. int *pipefd Returns the file descriptor for the end of the pipe. ++++++++++++++++++++++++++++++++++++++*/ static int pipe_and_fork(int filefd,int *pipefd) { int pipe_fd[2]={-1,-1}; pid_t childpid; #define PIPE_READER 0 #define PIPE_WRITER 1 if(pipe(pipe_fd)) { logassert(0,"Cannot create pipe for uncompressor (try without using a compressed file)"); return(1); } if((childpid=fork()) == -1) { logassert(0,"Cannot create new process for uncompressor (try without using a compressed file)"); return(1); } if(childpid==0) /* The child */ { int i; *pipefd=pipe_fd[PIPE_WRITER]; /* Close all unneeded file descriptors */ for(i=0;i<255;i++) if(i!=filefd && i!=*pipefd) close(i); return(0); } else /* The parent */ { struct sigaction action; *pipefd=pipe_fd[PIPE_READER]; /* Close all unneeded file descriptors */ close(pipe_fd[PIPE_WRITER]); close(filefd); /* Ignore child exiting and pipe signals */ /* SIGCHLD */ action.sa_handler=SIG_IGN; sigemptyset(&action.sa_mask); action.sa_flags=0; sigaction(SIGCHLD,&action,NULL); /* SIGPIPE */ action.sa_handler=SIG_IGN; sigemptyset(&action.sa_mask); action.sa_flags=0; sigaction(SIGPIPE,&action,NULL); return(1); } } #endif /* (defined(USE_BZIP2) && USE_BZIP2) || (defined(USE_GZIP) && USE_GZIP) || (defined(USE_XZ) && USE_XZ) */ #if defined(USE_BZIP2) && USE_BZIP2 /*++++++++++++++++++++++++++++++++++++++ Uncompress a file using bzip2 as a pipeline. int filefd The incoming, compressed, data. int pipefd The outgoing, uncompressed, data. ++++++++++++++++++++++++++++++++++++++*/ static void uncompress_bzip2_pipe(int filefd,int pipefd) { bz_stream bz={0}; char inbuffer[16384],outbuffer[16384]; int infinished=0; int state; if(BZ2_bzDecompressInit(&bz,0,0)!=BZ_OK) exit(EXIT_FAILURE); do { if(bz.avail_in==0 && !infinished) { ssize_t n=read(filefd,inbuffer,sizeof(inbuffer)); if(n<=0) infinished=1; else { bz.next_in=inbuffer; bz.avail_in=n; } } bz.next_out=outbuffer; bz.avail_out=sizeof(outbuffer); state=BZ2_bzDecompress(&bz); if(state!=BZ_OK && state!=BZ_STREAM_END) exit(EXIT_FAILURE); if(bz.avail_out0) { m=write(pipefd,p,n); if(m<=0) exit(EXIT_FAILURE); p+=m; n-=m; } } } while(state!=BZ_STREAM_END); if(BZ2_bzDecompressEnd(&bz)!=BZ_OK) exit(EXIT_FAILURE); exit(EXIT_SUCCESS); } #endif /* USE_BZIP2 */ #if defined(USE_GZIP) && USE_GZIP /*++++++++++++++++++++++++++++++++++++++ Uncompress a file using gzip as a pipeline. int filefd The incoming, compressed, data. int pipefd The outgoing, uncompressed, data. ++++++++++++++++++++++++++++++++++++++*/ static void uncompress_gzip_pipe(int filefd,int pipefd) { z_stream z={0}; unsigned char inbuffer[16384],outbuffer[16384]; int infinished=0; int state; if(inflateInit2(&z,15+32)!=Z_OK) exit(EXIT_FAILURE); do { if(z.avail_in==0 && !infinished) { ssize_t n=read(filefd,inbuffer,sizeof(inbuffer)); if(n<=0) infinished=1; else { z.next_in=inbuffer; z.avail_in=n; } } z.next_out=outbuffer; z.avail_out=sizeof(outbuffer); state=inflate(&z,Z_NO_FLUSH); if(state!=Z_OK && state!=Z_STREAM_END) { exit(EXIT_FAILURE); } if(z.avail_out0) { m=write(pipefd,p,n); if(m<=0) exit(EXIT_FAILURE); p+=m; n-=m; } } } while(state!=Z_STREAM_END); if(inflateEnd(&z)!=Z_OK) exit(EXIT_FAILURE); exit(EXIT_SUCCESS); } #endif /* USE_GZIP */ #if defined(USE_XZ) && USE_XZ /*++++++++++++++++++++++++++++++++++++++ Uncompress a file using xz as a pipeline. int filefd The incoming, compressed, data. int pipefd The outgoing, uncompressed, data. ++++++++++++++++++++++++++++++++++++++*/ static void uncompress_xz_pipe(int filefd,int pipefd) { lzma_stream lzma=LZMA_STREAM_INIT; unsigned char inbuffer[16384],outbuffer[16384]; int infinished=0; lzma_ret retval; if(lzma_stream_decoder(&lzma,UINT64_MAX,0)!=LZMA_OK) exit(EXIT_FAILURE); do { if(lzma.avail_in==0 && !infinished) { ssize_t n=read(filefd,inbuffer,sizeof(inbuffer)); if(n<=0) infinished=1; else { lzma.next_in=inbuffer; lzma.avail_in=n; } } lzma.next_out=outbuffer; lzma.avail_out=sizeof(outbuffer); retval=lzma_code(&lzma,LZMA_RUN); if(retval!=LZMA_OK && retval!=LZMA_STREAM_END) { exit(EXIT_FAILURE); } if(lzma.avail_out0) { m=write(pipefd,p,n); if(m<=0) exit(EXIT_FAILURE); p+=m; n-=m; } } } while(retval!=LZMA_STREAM_END); lzma_end(&lzma); exit(EXIT_SUCCESS); } #endif /* USE_XZ */ #endif /* !defined(_MSC_VER) && !defined(__MINGW32__) */ routino-3.0/src/xmlparse.c 644 233 144 210007 12563633052 11056 0/*************************************** A simple generic XML parser where the structure comes from the function parameters. Not intended to be fully conforming to XML standard or a validating parser but sufficient to parse OSM XML and simple program configuration files. Part of the Routino routing software. ******************/ /****************** This file Copyright 2010-2015 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #include #if defined(_MSC_VER) #include #include #define read(fd,address,length) _read(fd,address,(unsigned int)(length)) #define snprintf _snprintf #define ssize_t SSIZE_T #else #include #endif #include #include #include #include #include #if defined(_MSC_VER) || defined(__MINGW32__) #define strcasecmp _stricmp #else #include #endif #include #include "xmlparse.h" /* Parser states */ #define LEX_EOF 0 #define LEX_FUNC_TAG_BEGIN 1 #define LEX_FUNC_XML_DECL_BEGIN 2 #define LEX_FUNC_TAG_POP 3 #define LEX_FUNC_TAG_PUSH 4 #define LEX_FUNC_XML_DECL_FINISH 5 #define LEX_FUNC_TAG_FINISH 6 #define LEX_FUNC_ATTR_KEY 7 #define LEX_FUNC_ATTR_VAL 8 #define LEX_STATE_INITIAL 10 #define LEX_STATE_BANGTAG 11 #define LEX_STATE_COMMENT 12 #define LEX_STATE_XML_DECL_START 13 #define LEX_STATE_XML_DECL 14 #define LEX_STATE_TAG_START 15 #define LEX_STATE_TAG 16 #define LEX_STATE_ATTR_KEY 17 #define LEX_STATE_ATTR_VAL 18 #define LEX_STATE_END_TAG1 19 #define LEX_STATE_END_TAG2 20 #define LEX_STATE_DQUOTED 21 #define LEX_STATE_SQUOTED 22 #define LEX_ERROR_TAG_START 101 #define LEX_ERROR_XML_DECL_START 102 #define LEX_ERROR_TAG 103 #define LEX_ERROR_XML_DECL 104 #define LEX_ERROR_ATTR 105 #define LEX_ERROR_END_TAG 106 #define LEX_ERROR_COMMENT 107 #define LEX_ERROR_CLOSE 108 #define LEX_ERROR_ATTR_VAL 109 #define LEX_ERROR_ENTITY_REF 110 #define LEX_ERROR_CHAR_REF 111 #define LEX_ERROR_TEXT_OUTSIDE 112 #define LEX_ERROR_UNEXP_TAG 201 #define LEX_ERROR_UNBALANCED 202 #define LEX_ERROR_NO_START 203 #define LEX_ERROR_UNEXP_ATT 204 #define LEX_ERROR_UNEXP_EOF 205 #define LEX_ERROR_XML_NOT_FIRST 206 #define LEX_ERROR_CALLBACK 255 /* Parsing variables and functions (re-initialised for each file) */ static uint64_t lineno; static unsigned char buffer[2][16384]; static unsigned char *buffer_token,*buffer_end,*buffer_ptr; static int buffer_active=0; static char *stored_message=NULL; /*++++++++++++++++++++++++++++++++++++++ Refill the data buffer making sure that the string starting at buffer_token is contiguous. int buffer_refill Return 0 if everything is OK or 1 for EOF. int fd The file descriptor to read from. ++++++++++++++++++++++++++++++++++++++*/ static inline int buffer_refill(int fd) { ssize_t n; size_t m=0; m=(buffer_end-buffer[buffer_active])+1; if(m>(sizeof(buffer[0])/2)) /* more than half full */ { m=0; buffer_active=!buffer_active; if(buffer_token) { m=(buffer_end-buffer_token)+1; memcpy(buffer[buffer_active],buffer_token,m); buffer_token=buffer[buffer_active]; } } n=read(fd,buffer[buffer_active]+m,sizeof(buffer[0])-m); buffer_ptr=buffer[buffer_active]+m; buffer_end=buffer[buffer_active]+m+n-1; if(n<=0) return(1); else return(0); } /* Macros to simplify the parser (and make it look more like lex) */ #define BEGIN(xx) do{ state=(xx); goto new_state; } while(0) #define NEXT(xx) next_state=(xx) #define START_TOKEN buffer_token=buffer_ptr #define END_TOKEN buffer_token=NULL #define NEXT_CHAR \ do{ \ if(buffer_ptr==buffer_end) \ { if(buffer_refill(fd)) BEGIN(LEX_EOF); } \ else \ buffer_ptr++; \ } while(0) /* -------- equivalent flex definition -------- S [ \t\r] N (\n) U1 [\x09\x0A\x0D\x20-\x7F] U2 [\xC2-\xDF][\x80-\xBF] U3a \xE0[\xA0-\xBF][\x80-\xBF] U3b [\xE1-\xEC][\x80-\xBF][\x80-\xBF] U3c \xED[\x80-\x9F][\x80-\xBF] U3d [\xEE-\xEF][\x80-\xBF][\x80-\xBF] U3 {U3a}|{U3b}|{U3c}|{U3d} U4a \xF0[\x90-\xBF][\x80-\xBF][\x80-\xBF] U4b [\xF1-\xF3][\x80-\xBF][\x80-\xBF][\x80-\xBF] U4c \xF4[\x80-\x8F][\x80-\xBF][\x80-\xBF] U4 {U4a}|{U4b}|{U4c} U ({U1}|{U2}|{U3}|{U4}) U1_xml ([\x09\x0A\x0D\x20-\x25\x27-\x3B\x3D\x3F-\x7F]) U1quotedS_xml ([\x09\x0A\x0D\x20-\x25\x28-\x3B\x3D\x3F-\x7F]) U1quotedD_xml ([\x09\x0A\x0D\x20-\x21\x23-\x25\x27-\x3B\x3D\x3F-\x7F]) UquotedS ({U1quotedS_xml}|{U2}|{U3}|{U4}) UquotedD ({U1quotedD_xml}|{U2}|{U3}|{U4}) letter [a-zA-Z] digit [0-9] xdigit [a-fA-F0-9] namechar ({letter}|{digit}|[-._:]) namestart ({letter}|[_:]) name ({namestart}{namechar}*) entityref (&{name};) charref (&#({digit}+|x{xdigit}+);) -------- equivalent flex definition -------- */ /* Tables containing character class defintions (advance declaration for data at end of file). */ static const unsigned char quotedD[256],quotedS[256]; static const unsigned char *U2[1],*U3a[2],*U3b[2],*U3c[2],*U3d[2],*U4a[3],*U4b[3],*U4c[3]; static const unsigned char namestart[256],namechar[256],whitespace[256],digit[256],xdigit[256]; /*++++++++++++++++++++++++++++++++++++++ A function to call the callback function with the parameters needed. int call_callback Returns 1 if the callback returned with an error. const char *name The name of the tag. int (*callback)() The callback function. int type The type of tag (start and/or end). int nattributes The number of attributes collected. unsigned char *attributes[XMLPARSE_MAX_ATTRS] The list of attributes. ++++++++++++++++++++++++++++++++++++++*/ static inline int call_callback(const char *name,int (*callback)(),int type,int nattributes,unsigned char *attributes[XMLPARSE_MAX_ATTRS]) { switch(nattributes) { case 0: return (*callback)(name,type); case 1: return (*callback)(name,type,attributes[0]); case 2: return (*callback)(name,type,attributes[0],attributes[1]); case 3: return (*callback)(name,type,attributes[0],attributes[1],attributes[2]); case 4: return (*callback)(name,type,attributes[0],attributes[1],attributes[2],attributes[3]); case 5: return (*callback)(name,type,attributes[0],attributes[1],attributes[2],attributes[3],attributes[4]); case 6: return (*callback)(name,type,attributes[0],attributes[1],attributes[2],attributes[3],attributes[4],attributes[5]); case 7: return (*callback)(name,type,attributes[0],attributes[1],attributes[2],attributes[3],attributes[4],attributes[5],attributes[6]); case 8: return (*callback)(name,type,attributes[0],attributes[1],attributes[2],attributes[3],attributes[4],attributes[5],attributes[6],attributes[7]); case 9: return (*callback)(name,type,attributes[0],attributes[1],attributes[2],attributes[3],attributes[4],attributes[5],attributes[6],attributes[7],attributes[8]); case 10: return (*callback)(name,type,attributes[0],attributes[1],attributes[2],attributes[3],attributes[4],attributes[5],attributes[6],attributes[7],attributes[8],attributes[9]); case 11: return (*callback)(name,type,attributes[0],attributes[1],attributes[2],attributes[3],attributes[4],attributes[5],attributes[6],attributes[7],attributes[8],attributes[9],attributes[10]); case 12: return (*callback)(name,type,attributes[0],attributes[1],attributes[2],attributes[3],attributes[4],attributes[5],attributes[6],attributes[7],attributes[8],attributes[9],attributes[10],attributes[11]); case 13: return (*callback)(name,type,attributes[0],attributes[1],attributes[2],attributes[3],attributes[4],attributes[5],attributes[6],attributes[7],attributes[8],attributes[9],attributes[10],attributes[11],attributes[12]); case 14: return (*callback)(name,type,attributes[0],attributes[1],attributes[2],attributes[3],attributes[4],attributes[5],attributes[6],attributes[7],attributes[8],attributes[9],attributes[10],attributes[11],attributes[12],attributes[13]); case 15: return (*callback)(name,type,attributes[0],attributes[1],attributes[2],attributes[3],attributes[4],attributes[5],attributes[6],attributes[7],attributes[8],attributes[9],attributes[10],attributes[11],attributes[12],attributes[13],attributes[14]); case 16: return (*callback)(name,type,attributes[0],attributes[1],attributes[2],attributes[3],attributes[4],attributes[5],attributes[6],attributes[7],attributes[8],attributes[9],attributes[10],attributes[11],attributes[12],attributes[13],attributes[14],attributes[15]); default: ParseXML_SetError("Too many attributes for tag '%s' source code needs changing.",name); return(1); } } /*++++++++++++++++++++++++++++++++++++++ Parse the XML and call the functions for each tag as seen. int ParseXML Returns 0 if OK or something else in case of an error. int fd The file descriptor of the file to parse. const xmltag *const *tags The array of pointers to tags for the top level. int options A list of XML Parser options OR-ed together. ++++++++++++++++++++++++++++++++++++++*/ int ParseXML(int fd,const xmltag *const *tags,int options) { int i; int state,next_state,after_attr; unsigned char saved_buffer_ptr=0; const unsigned char *quoted; unsigned char *attributes[XMLPARSE_MAX_ATTRS]={NULL}; int attribute=0; int stackdepth=0,stackused=0; const xmltag * const **tags_stack=NULL; const xmltag **tag_stack=NULL; const xmltag *tag=NULL; /* The actual parser. */ lineno=1; if(stored_message) free(stored_message); stored_message=NULL; buffer_end=buffer[buffer_active]+sizeof(buffer[0])-1; buffer_token=NULL; buffer_refill(fd); BEGIN(LEX_STATE_INITIAL); new_state: switch(state) { /* ================ Parsing states ================ */ /* -------- equivalent flex definition -------- """"<" { BEGIN(TAG_START); } ">" { return(LEX_ERROR_CLOSE); } {N} { lineno++; } {S}+ { } . { return(LEX_ERROR_TEXT_OUTSIDE); } -------- equivalent flex definition -------- */ case LEX_STATE_INITIAL: while(1) { while(whitespace[(int)*buffer_ptr]) NEXT_CHAR; if(*buffer_ptr=='\n') { NEXT_CHAR; lineno++; } else if(*buffer_ptr=='<') { NEXT_CHAR; if(*buffer_ptr=='/') { NEXT_CHAR; BEGIN(LEX_STATE_END_TAG1); } else if(*buffer_ptr=='!') { NEXT_CHAR; BEGIN(LEX_STATE_BANGTAG); } else if(*buffer_ptr=='?') { NEXT_CHAR; BEGIN(LEX_STATE_XML_DECL_START); } else BEGIN(LEX_STATE_TAG_START); } else if(*buffer_ptr=='>') BEGIN(LEX_ERROR_CLOSE); else BEGIN(LEX_ERROR_TEXT_OUTSIDE); } break; /* -------- equivalent flex definition -------- "--" { BEGIN(COMMENT); } {N} { return(LEX_ERROR_TAG_START); } . { return(LEX_ERROR_TAG_START); } -------- equivalent flex definition -------- */ case LEX_STATE_BANGTAG: if(*buffer_ptr!='-') BEGIN(LEX_ERROR_TAG_START); NEXT_CHAR; if(*buffer_ptr!='-') BEGIN(LEX_ERROR_TAG_START); NEXT_CHAR; BEGIN(LEX_STATE_COMMENT); break; /* -------- equivalent flex definition -------- "-->" { BEGIN(INITIAL); } "--"[^>] { return(LEX_ERROR_COMMENT); } "-" { } {N} { lineno++; } [^-\n]+ { } -------- equivalent flex definition -------- */ case LEX_STATE_COMMENT: while(1) { while(*buffer_ptr!='-' && *buffer_ptr!='\n') NEXT_CHAR; if(*buffer_ptr=='-') { NEXT_CHAR; if(*buffer_ptr!='-') continue; NEXT_CHAR; if(*buffer_ptr=='>') { NEXT_CHAR; BEGIN(LEX_STATE_INITIAL); } BEGIN(LEX_ERROR_COMMENT); } else /* if(*buffer_ptr=='\n') */ { NEXT_CHAR; lineno++; } } break; /* -------- equivalent flex definition -------- xml { BEGIN(XML_DECL); return(LEX_XML_DECL_BEGIN); } {N} { return(LEX_ERROR_XML_DECL_START); } . { return(LEX_ERROR_XML_DECL_START); } -------- equivalent flex definition -------- */ case LEX_STATE_XML_DECL_START: START_TOKEN; if(*buffer_ptr=='x') { NEXT_CHAR; if(*buffer_ptr=='m') { NEXT_CHAR; if(*buffer_ptr=='l') { NEXT_CHAR; saved_buffer_ptr=*buffer_ptr; *buffer_ptr=0; NEXT(LEX_STATE_XML_DECL); BEGIN(LEX_FUNC_XML_DECL_BEGIN); } } } BEGIN(LEX_ERROR_XML_DECL_START); /* -------- equivalent flex definition -------- "?>" { BEGIN(INITIAL); return(LEX_XML_DECL_FINISH); } {S}+ { } {N} { lineno++; } {name} { after_attr=XML_DECL; BEGIN(ATTR_KEY); return(LEX_ATTR_KEY); } . { return(LEX_ERROR_XML_DECL); } -------- equivalent flex definition -------- */ case LEX_STATE_XML_DECL: while(1) { while(whitespace[(int)*buffer_ptr]) NEXT_CHAR; if(namestart[(int)*buffer_ptr]) { START_TOKEN; NEXT_CHAR; while(namechar[(int)*buffer_ptr]) NEXT_CHAR; saved_buffer_ptr=*buffer_ptr; *buffer_ptr=0; after_attr=LEX_STATE_XML_DECL; NEXT(LEX_STATE_ATTR_KEY); BEGIN(LEX_FUNC_ATTR_KEY); } else if(*buffer_ptr=='?') { NEXT_CHAR; if(*buffer_ptr=='>') { NEXT_CHAR; NEXT(LEX_STATE_INITIAL); BEGIN(LEX_FUNC_XML_DECL_FINISH); } BEGIN(LEX_ERROR_XML_DECL); } else if(*buffer_ptr=='\n') { NEXT_CHAR; lineno++; } else BEGIN(LEX_ERROR_XML_DECL); } break; /* -------- equivalent flex definition -------- {name} { BEGIN(TAG); return(LEX_TAG_BEGIN); } {N} { return(LEX_ERROR_TAG_START); } . { return(LEX_ERROR_TAG_START); } -------- equivalent flex definition -------- */ case LEX_STATE_TAG_START: if(namestart[(int)*buffer_ptr]) { START_TOKEN; NEXT_CHAR; while(namechar[(int)*buffer_ptr]) NEXT_CHAR; saved_buffer_ptr=*buffer_ptr; *buffer_ptr=0; NEXT(LEX_STATE_TAG); BEGIN(LEX_FUNC_TAG_BEGIN); } BEGIN(LEX_ERROR_TAG_START); /* -------- equivalent flex definition -------- {name} { BEGIN(END_TAG2); return(LEX_TAG_POP); } {N} { return(LEX_ERROR_END_TAG); } . { return(LEX_ERROR_END_TAG); } -------- equivalent flex definition -------- */ case LEX_STATE_END_TAG1: if(namestart[(int)*buffer_ptr]) { START_TOKEN; NEXT_CHAR; while(namechar[(int)*buffer_ptr]) NEXT_CHAR; saved_buffer_ptr=*buffer_ptr; *buffer_ptr=0; NEXT(LEX_STATE_END_TAG2); BEGIN(LEX_FUNC_TAG_POP); } BEGIN(LEX_ERROR_END_TAG); /* -------- equivalent flex definition -------- ">" { BEGIN(INITIAL); } {N} { return(LEX_ERROR_END_TAG); } . { return(LEX_ERROR_END_TAG); } -------- equivalent flex definition -------- */ case LEX_STATE_END_TAG2: if(*buffer_ptr=='>') { NEXT_CHAR; BEGIN(LEX_STATE_INITIAL); } BEGIN(LEX_ERROR_END_TAG); /* -------- equivalent flex definition -------- "/>" { BEGIN(INITIAL); return(LEX_TAG_FINISH); } ">" { BEGIN(INITIAL); return(LEX_TAG_PUSH); } {S}+ { } {N} { lineno++; } {name} { after_attr=TAG; BEGIN(ATTR_KEY); return(LEX_ATTR_KEY); } . { return(LEX_ERROR_TAG); } -------- equivalent flex definition -------- */ case LEX_STATE_TAG: while(1) { while(whitespace[(int)*buffer_ptr]) NEXT_CHAR; if(namestart[(int)*buffer_ptr]) { START_TOKEN; NEXT_CHAR; while(namechar[(int)*buffer_ptr]) NEXT_CHAR; saved_buffer_ptr=*buffer_ptr; *buffer_ptr=0; after_attr=LEX_STATE_TAG; NEXT(LEX_STATE_ATTR_KEY); BEGIN(LEX_FUNC_ATTR_KEY); } else if(*buffer_ptr=='/') { NEXT_CHAR; if(*buffer_ptr=='>') { NEXT_CHAR; NEXT(LEX_STATE_INITIAL); BEGIN(LEX_FUNC_TAG_FINISH); } BEGIN(LEX_ERROR_TAG); } else if(*buffer_ptr=='>') { NEXT_CHAR; NEXT(LEX_STATE_INITIAL); BEGIN(LEX_FUNC_TAG_PUSH); } else if(*buffer_ptr=='\n') { NEXT_CHAR; lineno++; } else BEGIN(LEX_ERROR_TAG); } break; /* -------- equivalent flex definition -------- = { BEGIN(ATTR_VAL); } {N} { return(LEX_ERROR_ATTR); } . { return(LEX_ERROR_ATTR); } -------- equivalent flex definition -------- */ case LEX_STATE_ATTR_KEY: if(*buffer_ptr=='=') { NEXT_CHAR; BEGIN(LEX_STATE_ATTR_VAL); } BEGIN(LEX_ERROR_ATTR); /* -------- equivalent flex definition -------- \" { BEGIN(DQUOTED); } \' { BEGIN(SQUOTED); } {N} { return(LEX_ERROR_ATTR); } . { return(LEX_ERROR_ATTR); } -------- equivalent flex definition -------- */ case LEX_STATE_ATTR_VAL: if(*buffer_ptr=='"') { NEXT_CHAR; BEGIN(LEX_STATE_DQUOTED); } else if(*buffer_ptr=='\'') { NEXT_CHAR; BEGIN(LEX_STATE_SQUOTED); } BEGIN(LEX_ERROR_ATTR); /* -------- equivalent flex definition -------- \" { BEGIN(after_attr); return(LEX_ATTR_VAL); } {entityref} { if(options&XMLPARSE_RETURN_ATTR_ENCODED) {append_string(yytext);} else { const char *str=ParseXML_Decode_Entity_Ref(yytext); if(str) {append_string(str);} else {return(LEX_ERROR_ENTITY_REF);} } } {charref} { if(options&XMLPARSE_RETURN_ATTR_ENCODED) {append_string(yytext);} else { const char *str=ParseXML_Decode_Char_Ref(yytext); if(str) {append_string(str);} else {return(LEX_ERROR_CHAR_REF);} } } {UquotedD} { } [<>&] { return(LEX_ERROR_ATTR_VAL); } . { return(LEX_ERROR_ATTR_VAL); } \' { BEGIN(after_attr); return(LEX_ATTR_VAL); } {entityref} { if(options&XMLPARSE_RETURN_ATTR_ENCODED) {append_string(yytext);} else { const char *str=ParseXML_Decode_Entity_Ref(yytext); if(str) {append_string(str);} else {return(LEX_ERROR_ENTITY_REF);} } } {charref} { if(options&XMLPARSE_RETURN_ATTR_ENCODED) {append_string(yytext);} else { const char *str=ParseXML_Decode_Char_Ref(yytext); if(str) {append_string(str);} else {return(LEX_ERROR_CHAR_REF);} } } {UquotedS} { append_string(yytext); } [<>&] { return(LEX_ERROR_ATTR_VAL); } . { return(LEX_ERROR_ATTR_VAL); } -------- equivalent flex definition -------- */ case LEX_STATE_DQUOTED: case LEX_STATE_SQUOTED: if(state==LEX_STATE_DQUOTED) quoted=quotedD; else quoted=quotedS; START_TOKEN; while(1) { switch(quoted[(int)*buffer_ptr]) { case 10: /* U1 - used by all tag keys and many values */ do { NEXT_CHAR; } while(quoted[(int)*buffer_ptr]==10); break; case 20: /* U2 */ NEXT_CHAR; if(!U2[0][(int)*buffer_ptr]) BEGIN(LEX_ERROR_ATTR_VAL); NEXT_CHAR; break; case 31: /* U3a */ NEXT_CHAR; if(!U3a[0][(int)*buffer_ptr]) BEGIN(LEX_ERROR_ATTR_VAL); NEXT_CHAR; if(!U3a[1][(int)*buffer_ptr]) BEGIN(LEX_ERROR_ATTR_VAL); NEXT_CHAR; break; case 32: /* U3b */ NEXT_CHAR; if(!U3b[0][(int)*buffer_ptr]) BEGIN(LEX_ERROR_ATTR_VAL); NEXT_CHAR; if(!U3b[1][(int)*buffer_ptr]) BEGIN(LEX_ERROR_ATTR_VAL); NEXT_CHAR; break; case 33: /* U3c */ NEXT_CHAR; if(!U3c[0][(int)*buffer_ptr]) BEGIN(LEX_ERROR_ATTR_VAL); NEXT_CHAR; if(!U3c[1][(int)*buffer_ptr]) BEGIN(LEX_ERROR_ATTR_VAL); NEXT_CHAR; break; case 34: /* U3d */ NEXT_CHAR; if(!U3d[0][(int)*buffer_ptr]) BEGIN(LEX_ERROR_ATTR_VAL); NEXT_CHAR; if(!U3d[1][(int)*buffer_ptr]) BEGIN(LEX_ERROR_ATTR_VAL); NEXT_CHAR; break; case 41: /* U4a */ NEXT_CHAR; if(!U4a[0][(int)*buffer_ptr]) BEGIN(LEX_ERROR_ATTR_VAL); NEXT_CHAR; if(!U4a[1][(int)*buffer_ptr]) BEGIN(LEX_ERROR_ATTR_VAL); NEXT_CHAR; if(!U4a[2][(int)*buffer_ptr]) BEGIN(LEX_ERROR_ATTR_VAL); NEXT_CHAR; break; case 42: /* U4b */ NEXT_CHAR; if(!U4b[0][(int)*buffer_ptr]) BEGIN(LEX_ERROR_ATTR_VAL); NEXT_CHAR; if(!U4b[1][(int)*buffer_ptr]) BEGIN(LEX_ERROR_ATTR_VAL); NEXT_CHAR; if(!U4b[2][(int)*buffer_ptr]) BEGIN(LEX_ERROR_ATTR_VAL); NEXT_CHAR; break; case 43: /* U4c */ NEXT_CHAR; if(!U4c[0][(int)*buffer_ptr]) BEGIN(LEX_ERROR_ATTR_VAL); NEXT_CHAR; if(!U4c[1][(int)*buffer_ptr]) BEGIN(LEX_ERROR_ATTR_VAL); NEXT_CHAR; if(!U4c[2][(int)*buffer_ptr]) BEGIN(LEX_ERROR_ATTR_VAL); NEXT_CHAR; break; case 50: /* entityref or charref */ NEXT_CHAR; if(*buffer_ptr=='#') /* charref */ { int charref_len=3; NEXT_CHAR; if(digit[(int)*buffer_ptr]) /* decimal */ { NEXT_CHAR; charref_len++; while(digit[(int)*buffer_ptr]) { NEXT_CHAR; charref_len++; } if(*buffer_ptr!=';') BEGIN(LEX_ERROR_ATTR_VAL); } else if(*buffer_ptr=='x') /* hex */ { NEXT_CHAR; charref_len++; while(xdigit[(int)*buffer_ptr]) { NEXT_CHAR; charref_len++; } if(*buffer_ptr!=';') BEGIN(LEX_ERROR_ATTR_VAL); } else /* other */ BEGIN(LEX_ERROR_ATTR_VAL); NEXT_CHAR; if(!(options&XMLPARSE_RETURN_ATTR_ENCODED)) { const char *str; saved_buffer_ptr=*buffer_ptr; *buffer_ptr=0; str=ParseXML_Decode_Char_Ref((char*)(buffer_ptr-charref_len)); if(!str) { buffer_ptr-=charref_len; BEGIN(LEX_ERROR_CHAR_REF); } buffer_token=memmove(buffer_token+(charref_len-strlen(str)),buffer_token,buffer_ptr-buffer_token-charref_len); memcpy(buffer_ptr-strlen(str),str,strlen(str)); *buffer_ptr=saved_buffer_ptr; } } else if(namestart[(int)*buffer_ptr]) /* entityref */ { int entityref_len=3; NEXT_CHAR; while(namechar[(int)*buffer_ptr]) { NEXT_CHAR; entityref_len++; } if(*buffer_ptr!=';') BEGIN(LEX_ERROR_ATTR_VAL); NEXT_CHAR; if(!(options&XMLPARSE_RETURN_ATTR_ENCODED)) { const char *str; saved_buffer_ptr=*buffer_ptr; *buffer_ptr=0; str=ParseXML_Decode_Entity_Ref((char*)(buffer_ptr-entityref_len)); if(!str) { buffer_ptr-=entityref_len; BEGIN(LEX_ERROR_ENTITY_REF); } buffer_token=memmove(buffer_token+(entityref_len-strlen(str)),buffer_token,buffer_ptr-buffer_token-entityref_len); memcpy(buffer_ptr-strlen(str),str,strlen(str)); *buffer_ptr=saved_buffer_ptr; } } else /* other */ BEGIN(LEX_ERROR_ATTR_VAL); break; case 99: /* quote */ *buffer_ptr=0; NEXT_CHAR; NEXT(after_attr); BEGIN(LEX_FUNC_ATTR_VAL); default: /* other */ BEGIN(LEX_ERROR_ATTR_VAL); } } break; /* ================ Functional states ================ */ /* The start of a tag for an XML declaration */ case LEX_FUNC_XML_DECL_BEGIN: if(tag_stack) BEGIN(LEX_ERROR_XML_NOT_FIRST); /* The start of a tag for an element */ case LEX_FUNC_TAG_BEGIN: tag=NULL; for(i=0;tags[i];i++) if(buffer_token[0]==tags[i]->name[0] || tolower(buffer_token[0])==tags[i]->name[0]) if(!strcasecmp((char*)buffer_token+1,tags[i]->name+1)) { tag=tags[i]; for(i=0;inattributes;i++) attributes[i]=NULL; break; } if(tag==NULL) BEGIN(LEX_ERROR_UNEXP_TAG); END_TOKEN; *buffer_ptr=saved_buffer_ptr; BEGIN(next_state); /* The end of the start-tag for an element */ case LEX_FUNC_TAG_PUSH: if(stackused==stackdepth) { tag_stack =realloc(tag_stack ,(stackdepth+=8)*sizeof(xmltag*)); tags_stack=realloc(tags_stack,(stackdepth+=8)*sizeof(xmltag**)); } tag_stack [stackused]=tag; tags_stack[stackused]=tags; stackused++; if(tag->callback) if(call_callback(tag->name,tag->callback,XMLPARSE_TAG_START,tag->nattributes,attributes)) BEGIN(LEX_ERROR_CALLBACK); tags=tag->subtags; BEGIN(next_state); /* The end of the empty-element-tag for an XML declaration */ case LEX_FUNC_XML_DECL_FINISH: /* The end of the empty-element-tag for an element */ case LEX_FUNC_TAG_FINISH: if(tag->callback) if(call_callback(tag->name,tag->callback,XMLPARSE_TAG_START|XMLPARSE_TAG_END,tag->nattributes,attributes)) BEGIN(LEX_ERROR_CALLBACK); if(stackused>0) tag=tag_stack[stackused-1]; else tag=NULL; BEGIN(next_state); /* The end of the end-tag for an element */ case LEX_FUNC_TAG_POP: stackused--; tags=tags_stack[stackused]; tag =tag_stack [stackused]; if(strcmp((char*)buffer_token,tag->name)) BEGIN(LEX_ERROR_UNBALANCED); if(stackused<0) BEGIN(LEX_ERROR_NO_START); for(i=0;inattributes;i++) attributes[i]=NULL; if(tag->callback) if(call_callback(tag->name,tag->callback,XMLPARSE_TAG_END,tag->nattributes,attributes)) BEGIN(LEX_ERROR_CALLBACK); if(stackused>0) tag=tag_stack[stackused-1]; else tag=NULL; END_TOKEN; *buffer_ptr=saved_buffer_ptr; BEGIN(next_state); /* An attribute key */ case LEX_FUNC_ATTR_KEY: attribute=-1; for(i=0;inattributes;i++) if(buffer_token[0]==tag->attributes[i][0] || tolower(buffer_token[0])==tag->attributes[i][0]) if(!strcasecmp((char*)buffer_token+1,tag->attributes[i]+1)) { attribute=i; break; } if(attribute==-1) { if((options&XMLPARSE_UNKNOWN_ATTRIBUTES)==XMLPARSE_UNKNOWN_ATTR_ERROR || ((options&XMLPARSE_UNKNOWN_ATTRIBUTES)==XMLPARSE_UNKNOWN_ATTR_ERRNONAME && !strchr((char*)buffer_token,':'))) BEGIN(LEX_ERROR_UNEXP_ATT); #ifndef LIBROUTINO else if((options&XMLPARSE_UNKNOWN_ATTRIBUTES)==XMLPARSE_UNKNOWN_ATTR_WARN) ParseXML_SetError("Warning on line %"PRIu64": unexpected attribute '%s' for tag '%s'.",lineno,buffer_token,tag->name); #endif } END_TOKEN; *buffer_ptr=saved_buffer_ptr; BEGIN(next_state); /* An attribute value */ case LEX_FUNC_ATTR_VAL: if(tag->callback && attribute!=-1) attributes[attribute]=buffer_token; END_TOKEN; BEGIN(next_state); /* End of file */ case LEX_EOF: if(tag) BEGIN(LEX_ERROR_UNEXP_EOF); break; /* ================ Error states ================ */ case LEX_ERROR_TAG_START: ParseXML_SetError("Character '<' seen not at start of tag."); break; case LEX_ERROR_XML_DECL_START: ParseXML_SetError("Characters ''.",tag->name); break; case LEX_ERROR_XML_DECL: ParseXML_SetError("Invalid character seen inside XML declaration ''."); break; case LEX_ERROR_ATTR: ParseXML_SetError("Invalid attribute definition seen in tag."); break; case LEX_ERROR_END_TAG: ParseXML_SetError("Invalid character seen in end-tag."); break; case LEX_ERROR_COMMENT: ParseXML_SetError("Invalid comment seen."); break; case LEX_ERROR_CLOSE: ParseXML_SetError("Character '>' seen not at end of tag."); break; case LEX_ERROR_ATTR_VAL: ParseXML_SetError("Invalid character '%c' seen in attribute value.",*buffer_ptr); break; case LEX_ERROR_ENTITY_REF: ParseXML_SetError("Invalid entity reference '%s' seen in attribute value.",buffer_ptr); break; case LEX_ERROR_CHAR_REF: ParseXML_SetError("Invalid character reference '%s' seen in attribute value.",buffer_ptr); break; case LEX_ERROR_TEXT_OUTSIDE: ParseXML_SetError("Non-whitespace '%c' seen outside tag.",*buffer_ptr); break; case LEX_ERROR_UNEXP_TAG: ParseXML_SetError("Unexpected tag '%s'.",buffer_token); break; case LEX_ERROR_UNBALANCED: ParseXML_SetError("End tag '' doesn't match start tag '<%s ...>'.",buffer_token,tag->name); break; case LEX_ERROR_NO_START: ParseXML_SetError("End tag '' seen but there was no start tag '<%s ...>'.",buffer_token,buffer_token); break; case LEX_ERROR_UNEXP_ATT: ParseXML_SetError("Unexpected attribute '%s' for tag '%s'.",buffer_token,tag->name); break; case LEX_ERROR_UNEXP_EOF: ParseXML_SetError("End of file seen without end tag ''.",tag->name); break; case LEX_ERROR_XML_NOT_FIRST: ParseXML_SetError("XML declaration '' not before all other tags."); break; case LEX_ERROR_CALLBACK: /* The error message should have been set by the callback function, have a fallback just in case */ if(!stored_message) ParseXML_SetError("Unknown error from tag callback function."); break; } /* Print the error message */ #ifndef LIBROUTINO if(state) fprintf(stderr,"XML Parser: %s\n",stored_message); #endif /* Delete the tagdata */ if(stackdepth) { free(tag_stack); free(tags_stack); } return(state); } /*++++++++++++++++++++++++++++++++++++++ Return the current parser line number. uint64_t ParseXML_LineNumber Returns the line number. ++++++++++++++++++++++++++++++++++++++*/ uint64_t ParseXML_LineNumber(void) { return(lineno); } /*++++++++++++++++++++++++++++++++++++++ Store an error message for later. const char *format The format string. ... The other arguments. ++++++++++++++++++++++++++++++++++++++*/ void ParseXML_SetError(const char *format, ...) { va_list ap; char temp[2]; int line_length,error_length; line_length=snprintf(temp,1,"Error on line %" PRIu64 ": ",lineno); va_start(ap,format); error_length=vsnprintf(temp,1,format,ap); va_end(ap); if(stored_message) free(stored_message); stored_message=malloc(error_length+line_length+1); line_length=sprintf(stored_message,"Error on line %" PRIu64 ": ",lineno); va_start(ap,format); vsprintf(stored_message+line_length,format,ap); va_end(ap); } /*++++++++++++++++++++++++++++++++++++++ Return a stored error message. char *ParseXML_GetError Returns the most recent stored error. ++++++++++++++++++++++++++++++++++++++*/ char *ParseXML_GetError(void) { return(stored_message); } /*++++++++++++++++++++++++++++++++++++++ Convert an XML entity reference into an ASCII string. char *ParseXML_Decode_Entity_Ref Returns a pointer to the replacement decoded string. const char *string The entity reference string. ++++++++++++++++++++++++++++++++++++++*/ char *ParseXML_Decode_Entity_Ref(const char *string) { if(!strcmp(string,"&")) return("&"); if(!strcmp(string,"<")) return("<"); if(!strcmp(string,">")) return(">"); if(!strcmp(string,"'")) return("'"); if(!strcmp(string,""")) return("\""); return(NULL); } /*++++++++++++++++++++++++++++++++++++++ Convert an XML character reference into an ASCII string. char *ParseXML_Decode_Char_Ref Returns a pointer to the replacement decoded string. const char *string The character reference string. ++++++++++++++++++++++++++++++++++++++*/ char *ParseXML_Decode_Char_Ref(const char *string) { static char result[5]=""; /* static allocation of return value (set each call) */ long int unicode; if(string[2]=='x') unicode=strtol(string+3,NULL,16); else unicode=strtol(string+2,NULL,10); if(unicode<0x80) { /* 0000 0000-0000 007F => 0xxxxxxx */ result[0]=(char)unicode; result[1]=0; } else if(unicode<0x07FF) { /* 0000 0080-0000 07FF => 110xxxxx 10xxxxxx */ result[0]=(char)(0xC0+((unicode&0x07C0)>>6)); result[1]=(char)(0x80+ (unicode&0x003F)); result[2]=0; } else if(unicode<0xFFFF) { /* 0000 0800-0000 FFFF => 1110xxxx 10xxxxxx 10xxxxxx */ result[0]=(char)(0xE0+((unicode&0xF000)>>12)); result[1]=(char)(0x80+((unicode&0x0FC0)>>6)); result[2]=(char)(0x80+ (unicode&0x003F)); result[3]=0; } else if(unicode<0x1FFFFF) { /* 0001 0000-001F FFFF => 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */ result[0]=(char)(0xF0+((unicode&0x1C0000)>>18)); result[1]=(char)(0x80+((unicode&0x03F000)>>12)); result[2]=(char)(0x80+((unicode&0x000FC0)>>6)); result[3]=(char)(0x80+ (unicode&0x00003F)); result[4]=0; } else { result[0]=(char)0xFF; result[1]=(char)0xFD; result[2]=0; } return(result); } /*++++++++++++++++++++++++++++++++++++++ Convert a string into something that is safe to output in an XML file. char *ParseXML_Encode_Safe_XML Returns a pointer to a static replacement encoded string (or the original if no change needed). const char *string The string to convert. ++++++++++++++++++++++++++++++++++++++*/ char *ParseXML_Encode_Safe_XML(const char *string) { static const char hexstring[17]="0123456789ABCDEF"; /* local lookup table */ static char *result=NULL; /* static allocation of return value */ int i=0,j=0,len; for(i=0;string[i];i++) if(string[i]=='<' || string[i]=='>' || string[i]=='&' || string[i]=='\'' || string[i]=='"' || string[i]<32 || (unsigned char)string[i]>127) break; if(!string[i]) return((char*)string); len=i+256-6; result=(char*)realloc((void*)result,len+7); strncpy(result,string,j=i); do { for(;j') { result[j++]='&'; result[j++]='g'; result[j++]='t'; result[j++]=';'; } else if(string[i]>=32 && (unsigned char)string[i]<=127) result[j++]=string[i]; else { unsigned int unicode; /* Decode the UTF-8 */ if((string[i]&0x80)==0) { /* 0000 0000-0000 007F => 0xxxxxxx */ unicode=string[i]; } else if((string[i]&0xE0)==0xC0 && (string[i]&0x1F)>=2 && (string[i+1]&0xC0)==0x80) { /* 0000 0080-0000 07FF => 110xxxxx 10xxxxxx */ unicode =(string[i++]&0x1F)<<6; unicode|= string[i ]&0x3F; } else if((string[i]&0xF0)==0xE0 && (string[i+1]&0xC0)==0x80 && (string[i+2]&0xC0)==0x80) { /* 0000 0800-0000 FFFF => 1110xxxx 10xxxxxx 10xxxxxx */ unicode =(string[i++]&0x0F)<<12; unicode|=(string[i++]&0x3F)<<6; unicode|= string[i ]&0x3F; } else if((string[i]&0xF8)==0xF0 && (string[i+1]&0xC0)==0x80 && (string[i+2]&0xC0)==0x80 && (string[i+3]&0xC0)==0x80) { /* 0001 0000-001F FFFF => 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */ unicode =(string[i++]&0x07)<<18; unicode|=(string[i++]&0x3F)<<12; unicode|=(string[i++]&0x3F)<<6; unicode|= string[i ]&0x3F; } else unicode=0xFFFD; /* Output the character entity */ result[j++]='&'; result[j++]='#'; result[j++]='x'; if(unicode&0x00FF0000) { result[j++]=hexstring[((unicode>>16)&0xf0)>>4]; result[j++]=hexstring[((unicode>>16)&0x0f) ]; } if(unicode&0x00FFFF00) { result[j++]=hexstring[((unicode>>8)&0xf0)>>4]; result[j++]=hexstring[((unicode>>8)&0x0f) ]; } result[j++]=hexstring[(unicode&0xf0)>>4]; result[j++]=hexstring[(unicode&0x0f) ]; result[j++]=';'; } if(string[i]) /* Not finished */ { len+=256; result=(char*)realloc((void*)result,len+7); } } while(string[i]); result[j]=0; return(result); } /*++++++++++++++++++++++++++++++++++++++ Check that a string really is an integer. int ParseXML_IsInteger Returns 1 if an integer could be found or 0 otherwise. const char *string The string to be parsed. ++++++++++++++++++++++++++++++++++++++*/ int ParseXML_IsInteger(const char *string) { const unsigned char *p=(unsigned char*)string; if(*p=='-' || *p=='+') p++; while(digit[(int)*p]) p++; if(*p) return(0); else return(1); } /*++++++++++++++++++++++++++++++++++++++ Check that a string really is a floating point number. int ParseXML_IsFloating Returns 1 if a floating point number could be found or 0 otherwise. const char *string The string to be parsed. ++++++++++++++++++++++++++++++++++++++*/ int ParseXML_IsFloating(const char *string) { const unsigned char *p=(unsigned char*)string; if(*p=='-' || *p=='+') p++; while(digit[(int)*p] || *p=='.') p++; if(*p=='e' || *p=='E') { p++; if(*p=='-' || *p=='+') p++; while(digit[*p]) p++; } if(*p) return(0); else return(1); } /* Table for checking for double-quoted characters. */ static const unsigned char quotedD[256]={ 0, 0, 0, 0, 0, 0, 0, 0, 0,10,10, 0, 0,10, 0, 0, /* 0x00-0x0f " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10-0x1f " " */ 10,10,99,10,10,10,50,10,10,10,10,10,10,10,10,10, /* 0x20-0x2f " !"#$%&'()*+,-./" */ 10,10,10,10,10,10,10,10,10,10,10,10, 0,10, 0,10, /* 0x30-0x3f "0123456789:;<=>?" */ 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, /* 0x40-0x4f "@ABCDEFGHIJKLMNO" */ 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, /* 0x50-0x5f "PQRSTUVWXYZ[\]^_" */ 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, /* 0x60-0x6f "`abcdefghijklmno" */ 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, /* 0x70-0x7f "pqrstuvwxyz{|}~ " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80-0x8f " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90-0x9f " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xa0-0xaf " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xb0-0xbf " " */ 0, 0,20,20,20,20,20,20,20,20,20,20,20,20,20,20, /* 0xc0-0xcf " " */ 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20, /* 0xd0-0xdf " " */ 31,32,32,32,32,32,32,32,32,32,32,32,32,33,34,34, /* 0xe0-0xef " " */ 41,42,42,42,43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* 0xf0-0xff " " */ /* Table for checking for single-quoted characters. */ static const unsigned char quotedS[256]={ 0, 0, 0, 0, 0, 0, 0, 0, 0,10,10, 0, 0,10, 0, 0, /* 0x00-0x0f " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10-0x1f " " */ 10,10,10,10,10,10,50,99,10,10,10,10,10,10,10,10, /* 0x20-0x2f " !"#$%&'()*+,-./" */ 10,10,10,10,10,10,10,10,10,10,10,10, 0,10, 0,10, /* 0x30-0x3f "0123456789:;<=>?" */ 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, /* 0x40-0x4f "@ABCDEFGHIJKLMNO" */ 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, /* 0x50-0x5f "PQRSTUVWXYZ[\]^_" */ 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, /* 0x60-0x6f "`abcdefghijklmno" */ 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, /* 0x70-0x7f "pqrstuvwxyz{|}~ " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80-0x8f " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90-0x9f " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xa0-0xaf " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xb0-0xbf " " */ 0, 0,20,20,20,20,20,20,20,20,20,20,20,20,20,20, /* 0xc0-0xcf " " */ 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20, /* 0xd0-0xdf " " */ 31,32,32,32,32,32,32,32,32,32,32,32,32,33,34,34, /* 0xe0-0xef " " */ 41,42,42,42,43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* 0xf0-0xff " " */ /* Table for checking for characters between 0x80 and 0x8f. */ static const unsigned char U_80_8F[256]={ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00-0x0f " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10-0x1f " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20-0x2f " !"#$%&'()*+,-./" */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x30-0x3f "0123456789:;<=>?" */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x40-0x4f "@ABCDEFGHIJKLMNO" */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x50-0x5f "PQRSTUVWXYZ[\]^_" */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60-0x6f "`abcdefghijklmno" */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70-0x7f "pqrstuvwxyz{|}~ " */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x80-0x8f " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90-0x9f " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xa0-0xaf " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xb0-0xbf " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xc0-0xcf " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xd0-0xdf " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xe0-0xef " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* 0xf0-0xff " " */ /* Table for checking for characters between 0x80 and 0x9f. */ static const unsigned char U_80_9F[256]={ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00-0x0f " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10-0x1f " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20-0x2f " !"#$%&'()*+,-./" */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x30-0x3f "0123456789:;<=>?" */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x40-0x4f "@ABCDEFGHIJKLMNO" */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x50-0x5f "PQRSTUVWXYZ[\]^_" */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60-0x6f "`abcdefghijklmno" */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70-0x7f "pqrstuvwxyz{|}~ " */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x80-0x8f " " */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x90-0x9f " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xa0-0xaf " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xb0-0xbf " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xc0-0xcf " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xd0-0xdf " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xe0-0xef " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* 0xf0-0xff " " */ /* Table for checking for characters between 0x80 and 0xbf. */ static const unsigned char U_80_BF[256]={ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00-0x0f " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10-0x1f " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20-0x2f " !"#$%&'()*+,-./" */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x30-0x3f "0123456789:;<=>?" */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x40-0x4f "@ABCDEFGHIJKLMNO" */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x50-0x5f "PQRSTUVWXYZ[\]^_" */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60-0x6f "`abcdefghijklmno" */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70-0x7f "pqrstuvwxyz{|}~ " */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x80-0x8f " " */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x90-0x9f " " */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0xa0-0xaf " " */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0xb0-0xbf " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xc0-0xcf " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xd0-0xdf " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xe0-0xef " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* 0xf0-0xff " " */ /* Table for checking for characters between 0x90 and 0xbf. */ static const unsigned char U_90_BF[256]={ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00-0x0f " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10-0x1f " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20-0x2f " !"#$%&'()*+,-./" */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x30-0x3f "0123456789:;<=>?" */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x40-0x4f "@ABCDEFGHIJKLMNO" */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x50-0x5f "PQRSTUVWXYZ[\]^_" */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60-0x6f "`abcdefghijklmno" */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70-0x7f "pqrstuvwxyz{|}~ " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80-0x8f " " */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x90-0x9f " " */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0xa0-0xaf " " */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0xb0-0xbf " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xc0-0xcf " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xd0-0xdf " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xe0-0xef " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* 0xf0-0xff " " */ /* Table for checking for characters between 0xa0 and 0xbf. */ static const unsigned char U_A0_BF[256]={ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00-0x0f " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10-0x1f " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20-0x2f " !"#$%&'()*+,-./" */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x30-0x3f "0123456789:;<=>?" */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x40-0x4f "@ABCDEFGHIJKLMNO" */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x50-0x5f "PQRSTUVWXYZ[\]^_" */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60-0x6f "`abcdefghijklmno" */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70-0x7f "pqrstuvwxyz{|}~ " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80-0x8f " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90-0x9f " " */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0xa0-0xaf " " */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0xb0-0xbf " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xc0-0xcf " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xd0-0xdf " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xe0-0xef " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* 0xf0-0xff " " */ /* Table for checking for U2 characters = C2-DF,80-BF = U+0080-U+07FF. */ static const unsigned char *U2[1]={ U_80_BF }; /* Table for checking for U3a characters = E0,A0-BF,80-BF = U+0800-U+0FFF. */ static const unsigned char *U3a[2]={ U_A0_BF, U_80_BF }; /* Table for checking for U3b characters = E1-EC,80-BF,80-BF = U+1000-U+CFFF. */ static const unsigned char *U3b[2]={ U_80_BF, U_80_BF }; /* Table for checking for U3c characters = ED,80-9F,80-BF = U+D000-U+D7FF (U+D800-U+DFFF are not legal in XML). */ static const unsigned char *U3c[2]={ U_80_9F, U_80_BF }; /* Table for checking for U3d characters = EE-EF,80-BF,80-BF = U+E000-U+FFFF (U+FFFE-U+FFFF are not legal in XML but handled). */ static const unsigned char *U3d[2]={ U_80_BF, U_80_BF }; /* Table for checking for U4a characters = F0,90-BF,80-BF,80-BF = U+10000-U+3FFFF. */ static const unsigned char *U4a[3]={ U_90_BF, U_80_BF, U_80_BF }; /* Table for checking for U4b characters = F1-F3,80-BF,80-BF,80-BF = U+40000-U+FFFFF. */ static const unsigned char *U4b[3]={ U_80_BF, U_80_BF, U_80_BF }; /* Table for checking for U4c characters = F4,80-8F,80-BF,80-BF = U+100000-U+10FFFF (U+110000- are not legal in XML). */ static const unsigned char *U4c[3]={ U_80_8F, U_80_BF, U_80_BF }; /* Table for checking for namestart characters. */ static const unsigned char namestart[256]={ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00-0x0f " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10-0x1f " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20-0x2f " !"#$%&'()*+,-./" */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, /* 0x30-0x3f "0123456789:;<=>?" */ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40-0x4f "@ABCDEFGHIJKLMNO" */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 0x50-0x5f "PQRSTUVWXYZ[\]^_" */ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60-0x6f "`abcdefghijklmno" */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 0x70-0x7f "pqrstuvwxyz{|}~ " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80-0x8f " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90-0x9f " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xa0-0xaf " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xb0-0xbf " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xc0-0xcf " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xd0-0xdf " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xe0-0xef " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* 0xf0-0xff " " */ /* Table for checking for namechar characters. */ static const unsigned char namechar[256] ={ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00-0x0f " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10-0x1f " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, /* 0x20-0x2f " !"#$%&'()*+,-./" */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 0x30-0x3f "0123456789:;<=>?" */ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40-0x4f "@ABCDEFGHIJKLMNO" */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 0x50-0x5f "PQRSTUVWXYZ[\]^_" */ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60-0x6f "`abcdefghijklmno" */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 0x70-0x7f "pqrstuvwxyz{|}~ " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80-0x8f " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90-0x9f " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xa0-0xaf " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xb0-0xbf " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xc0-0xcf " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xd0-0xdf " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xe0-0xef " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* 0xf0-0xff " " */ /* Table for checking for whitespace characters. */ static const unsigned char whitespace[256]={ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, /* 0x00-0x0f " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10-0x1f " " */ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20-0x2f " !"#$%&'()*+,-./" */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x30-0x3f "0123456789:;<=>?" */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x40-0x4f "@ABCDEFGHIJKLMNO" */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x50-0x5f "PQRSTUVWXYZ[\]^_" */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60-0x6f "`abcdefghijklmno" */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70-0x7f "pqrstuvwxyz{|}~ " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80-0x8f " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90-0x9f " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xa0-0xaf " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xb0-0xbf " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xc0-0xcf " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xd0-0xdf " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xe0-0xef " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* 0xf0-0xff " " */ /* Table for checking for digit characters. */ static const unsigned char digit[256]={ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00-0x0f " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10-0x1f " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20-0x2f " !"#$%&'()*+,-./" */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 0x30-0x3f "0123456789:;<=>?" */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x40-0x4f "@ABCDEFGHIJKLMNO" */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x50-0x5f "PQRSTUVWXYZ[\]^_" */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60-0x6f "`abcdefghijklmno" */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70-0x7f "pqrstuvwxyz{|}~ " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80-0x8f " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90-0x9f " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xa0-0xaf " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xb0-0xbf " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xc0-0xcf " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xd0-0xdf " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xe0-0xef " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* 0xf0-0xff " " */ /* Table for checking for xdigit characters. */ static const unsigned char xdigit[256]={ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00-0x0f " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10-0x1f " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20-0x2f " !"#$%&'()*+,-./" */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 0x30-0x3f "0123456789:;<=>?" */ 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x40-0x4f "@ABCDEFGHIJKLMNO" */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x50-0x5f "PQRSTUVWXYZ[\]^_" */ 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60-0x6f "`abcdefghijklmno" */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70-0x7f "pqrstuvwxyz{|}~ " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80-0x8f " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90-0x9f " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xa0-0xaf " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xb0-0xbf " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xc0-0xcf " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xd0-0xdf " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xe0-0xef " " */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* 0xf0-0xff " " */ routino-3.0/src/filedumperx.c 644 233 144 22356 12574074473 11547 0/*************************************** Memory file dumper for the intermediate files containing parsed data. Part of the Routino routing software. ******************/ /****************** This file Copyright 2008-2015 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #include #include #include #include #include "version.h" #include "typesx.h" #include "nodesx.h" #include "waysx.h" #include "relationsx.h" #include "files.h" #include "sorting.h" /* Local functions */ static void print_nodes(const char *filename); static void print_ways(const char *filename); static void print_route_relations(const char *filename); static void print_turn_relations(const char *filename); static void print_usage(int detail,const char *argerr,const char *err); /*++++++++++++++++++++++++++++++++++++++ The main program for the file dumper. ++++++++++++++++++++++++++++++++++++++*/ int main(int argc,char** argv) { int arg; char *dirname=NULL,*prefix=NULL; char *nodes_filename,*ways_filename,*route_relations_filename,*turn_relations_filename; int option_dump; /* Parse the command line arguments */ for(arg=1;arg=0) { fprintf(stderr, "Usage: filedumperx [--version]\n" " [--help]\n" " [--dir=] [--prefix=]\n" " [--dump [--nodes]\n" " [--ways]\n" " [--route-relations]\n" " [--turn-relations]]\n"); if(argerr) fprintf(stderr, "\n" "Error with command line parameter: %s\n",argerr); if(err) fprintf(stderr, "\n" "Error: %s\n",err); } if(detail==1) fprintf(stderr, "\n" "--version Print the version of Routino.\n" "\n" "--help Prints this information.\n" "\n" "--dir= The directory containing the routing database.\n" "--prefix= The filename prefix for the routing database.\n" "\n" "--dump Dump the intermediate files after parsing.\n" " --nodes * all of the nodes.\n" " --ways * all of the ways.\n" " --route-relations * all of the route relations.\n" " --turn-relations * all of the turn relations.\n"); exit(!detail); } routino-3.0/src/results.c 644 233 144 16673 12563633052 10721 0/*************************************** Result data type functions. Part of the Routino routing software. ******************/ /****************** This file Copyright 2008-2015 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #include #include #include "results.h" #include "logging.h" #define HASH_NODE_SEGMENT(node,segment) ((node)^(segment<<4)) /*++++++++++++++++++++++++++++++++++++++ Allocate a new results list. Results *NewResultsList Returns the results list. uint8_t log2bins The base 2 logarithm of the initial number of bins in the results array. ++++++++++++++++++++++++++++++++++++++*/ Results *NewResultsList(uint8_t log2bins) { Results *results; results=(Results*)malloc(sizeof(Results)); results->nbins=1<mask=results->nbins-1; results->ncollisions=log2bins-4; results->number=0; results->count=(uint8_t*)calloc(results->nbins,sizeof(uint8_t)); results->point=(Result**)calloc(results->nbins,sizeof(Result*)); #ifndef LIBROUTINO log_malloc(results->count,results->nbins*sizeof(uint8_t)); log_malloc(results->point,results->nbins*sizeof(Result*)); #endif results->ndata1=0; results->nallocdata1=0; results->ndata2=results->nbins>>2; results->data=NULL; results->start_node=NO_NODE; results->prev_segment=NO_SEGMENT; results->finish_node=NO_NODE; results->last_segment=NO_SEGMENT; results->start_waypoint=NO_WAYPOINT; results->finish_waypoint=NO_WAYPOINT; return(results); } /*++++++++++++++++++++++++++++++++++++++ Allocate a new results list. Results *results The results list to be reset. ++++++++++++++++++++++++++++++++++++++*/ void ResetResultsList(Results *results) { uint32_t i; results->number=0; results->ndata1=0; for(i=0;inbins;i++) { results->point[i]=NULL; results->count[i]=0; } results->start_node=NO_NODE; results->prev_segment=NO_SEGMENT; results->finish_node=NO_NODE; results->last_segment=NO_SEGMENT; } /*++++++++++++++++++++++++++++++++++++++ Free a results list. Results *results The results list to be destroyed. ++++++++++++++++++++++++++++++++++++++*/ void FreeResultsList(Results *results) { uint32_t i; for(i=0;inallocdata1;i++) { #ifndef LIBROUTINO log_free(results->data[i]); #endif free(results->data[i]); } free(results->data); #ifndef LIBROUTINO log_free(results->point); #endif free(results->point); #ifndef LIBROUTINO log_free(results->count); #endif free(results->count); free(results); } /*++++++++++++++++++++++++++++++++++++++ Insert a new result into the results data structure in the right order. Result *InsertResult Returns the result that has been inserted. Results *results The results structure to insert into. index_t node The node that is to be inserted into the results. index_t segment The segment that is to be inserted into the results. ++++++++++++++++++++++++++++++++++++++*/ Result *InsertResult(Results *results,index_t node,index_t segment) { Result *result; uint32_t bin=HASH_NODE_SEGMENT(node,segment)&results->mask; /* Check if we have hit the limit on the number of collisions per bin */ if(results->count[bin]==results->ncollisions) { uint32_t i; results->nbins<<=1; results->mask=results->nbins-1; results->ncollisions++; results->count=(uint8_t*)realloc((void*)results->count,results->nbins*sizeof(uint8_t)); results->point=(Result**)realloc((void*)results->point,results->nbins*sizeof(Result*)); #ifndef LIBROUTINO log_malloc(results->count,results->nbins*sizeof(uint8_t)); log_malloc(results->point,results->nbins*sizeof(Result*)); #endif for(i=0;inbins/2;i++) { Result *r=results->point[i]; Result **bin1,**bin2; results->count[i] =0; results->count[i+results->nbins/2]=0; bin1=&results->point[i]; bin2=&results->point[i+results->nbins/2]; *bin1=NULL; *bin2=NULL; while(r) { Result *rh=r->hashnext; uint32_t newbin=HASH_NODE_SEGMENT(r->node,r->segment)&results->mask; r->hashnext=NULL; if(newbin==i) { *bin1=r; bin1=&r->hashnext; } else { *bin2=r; bin2=&r->hashnext; } results->count[newbin]++; r=rh; } } bin=HASH_NODE_SEGMENT(node,segment)&results->mask; } /* Check if we need more data space allocated */ if((results->number%results->ndata2)==0) { results->ndata1++; if(results->ndata1>=results->nallocdata1) { results->nallocdata1++; results->data=(Result**)realloc((void*)results->data,results->nallocdata1*sizeof(Result*)); results->data[results->nallocdata1-1]=(Result*)malloc(results->ndata2*sizeof(Result)); #ifndef LIBROUTINO log_malloc(results->data[results->nallocdata1-1],results->ndata2*sizeof(Result)); #endif } } /* Insert the new entry */ result=&results->data[results->ndata1-1][results->number%results->ndata2]; result->hashnext=results->point[bin]; results->point[bin]=result; results->count[bin]++; results->number++; /* Initialise the result */ result->node=node; result->segment=segment; result->prev=NULL; result->next=NULL; result->score=0; result->sortby=0; result->queued=NOT_QUEUED; return(result); } /*++++++++++++++++++++++++++++++++++++++ Find a result; search by node and segment. Result *FindResult Returns the result that has been found. Results *results The results structure to search. index_t node The node that is to be found. index_t segment The segment that was used to reach this node. ++++++++++++++++++++++++++++++++++++++*/ Result *FindResult(Results *results,index_t node,index_t segment) { Result *r; uint32_t bin=HASH_NODE_SEGMENT(node,segment)&results->mask; r=results->point[bin]; while(r) { if(r->segment==segment && r->node==node) break; r=r->hashnext; } return(r); } /*++++++++++++++++++++++++++++++++++++++ Find the first result from a set of results. Result *FirstResult Returns the first result. Results *results The set of results. ++++++++++++++++++++++++++++++++++++++*/ Result *FirstResult(Results *results) { return(&results->data[0][0]); } /*++++++++++++++++++++++++++++++++++++++ Find the next result from a set of results. Result *NextResult Returns the next result. Results *results The set of results. Result *result The previous result. ++++++++++++++++++++++++++++++++++++++*/ Result *NextResult(Results *results,Result *result) { uint32_t i; size_t j=0; for(i=0;indata1;i++) if(result>=results->data[i]) { j=result-results->data[i]; if(jndata2) break; } if(++j>=results->ndata2) {i++;j=0;} if((i*results->ndata2+j)>=results->number) return(NULL); return(&results->data[i][j]); } routino-3.0/src/logging.c 644 233 144 32423 12531126220 10622 0/*************************************** Functions to handle logging functions. Part of the Routino routing software. ******************/ /****************** This file Copyright 2008-2015 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #include #include #include #include #include #if defined(_MSC_VER) #include #include static const uint64_t EPOCH = ((uint64_t) 116444736000000000ULL); int gettimeofday(struct timeval * tp, struct timezone * tzp) { FILETIME file_time; SYSTEMTIME system_time; ULARGE_INTEGER ularge; GetSystemTime(&system_time); SystemTimeToFileTime(&system_time, &file_time); ularge.LowPart = file_time.dwLowDateTime; ularge.HighPart = file_time.dwHighDateTime; tp->tv_sec = (long) ((ularge.QuadPart - EPOCH) / 10000000L); tp->tv_usec = (long) (system_time.wMilliseconds * 1000); return 0; } #else #include #endif #include "logging.h" /* Global variables */ /*+ The option to print the output in a way that allows logging to a file. +*/ int option_loggable=0; /*+ The option to print elapsed time with the output. +*/ int option_logtime=0; /*+ The option to print memory usage with the output. +*/ int option_logmemory=0; /* Local data types */ /*+ A structure to contain the list of allocated memory. +*/ struct mallocinfo { void *address; /*+ The address of the allocated memory. +*/ size_t size; /*+ The size of the allocated memory. +*/ }; /* Local functions */ static void vfprintf_first(FILE *file,const char *format,va_list ap); static void vfprintf_middle(FILE *file,const char *format,va_list ap); static void vfprintf_last(FILE *file,const char *format,va_list ap); static void fprintf_elapsed_time(FILE *file,struct timeval *start); static void fprintf_max_memory(FILE *file,size_t max_alloc,size_t max_mmap); /* Local variables */ /*+ The time that program_start() was called. +*/ static struct timeval program_start_time; /*+ The time that printf_first() was called. +*/ static struct timeval function_start_time; /*+ The list of allocated memory. +*/ static struct mallocinfo *mallocedmem; /*+ The number of allocated memory blocks. +*/ static int nmallocedmem=0; /*+ The length of the string printed out last time. +*/ static int printed_length=0; /*+ The maximum amount of memory allocated and memory mapped since starting the program. +*/ static size_t program_max_alloc=0,program_max_mmap=0; /*+ The maximum amount of memory allocated and memory mapped since starting the function. +*/ static size_t function_max_alloc=0,function_max_mmap=0; /*+ The current amount of memory allocated and memory mapped. +*/ static size_t current_alloc=0,current_mmap=0; /*++++++++++++++++++++++++++++++++++++++ Record the time that the program started. ++++++++++++++++++++++++++++++++++++++*/ void printf_program_start(void) { gettimeofday(&program_start_time,NULL); program_max_alloc=program_max_mmap=0; } /*++++++++++++++++++++++++++++++++++++++ Record the time that the program started. ++++++++++++++++++++++++++++++++++++++*/ void printf_program_end(void) { if(option_logtime || option_logmemory) { if(option_logtime) fprintf_elapsed_time(stdout,&program_start_time); if(option_logmemory) fprintf_max_memory(stdout,program_max_alloc,program_max_mmap); printf("Finish Program\n"); if(option_logtime==2) printf("[ m:ss.micros] "); else if(option_logtime==1) printf("[ m:ss.mil] "); if(option_logmemory) printf("[RAM,FILE MB] "); if(option_logtime) printf("elapsed time"); if(option_logmemory) { if(option_logtime) printf(", "); printf("maximum memory"); } printf("\n"); fflush(stdout); } } /*++++++++++++++++++++++++++++++++++++++ Print the first message in an overwriting sequence (to stdout). const char *format The format string. ... The other arguments. ++++++++++++++++++++++++++++++++++++++*/ void printf_first(const char *format, ...) { va_list ap; if(option_logtime) gettimeofday(&function_start_time,NULL); if(option_logmemory) { function_max_alloc=current_alloc; function_max_mmap=current_mmap; } if(option_loggable) return; va_start(ap,format); vfprintf_first(stdout,format,ap); va_end(ap); } /*++++++++++++++++++++++++++++++++++++++ Print the middle message in an overwriting sequence (to stdout). const char *format The format string. ... The other arguments. ++++++++++++++++++++++++++++++++++++++*/ void printf_middle(const char *format, ...) { va_list ap; if(option_loggable) return; va_start(ap,format); vfprintf_middle(stdout,format,ap); va_end(ap); } /*++++++++++++++++++++++++++++++++++++++ Print the last message in an overwriting sequence (to stdout). const char *format The format string. ... The other arguments. ++++++++++++++++++++++++++++++++++++++*/ void printf_last(const char *format, ...) { va_list ap; va_start(ap,format); vfprintf_last(stdout,format,ap); va_end(ap); } /*++++++++++++++++++++++++++++++++++++++ Print the first message in an overwriting sequence to a specified file. FILE *file The file to write to. const char *format The format string. ... The other arguments. ++++++++++++++++++++++++++++++++++++++*/ void fprintf_first(FILE *file,const char *format, ...) { va_list ap; if(option_logtime) gettimeofday(&function_start_time,NULL); if(option_logmemory) { function_max_alloc=current_alloc; function_max_mmap=current_mmap; } if(option_loggable) return; va_start(ap,format); vfprintf_first(file,format,ap); va_end(ap); } /*++++++++++++++++++++++++++++++++++++++ Print the middle message in an overwriting sequence to a specified file. FILE *file The file to write to. const char *format The format string. ... The other arguments. ++++++++++++++++++++++++++++++++++++++*/ void fprintf_middle(FILE *file,const char *format, ...) { va_list ap; if(option_loggable) return; va_start(ap,format); vfprintf_middle(file,format,ap); va_end(ap); } /*++++++++++++++++++++++++++++++++++++++ Print the last message in an overwriting sequence to a specified file. FILE *file The file to write to. const char *format The format string. ... The other arguments. ++++++++++++++++++++++++++++++++++++++*/ void fprintf_last(FILE *file,const char *format, ...) { va_list ap; va_start(ap,format); vfprintf_last(file,format,ap); va_end(ap); } /*++++++++++++++++++++++++++++++++++++++ Record the memory allocations (record the amount in use). void *address The address that has been allocated. size_t size The size of the memory that has been allocated. ++++++++++++++++++++++++++++++++++++++*/ void log_malloc(void *address,size_t size) { int i; if(!option_logmemory) return; /* Store the information about the allocated memory */ for(i=0;ifunction_max_alloc) function_max_alloc=current_alloc; if(current_alloc>program_max_alloc) program_max_alloc=current_alloc; } /*++++++++++++++++++++++++++++++++++++++ Record the memory de-allocations. void *address The address that has been freed. ++++++++++++++++++++++++++++++++++++++*/ void log_free(void *address) { size_t size=0; int i; if(!option_logmemory) return; /* Remove the information about the allocated memory */ for(i=0;ii) memmove(&mallocedmem[i],&mallocedmem[i+1],(nmallocedmem-i)*sizeof(struct mallocinfo)); /* Reduce the sum of allocated memory */ current_alloc-=size; } /*++++++++++++++++++++++++++++++++++++++ Record the amount of memory that has been mapped into files. size_t size The size of the file that has been mapped. ++++++++++++++++++++++++++++++++++++++*/ void log_mmap(size_t size) { if(!option_logmemory) return; current_mmap+=size; if(current_mmap>function_max_mmap) function_max_mmap=current_mmap; if(current_mmap>program_max_mmap) program_max_mmap=current_mmap; } /*++++++++++++++++++++++++++++++++++++++ Record the amount of memory that has been unmapped from files. size_t size The size of the file that has been unmapped. ++++++++++++++++++++++++++++++++++++++*/ void log_munmap(size_t size) { if(!option_logmemory) return; current_mmap-=size; } /*++++++++++++++++++++++++++++++++++++++ Do the work to print the first message in an overwriting sequence. FILE *file The file to write to. const char *format The format string. va_list ap The other arguments. ++++++++++++++++++++++++++++++++++++++*/ static void vfprintf_first(FILE *file,const char *format,va_list ap) { int retval; if(option_logtime) fprintf_elapsed_time(file,&function_start_time); if(option_logmemory) fprintf_max_memory(file,function_max_alloc,function_max_mmap); retval=vfprintf(file,format,ap); fflush(file); if(retval>0) printed_length=retval; } /*++++++++++++++++++++++++++++++++++++++ Do the work to print the middle message in an overwriting sequence. FILE *file The file to write to. const char *format The format string. va_list ap The other arguments. ++++++++++++++++++++++++++++++++++++++*/ static void vfprintf_middle(FILE *file,const char *format,va_list ap) { int retval; fputc('\r',file); if(option_logtime) fprintf_elapsed_time(file,&function_start_time); if(option_logmemory) fprintf_max_memory(file,function_max_alloc,function_max_mmap); retval=vfprintf(file,format,ap); fflush(file); if(retval>0) { int new_printed_length=retval; while(retval++0) while(retval++tv_sec; elapsed.tv_usec=finish.tv_usec-start->tv_usec; if(elapsed.tv_usec<0) { elapsed.tv_sec -=1; elapsed.tv_usec+=1000000; } if(option_logtime==2) fprintf(file,"[%2ld:%02ld.%06ld] ",elapsed.tv_sec/60,elapsed.tv_sec%60,elapsed.tv_usec); else fprintf(file,"[%2ld:%02ld.%03ld] ",elapsed.tv_sec/60,elapsed.tv_sec%60,elapsed.tv_usec/1000); } /*++++++++++++++++++++++++++++++++++++++ Print the maximum used memory without a following newline. FILE *file The file to print to. size_t max_alloc The maximum amount of allocated memory. size_t max_mmap The maximum amount of memory mapped memory. ++++++++++++++++++++++++++++++++++++++*/ static void fprintf_max_memory(FILE *file,size_t max_alloc,size_t max_mmap) { fprintf(file,"[%3zu, %3zu MB] ",max_alloc/(1024*1024),max_mmap/(1024*1024)); } /*++++++++++++++++++++++++++++++++++++++ Log a fatal error and exit const char *message The error message. const char *file The file in which the error occured. int line The line number in the file at which the error occured. ++++++++++++++++++++++++++++++++++++++*/ void _logassert(const char *message,const char *file,int line) { fprintf(stderr,"Routino Fatal Error (%s:%d): %s\n",file,line,message); exit(EXIT_FAILURE); } routino-3.0/src/cache.h 644 233 144 21730 12550223461 10251 0/*************************************** Functions to maintain an in-RAM cache of on-disk data for slim mode. Part of the Routino routing software. ******************/ /****************** This file Copyright 2013-2015 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #if SLIM #ifndef CACHE_H #define CACHE_H /*+ To stop multiple inclusions. +*/ #include #include "types.h" /* Macros for constants */ #define CACHEWIDTH 8192 /*+ The width of the cache. +*/ #define CACHEDEPTH 16 /*+ The depth of the cache. +*/ /* Macro for structure forward declaration */ #define CACHE_STRUCTURE_FWD(type) typedef struct _##type##Cache type##Cache; /* Macro for structure declaration */ /*+ A macro to create a cache structure. +*/ #define CACHE_STRUCTURE(type) \ \ struct _##type##Cache \ { \ int first [CACHEWIDTH]; /*+ The first entry to fill +*/ \ \ type data [CACHEWIDTH][CACHEDEPTH]; /*+ The array of type##s. +*/ \ index_t indices[CACHEWIDTH][CACHEDEPTH]; /*+ The array of indexes. +*/ \ }; /* Macros for function prototypes */ #define CACHE_NEWCACHE_PROTO(type) static inline type##Cache *New##type##Cache(void); #define CACHE_DELETECACHE_PROTO(type) static inline void Delete##type##Cache(type##Cache *cache); #define CACHE_FETCHCACHE_PROTO(type) static inline type *FetchCached##type(type##Cache *cache,index_t index,int fd,offset_t offset); #define CACHE_REPLACECACHE_PROTO(type) static inline void ReplaceCached##type(type##Cache *cache,type *value,index_t index,int fd,offset_t offset); #define CACHE_INVALIDATECACHE_PROTO(type) static inline void Invalidate##type##Cache(type##Cache *cache); /* Macros for function definitions */ /*+ A macro to create a function that creates a new cache data structure. +*/ #define CACHE_NEWCACHE(type) \ \ static inline type##Cache *New##type##Cache(void) \ { \ type##Cache *cache; \ \ cache=(type##Cache*)malloc(sizeof(type##Cache)); \ \ Invalidate##type##Cache(cache); \ \ return(cache); \ } /*+ A macro to create a function that deletes a cache data structure. +*/ #define CACHE_DELETECACHE(type) \ \ static inline void Delete##type##Cache(type##Cache *cache) \ { \ free(cache); \ } /*+ A macro to create a function that fetches an item from a cache data structure or reads from file. +*/ #define CACHE_FETCHCACHE(type) \ \ static inline type *FetchCached##type(type##Cache *cache,index_t index,int fd,offset_t offset) \ { \ int row=index%CACHEWIDTH; \ int col; \ \ for(col=0;colindices[row][col]==index) \ return(&cache->data[row][col]); \ \ col=cache->first[row]; \ \ cache->first[row]=(cache->first[row]+1)%CACHEDEPTH; \ \ SlimFetch(fd,&cache->data[row][col],sizeof(type),offset+(offset_t)index*sizeof(type)); \ \ cache->indices[row][col]=index; \ \ return(&cache->data[row][col]); \ } /*+ A macro to create a function that replaces an item in a cache data structure and writes to file. +*/ #define CACHE_REPLACECACHE(type) \ \ static inline void ReplaceCached##type(type##Cache *cache,type *value,index_t index,int fd,offset_t offset) \ { \ int row=index%CACHEWIDTH; \ int col; \ \ for(col=0;colindices[row][col]==index) \ break; \ \ if(col==CACHEDEPTH) \ { \ col=cache->first[row]; \ \ cache->first[row]=(cache->first[row]+1)%CACHEDEPTH; \ } \ \ cache->indices[row][col]=index; \ \ cache->data[row][col]=*value; \ \ SlimReplace(fd,&cache->data[row][col],sizeof(type),offset+(offset_t)index*sizeof(type)); \ } /*+ A macro to create a function that invalidates the contents of a cache data structure. +*/ #define CACHE_INVALIDATECACHE(type) \ \ static inline void Invalidate##type##Cache(type##Cache *cache) \ { \ int row,col; \ \ for(row=0;rowfirst[row]=0; \ \ for(col=0;colindices[row][col]=NO_NODE; \ } \ } /*+ Cache data structure forward declarations (for planetsplitter). +*/ CACHE_STRUCTURE_FWD(NodeX) CACHE_STRUCTURE_FWD(SegmentX) CACHE_STRUCTURE_FWD(WayX) /*+ Cache data structure forward declarations (for router). +*/ CACHE_STRUCTURE_FWD(Node) CACHE_STRUCTURE_FWD(Segment) CACHE_STRUCTURE_FWD(Way) CACHE_STRUCTURE_FWD(TurnRelation) #endif /* CACHE_H */ #endif /* SLIM */ routino-3.0/src/prunex.c 644 233 144 124362 12420524666 10556 0/*************************************** Data pruning functions. Part of the Routino routing software. ******************/ /****************** This file Copyright 2011-2014 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #include #include "types.h" #include "segments.h" #include "typesx.h" #include "nodesx.h" #include "segmentsx.h" #include "waysx.h" #include "prunex.h" #include "files.h" #include "logging.h" /* Global variables */ /*+ The command line '--tmpdir' option or its default value. +*/ extern char *option_tmpdirname; /* Local functions */ static void prune_segment(SegmentsX *segmentsx,SegmentX *segmentx); static void modify_segment(SegmentsX *segmentsx,SegmentX *segmentx,index_t newnode1,index_t newnode2); static void unlink_segment_node1_refs(SegmentsX *segmentsx,SegmentX *segmentx); static void unlink_segment_node2_refs(SegmentsX *segmentsx,SegmentX *segmentx); static double distance(double lat1,double lon1,double lat2,double lon2); /*++++++++++++++++++++++++++++++++++++++ Initialise the data structures needed for pruning. NodesX *nodesx The set of nodes to use. SegmentsX *segmentsx The set of segments to use. WaysX *waysx The set of ways to use. ++++++++++++++++++++++++++++++++++++++*/ void StartPruning(NodesX *nodesx,SegmentsX *segmentsx,WaysX *waysx) { SegmentX segmentx; index_t index=0,lastnode1=NO_NODE; if(segmentsx->number==0) return; /* Print the start message */ printf_first("Adding Extra Segment Indexes: Segments=0"); /* Allocate the array of next segment */ segmentsx->next1=(index_t*)calloc(segmentsx->number,sizeof(index_t)); log_malloc(segmentsx->next1,segmentsx->number*sizeof(index_t)); logassert(segmentsx->next1,"Failed to allocate memory (try using slim mode?)"); /* Check calloc() worked */ /* Open the file read-only */ segmentsx->fd=ReOpenFileBuffered(segmentsx->filename_tmp); /* Read the on-disk image */ while(!ReadFileBuffered(segmentsx->fd,&segmentx,sizeof(SegmentX))) { index_t node1=segmentx.node1; if(index==0) ; else if(lastnode1==node1) segmentsx->next1[index-1]=index; else segmentsx->next1[index-1]=NO_SEGMENT; lastnode1=node1; index++; if(!(index%10000)) printf_middle("Added Extra Segment Indexes: Segments=%"Pindex_t,index); } segmentsx->next1[index-1]=NO_SEGMENT; /* Close the file */ segmentsx->fd=CloseFileBuffered(segmentsx->fd); /* Print the final message */ printf_last("Added Extra Segment Indexes: Segments=%"Pindex_t,segmentsx->number); } /*++++++++++++++++++++++++++++++++++++++ Delete the data structures needed for pruning. NodesX *nodesx The set of nodes to use. SegmentsX *segmentsx The set of segments to use. WaysX *waysx The set of ways to use. ++++++++++++++++++++++++++++++++++++++*/ void FinishPruning(NodesX *nodesx,SegmentsX *segmentsx,WaysX *waysx) { if(segmentsx->next1) { log_free(segmentsx->next1); free(segmentsx->next1); segmentsx->next1=NULL; } } /*++++++++++++++++++++++++++++++++++++++ Prune out any groups of nodes and segments whose total length is less than a specified minimum. NodesX *nodesx The set of nodes to use. SegmentsX *segmentsx The set of segments to use. WaysX *waysx The set of ways to use. distance_t minimum The minimum distance to keep. ++++++++++++++++++++++++++++++++++++++*/ void PruneIsolatedRegions(NodesX *nodesx,SegmentsX *segmentsx,WaysX *waysx,distance_t minimum) { WaysX *newwaysx; WayX tmpwayx; transport_t transport; BitMask *connected,*region; index_t *regionsegments,*othersegments; index_t nallocregionsegments,nallocothersegments; if(nodesx->number==0 || segmentsx->number==0) return; /* Map into memory / open the files */ #if !SLIM nodesx->data=MapFile(nodesx->filename_tmp); segmentsx->data=MapFileWriteable(segmentsx->filename_tmp); waysx->data=MapFile(waysx->filename_tmp); #else nodesx->fd=SlimMapFile(nodesx->filename_tmp); segmentsx->fd=SlimMapFileWriteable(segmentsx->filename_tmp); waysx->fd=SlimMapFile(waysx->filename_tmp); InvalidateNodeXCache(nodesx->cache); InvalidateSegmentXCache(segmentsx->cache); InvalidateWayXCache(waysx->cache); #endif newwaysx=NewWayList(0,0); CloseFileBuffered(newwaysx->fd); newwaysx->fd=SlimMapFileWriteable(newwaysx->filename_tmp); connected=AllocBitMask(segmentsx->number); region =AllocBitMask(segmentsx->number); log_malloc(connected,LengthBitMask(segmentsx->number)*sizeof(BitMask)); log_malloc(region ,LengthBitMask(segmentsx->number)*sizeof(BitMask)); logassert(connected,"Failed to allocate memory (try using slim mode?)"); /* Check AllocBitMask() worked */ logassert(region ,"Failed to allocate memory (try using slim mode?)"); /* Check AllocBitMask() worked */ regionsegments=(index_t*)malloc((nallocregionsegments=1024)*sizeof(index_t)); othersegments =(index_t*)malloc((nallocothersegments =1024)*sizeof(index_t)); logassert(regionsegments,"Failed to allocate memory (try using slim mode?)"); /* Check malloc() worked */ logassert(othersegments ,"Failed to allocate memory (try using slim mode?)"); /* Check malloc() worked */ /* Loop through the transport types */ for(transport=Transport_None+1;transportallow&transports)) continue; /* Print the start message */ printf_first("Pruning Isolated Regions (%s): Segments=0 Adjusted=0 Pruned=0",transport_str); /* Loop through the segments and find the disconnected ones */ ClearAllBits(connected,segmentsx->number); ClearAllBits(region ,segmentsx->number); for(i=0;inumber;i++) { index_t nregionsegments=0,nothersegments=0; distance_t total=0; SegmentX *segmentx; WayX *wayx; if(IsBitSet(connected,i)) goto endloop; segmentx=LookupSegmentX(segmentsx,i,1); if(IsPrunedSegmentX(segmentx)) goto endloop; if(segmentx->waynumber) wayx=LookupWayX(waysx,segmentx->way,1); else SlimFetch(newwaysx->fd,(wayx=&tmpwayx),sizeof(WayX),(segmentx->way-waysx->number)*sizeof(WayX)); if(!(wayx->way.allow&transports)) goto endloop; othersegments[nothersegments++]=i; SetBit(region,i); do { index_t thissegment,nodes[2]; thissegment=othersegments[--nothersegments]; if(nregionsegments==nallocregionsegments) regionsegments=(index_t*)realloc(regionsegments,(nallocregionsegments+=1024)*sizeof(index_t)); regionsegments[nregionsegments++]=thissegment; segmentx=LookupSegmentX(segmentsx,thissegment,1); nodes[0]=segmentx->node1; nodes[1]=segmentx->node2; total+=DISTANCE(segmentx->distance); for(j=0;j<2;j++) { NodeX *nodex=LookupNodeX(nodesx,nodes[j],1); if(!(nodex->allow&transports)) continue; segmentx=FirstSegmentX(segmentsx,nodes[j],1); while(segmentx) { index_t segment=IndexSegmentX(segmentsx,segmentx); if(segment!=thissegment) { if(segmentx->waynumber) wayx=LookupWayX(waysx,segmentx->way,1); else SlimFetch(newwaysx->fd,(wayx=&tmpwayx),sizeof(WayX),(segmentx->way-waysx->number)*sizeof(WayX)); if(wayx->way.allow&transports) { /* Already connected - finish */ if(IsBitSet(connected,segment)) { total=minimum; goto foundconnection; } /* Not in region - add to list */ if(!IsBitSet(region,segment)) { if(nothersegments==nallocothersegments) othersegments=(index_t*)realloc(othersegments,(nallocothersegments+=1024)*sizeof(index_t)); othersegments[nothersegments++]=segment; SetBit(region,segment); } } } segmentx=NextSegmentX(segmentsx,segmentx,nodes[j]); } } } while(nothersegments>0 && totalwaynumber) wayx=LookupWayX(waysx,segmentx->way,1); else SlimFetch(newwaysx->fd,(wayx=&tmpwayx),sizeof(WayX),(segmentx->way-waysx->number)*sizeof(WayX)); if(wayx->way.allow==transports) { prune_segment(segmentsx,segmentx); npruned++; } else { if(segmentx->waynumber) /* create a new way */ { tmpwayx=*wayx; tmpwayx.way.allow&=~transports; segmentx->way=waysx->number+newwaysx->number; SlimReplace(newwaysx->fd,&tmpwayx,sizeof(WayX),(segmentx->way-waysx->number)*sizeof(WayX)); newwaysx->number++; PutBackSegmentX(segmentsx,segmentx); } else /* modify the existing one */ { tmpwayx.way.allow&=~transports; SlimReplace(newwaysx->fd,&tmpwayx,sizeof(WayX),(segmentx->way-waysx->number)*sizeof(WayX)); } nadjusted++; } } } else /* connected - mark as part of the main region */ { for(j=0;jnumber,nadjusted,npruned,nregions); } /* Unmap from memory / close the files */ log_free(region); log_free(connected); free(region); free(connected); free(regionsegments); free(othersegments); #if !SLIM nodesx->data=UnmapFile(nodesx->data); segmentsx->data=UnmapFile(segmentsx->data); waysx->data=UnmapFile(waysx->data); #else nodesx->fd=SlimUnmapFile(nodesx->fd); segmentsx->fd=SlimUnmapFile(segmentsx->fd); waysx->fd=SlimUnmapFile(waysx->fd); #endif SlimUnmapFile(newwaysx->fd); waysx->number+=newwaysx->number; waysx->fd=OpenFileBufferedAppend(waysx->filename_tmp); newwaysx->fd=ReOpenFileBuffered(newwaysx->filename_tmp); while(!ReadFileBuffered(newwaysx->fd,&tmpwayx,sizeof(WayX))) WriteFileBuffered(waysx->fd,&tmpwayx,sizeof(WayX)); CloseFileBuffered(waysx->fd); CloseFileBuffered(newwaysx->fd); FreeWayList(newwaysx,0); } /*++++++++++++++++++++++++++++++++++++++ Prune out any segments that are shorter than a specified minimum. NodesX *nodesx The set of nodes to use. SegmentsX *segmentsx The set of segments to use. WaysX *waysx The set of ways to use. distance_t minimum The maximum length to remove or one less than the minimum length to keep. ++++++++++++++++++++++++++++++++++++++*/ void PruneShortSegments(NodesX *nodesx,SegmentsX *segmentsx,WaysX *waysx,distance_t minimum) { index_t i; index_t nshort=0,npruned=0; if(nodesx->number==0 || segmentsx->number==0 || waysx->number==0) return; /* Print the start message */ printf_first("Pruning Short Segments: Segments=0 Short=0 Pruned=0"); /* Map into memory / open the files */ #if !SLIM nodesx->data=MapFileWriteable(nodesx->filename_tmp); segmentsx->data=MapFileWriteable(segmentsx->filename_tmp); waysx->data=MapFile(waysx->filename_tmp); #else nodesx->fd=SlimMapFileWriteable(nodesx->filename_tmp); segmentsx->fd=SlimMapFileWriteable(segmentsx->filename_tmp); waysx->fd=SlimMapFile(waysx->filename_tmp); InvalidateNodeXCache(nodesx->cache); InvalidateSegmentXCache(segmentsx->cache); InvalidateWayXCache(waysx->cache); #endif /* Loop through the segments and find the short ones for possible modification */ for(i=0;inumber;i++) { SegmentX *segmentx2=LookupSegmentX(segmentsx,i,2); if(IsPrunedSegmentX(segmentx2)) goto endloop; /* : Initial state: ..N3 -------- N2 : S2 : Final state: ..N3 : = OR = : : Initial state: ..N1 -------- N2 ---- N3 -------- N4.. : S1 S2 S3 : : : Final state: ..N1 ------------ N3 ------------ N4.. : S1 S3 : Not if N1 is the same as N4. Must not delete N2 (or N3) if S2 (or S3) has different one-way properties from S1. Must not delete N2 (or N3) if S2 (or S3) has different highway properties from S1. Must combine N2, S2 and N3 disallowed transports into new N3. Must not delete N2 (or N3) if it is a mini-roundabout. Must not delete N2 (or N3) if it is involved in a turn restriction. = OR = : : Initial state: ..N1 -------- N2 ---- N3.. : S1 S2 : : : Final state: ..N1 ------------ N3.. : S1 : Not if N1 is the same as N3. Not if S1 has different one-way properties from S2. Not if S1 has different highway properties from S2. Not if N2 disallows transports allowed on S1 and S2. Not if N2 is a mini-roundabout. Not if N2 is involved in a turn restriction. */ if(DISTANCE(segmentx2->distance)<=minimum) { index_t node1=NO_NODE,node2,node3,node4=NO_NODE; index_t segment1=NO_SEGMENT,segment2=i,segment3=NO_SEGMENT; SegmentX *segmentx; int segcount2=0,segcount3=0; nshort++; node2=segmentx2->node1; node3=segmentx2->node2; /* Count the segments connected to N2 */ segmentx=FirstSegmentX(segmentsx,node2,4); while(segmentx) { segcount2++; if(segment1==NO_SEGMENT) { index_t segment=IndexSegmentX(segmentsx,segmentx); if(segment!=segment2) { segment1=segment; node1=OtherNode(segmentx,node2); } } else if(segcount2>2) break; segmentx=NextSegmentX(segmentsx,segmentx,node2); } /* Count the segments connected to N3 */ segmentx=FirstSegmentX(segmentsx,node3,4); while(segmentx) { segcount3++; if(segment3==NO_SEGMENT) { index_t segment=IndexSegmentX(segmentsx,segmentx); if(segment!=segment2) { segment3=segment; node4=OtherNode(segmentx,node3); } } else if(segcount3>2) break; segmentx=NextSegmentX(segmentsx,segmentx,node3); } /* Check which case we are handling (and canonicalise) */ if(segcount2>2 && segcount3>2) /* none of the cases in diagram - too complicated */ { goto endloop; } else if(segcount2==1 || segcount3==1) /* first case in diagram - prune segment */ { prune_segment(segmentsx,segmentx2); } else if(segcount2==2 && segcount3==2) /* second case in diagram - modify one segment and prune segment */ { SegmentX *segmentx1,*segmentx3; WayX *wayx1,*wayx2,*wayx3; NodeX *nodex2,*nodex3,*newnodex; index_t newnode; int join12=1,join23=1,same13=1; /* Check if pruning would collapse a loop */ if(node1==node4) goto endloop; /* Check if allowed due to one-way properties */ segmentx1=LookupSegmentX(segmentsx,segment1,1); segmentx3=LookupSegmentX(segmentsx,segment3,3); if(!IsOneway(segmentx1) && !IsOneway(segmentx2)) ; else if(IsOneway(segmentx1) && IsOneway(segmentx2)) { if(IsOnewayTo(segmentx1,node2) && !IsOnewayFrom(segmentx2,node2)) /* S1 is one-way but S2 doesn't continue */ join12=0; if(IsOnewayFrom(segmentx1,node2) && !IsOnewayTo(segmentx2,node2)) /* S1 is one-way but S2 doesn't continue */ join12=0; } else join12=0; if(!IsOneway(segmentx3) && !IsOneway(segmentx2)) ; else if(IsOneway(segmentx3) && IsOneway(segmentx2)) { if(IsOnewayTo(segmentx3,node3) && !IsOnewayFrom(segmentx2,node3)) /* S3 is one-way but S2 doesn't continue */ join23=0; if(IsOnewayFrom(segmentx3,node3) && !IsOnewayTo(segmentx2,node3)) /* S3 is one-way but S2 doesn't continue */ join23=0; } else join23=0; if(!join12 && !join23) goto endloop; /* Check if allowed due to highway properties */ wayx1=LookupWayX(waysx,segmentx1->way,1); wayx2=LookupWayX(waysx,segmentx2->way,2); wayx3=LookupWayX(waysx,segmentx3->way,3); if(WaysCompare(&wayx1->way,&wayx2->way)) join12=0; if(WaysCompare(&wayx3->way,&wayx2->way)) join23=0; if(!join12 && !join23) goto endloop; /* Check if allowed due to mini-roundabout and turn restriction */ nodex2=LookupNodeX(nodesx,node2,2); nodex3=LookupNodeX(nodesx,node3,3); if(nodex2->flags&NODE_MINIRNDBT) join12=0; if(nodex3->flags&NODE_MINIRNDBT) join23=0; if(!join12 && !join23) goto endloop; if(nodex2->flags&NODE_TURNRSTRCT2 || nodex2->flags&NODE_TURNRSTRCT) join12=0; if(nodex3->flags&NODE_TURNRSTRCT2 || nodex3->flags&NODE_TURNRSTRCT) join23=0; if(!join12 && !join23) goto endloop; /* New node properties */ if(join12) { newnode=node3; newnodex=nodex3; } else /* if(join23) */ { newnode=node2; newnodex=nodex2; } newnodex->allow=nodex2->allow&nodex3->allow; /* combine the restrictions of the two nodes */ newnodex->allow&=~((~wayx2->way.allow)&wayx3->way.allow); /* disallow anything blocked by segment2 */ newnodex->allow&=~((~wayx2->way.allow)&wayx1->way.allow); /* disallow anything blocked by segment2 */ newnodex->latitude =(nodex2->latitude +nodex3->latitude )/2; newnodex->longitude=(nodex2->longitude+nodex3->longitude)/2; PutBackNodeX(nodesx,newnodex); /* Modify segments - update the distances */ if(!IsOneway(segmentx1) && !IsOneway(segmentx3)) ; else if(IsOneway(segmentx1) && IsOneway(segmentx3)) { if(IsOnewayTo(segmentx1,node3) && !IsOnewayFrom(segmentx3,node3)) /* S1 is one-way but S3 doesn't continue */ same13=0; if(IsOnewayFrom(segmentx1,node3) && !IsOnewayTo(segmentx3,node3)) /* S1 is one-way but S3 doesn't continue */ same13=0; } else same13=0; if(WaysCompare(&wayx1->way,&wayx3->way)) same13=0; if(same13) { segmentx1->distance+=DISTANCE(segmentx2->distance)/2; segmentx3->distance+=DISTANCE(segmentx2->distance)-DISTANCE(segmentx2->distance)/2; } else if(join12) segmentx1->distance+=DISTANCE(segmentx2->distance); else /* if(join23) */ segmentx3->distance+=DISTANCE(segmentx2->distance); /* Modify segments - update the segments */ if(segmentx1->node1==node1) { if(segmentx1->node2!=newnode) modify_segment(segmentsx,segmentx1,node1,newnode); else PutBackSegmentX(segmentsx,segmentx1); } else /* if(segmentx1->node2==node1) */ { if(segmentx1->node1!=newnode) modify_segment(segmentsx,segmentx1,newnode,node1); else PutBackSegmentX(segmentsx,segmentx1); } if(segmentx3->node1==node4) { if(segmentx3->node2!=newnode) modify_segment(segmentsx,segmentx3,node4,newnode); else PutBackSegmentX(segmentsx,segmentx3); } else /* if(segmentx3->node2==node4) */ { if(segmentx3->node1!=newnode) modify_segment(segmentsx,segmentx3,newnode,node4); else PutBackSegmentX(segmentsx,segmentx3); } ReLookupSegmentX(segmentsx,segmentx2); prune_segment(segmentsx,segmentx2); } else /* third case in diagram - prune one segment */ { SegmentX *segmentx1; WayX *wayx1,*wayx2; NodeX *nodex2; if(segcount3==2) /* not as in diagram, shuffle things round */ { index_t temp; temp=segment1; segment1=segment3; segment3=temp; temp=node1; node1=node4; node4=temp; temp=node2; node2=node3; node3=temp; } /* Check if pruning would collapse a loop */ if(node1==node3) goto endloop; /* Check if allowed due to one-way properties */ segmentx1=LookupSegmentX(segmentsx,segment1,1); if(!IsOneway(segmentx1) && !IsOneway(segmentx2)) ; else if(IsOneway(segmentx1) && IsOneway(segmentx2)) { if(IsOnewayTo(segmentx1,node2) && !IsOnewayFrom(segmentx2,node2)) /* S1 is one-way but S2 doesn't continue */ goto endloop; if(IsOnewayFrom(segmentx1,node2) && !IsOnewayTo(segmentx2,node2)) /* S1 is one-way but S2 doesn't continue */ goto endloop; } else goto endloop; /* Check if allowed due to highway properties */ wayx1=LookupWayX(waysx,segmentx1->way,1); wayx2=LookupWayX(waysx,segmentx2->way,2); if(WaysCompare(&wayx1->way,&wayx2->way)) goto endloop; /* Check if allowed due to mini-roundabout and turn restriction */ nodex2=LookupNodeX(nodesx,node2,2); if(nodex2->flags&NODE_MINIRNDBT) goto endloop; if(nodex2->flags&NODE_TURNRSTRCT2 || nodex2->flags&NODE_TURNRSTRCT) goto endloop; /* Check if allowed due to node restrictions */ if((nodex2->allow&wayx1->way.allow)!=wayx1->way.allow) goto endloop; if((nodex2->allow&wayx2->way.allow)!=wayx2->way.allow) goto endloop; /* Modify segments */ segmentx1->distance+=DISTANCE(segmentx2->distance); if(segmentx1->node1==node1) modify_segment(segmentsx,segmentx1,node1,node3); else /* if(segmentx1->node2==node1) */ modify_segment(segmentsx,segmentx1,node3,node1); ReLookupSegmentX(segmentsx,segmentx2); prune_segment(segmentsx,segmentx2); } npruned++; } endloop: if(!((i+1)%10000)) printf_middle("Pruning Short Segments: Segments=%"Pindex_t" Short=%"Pindex_t" Pruned=%"Pindex_t,i+1,nshort,npruned); } /* Unmap from memory / close the files */ #if !SLIM nodesx->data=UnmapFile(nodesx->data); segmentsx->data=UnmapFile(segmentsx->data); waysx->data=UnmapFile(waysx->data); #else nodesx->fd=SlimUnmapFile(nodesx->fd); segmentsx->fd=SlimUnmapFile(segmentsx->fd); waysx->fd=SlimUnmapFile(waysx->fd); #endif /* Print the final message */ printf_last("Pruned Short Segments: Segments=%"Pindex_t" Short=%"Pindex_t" Pruned=%"Pindex_t,segmentsx->number,nshort,npruned); } /*++++++++++++++++++++++++++++++++++++++ Prune out any nodes from straight highways where the introduced error is smaller than a specified maximum. NodesX *nodesx The set of nodes to use. SegmentsX *segmentsx The set of segments to use. WaysX *waysx The set of ways to use. distance_t maximum The maximum error to introduce. ++++++++++++++++++++++++++++++++++++++*/ void PruneStraightHighwayNodes(NodesX *nodesx,SegmentsX *segmentsx,WaysX *waysx,distance_t maximum) { index_t i; index_t npruned=0; index_t nalloc; BitMask *checked; index_t *nodes,*segments; double *lats,*lons; double maximumf; if(nodesx->number==0 || segmentsx->number==0 || waysx->number==0) return; /* Print the start message */ printf_first("Pruning Straight Highway Nodes: Nodes=0 Pruned=0"); /* Map into memory / open the files */ #if !SLIM nodesx->data=MapFile(nodesx->filename_tmp); segmentsx->data=MapFileWriteable(segmentsx->filename_tmp); waysx->data=MapFile(waysx->filename_tmp); #else nodesx->fd=SlimMapFile(nodesx->filename_tmp); segmentsx->fd=SlimMapFileWriteable(segmentsx->filename_tmp); waysx->fd=SlimMapFile(waysx->filename_tmp); InvalidateNodeXCache(nodesx->cache); InvalidateSegmentXCache(segmentsx->cache); InvalidateWayXCache(waysx->cache); #endif checked=AllocBitMask(nodesx->number); log_malloc(checked,LengthBitMask(nodesx->number)*sizeof(BitMask)); logassert(checked,"Failed to allocate memory (try using slim mode?)"); /* Check AllocBitMask() worked */ nodes =(index_t*)malloc((nalloc=1024)*sizeof(index_t)); segments=(index_t*)malloc( nalloc *sizeof(index_t)); logassert(nodes ,"Failed to allocate memory (try using slim mode?)"); /* Check malloc() worked */ logassert(segments,"Failed to allocate memory (try using slim mode?)"); /* Check malloc() worked */ lats=(double*)malloc(nalloc*sizeof(double)); lons=(double*)malloc(nalloc*sizeof(double)); logassert(lats,"Failed to allocate memory (try using slim mode?)"); /* Check malloc() worked */ logassert(lons,"Failed to allocate memory (try using slim mode?)"); /* Check malloc() worked */ /* Loop through the nodes and find stretches of simple highway for possible modification */ maximumf=distance_to_km(maximum); for(i=0;inumber;i++) { int lowerbounded=0,upperbounded=0; index_t lower=nalloc/2,current=nalloc/2,upper=nalloc/2; if(IsBitSet(checked,i)) goto endloop; if(segmentsx->firstnode[i]==NO_SEGMENT) goto endloop; /* Find all connected nodes */ nodes[current]=i; do { index_t node1=NO_NODE,node2=NO_NODE; index_t segment1=NO_SEGMENT,segment2=NO_SEGMENT; index_t way1=NO_WAY,way2=NO_WAY; int segcount=0; NodeX *nodex; /* Get the node data */ nodex=LookupNodeX(nodesx,nodes[current],1); lats[current]=latlong_to_radians(nodex->latitude); lons[current]=latlong_to_radians(nodex->longitude); /* Count the segments at the node if not forced to be an end node */ if(IsBitSet(checked,nodes[current])) ; else if(nodex->flags&NODE_MINIRNDBT) ; else if(nodex->flags&NODE_TURNRSTRCT2 || nodex->flags&NODE_TURNRSTRCT) ; else { SegmentX *segmentx; /* Count the segments connected to the node */ segmentx=FirstSegmentX(segmentsx,nodes[current],3); while(segmentx) { segcount++; if(node1==NO_NODE) { segment1=IndexSegmentX(segmentsx,segmentx); node1=OtherNode(segmentx,nodes[current]); way1=segmentx->way; } else if(node2==NO_NODE) { segment2=IndexSegmentX(segmentsx,segmentx); node2=OtherNode(segmentx,nodes[current]); way2=segmentx->way; } else break; segmentx=NextSegmentX(segmentsx,segmentx,nodes[current]); } } /* Check if allowed due to one-way properties */ if(segcount==2) { SegmentX *segmentx1,*segmentx2; segmentx1=LookupSegmentX(segmentsx,segment1,1); segmentx2=LookupSegmentX(segmentsx,segment2,2); if(!IsOneway(segmentx1) && !IsOneway(segmentx2)) ; else if(IsOneway(segmentx1) && IsOneway(segmentx2)) { if(IsOnewayTo(segmentx1,nodes[current]) && !IsOnewayFrom(segmentx2,nodes[current])) /* S1 is one-way but S2 doesn't continue */ segcount=0; if(IsOnewayFrom(segmentx1,nodes[current]) && !IsOnewayTo(segmentx2,nodes[current])) /* S1 is one-way but S2 doesn't continue */ segcount=0; } else segcount=0; } /* Check if allowed due to highway properties and node restrictions */ if(segcount==2) { WayX *wayx1,*wayx2; wayx1=LookupWayX(waysx,way1,1); wayx2=LookupWayX(waysx,way2,2); if(WaysCompare(&wayx1->way,&wayx2->way)) segcount=0; if(wayx1->way.name!=wayx2->way.name) segcount=0; if((nodex->allow&wayx1->way.allow)!=wayx1->way.allow) segcount=0; if((nodex->allow&wayx2->way.allow)!=wayx2->way.allow) segcount=0; } /* Update the lists */ if(segcount==2) { /* Make space in the lists */ if(upper==(nalloc-1)) { nodes =(index_t*)realloc(nodes ,(nalloc+=1024)*sizeof(index_t)); segments=(index_t*)realloc(segments, nalloc *sizeof(index_t)); lats=(double*)realloc(lats,nalloc*sizeof(double)); lons=(double*)realloc(lons,nalloc*sizeof(double)); } if(lower==0) /* move everything up by one */ { memmove(nodes+1 ,nodes ,(1+upper-lower)*sizeof(index_t)); memmove(segments+1,segments,(1+upper-lower)*sizeof(index_t)); memmove(lats+1,lats,(1+upper-lower)*sizeof(double)); memmove(lons+1,lons,(1+upper-lower)*sizeof(double)); current++; lower++; upper++; } if(lower==upper) /* first */ { lower--; nodes[lower]=node1; segments[lower]=segment1; upper++; nodes[upper]=node2; segments[upper-1]=segment2; segments[upper]=NO_SEGMENT; current--; } else if(current==lower) { lower--; if(nodes[current+1]==node2) { nodes[lower]=node1; segments[lower]=segment1; } else /* if(nodes[current+1]==node1) */ { nodes[lower]=node2; segments[lower]=segment2; } current--; } else /* if(current==upper) */ { upper++; if(nodes[current-1]==node2) { nodes[upper]=node1; segments[upper-1]=segment1; } else /* if(nodes[current-1]==node1) */ { nodes[upper]=node2; segments[upper-1]=segment2; } segments[upper]=NO_SEGMENT; current++; } if(nodes[upper]==nodes[lower]) { if(!lowerbounded && !upperbounded) { nodex=LookupNodeX(nodesx,nodes[lower],1); lats[lower]=latlong_to_radians(nodex->latitude); lons[lower]=latlong_to_radians(nodex->longitude); } lats[upper]=lats[lower]; lons[upper]=lons[lower]; lowerbounded=1; upperbounded=1; } } else /* if(segment!=2) */ { if(current==upper) upperbounded=1; if(current==lower) { lowerbounded=1; current=upper; } } } while(!(lowerbounded && upperbounded)); /* Mark the nodes */ for(current=lower;current<=upper;current++) SetBit(checked,nodes[current]); /* Check for straight highway */ for(;lower<(upper-1);lower++) { for(current=upper;current>(lower+1);current--) { SegmentX *segmentx; distance_t dist=0; double dist1,dist2,dist3,distp; index_t c; dist3=distance(lats[lower],lons[lower],lats[current],lons[current]); for(c=lower+1;c=0 && dist3b>=0) distp=sqrt(dist1*dist1-dist3a*dist3a); else if(dist3a>0) distp=dist2; else /* if(dist3b>0) */ distp=dist1; } if(distp>maximumf) /* gone too far */ break; } if(cdistance); prune_segment(segmentsx,segmentx); npruned++; } segmentx=LookupSegmentX(segmentsx,segments[lower],1); if(nodes[lower]==nodes[current]) /* loop; all within maximum distance */ { prune_segment(segmentsx,segmentx); npruned++; } else { segmentx->distance+=dist; if(segmentx->node1==nodes[lower]) modify_segment(segmentsx,segmentx,nodes[lower],nodes[current]); else /* if(segmentx->node2==nodes[lower]) */ modify_segment(segmentsx,segmentx,nodes[current],nodes[lower]); } lower=current-1; break; } } endloop: if(!((i+1)%10000)) printf_middle("Pruning Straight Highway Nodes: Nodes=%"Pindex_t" Pruned=%"Pindex_t,i+1,npruned); } /* Unmap from memory / close the files */ log_free(checked); free(checked); free(nodes); free(segments); free(lats); free(lons); #if !SLIM nodesx->data=UnmapFile(nodesx->data); segmentsx->data=UnmapFile(segmentsx->data); waysx->data=UnmapFile(waysx->data); #else nodesx->fd=SlimUnmapFile(nodesx->fd); segmentsx->fd=SlimUnmapFile(segmentsx->fd); waysx->fd=SlimUnmapFile(waysx->fd); #endif /* Print the final message */ printf_last("Pruned Straight Highway Nodes: Nodes=%"Pindex_t" Pruned=%"Pindex_t,nodesx->number,npruned); } /*++++++++++++++++++++++++++++++++++++++ Prune a segment; unused nodes and ways will get marked for pruning later. SegmentsX *segmentsx The set of segments to use. SegmentX *segmentx The segment to be pruned. ++++++++++++++++++++++++++++++++++++++*/ static void prune_segment(SegmentsX *segmentsx,SegmentX *segmentx) { unlink_segment_node1_refs(segmentsx,segmentx); unlink_segment_node2_refs(segmentsx,segmentx); segmentx->node1=NO_NODE; segmentx->node2=NO_NODE; segmentx->next2=NO_SEGMENT; PutBackSegmentX(segmentsx,segmentx); } /*++++++++++++++++++++++++++++++++++++++ Modify a segment's nodes; unused nodes will get marked for pruning later. SegmentsX *segmentsx The set of segments to use. SegmentX *segmentx The segment to be modified. index_t newnode1 The new value of node1. index_t newnode2 The new value of node2. ++++++++++++++++++++++++++++++++++++++*/ static void modify_segment(SegmentsX *segmentsx,SegmentX *segmentx,index_t newnode1,index_t newnode2) { index_t thissegment=IndexSegmentX(segmentsx,segmentx); if(newnode1>newnode2) /* rotate the segment around */ { index_t temp; if(segmentx->distance&(ONEWAY_2TO1|ONEWAY_1TO2)) segmentx->distance^=ONEWAY_2TO1|ONEWAY_1TO2; temp=newnode1; newnode1=newnode2; newnode2=temp; } if(newnode1!=segmentx->node1) unlink_segment_node1_refs(segmentsx,segmentx); if(newnode2!=segmentx->node2) unlink_segment_node2_refs(segmentsx,segmentx); if(newnode1!=segmentx->node1) /* only modify it if the node has changed */ { segmentx->node1=newnode1; segmentsx->next1[thissegment]=segmentsx->firstnode[newnode1]; segmentsx->firstnode[newnode1]=thissegment; } if(newnode2!=segmentx->node2) /* only modify it if the node has changed */ { segmentx->node2=newnode2; segmentx->next2=segmentsx->firstnode[newnode2]; segmentsx->firstnode[newnode2]=thissegment; } PutBackSegmentX(segmentsx,segmentx); } /*++++++++++++++++++++++++++++++++++++++ Unlink a node1 from a segment by modifying the linked list type arrangement of node references. SegmentsX *segmentsx The set of segments to use. SegmentX *segmentx The segment to be modified. ++++++++++++++++++++++++++++++++++++++*/ static void unlink_segment_node1_refs(SegmentsX *segmentsx,SegmentX *segmentx) { index_t segment,thissegment; thissegment=IndexSegmentX(segmentsx,segmentx); segment=segmentsx->firstnode[segmentx->node1]; if(segment==thissegment) segmentsx->firstnode[segmentx->node1]=segmentsx->next1[thissegment]; else { do { index_t nextsegment; SegmentX *segx=LookupSegmentX(segmentsx,segment,4); if(segx->node1==segmentx->node1) { nextsegment=segmentsx->next1[segment]; if(nextsegment==thissegment) segmentsx->next1[segment]=segmentsx->next1[thissegment]; } else /* if(segx->node2==segmentx->node1) */ { nextsegment=segx->next2; if(nextsegment==thissegment) { segx->next2=segmentsx->next1[thissegment]; PutBackSegmentX(segmentsx,segx); } } segment=nextsegment; } while(segment!=thissegment && segment!=NO_SEGMENT); } } /*++++++++++++++++++++++++++++++++++++++ Unlink a node2 from a segment by modifying the linked list type arrangement of node references. SegmentsX *segmentsx The set of segments to use. SegmentX *segmentx The segment to be modified. ++++++++++++++++++++++++++++++++++++++*/ static void unlink_segment_node2_refs(SegmentsX *segmentsx,SegmentX *segmentx) { index_t segment,thissegment; thissegment=IndexSegmentX(segmentsx,segmentx); segment=segmentsx->firstnode[segmentx->node2]; if(segment==thissegment) segmentsx->firstnode[segmentx->node2]=segmentx->next2; else { do { index_t nextsegment; SegmentX *segx=LookupSegmentX(segmentsx,segment,4); if(segx->node1==segmentx->node2) { nextsegment=segmentsx->next1[segment]; if(nextsegment==thissegment) segmentsx->next1[segment]=segmentx->next2; } else /* if(segx->node2==segmentx->node2) */ { nextsegment=segx->next2; if(nextsegment==thissegment) { segx->next2=segmentx->next2; PutBackSegmentX(segmentsx,segx); } } segment=nextsegment; } while(segment!=thissegment && segment!=NO_SEGMENT); } } /*++++++++++++++++++++++++++++++++++++++ Calculate the distance between two locations. double distance Returns the distance between the locations. double lat1 The latitude of the first location. double lon1 The longitude of the first location. double lat2 The latitude of the second location. double lon2 The longitude of the second location. ++++++++++++++++++++++++++++++++++++++*/ static double distance(double lat1,double lon1,double lat2,double lon2) { double dlon = lon1 - lon2; double dlat = lat1 - lat2; double a1,a2,a,sa,c,d; if(dlon==0 && dlat==0) return 0; a1 = sin (dlat / 2); a2 = sin (dlon / 2); a = (a1 * a1) + cos (lat1) * cos (lat2) * a2 * a2; sa = sqrt (a); if (sa <= 1.0) {c = 2 * asin (sa);} else {c = 2 * asin (1.0);} d = 6378.137 * c; return(d); } routino-3.0/src/test/ 40755 233 144 0 12573351516 7765 5routino-3.0/src/test/a-b-c.sh 755 233 144 5213 12563633052 11215 0#!/bin/sh # Exit on error set -e # Test name name=`basename $0 .sh` # Slim or non-slim if [ "$1" = "slim" ]; then slim="-slim" dir="slim" else slim="" dir="fat" fi # Libroutino or not libroutino LD_LIBRARY_PATH=$PWD/..:$LD_LIBRARY_PATH export LD_LIBRARY_PATH if [ "$2" = "lib" ]; then lib="+lib" else lib="" fi # Pruned or non-pruned if [ "$2" = "prune" ]; then prune="" pruned="-pruned" else prune="--prune-none" pruned="" fi # Create the output directory dir="$dir$lib$pruned" [ -d $dir ] || mkdir $dir # Run the programs under a run-time debugger debugger=valgrind debugger= # Name related options osm=$name.osm log=$name$lib$slim$pruned.log option_prefix="--prefix=$name" option_dir="--dir=$dir" # Generic program options option_planetsplitter="--loggable --tagging=../../xml/routino-tagging.xml --errorlog $prune" option_filedumper="--dump-osm" option_router="--profile=motorcar --profiles=../../xml/routino-profiles.xml --translations=copyright.xml" if [ ! "$2" = "lib" ]; then option_router="$option_router --loggable" fi # Run planetsplitter echo "Running planetsplitter" echo ../planetsplitter$slim $option_dir $option_prefix $option_planetsplitter $osm > $log $debugger ../planetsplitter$slim $option_dir $option_prefix $option_planetsplitter $osm >> $log # Run filedumper echo "Running filedumper" echo ../filedumper$slim $option_dir $option_prefix $option_filedumper >> $log $debugger ../filedumper$slim $option_dir $option_prefix $option_filedumper > $dir/$osm # Waypoints waypoints=`perl waypoints.pl $osm list` # Run the router for each waypoint for waypoint in $waypoints; do case $waypoint in *a) waypoint=`echo $waypoint | sed -e 's%a$%%'` ;; *) continue ;; esac echo "Running router : $waypoint" waypoint_a=`perl waypoints.pl $osm ${waypoint}a 1` waypoint_b=`perl waypoints.pl $osm ${waypoint}b 2` waypoint_c=`perl waypoints.pl $osm ${waypoint}c 3` [ -d $dir/$name-$waypoint ] || mkdir $dir/$name-$waypoint echo ../router$lib$slim $option_dir $option_prefix $option_osm $option_router $waypoint_a $waypoint_b $waypoint_c >> $log $debugger ../router$lib$slim $option_dir $option_prefix $option_osm $option_router $waypoint_a $waypoint_b $waypoint_c >> $log mv shortest* $dir/$name-$waypoint echo diff -u expected/$name-$waypoint.txt $dir/$name-$waypoint/shortest-all.txt >> $log if ./is-fast-math; then diff -U 0 expected/$name-$waypoint.txt $dir/$name-$waypoint/shortest-all.txt | 2>&1 egrep '^[-+] ' || true else diff -u expected/$name-$waypoint.txt $dir/$name-$waypoint/shortest-all.txt >> $log fi done routino-3.0/src/test/oneway-loop.sh 777 233 144 0 12064636362 15630 2start-1-finish.shroutino-3.0/src/test/loops.osm 644 233 144 16247 12064636362 11707 0 routino-3.0/src/test/invalid-turn-relations.osm 644 233 144 22476 12105426741 15160 0 routino-3.0/src/test/super-or-not.sh 777 233 144 0 12064636362 13617 2a-b.shroutino-3.0/src/test/waypoints.pl 755 233 144 3443 12306670127 12376 0#!/usr/bin/perl # # Routing test case generator tool. # # Part of the Routino routing software. # # This file Copyright 2011-2014 Andrew M. Bishop # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # use strict; # Command line if($#ARGV<1 || $ARGV>2 || ! -f $ARGV[0]) { die "Usage: waypoints.pl list\n". " waypoints.pl \n"; } # Parse the file open(FILE,"<$ARGV[0]") || die "Cannot open '$ARGV[0]'\n"; my %waypoints=(); my @waypoints=(); my @waypoint_lat=(); my @waypoint_lon=(); my $innode=0; while() { if($innode) { if(m%%); } elsif(m%%) { $innode=1; push(@waypoint_lat,$1); push(@waypoint_lon,$2); } } close(FILE); # Perform the action if($ARGV[1] eq "list") { print join(" ",sort @waypoints)."\n"; exit 0; } if($waypoints{$ARGV[1]} ne "") { print "--lat$ARGV[2]=$waypoint_lat[$waypoints{$ARGV[1]}] --lon$ARGV[2]=$waypoint_lon[$waypoints{$ARGV[1]}]\n"; exit 0; } exit 1; routino-3.0/src/test/node-restrictions.osm 644 233 144 16636 12114366273 14225 0 routino-3.0/src/test/node-restrictions.sh 777 233 144 0 12064636362 17032 2start-1-finish.shroutino-3.0/src/test/cycle-both-ways.sh 777 233 144 0 12327512664 16026 2cycle-drive.shroutino-3.0/src/test/coincident-waypoint.sh 777 233 144 0 12333356554 15676 2a-b-c-d.shroutino-3.0/src/test/dead-ends.sh 777 233 144 0 12064636362 15203 2start-1-finish.shroutino-3.0/src/test/loops.sh 777 233 144 0 12064636362 14513 2start-1-finish.shroutino-3.0/src/test/run-tests.sh 755 233 144 3205 12563633052 12301 0#!/bin/sh status=true run_a_test () { script=$1 shift if ./$script $@ ; then echo "... passed" else echo "... FAILED" status=false fi } compare_results () { if diff -q -r $1 $2; then echo "... matched" else echo "... match FAILED" status=false fi } # Initial informational message echo "" ./is-fast-math message # Loop round the different test types for type in 1 2 3; do case $type in 1) suffix="" arg="" description="" ;; 2) suffix="+lib" arg="lib" description="libroutino" ;; 3) suffix="-pruned" arg="prune" description="pruned" ;; esac # Normal mode for script in $@; do echo "" echo "Testing: $script (non-slim, $description) ... " run_a_test $script fat $arg done # Normal mode for script in $@; do echo "" echo "Testing: $script (slim, $description) ... " run_a_test $script slim $arg done # Check results if $status; then echo "Success: all tests passed" else echo "Warning: Some tests FAILED" exit 1 fi # Compare normal/slim results echo "" echo "Comparing: slim and non-slim results ($description) ... " compare_results fat$suffix slim$suffix # Check comparison if $status; then echo "Success: slim and non-slim results match" else echo "Warning: slim and non-slim results are different" exit 1 fi done exit 0 routino-3.0/src/test/prune-short.sh 777 233 144 0 12114364765 15207 2only-split.shroutino-3.0/src/test/prune-short.osm 644 233 144 65656 12114416166 13043 0 routino-3.0/src/test/super-or-not.osm 644 233 144 4757 12064636362 13110 0 routino-3.0/src/test/prune-straight.osm 644 233 144 20500 12327506436 13512 0 routino-3.0/src/test/cycle-drive.sh 755 233 144 5151 12563633052 12545 0#!/bin/sh # Exit on error set -e # Test name name=`basename $0 .sh` # Slim or non-slim if [ "$1" = "slim" ]; then slim="-slim" dir="slim" else slim="" dir="fat" fi # Libroutino or not libroutino LD_LIBRARY_PATH=$PWD/..:$LD_LIBRARY_PATH export LD_LIBRARY_PATH if [ "$2" = "lib" ]; then lib="+lib" else lib="" fi # Pruned or non-pruned if [ "$2" = "prune" ]; then prune="" pruned="-pruned" else prune="--prune-none" pruned="" fi # Create the output directory dir=$dir$lib$pruned [ -d $dir ] || mkdir $dir # Run the programs under a run-time debugger debugger=valgrind debugger= # Name related options osm=$name.osm log=$name$lib$slim$pruned.log option_prefix="--prefix=$name" option_dir="--dir=$dir" # Generic program options option_planetsplitter="--loggable --tagging=../../xml/routino-tagging.xml --errorlog $prune" option_filedumper="--dump-osm" option_router="--profiles=../../xml/routino-profiles.xml --translations=copyright.xml" if [ ! "$2" = "lib" ]; then option_router="$option_router --loggable" fi # Run planetsplitter echo "Running planetsplitter" echo ../planetsplitter$slim $option_dir $option_prefix $option_planetsplitter $osm > $log $debugger ../planetsplitter$slim $option_dir $option_prefix $option_planetsplitter $osm >> $log # Run filedumper echo "Running filedumper" echo ../filedumper$slim $option_dir $option_prefix $option_filedumper >> $log $debugger ../filedumper$slim $option_dir $option_prefix $option_filedumper > $dir/$osm # Waypoints waypoints=`perl waypoints.pl $osm list` waypoint_start=`perl waypoints.pl $osm WPstart 1` waypoint_finish=`perl waypoints.pl $osm WPfinish 2` # Run the router for each profile type profiles="motorcar bicycle" for profile in $profiles; do case $profile in motorcar) waypoint=WP01 ;; *) waypoint=WP02 ;; esac echo "Running router : $waypoint" [ -d $dir/$name-$waypoint ] || mkdir $dir/$name-$waypoint echo ../router$lib$slim $option_dir $option_prefix $option_osm $option_router --profile=$profile $waypoint_start $waypoint_finish >> $log $debugger ../router$lib$slim $option_dir $option_prefix $option_osm $option_router --profile=$profile $waypoint_start $waypoint_finish >> $log mv shortest* $dir/$name-$waypoint echo diff -u expected/$name-$waypoint.txt $dir/$name-$waypoint/shortest-all.txt >> $log if ./is-fast-math; then diff -U 0 expected/$name-$waypoint.txt $dir/$name-$waypoint/shortest-all.txt | 2>&1 egrep '^[-+] ' || true else diff -u expected/$name-$waypoint.txt $dir/$name-$waypoint/shortest-all.txt >> $log fi done routino-3.0/src/test/a-b-c-d.sh 755 233 144 5330 12563633052 11436 0#!/bin/sh # Exit on error set -e # Test name name=`basename $0 .sh` # Slim or non-slim if [ "$1" = "slim" ]; then slim="-slim" dir="slim" else slim="" dir="fat" fi # Libroutino or not libroutino LD_LIBRARY_PATH=$PWD/..:$LD_LIBRARY_PATH export LD_LIBRARY_PATH if [ "$2" = "lib" ]; then lib="+lib" else lib="" fi # Pruned or non-pruned if [ "$2" = "prune" ]; then prune="" pruned="-pruned" else prune="--prune-none" pruned="" fi # Create the output directory dir=$dir$lib$pruned [ -d $dir ] || mkdir $dir # Run the programs under a run-time debugger debugger=valgrind debugger= # Name related options osm=$name.osm log=$name$slim$lib$pruned.log option_prefix="--prefix=$name" option_dir="--dir=$dir" # Generic program options option_planetsplitter="--loggable --tagging=../../xml/routino-tagging.xml --errorlog $prune" option_filedumper="--dump-osm" option_router="--profile=motorcar --profiles=../../xml/routino-profiles.xml --translations=copyright.xml" if [ ! "$2" = "lib" ]; then option_router="$option_router --loggable" fi # Run planetsplitter echo "Running planetsplitter" echo ../planetsplitter$slim $option_dir $option_prefix $option_planetsplitter $osm > $log $debugger ../planetsplitter$slim $option_dir $option_prefix $option_planetsplitter $osm >> $log # Run filedumper echo "Running filedumper" echo ../filedumper$slim $option_dir $option_prefix $option_filedumper >> $log $debugger ../filedumper$slim $option_dir $option_prefix $option_filedumper > $dir/$osm # Waypoints waypoints=`perl waypoints.pl $osm list` # Run the router for each waypoint for waypoint in $waypoints; do case $waypoint in *a) waypoint=`echo $waypoint | sed -e 's%a$%%'` ;; *) continue ;; esac echo "Running router : $waypoint" waypoint_a=`perl waypoints.pl $osm ${waypoint}a 1` waypoint_b=`perl waypoints.pl $osm ${waypoint}b 2` waypoint_c=`perl waypoints.pl $osm ${waypoint}c 3` waypoint_d=`perl waypoints.pl $osm ${waypoint}d 4` [ -d $dir/$name-$waypoint ] || mkdir $dir/$name-$waypoint echo ../router$lib$slim $option_dir $option_prefix $option_osm $option_router $waypoint_a $waypoint_b $waypoint_c $waypoint_d >> $log $debugger ../router$lib$slim $option_dir $option_prefix $option_osm $option_router $waypoint_a $waypoint_b $waypoint_c $waypoint_d >> $log mv shortest* $dir/$name-$waypoint echo diff -u expected/$name-$waypoint.txt $dir/$name-$waypoint/shortest-all.txt >> $log if ./is-fast-math; then diff -U 0 expected/$name-$waypoint.txt $dir/$name-$waypoint/shortest-all.txt | 2>&1 egrep '^[-+] ' || true else diff -u expected/$name-$waypoint.txt $dir/$name-$waypoint/shortest-all.txt >> $log fi done routino-3.0/src/test/dead-ends.osm 644 233 144 16570 12326256227 12375 0 routino-3.0/src/test/fake-node-with-loop.osm 644 233 144 10546 12327506445 14320 0 routino-3.0/src/test/is-fast-math.c 644 233 144 450 12154147145 12415 0#include int main(int argc,char **argv) { #ifdef __FAST_MATH__ if(argc>1) printf("Compiled with -ffast-math => results may differ slightly.\n"); return 0; #else if(argc>1) printf("Not compiled with -ffast-math => results should match exactly.\n"); return 1; #endif } routino-3.0/src/test/a-b.sh 755 233 144 5074 12563633052 11002 0#!/bin/sh # Exit on error set -e # Test name name=`basename $0 .sh` # Slim or non-slim if [ "$1" = "slim" ]; then slim="-slim" dir="slim" else slim="" dir="fat" fi # Libroutino or not libroutino LD_LIBRARY_PATH=$PWD/..:$LD_LIBRARY_PATH export LD_LIBRARY_PATH if [ "$2" = "lib" ]; then lib="+lib" else lib="" fi # Pruned or non-pruned if [ "$2" = "prune" ]; then prune="" pruned="-pruned" else prune="--prune-none" pruned="" fi # Create the output directory dir="$dir$lib$pruned" [ -d $dir ] || mkdir $dir # Run the programs under a run-time debugger debugger=valgrind debugger= # Name related options osm=$name.osm log=$name$lib$slim$pruned.log option_prefix="--prefix=$name" option_dir="--dir=$dir" # Generic program options option_planetsplitter="--loggable --tagging=../../xml/routino-tagging.xml --errorlog $prune" option_filedumper="--dump-osm" option_router="--profile=motorcar --profiles=../../xml/routino-profiles.xml --translations=copyright.xml" if [ ! "$2" = "lib" ]; then option_router="$option_router --loggable" fi # Run planetsplitter echo "Running planetsplitter" echo ../planetsplitter$slim $option_dir $option_prefix $option_planetsplitter $osm > $log $debugger ../planetsplitter$slim $option_dir $option_prefix $option_planetsplitter $osm >> $log # Run filedumper echo "Running filedumper" echo ../filedumper$slim $option_dir $option_prefix $option_filedumper >> $log $debugger ../filedumper$slim $option_dir $option_prefix $option_filedumper > $dir/$osm # Waypoints waypoints=`perl waypoints.pl $osm list` # Run the router for each waypoint for waypoint in $waypoints; do case $waypoint in *a) waypoint=`echo $waypoint | sed -e 's%a$%%'` ;; *) continue ;; esac echo "Running router : $waypoint" waypoint_a=`perl waypoints.pl $osm ${waypoint}a 1` waypoint_b=`perl waypoints.pl $osm ${waypoint}b 2` [ -d $dir/$name-$waypoint ] || mkdir $dir/$name-$waypoint echo ../router$lib$slim $option_dir $option_prefix $option_osm $option_router $waypoint_a $waypoint_b >> $log $debugger ../router$lib$slim $option_dir $option_prefix $option_osm $option_router $waypoint_a $waypoint_b >> $log mv shortest* $dir/$name-$waypoint echo diff -u expected/$name-$waypoint.txt $dir/$name-$waypoint/shortest-all.txt >> $log if ./is-fast-math; then diff -U 0 expected/$name-$waypoint.txt $dir/$name-$waypoint/shortest-all.txt | 2>&1 egrep '^[-+] ' || true else diff -u expected/$name-$waypoint.txt $dir/$name-$waypoint/shortest-all.txt >> $log fi done routino-3.0/src/test/prune-straight.sh 777 233 144 0 12114436047 15666 2only-split.shroutino-3.0/src/test/Makefile 644 233 144 3442 12563636736 11455 0# Test cases Makefile # # Part of the Routino routing software. # # This file Copyright 2011-2015 Andrew M. Bishop # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # # All configuration is in the top-level Makefile.conf include ../../Makefile.conf # executables ROUTINO_EXE=planetsplitter$(.EXE) planetsplitter-slim$(.EXE) \ router$(.EXE) router-slim$(.EXE) \ router+lib$(.EXE) router+lib-slim$(.EXE) \ filedumper$(.EXE) filedumper-slim$(.EXE) EXE=is-fast-math$(.EXE) # Compilation targets O=$(notdir $(wildcard *.osm)) S=$(foreach f,$(O),$(addsuffix .sh,$(basename $f))) ######## all : ######## test : test-exe $(EXE) @./run-tests.sh $(S) ######## test-exe : cd .. && $(MAKE) $(ROUTINO_EXE) is-fast-math$(.EXE) : is-fast-math.o $(LD) $< -o $@ $(LDFLAGS) is-fast-math.o : is-fast-math.c $(CC) -c $(CFLAGS) $< -o $@ ######## install: ######## clean: rm -rf fat rm -rf slim rm -rf fat+lib rm -rf slim+lib rm -rf fat-pruned rm -rf slim-pruned rm -f *.log rm -f *~ rm -f *.o rm -f $(EXE) rm -f core rm -f *.gcda *.gcno *.gcov gmon.out ######## distclean: clean ######## .PHONY:: all test install clean distclean .PHONY:: test-exe routino-3.0/src/test/copyright.xml 644 233 144 2406 12563645242 12536 0 routino-3.0/src/test/start-1-finish.sh 755 233 144 5203 12563633052 13106 0#!/bin/sh # Exit on error set -e # Test name name=`basename $0 .sh` # Slim or non-slim if [ "$1" = "slim" ]; then slim="-slim" dir="slim" else slim="" dir="fat" fi # Libroutino or not libroutino LD_LIBRARY_PATH=$PWD/..:$LD_LIBRARY_PATH export LD_LIBRARY_PATH if [ "$2" = "lib" ]; then lib="+lib" else lib="" fi # Pruned or non-pruned if [ "$2" = "prune" ]; then prune="" pruned="-pruned" else prune="--prune-none" pruned="" fi # Create the output directory dir=$dir$lib$pruned [ -d $dir ] || mkdir $dir # Run the programs under a run-time debugger debugger=valgrind debugger= # Name related options osm=$name.osm log=$name$lib$slim$pruned.log option_prefix="--prefix=$name" option_dir="--dir=$dir" # Generic program options option_planetsplitter="--loggable --tagging=../../xml/routino-tagging.xml --errorlog $prune" option_filedumper="--dump-osm" option_router="--profile=motorcar --profiles=../../xml/routino-profiles.xml --translations=copyright.xml" if [ ! "$2" = "lib" ]; then option_router="$option_router --loggable" fi # Run planetsplitter echo "Running planetsplitter" echo ../planetsplitter$slim $option_dir $option_prefix $option_planetsplitter $osm > $log $debugger ../planetsplitter$slim $option_dir $option_prefix $option_planetsplitter $osm >> $log # Run filedumper echo "Running filedumper" echo ../filedumper$slim $option_dir $option_prefix $option_filedumper >> $log $debugger ../filedumper$slim $option_dir $option_prefix $option_filedumper > $dir/$osm # Waypoints waypoints=`perl waypoints.pl $osm list` waypoint_start=`perl waypoints.pl $osm WPstart 1` waypoint_finish=`perl waypoints.pl $osm WPfinish 3` # Run the router for each waypoint for waypoint in $waypoints; do [ ! $waypoint = "WPstart" ] || continue [ ! $waypoint = "WPfinish" ] || continue echo "Running router : $waypoint" waypoint_test=`perl waypoints.pl $osm $waypoint 2` [ -d $dir/$name-$waypoint ] || mkdir $dir/$name-$waypoint echo ../router$lib$slim $option_dir $option_prefix $option_osm $option_router $waypoint_start $waypoint_test $waypoint_finish >> $log $debugger ../router$lib$slim $option_dir $option_prefix $option_osm $option_router $waypoint_start $waypoint_test $waypoint_finish >> $log mv shortest* $dir/$name-$waypoint echo diff -u expected/$name-$waypoint.txt $dir/$name-$waypoint/shortest-all.txt >> $log if ./is-fast-math; then diff -U 0 expected/$name-$waypoint.txt $dir/$name-$waypoint/shortest-all.txt | 2>&1 egrep '^[-+] ' || true else diff -u expected/$name-$waypoint.txt $dir/$name-$waypoint/shortest-all.txt >> $log fi done routino-3.0/src/test/cycle-both-ways.osm 644 233 144 10655 12327513605 13556 0 routino-3.0/src/test/only-split.sh 755 233 144 3111 12563633052 12443 0#!/bin/sh # Exit on error set -e # Test name name=`basename $0 .sh` # Slim or non-slim if [ "$1" = "slim" ]; then slim="-slim" dir="slim" else slim="" dir="fat" fi # Libroutino or not libroutino LD_LIBRARY_PATH=$PWD/..:$LD_LIBRARY_PATH export LD_LIBRARY_PATH if [ "$2" = "lib" ]; then lib="+lib" else lib="" fi # Pruned or non-pruned if [ "$2" = "prune" ]; then case $name in prune-isolated) prune="--prune-none --prune-isolated=100";; prune-short) prune="--prune-none --prune-short=5";; prune-straight) prune="--prune-none --prune-straight=5";; *) prune="";; esac pruned="-pruned" else prune="--prune-none" pruned="" fi # Create the output directory dir=$dir$lib$pruned [ -d $dir ] || mkdir $dir # Run the programs under a run-time debugger debugger=valgrind debugger= # Name related options osm=$name.osm log=$name$lib$slim$pruned.log option_prefix="--prefix=$name" option_dir="--dir=$dir" # Generic program options option_planetsplitter="--loggable --tagging=../../xml/routino-tagging.xml --errorlog $prune" option_filedumper="--dump-osm" # Run planetsplitter echo "Running planetsplitter" echo ../planetsplitter$slim $option_dir $option_prefix $option_planetsplitter $osm > $log $debugger ../planetsplitter$slim $option_dir $option_prefix $option_planetsplitter $osm >> $log # Run filedumper echo "Running filedumper" echo ../filedumper$slim $option_dir $option_prefix $option_filedumper >> $log $debugger ../filedumper$slim $option_dir $option_prefix $option_filedumper > $dir/$osm routino-3.0/src/test/oneway-loop.osm 644 233 144 10263 12114366272 13010 0 routino-3.0/src/test/coincident-waypoint.osm 644 233 144 10700 12333376606 14527 0 routino-3.0/src/test/no-super.sh 777 233 144 0 12064636362 13235 2a-b-c.shroutino-3.0/src/test/expected/ 40755 233 144 0 12333376644 11571 5routino-3.0/src/test/expected/dead-ends-WP10.txt 644 233 144 3017 12154145517 14652 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.219535 -0.521016 -1 Waypt 0.000 0.00 0.00 0.0 -0.220223 -0.521052 5* Junct- 0.076 0.05 0.08 0.0 96 182 main 1 -0.220666 -0.521060 4* Junct 0.049 0.03 0.12 0.1 96 180 main 1 -0.220702 -0.519478 12* Junct 0.176 0.22 0.30 0.3 48 91 high street -0.220739 -0.517804 18* Junct 0.186 0.23 0.49 0.5 48 91 high street -0.220782 -0.516137 24* Junct 0.185 0.23 0.67 0.8 48 91 high street -0.220361 -0.515961 25* Junct- 0.050 0.06 0.72 0.8 48 22 dead-end 3 -0.220019 -0.515847 26 Inter 0.040 0.05 0.76 0.9 48 18 dead-end 3 -0.219672 -0.516031 -2 Waypt 0.043 0.05 0.81 0.9 48 332 dead-end 3 -0.220019 -0.515847 26 Inter 0.043 0.05 0.85 1.0 48 152 dead-end 3 -0.220361 -0.515961 25* Junct- 0.040 0.05 0.89 1.0 48 198 dead-end 3 -0.220782 -0.516137 24* Junct 0.050 0.06 0.94 1.1 48 202 dead-end 3 -0.220817 -0.514062 32* Junct 0.230 0.29 1.17 1.4 48 90 high street -0.220344 -0.514042 33* Junct- 0.052 0.03 1.22 1.4 96 2 main 2 -0.219539 -0.514007 -3 Waypt 0.089 0.06 1.31 1.5 96 2 main 2 routino-3.0/src/test/expected/turns-WP02.txt 644 233 144 2403 12064636362 14203 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.218453 -0.520799 -1 Waypt 0.000 0.00 0.00 0.0 -0.219107 -0.520828 6* Junct- 0.072 0.04 0.07 0.0 96 182 main 1 -0.220666 -0.520893 5* Junct 0.173 0.11 0.24 0.2 96 182 main 1 -0.220671 -0.520223 11* Junct 0.074 0.09 0.32 0.2 48 90 high street -0.220691 -0.519461 19* Junct 0.084 0.10 0.40 0.3 48 91 high street -0.220111 -0.519553 17 Inter 0.065 0.08 0.47 0.4 48 351 loop 1 -0.219817 -0.519807 15 Inter 0.043 0.05 0.51 0.5 48 319 loop 1 -0.220067 -0.520109 13* Waypt 0.043 0.05 0.55 0.5 48 230 loop 1 -0.220671 -0.520223 11* Junct 0.068 0.09 0.62 0.6 48 190 loop 1 -0.220666 -0.520893 5* Junct 0.074 0.09 0.70 0.7 48 270 high street -0.221308 -0.520914 4* Junct- 0.071 0.04 0.77 0.8 96 181 main 1 -0.221561 -0.520922 -3 Waypt 0.027 0.02 0.79 0.8 96 181 main 1 routino-3.0/src/test/expected/loops-WP05.txt 644 233 144 3337 12064636362 14176 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.219562 -0.520851 -1 Waypt 0.000 0.00 0.00 0.0 -0.220223 -0.520885 5* Junct- 0.073 0.04 0.07 0.0 96 182 main 1 -0.220666 -0.520893 4* Junct 0.049 0.03 0.12 0.1 96 181 main 1 -0.220695 -0.519489 11* Junct 0.156 0.20 0.28 0.3 48 91 high street -0.220280 -0.519256 15* Junct- 0.052 0.07 0.33 0.3 48 29 loop 1 -0.219910 -0.519112 17 Inter 0.044 0.06 0.37 0.4 48 21 loop 1 -0.219237 -0.519286 13* Junct 0.077 0.10 0.45 0.5 48 345 loop 1 -0.218764 -0.519471 12 Inter 0.056 0.07 0.51 0.6 48 338 loop 1 -0.218380 -0.519134 16 Waypt 0.056 0.07 0.56 0.6 48 41 loop 1 -0.218776 -0.518838 18 Inter 0.055 0.07 0.62 0.7 48 143 loop 1 -0.219237 -0.519286 13* Junct 0.071 0.09 0.69 0.8 48 224 loop 1 -0.219910 -0.519112 17 Inter 0.077 0.10 0.77 0.9 48 165 loop 1 -0.220280 -0.519256 15* Junct- 0.044 0.06 0.81 0.9 48 201 loop 1 -0.220695 -0.519489 11* Junct 0.052 0.07 0.86 1.0 48 209 loop 1 -0.220739 -0.517801 19* Junct 0.187 0.23 1.05 1.2 48 91 high street -0.220784 -0.516035 30* Junct 0.196 0.24 1.25 1.5 48 91 high street -0.220311 -0.516015 31* Junct- 0.052 0.03 1.30 1.5 96 2 main 2 -0.219596 -0.515984 -3 Waypt 0.079 0.05 1.38 1.6 96 2 main 2 routino-3.0/src/test/expected/dead-ends-WP11.txt 644 233 144 3265 12154145517 14660 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.219535 -0.521016 -1 Waypt 0.000 0.00 0.00 0.0 -0.220223 -0.521052 5* Junct- 0.076 0.05 0.08 0.0 96 182 main 1 -0.220666 -0.521060 4* Junct 0.049 0.03 0.12 0.1 96 180 main 1 -0.220702 -0.519478 12* Junct 0.176 0.22 0.30 0.3 48 91 high street -0.220739 -0.517804 18* Junct 0.186 0.23 0.49 0.5 48 91 high street -0.220782 -0.516137 24* Junct 0.185 0.23 0.67 0.8 48 91 high street -0.220361 -0.515961 25* Junct- 0.050 0.06 0.72 0.8 48 22 dead-end 3 -0.220019 -0.515847 26 Inter 0.040 0.05 0.76 0.9 48 18 dead-end 3 -0.219341 -0.516206 23 Inter 0.085 0.10 0.85 1.0 48 332 dead-end 3 -0.218493 -0.515789 27* Waypt 0.105 0.13 0.95 1.1 48 26 dead-end 3 -0.219341 -0.516206 23 Inter 0.105 0.13 1.06 1.2 48 206 dead-end 3 -0.220019 -0.515847 26 Inter 0.085 0.10 1.14 1.3 48 152 dead-end 3 -0.220361 -0.515961 25* Junct- 0.040 0.05 1.18 1.4 48 198 dead-end 3 -0.220782 -0.516137 24* Junct 0.050 0.06 1.23 1.5 48 202 dead-end 3 -0.220817 -0.514062 32* Junct 0.230 0.29 1.46 1.7 48 90 high street -0.220344 -0.514042 33* Junct- 0.052 0.03 1.51 1.8 96 2 main 2 -0.219539 -0.514007 -3 Waypt 0.089 0.06 1.60 1.8 96 2 main 2 routino-3.0/src/test/expected/fake-node-with-loop-WP02.txt 644 233 144 2420 12327215464 16576 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.216959 -0.520771 -1 Waypt 0.000 0.00 0.00 0.0 -0.217286 -0.520780 10 Junct- 0.036 0.02 0.04 0.0 96 181 main 1 -0.218523 -0.520806 9 Junct- 0.137 0.09 0.17 0.1 96 181 main 1 -0.219171 -0.520827 -2 Waypt 0.071 0.04 0.24 0.1 96 181 main 1 -0.219482 -0.520837 8* Junct 0.034 0.02 0.28 0.2 96 181 main 1 -0.219692 -0.520509 14 Junct- 0.043 0.03 0.32 0.2 96 122 roundabout -0.220082 -0.520522 13 Junct- 0.043 0.03 0.36 0.2 96 181 roundabout -0.220268 -0.520863 7 Inter 0.043 0.03 0.41 0.2 96 241 roundabout -0.220062 -0.521204 4 Junct- 0.044 0.03 0.45 0.3 96 301 roundabout -0.219665 -0.521190 5 Junct- 0.044 0.03 0.49 0.3 96 1 roundabout -0.219482 -0.520837 8* Junct 0.044 0.03 0.54 0.3 96 62 roundabout -0.218842 -0.520816 -3 Waypt 0.070 0.04 0.61 0.4 96 1 main 1 routino-3.0/src/test/expected/dead-ends-WP01.txt 644 233 144 2301 12154145517 14645 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.219535 -0.521016 -1 Waypt 0.000 0.00 0.00 0.0 -0.220223 -0.521052 5* Junct- 0.076 0.05 0.08 0.0 96 182 main 1 -0.220666 -0.521060 4* Junct 0.049 0.03 0.12 0.1 96 180 main 1 -0.220702 -0.519478 12* Junct 0.176 0.22 0.30 0.3 48 91 high street -0.220263 -0.519309 13* Waypt 0.052 0.07 0.35 0.4 48 21 dead-end 1 -0.220702 -0.519478 12* Junct 0.052 0.07 0.41 0.4 48 201 dead-end 1 -0.220739 -0.517804 18* Junct 0.186 0.23 0.59 0.7 48 91 high street -0.220782 -0.516137 24* Junct 0.185 0.23 0.78 0.9 48 91 high street -0.220817 -0.514062 32* Junct 0.230 0.29 1.01 1.2 48 90 high street -0.220344 -0.514042 33* Junct- 0.052 0.03 1.06 1.2 96 2 main 2 -0.219539 -0.514007 -3 Waypt 0.089 0.06 1.15 1.3 96 2 main 2 routino-3.0/src/test/expected/coincident-waypoint-WP04.txt 644 233 144 1172 12333376614 17023 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.217286 -0.520780 7 Waypt 0.000 0.00 0.00 0.0 -0.217286 -0.520780 7 Waypt 0.000 0.00 0.00 0.0 96 270 main 1 -0.218523 -0.520806 6 Waypt 0.137 0.09 0.14 0.1 96 181 main 1 -0.218523 -0.520806 6 Waypt 0.000 0.00 0.14 0.1 96 270 main 1 routino-3.0/src/test/expected/node-restrictions-WP02.txt 644 233 144 3420 12064636362 16503 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.219564 -0.520846 -1 Waypt 0.000 0.00 0.00 0.0 -0.220666 -0.520893 4* Junct 0.122 0.07 0.12 0.1 96 182 main 1 -0.220682 -0.520141 9* Junct 0.083 0.08 0.20 0.2 64 91 high street -0.220695 -0.519489 12* Change 0.072 0.07 0.28 0.2 64 91 high street -0.221123 -0.519360 13 Inter 0.049 0.06 0.33 0.3 48 163 somepass road -0.221154 -0.518671 -2 Waypt 0.075 0.09 0.40 0.4 48 92 somepass road -0.221123 -0.519360 13 Inter 0.075 0.09 0.48 0.5 48 272 somepass road -0.220695 -0.519489 12* Junct 0.049 0.06 0.53 0.5 48 343 somepass road -0.220694 -0.519227 15 Inter 0.029 0.04 0.55 0.6 48 89 long road -0.220386 -0.519076 16 Inter 0.038 0.05 0.59 0.6 48 26 long road -0.220961 -0.518928 17 Inter 0.066 0.08 0.66 0.7 48 165 long road -0.220427 -0.518622 18 Inter 0.068 0.09 0.73 0.8 48 29 long road -0.220949 -0.518422 21 Inter 0.062 0.08 0.79 0.8 48 159 long road -0.220455 -0.518238 22 Inter 0.058 0.07 0.85 0.9 48 20 long road -0.220746 -0.518070 23 Inter 0.037 0.04 0.88 1.0 48 149 long road -0.220739 -0.517801 26* Junct 0.029 0.04 0.91 1.0 48 88 long road -0.220784 -0.516035 31* Junct 0.196 0.18 1.11 1.2 64 91 high street -0.219593 -0.515985 -3 Waypt 0.132 0.08 1.24 1.3 96 2 main 2 routino-3.0/src/test/expected/dead-ends-WP09.txt 644 233 144 2551 12154145517 14664 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.219535 -0.521016 -1 Waypt 0.000 0.00 0.00 0.0 -0.220223 -0.521052 5* Junct- 0.076 0.05 0.08 0.0 96 182 main 1 -0.220666 -0.521060 4* Junct 0.049 0.03 0.12 0.1 96 180 main 1 -0.220702 -0.519478 12* Junct 0.176 0.22 0.30 0.3 48 91 high street -0.220739 -0.517804 18* Junct 0.186 0.23 0.49 0.5 48 91 high street -0.220782 -0.516137 24* Junct 0.185 0.23 0.67 0.8 48 91 high street -0.220361 -0.515961 25* Junct- 0.050 0.06 0.72 0.8 48 22 dead-end 3 -0.220019 -0.515847 26 Waypt 0.040 0.05 0.76 0.9 48 18 dead-end 3 -0.220361 -0.515961 25* Junct- 0.040 0.05 0.80 0.9 48 198 dead-end 3 -0.220782 -0.516137 24* Junct 0.050 0.06 0.85 1.0 48 202 dead-end 3 -0.220817 -0.514062 32* Junct 0.230 0.29 1.08 1.3 48 90 high street -0.220344 -0.514042 33* Junct- 0.052 0.03 1.13 1.3 96 2 main 2 -0.219539 -0.514007 -3 Waypt 0.089 0.06 1.22 1.4 96 2 main 2 routino-3.0/src/test/expected/node-restrictions-WP01.txt 644 233 144 3420 12064636362 16502 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.219564 -0.520846 -1 Waypt 0.000 0.00 0.00 0.0 -0.220666 -0.520893 4* Junct 0.122 0.07 0.12 0.1 96 182 main 1 -0.220682 -0.520141 9* Junct 0.083 0.08 0.20 0.2 64 91 high street -0.220695 -0.519489 12* Change 0.072 0.07 0.28 0.2 64 91 high street -0.221123 -0.519360 13 Inter 0.049 0.06 0.33 0.3 48 163 somepass road -0.221156 -0.518615 19* Waypt 0.082 0.10 0.41 0.4 48 92 somepass road -0.221123 -0.519360 13 Inter 0.082 0.10 0.49 0.5 48 272 somepass road -0.220695 -0.519489 12* Junct 0.049 0.06 0.54 0.5 48 343 somepass road -0.220694 -0.519227 15 Inter 0.029 0.04 0.57 0.6 48 89 long road -0.220386 -0.519076 16 Inter 0.038 0.05 0.61 0.6 48 26 long road -0.220961 -0.518928 17 Inter 0.066 0.08 0.67 0.7 48 165 long road -0.220427 -0.518622 18 Inter 0.068 0.09 0.74 0.8 48 29 long road -0.220949 -0.518422 21 Inter 0.062 0.08 0.80 0.9 48 159 long road -0.220455 -0.518238 22 Inter 0.058 0.07 0.86 0.9 48 20 long road -0.220746 -0.518070 23 Inter 0.037 0.04 0.90 1.0 48 149 long road -0.220739 -0.517801 26* Junct 0.029 0.04 0.93 1.0 48 88 long road -0.220784 -0.516035 31* Junct 0.196 0.18 1.12 1.2 64 91 high street -0.219593 -0.515985 -3 Waypt 0.132 0.08 1.25 1.3 96 2 main 2 routino-3.0/src/test/expected/loops-WP02.txt 644 233 144 3337 12333160116 14157 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.219562 -0.520851 -1 Waypt 0.000 0.00 0.00 0.0 -0.220223 -0.520885 5* Junct- 0.073 0.04 0.07 0.0 96 182 main 1 -0.220666 -0.520893 4* Junct 0.049 0.03 0.12 0.1 96 181 main 1 -0.220695 -0.519489 11* Junct 0.156 0.20 0.28 0.3 48 91 high street -0.220280 -0.519256 15* Junct- 0.052 0.07 0.33 0.3 48 29 loop 1 -0.219910 -0.519112 17 Waypt 0.044 0.06 0.37 0.4 48 21 loop 1 -0.219237 -0.519286 13* Junct 0.077 0.10 0.45 0.5 48 345 loop 1 -0.218764 -0.519471 12 Inter 0.056 0.07 0.51 0.6 48 338 loop 1 -0.218380 -0.519134 16 Inter 0.056 0.07 0.56 0.6 48 41 loop 1 -0.218776 -0.518838 18 Inter 0.055 0.07 0.62 0.7 48 143 loop 1 -0.219237 -0.519286 13* Junct 0.071 0.09 0.69 0.8 48 224 loop 1 -0.219910 -0.519112 17 Inter 0.077 0.10 0.77 0.9 48 165 loop 1 -0.220280 -0.519256 15* Junct- 0.044 0.06 0.81 0.9 48 201 loop 1 -0.220695 -0.519489 11* Junct 0.052 0.07 0.86 1.0 48 209 loop 1 -0.220739 -0.517801 19* Junct 0.187 0.23 1.05 1.2 48 91 high street -0.220784 -0.516035 30* Junct 0.196 0.24 1.25 1.5 48 91 high street -0.220311 -0.516015 31* Junct- 0.052 0.03 1.30 1.5 96 2 main 2 -0.219596 -0.515984 -3 Waypt 0.079 0.05 1.38 1.6 96 2 main 2 routino-3.0/src/test/expected/turns-WP12.txt 644 233 144 4573 12064636362 14216 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.218453 -0.520799 -1 Waypt 0.000 0.00 0.00 0.0 -0.219107 -0.520828 6* Junct 0.072 0.04 0.07 0.0 96 182 main 1 -0.219123 -0.520207 12* Junct 0.069 0.09 0.14 0.1 48 91 top road -0.219131 -0.519426 20* Junct 0.086 0.11 0.23 0.2 48 90 top road -0.219135 -0.518823 23* Junct 0.067 0.08 0.29 0.3 48 90 top road -0.219145 -0.517626 33* Junct 0.133 0.17 0.43 0.5 48 90 top road -0.219144 -0.517257 36* Junct 0.041 0.05 0.47 0.5 48 89 top road -0.219291 -0.517193 38 Inter 0.017 0.02 0.48 0.6 48 156 roundabout -0.219352 -0.517060 42 Junct- 0.016 0.02 0.50 0.6 48 114 roundabout -0.219304 -0.516904 45 Inter 0.018 0.02 0.52 0.6 48 72 roundabout -0.219153 -0.516826 46* Junct- 0.018 0.02 0.54 0.6 48 27 roundabout -0.218966 -0.516910 44 Inter 0.022 0.03 0.56 0.6 48 335 roundabout -0.218923 -0.517072 39 Junct- 0.018 0.02 0.58 0.7 48 284 roundabout -0.218998 -0.517207 37 Inter 0.017 0.02 0.59 0.7 48 240 roundabout -0.219144 -0.517257 36* Junct 0.017 0.02 0.61 0.7 48 199 roundabout -0.219145 -0.517626 33* Junct 0.041 0.05 0.65 0.8 48 269 top road -0.219135 -0.518823 23* Junct 0.133 0.17 0.79 0.9 48 270 top road -0.219131 -0.519426 20* Junct 0.067 0.08 0.85 1.0 48 270 top road -0.218482 -0.519542 18* Inter 0.073 0.09 0.93 1.1 48 349 loop 4 -0.218258 -0.519789 16 Waypt 0.037 0.04 0.96 1.1 48 312 loop 4 -0.218474 -0.520060 14* Inter 0.038 0.05 1.00 1.2 48 231 loop 4 -0.219123 -0.520207 12* Junct 0.074 0.09 1.07 1.3 48 192 loop 4 -0.219107 -0.520828 6* Junct 0.069 0.09 1.14 1.4 48 271 top road -0.220666 -0.520893 5* Junct- 0.173 0.11 1.32 1.5 96 182 main 1 -0.221308 -0.520914 4* Junct- 0.071 0.04 1.39 1.5 96 181 main 1 -0.221561 -0.520922 -3 Waypt 0.027 0.02 1.41 1.5 96 181 main 1 routino-3.0/src/test/expected/loops-WP09.txt 644 233 144 3457 12064636362 14205 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.219562 -0.520851 -1 Waypt 0.000 0.00 0.00 0.0 -0.220223 -0.520885 5* Junct- 0.073 0.04 0.07 0.0 96 182 main 1 -0.220666 -0.520893 4* Junct 0.049 0.03 0.12 0.1 96 181 main 1 -0.220695 -0.519489 11* Junct 0.156 0.20 0.28 0.3 48 91 high street -0.220739 -0.517801 19* Junct 0.187 0.23 0.47 0.5 48 91 high street -0.220301 -0.517576 22* Junct- 0.054 0.07 0.52 0.6 48 27 loop 2 -0.219946 -0.517397 24 Inter 0.044 0.06 0.56 0.6 48 26 loop 2 -0.219266 -0.517579 21* Junct 0.078 0.10 0.64 0.7 48 345 loop 2 -0.219013 -0.517333 -2 Waypt 0.039 0.05 0.68 0.8 48 44 loop 2 -0.218805 -0.517131 25 Inter 0.032 0.04 0.71 0.8 48 44 loop 2 -0.218417 -0.517462 23* Junct- 0.056 0.07 0.77 0.9 48 319 loop 2 -0.218794 -0.517763 20 Inter 0.053 0.07 0.82 0.9 48 218 loop 2 -0.219266 -0.517579 21* Junct 0.056 0.07 0.88 1.0 48 158 loop 2 -0.219946 -0.517397 24 Inter 0.078 0.10 0.95 1.1 48 165 loop 2 -0.220301 -0.517576 22* Junct- 0.044 0.06 1.00 1.2 48 206 loop 2 -0.220739 -0.517801 19* Junct 0.054 0.07 1.05 1.2 48 207 loop 2 -0.220784 -0.516035 30* Junct 0.196 0.24 1.25 1.5 48 91 high street -0.220311 -0.516015 31* Junct- 0.052 0.03 1.30 1.5 96 2 main 2 -0.219596 -0.515984 -3 Waypt 0.079 0.05 1.38 1.6 96 2 main 2 routino-3.0/src/test/expected/turns-WP14.txt 644 233 144 6532 12064636362 14215 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.218453 -0.520799 -1 Waypt 0.000 0.00 0.00 0.0 -0.219107 -0.520828 6* Junct 0.072 0.04 0.07 0.0 96 182 main 1 -0.219123 -0.520207 12* Junct 0.069 0.09 0.14 0.1 48 91 top road -0.219131 -0.519426 20* Junct 0.086 0.11 0.23 0.2 48 90 top road -0.219135 -0.518823 23* Junct 0.067 0.08 0.29 0.3 48 90 top road -0.219145 -0.517626 33* Junct 0.133 0.17 0.43 0.5 48 90 top road -0.219144 -0.517257 36* Junct 0.041 0.05 0.47 0.5 48 89 top road -0.219291 -0.517193 38 Inter 0.017 0.02 0.48 0.6 48 156 roundabout -0.219352 -0.517060 42 Junct- 0.016 0.02 0.50 0.6 48 114 roundabout -0.219304 -0.516904 45 Inter 0.018 0.02 0.52 0.6 48 72 roundabout -0.219153 -0.516826 46* Junct- 0.018 0.02 0.54 0.6 48 27 roundabout -0.218966 -0.516910 44 Inter 0.022 0.03 0.56 0.6 48 335 roundabout -0.218923 -0.517072 39 Junct- 0.018 0.02 0.58 0.7 48 284 roundabout -0.218998 -0.517207 37 Inter 0.017 0.02 0.59 0.7 48 240 roundabout -0.219144 -0.517257 36* Junct 0.017 0.02 0.61 0.7 48 199 roundabout -0.219145 -0.517626 33* Junct 0.041 0.05 0.65 0.8 48 269 top road -0.218619 -0.517921 32* Inter 0.067 0.08 0.72 0.8 48 330 loop 5 -0.218431 -0.518243 28 Inter 0.041 0.05 0.76 0.9 48 300 loop 5 -0.218600 -0.518557 25* Waypt 0.039 0.05 0.80 0.9 48 241 loop 5 -0.219135 -0.518823 23* Junct 0.066 0.08 0.86 1.0 48 206 loop 5 -0.219145 -0.517626 33* Junct 0.133 0.17 1.00 1.2 48 90 top road -0.219144 -0.517257 36* Junct 0.041 0.05 1.04 1.2 48 89 top road -0.219291 -0.517193 38 Inter 0.017 0.02 1.06 1.3 48 156 roundabout -0.219352 -0.517060 42 Junct- 0.016 0.02 1.07 1.3 48 114 roundabout -0.219304 -0.516904 45 Inter 0.018 0.02 1.09 1.3 48 72 roundabout -0.219153 -0.516826 46* Junct- 0.018 0.02 1.11 1.3 48 27 roundabout -0.218966 -0.516910 44 Inter 0.022 0.03 1.13 1.3 48 335 roundabout -0.218923 -0.517072 39 Junct- 0.018 0.02 1.15 1.4 48 284 roundabout -0.218998 -0.517207 37 Inter 0.017 0.02 1.17 1.4 48 240 roundabout -0.219144 -0.517257 36* Junct 0.017 0.02 1.18 1.4 48 199 roundabout -0.219145 -0.517626 33* Junct 0.041 0.05 1.22 1.5 48 269 top road -0.219135 -0.518823 23* Junct 0.133 0.17 1.36 1.6 48 270 top road -0.219131 -0.519426 20* Junct 0.067 0.08 1.42 1.7 48 270 top road -0.219123 -0.520207 12* Junct 0.086 0.11 1.51 1.8 48 270 top road -0.219107 -0.520828 6* Junct 0.069 0.09 1.58 1.9 48 271 top road -0.220666 -0.520893 5* Junct- 0.173 0.11 1.75 2.0 96 182 main 1 -0.221308 -0.520914 4* Junct- 0.071 0.04 1.82 2.0 96 181 main 1 -0.221561 -0.520922 -3 Waypt 0.027 0.02 1.85 2.1 96 181 main 1 routino-3.0/src/test/expected/oneway-loop-WP01.txt 644 233 144 2317 12064636362 15304 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.219564 -0.520846 -1 Waypt 0.000 0.00 0.00 0.0 -0.220666 -0.520893 4* Junct 0.122 0.07 0.12 0.1 96 182 main 1 -0.220695 -0.519489 9* Inter 0.156 0.20 0.28 0.3 48 91 high street -0.220739 -0.517801 12* Junct 0.187 0.23 0.47 0.5 48 91 high street -0.220405 -0.517799 13 Inter 0.037 0.04 0.50 0.5 48 0 reverse loop -0.220210 -0.518605 11 Waypt 0.092 0.12 0.59 0.7 48 283 reverse loop -0.220333 -0.519485 10 Inter 0.098 0.12 0.69 0.8 48 262 reverse loop -0.220695 -0.519489 9* Inter 0.040 0.05 0.73 0.8 48 180 reverse loop -0.220739 -0.517801 12* Junct 0.187 0.23 0.92 1.1 48 91 high street -0.220784 -0.516035 18* Junct 0.196 0.24 1.11 1.3 48 91 high street -0.219593 -0.515985 -3 Waypt 0.132 0.08 1.25 1.4 96 2 main 2 routino-3.0/src/test/expected/node-restrictions-WP04.txt 644 233 144 3410 12064636362 16504 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.219564 -0.520846 -1 Waypt 0.000 0.00 0.00 0.0 -0.220666 -0.520893 4* Junct 0.122 0.07 0.12 0.1 96 182 main 1 -0.220682 -0.520141 9* Junct 0.083 0.08 0.20 0.2 64 91 high street -0.220695 -0.519489 12* Change 0.072 0.07 0.28 0.2 64 91 high street -0.220140 -0.519342 14 Inter 0.063 0.08 0.34 0.3 48 14 nopass road -0.220173 -0.518597 20 Waypt 0.082 0.10 0.42 0.4 48 92 nopass road -0.220140 -0.519342 14 Inter 0.082 0.10 0.50 0.5 48 272 nopass road -0.220695 -0.519489 12* Junct 0.063 0.08 0.57 0.6 48 194 nopass road -0.220694 -0.519227 15 Inter 0.029 0.04 0.60 0.6 48 89 long road -0.220386 -0.519076 16 Inter 0.038 0.05 0.63 0.7 48 26 long road -0.220961 -0.518928 17 Inter 0.066 0.08 0.70 0.7 48 165 long road -0.220427 -0.518622 18 Inter 0.068 0.09 0.77 0.8 48 29 long road -0.220949 -0.518422 21 Inter 0.062 0.08 0.83 0.9 48 159 long road -0.220455 -0.518238 22 Inter 0.058 0.07 0.89 1.0 48 20 long road -0.220746 -0.518070 23 Inter 0.037 0.04 0.93 1.0 48 149 long road -0.220739 -0.517801 26* Junct 0.029 0.04 0.95 1.1 48 88 long road -0.220784 -0.516035 31* Junct 0.196 0.18 1.15 1.2 64 91 high street -0.219593 -0.515985 -3 Waypt 0.132 0.08 1.28 1.3 96 2 main 2 routino-3.0/src/test/expected/turns-WP08.txt 644 233 144 4461 12064636362 14217 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.218453 -0.520799 -1 Waypt 0.000 0.00 0.00 0.0 -0.219107 -0.520828 6* Junct 0.072 0.04 0.07 0.0 96 182 main 1 -0.219123 -0.520207 12* Junct 0.069 0.09 0.14 0.1 48 91 top road -0.219131 -0.519426 20* Junct 0.086 0.11 0.23 0.2 48 90 top road -0.219135 -0.518823 23* Junct 0.067 0.08 0.29 0.3 48 90 top road -0.219145 -0.517626 33* Junct 0.133 0.17 0.43 0.5 48 90 top road -0.219144 -0.517257 36* Junct 0.041 0.05 0.47 0.5 48 89 top road -0.219291 -0.517193 38 Inter 0.017 0.02 0.48 0.6 48 156 roundabout -0.219352 -0.517060 42 Junct- 0.016 0.02 0.50 0.6 48 114 roundabout -0.219304 -0.516904 45 Inter 0.018 0.02 0.52 0.6 48 72 roundabout -0.219153 -0.516826 46* Junct 0.018 0.02 0.54 0.6 48 27 roundabout -0.219184 -0.515968 55* Junct 0.095 0.12 0.63 0.7 48 92 top road -0.220784 -0.516035 54* Junct 0.178 0.11 0.81 0.8 96 182 main 2 -0.220760 -0.516647 48* Junct 0.068 0.09 0.88 0.9 48 272 high street -0.220097 -0.516762 47* Inter 0.074 0.09 0.95 1.0 48 350 loop 3 -0.219872 -0.517009 43 Inter 0.037 0.04 0.99 1.1 48 312 loop 3 -0.220089 -0.517279 35* Waypt 0.038 0.05 1.03 1.1 48 231 loop 3 -0.220739 -0.517425 34* Junct 0.074 0.09 1.10 1.2 48 192 loop 3 -0.220724 -0.518071 31* Junct 0.071 0.09 1.17 1.3 48 271 high street -0.220708 -0.518842 22* Junct 0.085 0.10 1.26 1.4 48 271 high street -0.220691 -0.519461 19* Junct 0.069 0.09 1.33 1.5 48 271 high street -0.220671 -0.520223 11* Junct 0.084 0.10 1.41 1.6 48 271 high street -0.220666 -0.520893 5* Junct 0.074 0.09 1.48 1.7 48 270 high street -0.221308 -0.520914 4* Junct- 0.071 0.04 1.55 1.7 96 181 main 1 -0.221561 -0.520922 -3 Waypt 0.027 0.02 1.58 1.7 96 181 main 1 routino-3.0/src/test/expected/super-or-not-WP02.txt 644 233 144 1205 12064636362 15401 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.216828 -0.519457 -1 Waypt 0.000 0.00 0.00 0.0 -0.217245 -0.519637 2* Junct 0.050 0.06 0.05 0.1 48 203 Local road -0.217248 -0.515206 10* Junct 0.493 0.31 0.54 0.4 96 90 Main road -0.216919 -0.515308 -2 Waypt 0.038 0.05 0.58 0.4 48 342 Local road routino-3.0/src/test/expected/roundabout-waypoints-WP01.txt 644 233 144 1446 12317763605 17254 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.218454 -0.520798 -1 Waypt 0.000 0.00 0.00 0.0 -0.219482 -0.520837 9* Waypt 0.113 0.07 0.11 0.1 96 182 main 1 -0.219692 -0.520509 15 Junct- 0.043 0.03 0.16 0.1 96 122 roundabout -0.220082 -0.520522 14 Junct- 0.043 0.03 0.20 0.1 96 181 roundabout -0.220268 -0.520863 8* Junct 0.043 0.03 0.24 0.1 96 241 roundabout -0.221566 -0.520921 -3 Waypt 0.143 0.09 0.39 0.2 96 182 main 2 routino-3.0/src/test/expected/loops-WP01.txt 644 233 144 3336 12333160116 14155 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.219562 -0.520851 -1 Waypt 0.000 0.00 0.00 0.0 -0.220223 -0.520885 5* Junct- 0.073 0.04 0.07 0.0 96 182 main 1 -0.220666 -0.520893 4* Junct 0.049 0.03 0.12 0.1 96 181 main 1 -0.220695 -0.519489 11* Junct 0.156 0.20 0.28 0.3 48 91 high street -0.220280 -0.519256 15* Waypt 0.052 0.07 0.33 0.3 48 29 loop 1 -0.219910 -0.519112 17 Inter 0.044 0.06 0.37 0.4 48 21 loop 1 -0.219237 -0.519286 13* Junct 0.077 0.10 0.45 0.5 48 345 loop 1 -0.218764 -0.519471 12 Inter 0.056 0.07 0.51 0.6 48 338 loop 1 -0.218380 -0.519134 16 Inter 0.056 0.07 0.56 0.6 48 41 loop 1 -0.218776 -0.518838 18 Inter 0.055 0.07 0.62 0.7 48 143 loop 1 -0.219237 -0.519286 13* Junct 0.071 0.09 0.69 0.8 48 224 loop 1 -0.219910 -0.519112 17 Inter 0.077 0.10 0.77 0.9 48 165 loop 1 -0.220280 -0.519256 15* Junct- 0.044 0.06 0.81 0.9 48 201 loop 1 -0.220695 -0.519489 11* Junct 0.052 0.07 0.86 1.0 48 209 loop 1 -0.220739 -0.517801 19* Junct 0.187 0.23 1.05 1.2 48 91 high street -0.220784 -0.516035 30* Junct 0.196 0.24 1.25 1.5 48 91 high street -0.220311 -0.516015 31* Junct- 0.052 0.03 1.30 1.5 96 2 main 2 -0.219596 -0.515984 -3 Waypt 0.079 0.05 1.38 1.6 96 2 main 2 routino-3.0/src/test/expected/roundabout-waypoints-WP07.txt 644 233 144 1446 12317763605 17262 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.218454 -0.520798 -1 Waypt 0.000 0.00 0.00 0.0 -0.219482 -0.520837 9* Junct 0.113 0.07 0.11 0.1 96 182 main 1 -0.219692 -0.520509 15 Junct- 0.043 0.03 0.16 0.1 96 122 roundabout -0.220082 -0.520522 14 Junct- 0.043 0.03 0.20 0.1 96 181 roundabout -0.220268 -0.520863 8* Waypt 0.043 0.03 0.24 0.1 96 241 roundabout -0.221566 -0.520921 -3 Waypt 0.143 0.09 0.39 0.2 96 182 main 2 routino-3.0/src/test/expected/cycle-both-ways-WP02.txt 644 233 144 2177 12327514136 16046 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.221402 -0.520913 -1 Waypt 0.000 0.00 0.00 0.0 -0.220268 -0.520863 8* Junct 0.125 0.38 0.12 0.4 20 2 main 2 -0.220062 -0.521204 2 Inter 0.044 0.13 0.17 0.5 20 301 roundabout -0.219665 -0.521190 3 Junct- 0.044 0.13 0.21 0.6 20 1 roundabout -0.219482 -0.520837 9* Junct- 0.044 0.13 0.26 0.8 20 62 roundabout -0.219692 -0.520509 15* Junct- 0.043 0.13 0.30 0.9 20 122 roundabout -0.220082 -0.520522 14* Junct 0.043 0.13 0.34 1.0 20 181 roundabout -0.220768 -0.519742 16 Inter 0.115 0.34 0.46 1.4 20 131 residential road -0.220811 -0.518939 19* Junct 0.089 0.27 0.55 1.6 20 93 residential road -0.221319 -0.518949 -2 Waypt 0.056 0.17 0.60 1.8 20 181 main 3 routino-3.0/src/test/expected/loops-WP06.txt 644 233 144 3337 12333160116 14163 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.219562 -0.520851 -1 Waypt 0.000 0.00 0.00 0.0 -0.220223 -0.520885 5* Junct- 0.073 0.04 0.07 0.0 96 182 main 1 -0.220666 -0.520893 4* Junct 0.049 0.03 0.12 0.1 96 181 main 1 -0.220695 -0.519489 11* Junct 0.156 0.20 0.28 0.3 48 91 high street -0.220739 -0.517801 19* Junct 0.187 0.23 0.47 0.5 48 91 high street -0.220301 -0.517576 22* Waypt 0.054 0.07 0.52 0.6 48 27 loop 2 -0.219946 -0.517397 24 Inter 0.044 0.06 0.56 0.6 48 26 loop 2 -0.219266 -0.517579 21* Junct 0.078 0.10 0.64 0.7 48 345 loop 2 -0.218794 -0.517763 20 Inter 0.056 0.07 0.70 0.8 48 338 loop 2 -0.218417 -0.517462 23* Junct- 0.053 0.07 0.75 0.9 48 38 loop 2 -0.218805 -0.517131 25 Inter 0.056 0.07 0.81 0.9 48 139 loop 2 -0.219266 -0.517579 21* Junct 0.071 0.09 0.88 1.0 48 224 loop 2 -0.219946 -0.517397 24 Inter 0.078 0.10 0.95 1.1 48 165 loop 2 -0.220301 -0.517576 22* Junct- 0.044 0.06 1.00 1.2 48 206 loop 2 -0.220739 -0.517801 19* Junct 0.054 0.07 1.05 1.2 48 207 loop 2 -0.220784 -0.516035 30* Junct 0.196 0.24 1.25 1.5 48 91 high street -0.220311 -0.516015 31* Junct- 0.052 0.03 1.30 1.5 96 2 main 2 -0.219596 -0.515984 -3 Waypt 0.079 0.05 1.38 1.6 96 2 main 2 routino-3.0/src/test/expected/no-super-WP02.txt 644 233 144 1051 12064636362 14576 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.216472 -0.519026 -1 Waypt 0.000 0.00 0.00 0.0 -0.216671 -0.515660 -2 Waypt 0.374 0.47 0.37 0.5 48 93 road2 -0.216579 -0.517212 -3 Waypt 0.172 0.21 0.55 0.7 48 273 road2 routino-3.0/src/test/expected/coincident-waypoint-WP03.txt 644 233 144 1432 12333375370 17017 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.217022 -0.520773 -1 Waypt 0.000 0.00 0.00 0.0 -0.217022 -0.520773 -2 Waypt 0.000 0.00 0.00 0.0 96 270 main 1 -0.217286 -0.520780 7 Junct- 0.029 0.02 0.03 0.0 96 181 main 1 -0.218523 -0.520806 6 Junct- 0.137 0.09 0.17 0.1 96 181 main 1 -0.219153 -0.520826 -3 Waypt 0.069 0.04 0.23 0.1 96 181 main 1 -0.219153 -0.520826 -4 Waypt 0.000 0.00 0.23 0.1 96 270 main 1 routino-3.0/src/test/expected/node-restrictions-WP05.txt 644 233 144 3410 12064636362 16505 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.219564 -0.520846 -1 Waypt 0.000 0.00 0.00 0.0 -0.220666 -0.520893 4* Junct 0.122 0.07 0.12 0.1 96 182 main 1 -0.220682 -0.520141 9* Junct 0.083 0.08 0.20 0.2 64 91 high street -0.220695 -0.519489 12* Change 0.072 0.07 0.28 0.2 64 91 high street -0.220140 -0.519342 14 Inter 0.063 0.08 0.34 0.3 48 14 nopass road -0.220170 -0.518653 -2 Waypt 0.075 0.09 0.41 0.4 48 92 nopass road -0.220140 -0.519342 14 Inter 0.075 0.09 0.49 0.5 48 272 nopass road -0.220695 -0.519489 12* Junct 0.063 0.08 0.55 0.6 48 194 nopass road -0.220694 -0.519227 15 Inter 0.029 0.04 0.58 0.6 48 89 long road -0.220386 -0.519076 16 Inter 0.038 0.05 0.62 0.6 48 26 long road -0.220961 -0.518928 17 Inter 0.066 0.08 0.69 0.7 48 165 long road -0.220427 -0.518622 18 Inter 0.068 0.09 0.75 0.8 48 29 long road -0.220949 -0.518422 21 Inter 0.062 0.08 0.82 0.9 48 159 long road -0.220455 -0.518238 22 Inter 0.058 0.07 0.87 1.0 48 20 long road -0.220746 -0.518070 23 Inter 0.037 0.04 0.91 1.0 48 149 long road -0.220739 -0.517801 26* Junct 0.029 0.04 0.94 1.0 48 88 long road -0.220784 -0.516035 31* Junct 0.196 0.18 1.14 1.2 64 91 high street -0.219593 -0.515985 -3 Waypt 0.132 0.08 1.27 1.3 96 2 main 2 routino-3.0/src/test/expected/turns-WP06.txt 644 233 144 3642 12064636362 14215 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.218453 -0.520799 -1 Waypt 0.000 0.00 0.00 0.0 -0.219107 -0.520828 6* Junct- 0.072 0.04 0.07 0.0 96 182 main 1 -0.220666 -0.520893 5* Junct 0.173 0.11 0.24 0.2 96 182 main 1 -0.220671 -0.520223 11* Junct 0.074 0.09 0.32 0.2 48 90 high street -0.220691 -0.519461 19* Junct 0.084 0.10 0.40 0.3 48 91 high street -0.220708 -0.518842 22* Junct 0.069 0.09 0.47 0.4 48 91 high street -0.220724 -0.518071 31* Junct 0.085 0.10 0.56 0.5 48 91 high street -0.220143 -0.518162 30 Inter 0.065 0.08 0.62 0.6 48 351 loop 2 -0.219850 -0.518416 27 Waypt 0.043 0.05 0.67 0.7 48 319 loop 2 -0.220100 -0.518718 24* Inter 0.043 0.05 0.71 0.7 48 230 loop 2 -0.220708 -0.518842 22* Junct 0.069 0.09 0.78 0.8 48 191 loop 2 -0.220724 -0.518071 31* Junct 0.085 0.10 0.86 0.9 48 91 high street -0.220739 -0.517425 34* Junct 0.071 0.09 0.93 1.0 48 91 high street -0.220760 -0.516647 48* Junct 0.086 0.11 1.02 1.1 48 91 high street -0.220784 -0.516035 54* Junct 0.068 0.09 1.09 1.2 48 92 high street -0.221431 -0.516056 53* Junct 0.072 0.04 1.16 1.2 96 181 main 2 -0.221376 -0.518235 29* Junct 0.242 0.30 1.40 1.5 48 271 bottom road -0.221360 -0.518860 21* Junct 0.069 0.09 1.47 1.6 48 271 bottom road -0.221308 -0.520914 4* Junct 0.228 0.28 1.70 1.9 48 271 bottom road -0.221561 -0.520922 -3 Waypt 0.027 0.02 1.73 1.9 96 181 main 1 routino-3.0/src/test/expected/cycle-both-ways-WP01.txt 644 233 144 2172 12327514136 16040 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.221402 -0.520913 -1 Waypt 0.000 0.00 0.00 0.0 -0.220268 -0.520863 8* Junct 0.125 0.08 0.12 0.1 96 2 main 2 -0.220062 -0.521204 2 Inter 0.044 0.03 0.17 0.1 96 301 roundabout -0.219665 -0.521190 3 Inter 0.044 0.03 0.21 0.1 96 1 roundabout -0.219482 -0.520837 9* Junct- 0.044 0.03 0.26 0.2 96 62 roundabout -0.219692 -0.520509 15* Junct 0.043 0.03 0.30 0.2 96 122 roundabout -0.219271 -0.519532 17 Inter 0.118 0.15 0.42 0.3 48 66 residential road -0.219302 -0.518908 20* Junct 0.069 0.09 0.49 0.4 48 92 residential road -0.220811 -0.518939 19* Junct- 0.167 0.10 0.65 0.5 96 181 main 3 -0.221319 -0.518949 -2 Waypt 0.056 0.04 0.71 0.6 96 181 main 3 routino-3.0/src/test/expected/no-super-WP03.txt 644 233 144 1541 12064636362 14603 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.217185 -0.519054 5 Waypt 0.000 0.00 0.00 0.0 -0.217382 -0.518273 8 Inter 0.089 0.11 0.09 0.1 48 104 road3 -0.217219 -0.517733 11 Inter 0.062 0.08 0.15 0.2 48 73 road3 -0.217399 -0.516857 14 Inter 0.099 0.12 0.25 0.3 48 101 road3 -0.217202 -0.515964 17 Waypt 0.101 0.12 0.35 0.4 48 77 road3 -0.217399 -0.516857 14 Inter 0.101 0.12 0.45 0.6 48 257 road3 -0.217219 -0.517733 11 Waypt 0.099 0.12 0.55 0.7 48 281 road3 routino-3.0/src/test/expected/no-super-WP04.txt 644 233 144 2231 12064636362 14601 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.217903 -0.519035 6 Waypt 0.000 0.00 0.00 0.0 -0.218100 -0.518253 9 Inter 0.089 0.11 0.09 0.1 48 104 road4 -0.217937 -0.517713 12 Inter 0.062 0.08 0.15 0.2 48 73 road4 -0.218117 -0.516837 16 Inter 0.099 0.12 0.25 0.3 48 101 road4 -0.217920 -0.515945 18 Inter 0.101 0.12 0.35 0.4 48 77 road4 -0.218143 -0.515189 21 Inter 0.087 0.11 0.44 0.5 48 106 road4 -0.217911 -0.514640 26 Waypt 0.066 0.08 0.50 0.6 48 67 road4 -0.218143 -0.515189 21 Inter 0.066 0.08 0.57 0.7 48 247 road4 -0.217920 -0.515945 18 Inter 0.087 0.11 0.66 0.8 48 286 road4 -0.218117 -0.516837 16 Inter 0.101 0.12 0.76 0.9 48 257 road4 -0.217937 -0.517713 12 Waypt 0.099 0.12 0.86 1.1 48 281 road4 routino-3.0/src/test/expected/dead-ends-WP03.txt 644 233 144 3017 12154145517 14654 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.219535 -0.521016 -1 Waypt 0.000 0.00 0.00 0.0 -0.220223 -0.521052 5* Junct- 0.076 0.05 0.08 0.0 96 182 main 1 -0.220666 -0.521060 4* Junct 0.049 0.03 0.12 0.1 96 180 main 1 -0.220702 -0.519478 12* Junct 0.176 0.22 0.30 0.3 48 91 high street -0.220263 -0.519309 13* Junct- 0.052 0.07 0.35 0.4 48 21 dead-end 1 -0.219924 -0.519179 14 Inter 0.040 0.05 0.39 0.4 48 20 dead-end 1 -0.219567 -0.519373 -2 Waypt 0.045 0.06 0.44 0.5 48 331 dead-end 1 -0.219924 -0.519179 14 Inter 0.045 0.06 0.48 0.5 48 151 dead-end 1 -0.220263 -0.519309 13* Junct- 0.040 0.05 0.52 0.6 48 200 dead-end 1 -0.220702 -0.519478 12* Junct 0.052 0.07 0.57 0.6 48 201 dead-end 1 -0.220739 -0.517804 18* Junct 0.186 0.23 0.76 0.9 48 91 high street -0.220782 -0.516137 24* Junct 0.185 0.23 0.95 1.1 48 91 high street -0.220817 -0.514062 32* Junct 0.230 0.29 1.18 1.4 48 90 high street -0.220344 -0.514042 33* Junct- 0.052 0.03 1.23 1.4 96 2 main 2 -0.219539 -0.514007 -3 Waypt 0.089 0.06 1.32 1.5 96 2 main 2 routino-3.0/src/test/expected/node-restrictions-WP07.txt 644 233 144 3144 12064636362 16513 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.219564 -0.520846 -1 Waypt 0.000 0.00 0.00 0.0 -0.220666 -0.520893 4* Junct 0.122 0.07 0.12 0.1 96 182 main 1 -0.220682 -0.520141 9* Junct 0.083 0.08 0.20 0.2 64 91 high street -0.219009 -0.520075 10* Waypt 0.186 0.17 0.39 0.3 64 2 dead end road -0.220682 -0.520141 9* Junct 0.186 0.17 0.58 0.5 64 182 dead end road -0.220695 -0.519489 12* Change 0.072 0.07 0.65 0.6 64 91 high street -0.220694 -0.519227 15 Inter 0.029 0.04 0.68 0.6 48 89 long road -0.220386 -0.519076 16 Inter 0.038 0.05 0.72 0.6 48 26 long road -0.220961 -0.518928 17 Inter 0.066 0.08 0.78 0.7 48 165 long road -0.220427 -0.518622 18 Inter 0.068 0.09 0.85 0.8 48 29 long road -0.220949 -0.518422 21 Inter 0.062 0.08 0.91 0.9 48 159 long road -0.220455 -0.518238 22 Inter 0.058 0.07 0.97 1.0 48 20 long road -0.220746 -0.518070 23 Inter 0.037 0.04 1.01 1.0 48 149 long road -0.220739 -0.517801 26* Junct 0.029 0.04 1.04 1.0 48 88 long road -0.220784 -0.516035 31* Junct 0.196 0.18 1.23 1.2 64 91 high street -0.219593 -0.515985 -3 Waypt 0.132 0.08 1.36 1.3 96 2 main 2 routino-3.0/src/test/expected/turns-WP07.txt 644 233 144 5050 12064636362 14211 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.218453 -0.520799 -1 Waypt 0.000 0.00 0.00 0.0 -0.219107 -0.520828 6* Junct 0.072 0.04 0.07 0.0 96 182 main 1 -0.219123 -0.520207 12* Junct 0.069 0.09 0.14 0.1 48 91 top road -0.219131 -0.519426 20* Junct 0.086 0.11 0.23 0.2 48 90 top road -0.219135 -0.518823 23* Junct 0.067 0.08 0.29 0.3 48 90 top road -0.219145 -0.517626 33* Junct 0.133 0.17 0.43 0.5 48 90 top road -0.219144 -0.517257 36* Junct 0.041 0.05 0.47 0.5 48 89 top road -0.219291 -0.517193 38 Inter 0.017 0.02 0.48 0.6 48 156 roundabout -0.219352 -0.517060 42 Junct- 0.016 0.02 0.50 0.6 48 114 roundabout -0.219304 -0.516904 45 Inter 0.018 0.02 0.52 0.6 48 72 roundabout -0.219153 -0.516826 46* Junct 0.018 0.02 0.54 0.6 48 27 roundabout -0.219184 -0.515968 55* Junct 0.095 0.12 0.63 0.7 48 92 top road -0.220784 -0.516035 54* Junct 0.178 0.11 0.81 0.8 96 182 main 2 -0.220760 -0.516647 48* Junct 0.068 0.09 0.88 0.9 48 272 high street -0.220739 -0.517425 34* Junct 0.086 0.11 0.96 1.0 48 271 high street -0.220238 -0.517313 -2 Waypt 0.057 0.07 1.02 1.1 48 12 loop 3 -0.220089 -0.517279 35* Inter 0.017 0.02 1.04 1.1 48 12 loop 3 -0.219872 -0.517009 43 Inter 0.038 0.05 1.08 1.2 48 51 loop 3 -0.220097 -0.516762 47* Inter 0.037 0.04 1.11 1.2 48 132 loop 3 -0.220760 -0.516647 48* Junct 0.074 0.09 1.19 1.3 48 170 loop 3 -0.220739 -0.517425 34* Junct 0.086 0.11 1.27 1.4 48 271 high street -0.220724 -0.518071 31* Junct 0.071 0.09 1.34 1.5 48 271 high street -0.220708 -0.518842 22* Junct 0.085 0.10 1.43 1.6 48 271 high street -0.220691 -0.519461 19* Junct 0.069 0.09 1.50 1.7 48 271 high street -0.220671 -0.520223 11* Junct 0.084 0.10 1.58 1.8 48 271 high street -0.220666 -0.520893 5* Junct 0.074 0.09 1.66 1.9 48 270 high street -0.221308 -0.520914 4* Junct- 0.071 0.04 1.73 1.9 96 181 main 1 -0.221561 -0.520922 -3 Waypt 0.027 0.02 1.75 2.0 96 181 main 1 routino-3.0/src/test/expected/turns-WP16.txt 644 233 144 2145 12064636362 14213 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.218453 -0.520799 -1 Waypt 0.000 0.00 0.00 0.0 -0.219107 -0.520828 6* Junct- 0.072 0.04 0.07 0.0 96 182 main 1 -0.220666 -0.520893 5* Junct- 0.173 0.11 0.24 0.2 96 182 main 1 -0.221308 -0.520914 4* Junct 0.071 0.04 0.32 0.2 96 181 main 1 -0.221360 -0.518860 21* Junct 0.228 0.28 0.54 0.5 48 91 bottom road -0.221711 -0.518511 26* Waypt 0.055 0.07 0.60 0.5 48 135 loop 6 -0.221376 -0.518235 29* Junct 0.048 0.06 0.65 0.6 48 39 loop 6 -0.221360 -0.518860 21* Junct 0.069 0.09 0.72 0.7 48 271 bottom road -0.221308 -0.520914 4* Junct 0.228 0.28 0.94 1.0 48 271 bottom road -0.221561 -0.520922 -3 Waypt 0.027 0.02 0.97 1.0 96 181 main 1 routino-3.0/src/test/expected/fake-node-with-loop-WP01.txt 644 233 144 2540 12327215464 16600 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.216904 -0.520770 -1 Waypt 0.000 0.00 0.00 0.0 -0.217286 -0.520780 10 Junct- 0.042 0.03 0.04 0.0 96 181 main 1 -0.218086 -0.520797 -2 Waypt 0.088 0.06 0.13 0.1 96 181 main 1 -0.218523 -0.520806 9 Junct- 0.048 0.03 0.18 0.1 96 181 main 1 -0.219482 -0.520837 8* Junct 0.106 0.07 0.28 0.2 96 181 main 1 -0.219692 -0.520509 14 Junct- 0.043 0.03 0.33 0.2 96 122 roundabout -0.220082 -0.520522 13 Junct- 0.043 0.03 0.37 0.2 96 181 roundabout -0.220268 -0.520863 7 Inter 0.043 0.03 0.41 0.3 96 241 roundabout -0.220062 -0.521204 4 Junct- 0.044 0.03 0.46 0.3 96 301 roundabout -0.219665 -0.521190 5 Junct- 0.044 0.03 0.50 0.3 96 1 roundabout -0.219482 -0.520837 8* Junct 0.044 0.03 0.55 0.3 96 62 roundabout -0.218523 -0.520806 9 Junct- 0.106 0.07 0.65 0.4 96 1 main 1 -0.217741 -0.520789 -3 Waypt 0.086 0.05 0.74 0.5 96 1 main 1 routino-3.0/src/test/expected/loops-WP07.txt 644 233 144 3340 12333160116 14156 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.219562 -0.520851 -1 Waypt 0.000 0.00 0.00 0.0 -0.220223 -0.520885 5* Junct- 0.073 0.04 0.07 0.0 96 182 main 1 -0.220666 -0.520893 4* Junct 0.049 0.03 0.12 0.1 96 181 main 1 -0.220695 -0.519489 11* Junct 0.156 0.20 0.28 0.3 48 91 high street -0.220739 -0.517801 19* Junct 0.187 0.23 0.47 0.5 48 91 high street -0.220301 -0.517576 22* Junct- 0.054 0.07 0.52 0.6 48 27 loop 2 -0.219946 -0.517397 24 Waypt 0.044 0.06 0.56 0.6 48 26 loop 2 -0.219266 -0.517579 21* Junct 0.078 0.10 0.64 0.7 48 345 loop 2 -0.218794 -0.517763 20 Inter 0.056 0.07 0.70 0.8 48 338 loop 2 -0.218417 -0.517462 23* Junct- 0.053 0.07 0.75 0.9 48 38 loop 2 -0.218805 -0.517131 25 Inter 0.056 0.07 0.81 0.9 48 139 loop 2 -0.219266 -0.517579 21* Junct 0.071 0.09 0.88 1.0 48 224 loop 2 -0.219946 -0.517397 24 Inter 0.078 0.10 0.95 1.1 48 165 loop 2 -0.220301 -0.517576 22* Junct- 0.044 0.06 1.00 1.2 48 206 loop 2 -0.220739 -0.517801 19* Junct 0.054 0.07 1.05 1.2 48 207 loop 2 -0.220784 -0.516035 30* Junct 0.196 0.24 1.25 1.5 48 91 high street -0.220311 -0.516015 31* Junct- 0.052 0.03 1.30 1.5 96 2 main 2 -0.219596 -0.515984 -3 Waypt 0.079 0.05 1.38 1.6 96 2 main 2 routino-3.0/src/test/expected/loops-WP10.txt 644 233 144 3340 12064636362 14164 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.219562 -0.520851 -1 Waypt 0.000 0.00 0.00 0.0 -0.220223 -0.520885 5* Junct- 0.073 0.04 0.07 0.0 96 182 main 1 -0.220666 -0.520893 4* Junct 0.049 0.03 0.12 0.1 96 181 main 1 -0.220695 -0.519489 11* Junct 0.156 0.20 0.28 0.3 48 91 high street -0.220739 -0.517801 19* Junct 0.187 0.23 0.47 0.5 48 91 high street -0.220301 -0.517576 22* Junct- 0.054 0.07 0.52 0.6 48 27 loop 2 -0.219946 -0.517397 24 Inter 0.044 0.06 0.56 0.6 48 26 loop 2 -0.219266 -0.517579 21* Junct 0.078 0.10 0.64 0.7 48 345 loop 2 -0.218805 -0.517131 25 Waypt 0.071 0.09 0.71 0.8 48 44 loop 2 -0.218417 -0.517462 23* Junct- 0.056 0.07 0.77 0.9 48 319 loop 2 -0.218794 -0.517763 20 Inter 0.053 0.07 0.82 0.9 48 218 loop 2 -0.219266 -0.517579 21* Junct 0.056 0.07 0.88 1.0 48 158 loop 2 -0.219946 -0.517397 24 Inter 0.078 0.10 0.95 1.1 48 165 loop 2 -0.220301 -0.517576 22* Junct- 0.044 0.06 1.00 1.2 48 206 loop 2 -0.220739 -0.517801 19* Junct 0.054 0.07 1.05 1.2 48 207 loop 2 -0.220784 -0.516035 30* Junct 0.196 0.24 1.25 1.5 48 91 high street -0.220311 -0.516015 31* Junct- 0.052 0.03 1.30 1.5 96 2 main 2 -0.219596 -0.515984 -3 Waypt 0.079 0.05 1.38 1.6 96 2 main 2 routino-3.0/src/test/expected/turns-WP10.txt 644 233 144 5154 12064636362 14210 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.218453 -0.520799 -1 Waypt 0.000 0.00 0.00 0.0 -0.219107 -0.520828 6* Junct 0.072 0.04 0.07 0.0 96 182 main 1 -0.219123 -0.520207 12* Junct 0.069 0.09 0.14 0.1 48 91 top road -0.219131 -0.519426 20* Junct 0.086 0.11 0.23 0.2 48 90 top road -0.219135 -0.518823 23* Junct 0.067 0.08 0.29 0.3 48 90 top road -0.219145 -0.517626 33* Junct 0.133 0.17 0.43 0.5 48 90 top road -0.219144 -0.517257 36* Junct 0.041 0.05 0.47 0.5 48 89 top road -0.219291 -0.517193 38 Inter 0.017 0.02 0.48 0.6 48 156 roundabout -0.219352 -0.517060 42 Junct- 0.016 0.02 0.50 0.6 48 114 roundabout -0.219304 -0.516904 45 Inter 0.018 0.02 0.52 0.6 48 72 roundabout -0.219153 -0.516826 46* Junct- 0.018 0.02 0.54 0.6 48 27 roundabout -0.218966 -0.516910 44 Inter 0.022 0.03 0.56 0.6 48 335 roundabout -0.218923 -0.517072 39 Junct- 0.018 0.02 0.58 0.7 48 284 roundabout -0.218998 -0.517207 37 Inter 0.017 0.02 0.59 0.7 48 240 roundabout -0.219144 -0.517257 36* Junct 0.017 0.02 0.61 0.7 48 199 roundabout -0.219145 -0.517626 33* Junct 0.041 0.05 0.65 0.8 48 269 top road -0.219135 -0.518823 23* Junct 0.133 0.17 0.79 0.9 48 270 top road -0.219131 -0.519426 20* Junct 0.067 0.08 0.85 1.0 48 270 top road -0.219123 -0.520207 12* Junct 0.086 0.11 0.94 1.1 48 270 top road -0.218605 -0.520090 -2 Waypt 0.059 0.07 1.00 1.2 48 12 loop 4 -0.218474 -0.520060 14* Inter 0.015 0.02 1.01 1.2 48 12 loop 4 -0.218258 -0.519789 16 Inter 0.038 0.05 1.05 1.2 48 51 loop 4 -0.218482 -0.519542 18* Inter 0.037 0.04 1.09 1.3 48 132 loop 4 -0.219131 -0.519426 20* Junct 0.073 0.09 1.16 1.4 48 169 loop 4 -0.219123 -0.520207 12* Junct 0.086 0.11 1.25 1.5 48 270 top road -0.219107 -0.520828 6* Junct 0.069 0.09 1.31 1.6 48 271 top road -0.220666 -0.520893 5* Junct- 0.173 0.11 1.49 1.7 96 182 main 1 -0.221308 -0.520914 4* Junct- 0.071 0.04 1.56 1.7 96 181 main 1 -0.221561 -0.520922 -3 Waypt 0.027 0.02 1.59 1.7 96 181 main 1 routino-3.0/src/test/expected/turns-WP15.txt 644 233 144 6532 12064636362 14216 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.218453 -0.520799 -1 Waypt 0.000 0.00 0.00 0.0 -0.219107 -0.520828 6* Junct 0.072 0.04 0.07 0.0 96 182 main 1 -0.219123 -0.520207 12* Junct 0.069 0.09 0.14 0.1 48 91 top road -0.219131 -0.519426 20* Junct 0.086 0.11 0.23 0.2 48 90 top road -0.219135 -0.518823 23* Junct 0.067 0.08 0.29 0.3 48 90 top road -0.219145 -0.517626 33* Junct 0.133 0.17 0.43 0.5 48 90 top road -0.219144 -0.517257 36* Junct 0.041 0.05 0.47 0.5 48 89 top road -0.219291 -0.517193 38 Inter 0.017 0.02 0.48 0.6 48 156 roundabout -0.219352 -0.517060 42 Junct- 0.016 0.02 0.50 0.6 48 114 roundabout -0.219304 -0.516904 45 Inter 0.018 0.02 0.52 0.6 48 72 roundabout -0.219153 -0.516826 46* Junct- 0.018 0.02 0.54 0.6 48 27 roundabout -0.218966 -0.516910 44 Inter 0.022 0.03 0.56 0.6 48 335 roundabout -0.218923 -0.517072 39 Junct- 0.018 0.02 0.58 0.7 48 284 roundabout -0.218998 -0.517207 37 Inter 0.017 0.02 0.59 0.7 48 240 roundabout -0.219144 -0.517257 36* Junct 0.017 0.02 0.61 0.7 48 199 roundabout -0.219145 -0.517626 33* Junct 0.041 0.05 0.65 0.8 48 269 top road -0.218619 -0.517921 32* Inter 0.067 0.08 0.72 0.8 48 330 loop 5 -0.218431 -0.518243 28 Waypt 0.041 0.05 0.76 0.9 48 300 loop 5 -0.218600 -0.518557 25* Inter 0.039 0.05 0.80 0.9 48 241 loop 5 -0.219135 -0.518823 23* Junct 0.066 0.08 0.86 1.0 48 206 loop 5 -0.219145 -0.517626 33* Junct 0.133 0.17 1.00 1.2 48 90 top road -0.219144 -0.517257 36* Junct 0.041 0.05 1.04 1.2 48 89 top road -0.219291 -0.517193 38 Inter 0.017 0.02 1.06 1.3 48 156 roundabout -0.219352 -0.517060 42 Junct- 0.016 0.02 1.07 1.3 48 114 roundabout -0.219304 -0.516904 45 Inter 0.018 0.02 1.09 1.3 48 72 roundabout -0.219153 -0.516826 46* Junct- 0.018 0.02 1.11 1.3 48 27 roundabout -0.218966 -0.516910 44 Inter 0.022 0.03 1.13 1.3 48 335 roundabout -0.218923 -0.517072 39 Junct- 0.018 0.02 1.15 1.4 48 284 roundabout -0.218998 -0.517207 37 Inter 0.017 0.02 1.17 1.4 48 240 roundabout -0.219144 -0.517257 36* Junct 0.017 0.02 1.18 1.4 48 199 roundabout -0.219145 -0.517626 33* Junct 0.041 0.05 1.22 1.5 48 269 top road -0.219135 -0.518823 23* Junct 0.133 0.17 1.36 1.6 48 270 top road -0.219131 -0.519426 20* Junct 0.067 0.08 1.42 1.7 48 270 top road -0.219123 -0.520207 12* Junct 0.086 0.11 1.51 1.8 48 270 top road -0.219107 -0.520828 6* Junct 0.069 0.09 1.58 1.9 48 271 top road -0.220666 -0.520893 5* Junct- 0.173 0.11 1.75 2.0 96 182 main 1 -0.221308 -0.520914 4* Junct- 0.071 0.04 1.82 2.0 96 181 main 1 -0.221561 -0.520922 -3 Waypt 0.027 0.02 1.85 2.1 96 181 main 1 routino-3.0/src/test/expected/node-restrictions-WP03.txt 644 233 144 3420 12064636362 16504 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.219564 -0.520846 -1 Waypt 0.000 0.00 0.00 0.0 -0.220666 -0.520893 4* Junct 0.122 0.07 0.12 0.1 96 182 main 1 -0.220682 -0.520141 9* Junct 0.083 0.08 0.20 0.2 64 91 high street -0.220695 -0.519489 12* Change 0.072 0.07 0.28 0.2 64 91 high street -0.220694 -0.519227 15 Inter 0.029 0.04 0.31 0.3 48 89 long road -0.220386 -0.519076 16 Inter 0.038 0.05 0.34 0.3 48 26 long road -0.220961 -0.518928 17 Inter 0.066 0.08 0.41 0.4 48 165 long road -0.220427 -0.518622 18 Inter 0.068 0.09 0.48 0.5 48 29 long road -0.220949 -0.518422 21 Inter 0.062 0.08 0.54 0.5 48 159 long road -0.220455 -0.518238 22 Inter 0.058 0.07 0.60 0.6 48 20 long road -0.220746 -0.518070 23 Inter 0.037 0.04 0.64 0.7 48 149 long road -0.220739 -0.517801 26* Junct 0.029 0.04 0.66 0.7 48 88 long road -0.221166 -0.517916 24 Inter 0.049 0.06 0.71 0.8 48 195 somepass road -0.221157 -0.518560 -2 Waypt 0.070 0.09 0.78 0.8 48 270 somepass road -0.221166 -0.517916 24 Inter 0.070 0.09 0.85 0.9 48 90 somepass road -0.220739 -0.517801 26* Junct 0.049 0.06 0.90 1.0 48 15 somepass road -0.220784 -0.516035 31* Junct 0.196 0.18 1.10 1.2 64 91 high street -0.219593 -0.515985 -3 Waypt 0.132 0.08 1.23 1.3 96 2 main 2 routino-3.0/src/test/expected/node-restrictions-WP08.txt 644 233 144 3144 12154146101 16477 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.219564 -0.520846 -1 Waypt 0.000 0.00 0.00 0.0 -0.220666 -0.520893 4* Junct 0.122 0.07 0.12 0.1 96 182 main 1 -0.220682 -0.520141 9* Junct 0.083 0.08 0.20 0.2 64 91 high street -0.219009 -0.520075 10* Waypt 0.186 0.17 0.39 0.3 64 2 dead end road -0.220682 -0.520141 9* Junct 0.186 0.17 0.58 0.5 64 182 dead end road -0.220695 -0.519489 12* Change 0.072 0.07 0.65 0.6 64 91 high street -0.220694 -0.519227 15 Inter 0.029 0.04 0.68 0.6 48 89 long road -0.220386 -0.519076 16 Inter 0.038 0.05 0.72 0.6 48 26 long road -0.220961 -0.518928 17 Inter 0.066 0.08 0.78 0.7 48 165 long road -0.220427 -0.518622 18 Inter 0.068 0.09 0.85 0.8 48 29 long road -0.220949 -0.518422 21 Inter 0.062 0.08 0.91 0.9 48 159 long road -0.220455 -0.518238 22 Inter 0.058 0.07 0.97 1.0 48 20 long road -0.220746 -0.518070 23 Inter 0.037 0.04 1.01 1.0 48 149 long road -0.220739 -0.517801 26* Junct 0.029 0.04 1.04 1.0 48 88 long road -0.220784 -0.516035 31* Junct 0.196 0.18 1.23 1.2 64 91 high street -0.219593 -0.515985 -3 Waypt 0.132 0.08 1.36 1.3 96 2 main 2 routino-3.0/src/test/expected/loops-WP08.txt 644 233 144 3457 12064636362 14204 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.219562 -0.520851 -1 Waypt 0.000 0.00 0.00 0.0 -0.220223 -0.520885 5* Junct- 0.073 0.04 0.07 0.0 96 182 main 1 -0.220666 -0.520893 4* Junct 0.049 0.03 0.12 0.1 96 181 main 1 -0.220695 -0.519489 11* Junct 0.156 0.20 0.28 0.3 48 91 high street -0.220739 -0.517801 19* Junct 0.187 0.23 0.47 0.5 48 91 high street -0.220301 -0.517576 22* Junct- 0.054 0.07 0.52 0.6 48 27 loop 2 -0.219946 -0.517397 24 Inter 0.044 0.06 0.56 0.6 48 26 loop 2 -0.219597 -0.517490 -2 Waypt 0.040 0.05 0.60 0.7 48 345 loop 2 -0.219266 -0.517579 21* Junct 0.038 0.05 0.64 0.7 48 345 loop 2 -0.218794 -0.517763 20 Inter 0.056 0.07 0.70 0.8 48 338 loop 2 -0.218417 -0.517462 23* Junct- 0.053 0.07 0.75 0.9 48 38 loop 2 -0.218805 -0.517131 25 Inter 0.056 0.07 0.81 0.9 48 139 loop 2 -0.219266 -0.517579 21* Junct 0.071 0.09 0.88 1.0 48 224 loop 2 -0.219946 -0.517397 24 Inter 0.078 0.10 0.95 1.1 48 165 loop 2 -0.220301 -0.517576 22* Junct- 0.044 0.06 1.00 1.2 48 206 loop 2 -0.220739 -0.517801 19* Junct 0.054 0.07 1.05 1.2 48 207 loop 2 -0.220784 -0.516035 30* Junct 0.196 0.24 1.25 1.5 48 91 high street -0.220311 -0.516015 31* Junct- 0.052 0.03 1.30 1.5 96 2 main 2 -0.219596 -0.515984 -3 Waypt 0.079 0.05 1.38 1.6 96 2 main 2 routino-3.0/src/test/expected/loops-WP11.txt 644 233 144 3337 12064636362 14173 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.219562 -0.520851 -1 Waypt 0.000 0.00 0.00 0.0 -0.220223 -0.520885 5* Junct- 0.073 0.04 0.07 0.0 96 182 main 1 -0.220666 -0.520893 4* Junct 0.049 0.03 0.12 0.1 96 181 main 1 -0.220695 -0.519489 11* Junct 0.156 0.20 0.28 0.3 48 91 high street -0.220739 -0.517801 19* Junct 0.187 0.23 0.47 0.5 48 91 high street -0.220301 -0.517576 22* Junct- 0.054 0.07 0.52 0.6 48 27 loop 2 -0.219946 -0.517397 24 Inter 0.044 0.06 0.56 0.6 48 26 loop 2 -0.219266 -0.517579 21* Junct 0.078 0.10 0.64 0.7 48 345 loop 2 -0.218794 -0.517763 20 Inter 0.056 0.07 0.70 0.8 48 338 loop 2 -0.218417 -0.517462 23* Waypt 0.053 0.07 0.75 0.9 48 38 loop 2 -0.218805 -0.517131 25 Inter 0.056 0.07 0.81 0.9 48 139 loop 2 -0.219266 -0.517579 21* Junct 0.071 0.09 0.88 1.0 48 224 loop 2 -0.219946 -0.517397 24 Inter 0.078 0.10 0.95 1.1 48 165 loop 2 -0.220301 -0.517576 22* Junct- 0.044 0.06 1.00 1.2 48 206 loop 2 -0.220739 -0.517801 19* Junct 0.054 0.07 1.05 1.2 48 207 loop 2 -0.220784 -0.516035 30* Junct 0.196 0.24 1.25 1.5 48 91 high street -0.220311 -0.516015 31* Junct- 0.052 0.03 1.30 1.5 96 2 main 2 -0.219596 -0.515984 -3 Waypt 0.079 0.05 1.38 1.6 96 2 main 2 routino-3.0/src/test/expected/coincident-waypoint-WP02.txt 644 233 144 1312 12333375370 17013 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.216959 -0.520771 -1 Waypt 0.000 0.00 0.00 0.0 -0.217286 -0.520780 7 Junct- 0.036 0.02 0.04 0.0 96 181 main 1 -0.218523 -0.520806 6 Waypt 0.137 0.09 0.17 0.1 96 181 main 1 -0.218523 -0.520806 6 Waypt 0.000 0.00 0.17 0.1 96 270 main 1 -0.219117 -0.520825 -4 Waypt 0.065 0.04 0.24 0.1 96 181 main 1 routino-3.0/src/test/expected/coincident-waypoint-WP01.txt 644 233 144 1432 12333375370 17015 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.216904 -0.520770 -1 Waypt 0.000 0.00 0.00 0.0 -0.217286 -0.520780 7 Junct- 0.042 0.03 0.04 0.0 96 181 main 1 -0.217741 -0.520789 -2 Waypt 0.050 0.03 0.09 0.1 96 181 main 1 -0.217741 -0.520789 -3 Waypt 0.000 0.00 0.09 0.1 96 270 main 1 -0.218523 -0.520806 6 Junct- 0.086 0.05 0.18 0.1 96 181 main 1 -0.219080 -0.520824 -4 Waypt 0.061 0.04 0.24 0.1 96 181 main 1 routino-3.0/src/test/expected/roundabout-waypoints-WP04.txt 644 233 144 1571 12317763605 17256 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.218454 -0.520798 -1 Waypt 0.000 0.00 0.00 0.0 -0.219482 -0.520837 9* Junct 0.113 0.07 0.11 0.1 96 182 main 1 -0.219692 -0.520509 15 Junct- 0.043 0.03 0.16 0.1 96 122 roundabout -0.219878 -0.520515 -2 Waypt 0.020 0.01 0.18 0.1 96 181 roundabout -0.220082 -0.520522 14 Junct- 0.022 0.01 0.20 0.1 96 181 roundabout -0.220268 -0.520863 8* Junct 0.043 0.03 0.24 0.1 96 241 roundabout -0.221566 -0.520921 -3 Waypt 0.143 0.09 0.38 0.2 96 182 main 2 routino-3.0/src/test/expected/no-super-WP01.txt 644 233 144 2113 12064636362 14575 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.215814 -0.519419 -1 Waypt 0.000 0.00 0.00 0.0 -0.215737 -0.519035 7 Inter 0.043 0.05 0.04 0.1 48 78 road1 -0.215935 -0.518253 10 Inter 0.089 0.11 0.13 0.2 48 104 road1 -0.215772 -0.517713 13 Inter 0.062 0.08 0.19 0.2 48 73 road1 -0.215952 -0.516838 15 Inter 0.099 0.12 0.29 0.4 48 101 road1 -0.215755 -0.515945 19 Inter 0.101 0.12 0.39 0.5 48 77 road1 -0.215897 -0.515462 -2 Waypt 0.055 0.07 0.45 0.6 48 106 road1 -0.215755 -0.515945 19 Inter 0.055 0.07 0.50 0.6 48 286 road1 -0.215952 -0.516838 15 Inter 0.101 0.12 0.60 0.8 48 257 road1 -0.215868 -0.517244 -3 Waypt 0.046 0.06 0.65 0.8 48 281 road1 routino-3.0/src/test/expected/super-or-not-WP01.txt 644 233 144 1577 12064636362 15414 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.216158 -0.518809 -1 Waypt 0.000 0.00 0.00 0.0 -0.216435 -0.518515 4 Inter 0.044 0.06 0.04 0.1 48 133 Local road -0.215866 -0.517931 5 Inter 0.090 0.11 0.13 0.2 48 45 Local road -0.216470 -0.517412 6 Inter 0.088 0.11 0.22 0.3 48 139 Local road -0.215930 -0.516823 7 Inter 0.088 0.11 0.31 0.4 48 47 Local road -0.216451 -0.516221 8 Inter 0.088 0.11 0.40 0.5 48 130 Local road -0.216158 -0.515870 -2 Waypt 0.050 0.06 0.45 0.6 48 50 Local road routino-3.0/src/test/expected/turns-WP01.txt 644 233 144 2522 12064636362 14204 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.218453 -0.520799 -1 Waypt 0.000 0.00 0.00 0.0 -0.219107 -0.520828 6* Junct- 0.072 0.04 0.07 0.0 96 182 main 1 -0.220666 -0.520893 5* Junct 0.173 0.11 0.24 0.2 96 182 main 1 -0.220671 -0.520223 11* Junct 0.074 0.09 0.32 0.2 48 90 high street -0.220691 -0.519461 19* Junct 0.084 0.10 0.40 0.3 48 91 high street -0.220111 -0.519553 17 Inter 0.065 0.08 0.47 0.4 48 351 loop 1 -0.219817 -0.519807 15 Inter 0.043 0.05 0.51 0.5 48 319 loop 1 -0.220067 -0.520109 13* Inter 0.043 0.05 0.55 0.5 48 230 loop 1 -0.220191 -0.520132 -2 Waypt 0.014 0.02 0.57 0.6 48 190 loop 1 -0.220671 -0.520223 11* Junct 0.054 0.07 0.62 0.6 48 190 loop 1 -0.220666 -0.520893 5* Junct 0.074 0.09 0.70 0.7 48 270 high street -0.221308 -0.520914 4* Junct- 0.071 0.04 0.77 0.8 96 181 main 1 -0.221561 -0.520922 -3 Waypt 0.027 0.02 0.79 0.8 96 181 main 1 routino-3.0/src/test/expected/loops-WP03.txt 644 233 144 3456 12064636362 14176 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.219562 -0.520851 -1 Waypt 0.000 0.00 0.00 0.0 -0.220223 -0.520885 5* Junct- 0.073 0.04 0.07 0.0 96 182 main 1 -0.220666 -0.520893 4* Junct 0.049 0.03 0.12 0.1 96 181 main 1 -0.220695 -0.519489 11* Junct 0.156 0.20 0.28 0.3 48 91 high street -0.220280 -0.519256 15* Junct- 0.052 0.07 0.33 0.3 48 29 loop 1 -0.219910 -0.519112 17 Inter 0.044 0.06 0.37 0.4 48 21 loop 1 -0.219578 -0.519198 -2 Waypt 0.038 0.05 0.41 0.4 48 345 loop 1 -0.219237 -0.519286 13* Junct 0.039 0.05 0.45 0.5 48 345 loop 1 -0.218764 -0.519471 12 Inter 0.056 0.07 0.51 0.6 48 338 loop 1 -0.218380 -0.519134 16 Inter 0.056 0.07 0.56 0.6 48 41 loop 1 -0.218776 -0.518838 18 Inter 0.055 0.07 0.62 0.7 48 143 loop 1 -0.219237 -0.519286 13* Junct 0.071 0.09 0.69 0.8 48 224 loop 1 -0.219910 -0.519112 17 Inter 0.077 0.10 0.77 0.9 48 165 loop 1 -0.220280 -0.519256 15* Junct- 0.044 0.06 0.81 0.9 48 201 loop 1 -0.220695 -0.519489 11* Junct 0.052 0.07 0.86 1.0 48 209 loop 1 -0.220739 -0.517801 19* Junct 0.187 0.23 1.05 1.2 48 91 high street -0.220784 -0.516035 30* Junct 0.196 0.24 1.25 1.5 48 91 high street -0.220311 -0.516015 31* Junct- 0.052 0.03 1.30 1.5 96 2 main 2 -0.219596 -0.515984 -3 Waypt 0.079 0.05 1.38 1.6 96 2 main 2 routino-3.0/src/test/expected/turns-WP11.txt 644 233 144 4573 12064636362 14215 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.218453 -0.520799 -1 Waypt 0.000 0.00 0.00 0.0 -0.219107 -0.520828 6* Junct 0.072 0.04 0.07 0.0 96 182 main 1 -0.219123 -0.520207 12* Junct 0.069 0.09 0.14 0.1 48 91 top road -0.219131 -0.519426 20* Junct 0.086 0.11 0.23 0.2 48 90 top road -0.219135 -0.518823 23* Junct 0.067 0.08 0.29 0.3 48 90 top road -0.219145 -0.517626 33* Junct 0.133 0.17 0.43 0.5 48 90 top road -0.219144 -0.517257 36* Junct 0.041 0.05 0.47 0.5 48 89 top road -0.219291 -0.517193 38 Inter 0.017 0.02 0.48 0.6 48 156 roundabout -0.219352 -0.517060 42 Junct- 0.016 0.02 0.50 0.6 48 114 roundabout -0.219304 -0.516904 45 Inter 0.018 0.02 0.52 0.6 48 72 roundabout -0.219153 -0.516826 46* Junct- 0.018 0.02 0.54 0.6 48 27 roundabout -0.218966 -0.516910 44 Inter 0.022 0.03 0.56 0.6 48 335 roundabout -0.218923 -0.517072 39 Junct- 0.018 0.02 0.58 0.7 48 284 roundabout -0.218998 -0.517207 37 Inter 0.017 0.02 0.59 0.7 48 240 roundabout -0.219144 -0.517257 36* Junct 0.017 0.02 0.61 0.7 48 199 roundabout -0.219145 -0.517626 33* Junct 0.041 0.05 0.65 0.8 48 269 top road -0.219135 -0.518823 23* Junct 0.133 0.17 0.79 0.9 48 270 top road -0.219131 -0.519426 20* Junct 0.067 0.08 0.85 1.0 48 270 top road -0.218482 -0.519542 18* Inter 0.073 0.09 0.93 1.1 48 349 loop 4 -0.218258 -0.519789 16 Inter 0.037 0.04 0.96 1.1 48 312 loop 4 -0.218474 -0.520060 14* Waypt 0.038 0.05 1.00 1.2 48 231 loop 4 -0.219123 -0.520207 12* Junct 0.074 0.09 1.07 1.3 48 192 loop 4 -0.219107 -0.520828 6* Junct 0.069 0.09 1.14 1.4 48 271 top road -0.220666 -0.520893 5* Junct- 0.173 0.11 1.32 1.5 96 182 main 1 -0.221308 -0.520914 4* Junct- 0.071 0.04 1.39 1.5 96 181 main 1 -0.221561 -0.520922 -3 Waypt 0.027 0.02 1.41 1.5 96 181 main 1 routino-3.0/src/test/expected/roundabout-waypoints-WP06.txt 644 233 144 1571 12317763605 17260 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.218454 -0.520798 -1 Waypt 0.000 0.00 0.00 0.0 -0.219482 -0.520837 9* Junct 0.113 0.07 0.11 0.1 96 182 main 1 -0.219692 -0.520509 15 Junct- 0.043 0.03 0.16 0.1 96 122 roundabout -0.220082 -0.520522 14 Junct- 0.043 0.03 0.20 0.1 96 181 roundabout -0.220171 -0.520685 -2 Waypt 0.020 0.01 0.22 0.1 96 241 roundabout -0.220268 -0.520863 8* Junct 0.022 0.01 0.24 0.1 96 241 roundabout -0.221566 -0.520921 -3 Waypt 0.143 0.09 0.38 0.2 96 182 main 2 routino-3.0/src/test/expected/turns-WP04.txt 644 233 144 3761 12064636362 14215 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.218453 -0.520799 -1 Waypt 0.000 0.00 0.00 0.0 -0.219107 -0.520828 6* Junct- 0.072 0.04 0.07 0.0 96 182 main 1 -0.220666 -0.520893 5* Junct 0.173 0.11 0.24 0.2 96 182 main 1 -0.220671 -0.520223 11* Junct 0.074 0.09 0.32 0.2 48 90 high street -0.220691 -0.519461 19* Junct 0.084 0.10 0.40 0.3 48 91 high street -0.220708 -0.518842 22* Junct 0.069 0.09 0.47 0.4 48 91 high street -0.220724 -0.518071 31* Junct 0.085 0.10 0.56 0.5 48 91 high street -0.220143 -0.518162 30 Inter 0.065 0.08 0.62 0.6 48 351 loop 2 -0.219850 -0.518416 27 Inter 0.043 0.05 0.67 0.7 48 319 loop 2 -0.220100 -0.518718 24* Inter 0.043 0.05 0.71 0.7 48 230 loop 2 -0.220206 -0.518739 -2 Waypt 0.012 0.01 0.72 0.7 48 191 loop 2 -0.220708 -0.518842 22* Junct 0.057 0.07 0.78 0.8 48 191 loop 2 -0.220724 -0.518071 31* Junct 0.085 0.10 0.86 0.9 48 91 high street -0.220739 -0.517425 34* Junct 0.071 0.09 0.93 1.0 48 91 high street -0.220760 -0.516647 48* Junct 0.086 0.11 1.02 1.1 48 91 high street -0.220784 -0.516035 54* Junct 0.068 0.09 1.09 1.2 48 92 high street -0.221431 -0.516056 53* Junct 0.072 0.04 1.16 1.2 96 181 main 2 -0.221376 -0.518235 29* Junct 0.242 0.30 1.40 1.5 48 271 bottom road -0.221360 -0.518860 21* Junct 0.069 0.09 1.47 1.6 48 271 bottom road -0.221308 -0.520914 4* Junct 0.228 0.28 1.70 1.9 48 271 bottom road -0.221561 -0.520922 -3 Waypt 0.027 0.02 1.73 1.9 96 181 main 1 routino-3.0/src/test/expected/node-restrictions-WP06.txt 644 233 144 3410 12064636362 16506 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.219564 -0.520846 -1 Waypt 0.000 0.00 0.00 0.0 -0.220666 -0.520893 4* Junct 0.122 0.07 0.12 0.1 96 182 main 1 -0.220682 -0.520141 9* Junct 0.083 0.08 0.20 0.2 64 91 high street -0.220695 -0.519489 12* Change 0.072 0.07 0.28 0.2 64 91 high street -0.220694 -0.519227 15 Inter 0.029 0.04 0.31 0.3 48 89 long road -0.220386 -0.519076 16 Inter 0.038 0.05 0.34 0.3 48 26 long road -0.220961 -0.518928 17 Inter 0.066 0.08 0.41 0.4 48 165 long road -0.220427 -0.518622 18 Inter 0.068 0.09 0.48 0.5 48 29 long road -0.220949 -0.518422 21 Inter 0.062 0.08 0.54 0.5 48 159 long road -0.220455 -0.518238 22 Inter 0.058 0.07 0.60 0.6 48 20 long road -0.220746 -0.518070 23 Inter 0.037 0.04 0.64 0.7 48 149 long road -0.220739 -0.517801 26* Junct 0.029 0.04 0.66 0.7 48 88 long road -0.220212 -0.517903 25 Inter 0.059 0.07 0.72 0.8 48 349 nopass road -0.220176 -0.518543 -2 Waypt 0.070 0.09 0.79 0.9 48 273 nopass road -0.220212 -0.517903 25 Inter 0.070 0.09 0.86 0.9 48 93 nopass road -0.220739 -0.517801 26* Junct 0.059 0.07 0.92 1.0 48 169 nopass road -0.220784 -0.516035 31* Junct 0.196 0.18 1.12 1.2 64 91 high street -0.219593 -0.515985 -3 Waypt 0.132 0.08 1.25 1.3 96 2 main 2 routino-3.0/src/test/expected/turns-WP05.txt 644 233 144 3642 12064636362 14214 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.218453 -0.520799 -1 Waypt 0.000 0.00 0.00 0.0 -0.219107 -0.520828 6* Junct- 0.072 0.04 0.07 0.0 96 182 main 1 -0.220666 -0.520893 5* Junct 0.173 0.11 0.24 0.2 96 182 main 1 -0.220671 -0.520223 11* Junct 0.074 0.09 0.32 0.2 48 90 high street -0.220691 -0.519461 19* Junct 0.084 0.10 0.40 0.3 48 91 high street -0.220708 -0.518842 22* Junct 0.069 0.09 0.47 0.4 48 91 high street -0.220724 -0.518071 31* Junct 0.085 0.10 0.56 0.5 48 91 high street -0.220143 -0.518162 30 Inter 0.065 0.08 0.62 0.6 48 351 loop 2 -0.219850 -0.518416 27 Inter 0.043 0.05 0.67 0.7 48 319 loop 2 -0.220100 -0.518718 24* Waypt 0.043 0.05 0.71 0.7 48 230 loop 2 -0.220708 -0.518842 22* Junct 0.069 0.09 0.78 0.8 48 191 loop 2 -0.220724 -0.518071 31* Junct 0.085 0.10 0.86 0.9 48 91 high street -0.220739 -0.517425 34* Junct 0.071 0.09 0.93 1.0 48 91 high street -0.220760 -0.516647 48* Junct 0.086 0.11 1.02 1.1 48 91 high street -0.220784 -0.516035 54* Junct 0.068 0.09 1.09 1.2 48 92 high street -0.221431 -0.516056 53* Junct 0.072 0.04 1.16 1.2 96 181 main 2 -0.221376 -0.518235 29* Junct 0.242 0.30 1.40 1.5 48 271 bottom road -0.221360 -0.518860 21* Junct 0.069 0.09 1.47 1.6 48 271 bottom road -0.221308 -0.520914 4* Junct 0.228 0.28 1.70 1.9 48 271 bottom road -0.221561 -0.520922 -3 Waypt 0.027 0.02 1.73 1.9 96 181 main 1 routino-3.0/src/test/expected/dead-ends-WP05.txt 644 233 144 2301 12154145517 14651 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.219535 -0.521016 -1 Waypt 0.000 0.00 0.00 0.0 -0.220223 -0.521052 5* Junct- 0.076 0.05 0.08 0.0 96 182 main 1 -0.220666 -0.521060 4* Junct 0.049 0.03 0.12 0.1 96 180 main 1 -0.220702 -0.519478 12* Junct 0.176 0.22 0.30 0.3 48 91 high street -0.220739 -0.517804 18* Junct 0.186 0.23 0.49 0.5 48 91 high street -0.220296 -0.517634 20* Waypt 0.052 0.07 0.54 0.6 48 21 dead-end 2 -0.220739 -0.517804 18* Junct 0.052 0.07 0.59 0.7 48 201 dead-end 2 -0.220782 -0.516137 24* Junct 0.185 0.23 0.78 0.9 48 91 high street -0.220817 -0.514062 32* Junct 0.230 0.29 1.01 1.2 48 90 high street -0.220344 -0.514042 33* Junct- 0.052 0.03 1.06 1.2 96 2 main 2 -0.219539 -0.514007 -3 Waypt 0.089 0.06 1.15 1.3 96 2 main 2 routino-3.0/src/test/expected/dead-ends-WP02.txt 644 233 144 2551 12154145517 14655 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.219535 -0.521016 -1 Waypt 0.000 0.00 0.00 0.0 -0.220223 -0.521052 5* Junct- 0.076 0.05 0.08 0.0 96 182 main 1 -0.220666 -0.521060 4* Junct 0.049 0.03 0.12 0.1 96 180 main 1 -0.220702 -0.519478 12* Junct 0.176 0.22 0.30 0.3 48 91 high street -0.220263 -0.519309 13* Junct- 0.052 0.07 0.35 0.4 48 21 dead-end 1 -0.219924 -0.519179 14 Waypt 0.040 0.05 0.39 0.4 48 20 dead-end 1 -0.220263 -0.519309 13* Junct- 0.040 0.05 0.43 0.5 48 200 dead-end 1 -0.220702 -0.519478 12* Junct 0.052 0.07 0.48 0.5 48 201 dead-end 1 -0.220739 -0.517804 18* Junct 0.186 0.23 0.67 0.8 48 91 high street -0.220782 -0.516137 24* Junct 0.185 0.23 0.86 1.0 48 91 high street -0.220817 -0.514062 32* Junct 0.230 0.29 1.09 1.3 48 90 high street -0.220344 -0.514042 33* Junct- 0.052 0.03 1.14 1.3 96 2 main 2 -0.219539 -0.514007 -3 Waypt 0.089 0.06 1.23 1.4 96 2 main 2 routino-3.0/src/test/expected/loops-WP04.txt 644 233 144 3456 12064636362 14177 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.219562 -0.520851 -1 Waypt 0.000 0.00 0.00 0.0 -0.220223 -0.520885 5* Junct- 0.073 0.04 0.07 0.0 96 182 main 1 -0.220666 -0.520893 4* Junct 0.049 0.03 0.12 0.1 96 181 main 1 -0.220695 -0.519489 11* Junct 0.156 0.20 0.28 0.3 48 91 high street -0.220280 -0.519256 15* Junct- 0.052 0.07 0.33 0.3 48 29 loop 1 -0.219910 -0.519112 17 Inter 0.044 0.06 0.37 0.4 48 21 loop 1 -0.219237 -0.519286 13* Junct 0.077 0.10 0.45 0.5 48 345 loop 1 -0.218997 -0.519053 -2 Waypt 0.037 0.04 0.49 0.5 48 44 loop 1 -0.218776 -0.518838 18 Inter 0.034 0.04 0.52 0.6 48 44 loop 1 -0.218380 -0.519134 16 Inter 0.055 0.07 0.58 0.6 48 323 loop 1 -0.218764 -0.519471 12 Inter 0.056 0.07 0.63 0.7 48 221 loop 1 -0.219237 -0.519286 13* Junct 0.056 0.07 0.69 0.8 48 158 loop 1 -0.219910 -0.519112 17 Inter 0.077 0.10 0.77 0.9 48 165 loop 1 -0.220280 -0.519256 15* Junct- 0.044 0.06 0.81 0.9 48 201 loop 1 -0.220695 -0.519489 11* Junct 0.052 0.07 0.86 1.0 48 209 loop 1 -0.220739 -0.517801 19* Junct 0.187 0.23 1.05 1.2 48 91 high street -0.220784 -0.516035 30* Junct 0.196 0.24 1.25 1.5 48 91 high street -0.220311 -0.516015 31* Junct- 0.052 0.03 1.30 1.5 96 2 main 2 -0.219596 -0.515984 -3 Waypt 0.079 0.05 1.38 1.6 96 2 main 2 routino-3.0/src/test/expected/turns-WP13.txt 644 233 144 6651 12064636362 14216 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.218453 -0.520799 -1 Waypt 0.000 0.00 0.00 0.0 -0.219107 -0.520828 6* Junct 0.072 0.04 0.07 0.0 96 182 main 1 -0.219123 -0.520207 12* Junct 0.069 0.09 0.14 0.1 48 91 top road -0.219131 -0.519426 20* Junct 0.086 0.11 0.23 0.2 48 90 top road -0.219135 -0.518823 23* Junct 0.067 0.08 0.29 0.3 48 90 top road -0.219145 -0.517626 33* Junct 0.133 0.17 0.43 0.5 48 90 top road -0.219144 -0.517257 36* Junct 0.041 0.05 0.47 0.5 48 89 top road -0.219291 -0.517193 38 Inter 0.017 0.02 0.48 0.6 48 156 roundabout -0.219352 -0.517060 42 Junct- 0.016 0.02 0.50 0.6 48 114 roundabout -0.219304 -0.516904 45 Inter 0.018 0.02 0.52 0.6 48 72 roundabout -0.219153 -0.516826 46* Junct- 0.018 0.02 0.54 0.6 48 27 roundabout -0.218966 -0.516910 44 Inter 0.022 0.03 0.56 0.6 48 335 roundabout -0.218923 -0.517072 39 Junct- 0.018 0.02 0.58 0.7 48 284 roundabout -0.218998 -0.517207 37 Inter 0.017 0.02 0.59 0.7 48 240 roundabout -0.219144 -0.517257 36* Junct 0.017 0.02 0.61 0.7 48 199 roundabout -0.219145 -0.517626 33* Junct 0.041 0.05 0.65 0.8 48 269 top road -0.218619 -0.517921 32* Inter 0.067 0.08 0.72 0.8 48 330 loop 5 -0.218431 -0.518243 28 Inter 0.041 0.05 0.76 0.9 48 300 loop 5 -0.218600 -0.518557 25* Inter 0.039 0.05 0.80 0.9 48 241 loop 5 -0.218691 -0.518602 -2 Waypt 0.011 0.01 0.81 1.0 48 206 loop 5 -0.219135 -0.518823 23* Junct 0.054 0.07 0.86 1.0 48 206 loop 5 -0.219145 -0.517626 33* Junct 0.133 0.17 1.00 1.2 48 90 top road -0.219144 -0.517257 36* Junct 0.041 0.05 1.04 1.2 48 89 top road -0.219291 -0.517193 38 Inter 0.017 0.02 1.05 1.3 48 156 roundabout -0.219352 -0.517060 42 Junct- 0.016 0.02 1.07 1.3 48 114 roundabout -0.219304 -0.516904 45 Inter 0.018 0.02 1.09 1.3 48 72 roundabout -0.219153 -0.516826 46* Junct- 0.018 0.02 1.11 1.3 48 27 roundabout -0.218966 -0.516910 44 Inter 0.022 0.03 1.13 1.3 48 335 roundabout -0.218923 -0.517072 39 Junct- 0.018 0.02 1.15 1.4 48 284 roundabout -0.218998 -0.517207 37 Inter 0.017 0.02 1.16 1.4 48 240 roundabout -0.219144 -0.517257 36* Junct 0.017 0.02 1.18 1.4 48 199 roundabout -0.219145 -0.517626 33* Junct 0.041 0.05 1.22 1.5 48 269 top road -0.219135 -0.518823 23* Junct 0.133 0.17 1.35 1.6 48 270 top road -0.219131 -0.519426 20* Junct 0.067 0.08 1.42 1.7 48 270 top road -0.219123 -0.520207 12* Junct 0.086 0.11 1.51 1.8 48 270 top road -0.219107 -0.520828 6* Junct 0.069 0.09 1.58 1.9 48 271 top road -0.220666 -0.520893 5* Junct- 0.173 0.11 1.75 2.0 96 182 main 1 -0.221308 -0.520914 4* Junct- 0.071 0.04 1.82 2.0 96 181 main 1 -0.221561 -0.520922 -3 Waypt 0.027 0.02 1.85 2.1 96 181 main 1 routino-3.0/src/test/expected/roundabout-waypoints-WP02.txt 644 233 144 1571 12317763605 17254 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.218454 -0.520798 -1 Waypt 0.000 0.00 0.00 0.0 -0.219482 -0.520837 9* Junct 0.113 0.07 0.11 0.1 96 182 main 1 -0.219577 -0.520689 -2 Waypt 0.019 0.01 0.13 0.1 96 122 roundabout -0.219692 -0.520509 15 Junct- 0.023 0.01 0.15 0.1 96 122 roundabout -0.220082 -0.520522 14 Junct- 0.043 0.03 0.20 0.1 96 181 roundabout -0.220268 -0.520863 8* Junct 0.043 0.03 0.24 0.1 96 241 roundabout -0.221566 -0.520921 -3 Waypt 0.143 0.09 0.38 0.2 96 182 main 2 routino-3.0/src/test/expected/dead-ends-WP04.txt 644 233 144 3265 12154145517 14662 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.219535 -0.521016 -1 Waypt 0.000 0.00 0.00 0.0 -0.220223 -0.521052 5* Junct- 0.076 0.05 0.08 0.0 96 182 main 1 -0.220666 -0.521060 4* Junct 0.049 0.03 0.12 0.1 96 180 main 1 -0.220702 -0.519478 12* Junct 0.176 0.22 0.30 0.3 48 91 high street -0.220263 -0.519309 13* Junct- 0.052 0.07 0.35 0.4 48 21 dead-end 1 -0.219924 -0.519179 14 Inter 0.040 0.05 0.39 0.4 48 20 dead-end 1 -0.219235 -0.519555 11 Inter 0.087 0.11 0.48 0.5 48 331 dead-end 1 -0.218387 -0.519137 15 Waypt 0.105 0.13 0.58 0.7 48 26 dead-end 1 -0.219235 -0.519555 11 Inter 0.105 0.13 0.69 0.8 48 206 dead-end 1 -0.219924 -0.519179 14 Inter 0.087 0.11 0.78 0.9 48 151 dead-end 1 -0.220263 -0.519309 13* Junct- 0.040 0.05 0.82 0.9 48 200 dead-end 1 -0.220702 -0.519478 12* Junct 0.052 0.07 0.87 1.0 48 201 dead-end 1 -0.220739 -0.517804 18* Junct 0.186 0.23 1.05 1.2 48 91 high street -0.220782 -0.516137 24* Junct 0.185 0.23 1.24 1.5 48 91 high street -0.220817 -0.514062 32* Junct 0.230 0.29 1.47 1.8 48 90 high street -0.220344 -0.514042 33* Junct- 0.052 0.03 1.52 1.8 96 2 main 2 -0.219539 -0.514007 -3 Waypt 0.089 0.06 1.61 1.8 96 2 main 2 routino-3.0/src/test/expected/dead-ends-WP08.txt 644 233 144 2301 12154146045 14651 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.219535 -0.521016 -1 Waypt 0.000 0.00 0.00 0.0 -0.220223 -0.521052 5* Junct- 0.076 0.05 0.08 0.0 96 182 main 1 -0.220666 -0.521060 4* Junct 0.049 0.03 0.12 0.1 96 180 main 1 -0.220702 -0.519478 12* Junct 0.176 0.22 0.30 0.3 48 91 high street -0.220739 -0.517804 18* Junct 0.186 0.23 0.49 0.5 48 91 high street -0.220782 -0.516137 24* Junct 0.185 0.23 0.67 0.8 48 91 high street -0.220361 -0.515961 25* Waypt 0.050 0.06 0.72 0.8 48 22 dead-end 3 -0.220782 -0.516137 24* Junct 0.050 0.06 0.77 0.9 48 202 dead-end 3 -0.220817 -0.514062 32* Junct 0.230 0.29 1.00 1.2 48 90 high street -0.220344 -0.514042 33* Junct- 0.052 0.03 1.05 1.2 96 2 main 2 -0.219539 -0.514007 -3 Waypt 0.089 0.06 1.14 1.3 96 2 main 2 routino-3.0/src/test/expected/roundabout-waypoints-WP03.txt 644 233 144 1445 12317763605 17255 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.218454 -0.520798 -1 Waypt 0.000 0.00 0.00 0.0 -0.219482 -0.520837 9* Junct 0.113 0.07 0.11 0.1 96 182 main 1 -0.219692 -0.520509 15 Waypt 0.043 0.03 0.16 0.1 96 122 roundabout -0.220082 -0.520522 14 Junct- 0.043 0.03 0.20 0.1 96 181 roundabout -0.220268 -0.520863 8* Junct 0.043 0.03 0.24 0.1 96 241 roundabout -0.221566 -0.520921 -3 Waypt 0.143 0.09 0.39 0.2 96 182 main 2 routino-3.0/src/test/expected/super-or-not-WP03.txt 644 233 144 1206 12064636362 15403 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.217245 -0.519637 2* Waypt 0.000 0.00 0.00 0.0 -0.215919 -0.519064 3 Inter 0.160 0.20 0.16 0.2 48 23 Local road -0.216435 -0.518515 4 Inter 0.083 0.10 0.24 0.3 48 133 Local road -0.215866 -0.517931 5 Waypt 0.090 0.11 0.33 0.4 48 45 Local road routino-3.0/src/test/expected/dead-ends-WP07.txt 644 233 144 3017 12154145517 14660 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.219535 -0.521016 -1 Waypt 0.000 0.00 0.00 0.0 -0.220223 -0.521052 5* Junct- 0.076 0.05 0.08 0.0 96 182 main 1 -0.220666 -0.521060 4* Junct 0.049 0.03 0.12 0.1 96 180 main 1 -0.220702 -0.519478 12* Junct 0.176 0.22 0.30 0.3 48 91 high street -0.220739 -0.517804 18* Junct 0.186 0.23 0.49 0.5 48 91 high street -0.220296 -0.517634 20* Junct- 0.052 0.07 0.54 0.6 48 21 dead-end 2 -0.219991 -0.517512 21 Inter 0.036 0.04 0.57 0.6 48 21 dead-end 2 -0.219635 -0.517707 -2 Waypt 0.045 0.06 0.62 0.7 48 331 dead-end 2 -0.219991 -0.517512 21 Inter 0.045 0.06 0.67 0.7 48 151 dead-end 2 -0.220296 -0.517634 20* Junct- 0.036 0.04 0.70 0.8 48 201 dead-end 2 -0.220739 -0.517804 18* Junct 0.052 0.07 0.75 0.9 48 201 dead-end 2 -0.220782 -0.516137 24* Junct 0.185 0.23 0.94 1.1 48 91 high street -0.220817 -0.514062 32* Junct 0.230 0.29 1.17 1.4 48 90 high street -0.220344 -0.514042 33* Junct- 0.052 0.03 1.22 1.4 96 2 main 2 -0.219539 -0.514007 -3 Waypt 0.089 0.06 1.31 1.5 96 2 main 2 routino-3.0/src/test/expected/turns-WP09.txt 644 233 144 4461 12064636362 14220 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.218453 -0.520799 -1 Waypt 0.000 0.00 0.00 0.0 -0.219107 -0.520828 6* Junct 0.072 0.04 0.07 0.0 96 182 main 1 -0.219123 -0.520207 12* Junct 0.069 0.09 0.14 0.1 48 91 top road -0.219131 -0.519426 20* Junct 0.086 0.11 0.23 0.2 48 90 top road -0.219135 -0.518823 23* Junct 0.067 0.08 0.29 0.3 48 90 top road -0.219145 -0.517626 33* Junct 0.133 0.17 0.43 0.5 48 90 top road -0.219144 -0.517257 36* Junct 0.041 0.05 0.47 0.5 48 89 top road -0.219291 -0.517193 38 Inter 0.017 0.02 0.48 0.6 48 156 roundabout -0.219352 -0.517060 42 Junct- 0.016 0.02 0.50 0.6 48 114 roundabout -0.219304 -0.516904 45 Inter 0.018 0.02 0.52 0.6 48 72 roundabout -0.219153 -0.516826 46* Junct 0.018 0.02 0.54 0.6 48 27 roundabout -0.219184 -0.515968 55* Junct 0.095 0.12 0.63 0.7 48 92 top road -0.220784 -0.516035 54* Junct 0.178 0.11 0.81 0.8 96 182 main 2 -0.220760 -0.516647 48* Junct 0.068 0.09 0.88 0.9 48 272 high street -0.220097 -0.516762 47* Inter 0.074 0.09 0.95 1.0 48 350 loop 3 -0.219872 -0.517009 43 Waypt 0.037 0.04 0.99 1.1 48 312 loop 3 -0.220089 -0.517279 35* Inter 0.038 0.05 1.03 1.1 48 231 loop 3 -0.220739 -0.517425 34* Junct 0.074 0.09 1.10 1.2 48 192 loop 3 -0.220724 -0.518071 31* Junct 0.071 0.09 1.17 1.3 48 271 high street -0.220708 -0.518842 22* Junct 0.085 0.10 1.26 1.4 48 271 high street -0.220691 -0.519461 19* Junct 0.069 0.09 1.33 1.5 48 271 high street -0.220671 -0.520223 11* Junct 0.084 0.10 1.41 1.6 48 271 high street -0.220666 -0.520893 5* Junct 0.074 0.09 1.48 1.7 48 270 high street -0.221308 -0.520914 4* Junct- 0.071 0.04 1.55 1.7 96 181 main 1 -0.221561 -0.520922 -3 Waypt 0.027 0.02 1.58 1.7 96 181 main 1 routino-3.0/src/test/expected/dead-ends-WP06.txt 644 233 144 2551 12154145517 14661 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.219535 -0.521016 -1 Waypt 0.000 0.00 0.00 0.0 -0.220223 -0.521052 5* Junct- 0.076 0.05 0.08 0.0 96 182 main 1 -0.220666 -0.521060 4* Junct 0.049 0.03 0.12 0.1 96 180 main 1 -0.220702 -0.519478 12* Junct 0.176 0.22 0.30 0.3 48 91 high street -0.220739 -0.517804 18* Junct 0.186 0.23 0.49 0.5 48 91 high street -0.220296 -0.517634 20* Junct- 0.052 0.07 0.54 0.6 48 21 dead-end 2 -0.219991 -0.517512 21 Waypt 0.036 0.04 0.57 0.6 48 21 dead-end 2 -0.220296 -0.517634 20* Junct- 0.036 0.04 0.61 0.7 48 201 dead-end 2 -0.220739 -0.517804 18* Junct 0.052 0.07 0.66 0.7 48 201 dead-end 2 -0.220782 -0.516137 24* Junct 0.185 0.23 0.85 1.0 48 91 high street -0.220817 -0.514062 32* Junct 0.230 0.29 1.08 1.3 48 90 high street -0.220344 -0.514042 33* Junct- 0.052 0.03 1.13 1.3 96 2 main 2 -0.219539 -0.514007 -3 Waypt 0.089 0.06 1.22 1.4 96 2 main 2 routino-3.0/src/test/expected/roundabout-waypoints-WP05.txt 644 233 144 1445 12317763605 17257 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.218454 -0.520798 -1 Waypt 0.000 0.00 0.00 0.0 -0.219482 -0.520837 9* Junct 0.113 0.07 0.11 0.1 96 182 main 1 -0.219692 -0.520509 15 Junct- 0.043 0.03 0.16 0.1 96 122 roundabout -0.220082 -0.520522 14 Waypt 0.043 0.03 0.20 0.1 96 181 roundabout -0.220268 -0.520863 8* Junct 0.043 0.03 0.24 0.1 96 241 roundabout -0.221566 -0.520921 -3 Waypt 0.143 0.09 0.39 0.2 96 182 main 2 routino-3.0/src/test/expected/turns-WP03.txt 644 233 144 2403 12064636362 14204 0# Creator : Routino - http://www.routino.org/ # Source : Routino test cases - (c) Andrew M. Bishop # License : GNU Affero General Public License v3 or later # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n -0.218453 -0.520799 -1 Waypt 0.000 0.00 0.00 0.0 -0.219107 -0.520828 6* Junct- 0.072 0.04 0.07 0.0 96 182 main 1 -0.220666 -0.520893 5* Junct 0.173 0.11 0.24 0.2 96 182 main 1 -0.220671 -0.520223 11* Junct 0.074 0.09 0.32 0.2 48 90 high street -0.220691 -0.519461 19* Junct 0.084 0.10 0.40 0.3 48 91 high street -0.220111 -0.519553 17 Inter 0.065 0.08 0.47 0.4 48 351 loop 1 -0.219817 -0.519807 15 Waypt 0.043 0.05 0.51 0.5 48 319 loop 1 -0.220067 -0.520109 13* Inter 0.043 0.05 0.55 0.5 48 230 loop 1 -0.220671 -0.520223 11* Junct 0.068 0.09 0.62 0.6 48 190 loop 1 -0.220666 -0.520893 5* Junct 0.074 0.09 0.70 0.7 48 270 high street -0.221308 -0.520914 4* Junct- 0.071 0.04 0.77 0.8 96 181 main 1 -0.221561 -0.520922 -3 Waypt 0.027 0.02 0.79 0.8 96 181 main 1 routino-3.0/src/test/invalid-turn-relations.sh 777 233 144 0 12064636362 17332 2only-split.shroutino-3.0/src/test/roundabout-waypoints.osm 644 233 144 10276 12327506431 14757 0 routino-3.0/src/test/roundabout-waypoints.sh 777 233 144 0 12317323573 17572 2start-1-finish.shroutino-3.0/src/test/turns.sh 777 233 144 0 12064636362 14532 2start-1-finish.shroutino-3.0/src/test/fake-node-with-loop.sh 777 233 144 0 12326742550 15234 2a-b-c.shroutino-3.0/src/test/no-super.osm 644 233 144 11616 12064636362 12316 0 routino-3.0/src/test/turns.osm 644 233 144 43517 12064636362 11726 0 routino-3.0/src/types.c 644 233 144 32536 12563633052 10360 0/*************************************** Functions for handling the data types. Part of the Routino routing software. ******************/ /****************** This file Copyright 2008-2015 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #include #include "types.h" /*++++++++++++++++++++++++++++++++++++++ Decide on the type of a way given the "highway" parameter. Highway HighwayType Returns the highway type of the way. const char *highway The string containing the type of the way. ++++++++++++++++++++++++++++++++++++++*/ Highway HighwayType(const char *highway) { switch(*highway) { case 'c': if(!strcmp(highway,"cycleway")) return(Highway_Cycleway); break; case 'f': if(!strcmp(highway,"ferry")) return(Highway_Ferry); break; case 'm': if(!strcmp(highway,"motorway")) return(Highway_Motorway); break; case 'p': if(!strcmp(highway,"primary")) return(Highway_Primary); if(!strcmp(highway,"path")) return(Highway_Path); break; case 'r': if(!strcmp(highway,"residential")) return(Highway_Residential); break; case 's': if(!strcmp(highway,"secondary")) return(Highway_Secondary); if(!strcmp(highway,"service")) return(Highway_Service); if(!strcmp(highway,"steps")) return(Highway_Steps); break; case 't': if(!strcmp(highway,"trunk")) return(Highway_Trunk); if(!strcmp(highway,"tertiary")) return(Highway_Tertiary); if(!strcmp(highway,"track")) return(Highway_Track); break; case 'u': if(!strcmp(highway,"unclassified")) return(Highway_Unclassified); break; default: ; } return(Highway_None); } /*++++++++++++++++++++++++++++++++++++++ Decide on the type of transport given the name of it. Transport TransportType Returns the type of the transport. const char *transport The string containing the method of transport. ++++++++++++++++++++++++++++++++++++++*/ Transport TransportType(const char *transport) { switch(*transport) { case 'b': if(!strcmp(transport,"bicycle")) return(Transport_Bicycle); break; case 'f': if(!strcmp(transport,"foot")) return(Transport_Foot); break; case 'g': if(!strcmp(transport,"goods")) return(Transport_Goods); break; case 'h': if(!strcmp(transport,"horse")) return(Transport_Horse); if(!strcmp(transport,"hgv")) return(Transport_HGV); break; case 'm': if(!strcmp(transport,"moped")) return(Transport_Moped); if(!strcmp(transport,"motorcycle")) return(Transport_Motorcycle); if(!strcmp(transport,"motorcar")) return(Transport_Motorcar); break; case 'p': if(!strcmp(transport,"psv")) return(Transport_PSV); break; case 'w': if(!strcmp(transport,"wheelchair")) return(Transport_Wheelchair); break; default: return(Transport_None); } return(Transport_None); } /*++++++++++++++++++++++++++++++++++++++ Decide on the type of property given the name of it. Property PropertyType Returns the type of the property. const char *property The string containing the method of property. ++++++++++++++++++++++++++++++++++++++*/ Property PropertyType(const char *property) { switch(*property) { case 'b': if(!strcmp(property,"bicycleroute")) return(Property_BicycleRoute); if(!strcmp(property,"bridge")) return(Property_Bridge); break; case 'f': if(!strcmp(property,"footroute")) return(Property_FootRoute); break; case 'm': if(!strcmp(property,"multilane")) return(Property_Multilane); break; case 'p': if(!strcmp(property,"paved")) return(Property_Paved); break; case 't': if(!strcmp(property,"tunnel")) return(Property_Tunnel); break; default: return(Property_None); } return(Property_None); } /*++++++++++++++++++++++++++++++++++++++ A string containing the name of a type of highway. const char *HighwayName Returns the name. Highway highway The highway type. ++++++++++++++++++++++++++++++++++++++*/ const char *HighwayName(Highway highway) { switch(highway) { case Highway_None: return("NONE"); case Highway_Motorway: return("motorway"); case Highway_Trunk: return("trunk"); case Highway_Primary: return("primary"); case Highway_Secondary: return("secondary"); case Highway_Tertiary: return("tertiary"); case Highway_Unclassified: return("unclassified"); case Highway_Residential: return("residential"); case Highway_Service: return("service"); case Highway_Track: return("track"); case Highway_Cycleway: return("cycleway"); case Highway_Path: return("path"); case Highway_Steps: return("steps"); case Highway_Ferry: return("ferry"); case Highway_Count: ; case Highway_CycleBothWays: ; case Highway_OneWay: ; case Highway_Roundabout: ; case Highway_Area: ; } return(NULL); } /*++++++++++++++++++++++++++++++++++++++ A string containing the name of a type of transport. const char *TransportName Returns the name. Transport transport The transport type. ++++++++++++++++++++++++++++++++++++++*/ const char *TransportName(Transport transport) { switch(transport) { case Transport_None: return("NONE"); case Transport_Foot: return("foot"); case Transport_Horse: return("horse"); case Transport_Wheelchair: return("wheelchair"); case Transport_Bicycle: return("bicycle"); case Transport_Moped: return("moped"); case Transport_Motorcycle: return("motorcycle"); case Transport_Motorcar: return("motorcar"); case Transport_Goods: return("goods"); case Transport_HGV: return("hgv"); case Transport_PSV: return("psv"); case Transport_Count: ; } return(NULL); } /*++++++++++++++++++++++++++++++++++++++ A string containing the name of a highway property. const char *PropertyName Returns the name. Property property The property type. ++++++++++++++++++++++++++++++++++++++*/ const char *PropertyName(Property property) { switch(property) { case Property_None: return("NONE"); case Property_Paved: return("paved"); case Property_Multilane: return("multilane"); case Property_Bridge: return("bridge"); case Property_Tunnel: return("tunnel"); case Property_FootRoute: return("footroute"); case Property_BicycleRoute: return("bicycleroute"); case Property_Count: ; } return(NULL); } /*++++++++++++++++++++++++++++++++++++++ A string containing the names of highways. const char *HighwaysNameList Returns the list of names. highways_t highways The highways type. ++++++++++++++++++++++++++++++++++++++*/ const char *HighwaysNameList(highways_t highways) { static char string[256]; /* static allocation of return value (set each call) */ string[0]=0; if(highways & Highways_Motorway) strcat(string,"motorway"); if(highways & Highways_Trunk) { if(*string) strcat(string,", "); strcat(string,"trunk"); } if(highways & Highways_Primary) { if(*string) strcat(string,", "); strcat(string,"primary"); } if(highways & Highways_Tertiary) { if(*string) strcat(string,", "); strcat(string,"tertiary"); } if(highways & Highways_Unclassified) { if(*string) strcat(string,", "); strcat(string,"unclassified"); } if(highways & Highways_Residential) { if(*string) strcat(string,", "); strcat(string,"residential"); } if(highways & Highways_Service) { if(*string) strcat(string,", "); strcat(string,"service"); } if(highways & Highways_Track) { if(*string) strcat(string,", "); strcat(string,"track"); } if(highways & Highways_Cycleway) { if(*string) strcat(string,", "); strcat(string,"cycleway"); } if(highways & Highways_Path) { if(*string) strcat(string,", "); strcat(string,"path"); } if(highways & Highways_Steps) { if(*string) strcat(string,", "); strcat(string,"steps"); } if(highways & Highways_Ferry) { if(*string) strcat(string,", "); strcat(string,"ferry"); } return(string); } /*++++++++++++++++++++++++++++++++++++++ A string containing the names of allowed transports on a way. const char *AllowedNameList Returns the list of names. transports_t allowed The allowed type. ++++++++++++++++++++++++++++++++++++++*/ const char *AllowedNameList(transports_t allowed) { static char string[256]; /* static allocation of return value (set each call) */ string[0]=0; if(allowed & Transports_Foot) strcat(string,"foot"); if(allowed & Transports_Horse) { if(*string) strcat(string,", "); strcat(string,"horse"); } if(allowed & Transports_Wheelchair) { if(*string) strcat(string,", "); strcat(string,"wheelchair"); } if(allowed & Transports_Bicycle) { if(*string) strcat(string,", "); strcat(string,"bicycle"); } if(allowed & Transports_Moped) { if(*string) strcat(string,", "); strcat(string,"moped"); } if(allowed & Transports_Motorcycle) { if(*string) strcat(string,", "); strcat(string,"motorcycle"); } if(allowed & Transports_Motorcar) { if(*string) strcat(string,", "); strcat(string,"motorcar"); } if(allowed & Transports_Goods) { if(*string) strcat(string,", "); strcat(string,"goods"); } if(allowed & Transports_HGV) { if(*string) strcat(string,", "); strcat(string,"hgv"); } if(allowed & Transports_PSV) { if(*string) strcat(string,", "); strcat(string,"psv"); } return(string); } /*++++++++++++++++++++++++++++++++++++++ A string containing the names of the properties of a way. const char *PropertiesNameList Returns the list of names. properties_t properties The properties of the way. ++++++++++++++++++++++++++++++++++++++*/ const char *PropertiesNameList(properties_t properties) { static char string[256]; /* static allocation of return value (set each call) */ string[0]=0; if(properties & Properties_Paved) { if(*string) strcat(string,", "); strcat(string,"paved"); } if(properties & Properties_Multilane) { if(*string) strcat(string,", "); strcat(string,"multilane"); } if(properties & Properties_Bridge) { if(*string) strcat(string,", "); strcat(string,"bridge"); } if(properties & Properties_Tunnel) { if(*string) strcat(string,", "); strcat(string,"tunnel"); } if(properties & Properties_FootRoute) { if(*string) strcat(string,", "); strcat(string,"footroute"); } if(properties & Properties_BicycleRoute) { if(*string) strcat(string,", "); strcat(string,"bicycleroute"); } return(string); } /*++++++++++++++++++++++++++++++++++++++ Returns a list of all the highway types. const char *HighwayList Return a list of all the highway types. ++++++++++++++++++++++++++++++++++++++*/ const char *HighwayList(void) { return " motorway = Motorway\n" " trunk = Trunk\n" " primary = Primary\n" " secondary = Secondary\n" " tertiary = Tertiary\n" " unclassified = Unclassified\n" " residential = Residential\n" " service = Service\n" " track = Track\n" " cycleway = Cycleway\n" " path = Path\n" " steps = Steps\n" " ferry = Ferry\n" ; } /*++++++++++++++++++++++++++++++++++++++ Returns a list of all the transport types. const char *TransportList Return a list of all the transport types. ++++++++++++++++++++++++++++++++++++++*/ const char *TransportList(void) { return " foot = Foot\n" " bicycle = Bicycle\n" " wheelchair = Wheelchair\n" " horse = Horse\n" " moped = Moped (Small motorcycle, limited speed)\n" " motorcycle = Motorcycle\n" " motorcar = Motorcar\n" " goods = Goods (Small lorry, van)\n" " hgv = HGV (Heavy Goods Vehicle - large lorry)\n" " psv = PSV (Public Service Vehicle - bus, coach)\n" ; } /*++++++++++++++++++++++++++++++++++++++ Returns a list of all the property types. const char *PropertyList Return a list of all the highway proprties. ++++++++++++++++++++++++++++++++++++++*/ const char *PropertyList(void) { return " paved = Paved (suitable for normal wheels)\n" " multilane = Multiple lanes\n" " bridge = Bridge\n" " tunnel = Tunnel\n" " footroute = A route marked for foot travel\n" " bicycleroute = A route marked for bicycle travel\n" ; } routino-3.0/src/files.h 644 233 144 11413 12563634111 10307 0/*************************************** Header file for file function prototypes Part of the Routino routing software. ******************/ /****************** This file Copyright 2008-2015 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #ifndef FILES_H #define FILES_H /*+ To stop multiple inclusions. +*/ /* If your system does not have the pread() and pwrite() system calls then you * will need to change this line to the value 0 so that seek() and * read()/write() are used instead of pread()/pwrite(). */ #if defined(_MSC_VER) || defined(__MINGW32__) #define HAVE_PREAD_PWRITE 0 #else #define HAVE_PREAD_PWRITE 1 #endif #if defined(_MSC_VER) #include #include #define read(fd,address,length) _read(fd,address,(unsigned int)(length)) #define write(fd,address,length) _write(fd,address,(unsigned int)(length)) #define ssize_t SSIZE_T #else #include #endif #if defined(_MSC_VER) || defined(__MINGW32__) #undef lseek #define lseek _lseeki64 #endif #include #include #include "logging.h" /* Types */ /*+ A 64-bit file offset since a 32-bit off_t (which is signed) is smaller than a 32-bit size_t (which is unsigned) that can be writtento or read from a file. +*/ typedef int64_t offset_t; /* Functions in files.c */ char *FileName(const char *dirname,const char *prefix, const char *name); void *MapFile(const char *filename); void *MapFileWriteable(const char *filename); void *UnmapFile(const void *address); int SlimMapFile(const char *filename); int SlimMapFileWriteable(const char *filename); int SlimUnmapFile(int fd); int OpenFileBufferedNew(const char *filename); int OpenFileBufferedAppend(const char *filename); int ReOpenFileBuffered(const char *filename); int ReplaceFileBuffered(const char *filename,int *oldfd); int WriteFileBuffered(int fd,const void *address,size_t length); int ReadFileBuffered(int fd,void *address,size_t length); int SeekFileBuffered(int fd,offset_t position); int SkipFileBuffered(int fd,offset_t skip); int CloseFileBuffered(int fd); int OpenFile(const char *filename); void CloseFile(int fd); offset_t SizeFile(const char *filename); offset_t SizeFileFD(int fd); int ExistsFile(const char *filename); int DeleteFile(const char *filename); int RenameFile(const char *oldfilename,const char *newfilename); /* Functions in files.h */ static inline int SlimReplace(int fd,const void *address,size_t length,offset_t position); static inline int SlimFetch(int fd,void *address,size_t length,offset_t position); /* Inline the frequently called functions */ /*++++++++++++++++++++++++++++++++++++++ Write data to a file that has been opened for slim mode access. int SlimReplace Returns 0 if OK or something else in case of an error. int fd The file descriptor to write to. const void *address The address of the data to be written. size_t length The length of data to write. offset_t position The position in the file to seek to. ++++++++++++++++++++++++++++++++++++++*/ static inline int SlimReplace(int fd,const void *address,size_t length,offset_t position) { /* Seek and write the data */ #if HAVE_PREAD_PWRITE if(pwrite(fd,address,length,position)!=(ssize_t)length) return(-1); #else if(lseek(fd,position,SEEK_SET)!=position) return(-1); if(write(fd,address,length)!=(ssize_t)length) return(-1); #endif return(0); } /*++++++++++++++++++++++++++++++++++++++ Read data from a file that has been opened for slim mode access. int SlimFetch Returns 0 if OK or something else in case of an error. int fd The file descriptor to read from. void *address The address the data is to be read into. size_t length The length of data to read. offset_t position The position in the file to seek to. ++++++++++++++++++++++++++++++++++++++*/ static inline int SlimFetch(int fd,void *address,size_t length,offset_t position) { /* Seek and read the data */ #if HAVE_PREAD_PWRITE if(pread(fd,address,length,position)!=(ssize_t)length) return(-1); #else if(lseek(fd,position,SEEK_SET)!=position) return(-1); if(read(fd,address,length)!=(ssize_t)length) return(-1); #endif return(0); } #endif /* FILES_H */ routino-3.0/src/fakes.h 644 233 144 3742 12563633051 10266 0/*************************************** Header file for fake node and segment function prototypes Part of the Routino routing software. ******************/ /****************** This file Copyright 2008-2015 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #ifndef FAKES_H #define FAKES_H /*+ To stop multiple inclusions. +*/ #include "types.h" /* Macros */ /*+ Return true if this is a fake node. +*/ #define IsFakeNode(xxx) ((xxx)>=NODE_FAKE && (xxx)!=NO_NODE) /*+ Return true if this is a fake segment. +*/ #define IsFakeSegment(xxx) ((xxx)>=SEGMENT_FAKE && (xxx)!=NO_SEGMENT) /* Functions in fakes.c */ index_t CreateFakes(Nodes *nodes,Segments *segments,int point,Segment *segmentp,index_t node1,index_t node2,distance_t dist1,distance_t dist2); index_t CreateFakeNullSegment(Segments *segments,index_t node,index_t segment,int point); void DeleteFakeNodes(void); void GetFakeLatLong(index_t fakenode, double *latitude,double *longitude); Segment *FirstFakeSegment(index_t fakenode); Segment *NextFakeSegment(Segment *fakesegmentp,index_t fakenode); Segment *ExtraFakeSegment(index_t realnode,index_t fakenode); Segment *LookupFakeSegment(index_t index); index_t IndexFakeSegment(Segment *fakesegmentp); index_t IndexRealSegment(index_t fakesegment); int IsFakeUTurn(index_t fakesegment1,index_t fakesegment2); #endif /* FAKES_H */ routino-3.0/src/fakes.c 644 233 144 27550 12563633051 10304 0/*************************************** Fake node and segment generation. Part of the Routino routing software. ******************/ /****************** This file Copyright 2008-2015 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #include "types.h" #include "nodes.h" #include "segments.h" #include "fakes.h" /*+ The minimum distance along a segment from a node to insert a fake node. (in km). +*/ #define MINSEGMENT 0.005 /* Local variables (re-initialised by DeleteFakeNodes() function) */ /*+ A set of fake segments to allow start/finish in the middle of a segment. +*/ static Segment fake_segments[4*NWAYPOINTS+1]; /*+ A set of pointers to the real segments underlying the fake segments. +*/ static index_t real_segments[4*NWAYPOINTS+1]; /*+ A set of fake node latitudes and longitudes. +*/ static double fake_lon[NWAYPOINTS+1],fake_lat[NWAYPOINTS+1]; /*+ The previous waypoint. +*/ static int prevpoint=0; /*++++++++++++++++++++++++++++++++++++++ Create a pair of fake segments corresponding to the given segment split in two (and will create an extra two fake segments if adjacent waypoints are on the same segment). index_t CreateFakes Returns the fake node index (or a real one in special cases). Nodes *nodes The set of nodes to use. Segments *segments The set of segments to use. int point Which of the waypoints this is. Segment *segmentp The segment to split. index_t node1 The first node at the end of this segment. index_t node2 The second node at the end of this segment. distance_t dist1 The distance to the first node. distance_t dist2 The distance to the second node. ++++++++++++++++++++++++++++++++++++++*/ index_t CreateFakes(Nodes *nodes,Segments *segments,int point,Segment *segmentp,index_t node1,index_t node2,distance_t dist1,distance_t dist2) { index_t fakenode; double lat1,lon1,lat2,lon2; /* Initialise all the connecting segments to fake values */ fake_segments[4*point-4].node1=NO_NODE; fake_segments[4*point-4].node2=NO_NODE; fake_segments[4*point-3].node1=NO_NODE; fake_segments[4*point-3].node2=NO_NODE; fake_segments[4*point-2].node1=NO_NODE; fake_segments[4*point-2].node2=NO_NODE; fake_segments[4*point-1].node1=NO_NODE; fake_segments[4*point-1].node2=NO_NODE; /* Check if we are actually close enough to an existing node */ if(dist1<=km_to_distance(MINSEGMENT) && dist2>km_to_distance(MINSEGMENT)) { prevpoint=point; return(node1); } if(dist2<=km_to_distance(MINSEGMENT) && dist1>km_to_distance(MINSEGMENT)) { prevpoint=point; return(node2); } if(dist1<=km_to_distance(MINSEGMENT) && dist2<=km_to_distance(MINSEGMENT)) { prevpoint=point; if(dist13 && lat2<-3) lat2+=2*M_PI; else if(lat1<-3 && lat2>3) lat1+=2*M_PI; fake_lat[point]=lat1+(lat2-lat1)*(double)dist1/(double)(dist1+dist2); /* (dist1+dist2) must be > 0 */ fake_lon[point]=lon1+(lon2-lon1)*(double)dist1/(double)(dist1+dist2); /* (dist1+dist2) must be > 0 */ if(fake_lat[point]>M_PI) fake_lat[point]-=2*M_PI; /* * node1 fakenode node2 * #----------*----------------------------# real_segments[4*point-{4,3}] * * #----------* fake_segments[4*point-4] * *----------------------------# fake_segments[4*point-3] * * * node1 fakenode[prevpoint] node2 * #----------*------------------%---------# real_segments[4*prevpoint-{4,3,1}], real_segments[4*point-{4,3,2}] * fakenode[point] * #----------* fake_segments[4*prevpoint-4] * *----------------------------# fake_segments[4*prevpoint-3] * *------------------% fake_segments[4*prevpoint-1] * #-----------------------------% fake_segments[4*point-4] * %---------# fake_segments[4*point-3] * *------------------% fake_segments[4*point-2] */ /* Create the first fake segment */ fake_segments[4*point-4]=*segmentp; fake_segments[4*point-4].node2=fakenode; fake_segments[4*point-4].distance=DISTANCE(dist1)|DISTFLAG(segmentp->distance); real_segments[4*point-4]=IndexSegment(segments,segmentp); /* Create the second fake segment */ fake_segments[4*point-3]=*segmentp; fake_segments[4*point-3].node1=fakenode; fake_segments[4*point-3].distance=DISTANCE(dist2)|DISTFLAG(segmentp->distance); real_segments[4*point-3]=IndexSegment(segments,segmentp); /* Create a third fake segment to join adjacent points if both are fake and on the same real segment */ if(prevpoint>0 && fake_segments[4*prevpoint-4].node1==node1 && fake_segments[4*prevpoint-3].node2==node2) { if(DISTANCE(dist1)>DISTANCE(fake_segments[4*prevpoint-4].distance)) /* point is further from node1 than prevpoint */ { fake_segments[4*point-2]=fake_segments[4*prevpoint-3]; fake_segments[4*point-2].node2=fakenode; fake_segments[4*point-2].distance=(DISTANCE(dist1)-DISTANCE(fake_segments[4*prevpoint-4].distance))|DISTFLAG(segmentp->distance); } else { fake_segments[4*point-2]=fake_segments[4*prevpoint-4]; fake_segments[4*point-2].node1=fakenode; fake_segments[4*point-2].distance=(DISTANCE(fake_segments[4*prevpoint-4].distance)-DISTANCE(dist1))|DISTFLAG(segmentp->distance); } real_segments[4*point-2]=IndexSegment(segments,segmentp); fake_segments[4*prevpoint-1]=fake_segments[4*point-2]; real_segments[4*prevpoint-1]=real_segments[4*point-2]; } /* Return the fake node */ prevpoint=point; return(fakenode); } /*++++++++++++++++++++++++++++++++++++++ Create a fake segment connecting a node to itself. index_t CreateFakeNullSegment Returns the index of a fake segment. Segments *segments The list of segments to use. index_t node The node that is to be linked. index_t segment The segment that is to be emulated. int point The waypoint number. ++++++++++++++++++++++++++++++++++++++*/ index_t CreateFakeNullSegment(Segments *segments,index_t node,index_t segment,int point) { Segment *segmentp=LookupSegment(segments,segment,1); fake_segments[4*point-2].node1=node; fake_segments[4*point-2].node2=node; fake_segments[4*point-2].way=segmentp->way; fake_segments[4*point-2].distance=0; return(4*point-2+SEGMENT_FAKE); } /*++++++++++++++++++++++++++++++++++++++ Re-initialise the fake node data storage. ++++++++++++++++++++++++++++++++++++++*/ void DeleteFakeNodes(void) { unsigned int i; for(i=0;i. ***************************************/ #ifndef ROUTINO_H #define ROUTINO_H /*+ To stop multiple inclusions. +*/ /* Limit the exported symbols in the library */ #if defined(_MSC_VER) #ifdef LIBROUTINO #define DLL_PUBLIC __declspec(dllexport) #else #define DLL_PUBLIC __declspec(dllimport) #endif #endif #if defined(__GNUC__) && __GNUC__ >= 4 #if defined(__MINGW32__) || defined(__CYGWIN__) #ifdef LIBROUTINO #define DLL_PUBLIC __attribute__ ((dllexport)) #else #define DLL_PUBLIC __attribute__ ((dllimport)) #endif #else #ifdef LIBROUTINO #define DLL_PUBLIC __attribute__ ((visibility ("default"))) #endif #endif #endif #ifndef DLL_PUBLIC #define DLL_PUBLIC #endif /* Handle compilation with a C++ compiler */ #ifdef __cplusplus extern "C" { #endif /* Routino library API version */ #define ROUTINO_API_VERSION 7 /*+ A version number for the Routino API. +*/ /* Routino error constants */ #define ROUTINO_ERROR_NONE 0 /*+ No error. +*/ #define ROUTINO_ERROR_NO_DATABASE 1 /*+ A function was called without the database variable set. +*/ #define ROUTINO_ERROR_NO_PROFILE 2 /*+ A function was called without the profile variable set. +*/ #define ROUTINO_ERROR_NO_TRANSLATION 3 /*+ A function was called without the translation variable set. +*/ #define ROUTINO_ERROR_NO_DATABASE_FILES 11 /*+ The specified database to load did not exist. +*/ #define ROUTINO_ERROR_BAD_DATABASE_FILES 12 /*+ The specified database could not be loaded. +*/ #define ROUTINO_ERROR_NO_PROFILES_XML 13 /*+ The specified profiles XML file did not exist. +*/ #define ROUTINO_ERROR_BAD_PROFILES_XML 14 /*+ The specified profiles XML file could not be loaded. +*/ #define ROUTINO_ERROR_NO_TRANSLATIONS_XML 15 /*+ The specified translations XML file did not exist. +*/ #define ROUTINO_ERROR_BAD_TRANSLATIONS_XML 16 /*+ The specified translations XML file could not be loaded. +*/ #define ROUTINO_ERROR_NO_SUCH_PROFILE 21 /*+ The requested profile name does not exist in the loaded XML file. +*/ #define ROUTINO_ERROR_NO_SUCH_TRANSLATION 22 /*+ The requested translation language does not exist in the loaded XML file. +*/ #define ROUTINO_ERROR_NO_NEARBY_HIGHWAY 31 /*+ There is no highway near the coordinates to place a waypoint. +*/ #define ROUTINO_ERROR_PROFILE_DATABASE_ERR 41 /*+ The profile and database do not work together. +*/ #define ROUTINO_ERROR_NOTVALID_PROFILE 42 /*+ The profile being used has not been validated. +*/ #define ROUTINO_ERROR_BAD_USER_PROFILE 43 /*+ The user specified profile contained invalid data. +*/ #define ROUTINO_ERROR_BAD_OPTIONS 51 /*+ The routing options specified are not consistent with each other. +*/ #define ROUTINO_ERROR_WRONG_API_VERSION 61 /*+ There is a mismatch between the library and caller API version. +*/ #define ROUTINO_ERROR_PROGRESS_ABORTED 71 /*+ The progress function returned false. +*/ #define ROUTINO_ERROR_NO_ROUTE_1 1001 /*+ A route could not be found to waypoint 1. +*/ #define ROUTINO_ERROR_NO_ROUTE_2 1002 /*+ A route could not be found to waypoint 2. +*/ #define ROUTINO_ERROR_NO_ROUTE_3 1003 /*+ A route could not be found to waypoint 3. +*/ /* Higher values of the error number refer to later waypoints. */ /* Routino routing option constants */ #define ROUTINO_ROUTE_SHORTEST 0 /*+ Calculate the shortest route. +*/ #define ROUTINO_ROUTE_QUICKEST 1 /*+ Calculate the quickest route. +*/ #define ROUTINO_ROUTE_FILE_HTML 2 /*+ Output an HTML route file. +*/ #define ROUTINO_ROUTE_FILE_GPX_TRACK 4 /*+ Output a GPX track file. +*/ #define ROUTINO_ROUTE_FILE_GPX_ROUTE 8 /*+ Output a GPX route file. +*/ #define ROUTINO_ROUTE_FILE_TEXT 16 /*+ Output a text file with important junctions. +*/ #define ROUTINO_ROUTE_FILE_TEXT_ALL 32 /*+ Output a text file with all nodes and segments. +*/ #define ROUTINO_ROUTE_FILE_STDOUT 64 /*+ Output a single file type to stdout. +*/ #define ROUTINO_ROUTE_LIST_HTML 128 /*+ Output a linked list of points containing the HTML file information but as plain text. +*/ #define ROUTINO_ROUTE_LIST_HTML_ALL 256 /*+ Output a linked list of points containing the HTML file information as plain text and with all points. +*/ #define ROUTINO_ROUTE_LIST_TEXT 512 /*+ Output a linked list of points containing the text file information. +*/ #define ROUTINO_ROUTE_LIST_TEXT_ALL 1024 /*+ Output a linked list of points containing the text all file information. +*/ /* Routino output point types */ #define ROUTINO_POINT_UNIMPORTANT 0 /*+ An unimportant, intermediate, node. +*/ #define ROUTINO_POINT_RB_NOT_EXIT 1 /*+ A roundabout exit that is not taken. +*/ #define ROUTINO_POINT_JUNCT_CONT 2 /*+ An un-interesting junction where the route continues without comment. +*/ #define ROUTINO_POINT_CHANGE 3 /*+ The highway changes type but nothing else happens. +*/ #define ROUTINO_POINT_JUNCT_IMPORT 4 /*+ An interesting junction to be described. +*/ #define ROUTINO_POINT_RB_ENTRY 5 /*+ The entrance to a roundabout. +*/ #define ROUTINO_POINT_RB_EXIT 6 /*+ The exit from a roundabout. +*/ #define ROUTINO_POINT_MINI_RB 7 /*+ The location of a mini-roundabout. +*/ #define ROUTINO_POINT_UTURN 8 /*+ The location of a U-turn. +*/ #define ROUTINO_POINT_WAYPOINT 9 /*+ A waypoint. +*/ /* Routino user profile array indexes */ #define ROUTINO_HIGHWAY_MOTORWAY 1 /*+ A Motorway highway. +*/ #define ROUTINO_HIGHWAY_TRUNK 2 /*+ A Trunk highway. +*/ #define ROUTINO_HIGHWAY_PRIMARY 3 /*+ A Primary highway. +*/ #define ROUTINO_HIGHWAY_SECONDARY 4 /*+ A Secondary highway. +*/ #define ROUTINO_HIGHWAY_TERTIARY 5 /*+ A Tertiary highway. +*/ #define ROUTINO_HIGHWAY_UNCLASSIFIED 6 /*+ A Unclassified highway. +*/ #define ROUTINO_HIGHWAY_RESIDENTIAL 7 /*+ A Residential highway. +*/ #define ROUTINO_HIGHWAY_SERVICE 8 /*+ A Service highway. +*/ #define ROUTINO_HIGHWAY_TRACK 9 /*+ A Track highway. +*/ #define ROUTINO_HIGHWAY_CYCLEWAY 10 /*+ A Cycleway highway. +*/ #define ROUTINO_HIGHWAY_PATH 11 /*+ A Path highway. +*/ #define ROUTINO_HIGHWAY_STEPS 12 /*+ A Steps highway. +*/ #define ROUTINO_HIGHWAY_FERRY 13 /*+ A Ferry highway. +*/ #define ROUTINO_PROPERTY_PAVED 1 /*+ A Paved highway. +*/ #define ROUTINO_PROPERTY_MULTILANE 2 /*+ A Multilane highway. +*/ #define ROUTINO_PROPERTY_BRIDGE 3 /*+ A Bridge highway. +*/ #define ROUTINO_PROPERTY_TUNNEL 4 /*+ A Tunnel highway. +*/ #define ROUTINO_PROPERTY_FOOTROUTE 5 /*+ A Footroute highway. +*/ #define ROUTINO_PROPERTY_BICYCLEROUTE 6 /*+ A Bicycleroute highway. +*/ /* Routino types */ /*+ A data structure to hold a Routino database loaded from a file (the contents are private). +*/ typedef struct _Routino_Database Routino_Database; /*+ A data structure to hold a Routino waypoint found within the database (the contents are private). +*/ typedef struct _Routino_Waypoint Routino_Waypoint; /*+ A data structure to hold a Routino routing profile (the contents are private). +*/ #ifdef LIBROUTINO typedef struct _Profile Routino_Profile; #else typedef struct _Routino_Profile Routino_Profile; #endif /*+ A data structure to hold a Routino translation (the contents are private). +*/ #ifdef LIBROUTINO typedef struct _Translation Routino_Translation; #else typedef struct _Routino_Translation Routino_Translation; #endif /*+ A data structure to hold a routing profile that can be defined by the user. +*/ typedef struct _Routino_UserProfile { int transport; /*+ The type of transport. +*/ float highway[14]; /*+ A floating point preference for travel on the highway (range 0 to 1). +*/ float speed[14]; /*+ The maximum speed on each type of highway (km/hour). +*/ float props[7]; /*+ A floating point preference for ways with this attribute (range 0 to 1). +*/ int oneway; /*+ A flag to indicate if one-way restrictions apply. +*/ int turns; /*+ A flag to indicate if turn restrictions apply. +*/ float weight; /*+ The weight of the vehicle (in tonnes). +*/ float height; /*+ The height of the vehicle (in metres). +*/ float width; /*+ The width of vehicle (in metres). +*/ float length; /*+ The length of vehicle (in metres). +*/ } Routino_UserProfile; /*+ Forward declaration of the Routino_Output data type. +*/ typedef struct _Routino_Output Routino_Output; /*+ A linked list output of the calculated route whose contents depend on the ROUTINO_ROUTE_LIST_* options selected. +*/ struct _Routino_Output { Routino_Output *next; /*+ A pointer to the next route section. +*/ float lon; /*+ The longitude of the point (radians). +*/ float lat; /*+ The latitude of the point (radians). +*/ float dist; /*+ The total distance travelled (kilometres) up to the point. +*/ float time; /*+ The total journey time (seconds) up to the point. +*/ float speed; /*+ The speed (km/hr) for this section of the route (ROUTINO_ROUTE_LIST_TEXT_ALL format only). +*/ int type; /*+ The type of point (one of the ROUTINO_POINT_* values). +*/ int turn; /*+ The amount to turn (degrees) for the next section of the route (ROUTINO_ROUTE_LIST_TEXT or ROUTINO_ROUTE_LIST_HTML or ROUTINO_ROUTE_LIST_HTML_ALL format). +*/ int bearing; /*+ The compass direction (degrees) for the next section of the route. +*/ char *name; /*+ The name of the next section of the route (ROUTINO_ROUTE_LIST_TEXT or ROUTINO_ROUTE_LIST_HTML or ROUTINO_ROUTE_LIST_HTML_ALL format) or previous section of the route (ROUTINO_ROUTE_LIST_TEXT_ALL format). +*/ char *desc1; /*+ The first part of the description of the next section of route (ROUTINO_ROUTE_LIST_HTML or ROUTINO_ROUTE_LIST_HTML format). +*/ char *desc2; /*+ The second part of the description of the next section of route (ROUTINO_ROUTE_LIST_HTML or ROUTINO_ROUTE_LIST_HTML format). +*/ char *desc3; /*+ The third part of the description, the total distance and time at the end of the next section of route (ROUTINO_ROUTE_LIST_HTML or ROUTINO_ROUTE_LIST_HTML format). +*/ }; /*+ A type of function that can be used as a callback to indicate routing progress, if it returns false the router stops. +*/ typedef int (*Routino_ProgressFunc)(double complete); /* Routino error number variable */ /*+ Contains the libroutino API version number. +*/ DLL_PUBLIC extern int Routino_APIVersion; /*+ Contains the error number of the most recent Routino function (one of the ROUTINO_ERROR_* values). +*/ DLL_PUBLIC extern int Routino_errno; /* Routino library functions */ #define Routino_CheckAPIVersion() Routino_Check_API_Version(ROUTINO_API_VERSION) /*+ A wrapper function to simplify the API version check. +*/ DLL_PUBLIC int Routino_Check_API_Version(int caller_version); DLL_PUBLIC Routino_Database *Routino_LoadDatabase(const char *dirname,const char *prefix); DLL_PUBLIC void Routino_UnloadDatabase(Routino_Database *database); DLL_PUBLIC int Routino_ParseXMLProfiles(const char *filename); DLL_PUBLIC char **Routino_GetProfileNames(void); DLL_PUBLIC Routino_Profile *Routino_GetProfile(const char *name); DLL_PUBLIC void Routino_FreeXMLProfiles(void); DLL_PUBLIC int Routino_ParseXMLTranslations(const char *filename); DLL_PUBLIC char **Routino_GetTranslationLanguages(void); DLL_PUBLIC char **Routino_GetTranslationLanguageFullNames(void); DLL_PUBLIC Routino_Translation *Routino_GetTranslation(const char *language); DLL_PUBLIC void Routino_FreeXMLTranslations(void); DLL_PUBLIC Routino_Profile *Routino_CreateProfileFromUserProfile(Routino_UserProfile *profile); DLL_PUBLIC Routino_UserProfile *Routino_CreateUserProfileFromProfile(Routino_Profile *profile); DLL_PUBLIC int Routino_ValidateProfile(Routino_Database *database,Routino_Profile *profile); DLL_PUBLIC Routino_Waypoint *Routino_FindWaypoint(Routino_Database *database,Routino_Profile *profile,double latitude,double longitude); DLL_PUBLIC Routino_Output *Routino_CalculateRoute(Routino_Database *database,Routino_Profile *profile,Routino_Translation *translation, Routino_Waypoint **waypoints,int nwaypoints,int options,Routino_ProgressFunc progress); DLL_PUBLIC void Routino_DeleteRoute(Routino_Output *output); /* Handle compilation with a C++ compiler */ #ifdef __cplusplus } #endif #endif /* ROUTINO_H */ routino-3.0/src/translations.h 644 233 144 4713 12564415511 11715 0/*************************************** Load the translations from a file and the functions for handling them. Part of the Routino routing software. ******************/ /****************** This file Copyright 2010-2015 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #ifndef TRANSLATIONS_H #define TRANSLATIONS_H /*+ To stop multiple inclusions. +*/ #include "types.h" /* Type declarations */ typedef struct _Translation { char *lang; char *language; char *raw_copyright_creator[2]; char *raw_copyright_source[2]; char *raw_copyright_license[2]; char *xml_copyright_creator[2]; char *xml_copyright_source[2]; char *xml_copyright_license[2]; char *xml_heading[9]; char *xml_turn[9]; char *xml_ordinal[10]; char *notxml_heading[9]; char *notxml_turn[9]; char *notxml_ordinal[10]; char *raw_highway[Highway_Count]; char *xml_route_shortest; char *xml_route_quickest; char *html_waypoint; char *html_junction; char *html_roundabout; char *html_title; char *html_start; char *html_segment; char *html_node; char *html_rbnode; char *html_stop; char *html_total; char *html_subtotal; char *nothtml_waypoint; char *nothtml_junction; char *nothtml_roundabout; char *nothtml_title; char *nothtml_start; char *nothtml_segment; char *nothtml_node; char *nothtml_rbnode; char *nothtml_stop; char *nothtml_total; char *nothtml_subtotal; char *gpx_desc; char *gpx_name; char *gpx_step; char *gpx_final; char *gpx_start; char *gpx_inter; char *gpx_trip; char *gpx_finish; } Translation; /* Functions in translations.c */ int ParseXMLTranslations(const char *filename,const char *lang,int all); char **GetTranslationLanguages(void); char **GetTranslationLanguageFullNames(void); Translation *GetTranslation(const char *lang); void FreeXMLTranslations(void); #endif /* TRANSLATIONS_H */ routino-3.0/src/functions.h 644 233 144 3072 12563633051 11201 0/*************************************** Header file for miscellaneous function prototypes Part of the Routino routing software. ******************/ /****************** This file Copyright 2008-2015 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #ifndef FUNCTIONS_H #define FUNCTIONS_H /*+ To stop multiple inclusions. +*/ #include "types.h" #include "profiles.h" #include "translations.h" #include "results.h" #include "routino.h" /* Functions in optimiser.c */ Results *CalculateRoute(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,Profile *profile, index_t start_node,index_t prev_segment,index_t finish_node, int start_waypoint,int finish_waypoint); /* Functions in output.c */ Routino_Output *PrintRoute(Results **results,int nresults,Nodes *nodes,Segments *segments,Ways *ways,Profile *profile,Translation *translation); #endif /* FUNCTIONS_H */ routino-3.0/src/superx.c 644 233 144 37501 12563633051 10536 0/*************************************** Super-Segment data type functions. Part of the Routino routing software. ******************/ /****************** This file Copyright 2008-2015 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #include #include "types.h" #include "segments.h" #include "ways.h" #include "typesx.h" #include "nodesx.h" #include "segmentsx.h" #include "waysx.h" #include "superx.h" #include "files.h" #include "logging.h" #include "results.h" /* Local functions */ static Results *FindSuperRoutes(NodesX *nodesx,SegmentsX *segmentsx,WaysX *waysx,node_t start,Way *match); /*++++++++++++++++++++++++++++++++++++++ Select the super-nodes from the list of nodes. NodesX *nodesx The set of nodes to use. SegmentsX *segmentsx The set of segments to use. WaysX *waysx The set of ways to use. ++++++++++++++++++++++++++++++++++++++*/ void ChooseSuperNodes(NodesX *nodesx,SegmentsX *segmentsx,WaysX *waysx) { index_t i; index_t nnodes=0; if(nodesx->number==0 || segmentsx->number==0 || waysx->number==0) return; /* Print the start message */ printf_first("Finding Super-Nodes: Nodes=0 Super-Nodes=0"); /* Allocate and set the super-node markers */ if(!nodesx->super) { nodesx->super=AllocBitMask(nodesx->number); log_malloc(nodesx->super,LengthBitMask(nodesx->number)*sizeof(BitMask)); logassert(nodesx->super,"Failed to allocate memory (try using slim mode?)"); /* Check AllocBitMask() worked */ SetAllBits(nodesx->super,nodesx->number); } /* Map into memory / open the files */ nodesx->fd=ReOpenFileBuffered(nodesx->filename_tmp); #if !SLIM segmentsx->data=MapFile(segmentsx->filename_tmp); waysx->data=MapFile(waysx->filename_tmp); #else segmentsx->fd=SlimMapFile(segmentsx->filename_tmp); waysx->fd=SlimMapFile(waysx->filename_tmp); InvalidateSegmentXCache(segmentsx->cache); InvalidateWayXCache(waysx->cache); #endif /* Find super-nodes */ for(i=0;inumber;i++) { NodeX nodex; ReadFileBuffered(nodesx->fd,&nodex,sizeof(NodeX)); if(IsBitSet(nodesx->super,i)) { int issuper=0; if(nodex.flags&(NODE_TURNRSTRCT|NODE_TURNRSTRCT2)) issuper=1; else { int count=0,j; Way segmentway[MAX_SEG_PER_NODE]; int segmentweight[MAX_SEG_PER_NODE]; SegmentX *segmentx=FirstSegmentX(segmentsx,i,1); while(segmentx) { WayX *wayx=LookupWayX(waysx,segmentx->way,1); int nsegments; /* Segments that are loops count twice */ logassert(countnode1==segmentx->node2) segmentweight[count]=2; else segmentweight[count]=1; segmentway[count]=wayx->way; /* If the node allows less traffic types than any connecting way then it is super if it allows anything */ if((wayx->way.allow&nodex.allow)!=wayx->way.allow && nodex.allow!=Transports_None) { issuper=1; break; } nsegments=segmentweight[count]; for(j=0;jway.allow & segmentway[j].allow) { /* If two ways are different in any attribute and there is a type of traffic that can use both then it is super */ if(WaysCompare(&segmentway[j],&wayx->way)) { issuper=1; break; } /* If there are two other segments that can be used by the same types of traffic as this one then it is super */ nsegments+=segmentweight[j]; if(nsegments>2) { issuper=1; break; } } if(issuper) break; segmentx=NextSegmentX(segmentsx,segmentx,i); count++; } } /* Mark the node as super if it is. */ if(issuper) nnodes++; else ClearBit(nodesx->super,i); } if(!((i+1)%10000)) printf_middle("Finding Super-Nodes: Nodes=%"Pindex_t" Super-Nodes=%"Pindex_t,i+1,nnodes); } /* Unmap from memory / close the files */ #if !SLIM segmentsx->data=UnmapFile(segmentsx->data); waysx->data=UnmapFile(waysx->data); #else segmentsx->fd=SlimUnmapFile(segmentsx->fd); waysx->fd=SlimUnmapFile(waysx->fd); #endif nodesx->fd=CloseFileBuffered(nodesx->fd); /* Print the final message */ printf_last("Found Super-Nodes: Nodes=%"Pindex_t" Super-Nodes=%"Pindex_t,nodesx->number,nnodes); } /*++++++++++++++++++++++++++++++++++++++ Create the super-segments from the existing segments. SegmentsX *CreateSuperSegments Returns the new super segments. NodesX *nodesx The set of nodes to use. SegmentsX *segmentsx The set of segments to use. WaysX *waysx The set of ways to use. ++++++++++++++++++++++++++++++++++++++*/ SegmentsX *CreateSuperSegments(NodesX *nodesx,SegmentsX *segmentsx,WaysX *waysx) { index_t i; SegmentsX *supersegmentsx; index_t sn=0,ss=0; supersegmentsx=NewSegmentList(); if(segmentsx->number==0 || waysx->number==0) { FinishSegmentList(supersegmentsx); return(supersegmentsx); } /* Print the start message */ printf_first("Creating Super-Segments: Super-Nodes=0 Super-Segments=0"); /* Map into memory / open the files */ #if !SLIM nodesx->data=MapFile(nodesx->filename_tmp); segmentsx->data=MapFile(segmentsx->filename_tmp); waysx->data=MapFile(waysx->filename_tmp); #else nodesx->fd=SlimMapFile(nodesx->filename_tmp); segmentsx->fd=SlimMapFile(segmentsx->filename_tmp); waysx->fd=SlimMapFile(waysx->filename_tmp); InvalidateNodeXCache(nodesx->cache); InvalidateSegmentXCache(segmentsx->cache); InvalidateWayXCache(waysx->cache); #endif /* Create super-segments for each super-node. */ for(i=0;inumber;i++) { if(IsBitSet(nodesx->super,i)) { SegmentX *segmentx; int count=0,match; Way prevway[MAX_SEG_PER_NODE]; segmentx=FirstSegmentX(segmentsx,i,1); while(segmentx) { WayX *wayx=LookupWayX(waysx,segmentx->way,1); /* Check that this type of way hasn't already been routed */ match=0; if(count>0) { int j; for(j=0;jway)) { match=1; break; } } logassert(countway; /* Route the way and store the super-segments. */ if(!match) { Results *results=FindSuperRoutes(nodesx,segmentsx,waysx,i,&wayx->way); Result *result=FirstResult(results); while(result) { if(IsBitSet(nodesx->super,result->node) && result->segment!=NO_SEGMENT) { if(wayx->way.type&Highway_OneWay && result->node!=i) AppendSegmentList(supersegmentsx,segmentx->way,i,result->node,DISTANCE((distance_t)result->score)|ONEWAY_1TO2); else AppendSegmentList(supersegmentsx,segmentx->way,i,result->node,DISTANCE((distance_t)result->score)); ss++; } result=NextResult(results,result); } } segmentx=NextSegmentX(segmentsx,segmentx,i); } sn++; if(!(sn%10000)) printf_middle("Creating Super-Segments: Super-Nodes=%"Pindex_t" Super-Segments=%"Pindex_t,sn,ss); } } FinishSegmentList(supersegmentsx); /* Unmap from memory / close the files */ #if !SLIM nodesx->data=UnmapFile(nodesx->data); segmentsx->data=UnmapFile(segmentsx->data); waysx->data=UnmapFile(waysx->data); #else nodesx->fd=SlimUnmapFile(nodesx->fd); segmentsx->fd=SlimUnmapFile(segmentsx->fd); waysx->fd=SlimUnmapFile(waysx->fd); #endif /* Free the no-longer required memory */ if(segmentsx->firstnode) { log_free(segmentsx->firstnode); free(segmentsx->firstnode); segmentsx->firstnode=NULL; } /* Print the final message */ printf_last("Created Super-Segments: Super-Nodes=%"Pindex_t" Super-Segments=%"Pindex_t,sn,ss); return(supersegmentsx); } /*++++++++++++++++++++++++++++++++++++++ Merge the segments and super-segments into a new segment list. SegmentsX *MergeSuperSegments Returns a new set of merged segments. SegmentsX *segmentsx The set of segments to use. SegmentsX *supersegmentsx The set of super-segments to use. ++++++++++++++++++++++++++++++++++++++*/ SegmentsX *MergeSuperSegments(SegmentsX *segmentsx,SegmentsX *supersegmentsx) { index_t i,j,lastj; index_t merged=0,added=0; SegmentsX *mergedsegmentsx; SegmentX supersegmentx; mergedsegmentsx=NewSegmentList(); if(segmentsx->number==0) { FinishSegmentList(mergedsegmentsx); return(mergedsegmentsx); } /* Print the start message */ printf_first("Merging Segments: Segments=0 Super=0 Merged=0 Added=0"); /* Open the files */ segmentsx->fd=ReOpenFileBuffered(segmentsx->filename_tmp); if(supersegmentsx->number>0) supersegmentsx->fd=ReOpenFileBuffered(supersegmentsx->filename_tmp); /* Loop through and create a new list of combined segments */ lastj=-1; j=0; for(i=0;inumber;i++) { int super=0; SegmentX segmentx; ReadFileBuffered(segmentsx->fd,&segmentx,sizeof(SegmentX)); while(jnumber) { if(j!=lastj) { ReadFileBuffered(supersegmentsx->fd,&supersegmentx,sizeof(SegmentX)); lastj=j; } if(segmentx.node1 ==supersegmentx.node1 && segmentx.node2 ==supersegmentx.node2 && segmentx.distance==supersegmentx.distance) { merged++; j++; /* mark as super-segment and normal segment */ super=1; break; } else if((segmentx.node1==supersegmentx.node1 && segmentx.node2==supersegmentx.node2) || (segmentx.node1==supersegmentx.node1 && segmentx.node2>supersegmentx.node2) || (segmentx.node1>supersegmentx.node1)) { /* mark as super-segment */ AppendSegmentList(mergedsegmentsx,supersegmentx.way,supersegmentx.node1,supersegmentx.node2,supersegmentx.distance|SEGMENT_SUPER); added++; j++; } else { /* mark as normal segment */ break; } } if(super) AppendSegmentList(mergedsegmentsx,segmentx.way,segmentx.node1,segmentx.node2,segmentx.distance|SEGMENT_SUPER|SEGMENT_NORMAL); else AppendSegmentList(mergedsegmentsx,segmentx.way,segmentx.node1,segmentx.node2,segmentx.distance|SEGMENT_NORMAL); if(!((i+1)%10000)) printf_middle("Merging Segments: Segments=%"Pindex_t" Super=%"Pindex_t" Merged=%"Pindex_t" Added=%"Pindex_t,i+1,j,merged,added); } if(jnumber) { if(j==lastj) { AppendSegmentList(mergedsegmentsx,supersegmentx.way,supersegmentx.node1,supersegmentx.node2,supersegmentx.distance|SEGMENT_SUPER); j++; } while(jnumber) { ReadFileBuffered(supersegmentsx->fd,&supersegmentx,sizeof(SegmentX)); AppendSegmentList(mergedsegmentsx,supersegmentx.way,supersegmentx.node1,supersegmentx.node2,supersegmentx.distance|SEGMENT_SUPER); added++; j++; } } FinishSegmentList(mergedsegmentsx); /* Close the files */ segmentsx->fd=CloseFileBuffered(segmentsx->fd); if(supersegmentsx->number>0) supersegmentsx->fd=CloseFileBuffered(supersegmentsx->fd); /* Print the final message */ printf_last("Merged Segments: Segments=%"Pindex_t" Super=%"Pindex_t" Merged=%"Pindex_t" Added=%"Pindex_t,segmentsx->number,supersegmentsx->number,merged,added); return(mergedsegmentsx); } /*++++++++++++++++++++++++++++++++++++++ Find all routes from a specified super-node to any other super-node that follows a certain type of way. Results *FindSuperRoutes Returns a set of results. NodesX *nodesx The set of nodes to use. SegmentsX *segmentsx The set of segments to use. WaysX *waysx The set of ways to use. node_t start The start node. Way *match A template for the type of way that the route must follow. ++++++++++++++++++++++++++++++++++++++*/ static Results *FindSuperRoutes(NodesX *nodesx,SegmentsX *segmentsx,WaysX *waysx,node_t start,Way *match) { static Results *results=NULL; /* static allocation of return value (reset each call) */ static Queue *queue=NULL; /* static allocation of internal value (reset each call) */ Result *result1,*result2; WayX *wayx; /* Insert the first node into the queue */ if(!results) results=NewResultsList(8); else ResetResultsList(results); if(!queue) queue=NewQueueList(8); else ResetQueueList(queue); result1=InsertResult(results,start,NO_SEGMENT); InsertInQueue(queue,result1,0); /* Loop across all nodes in the queue */ while((result1=PopFromQueue(queue))) { index_t node1; SegmentX *segmentx; node1=result1->node; segmentx=FirstSegmentX(segmentsx,node1,2); /* position 1 is already used */ while(segmentx) { NodeX *node2x; index_t node2,seg2; distance_t cumulative_distance; /* must not be one-way against the direction of travel */ if(IsOnewayTo(segmentx,node1)) goto endloop; seg2=IndexSegmentX(segmentsx,segmentx); /* must not be a u-turn */ if(result1->segment==seg2) goto endloop; wayx=LookupWayX(waysx,segmentx->way,2); /* position 1 is already used */ /* must be the right type of way */ if(WaysCompare(&wayx->way,match)) goto endloop; node2=OtherNode(segmentx,node1); node2x=LookupNodeX(nodesx,node2,2); /* position 1 is already used */ /* Don't route beyond a node with no access */ if(node2x->allow==Transports_None) goto endloop; cumulative_distance=(distance_t)result1->score+DISTANCE(segmentx->distance); result2=FindResult(results,node2,seg2); if(!result2) /* New end node */ { result2=InsertResult(results,node2,seg2); result2->prev=result1; result2->score=cumulative_distance; /* don't route beyond a super-node. */ if(!IsBitSet(nodesx->super,node2)) InsertInQueue(queue,result2,cumulative_distance); } else if(cumulative_distancescore) { result2->prev=result1; result2->score=cumulative_distance; /* don't route beyond a super-node. */ if(!IsBitSet(nodesx->super,node2)) InsertInQueue(queue,result2,cumulative_distance); } endloop: segmentx=NextSegmentX(segmentsx,segmentx,node1); } } return(results); } routino-3.0/src/version.h 644 233 144 2037 12574076105 10661 0/*************************************** Routino version. Part of the Routino routing software. ******************/ /****************** This file Copyright 2015 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #ifndef VERSION_H #define VERSION_H /*+ To stop multiple inclusions. +*/ #define ROUTINO_VERSION "3.0" #define ROUTINO_URL "" #endif /* VERSION_H */ routino-3.0/src/visualiser.h 644 233 144 6117 12327765765 11402 0/*************************************** Header file for visualiser functions. Part of the Routino routing software. ******************/ /****************** This file Copyright 2008-2014 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #ifndef VISUALISER_H #define VISUALISER_H /*+ To stop multiple inclusions. +*/ #include "types.h" #include "errorlog.h" /* Functions in visualiser.c */ void OutputJunctions(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,double latmin,double latmax,double lonmin,double lonmax); void OutputSuper(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,double latmin,double latmax,double lonmin,double lonmax); void OutputWaytype(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,double latmin,double latmax,double lonmin,double lonmax,highway_t mask); void OutputHighway(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,double latmin,double latmax,double lonmin,double lonmax,Highway highway); void OutputTransport(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,double latmin,double latmax,double lonmin,double lonmax,Transport transport); void OutputBarrier(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,double latmin,double latmax,double lonmin,double lonmax,Transport transport); void OutputTurnRestrictions(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,double latmin,double latmax,double lonmin,double lonmax); void OutputSpeedLimits(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,double latmin,double latmax,double lonmin,double lonmax); void OutputWeightLimits(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,double latmin,double latmax,double lonmin,double lonmax); void OutputHeightLimits(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,double latmin,double latmax,double lonmin,double lonmax); void OutputWidthLimits(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,double latmin,double latmax,double lonmin,double lonmax); void OutputLengthLimits(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,double latmin,double latmax,double lonmin,double lonmax); void OutputProperty(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,double latmin,double latmax,double lonmin,double lonmax,Property property); void OutputErrorLog(ErrorLogs *errorlogs,double latmin,double latmax,double lonmin,double lonmax); #endif /* VISUALISER_H */ routino-3.0/src/relations.c 644 233 144 24050 12563633052 11204 0/*************************************** Relation data type functions. Part of the Routino routing software. ******************/ /****************** This file Copyright 2008-2015 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #include #include "types.h" #include "relations.h" #include "fakes.h" #include "files.h" /*++++++++++++++++++++++++++++++++++++++ Load in a relation list from a file. Relations *LoadRelationList Returns the relation list. const char *filename The name of the file to load. ++++++++++++++++++++++++++++++++++++++*/ Relations *LoadRelationList(const char *filename) { Relations *relations; relations=(Relations*)malloc(sizeof(Relations)); #if !SLIM relations->data=MapFile(filename); /* Copy the RelationsFile header structure from the loaded data */ relations->file=*((RelationsFile*)relations->data); /* Set the pointers in the Relations structure. */ relations->turnrelations=(TurnRelation*)(relations->data+sizeof(RelationsFile)); #else relations->fd=SlimMapFile(filename); /* Copy the RelationsFile header structure from the loaded data */ SlimFetch(relations->fd,&relations->file,sizeof(RelationsFile),0); relations->troffset=sizeof(RelationsFile); relations->cache=NewTurnRelationCache(); #ifndef LIBROUTINO log_malloc(relations->cache,sizeof(*relations->cache)); #endif #endif if(relations->file.trnumber>0) { TurnRelation *relation; relation=LookupTurnRelation(relations,0,1); relations->via_start =relation->via; relation=LookupTurnRelation(relations,relations->file.trnumber-1,1); relations->via_end =relation->via; } return(relations); } /*++++++++++++++++++++++++++++++++++++++ Destroy the relation list. Relations *relations The relation list to destroy. ++++++++++++++++++++++++++++++++++++++*/ void DestroyRelationList(Relations *relations) { #if !SLIM relations->data=UnmapFile(relations->data); #else relations->fd=SlimUnmapFile(relations->fd); #ifndef LIBROUTINO log_free(relations->cache); #endif DeleteTurnRelationCache(relations->cache); #endif free(relations); } /*++++++++++++++++++++++++++++++++++++++ Find the first turn relation in the file whose 'via' matches a specific node. index_t FindFirstTurnRelation1 Returns the index of the first turn relation matching. Relations *relations The set of relations to use. index_t via The node that the route is going via. ++++++++++++++++++++++++++++++++++++++*/ index_t FindFirstTurnRelation1(Relations *relations,index_t via) { TurnRelation *relation; index_t start=0; index_t end=relations->file.trnumber-1; index_t mid; index_t match=NO_RELATION; /* Binary search - search key any exact match is required. * * # <- start | Check mid and move start or end if it doesn't match * # | * # | Since an exact match is wanted we can set end=mid-1 * # <- mid | or start=mid+1 because we know that mid doesn't match. * # | * # | Eventually either end=start or end=start+1 and one of * # <- end | start or end matches (but may not be the first). */ do { mid=(start+end)/2; /* Choose mid point */ relation=LookupTurnRelation(relations,mid,1); if(relation->viavia>via) /* Mid point is too high for 'via' */ end=mid?(mid-1):mid; else /* Mid point is correct for 'from' */ { match=mid; break; } } while((end-start)>1); if(match==NO_RELATION) /* Check if start matches */ { relation=LookupTurnRelation(relations,start,1); if(relation->via==via) match=start; } if(match==NO_RELATION) /* Check if end matches */ { relation=LookupTurnRelation(relations,end,1); if(relation->via==via) match=end; } if(match==NO_RELATION) return(match); while(match>0) /* Search backwards for the first match */ { relation=LookupTurnRelation(relations,match-1,1); if(relation->via==via) match--; else break; } return(match); } /*++++++++++++++++++++++++++++++++++++++ Find the next turn relation in the file whose 'via' matches a specific node. index_t FindNextTurnRelation1 Returns the index of the next turn relation matching. Relations *relations The set of relations to use. index_t current The current index of a relation that matches. ++++++++++++++++++++++++++++++++++++++*/ index_t FindNextTurnRelation1(Relations *relations,index_t current) { TurnRelation *relation; index_t via; relation=LookupTurnRelation(relations,current,1); via=relation->via; current++; if(current==relations->file.trnumber) return(NO_RELATION); relation=LookupTurnRelation(relations,current,1); if(relation->via==via) return(current); else return(NO_RELATION); } /*++++++++++++++++++++++++++++++++++++++ Find the first turn relation in the file whose 'via' and 'from' match a specific node and segment. index_t FindFirstTurnRelation2 Returns the index of the first turn relation matching. Relations *relations The set of relations to use. index_t via The node that the route is going via. index_t from The segment that the route is coming from. ++++++++++++++++++++++++++++++++++++++*/ index_t FindFirstTurnRelation2(Relations *relations,index_t via,index_t from) { TurnRelation *relation; index_t start=0; index_t end=relations->file.trnumber-1; index_t mid; index_t match=NO_RELATION; if(IsFakeSegment(from)) from=IndexRealSegment(from); /* Binary search - search key first match is required. * * # <- start | Check mid and move start or end if it doesn't match * # | * # | Since an exact match is wanted we can set end=mid-1 * # <- mid | or start=mid+1 because we know that mid doesn't match. * # | * # | Eventually either end=start or end=start+1 and one of * # <- end | start or end matches (but may not be the first). */ do { mid=(start+end)/2; /* Choose mid point */ relation=LookupTurnRelation(relations,mid,1); if(relation->viavia>via) /* Mid point is too high for 'via' */ end=mid?(mid-1):mid; else /* Mid point is correct for 'via' */ { if(relation->fromfrom>from) /* Mid point is too high for 'from' */ end=mid?(mid-1):mid; else /* Mid point is correct for 'from' */ { match=mid; break; } } } while((end-start)>1); if(match==NO_RELATION) /* Check if start matches */ { relation=LookupTurnRelation(relations,start,1); if(relation->via==via && relation->from==from) match=start; } if(match==NO_RELATION) /* Check if end matches */ { relation=LookupTurnRelation(relations,end,1); if(relation->via==via && relation->from==from) match=end; } if(match==NO_RELATION) return(match); while(match>0) /* Search backwards for the first match */ { relation=LookupTurnRelation(relations,match-1,1); if(relation->via==via && relation->from==from) match--; else break; } return(match); } /*++++++++++++++++++++++++++++++++++++++ Find the next turn relation in the file whose 'via' and 'from' match a specific node and segment. index_t FindNextTurnRelation2 Returns the index of the next turn relation matching. Relations *relations The set of relations to use. index_t current The current index of a relation that matches. ++++++++++++++++++++++++++++++++++++++*/ index_t FindNextTurnRelation2(Relations *relations,index_t current) { TurnRelation *relation; index_t via,from; relation=LookupTurnRelation(relations,current,1); via=relation->via; from=relation->from; current++; if(current==relations->file.trnumber) return(NO_RELATION); relation=LookupTurnRelation(relations,current,1); if(relation->via==via && relation->from==from) return(current); else return(NO_RELATION); } /*++++++++++++++++++++++++++++++++++++++ Determine if a turn is allowed between the nodes 'from', 'via' and 'to' for a particular transport type. int IsTurnAllowed Return 1 if the turn is allowed or 0 if not. Relations *relations The set of relations to use. index_t index The index of the first turn relation containing 'via' and 'from'. index_t via The via node. index_t from The from segment. index_t to The to segment. transports_t transport The type of transport that is being routed. ++++++++++++++++++++++++++++++++++++++*/ int IsTurnAllowed(Relations *relations,index_t index,index_t via,index_t from,index_t to,transports_t transport) { if(IsFakeSegment(from)) from=IndexRealSegment(from); if(IsFakeSegment(to)) to=IndexRealSegment(to); while(indexfile.trnumber) { TurnRelation *relation=LookupTurnRelation(relations,index,1); if(relation->via!=via) return(1); if(relation->from!=from) return(1); if(relation->to>to) return(1); if(relation->to==to) if(!(relation->except & transport)) return(0); index++; } return(1); } routino-3.0/src/router.c 644 233 144 62233 12574073774 10544 0/*************************************** OSM router. Part of the Routino routing software. ******************/ /****************** This file Copyright 2008-2015 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #include #include #include #include #include "version.h" #include "types.h" #include "nodes.h" #include "segments.h" #include "ways.h" #include "relations.h" #include "files.h" #include "logging.h" #include "functions.h" #include "fakes.h" #include "translations.h" #include "profiles.h" /*+ The maximum distance from the specified point to search for a node or segment (in km). +*/ #define MAXSEARCH 1 /* Global variables */ /*+ The option not to print any progress information. +*/ int option_quiet=0; /*+ The option to calculate the quickest route insted of the shortest. +*/ extern int option_quickest; /*+ The options to select the format of the file output. +*/ extern int option_file_html,option_file_gpx_track,option_file_gpx_route,option_file_text,option_file_text_all,option_file_stdout; int option_file_none=0; /* Local functions */ static void print_usage(int detail,const char *argerr,const char *err); /*++++++++++++++++++++++++++++++++++++++ The main program for the router. ++++++++++++++++++++++++++++++++++++++*/ int main(int argc,char** argv) { Nodes *OSMNodes; Segments *OSMSegments; Ways *OSMWays; Relations *OSMRelations; Results *results[NWAYPOINTS+1]={NULL}; int point_used[NWAYPOINTS+1]={0}; double point_lon[NWAYPOINTS+1],point_lat[NWAYPOINTS+1]; double heading=-999; int help_profile=0,help_profile_xml=0,help_profile_json=0,help_profile_pl=0; char *dirname=NULL,*prefix=NULL; char *profiles=NULL,*profilename=NULL; char *translations=NULL,*language=NULL; int exactnodes=0,reverse=0,loop=0; Transport transport=Transport_None; Profile *profile=NULL; Translation *translation=NULL; index_t start_node,finish_node=NO_NODE,first_node=NO_NODE; index_t join_segment=NO_SEGMENT; int arg,nresults=0; waypoint_t start_waypoint,finish_waypoint=NO_WAYPOINT; waypoint_t first_waypoint=NWAYPOINTS,last_waypoint=1,inc_dec_waypoint,waypoint; printf_program_start(); /* Parse the command line arguments */ if(argc<2) print_usage(0,NULL,NULL); /* Get the non-routing, general program options */ for(arg=1;argtransport=transport; } /* Parse the other command line arguments */ for(arg=1;argNWAYPOINTS || point_used[point]&1) print_usage(0,argv[arg],NULL); point_lon[point]=degrees_to_radians(atof(p)); point_used[point]+=1; if(pointlast_waypoint) last_waypoint=point; } else if(!strncmp(argv[arg],"--lat",5) && isdigit(argv[arg][5])) { int point; char *p=&argv[arg][6]; while(isdigit(*p)) p++; if(*p++!='=') print_usage(0,argv[arg],NULL); point=atoi(&argv[arg][5]); if(point>NWAYPOINTS || point_used[point]&2) print_usage(0,argv[arg],NULL); point_lat[point]=degrees_to_radians(atof(p)); point_used[point]+=2; if(pointlast_waypoint) last_waypoint=point; } else if(!strncmp(argv[arg],"--heading=",10)) { double h=atof(&argv[arg][10]); if(h>=-360 && h<=360) { heading=h; if(heading<0) heading+=360; } } else if(!strncmp(argv[arg],"--transport=",12)) ; /* Done this already */ else if(!strncmp(argv[arg],"--highway-",10)) { Highway highway; char *equal=strchr(argv[arg],'='); char *string; double p; if(!equal) print_usage(0,argv[arg],NULL); string=strcpy((char*)malloc(strlen(argv[arg])),argv[arg]+10); string[equal-argv[arg]-10]=0; highway=HighwayType(string); if(highway==Highway_None) print_usage(0,argv[arg],NULL); p=atof(equal+1); if(p<0 || p>100) print_usage(0,argv[arg],NULL); profile->highway[highway]=(score_t)(p/100); free(string); } else if(!strncmp(argv[arg],"--speed-",8)) { Highway highway; char *equal=strchr(argv[arg],'='); char *string; double s; if(!equal) print_usage(0,argv[arg],NULL); string=strcpy((char*)malloc(strlen(argv[arg])),argv[arg]+8); string[equal-argv[arg]-8]=0; highway=HighwayType(string); if(highway==Highway_None) print_usage(0,argv[arg],NULL); s=atof(equal+1); if(s<0) print_usage(0,argv[arg],NULL); profile->speed[highway]=kph_to_speed(s); free(string); } else if(!strncmp(argv[arg],"--property-",11)) { Property property; char *equal=strchr(argv[arg],'='); char *string; double p; if(!equal) print_usage(0,argv[arg],NULL); string=strcpy((char*)malloc(strlen(argv[arg])),argv[arg]+11); string[equal-argv[arg]-11]=0; property=PropertyType(string); if(property==Property_None) print_usage(0,argv[arg],NULL); p=atof(equal+1); if(p<0 || p>100) print_usage(0,argv[arg],NULL); profile->props[property]=(score_t)(p/100); free(string); } else if(!strncmp(argv[arg],"--oneway=",9)) profile->oneway=!!atoi(&argv[arg][9]); else if(!strncmp(argv[arg],"--turns=",8)) profile->turns=!!atoi(&argv[arg][8]); else if(!strncmp(argv[arg],"--weight=",9)) profile->weight=tonnes_to_weight(atof(&argv[arg][9])); else if(!strncmp(argv[arg],"--height=",9)) profile->height=metres_to_height(atof(&argv[arg][9])); else if(!strncmp(argv[arg],"--width=",8)) profile->width=metres_to_width(atof(&argv[arg][8])); else if(!strncmp(argv[arg],"--length=",9)) profile->length=metres_to_length(atof(&argv[arg][9])); else print_usage(0,argv[arg],NULL); } /* Print one of the profiles if requested */ if(help_profile) { PrintProfile(profile); exit(EXIT_SUCCESS); } else if(help_profile_xml) { PrintProfilesXML(); exit(EXIT_SUCCESS); } else if(help_profile_json) { PrintProfilesJSON(); exit(EXIT_SUCCESS); } else if(help_profile_pl) { PrintProfilesPerl(); exit(EXIT_SUCCESS); } /* Check the waypoints are valid */ for(waypoint=1;waypoint<=NWAYPOINTS;waypoint++) if(point_used[waypoint]==1 || point_used[waypoint]==2) print_usage(0,NULL,"All waypoints must have latitude and longitude."); if(first_waypoint>=last_waypoint) print_usage(0,NULL,"At least two waypoints must be specified."); /* Load in the selected translation */ if(option_file_html || option_file_gpx_route || option_file_gpx_track || option_file_text || option_file_text_all) { if(translations) { if(!ExistsFile(translations)) { fprintf(stderr,"Error: The '--translations' option specifies a file that does not exist.\n"); exit(EXIT_FAILURE); } } else { translations=FileName(dirname,prefix,"translations.xml"); if(!ExistsFile(translations)) { free(translations); translations=FileName(ROUTINO_DATADIR,NULL,"translations.xml"); if(!ExistsFile(translations)) { fprintf(stderr,"Error: The '--translations' option was not used and the default 'translations.xml' does not exist.\n"); exit(EXIT_FAILURE); } } } if(ParseXMLTranslations(translations,language,0)) { fprintf(stderr,"Error: Cannot read the translations in the file '%s'.\n",translations); exit(EXIT_FAILURE); } if(language) { translation=GetTranslation(language); if(!translation) { fprintf(stderr,"Warning: Cannot find a translation called '%s' in '%s'.\n",language,translations); exit(EXIT_FAILURE); } } else { translation=GetTranslation(""); if(!translation) { fprintf(stderr,"Warning: No translations in '%s'.\n",translations); exit(EXIT_FAILURE); } } } /* Load in the data - Note: No error checking because Load*List() will call exit() in case of an error. */ if(!option_quiet) printf_first("Loading Files:"); OSMNodes=LoadNodeList(FileName(dirname,prefix,"nodes.mem")); OSMSegments=LoadSegmentList(FileName(dirname,prefix,"segments.mem")); OSMWays=LoadWayList(FileName(dirname,prefix,"ways.mem")); OSMRelations=LoadRelationList(FileName(dirname,prefix,"relations.mem")); if(!option_quiet) printf_last("Loaded Files: nodes, segments, ways & relations"); /* Check the profile compared to the types of ways available */ if(UpdateProfile(profile,OSMWays)) { fprintf(stderr,"Error: Profile is invalid or not compatible with database.\n"); exit(EXIT_FAILURE); } /* Check for reverse direction */ if(reverse) { waypoint_t temp; temp=first_waypoint; first_waypoint=last_waypoint; last_waypoint=temp; last_waypoint--; inc_dec_waypoint=-1; } else { last_waypoint++; inc_dec_waypoint=1; } /* Loop through all pairs of waypoints */ for(waypoint=first_waypoint;waypoint!=last_waypoint;waypoint+=inc_dec_waypoint) { distance_t distmax=km_to_distance(MAXSEARCH); distance_t distmin; index_t segment=NO_SEGMENT; index_t node1,node2; if(point_used[waypoint]!=3) continue; if(!option_quiet) printf_first("Finding Closest Point: Waypoint %d",waypoint); /* Find the closest point */ start_node=finish_node; start_waypoint=finish_waypoint; if(exactnodes) { finish_node=FindClosestNode(OSMNodes,OSMSegments,OSMWays,point_lat[waypoint],point_lon[waypoint],distmax,profile,&distmin); } else { distance_t dist1,dist2; segment=FindClosestSegment(OSMNodes,OSMSegments,OSMWays,point_lat[waypoint],point_lon[waypoint],distmax,profile,&distmin,&node1,&node2,&dist1,&dist2); if(segment!=NO_SEGMENT) finish_node=CreateFakes(OSMNodes,OSMSegments,waypoint,LookupSegment(OSMSegments,segment,1),node1,node2,dist1,dist2); else finish_node=NO_NODE; } if(!option_quiet) printf_last("Found Closest Point: Waypoint %d",waypoint); if(finish_node==NO_NODE) { fprintf(stderr,"Error: Cannot find node close to specified point %d.\n",waypoint); exit(EXIT_FAILURE); } finish_waypoint=waypoint; if(!option_quiet) { double lat,lon; if(IsFakeNode(finish_node)) GetFakeLatLong(finish_node,&lat,&lon); else GetLatLong(OSMNodes,finish_node,NULL,&lat,&lon); if(IsFakeNode(finish_node)) printf("Waypoint %d is segment %"Pindex_t" (node %"Pindex_t" -> %"Pindex_t"): %3.6f %4.6f = %2.3f km\n",waypoint,segment,node1,node2, radians_to_degrees(lon),radians_to_degrees(lat),distance_to_km(distmin)); else printf("Waypoint %d is node %"Pindex_t": %3.6f %4.6f = %2.3f km\n",waypoint,finish_node, radians_to_degrees(lon),radians_to_degrees(lat),distance_to_km(distmin)); } /* Check the nodes */ if(start_node==NO_NODE) continue; if(first_node==NO_NODE) first_node=start_node; if(heading!=-999 && join_segment==NO_SEGMENT) join_segment=FindClosestSegmentHeading(OSMNodes,OSMSegments,OSMWays,start_node,heading,profile); /* Calculate the route */ results[nresults]=CalculateRoute(OSMNodes,OSMSegments,OSMWays,OSMRelations,profile,start_node,join_segment,finish_node,start_waypoint,finish_waypoint); if(!results[nresults]) exit(EXIT_FAILURE); join_segment=results[nresults]->last_segment; nresults++; } /* Finish the loop */ if(loop && finish_node!=NO_NODE) { results[nresults]=CalculateRoute(OSMNodes,OSMSegments,OSMWays,OSMRelations,profile,finish_node,join_segment,first_node,last_waypoint,first_waypoint); nresults++; } if(!option_quiet) { printf("Routed OK\n"); fflush(stdout); } /* Print out the combined route */ if(!option_quiet) printf_first("Generating Result Outputs"); if(!option_file_none) PrintRoute(results,nresults,OSMNodes,OSMSegments,OSMWays,profile,translation); if(!option_quiet) printf_last("Generated Result Outputs"); /* Destroy the remaining results lists and data structures */ #ifdef DEBUG_MEMORY_LEAK for(waypoint=0;waypoint=0) { fprintf(stderr, "Usage: router [--version]\n" " [--help | --help-profile | --help-profile-xml |\n" " --help-profile-json | --help-profile-perl ]\n" " [--dir=] [--prefix=]\n" " [--profiles=] [--translations=]\n" " [--exact-nodes-only]\n" " [--quiet | [--loggable] [--logtime] [--logmemory]]\n" " [--language=]\n" " [--output-html]\n" " [--output-gpx-track] [--output-gpx-route]\n" " [--output-text] [--output-text-all]\n" " [--output-none] [--output-stdout]\n" " [--profile=]\n" " [--transport=]\n" " [--shortest | --quickest]\n" " --lon1= --lat1=\n" " --lon2= --lon2=\n" " [ ... --lon99= --lon99=]\n" " [--reverse] [--loop]\n" " [--highway-= ...]\n" " [--speed-= ...]\n" " [--property-= ...]\n" " [--oneway=(0|1)] [--turns=(0|1)]\n" " [--weight=]\n" " [--height=] [--width=] [--length=]\n"); if(argerr) fprintf(stderr, "\n" "Error with command line parameter: %s\n",argerr); if(err) fprintf(stderr, "\n" "Error: %s\n",err); } if(detail==1) fprintf(stderr, "\n" "--version Print the version of Routino.\n" "\n" "--help Prints this information.\n" "--help-profile Prints the information about the selected profile.\n" "--help-profile-xml Prints all loaded profiles in XML format.\n" "--help-profile-json Prints all loaded profiles in JSON format.\n" "--help-profile-perl Prints all loaded profiles in Perl format.\n" "\n" "--dir= The directory containing the routing database.\n" "--prefix= The filename prefix for the routing database.\n" "--profiles= The name of the XML file containing the profiles\n" " (defaults to 'profiles.xml' with '--dir' and\n" " '--prefix' options or the file installed in\n" " '" ROUTINO_DATADIR "').\n" "--translations= The name of the XML file containing the translations\n" " (defaults to 'translations.xml' with '--dir' and\n" " '--prefix' options or the file installed in\n" " '" ROUTINO_DATADIR "').\n" "\n" "--exact-nodes-only Only route between nodes (don't find closest segment).\n" "\n" "--quiet Don't print any screen output when running.\n" "--loggable Print progress messages suitable for logging to file.\n" "--logtime Print the elapsed time for each processing step.\n" "--logmemory Print the max allocated/mapped memory for each step.\n" "\n" "--language= Use the translations for specified language.\n" "--output-html Write an HTML description of the route.\n" "--output-gpx-track Write a GPX track file with all route points.\n" "--output-gpx-route Write a GPX route file with interesting junctions.\n" "--output-text Write a plain text file with interesting junctions.\n" "--output-text-all Write a plain text file with all route points.\n" "--output-none Don't write any output files or read any translations.\n" " (If no output option is given then all are written.)\n" "--output-stdout Write to stdout instead of a file (requires exactly\n" " one output format option, implies '--quiet').\n" "\n" "--profile= Select the loaded profile with this name.\n" "--transport= Select the transport to use (selects the profile\n" " named after the transport if '--profile' is not used.)\n" "\n" "--shortest Find the shortest route between the waypoints.\n" "--quickest Find the quickest route between the waypoints.\n" "\n" "--lon= Specify the longitude of the n'th waypoint.\n" "--lat= Specify the latitude of the n'th waypoint.\n" "\n" "--reverse Find a route between the waypoints in reverse order.\n" "--loop Find a route that returns to the first waypoint.\n" "\n" "--heading= Initial compass bearing at lowest numbered waypoint.\n" "\n" " Routing preference options\n" "--highway-= * preference for highway type (%%).\n" "--speed-= * speed for highway type (km/h).\n" "--property-= * preference for proprty type (%%).\n" "--oneway=(0|1) * oneway restrictions are to be obeyed.\n" "--turns=(0|1) * turn restrictions are to be obeyed.\n" "--weight= * maximum weight limit (tonnes).\n" "--height= * maximum height limit (metres).\n" "--width= * maximum width limit (metres).\n" "--length= * maximum length limit (metres).\n" "\n" " defaults to motorcar but can be set to:\n" "%s" "\n" " can be selected from:\n" "%s" "\n" " can be selected from:\n" "%s", TransportList(),HighwayList(),PropertyList()); exit(!detail); } routino-3.0/src/waysx.h 644 233 144 12100 12550223461 10350 0/*************************************** A header file for the extended Ways structure. Part of the Routino routing software. ******************/ /****************** This file Copyright 2008-2015 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #ifndef WAYSX_H #define WAYSX_H /*+ To stop multiple inclusions. +*/ #include #include "types.h" #include "ways.h" #include "typesx.h" #include "cache.h" #include "files.h" /* Data structures */ /*+ An extended structure containing a single way. +*/ struct _WayX { way_t id; /*+ The way identifier; initially the OSM value, later the Way index. +*/ Way way; /*+ The real way data. +*/ }; /*+ A structure containing a set of ways (memory format). +*/ struct _WaysX { char *filename; /*+ The name of the intermediate file (for the WaysX). +*/ char *filename_tmp; /*+ The name of the temporary file (for the WaysX). +*/ int fd; /*+ The file descriptor of the open file (for the WaysX). +*/ index_t number; /*+ The number of extended ways still being considered. +*/ index_t knumber; /*+ The number of extended ways kept for next time. +*/ transports_t allow; /*+ The types of traffic that were seen when parsing. +*/ #if !SLIM WayX *data; /*+ The extended ways data (when mapped into memory). +*/ #else WayX cached[3]; /*+ Three cached extended ways read from the file in slim mode. +*/ index_t incache[3]; /*+ The indexes of the cached extended ways. +*/ WayXCache *cache; /*+ A RAM cache of extended ways read from the file. +*/ #endif way_t *idata; /*+ The extended way IDs (sorted by ID). +*/ offset_t *odata; /*+ The offset of the way in the file (used for error log). +*/ index_t *cdata; /*+ The compacted way IDs (same order as sorted ways). +*/ char *nfilename_tmp; /*+ The name of the temporary file (for the WaysX names). +*/ int nfd; /*+ The file descriptor of the temporary file (for the WaysX names). +*/ uint32_t nlength; /*+ The length of the string of name entries. +*/ }; /* Functions in waysx.c */ WaysX *NewWayList(int append,int readonly); void FreeWayList(WaysX *waysx,int keep); void AppendWayList(WaysX *waysx,way_t id,Way *way,node_t *nodes,int nnodes,const char *name); void FinishWayList(WaysX *waysx); index_t IndexWayX(WaysX *waysx,way_t id); void SortWayList(WaysX *waysx); SegmentsX *SplitWays(WaysX *waysx,NodesX *nodesx,int keep); void SortWayNames(WaysX *waysx); void CompactWayList(WaysX *waysx,SegmentsX *segmentsx); void SaveWayList(WaysX *waysx,const char *filename); /* Macros / inline functions */ #if !SLIM #define LookupWayX(waysx,index,position) &(waysx)->data[index] #define PutBackWayX(waysx,wayx) while(0) { /* nop */ } #else /* Prototypes */ static inline WayX *LookupWayX(WaysX *waysx,index_t index,int position); static inline void PutBackWayX(WaysX *waysx,WayX *wayx); CACHE_NEWCACHE_PROTO(WayX) CACHE_DELETECACHE_PROTO(WayX) CACHE_FETCHCACHE_PROTO(WayX) CACHE_REPLACECACHE_PROTO(WayX) CACHE_INVALIDATECACHE_PROTO(WayX) /* Data type */ CACHE_STRUCTURE(WayX) /* Inline functions */ CACHE_NEWCACHE(WayX) CACHE_DELETECACHE(WayX) CACHE_FETCHCACHE(WayX) CACHE_REPLACECACHE(WayX) CACHE_INVALIDATECACHE(WayX) /*++++++++++++++++++++++++++++++++++++++ Lookup a particular extended way with the specified id from the file on disk. WayX *LookupWayX Returns a pointer to a cached copy of the extended way. WaysX *waysx The set of ways to use. index_t index The way index to look for. int position The position in the cache to use. ++++++++++++++++++++++++++++++++++++++*/ static inline WayX *LookupWayX(WaysX *waysx,index_t index,int position) { waysx->cached[position-1]=*FetchCachedWayX(waysx->cache,index,waysx->fd,0); waysx->incache[position-1]=index; return(&waysx->cached[position-1]); } /*++++++++++++++++++++++++++++++++++++++ Put back an extended way's data into the file on disk. WaysX *waysx The set of ways to use. WayX *wayx The extended way to be put back. ++++++++++++++++++++++++++++++++++++++*/ static inline void PutBackWayX(WaysX *waysx,WayX *wayx) { int position1=wayx-&waysx->cached[0]; ReplaceCachedWayX(waysx->cache,wayx,waysx->incache[position1],waysx->fd,0); } #endif /* SLIM */ #endif /* WAYSX_H */ routino-3.0/src/router+lib.c 644 233 144 44515 12574073644 11305 0/*************************************** OSM router using libroutino library. Part of the Routino routing software. ******************/ /****************** This file Copyright 2008-2015 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #include #include #include #include #include #include #include "version.h" #include "routino.h" #ifndef M_PI #define M_PI 3.14159265358979323846 #endif /*+ The maximum number of waypoints +*/ #define NWAYPOINTS 99 /* Local functions */ static char *FileName(const char *dirname,const char *prefix, const char *name); static void print_usage(int detail,const char *argerr,const char *err); /*++++++++++++++++++++++++++++++++++++++ The main program for the router. ++++++++++++++++++++++++++++++++++++++*/ int main(int argc,char** argv) { Routino_Database *database; Routino_Profile *profile; Routino_Translation *translation; Routino_Waypoint **waypoints; Routino_Output *route; int point_used[NWAYPOINTS+1]={0}; double point_lon[NWAYPOINTS+1],point_lat[NWAYPOINTS+1]; char *dirname=NULL,*prefix=NULL; char *profiles=NULL,*profilename="motorcar"; char *translations=NULL,*language="en"; int reverse=0,loop=0; int quickest=0; int html=0,gpx_track=0,gpx_route=0,text=0,text_all=0,none=0,use_stdout=0; int list_html=0,list_html_all=0,list_text=0,list_text_all=0; int arg; int first_waypoint=NWAYPOINTS,last_waypoint=1,inc_dec_waypoint,waypoint,nwaypoints=0; int routing_options; /* Check the libroutino API version */ if(Routino_CheckAPIVersion()!=ROUTINO_ERROR_NONE) { fprintf(stderr,"Error: Executable version (%d) and library version (%d) do not match.\n",ROUTINO_API_VERSION,Routino_APIVersion); exit(EXIT_FAILURE); } /* Parse the command line arguments */ if(argc<2) print_usage(0,NULL,NULL); /* Get the non-routing, general program options */ for(arg=1;argNWAYPOINTS || point_used[point]&1) print_usage(0,argv[arg],NULL); point_lon[point]=atof(p); point_used[point]+=1; if(pointlast_waypoint) last_waypoint=point; } else if(!strncmp(argv[arg],"--lat",5) && isdigit(argv[arg][5])) { int point; char *p=&argv[arg][6]; while(isdigit(*p)) p++; if(*p++!='=') print_usage(0,argv[arg],NULL); point=atoi(&argv[arg][5]); if(point>NWAYPOINTS || point_used[point]&2) print_usage(0,argv[arg],NULL); point_lat[point]=atof(p); point_used[point]+=2; if(pointlast_waypoint) last_waypoint=point; } else print_usage(0,argv[arg],NULL); argv[arg]=NULL; } /* Check the specified command line options */ if(use_stdout && (html+gpx_track+gpx_route+text+text_all)!=1) { fprintf(stderr,"Error: The '--output-stdout' option requires exactly one other output option (but not '--output-none').\n"); exit(EXIT_FAILURE); } if(html==0 && gpx_track==0 && gpx_route==0 && text==0 && text_all==0 && none==0) html=gpx_track=gpx_route=text=text_all=1; /* Load in the selected profiles */ if(profiles) { if(access(profiles,F_OK)) { fprintf(stderr,"Error: The '--profiles' option specifies a file that does not exist.\n"); exit(EXIT_FAILURE); } } else { profiles=FileName(dirname,prefix,"profiles.xml"); if(access(profiles,F_OK)) { free(profiles); profiles=FileName(ROUTINO_DATADIR,NULL,"profiles.xml"); if(access(profiles,F_OK)) { fprintf(stderr,"Error: The '--profiles' option was not used and the default 'profiles.xml' does not exist.\n"); exit(EXIT_FAILURE); } } } if(!profilename) { fprintf(stderr,"Error: A profile name must be specified.\n"); exit(EXIT_FAILURE); } if(Routino_ParseXMLProfiles(profiles)) { fprintf(stderr,"Error: Cannot read the profiles in the file '%s'.\n",profiles); exit(EXIT_FAILURE); } profile=Routino_GetProfile(profilename); if(!profile) { char **list=Routino_GetProfileNames(); fprintf(stderr,"Error: Cannot find a profile called '%s' in '%s'.\n",profilename,profiles); fprintf(stderr,"Profiles available are: %s",*list++); while(*list) fprintf(stderr,", %s",*list++); fprintf(stderr,"\n"); exit(EXIT_FAILURE); } /* Load in the selected translation */ if(translations) { if(access(translations,F_OK)) { fprintf(stderr,"Error: The '--translations' option specifies a file that does not exist.\n"); exit(EXIT_FAILURE); } } else { translations=FileName(dirname,prefix,"translations.xml"); if(access(translations,F_OK)) { free(translations); translations=FileName(ROUTINO_DATADIR,NULL,"translations.xml"); if(access(translations,F_OK)) { fprintf(stderr,"Error: The '--translations' option was not used and the default 'translations.xml' does not exist.\n"); exit(EXIT_FAILURE); } } } if(Routino_ParseXMLTranslations(translations)) { fprintf(stderr,"Error: Cannot read the translations in the file '%s'.\n",translations); exit(EXIT_FAILURE); } if(language) { translation=Routino_GetTranslation(language); if(!translation) { char **list1=Routino_GetTranslationLanguages(); char **list2=Routino_GetTranslationLanguageFullNames(); fprintf(stderr,"Warning: Cannot find a translation called '%s' in '%s'.\n",language,translations); fprintf(stderr,"Languages available are: %s (%s)",*list1++,*list2++); while(*list1) fprintf(stderr,", %s (%s)",*list1++,*list2++); fprintf(stderr,"\n"); exit(EXIT_FAILURE); } } else { translation=Routino_GetTranslation(""); /* first in file */ if(!translation) { fprintf(stderr,"Warning: No translations in '%s'.\n",translations); exit(EXIT_FAILURE); } } /* Check the waypoints are valid */ for(waypoint=first_waypoint;waypoint<=last_waypoint;waypoint++) if(point_used[waypoint]==1 || point_used[waypoint]==2) print_usage(0,NULL,"All waypoints must have latitude and longitude."); else if(point_used[waypoint]==3) nwaypoints++; if(first_waypoint>=last_waypoint) { fprintf(stderr,"Error: At least two waypoints must be specified.\n"); exit(EXIT_FAILURE); } waypoints=calloc(sizeof(Routino_Waypoint*),nwaypoints+2); /* Load in the routing database */ database=Routino_LoadDatabase(dirname,prefix); /* Check the profile is valid for use with this database */ Routino_ValidateProfile(database,profile); /* Check for reverse direction */ if(reverse) { int temp; temp=first_waypoint; first_waypoint=last_waypoint; last_waypoint=temp; last_waypoint--; inc_dec_waypoint=-1; } else { last_waypoint++; inc_dec_waypoint=1; } /* Loop through all waypoints */ nwaypoints=0; for(waypoint=first_waypoint;waypoint!=last_waypoint;waypoint+=inc_dec_waypoint) if(point_used[waypoint]==3) { waypoints[nwaypoints]=Routino_FindWaypoint(database,profile,point_lat[waypoint],point_lon[waypoint]); if(!waypoints[nwaypoints]) { fprintf(stderr,"Error: Cannot find node close to specified point %d.\n",waypoint); exit(EXIT_FAILURE); } nwaypoints++; } if(loop) waypoints[nwaypoints++]=waypoints[0]; /* Create the route */ routing_options=0; if(quickest) routing_options|=ROUTINO_ROUTE_QUICKEST; else routing_options|=ROUTINO_ROUTE_SHORTEST; if(html ) routing_options|=ROUTINO_ROUTE_FILE_HTML; if(gpx_track) routing_options|=ROUTINO_ROUTE_FILE_GPX_TRACK; if(gpx_route) routing_options|=ROUTINO_ROUTE_FILE_GPX_ROUTE; if(text ) routing_options|=ROUTINO_ROUTE_FILE_TEXT; if(text_all ) routing_options|=ROUTINO_ROUTE_FILE_TEXT_ALL; if(list_html) routing_options|=ROUTINO_ROUTE_LIST_HTML; if(list_html_all) routing_options|=ROUTINO_ROUTE_LIST_HTML_ALL; if(list_text) routing_options|=ROUTINO_ROUTE_LIST_TEXT; if(list_text_all) routing_options|=ROUTINO_ROUTE_LIST_TEXT_ALL; route=Routino_CalculateRoute(database,profile,translation,waypoints,nwaypoints,routing_options,NULL); if(Routino_errno>=ROUTINO_ERROR_NO_ROUTE_1) { fprintf(stderr,"Error: Cannot find a route between specified waypoints.\n"); exit(EXIT_FAILURE); } else if(Routino_errno!=ROUTINO_ERROR_NONE) { fprintf(stderr,"Error: Internal error (%d).\n",Routino_errno); exit(EXIT_FAILURE); } /* Print the list output */ if(list_html || list_html_all || list_text || list_text_all) { Routino_Output *list=route; int first=1,last; while(list) { last=list->next?0:1; printf("----------------\n"); printf("Lon,Lat: %.5f, %.5f\n",(180.0/M_PI)*list->lon,(180.0/M_PI)*list->lat); if(list_html || list_html_all || list_text || list_text_all) printf("Dist,Time: %.3f km, %.1f minutes\n",list->dist,list->time); if(list_text_all && !first) printf("Speed: %.0f km/hr\n",list->speed); printf("Point type: %d\n",list->type); if((list_html || list_html_all || list_text) && !first && !last) printf("Turn: %d degrees\n",list->turn); if(((list_html || list_html_all || list_text) && !last) || (list_text_all && !first)) printf("Bearing: %d degrees\n",list->bearing); if(((list_html || list_text) && !last) || (list_html_all && list->name) || (list_text_all && !first)) printf("Name: %s\n",list->name); if(list_html || (list_html_all && list->name)) { printf("Desc1: %s\n",list->desc1); printf("Desc2: %s\n",list->desc2); if(!last) printf("Desc3: %s\n",list->desc3); } list=list->next; first=0; } } /* Tidy up and exit */ Routino_DeleteRoute(route); Routino_UnloadDatabase(database); Routino_FreeXMLProfiles(); Routino_FreeXMLTranslations(); for(waypoint=0;waypoint=0) { fprintf(stderr, "Usage: router [--version]\n" " [--help ]\n" " [--dir=] [--prefix=]\n" " [--profiles=] [--translations=]\n" " [--language=]\n" " [--output-html]\n" " [--output-gpx-track] [--output-gpx-route]\n" " [--output-text] [--output-text-all]\n" " [--output-none] [--output-stdout]\n" " [--list-html | --list-html-all |\n" " --list-text | --list-text-all]\n" " [--profile=]\n" " [--shortest | --quickest]\n" " --lon1= --lat1=\n" " --lon2= --lon2=\n" " [ ... --lon99= --lon99=]\n" " [--reverse] [--loop]\n"); if(argerr) fprintf(stderr, "\n" "Error with command line parameter: %s\n",argerr); if(err) fprintf(stderr, "\n" "Error: %s\n",err); } if(detail==1) fprintf(stderr, "\n" "--version Print the version of Routino.\n" "\n" "--help Prints this information.\n" "\n" "--dir= The directory containing the routing database.\n" "--prefix= The filename prefix for the routing database.\n" "--profiles= The name of the XML file containing the profiles\n" " (defaults to 'profiles.xml' with '--dir' and\n" " '--prefix' options or the file installed in\n" " '" ROUTINO_DATADIR "').\n" "--translations= The name of the XML file containing the translations\n" " (defaults to 'translations.xml' with '--dir' and\n" " '--prefix' options or the file installed in\n" " '" ROUTINO_DATADIR "').\n" "\n" "--language= Use the translations for specified language.\n" "--output-html Write an HTML description of the route.\n" "--output-gpx-track Write a GPX track file with all route points.\n" "--output-gpx-route Write a GPX route file with interesting junctions.\n" "--output-text Write a plain text file with interesting junctions.\n" "--output-text-all Write a plain text file with all route points.\n" "--output-none Don't write any output files or read any translations.\n" " (If no output option is given then all are written.)\n" "--output-stdout Write to stdout instead of a file (requires exactly\n" " one output format option, implies '--quiet').\n" "\n" "--list-html Create an HTML list of the route.\n" "--list-html-all Create an HTML list of the route with all points.\n" "--list-text Create a plain text list with interesting junctions.\n" "--list-text-all Create a plain text list with all route points.\n" "\n" "--profile= Select the loaded profile with this name.\n" "\n" "--shortest Find the shortest route between the waypoints.\n" "--quickest Find the quickest route between the waypoints.\n" "\n" "--lon= Specify the longitude of the n'th waypoint.\n" "--lat= Specify the latitude of the n'th waypoint.\n" "\n" "--reverse Find a route between the waypoints in reverse order.\n" "--loop Find a route that returns to the first waypoint.\n" "\n"); exit(!detail); } routino-3.0/src/translations.c 644 233 144 161043 12572603324 11750 0/*************************************** Load the translations from a file and the functions for handling them. Part of the Routino routing software. ******************/ /****************** This file Copyright 2010-2015 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #include #include #include #include "files.h" #include "translations.h" #include "xmlparse.h" /* Default English translations - Must not require any UTF-8 encoding */ static Translation default_translation= { .lang = "--", .language = "English (built-in)", .raw_copyright_creator = {"Creator","Routino - http://www.routino.org/"}, .raw_copyright_source = {NULL,NULL}, .raw_copyright_license = {NULL,NULL}, .xml_copyright_creator = {"Creator","Routino - http://www.routino.org/"}, .xml_copyright_source = {NULL,NULL}, .xml_copyright_license = {NULL,NULL}, .xml_heading = {"South","South-West","West","North-West","North","North-East","East","South-East","South"}, .xml_turn = {"Very sharp left","Sharp left","Left","Slight left","Straight on","Slight right","Right","Sharp right","Very sharp right"}, .xml_ordinal = {"First","Second","Third","Fourth","Fifth","Sixth","Seventh","Eighth","Ninth","Tenth"}, .notxml_heading = {"South","South-West","West","North-West","North","North-East","East","South-East","South"}, .notxml_turn = {"Very sharp left","Sharp left","Left","Slight left","Straight on","Slight right","Right","Sharp right","Very sharp right"}, .notxml_ordinal = {"First","Second","Third","Fourth","Fifth","Sixth","Seventh","Eighth","Ninth","Tenth"}, .raw_highway = {"","motorway","trunk road","primary road","secondary road","tertiary road","unclassified road","residential road","service road","track","cycleway","path","steps","ferry"}, .xml_route_shortest = "Shortest", .xml_route_quickest = "Quickest", .html_waypoint = "Waypoint", /* span tag added when reading XML translations file */ .html_junction = "Junction", .html_roundabout = "Roundabout", .html_title = "%s Route", .html_start = "Start at %s, head %s\n", /* span tags added when reading XML translations file */ .html_node = "At %s, go %s heading %s\n", /* span tags added when reading XML translations file */ .html_rbnode = "Leave %s, take the %s exit heading %s\n", /* span tags added when reading XML translations file */ .html_segment = "Follow %s for %.3f km, %.1f min", /* span tags added when reading XML translations file */ .html_stop = "Stop at %s\n", .html_total = "Total %.1f km, %.0f minutes\n",/* span tags added when reading XML translations file */ .html_subtotal= "%.1f km, %.0f minutes\n",/* span tag added when reading XML translations file */ .nothtml_waypoint = "Waypoint", .nothtml_junction = "Junction", .nothtml_roundabout = "Roundabout", .nothtml_title = "%s Route", .nothtml_start = "Start at %s, head %s", .nothtml_node = "At %s, go %s heading %s", .nothtml_rbnode = "Leave %s, take the %s exit heading %s", .nothtml_segment = "Follow %s for %.3f km, %.1f min", .nothtml_stop = "Stop at %s", .nothtml_total = "Total %.1f km, %.0f minutes", .nothtml_subtotal= "%.1f km, %.0f minutes", .gpx_desc = "%s route between 'start' and 'finish' waypoints", .gpx_name = "%s route", .gpx_step = "%s on '%s' for %.3f km, %.1f min", .gpx_final = "Total Journey %.1f km, %.0f minutes", .gpx_start = "START", .gpx_inter = "INTER", .gpx_trip = "TRIP", .gpx_finish = "FINISH" }; /* Local variables (re-intialised by FreeXMLTranslations() function) */ /*+ The translations that have been loaded from file. +*/ static Translation **loaded_translations=NULL; /*+ The number of translations that have been loaded from file. +*/ static int nloaded_translations=0; /* Local variables (re-initialised for each file) */ /*+ Store all of the translations. +*/ static int store_all; /*+ The translation language that is to be stored. +*/ static const char *store_lang; /*+ This current language is to be stored. +*/ static int store; /*+ The chosen language has been stored. +*/ static int stored; /* The XML tag processing function prototypes */ //static int xmlDeclaration_function(const char *_tag_,int _type_,const char *version,const char *encoding); //static int RoutinoTranslationsType_function(const char *_tag_,int _type_); static int LanguageType_function(const char *_tag_,int _type_,const char *lang,const char *language); //static int CopyrightType_function(const char *_tag_,int _type_); static int TurnType_function(const char *_tag_,int _type_,const char *direction,const char *string); static int HeadingType_function(const char *_tag_,int _type_,const char *direction,const char *string); static int OrdinalType_function(const char *_tag_,int _type_,const char *number,const char *string); static int HighwayType_function(const char *_tag_,int _type_,const char *type,const char *string); static int RouteType_function(const char *_tag_,int _type_,const char *type,const char *string); //static int HTMLType_function(const char *_tag_,int _type_); //static int GPXType_function(const char *_tag_,int _type_); static int CopyrightCreatorType_function(const char *_tag_,int _type_,const char *string,const char *text); static int CopyrightSourceType_function(const char *_tag_,int _type_,const char *string,const char *text); static int CopyrightLicenseType_function(const char *_tag_,int _type_,const char *string,const char *text); static int HTMLWaypointType_function(const char *_tag_,int _type_,const char *type,const char *string); static int HTMLTitleType_function(const char *_tag_,int _type_,const char *text); static int HTMLStartType_function(const char *_tag_,int _type_,const char *text); static int HTMLNodeType_function(const char *_tag_,int _type_,const char *text); static int HTMLRBNodeType_function(const char *_tag_,int _type_,const char *text); static int HTMLSegmentType_function(const char *_tag_,int _type_,const char *text); static int HTMLStopType_function(const char *_tag_,int _type_,const char *text); static int HTMLTotalType_function(const char *_tag_,int _type_,const char *text); static int HTMLSubtotalType_function(const char *_tag_,int _type_,const char *text); static int GPXWaypointType_function(const char *_tag_,int _type_,const char *type,const char *string); static int GPXDescType_function(const char *_tag_,int _type_,const char *text); static int GPXNameType_function(const char *_tag_,int _type_,const char *text); static int GPXStepType_function(const char *_tag_,int _type_,const char *text); static int GPXFinalType_function(const char *_tag_,int _type_,const char *text); /* The XML tag definitions (forward declarations) */ static const xmltag xmlDeclaration_tag; static const xmltag RoutinoTranslationsType_tag; static const xmltag LanguageType_tag; static const xmltag CopyrightType_tag; static const xmltag TurnType_tag; static const xmltag HeadingType_tag; static const xmltag OrdinalType_tag; static const xmltag HighwayType_tag; static const xmltag RouteType_tag; static const xmltag HTMLType_tag; static const xmltag GPXType_tag; static const xmltag CopyrightCreatorType_tag; static const xmltag CopyrightSourceType_tag; static const xmltag CopyrightLicenseType_tag; static const xmltag HTMLWaypointType_tag; static const xmltag HTMLTitleType_tag; static const xmltag HTMLStartType_tag; static const xmltag HTMLNodeType_tag; static const xmltag HTMLRBNodeType_tag; static const xmltag HTMLSegmentType_tag; static const xmltag HTMLStopType_tag; static const xmltag HTMLTotalType_tag; static const xmltag HTMLSubtotalType_tag; static const xmltag GPXWaypointType_tag; static const xmltag GPXDescType_tag; static const xmltag GPXNameType_tag; static const xmltag GPXStepType_tag; static const xmltag GPXFinalType_tag; /* The XML tag definition values */ /*+ The complete set of tags at the top level. +*/ static const xmltag * const xml_toplevel_tags[]={&xmlDeclaration_tag,&RoutinoTranslationsType_tag,NULL}; /*+ The xmlDeclaration type tag. +*/ static const xmltag xmlDeclaration_tag= {"xml", 2, {"version","encoding"}, NULL, {NULL}}; /*+ The RoutinoTranslationsType type tag. +*/ static const xmltag RoutinoTranslationsType_tag= {"routino-translations", 0, {NULL}, NULL, {&LanguageType_tag,NULL}}; /*+ The LanguageType type tag. +*/ static const xmltag LanguageType_tag= {"language", 2, {"lang","language"}, LanguageType_function, {&CopyrightType_tag,&TurnType_tag,&HeadingType_tag,&OrdinalType_tag,&HighwayType_tag,&RouteType_tag,&HTMLType_tag,&GPXType_tag,NULL}}; /*+ The CopyrightType type tag. +*/ static const xmltag CopyrightType_tag= {"copyright", 0, {NULL}, NULL, {&CopyrightCreatorType_tag,&CopyrightSourceType_tag,&CopyrightLicenseType_tag,NULL}}; /*+ The TurnType type tag. +*/ static const xmltag TurnType_tag= {"turn", 2, {"direction","string"}, TurnType_function, {NULL}}; /*+ The HeadingType type tag. +*/ static const xmltag HeadingType_tag= {"heading", 2, {"direction","string"}, HeadingType_function, {NULL}}; /*+ The OrdinalType type tag. +*/ static const xmltag OrdinalType_tag= {"ordinal", 2, {"number","string"}, OrdinalType_function, {NULL}}; /*+ The HighwayType type tag. +*/ static const xmltag HighwayType_tag= {"highway", 2, {"type","string"}, HighwayType_function, {NULL}}; /*+ The RouteType type tag. +*/ static const xmltag RouteType_tag= {"route", 2, {"type","string"}, RouteType_function, {NULL}}; /*+ The HTMLType type tag. +*/ static const xmltag HTMLType_tag= {"output-html", 0, {NULL}, NULL, {&HTMLWaypointType_tag,&HTMLTitleType_tag,&HTMLStartType_tag,&HTMLNodeType_tag,&HTMLRBNodeType_tag,&HTMLSegmentType_tag,&HTMLStopType_tag,&HTMLTotalType_tag,&HTMLSubtotalType_tag,NULL}}; /*+ The GPXType type tag. +*/ static const xmltag GPXType_tag= {"output-gpx", 0, {NULL}, NULL, {&GPXWaypointType_tag,&GPXDescType_tag,&GPXNameType_tag,&GPXStepType_tag,&GPXFinalType_tag,NULL}}; /*+ The CopyrightCreatorType type tag. +*/ static const xmltag CopyrightCreatorType_tag= {"creator", 2, {"string","text"}, CopyrightCreatorType_function, {NULL}}; /*+ The CopyrightSourceType type tag. +*/ static const xmltag CopyrightSourceType_tag= {"source", 2, {"string","text"}, CopyrightSourceType_function, {NULL}}; /*+ The CopyrightLicenseType type tag. +*/ static const xmltag CopyrightLicenseType_tag= {"license", 2, {"string","text"}, CopyrightLicenseType_function, {NULL}}; /*+ The HTMLWaypointType type tag. +*/ static const xmltag HTMLWaypointType_tag= {"waypoint", 2, {"type","string"}, HTMLWaypointType_function, {NULL}}; /*+ The HTMLTitleType type tag. +*/ static const xmltag HTMLTitleType_tag= {"title", 1, {"text"}, HTMLTitleType_function, {NULL}}; /*+ The HTMLStartType type tag. +*/ static const xmltag HTMLStartType_tag= {"start", 1, {"text"}, HTMLStartType_function, {NULL}}; /*+ The HTMLNodeType type tag. +*/ static const xmltag HTMLNodeType_tag= {"node", 1, {"text"}, HTMLNodeType_function, {NULL}}; /*+ The HTMLRBNodeType type tag. +*/ static const xmltag HTMLRBNodeType_tag= {"rbnode", 1, {"text"}, HTMLRBNodeType_function, {NULL}}; /*+ The HTMLSegmentType type tag. +*/ static const xmltag HTMLSegmentType_tag= {"segment", 1, {"text"}, HTMLSegmentType_function, {NULL}}; /*+ The HTMLStopType type tag. +*/ static const xmltag HTMLStopType_tag= {"stop", 1, {"text"}, HTMLStopType_function, {NULL}}; /*+ The HTMLTotalType type tag. +*/ static const xmltag HTMLTotalType_tag= {"total", 1, {"text"}, HTMLTotalType_function, {NULL}}; /*+ The HTMLSubtotalType type tag. +*/ static const xmltag HTMLSubtotalType_tag= {"subtotal", 1, {"text"}, HTMLSubtotalType_function, {NULL}}; /*+ The GPXWaypointType type tag. +*/ static const xmltag GPXWaypointType_tag= {"waypoint", 2, {"type","string"}, GPXWaypointType_function, {NULL}}; /*+ The GPXDescType type tag. +*/ static const xmltag GPXDescType_tag= {"desc", 1, {"text"}, GPXDescType_function, {NULL}}; /*+ The GPXNameType type tag. +*/ static const xmltag GPXNameType_tag= {"name", 1, {"text"}, GPXNameType_function, {NULL}}; /*+ The GPXStepType type tag. +*/ static const xmltag GPXStepType_tag= {"step", 1, {"text"}, GPXStepType_function, {NULL}}; /*+ The GPXFinalType type tag. +*/ static const xmltag GPXFinalType_tag= {"final", 1, {"text"}, GPXFinalType_function, {NULL}}; /* The XML tag processing functions */ /*++++++++++++++++++++++++++++++++++++++ The function that is called when the XML declaration is seen int xmlDeclaration_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *version The contents of the 'version' attribute (or NULL if not defined). const char *encoding The contents of the 'encoding' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ //static int xmlDeclaration_function(const char *_tag_,int _type_,const char *version,const char *encoding) //{ // return(0); //} /*++++++++++++++++++++++++++++++++++++++ The function that is called when the RoutinoTranslationsType XSD type is seen int RoutinoTranslationsType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. ++++++++++++++++++++++++++++++++++++++*/ //static int RoutinoTranslationsType_function(const char *_tag_,int _type_) //{ // return(0); //} /*++++++++++++++++++++++++++++++++++++++ The function that is called when the LanguageType XSD type is seen int LanguageType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *lang The contents of the 'lang' attribute (or NULL if not defined). const char *language The contents of the 'language' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int LanguageType_function(const char *_tag_,int _type_,const char *lang,const char *language) { if(_type_&XMLPARSE_TAG_START) { XMLPARSE_ASSERT_STRING(_tag_,lang); XMLPARSE_ASSERT_STRING(_tag_,language); if(store_all) store=1; else if(!store_lang && !stored) store=1; else if(store_lang && !strcmp(store_lang,lang)) store=1; else store=0; if(store) { int i; for(i=0;ilang)) XMLPARSE_MESSAGE(_tag_,"translation name must be unique"); if((nloaded_translations%16)==0) loaded_translations=(Translation**)realloc((void*)loaded_translations,(nloaded_translations+16)*sizeof(Translation*)); nloaded_translations++; loaded_translations[nloaded_translations-1]=(Translation*)calloc(1,sizeof(Translation)); *loaded_translations[nloaded_translations-1]=default_translation; loaded_translations[nloaded_translations-1]->lang =strcpy(malloc(strlen(lang )+1),lang ); loaded_translations[nloaded_translations-1]->language=strcpy(malloc(strlen(language)+1),language); } } if(_type_&XMLPARSE_TAG_END && store) { store=0; stored=1; } return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the CopyrightType XSD type is seen int CopyrightType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. ++++++++++++++++++++++++++++++++++++++*/ //static int CopyrightType_function(const char *_tag_,int _type_) //{ // return(0); //} /*++++++++++++++++++++++++++++++++++++++ The function that is called when the TurnType XSD type is seen int TurnType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *direction The contents of the 'direction' attribute (or NULL if not defined). const char *string The contents of the 'string' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int TurnType_function(const char *_tag_,int _type_,const char *direction,const char *string) { if(_type_&XMLPARSE_TAG_START && store) { char *xmlstring; int d; XMLPARSE_ASSERT_INTEGER(_tag_,direction); d=atoi(direction); XMLPARSE_ASSERT_STRING(_tag_,string); d+=4; if(d<0 || d>8) XMLPARSE_INVALID(_tag_,direction); loaded_translations[nloaded_translations-1]->notxml_turn[d]=strcpy(malloc(strlen(string)+1),string); xmlstring=ParseXML_Encode_Safe_XML(string); loaded_translations[nloaded_translations-1]->xml_turn[d]=strcpy(malloc(strlen(xmlstring)+1),xmlstring); } return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the HeadingType XSD type is seen int HeadingType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *direction The contents of the 'direction' attribute (or NULL if not defined). const char *string The contents of the 'string' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int HeadingType_function(const char *_tag_,int _type_,const char *direction,const char *string) { if(_type_&XMLPARSE_TAG_START && store) { char *xmlstring; int d; XMLPARSE_ASSERT_INTEGER(_tag_,direction); d=atoi(direction); XMLPARSE_ASSERT_STRING(_tag_,string); d+=4; if(d<0 || d>8) XMLPARSE_INVALID(_tag_,direction); loaded_translations[nloaded_translations-1]->notxml_heading[d]=strcpy(malloc(strlen(string)+1),string); xmlstring=ParseXML_Encode_Safe_XML(string); loaded_translations[nloaded_translations-1]->xml_heading[d]=strcpy(malloc(strlen(xmlstring)+1),xmlstring); } return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the OrdinalType XSD type is seen int OrdinalType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *number The contents of the 'number' attribute (or NULL if not defined). const char *string The contents of the 'string' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int OrdinalType_function(const char *_tag_,int _type_,const char *number,const char *string) { if(_type_&XMLPARSE_TAG_START && store) { char *xmlstring; int n; XMLPARSE_ASSERT_INTEGER(_tag_,number); n=atoi(number); XMLPARSE_ASSERT_STRING(_tag_,string); if(n<1 || n>10) XMLPARSE_INVALID(_tag_,number); loaded_translations[nloaded_translations-1]->notxml_ordinal[n-1]=strcpy(malloc(strlen(string)+1),string); xmlstring=ParseXML_Encode_Safe_XML(string); loaded_translations[nloaded_translations-1]->xml_ordinal[n-1]=strcpy(malloc(strlen(xmlstring)+1),xmlstring); } return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the HighwayType XSD type is seen int HighwayType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *type The contents of the 'type' attribute (or NULL if not defined). const char *string The contents of the 'string' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int HighwayType_function(const char *_tag_,int _type_,const char *type,const char *string) { if(_type_&XMLPARSE_TAG_START && store) { Highway highway; XMLPARSE_ASSERT_STRING(_tag_,type); XMLPARSE_ASSERT_STRING(_tag_,string); highway=HighwayType(type); if(highway==Highway_None) XMLPARSE_INVALID(_tag_,type); loaded_translations[nloaded_translations-1]->raw_highway[highway]=strcpy(malloc(strlen(string)+1),string); } return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the RouteType XSD type is seen int RouteType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *type The contents of the 'type' attribute (or NULL if not defined). const char *string The contents of the 'string' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int RouteType_function(const char *_tag_,int _type_,const char *type,const char *string) { if(_type_&XMLPARSE_TAG_START && store) { char *xmlstring; XMLPARSE_ASSERT_STRING(_tag_,type); XMLPARSE_ASSERT_STRING(_tag_,string); xmlstring=ParseXML_Encode_Safe_XML(string); if(!strcmp(type,"shortest")) loaded_translations[nloaded_translations-1]->xml_route_shortest=strcpy(malloc(strlen(xmlstring)+1),xmlstring); else if(!strcmp(type,"quickest")) loaded_translations[nloaded_translations-1]->xml_route_quickest=strcpy(malloc(strlen(xmlstring)+1),xmlstring); else XMLPARSE_INVALID(_tag_,type); } return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the HTMLType XSD type is seen int HTMLType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. ++++++++++++++++++++++++++++++++++++++*/ //static int HTMLType_function(const char *_tag_,int _type_) //{ // return(0); //} /*++++++++++++++++++++++++++++++++++++++ The function that is called when the GPXType XSD type is seen int GPXType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. ++++++++++++++++++++++++++++++++++++++*/ //static int GPXType_function(const char *_tag_,int _type_) //{ // return(0); //} /*++++++++++++++++++++++++++++++++++++++ The function that is called when the CopyrightCreatorType XSD type is seen int CopyrightCreatorType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *string The contents of the 'string' attribute (or NULL if not defined). const char *text The contents of the 'text' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int CopyrightCreatorType_function(const char *_tag_,int _type_,const char *string,const char *text) { if(_type_&XMLPARSE_TAG_START && store) { char *xmlstring,*xmltext; XMLPARSE_ASSERT_STRING(_tag_,string); XMLPARSE_ASSERT_STRING(_tag_,text); loaded_translations[nloaded_translations-1]->raw_copyright_creator[0]=strcpy(malloc(strlen(string)+1),string); loaded_translations[nloaded_translations-1]->raw_copyright_creator[1]=strcpy(malloc(strlen(text)+1) ,text); xmlstring=ParseXML_Encode_Safe_XML(string); loaded_translations[nloaded_translations-1]->xml_copyright_creator[0]=strcpy(malloc(strlen(xmlstring)+1),xmlstring); xmltext=ParseXML_Encode_Safe_XML(text); loaded_translations[nloaded_translations-1]->xml_copyright_creator[1]=strcpy(malloc(strlen(xmltext)+1),xmltext); } return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the CopyrightSourceType XSD type is seen int CopyrightSourceType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *string The contents of the 'string' attribute (or NULL if not defined). const char *text The contents of the 'text' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int CopyrightSourceType_function(const char *_tag_,int _type_,const char *string,const char *text) { if(_type_&XMLPARSE_TAG_START && store) { char *xmlstring,*xmltext; XMLPARSE_ASSERT_STRING(_tag_,string); XMLPARSE_ASSERT_STRING(_tag_,text); loaded_translations[nloaded_translations-1]->raw_copyright_source[0]=strcpy(malloc(strlen(string)+1),string); loaded_translations[nloaded_translations-1]->raw_copyright_source[1]=strcpy(malloc(strlen(text)+1) ,text); xmlstring=ParseXML_Encode_Safe_XML(string); loaded_translations[nloaded_translations-1]->xml_copyright_source[0]=strcpy(malloc(strlen(xmlstring)+1),xmlstring); xmltext=ParseXML_Encode_Safe_XML(text); loaded_translations[nloaded_translations-1]->xml_copyright_source[1]=strcpy(malloc(strlen(xmltext)+1),xmltext); } return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the CopyrightLicenseType XSD type is seen int CopyrightLicenseType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *string The contents of the 'string' attribute (or NULL if not defined). const char *text The contents of the 'text' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int CopyrightLicenseType_function(const char *_tag_,int _type_,const char *string,const char *text) { if(_type_&XMLPARSE_TAG_START && store) { char *xmlstring,*xmltext; XMLPARSE_ASSERT_STRING(_tag_,string); XMLPARSE_ASSERT_STRING(_tag_,text); loaded_translations[nloaded_translations-1]->raw_copyright_license[0]=strcpy(malloc(strlen(string)+1),string); loaded_translations[nloaded_translations-1]->raw_copyright_license[1]=strcpy(malloc(strlen(text)+1) ,text); xmlstring=ParseXML_Encode_Safe_XML(string); loaded_translations[nloaded_translations-1]->xml_copyright_license[0]=strcpy(malloc(strlen(xmlstring)+1),xmlstring); xmltext=ParseXML_Encode_Safe_XML(text); loaded_translations[nloaded_translations-1]->xml_copyright_license[1]=strcpy(malloc(strlen(xmltext)+1),xmltext); } return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the HTMLWaypointType XSD type is seen int HTMLWaypointType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *type The contents of the 'type' attribute (or NULL if not defined). const char *string The contents of the 'string' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int HTMLWaypointType_function(const char *_tag_,int _type_,const char *type,const char *string) { if(_type_&XMLPARSE_TAG_START && store) { char *xmlstring; XMLPARSE_ASSERT_STRING(_tag_,type); XMLPARSE_ASSERT_STRING(_tag_,string); xmlstring=ParseXML_Encode_Safe_XML(string); if(!strcmp(type,"waypoint")) { loaded_translations[nloaded_translations-1]->nothtml_waypoint=strcpy(malloc(strlen(string)+1),string); loaded_translations[nloaded_translations-1]->html_waypoint=malloc(strlen(xmlstring)+1+sizeof("")+sizeof("")); sprintf(loaded_translations[nloaded_translations-1]->html_waypoint,"%s",xmlstring); } else if(!strcmp(type,"junction")) { loaded_translations[nloaded_translations-1]->nothtml_junction=strcpy(malloc(strlen(string)+1),string); loaded_translations[nloaded_translations-1]->html_junction=strcpy(malloc(strlen(xmlstring)+1),xmlstring); } else if(!strcmp(type,"roundabout")) { loaded_translations[nloaded_translations-1]->nothtml_roundabout=strcpy(malloc(strlen(string)+1),string); loaded_translations[nloaded_translations-1]->html_roundabout=strcpy(malloc(strlen(xmlstring)+1),xmlstring); } else XMLPARSE_INVALID(_tag_,type); } return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the HTMLTitleType XSD type is seen int HTMLTitleType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *text The contents of the 'text' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int HTMLTitleType_function(const char *_tag_,int _type_,const char *text) { if(_type_&XMLPARSE_TAG_START && store) { char *xmltext; XMLPARSE_ASSERT_STRING(_tag_,text); xmltext=ParseXML_Encode_Safe_XML(text); loaded_translations[nloaded_translations-1]->nothtml_title=strcpy(malloc(strlen(text)+1),text); loaded_translations[nloaded_translations-1]->html_title=strcpy(malloc(strlen(xmltext)+1),xmltext); } return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the HTMLStartType XSD type is seen int HTMLStartType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *text The contents of the 'text' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int HTMLStartType_function(const char *_tag_,int _type_,const char *text) { if(_type_&XMLPARSE_TAG_START && store) { char *xmltext; const char *p; char *q; XMLPARSE_ASSERT_STRING(_tag_,text); xmltext=ParseXML_Encode_Safe_XML(text); loaded_translations[nloaded_translations-1]->nothtml_start=strcpy(malloc(strlen(text)+1),text); loaded_translations[nloaded_translations-1]->html_start=malloc(sizeof("")+strlen(xmltext)+sizeof("")+sizeof("")+1+1); p=xmltext; q=loaded_translations[nloaded_translations-1]->html_start; strcpy(q,""); q+=sizeof("")-1; while(*p!='%') *q++=*p++; *q++=*p++; while(*p!='%') *q++=*p++; p+=2; strcpy(q,"%s"); q+=sizeof("%s")-1; strcpy(q,p); strcat(q,"\n"); } return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the HTMLNodeType XSD type is seen int HTMLNodeType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *text The contents of the 'text' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int HTMLNodeType_function(const char *_tag_,int _type_,const char *text) { if(_type_&XMLPARSE_TAG_START && store) { char *xmltext; const char *p; char *q; XMLPARSE_ASSERT_STRING(_tag_,text); xmltext=ParseXML_Encode_Safe_XML(text); loaded_translations[nloaded_translations-1]->nothtml_node=strcpy(malloc(strlen(text)+1),text); loaded_translations[nloaded_translations-1]->html_node=malloc(sizeof("")+strlen(xmltext)+2*sizeof("")+2*sizeof("")+1+1); p=xmltext; q=loaded_translations[nloaded_translations-1]->html_node; strcpy(q,""); q+=sizeof("")-1; while(*p!='%') *q++=*p++; *q++=*p++; while(*p!='%') *q++=*p++; p+=2; strcpy(q,"%s"); q+=sizeof("%s")-1; while(*p!='%') *q++=*p++; p+=2; strcpy(q,"%s"); q+=sizeof("%s")-1; strcpy(q,p); strcat(q,"\n"); } return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the HTMLRBNodeType XSD type is seen int HTMLRBNodeType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *text The contents of the 'text' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int HTMLRBNodeType_function(const char *_tag_,int _type_,const char *text) { if(_type_&XMLPARSE_TAG_START && store) { char *xmltext; const char *p; char *q; XMLPARSE_ASSERT_STRING(_tag_,text); xmltext=ParseXML_Encode_Safe_XML(text); loaded_translations[nloaded_translations-1]->nothtml_rbnode=strcpy(malloc(strlen(text)+1),text); loaded_translations[nloaded_translations-1]->html_rbnode=malloc(sizeof("")+strlen(xmltext)+2*sizeof("")+2*sizeof("")+1+1); p=xmltext; q=loaded_translations[nloaded_translations-1]->html_rbnode; strcpy(q,""); q+=sizeof("")-1; while(*p!='%') *q++=*p++; *q++=*p++; while(*p!='%') *q++=*p++; p+=2; strcpy(q,"%s"); q+=sizeof("%s")-1; while(*p!='%') *q++=*p++; p+=2; strcpy(q,"%s"); q+=sizeof("%s")-1; strcpy(q,p); strcat(q,"\n"); } return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the HTMLSegmentType XSD type is seen int HTMLSegmentType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *text The contents of the 'text' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int HTMLSegmentType_function(const char *_tag_,int _type_,const char *text) { if(_type_&XMLPARSE_TAG_START && store) { char *xmltext; const char *p; char *q; XMLPARSE_ASSERT_STRING(_tag_,text); xmltext=ParseXML_Encode_Safe_XML(text); loaded_translations[nloaded_translations-1]->nothtml_segment=strcpy(malloc(strlen(text)+1),text); loaded_translations[nloaded_translations-1]->html_segment=malloc(sizeof("")+strlen(xmltext)+2*sizeof("")+2*sizeof("")+1); p=xmltext; q=loaded_translations[nloaded_translations-1]->html_segment; strcpy(q,""); q+=sizeof("")-1; while(*p!='%') *q++=*p++; p+=2; strcpy(q,"%s"); q+=sizeof("%s")-1; while(*p!='%') *q++=*p++; strcpy(q,""); q+=sizeof("")-1; strcpy(q,p); strcat(q,""); } return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the HTMLStopType XSD type is seen int HTMLStopType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *text The contents of the 'text' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int HTMLStopType_function(const char *_tag_,int _type_,const char *text) { if(_type_&XMLPARSE_TAG_START && store) { char *xmltext; XMLPARSE_ASSERT_STRING(_tag_,text); xmltext=ParseXML_Encode_Safe_XML(text); loaded_translations[nloaded_translations-1]->nothtml_stop=strcpy(malloc(strlen(text)+1),text); loaded_translations[nloaded_translations-1]->html_stop=malloc(sizeof("")+strlen(xmltext)+1+1); strcpy(loaded_translations[nloaded_translations-1]->html_stop,""); strcat(loaded_translations[nloaded_translations-1]->html_stop,xmltext); strcat(loaded_translations[nloaded_translations-1]->html_stop,"\n"); } return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the HTMLTotalType XSD type is seen int HTMLTotalType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *text The contents of the 'text' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int HTMLTotalType_function(const char *_tag_,int _type_,const char *text) { if(_type_&XMLPARSE_TAG_START && store) { char *xmltext; XMLPARSE_ASSERT_STRING(_tag_,text); xmltext=ParseXML_Encode_Safe_XML(text); loaded_translations[nloaded_translations-1]->nothtml_total=strcpy(malloc(strlen(text)+1),text); loaded_translations[nloaded_translations-1]->html_total=malloc(sizeof("")+strlen(xmltext)+sizeof("")+sizeof("")+1+1); strcpy(loaded_translations[nloaded_translations-1]->html_total,""); strcat(loaded_translations[nloaded_translations-1]->html_total,""); strcat(loaded_translations[nloaded_translations-1]->html_total,xmltext); strcat(loaded_translations[nloaded_translations-1]->html_total,""); strcat(loaded_translations[nloaded_translations-1]->html_total,"\n"); } return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the HTMLSubtotalType XSD type is seen int HTMLSubtotalType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *text The contents of the 'text' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int HTMLSubtotalType_function(const char *_tag_,int _type_,const char *text) { if(_type_&XMLPARSE_TAG_START && store) { char *xmltext; XMLPARSE_ASSERT_STRING(_tag_,text); xmltext=ParseXML_Encode_Safe_XML(text); loaded_translations[nloaded_translations-1]->nothtml_subtotal=strcpy(malloc(strlen(text)+1),text); loaded_translations[nloaded_translations-1]->html_subtotal=malloc(sizeof(" [")+strlen(xmltext)+sizeof("]")+1+1); strcpy(loaded_translations[nloaded_translations-1]->html_subtotal," ["); strcat(loaded_translations[nloaded_translations-1]->html_subtotal,xmltext); strcat(loaded_translations[nloaded_translations-1]->html_subtotal,"]"); strcat(loaded_translations[nloaded_translations-1]->html_subtotal,"\n"); } return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the GPXWaypointType XSD type is seen int GPXWaypointType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *type The contents of the 'type' attribute (or NULL if not defined). const char *string The contents of the 'string' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int GPXWaypointType_function(const char *_tag_,int _type_,const char *type,const char *string) { if(_type_&XMLPARSE_TAG_START && store) { char *xmlstring; XMLPARSE_ASSERT_STRING(_tag_,type); XMLPARSE_ASSERT_STRING(_tag_,string); xmlstring=ParseXML_Encode_Safe_XML(string); if(!strcmp(type,"start")) loaded_translations[nloaded_translations-1]->gpx_start=strcpy(malloc(strlen(xmlstring)+1),xmlstring); else if(!strcmp(type,"inter")) loaded_translations[nloaded_translations-1]->gpx_inter=strcpy(malloc(strlen(xmlstring)+1),xmlstring); else if(!strcmp(type,"trip")) loaded_translations[nloaded_translations-1]->gpx_trip=strcpy(malloc(strlen(xmlstring)+1),xmlstring); else if(!strcmp(type,"finish")) loaded_translations[nloaded_translations-1]->gpx_finish=strcpy(malloc(strlen(xmlstring)+1),xmlstring); else XMLPARSE_INVALID(_tag_,type); } return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the GPXDescType XSD type is seen int GPXDescType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *text The contents of the 'text' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int GPXDescType_function(const char *_tag_,int _type_,const char *text) { if(_type_&XMLPARSE_TAG_START && store) { char *xmltext; XMLPARSE_ASSERT_STRING(_tag_,text); xmltext=ParseXML_Encode_Safe_XML(text); loaded_translations[nloaded_translations-1]->gpx_desc=strcpy(malloc(strlen(xmltext)+1),xmltext); } return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the GPXNameType XSD type is seen int GPXNameType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *text The contents of the 'text' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int GPXNameType_function(const char *_tag_,int _type_,const char *text) { if(_type_&XMLPARSE_TAG_START && store) { char *xmltext; XMLPARSE_ASSERT_STRING(_tag_,text); xmltext=ParseXML_Encode_Safe_XML(text); loaded_translations[nloaded_translations-1]->gpx_name=strcpy(malloc(strlen(xmltext)+1),xmltext); } return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the GPXStepType XSD type is seen int GPXStepType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *text The contents of the 'text' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int GPXStepType_function(const char *_tag_,int _type_,const char *text) { if(_type_&XMLPARSE_TAG_START && store) { char *xmltext; XMLPARSE_ASSERT_STRING(_tag_,text); xmltext=ParseXML_Encode_Safe_XML(text); loaded_translations[nloaded_translations-1]->gpx_step=strcpy(malloc(strlen(xmltext)+1),xmltext); } return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the GPXFinalType XSD type is seen int GPXFinalType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *text The contents of the 'text' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int GPXFinalType_function(const char *_tag_,int _type_,const char *text) { if(_type_&XMLPARSE_TAG_START && store) { char *xmltext; XMLPARSE_ASSERT_STRING(_tag_,text); xmltext=ParseXML_Encode_Safe_XML(text); loaded_translations[nloaded_translations-1]->gpx_final=strcpy(malloc(strlen(xmltext)+1),xmltext); } return(0); } /*++++++++++++++++++++++++++++++++++++++ The XML translation parser. int ParseXMLTranslations Returns 0 if OK or something else in case of an error. const char *filename The name of the file to read. const char *lang The abbreviated language name to search for (NULL means first in file). int all Set to true to load all the translations. ++++++++++++++++++++++++++++++++++++++*/ int ParseXMLTranslations(const char *filename,const char *lang,int all) { int fd; int retval; if(!ExistsFile(filename)) return(1); fd=OpenFile(filename); /* Delete the existing translations */ if(nloaded_translations) FreeXMLTranslations(); /* Initialise variables used for parsing */ store_all=all; store_lang=lang; store=0; stored=0; /* Parse the file */ retval=ParseXML(fd,xml_toplevel_tags,XMLPARSE_UNKNOWN_ATTR_ERRNONAME|XMLPARSE_RETURN_ATTR_ENCODED); CloseFile(fd); if(retval) { FreeXMLTranslations(); return(2); } return(0); } /*++++++++++++++++++++++++++++++++++++++ Return a list of the languages that have been loaded from the XML file. char **GetTranslationLanguages Returns a NULL terminated list of strings - all allocated. ++++++++++++++++++++++++++++++++++++++*/ char **GetTranslationLanguages(void) { char **list=calloc(1+nloaded_translations,sizeof(char*)); int i; for(i=0;ilang)+1),loaded_translations[i]->lang); return(list); } /*++++++++++++++++++++++++++++++++++++++ Return a list of the full names of the languages that have been loaded from the XML file. char **GetTranslationLanguageFullNames Returns a NULL terminated list of strings - all allocated. ++++++++++++++++++++++++++++++++++++++*/ char **GetTranslationLanguageFullNames(void) { char **list=calloc(1+nloaded_translations,sizeof(char*)); int i; for(i=0;ilanguage)+1),loaded_translations[i]->language); return(list); } /*++++++++++++++++++++++++++++++++++++++ Get a named translation. Translation *GetTranslation Returns a pointer to the translation. const char *lang The abbreviated name of the language of the translation or NULL to get the default or an empty string to get the first one. ++++++++++++++++++++++++++++++++++++++*/ Translation *GetTranslation(const char *lang) { int i; if(!lang) return(&default_translation); if(!*lang && nloaded_translations>0) return(loaded_translations[0]); for(i=0;ilang,lang)) return(loaded_translations[i]); return(NULL); } /*++++++++++++++++++++++++++++++++++++++ Free the memory that has been allocated for the translations. ++++++++++++++++++++++++++++++++++++++*/ void FreeXMLTranslations() { int i,j; if(!loaded_translations) return; for(i=0;ilang); for(j=0;j<2;j++) { if(loaded_translations[i]->raw_copyright_creator[j] != default_translation.raw_copyright_creator[j]) free(loaded_translations[i]->raw_copyright_creator[j]); if(loaded_translations[i]->raw_copyright_source[j] != default_translation.raw_copyright_source[j]) free(loaded_translations[i]->raw_copyright_source[j]); if(loaded_translations[i]->raw_copyright_license[j] != default_translation.raw_copyright_license[j]) free(loaded_translations[i]->raw_copyright_license[j]); if(loaded_translations[i]->xml_copyright_creator[j] != default_translation.xml_copyright_creator[j]) free(loaded_translations[i]->xml_copyright_creator[j]); if(loaded_translations[i]->xml_copyright_source[j] != default_translation.xml_copyright_source[j]) free(loaded_translations[i]->xml_copyright_source[j]); if(loaded_translations[i]->xml_copyright_license[j] != default_translation.xml_copyright_license[j]) free(loaded_translations[i]->xml_copyright_license[j]); } for(j=0;j<9;j++) { if(loaded_translations[i]->xml_heading[j] != default_translation.xml_heading[j]) free(loaded_translations[i]->xml_heading[j]); if(loaded_translations[i]->xml_turn[j] != default_translation.xml_turn[j]) free(loaded_translations[i]->xml_turn[j]); } for(j=0;j<10;j++) if(loaded_translations[i]->xml_ordinal[j] != default_translation.xml_ordinal[j]) free(loaded_translations[i]->xml_ordinal[j]); for(j=0;j<9;j++) { if(loaded_translations[i]->notxml_heading[j] != default_translation.notxml_heading[j]) free(loaded_translations[i]->notxml_heading[j]); if(loaded_translations[i]->notxml_turn[j] != default_translation.notxml_turn[j]) free(loaded_translations[i]->notxml_turn[j]); } for(j=0;j<10;j++) if(loaded_translations[i]->notxml_ordinal[j] != default_translation.notxml_ordinal[j]) free(loaded_translations[i]->notxml_ordinal[j]); for(j=0;jraw_highway[j] != default_translation.raw_highway[j]) free(loaded_translations[i]->raw_highway[j]); if(loaded_translations[i]->xml_route_shortest != default_translation.xml_route_shortest) free(loaded_translations[i]->xml_route_shortest); if(loaded_translations[i]->xml_route_quickest != default_translation.xml_route_quickest) free(loaded_translations[i]->xml_route_quickest); if(loaded_translations[i]->html_waypoint != default_translation.html_waypoint) free(loaded_translations[i]->html_waypoint); if(loaded_translations[i]->html_junction != default_translation.html_junction) free(loaded_translations[i]->html_junction); if(loaded_translations[i]->html_roundabout != default_translation.html_roundabout) free(loaded_translations[i]->html_roundabout); if(loaded_translations[i]->html_title != default_translation.html_title) free(loaded_translations[i]->html_title); if(loaded_translations[i]->html_start != default_translation.html_start) free(loaded_translations[i]->html_start); if(loaded_translations[i]->html_node != default_translation.html_node) free(loaded_translations[i]->html_node); if(loaded_translations[i]->html_rbnode != default_translation.html_rbnode) free(loaded_translations[i]->html_rbnode); if(loaded_translations[i]->html_segment != default_translation.html_segment) free(loaded_translations[i]->html_segment); if(loaded_translations[i]->html_stop != default_translation.html_stop) free(loaded_translations[i]->html_stop); if(loaded_translations[i]->html_total != default_translation.html_total) free(loaded_translations[i]->html_total); if(loaded_translations[i]->html_subtotal!= default_translation.html_subtotal)free(loaded_translations[i]->html_subtotal); if(loaded_translations[i]->nothtml_waypoint != default_translation.nothtml_waypoint) free(loaded_translations[i]->nothtml_waypoint); if(loaded_translations[i]->nothtml_junction != default_translation.nothtml_junction) free(loaded_translations[i]->nothtml_junction); if(loaded_translations[i]->nothtml_roundabout != default_translation.nothtml_roundabout) free(loaded_translations[i]->nothtml_roundabout); if(loaded_translations[i]->nothtml_title != default_translation.nothtml_title) free(loaded_translations[i]->nothtml_title); if(loaded_translations[i]->nothtml_start != default_translation.nothtml_start) free(loaded_translations[i]->nothtml_start); if(loaded_translations[i]->nothtml_node != default_translation.nothtml_node) free(loaded_translations[i]->nothtml_node); if(loaded_translations[i]->nothtml_rbnode != default_translation.nothtml_rbnode) free(loaded_translations[i]->nothtml_rbnode); if(loaded_translations[i]->nothtml_segment != default_translation.nothtml_segment) free(loaded_translations[i]->nothtml_segment); if(loaded_translations[i]->nothtml_stop != default_translation.nothtml_stop) free(loaded_translations[i]->nothtml_stop); if(loaded_translations[i]->nothtml_total != default_translation.nothtml_total) free(loaded_translations[i]->nothtml_total); if(loaded_translations[i]->nothtml_subtotal!= default_translation.nothtml_subtotal)free(loaded_translations[i]->nothtml_subtotal); if(loaded_translations[i]->gpx_desc != default_translation.gpx_desc) free(loaded_translations[i]->gpx_desc); if(loaded_translations[i]->gpx_name != default_translation.gpx_name) free(loaded_translations[i]->gpx_name); if(loaded_translations[i]->gpx_step != default_translation.gpx_step) free(loaded_translations[i]->gpx_step); if(loaded_translations[i]->gpx_final != default_translation.gpx_final) free(loaded_translations[i]->gpx_final); if(loaded_translations[i]->gpx_start != default_translation.gpx_start) free(loaded_translations[i]->gpx_start); if(loaded_translations[i]->gpx_inter != default_translation.gpx_inter) free(loaded_translations[i]->gpx_inter); if(loaded_translations[i]->gpx_trip != default_translation.gpx_trip) free(loaded_translations[i]->gpx_trip); if(loaded_translations[i]->gpx_finish != default_translation.gpx_finish) free(loaded_translations[i]->gpx_finish); free(loaded_translations[i]); } free(loaded_translations); loaded_translations=NULL; nloaded_translations=0; } routino-3.0/src/waysx.c 644 233 144 52003 12563633051 10355 0/*************************************** Extended Way data type functions. Part of the Routino routing software. ******************/ /****************** This file Copyright 2008-2015 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #include #include #include "types.h" #include "ways.h" #include "typesx.h" #include "nodesx.h" #include "segmentsx.h" #include "waysx.h" #include "files.h" #include "logging.h" #include "sorting.h" /* Global variables */ /*+ The command line '--tmpdir' option or its default value. +*/ extern char *option_tmpdirname; /* Local variables */ /*+ Temporary file-local variables for use by the sort functions (re-initialised for each sort). +*/ static WaysX *sortwaysx; static SegmentsX *sortsegmentsx; /* Local functions */ static int sort_by_id(WayX *a,WayX *b); static int deduplicate_and_index_by_id(WayX *wayx,index_t index); static int sort_by_name(char *a,char *b); static int delete_unused(WayX *wayx,index_t index); static int sort_by_name_and_prop_and_id(WayX *a,WayX *b); static int deduplicate_and_index_by_compact_id(WayX *wayx,index_t index); /*++++++++++++++++++++++++++++++++++++++ Allocate a new way list (create a new file or open an existing one). WaysX *NewWayList Returns the way list. int append Set to 1 if the file is to be opened for appending. int readonly Set to 1 if the file is to be opened for reading. ++++++++++++++++++++++++++++++++++++++*/ WaysX *NewWayList(int append,int readonly) { WaysX *waysx; waysx=(WaysX*)calloc(1,sizeof(WaysX)); logassert(waysx,"Failed to allocate memory (try using slim mode?)"); /* Check calloc() worked */ waysx->filename =(char*)malloc(strlen(option_tmpdirname)+32); waysx->filename_tmp=(char*)malloc(strlen(option_tmpdirname)+32); /* allow %p to be up to 20 bytes */ sprintf(waysx->filename ,"%s/waysx.parsed.mem",option_tmpdirname); sprintf(waysx->filename_tmp,"%s/waysx.%p.tmp" ,option_tmpdirname,(void*)waysx); if(append || readonly) if(ExistsFile(waysx->filename)) { FILESORT_VARINT waysize; int fd; fd=ReOpenFileBuffered(waysx->filename); while(!ReadFileBuffered(fd,&waysize,FILESORT_VARSIZE)) { SkipFileBuffered(fd,waysize); waysx->number++; } CloseFileBuffered(fd); RenameFile(waysx->filename,waysx->filename_tmp); } if(append) waysx->fd=OpenFileBufferedAppend(waysx->filename_tmp); else if(!readonly) waysx->fd=OpenFileBufferedNew(waysx->filename_tmp); else waysx->fd=-1; #if SLIM waysx->cache=NewWayXCache(); log_malloc(waysx->cache,sizeof(*waysx->cache)); #endif waysx->nfilename_tmp=(char*)malloc(strlen(option_tmpdirname)+40); /* allow %p to be up to 20 bytes */ sprintf(waysx->nfilename_tmp,"%s/waynames.%p.tmp",option_tmpdirname,(void*)waysx); return(waysx); } /*++++++++++++++++++++++++++++++++++++++ Free a way list. WaysX *waysx The set of ways to be freed. int keep If set then the results file is to be kept. ++++++++++++++++++++++++++++++++++++++*/ void FreeWayList(WaysX *waysx,int keep) { if(keep) RenameFile(waysx->filename_tmp,waysx->filename); else DeleteFile(waysx->filename_tmp); free(waysx->filename); free(waysx->filename_tmp); if(waysx->idata) { log_free(waysx->idata); free(waysx->idata); } if(waysx->odata) { log_free(waysx->odata); free(waysx->odata); } if(waysx->cdata) { log_free(waysx->cdata); free(waysx->cdata); } DeleteFile(waysx->nfilename_tmp); free(waysx->nfilename_tmp); #if SLIM log_free(waysx->cache); DeleteWayXCache(waysx->cache); #endif free(waysx); } /*++++++++++++++++++++++++++++++++++++++ Append a single way to an unsorted way list. WaysX *waysx The set of ways to process. way_t id The ID of the way. Way *way The way data itself. node_t *nodes The list of nodes for this way. int nnodes The number of nodes for this way. const char *name The name or reference of the way. ++++++++++++++++++++++++++++++++++++++*/ void AppendWayList(WaysX *waysx,way_t id,Way *way,node_t *nodes,int nnodes,const char *name) { WayX wayx; FILESORT_VARINT size; node_t nonode=NO_NODE_ID; wayx.id=id; wayx.way=*way; size=sizeof(WayX)+(nnodes+1)*sizeof(node_t)+strlen(name)+1; WriteFileBuffered(waysx->fd,&size,FILESORT_VARSIZE); WriteFileBuffered(waysx->fd,&wayx,sizeof(WayX)); WriteFileBuffered(waysx->fd,nodes ,nnodes*sizeof(node_t)); WriteFileBuffered(waysx->fd,&nonode, sizeof(node_t)); WriteFileBuffered(waysx->fd,name,strlen(name)+1); waysx->number++; logassert(waysx->number!=0,"Too many ways (change index_t to 64-bits?)"); /* Zero marks the high-water mark for ways. */ } /*++++++++++++++++++++++++++++++++++++++ Finish appending ways and change the filename over. WaysX *waysx The ways that have been appended. ++++++++++++++++++++++++++++++++++++++*/ void FinishWayList(WaysX *waysx) { if(waysx->fd!=-1) waysx->fd=CloseFileBuffered(waysx->fd); } /*++++++++++++++++++++++++++++++++++++++ Find a particular way index. index_t IndexWayX Returns the index of the extended way with the specified id. WaysX *waysx The set of ways to process. way_t id The way id to look for. ++++++++++++++++++++++++++++++++++++++*/ index_t IndexWayX(WaysX *waysx,way_t id) { index_t start=0; index_t end=waysx->number-1; index_t mid; if(waysx->number==0) /* There are no ways */ return(NO_WAY); if(ididata[start]) /* Key is before start */ return(NO_WAY); if(id>waysx->idata[end]) /* Key is after end */ return(NO_WAY); /* Binary search - search key exact match only is required. * * # <- start | Check mid and move start or end if it doesn't match * # | * # | Since an exact match is wanted we can set end=mid-1 * # <- mid | or start=mid+1 because we know that mid doesn't match. * # | * # | Eventually either end=start or end=start+1 and one of * # <- end | start or end is the wanted one. */ do { mid=(start+end)/2; /* Choose mid point */ if(waysx->idata[mid]idata[mid]>id) /* Mid point is too high */ end=mid?(mid-1):mid; else /* Mid point is correct */ return(mid); } while((end-start)>1); if(waysx->idata[start]==id) /* Start is correct */ return(start); if(waysx->idata[end]==id) /* End is correct */ return(end); return(NO_WAY); } /*++++++++++++++++++++++++++++++++++++++ Sort the list of ways. WaysX *waysx The set of ways to process. ++++++++++++++++++++++++++++++++++++++*/ void SortWayList(WaysX *waysx) { index_t xnumber; int fd; /* Print the start message */ printf_first("Sorting Ways"); /* Re-open the file read-only and a new file writeable */ fd=ReplaceFileBuffered(waysx->filename_tmp,&waysx->fd); /* Allocate the array of indexes */ waysx->idata=(way_t*)malloc(waysx->number*sizeof(way_t)); log_malloc(waysx->idata,waysx->number*sizeof(way_t)); logassert(waysx->idata,"Failed to allocate memory (try using slim mode?)"); /* Check malloc() worked */ /* Sort the ways by ID and index them */ sortwaysx=waysx; xnumber=waysx->number; waysx->number=filesort_vary(waysx->fd,fd,NULL, (int (*)(const void*,const void*))sort_by_id, (int (*)(void*,index_t))deduplicate_and_index_by_id); waysx->knumber=waysx->number; /* Close the files */ waysx->fd=CloseFileBuffered(waysx->fd); CloseFileBuffered(fd); /* Print the final message */ printf_last("Sorted Ways: Ways=%"Pindex_t" Duplicates=%"Pindex_t,xnumber,xnumber-waysx->number); } /*++++++++++++++++++++++++++++++++++++++ Sort the ways into id order. int sort_by_id Returns the comparison of the id fields. WayX *a The first extended way. WayX *b The second extended way. ++++++++++++++++++++++++++++++++++++++*/ static int sort_by_id(WayX *a,WayX *b) { way_t a_id=a->id; way_t b_id=b->id; if(a_idb_id) return(1); else return(-FILESORT_PRESERVE_ORDER(a,b)); /* latest version first */ } /*++++++++++++++++++++++++++++++++++++++ Discard duplicate ways and create and index of ids. int deduplicate_and_index_by_id Return 1 if the value is to be kept, otherwise 0. WayX *wayx The extended way. index_t index The number of sorted ways that have already been written to the output file. ++++++++++++++++++++++++++++++++++++++*/ static int deduplicate_and_index_by_id(WayX *wayx,index_t index) { static way_t previd; /* internal variable (reset by first call in each sort; index==0) */ if(index==0 || wayx->id!=previd) { previd=wayx->id; if(wayx->way.type==WAY_DELETED) return(0); else { sortwaysx->idata[index]=wayx->id; return(1); } } else return(0); } /*++++++++++++++++++++++++++++++++++++++ Split the ways into segments and way names. SegmentsX *SplitWays Returns the set of segments that have been created. WaysX *waysx The set of ways to process. NodesX *nodesx The set of nodes to use. int keep If set to 1 then keep the old data file otherwise delete it. ++++++++++++++++++++++++++++++++++++++*/ SegmentsX *SplitWays(WaysX *waysx,NodesX *nodesx,int keep) { SegmentsX *segmentsx; index_t i; int fd,nfd; char *name=NULL; int namelen=0; /* Print the start message */ printf_first("Splitting Ways: Ways=0 Segments=0"); segmentsx=NewSegmentList(); /* Re-open the file read-only and a new file writeable */ if(keep) { RenameFile(waysx->filename_tmp,waysx->filename); waysx->fd=ReOpenFileBuffered(waysx->filename); fd=OpenFileBufferedNew(waysx->filename_tmp); } else fd=ReplaceFileBuffered(waysx->filename_tmp,&waysx->fd); nfd=OpenFileBufferedNew(waysx->nfilename_tmp); /* Loop through the ways and create the segments and way names */ for(i=0;inumber;i++) { WayX wayx; FILESORT_VARINT size; node_t node,prevnode=NO_NODE_ID; index_t index,previndex=NO_NODE; ReadFileBuffered(waysx->fd,&size,FILESORT_VARSIZE); ReadFileBuffered(waysx->fd,&wayx,sizeof(WayX)); waysx->allow|=wayx.way.allow; while(!ReadFileBuffered(waysx->fd,&node,sizeof(node_t)) && node!=NO_NODE_ID) { index=IndexNodeX(nodesx,node); if(prevnode==node) { logerror("Way %"Pway_t" contains node %"Pnode_t" that is connected to itself.\n",logerror_way(waysx->idata[i]),logerror_node(node)); } else if(index==NO_NODE) { logerror("Way %"Pway_t" contains node %"Pnode_t" that does not exist in the Routino database.\n",logerror_way(waysx->idata[i]),logerror_node(node)); } else if(previndex==NO_NODE) ; else { distance_t segment_flags=0; if(wayx.way.type&Highway_OneWay) segment_flags|=ONEWAY_1TO2; if(wayx.way.type&Highway_Area) segment_flags|=SEGMENT_AREA; AppendSegmentList(segmentsx,i,previndex,index,segment_flags); } prevnode=node; previndex=index; size-=sizeof(node_t); } size-=sizeof(node_t)+sizeof(WayX); if(namelenfd,name,size); WriteFileBuffered(fd,&wayx,sizeof(WayX)); size+=sizeof(index_t); WriteFileBuffered(nfd,&size,FILESORT_VARSIZE); WriteFileBuffered(nfd,&i,sizeof(index_t)); WriteFileBuffered(nfd,name,size-sizeof(index_t)); if(!((i+1)%1000)) printf_middle("Splitting Ways: Ways=%"Pindex_t" Segments=%"Pindex_t,i+1,segmentsx->number); } FinishSegmentList(segmentsx); if(name) free(name); /* Close the files */ waysx->fd=CloseFileBuffered(waysx->fd); CloseFileBuffered(fd); CloseFileBuffered(nfd); /* Print the final message */ printf_last("Split Ways: Ways=%"Pindex_t" Segments=%"Pindex_t,waysx->number,segmentsx->number); return(segmentsx); } /*++++++++++++++++++++++++++++++++++++++ Sort the way names and assign the offsets to the ways. WaysX *waysx The set of ways to process. ++++++++++++++++++++++++++++++++++++++*/ void SortWayNames(WaysX *waysx) { index_t i; int nfd; char *names[2]={NULL,NULL}; int namelen[2]={0,0}; int nnames=0; uint32_t lastlength=0; /* Print the start message */ printf_first("Sorting Way Names"); /* Re-open the file read-only and new file writeable */ nfd=ReplaceFileBuffered(waysx->nfilename_tmp,&waysx->nfd); /* Sort the way names */ waysx->nlength=0; filesort_vary(waysx->nfd,nfd,NULL, (int (*)(const void*,const void*))sort_by_name, NULL); /* Close the files */ waysx->nfd=CloseFileBuffered(waysx->nfd); CloseFileBuffered(nfd); /* Print the final message */ printf_last("Sorted Way Names: Ways=%"Pindex_t,waysx->number); /* Print the start message */ printf_first("Updating Ways with Names: Ways=0 Names=0"); /* Map into memory / open the file */ #if !SLIM waysx->data=MapFileWriteable(waysx->filename_tmp); #else waysx->fd=SlimMapFileWriteable(waysx->filename_tmp); #endif /* Re-open the file read-only and new file writeable */ nfd=ReplaceFileBuffered(waysx->nfilename_tmp,&waysx->nfd); /* Update the ways and de-duplicate the names */ for(i=0;inumber;i++) { WayX *wayx; index_t index; FILESORT_VARINT size; ReadFileBuffered(waysx->nfd,&size,FILESORT_VARSIZE); if(namelen[nnames%2]nfd,&index,sizeof(index_t)); ReadFileBuffered(waysx->nfd,names[nnames%2],size-sizeof(index_t)); if(nnames==0 || strcmp(names[0],names[1])) { WriteFileBuffered(nfd,names[nnames%2],size-sizeof(index_t)); lastlength=waysx->nlength; waysx->nlength+=size-sizeof(index_t); nnames++; } wayx=LookupWayX(waysx,index,1); wayx->way.name=lastlength; PutBackWayX(waysx,wayx); if(!((i+1)%1000)) printf_middle("Updating Ways with Names: Ways=%"Pindex_t" Names=%"Pindex_t,i+1,nnames); } if(names[0]) free(names[0]); if(names[1]) free(names[1]); /* Close the files */ waysx->nfd=CloseFileBuffered(waysx->nfd); CloseFileBuffered(nfd); /* Unmap from memory / close the files */ #if !SLIM waysx->data=UnmapFile(waysx->data); #else waysx->fd=SlimUnmapFile(waysx->fd); #endif /* Print the final message */ printf_last("Updated Ways with Names: Ways=%"Pindex_t" Names=%"Pindex_t,waysx->number,nnames); } /*++++++++++++++++++++++++++++++++++++++ Sort the ways into name order. int sort_by_name Returns the comparison of the name fields. char *a The first way name. char *b The second way name. ++++++++++++++++++++++++++++++++++++++*/ static int sort_by_name(char *a,char *b) { int compare; char *a_name=a+sizeof(index_t); char *b_name=b+sizeof(index_t); compare=strcmp(a_name,b_name); if(compare) return(compare); else return(FILESORT_PRESERVE_ORDER(a,b)); } /*++++++++++++++++++++++++++++++++++++++ Compact the way list, removing duplicated ways and unused ways. WaysX *waysx The set of ways to process. SegmentsX *segmentsx The set of segments to check. ++++++++++++++++++++++++++++++++++++++*/ void CompactWayList(WaysX *waysx,SegmentsX *segmentsx) { int fd; index_t cnumber; if(waysx->number==0) return; /* Print the start message */ printf_first("Sorting Ways and Compacting"); /* Allocate the array of indexes */ waysx->cdata=(index_t*)malloc(waysx->number*sizeof(index_t)); log_malloc(waysx->cdata,waysx->number*sizeof(index_t)); logassert(waysx->cdata,"Failed to allocate memory (try using slim mode?)"); /* Check malloc() worked */ /* Re-open the file read-only and a new file writeable */ fd=ReplaceFileBuffered(waysx->filename_tmp,&waysx->fd); /* Sort the ways to allow compacting according to the properties */ sortwaysx=waysx; sortsegmentsx=segmentsx; cnumber=filesort_fixed(waysx->fd,fd,sizeof(WayX),(int (*)(void*,index_t))delete_unused, (int (*)(const void*,const void*))sort_by_name_and_prop_and_id, (int (*)(void*,index_t))deduplicate_and_index_by_compact_id); /* Close the files */ waysx->fd=CloseFileBuffered(waysx->fd); CloseFileBuffered(fd); /* Free the data */ log_free(segmentsx->usedway); free(segmentsx->usedway); segmentsx->usedway=NULL; /* Print the final message */ printf_last("Sorted and Compacted Ways: Ways=%"Pindex_t" Unique=%"Pindex_t,waysx->number,cnumber); waysx->number=cnumber; } /*++++++++++++++++++++++++++++++++++++++ Delete the ways that are no longer being used. int delete_unused Return 1 if the value is to be kept, otherwise 0. WayX *wayx The extended way. index_t index The number of unsorted ways that have been read from the input file. ++++++++++++++++++++++++++++++++++++++*/ static int delete_unused(WayX *wayx,index_t index) { if(sortsegmentsx && !IsBitSet(sortsegmentsx->usedway,index)) { sortwaysx->cdata[index]=NO_WAY; return(0); } else { wayx->id=index; return(1); } } /*++++++++++++++++++++++++++++++++++++++ Sort the ways into name, properties and id order. int sort_by_name_and_prop_and_id Returns the comparison of the name, properties and id fields. WayX *a The first extended Way. WayX *b The second extended Way. ++++++++++++++++++++++++++++++++++++++*/ static int sort_by_name_and_prop_and_id(WayX *a,WayX *b) { int compare; index_t a_name=a->way.name; index_t b_name=b->way.name; if(a_nameb_name) return(1); compare=WaysCompare(&a->way,&b->way); if(compare) return(compare); return(sort_by_id(a,b)); } /*++++++++++++++++++++++++++++++++++++++ Create the index of compacted Way identifiers and ignore Ways with duplicated properties. int deduplicate_and_index_by_compact_id Return 1 if the value is to be kept, otherwise 0. WayX *wayx The extended way. index_t index The number of sorted ways that have already been written to the output file. ++++++++++++++++++++++++++++++++++++++*/ static int deduplicate_and_index_by_compact_id(WayX *wayx,index_t index) { static Way lastway; /* internal variable (reset by first call in each sort; index==0) */ if(index==0 || wayx->way.name!=lastway.name || WaysCompare(&lastway,&wayx->way)) { lastway=wayx->way; sortwaysx->cdata[wayx->id]=index; wayx->id=index; return(1); } else { sortwaysx->cdata[wayx->id]=index-1; return(0); } } /*++++++++++++++++++++++++++++++++++++++ Save the way list to a file. WaysX *waysx The set of ways to save. const char *filename The name of the file to save. ++++++++++++++++++++++++++++++++++++++*/ void SaveWayList(WaysX *waysx,const char *filename) { index_t i; int fd; index_t position=0; WayX wayx; WaysFile waysfile={0}; highways_t highways=0; transports_t allow=0; properties_t props=0; /* Print the start message */ printf_first("Writing Ways: Ways=0"); /* Re-open the files */ waysx->fd=ReOpenFileBuffered(waysx->filename_tmp); waysx->nfd=ReOpenFileBuffered(waysx->nfilename_tmp); /* Write out the ways data */ fd=OpenFileBufferedNew(filename); SeekFileBuffered(fd,sizeof(WaysFile)); for(i=0;inumber;i++) { ReadFileBuffered(waysx->fd,&wayx,sizeof(WayX)); highways|=HIGHWAYS(wayx.way.type); allow |=wayx.way.allow; props |=wayx.way.props; WriteFileBuffered(fd,&wayx.way,sizeof(Way)); if(!((i+1)%1000)) printf_middle("Writing Ways: Ways=%"Pindex_t,i+1); } /* Write out the ways names */ SeekFileBuffered(fd,sizeof(WaysFile)+(offset_t)waysx->number*sizeof(Way)); while(positionnlength) { size_t len=1024; char temp[1024]; if((waysx->nlength-position)<1024) len=waysx->nlength-position; ReadFileBuffered(waysx->nfd,temp,len); WriteFileBuffered(fd,temp,len); position+=len; } /* Close the files */ waysx->fd=CloseFileBuffered(waysx->fd); waysx->nfd=CloseFileBuffered(waysx->nfd); /* Write out the header structure */ waysfile.number =waysx->number; waysfile.highways=highways; waysfile.allow =allow; waysfile.props =props; SeekFileBuffered(fd,0); WriteFileBuffered(fd,&waysfile,sizeof(WaysFile)); CloseFileBuffered(fd); /* Print the final message */ printf_last("Wrote Ways: Ways=%"Pindex_t,waysx->number); } routino-3.0/src/segments.h 644 233 144 17363 12550012554 11041 0/*************************************** $Header: /home/amb/CVS/routino/src/segments.h,v 1.38 2010-12-21 17:18:41 amb Exp $ A header file for the segments. Part of the Routino routing software. ******************/ /****************** This file Copyright 2008-2015 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #ifndef SEGMENTS_H #define SEGMENTS_H /*+ To stop multiple inclusions. +*/ #include #include "types.h" #include "cache.h" #include "files.h" #include "profiles.h" /* Data structures */ /*+ A structure containing a single segment. +*/ struct _Segment { index_t node1; /*+ The index of the starting node. +*/ index_t node2; /*+ The index of the finishing node. +*/ index_t next2; /*+ The index of the next segment sharing node2. +*/ index_t way; /*+ The index of the way associated with the segment. +*/ distance_t distance; /*+ The distance between the nodes. +*/ }; /*+ A structure containing the header from the file. +*/ typedef struct _SegmentsFile { index_t number; /*+ The number of segments in total. +*/ index_t snumber; /*+ The number of super-segments. +*/ index_t nnumber; /*+ The number of normal segments. +*/ } SegmentsFile; /*+ A structure containing a set of segments (and pointers to mmap file). +*/ struct _Segments { SegmentsFile file; /*+ The header data from the file. +*/ #if !SLIM char *data; /*+ The memory mapped data. +*/ Segment *segments; /*+ An array of segments. +*/ #else int fd; /*+ The file descriptor for the file. +*/ Segment cached[4]; /*+ Three cached segments read from the file in slim mode. +*/ index_t incache[4]; /*+ The indexes of the cached segments. +*/ SegmentCache *cache; /*+ A RAM cache of segments read from the file. +*/ #endif }; /* Functions in segments.c */ Segments *LoadSegmentList(const char *filename); void DestroySegmentList(Segments *segments); index_t FindClosestSegmentHeading(Nodes *nodes,Segments *segments,Ways *ways,index_t node1,double heading,Profile *profile); distance_t Distance(double lat1,double lon1,double lat2,double lon2); double DeltaLat(double lon,distance_t distance); double DeltaLon(double lat,distance_t distance); duration_t Duration(Segment *segmentp,Way *wayp,Profile *profile); double TurnAngle(Nodes *nodes,Segment *segment1p,Segment *segment2p,index_t node); double BearingAngle(Nodes *nodes,Segment *segmentp,index_t node); static inline Segment *NextSegment(Segments *segments,Segment *segmentp,index_t node); /* Macros and inline functions */ /*+ Return true if this is a normal segment. +*/ #define IsNormalSegment(xxx) (((xxx)->distance)&SEGMENT_NORMAL) /*+ Return true if this is a super-segment. +*/ #define IsSuperSegment(xxx) (((xxx)->distance)&SEGMENT_SUPER) /*+ Return true if the segment is oneway. +*/ #define IsOneway(xxx) ((xxx)->distance&(ONEWAY_2TO1|ONEWAY_1TO2)) /*+ Return true if the segment is oneway towards the specified node. +*/ #define IsOnewayTo(xxx,yyy) ((xxx)->node1==(yyy)?((xxx)->distance&ONEWAY_2TO1):((xxx)->distance&ONEWAY_1TO2)) /*+ Return true if the segment is oneway from the specified node. +*/ #define IsOnewayFrom(xxx,yyy) ((xxx)->node2==(yyy)?((xxx)->distance&ONEWAY_2TO1):((xxx)->distance&ONEWAY_1TO2)) /*+ Return the other node in the segment that is not the specified node. +*/ #define OtherNode(xxx,yyy) ((xxx)->node1==(yyy)?(xxx)->node2:(xxx)->node1) #if !SLIM /*+ Return a segment pointer given a set of segments and an index. +*/ #define LookupSegment(xxx,yyy,ppp) (&(xxx)->segments[yyy]) /*+ Return a segment index given a set of segments and a pointer. +*/ #define IndexSegment(xxx,yyy) (index_t)((yyy)-&(xxx)->segments[0]) /*++++++++++++++++++++++++++++++++++++++ Find the next segment with a particular starting node. Segment *NextSegment Returns a pointer to the next segment. Segments *segments The set of segments to use. Segment *segmentp The current segment. index_t node The wanted node. ++++++++++++++++++++++++++++++++++++++*/ static inline Segment *NextSegment(Segments *segments,Segment *segmentp,index_t node) { if(segmentp->node1==node) { segmentp++; if(IndexSegment(segments,segmentp)>=segments->file.number || segmentp->node1!=node) return(NULL); else return(segmentp); } else { if(segmentp->next2==NO_SEGMENT) return(NULL); else return(LookupSegment(segments,segmentp->next2,1)); } } #else /* Prototypes */ static inline Segment *LookupSegment(Segments *segments,index_t index,int position); static inline index_t IndexSegment(Segments *segments,Segment *segmentp); CACHE_NEWCACHE_PROTO(Segment) CACHE_DELETECACHE_PROTO(Segment) CACHE_FETCHCACHE_PROTO(Segment) CACHE_INVALIDATECACHE_PROTO(Segment) /* Data type */ CACHE_STRUCTURE(Segment) /* Inline functions */ CACHE_NEWCACHE(Segment) CACHE_DELETECACHE(Segment) CACHE_FETCHCACHE(Segment) CACHE_INVALIDATECACHE(Segment) /*++++++++++++++++++++++++++++++++++++++ Find the Segment information for a particular segment. Segment *LookupSegment Returns a pointer to the cached segment information. Segments *segments The set of segments to use. index_t index The index of the segment. int position The position in the cache to store the value. ++++++++++++++++++++++++++++++++++++++*/ static inline Segment *LookupSegment(Segments *segments,index_t index,int position) { segments->cached[position-1]=*FetchCachedSegment(segments->cache,index,segments->fd,sizeof(SegmentsFile)); segments->incache[position-1]=index; return(&segments->cached[position-1]); } /*++++++++++++++++++++++++++++++++++++++ Find the segment index for a particular segment pointer. index_t IndexSegment Returns the index of the segment in the list. Segments *segments The set of segments to use. Segment *segmentp The segment whose index is to be found. ++++++++++++++++++++++++++++++++++++++*/ static inline index_t IndexSegment(Segments *segments,Segment *segmentp) { int position1=(int)(segmentp-&segments->cached[0]); return(segments->incache[position1]); } /*++++++++++++++++++++++++++++++++++++++ Find the next segment with a particular starting node. Segment *NextSegment Returns a pointer to the next segment. Segments *segments The set of segments to use. Segment *segmentp The current segment. index_t node The wanted node. ++++++++++++++++++++++++++++++++++++++*/ static inline Segment *NextSegment(Segments *segments,Segment *segmentp,index_t node) { int position=(int)(segmentp-&segments->cached[-1]); if(segmentp->node1==node) { index_t index=IndexSegment(segments,segmentp); index++; if(index>=segments->file.number) return(NULL); segmentp=LookupSegment(segments,index,position); if(segmentp->node1!=node) return(NULL); else return(segmentp); } else { if(segmentp->next2==NO_SEGMENT) return(NULL); else return(LookupSegment(segments,segmentp->next2,position)); } } #endif #endif /* SEGMENTS_H */ routino-3.0/src/tagging.c 644 233 144 66152 12563633051 10634 0/*************************************** Load the tagging rules from a file and the functions for handling them. Part of the Routino routing software. ******************/ /****************** This file Copyright 2010-2015 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #include #include #include #include #include #include "files.h" #include "tagging.h" #include "xmlparse.h" #include "logging.h" /* Constants */ #define TAGACTION_IF 1 #define TAGACTION_IFNOT 2 #define TAGACTION_INHERIT 3 /* Not a real action, just a marker */ #define TAGACTION_SET 4 #define TAGACTION_UNSET 5 #define TAGACTION_OUTPUT 6 #define TAGACTION_LOGERROR 7 static const char* const default_logerror_message="ignoring it"; /* Local variable (intialised before each use) */ static int64_t current_id; /* Local parsing variables (re-initialised by DeleteXMLTaggingRules() function) */ static TaggingRuleList NodeRules={NULL,0}; static TaggingRuleList WayRules={NULL,0}; static TaggingRuleList RelationRules={NULL,0}; static int current_list_stack_depth=0; static TaggingRuleList **current_list_stack=NULL; static TaggingRuleList *current_list=NULL; /* Local parsing functions */ static TaggingRuleList *AppendTaggingRule(TaggingRuleList *rules,const char *k,const char *v,int action); static void AppendTaggingAction(TaggingRuleList *rules,const char *k,const char *v,int action,const char *message); static void DeleteTaggingRuleList(TaggingRuleList *rules); static void ApplyRules(TaggingRuleList *rules,TagList *input,TagList *output,const char *match_k,const char *match_v); /* The XML tag processing function prototypes */ //static int xmlDeclaration_function(const char *_tag_,int _type_,const char *version,const char *encoding); //static int RoutinoTaggingType_function(const char *_tag_,int _type_); static int NodeType_function(const char *_tag_,int _type_); static int WayType_function(const char *_tag_,int _type_); static int RelationType_function(const char *_tag_,int _type_); static int IfType_function(const char *_tag_,int _type_,const char *k,const char *v); static int IfNotType_function(const char *_tag_,int _type_,const char *k,const char *v); static int SetType_function(const char *_tag_,int _type_,const char *k,const char *v); static int UnsetType_function(const char *_tag_,int _type_,const char *k); static int OutputType_function(const char *_tag_,int _type_,const char *k,const char *v); static int LogErrorType_function(const char *_tag_,int _type_,const char *k,const char *v,const char *message); /* The XML tag definitions (forward declarations) */ static const xmltag xmlDeclaration_tag; static const xmltag RoutinoTaggingType_tag; static const xmltag NodeType_tag; static const xmltag WayType_tag; static const xmltag RelationType_tag; static const xmltag IfType_tag; static const xmltag IfNotType_tag; static const xmltag SetType_tag; static const xmltag UnsetType_tag; static const xmltag OutputType_tag; static const xmltag LogErrorType_tag; /* The XML tag definition values */ /*+ The complete set of tags at the top level. +*/ static const xmltag * const xml_toplevel_tags[]={&xmlDeclaration_tag,&RoutinoTaggingType_tag,NULL}; /*+ The xmlDeclaration type tag. +*/ static const xmltag xmlDeclaration_tag= {"xml", 2, {"version","encoding"}, NULL, {NULL}}; /*+ The RoutinoTaggingType type tag. +*/ static const xmltag RoutinoTaggingType_tag= {"routino-tagging", 0, {NULL}, NULL, {&NodeType_tag,&WayType_tag,&RelationType_tag,NULL}}; /*+ The NodeType type tag. +*/ static const xmltag NodeType_tag= {"node", 0, {NULL}, NodeType_function, {&IfType_tag,&IfNotType_tag,NULL}}; /*+ The WayType type tag. +*/ static const xmltag WayType_tag= {"way", 0, {NULL}, WayType_function, {&IfType_tag,&IfNotType_tag,NULL}}; /*+ The RelationType type tag. +*/ static const xmltag RelationType_tag= {"relation", 0, {NULL}, RelationType_function, {&IfType_tag,&IfNotType_tag,NULL}}; /*+ The IfType type tag. +*/ static const xmltag IfType_tag= {"if", 2, {"k","v"}, IfType_function, {&IfType_tag,&IfNotType_tag,&SetType_tag,&UnsetType_tag,&OutputType_tag,&LogErrorType_tag,NULL}}; /*+ The IfNotType type tag. +*/ static const xmltag IfNotType_tag= {"ifnot", 2, {"k","v"}, IfNotType_function, {&IfType_tag,&IfNotType_tag,&SetType_tag,&UnsetType_tag,&OutputType_tag,&LogErrorType_tag,NULL}}; /*+ The SetType type tag. +*/ static const xmltag SetType_tag= {"set", 2, {"k","v"}, SetType_function, {NULL}}; /*+ The UnsetType type tag. +*/ static const xmltag UnsetType_tag= {"unset", 1, {"k"}, UnsetType_function, {NULL}}; /*+ The OutputType type tag. +*/ static const xmltag OutputType_tag= {"output", 2, {"k","v"}, OutputType_function, {NULL}}; /*+ The LogErrorType type tag. +*/ static const xmltag LogErrorType_tag= {"logerror", 3, {"k","v","message"}, LogErrorType_function, {NULL}}; /* The XML tag processing functions */ /*++++++++++++++++++++++++++++++++++++++ The function that is called when the XML declaration is seen int xmlDeclaration_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *version The contents of the 'version' attribute (or NULL if not defined). const char *encoding The contents of the 'encoding' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ //static int xmlDeclaration_function(const char *_tag_,int _type_,const char *version,const char *encoding) //{ // return(0); //} /*++++++++++++++++++++++++++++++++++++++ The function that is called when the RoutinoTaggingType XSD type is seen int RoutinoTaggingType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. ++++++++++++++++++++++++++++++++++++++*/ //static int RoutinoTaggingType_function(const char *_tag_,int _type_) //{ // return(0); //} /*++++++++++++++++++++++++++++++++++++++ The function that is called when the NodeType XSD type is seen int NodeType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. ++++++++++++++++++++++++++++++++++++++*/ static int NodeType_function(const char *_tag_,int _type_) { if(_type_&XMLPARSE_TAG_START) { current_list_stack_depth=0; current_list=&NodeRules; } return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the WayType XSD type is seen int WayType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. ++++++++++++++++++++++++++++++++++++++*/ static int WayType_function(const char *_tag_,int _type_) { if(_type_&XMLPARSE_TAG_START) { current_list_stack_depth=0; current_list=&WayRules; } return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the RelationType XSD type is seen int RelationType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. ++++++++++++++++++++++++++++++++++++++*/ static int RelationType_function(const char *_tag_,int _type_) { if(_type_&XMLPARSE_TAG_START) { current_list_stack_depth=0; current_list=&RelationRules; } return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the IfType XSD type is seen int IfType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *k The contents of the 'k' attribute (or NULL if not defined). const char *v The contents of the 'v' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int IfType_function(const char *_tag_,int _type_,const char *k,const char *v) { if(_type_&XMLPARSE_TAG_START) { if(!current_list_stack || (current_list_stack_depth%8)==7) current_list_stack=(TaggingRuleList**)realloc((void*)current_list_stack,(current_list_stack_depth+8)*sizeof(TaggingRuleList*)); current_list_stack[current_list_stack_depth++]=current_list; current_list=AppendTaggingRule(current_list,k,v,TAGACTION_IF); } if(_type_&XMLPARSE_TAG_END) current_list=current_list_stack[--current_list_stack_depth]; return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the IfNotType XSD type is seen int IfNotType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *k The contents of the 'k' attribute (or NULL if not defined). const char *v The contents of the 'v' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int IfNotType_function(const char *_tag_,int _type_,const char *k,const char *v) { if(_type_&XMLPARSE_TAG_START) { if(!current_list_stack || (current_list_stack_depth%8)==7) current_list_stack=(TaggingRuleList**)realloc((void*)current_list_stack,(current_list_stack_depth+8)*sizeof(TaggingRuleList*)); current_list_stack[current_list_stack_depth++]=current_list; current_list=AppendTaggingRule(current_list,k,v,TAGACTION_IFNOT); } if(_type_&XMLPARSE_TAG_END) current_list=current_list_stack[--current_list_stack_depth]; return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the SetType XSD type is seen int SetType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *k The contents of the 'k' attribute (or NULL if not defined). const char *v The contents of the 'v' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int SetType_function(const char *_tag_,int _type_,const char *k,const char *v) { if(_type_&XMLPARSE_TAG_START) AppendTaggingAction(current_list,k,v,TAGACTION_SET,NULL); return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the UnsetType XSD type is seen int UnsetType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *k The contents of the 'k' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int UnsetType_function(const char *_tag_,int _type_,const char *k) { if(_type_&XMLPARSE_TAG_START) AppendTaggingAction(current_list,k,NULL,TAGACTION_UNSET,NULL); return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the OutputType XSD type is seen int OutputType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *k The contents of the 'k' attribute (or NULL if not defined). const char *v The contents of the 'v' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int OutputType_function(const char *_tag_,int _type_,const char *k,const char *v) { if(_type_&XMLPARSE_TAG_START) AppendTaggingAction(current_list,k,v,TAGACTION_OUTPUT,NULL); return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the LogErrorType XSD type is seen int LogErrorType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *k The contents of the 'k' attribute (or NULL if not defined). const char *v The contents of the 'v' attribute (or NULL if not defined). const char *message The contents of the 'message' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int LogErrorType_function(const char *_tag_,int _type_,const char *k,const char *v,const char *message) { if(_type_&XMLPARSE_TAG_START) AppendTaggingAction(current_list,k,v,TAGACTION_LOGERROR,message); return(0); } /*++++++++++++++++++++++++++++++++++++++ The XML tagging rules parser. int ParseXMLTaggingRules Returns 0 if OK or something else in case of an error. const char *filename The name of the file to read. ++++++++++++++++++++++++++++++++++++++*/ int ParseXMLTaggingRules(const char *filename) { int fd; int retval; if(!ExistsFile(filename)) { fprintf(stderr,"Error: Specified tagging rules file '%s' does not exist.\n",filename); return(1); } fd=OpenFile(filename); /* Initialise variables used for parsing */ retval=ParseXML(fd,xml_toplevel_tags,XMLPARSE_UNKNOWN_ATTR_ERRNONAME); CloseFile(fd); if(current_list_stack) free(current_list_stack); if(retval) return(1); return(0); } /*++++++++++++++++++++++++++++++++++++++ Delete the tagging rules loaded from the XML file. ++++++++++++++++++++++++++++++++++++++*/ void DeleteXMLTaggingRules(void) { current_list_stack_depth=0; current_list_stack=NULL; current_list=NULL; DeleteTaggingRuleList(&NodeRules); DeleteTaggingRuleList(&WayRules); DeleteTaggingRuleList(&RelationRules); } /*++++++++++++++++++++++++++++++++++++++ Append a tagging rule to the list of rules. TaggingRuleList *AppendTaggingRule Returns the new TaggingRuleList inside the new TaggingRule. TaggingRuleList *rules The list of rules to add to. const char *k The tag key. const char *v The tag value. int action Set to the type of action. ++++++++++++++++++++++++++++++++++++++*/ TaggingRuleList *AppendTaggingRule(TaggingRuleList *rules,const char *k,const char *v,int action) { if((rules->nrules%16)==0) rules->rules=(TaggingRule*)realloc((void*)rules->rules,(rules->nrules+16)*sizeof(TaggingRule)); rules->nrules++; rules->rules[rules->nrules-1].action=action; if(k) rules->rules[rules->nrules-1].k=strcpy(malloc(strlen(k)+1),k); else rules->rules[rules->nrules-1].k=NULL; if(v) rules->rules[rules->nrules-1].v=strcpy(malloc(strlen(v)+1),v); else rules->rules[rules->nrules-1].v=NULL; rules->rules[rules->nrules-1].message=NULL; rules->rules[rules->nrules-1].rulelist=(TaggingRuleList*)calloc(sizeof(TaggingRuleList),1); return(rules->rules[rules->nrules-1].rulelist); } /*++++++++++++++++++++++++++++++++++++++ Append a tagging action to the list of rules. TaggingRuleList *rules The list of rules to add to. const char *k The tag key. const char *v The tag value. int action Set to the type of action. const char *message The message to use for the logerror action. ++++++++++++++++++++++++++++++++++++++*/ static void AppendTaggingAction(TaggingRuleList *rules,const char *k,const char *v,int action,const char *message) { if((rules->nrules%16)==0) rules->rules=(TaggingRule*)realloc((void*)rules->rules,(rules->nrules+16)*sizeof(TaggingRule)); rules->nrules++; rules->rules[rules->nrules-1].action=action; if(k) rules->rules[rules->nrules-1].k=strcpy(malloc(strlen(k)+1),k); else rules->rules[rules->nrules-1].k=NULL; if(v) rules->rules[rules->nrules-1].v=strcpy(malloc(strlen(v)+1),v); else rules->rules[rules->nrules-1].v=NULL; if(message) rules->rules[rules->nrules-1].message=strcpy(malloc(strlen(message)+1),message); else rules->rules[rules->nrules-1].message=(char*)default_logerror_message; rules->rules[rules->nrules-1].rulelist=NULL; } /*++++++++++++++++++++++++++++++++++++++ Delete a tagging rule. TaggingRuleList *rules The list of rules to be deleted. ++++++++++++++++++++++++++++++++++++++*/ void DeleteTaggingRuleList(TaggingRuleList *rules) { int i; for(i=0;inrules;i++) { if(rules->rules[i].k) free(rules->rules[i].k); if(rules->rules[i].v) free(rules->rules[i].v); if(rules->rules[i].message && rules->rules[i].message!=default_logerror_message) free(rules->rules[i].message); if(rules->rules[i].rulelist) { DeleteTaggingRuleList(rules->rules[i].rulelist); free(rules->rules[i].rulelist); } } if(rules->rules) free(rules->rules); rules->rules=NULL; rules->nrules=0; } /*++++++++++++++++++++++++++++++++++++++ Create a new TagList structure. TagList *NewTagList Returns the new allocated TagList. ++++++++++++++++++++++++++++++++++++++*/ TagList *NewTagList(void) { return((TagList*)calloc(sizeof(TagList),1)); } /*++++++++++++++++++++++++++++++++++++++ Delete a tag list and the contents. TagList *tags The list of tags to delete. ++++++++++++++++++++++++++++++++++++++*/ void DeleteTagList(TagList *tags) { int i; for(i=0;intags;i++) { if(tags->k[i]) free(tags->k[i]); if(tags->v[i]) free(tags->v[i]); } if(tags->k) free(tags->k); if(tags->v) free(tags->v); free(tags); } /*++++++++++++++++++++++++++++++++++++++ Append a tag to the list of tags. TagList *tags The list of tags to add to. const char *k The tag key. const char *v The tag value. ++++++++++++++++++++++++++++++++++++++*/ void AppendTag(TagList *tags,const char *k,const char *v) { if((tags->ntags%8)==0) { int i; tags->k=(char**)realloc((void*)tags->k,(tags->ntags+8)*sizeof(char*)); tags->v=(char**)realloc((void*)tags->v,(tags->ntags+8)*sizeof(char*)); for(i=tags->ntags;i<(tags->ntags+8);i++) tags->k[i]=tags->v[i]=NULL; } tags->k[tags->ntags]=strcpy(realloc(tags->k[tags->ntags],strlen(k)+1),k); tags->v[tags->ntags]=strcpy(realloc(tags->v[tags->ntags],strlen(v)+1),v); tags->ntags++; } /*++++++++++++++++++++++++++++++++++++++ Modify an existing tag or append a new tag to the list of tags. TagList *tags The list of tags to modify. const char *k The tag key. const char *v The tag value. ++++++++++++++++++++++++++++++++++++++*/ void ModifyTag(TagList *tags,const char *k,const char *v) { int i; for(i=0;intags;i++) if(!strcmp(tags->k[i],k)) { tags->v[i]=strcpy(realloc(tags->v[i],strlen(v)+1),v); return; } AppendTag(tags,k,v); } /*++++++++++++++++++++++++++++++++++++++ Delete an existing tag from the list of tags. TagList *tags The list of tags to modify. const char *k The tag key. ++++++++++++++++++++++++++++++++++++++*/ void DeleteTag(TagList *tags,const char *k) { int i,j; for(i=0;intags;i++) if(!strcmp(tags->k[i],k)) { if(tags->k[i]) free(tags->k[i]); if(tags->v[i]) free(tags->v[i]); for(j=i+1;jntags;j++) { tags->k[j-1]=tags->k[j]; tags->v[j-1]=tags->v[j]; } tags->ntags--; tags->k[tags->ntags]=NULL; tags->v[tags->ntags]=NULL; return; } } /*++++++++++++++++++++++++++++++++++++++ Create a string containing all of the tags formatted as if HTML. char *StringifyTag Returns a static pointer to the created string. TagList *tags The list of tags to convert. ++++++++++++++++++++++++++++++++++++++*/ char *StringifyTag(TagList *tags) { static char *string=NULL; /* static allocation of return value */ int i,length=0,used=0; for(i=0;intags;i++) { length+=strlen(tags->k[i]); length+=strlen(tags->v[i]); length+=16; } string=realloc((char*)string,length); for(i=0;intags;i++) used+=sprintf(string+used,"",tags->k[i],tags->v[i]); return(string); } /*++++++++++++++++++++++++++++++++++++++ Apply a set of tagging rules to a set of node tags. TagList *ApplyNodeTaggingRules Returns the list of output tags after modification. TagList *tags The tags to be modified. int64_t id The ID of the node. ++++++++++++++++++++++++++++++++++++++*/ TagList *ApplyNodeTaggingRules(TagList *tags,int64_t id) { TagList *result=NewTagList(); current_id=id; current_list=&NodeRules; ApplyRules(current_list,tags,result,NULL,NULL); return(result); } /*++++++++++++++++++++++++++++++++++++++ Apply a set of tagging rules to a set of way tags. TagList *ApplyWayTaggingRules Returns the list of output tags after modification. TagList *tags The tags to be modified. int64_t id The ID of the way. ++++++++++++++++++++++++++++++++++++++*/ TagList *ApplyWayTaggingRules(TagList *tags,int64_t id) { TagList *result=NewTagList(); current_id=id; current_list=&WayRules; ApplyRules(current_list,tags,result,NULL,NULL); return(result); } /*++++++++++++++++++++++++++++++++++++++ Apply a set of tagging rules to a set of relation tags. TagList *ApplyRelationTaggingRules Returns the list of output tags after modification. TagList *tags The tags to be modified. int64_t id The ID of the relation. ++++++++++++++++++++++++++++++++++++++*/ TagList *ApplyRelationTaggingRules(TagList *tags,int64_t id) { TagList *result=NewTagList(); current_id=id; current_list=&RelationRules; ApplyRules(current_list,tags,result,NULL,NULL); return(result); } /*++++++++++++++++++++++++++++++++++++++ Apply a set of rules to a matching tag. TaggingRuleList *rules The rules that are to be matched. TagList *input The input tags. TagList *output The output tags. const char *match_k The key matched at the higher level rule. const char *match_v The value matched at the higher level rule. ++++++++++++++++++++++++++++++++++++++*/ static void ApplyRules(TaggingRuleList *rules,TagList *input,TagList *output,const char *match_k,const char *match_v) { int i,j; char *match_k_copy=NULL,*match_v_copy=NULL; if(match_k) match_k_copy=strcpy(malloc(strlen(match_k)+1),match_k); if(match_v) match_v_copy=strcpy(malloc(strlen(match_v)+1),match_v); for(i=0;inrules;i++) { const char *k,*v; k=rules->rules[i].k; if(!k && rules->rules[i].action >= TAGACTION_INHERIT) k=match_k_copy; v=rules->rules[i].v; if(!v && rules->rules[i].action >= TAGACTION_INHERIT) v=match_v_copy; switch(rules->rules[i].action) { case TAGACTION_IF: if(k && v) { for(j=0;jntags;j++) if(!strcmp(input->k[j],k) && !strcmp(input->v[j],v)) ApplyRules(rules->rules[i].rulelist,input,output,input->k[j],input->v[j]); } else if(k && !v) { for(j=0;jntags;j++) if(!strcmp(input->k[j],k)) ApplyRules(rules->rules[i].rulelist,input,output,input->k[j],input->v[j]); } else if(!k && v) { for(j=0;jntags;j++) if(!strcmp(input->v[j],v)) ApplyRules(rules->rules[i].rulelist,input,output,input->k[j],input->v[j]); } else /* if(!k && !v) */ { if(!input->ntags) ApplyRules(rules->rules[i].rulelist,input,output,"",""); else for(j=0;jntags;j++) ApplyRules(rules->rules[i].rulelist,input,output,input->k[j],input->v[j]); } break; case TAGACTION_IFNOT: if(k && v) { for(j=0;jntags;j++) if(!strcmp(input->k[j],k) && !strcmp(input->v[j],v)) break; if(j!=input->ntags) break; } else if(k && !v) { for(j=0;jntags;j++) if(!strcmp(input->k[j],k)) break; if(j!=input->ntags) break; } else if(!k && v) { for(j=0;jntags;j++) if(!strcmp(input->v[j],v)) break; if(j!=input->ntags) break; } else /* if(!k && !v) */ { break; } ApplyRules(rules->rules[i].rulelist,input,output,k,v); break; case TAGACTION_SET: ModifyTag(input,k,v); break; case TAGACTION_UNSET: DeleteTag(input,k); break; case TAGACTION_OUTPUT: ModifyTag(output,k,v); break; case TAGACTION_LOGERROR: if(rules->rules[i].k && !rules->rules[i].v) for(j=0;jntags;j++) if(!strcmp(input->k[j],rules->rules[i].k)) { v=input->v[j]; break; } if(current_list==&NodeRules) logerror("Node %"Pnode_t" has an unrecognised tag '%s' = '%s' (in tagging rules); %s.\n",logerror_node(current_id),k,v,rules->rules[i].message); if(current_list==&WayRules) logerror("Way %"Pway_t" has an unrecognised tag '%s' = '%s' (in tagging rules); %s.\n",logerror_way(current_id),k,v,rules->rules[i].message); if(current_list==&RelationRules) logerror("Relation %"Prelation_t" has an unrecognised tag '%s' = '%s' (in tagging rules); %s.\n",logerror_relation(current_id),k,v,rules->rules[i].message); } } if(match_k_copy) free(match_k_copy); if(match_v_copy) free(match_v_copy); } routino-3.0/src/filedumper.c 644 233 144 133566 12574074473 11405 0/*************************************** Memory file dumper. Part of the Routino routing software. ******************/ /****************** This file Copyright 2008-2015 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #include #include #include #include #include #include #include "version.h" #include "types.h" #include "nodes.h" #include "segments.h" #include "ways.h" #include "relations.h" #include "errorlog.h" #include "files.h" #include "visualiser.h" #include "xmlparse.h" /* Local functions */ static void print_node(Nodes *nodes,index_t item); static void print_segment(Segments *segments,index_t item); static void print_way(Ways *ways,index_t item); static void print_turn_relation(Relations *relations,index_t item,Segments *segments,Nodes *nodes); static void print_errorlog(ErrorLogs *errorlogs,index_t item); static void print_head_osm(int coordcount,double latmin,double latmax,double lonmin,double lonmax); static void print_region_osm(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations, double latmin,double latmax,double lonmin,double lonmax,int option_no_super); static void print_node_osm(Nodes *nodes,index_t item); static void print_segment_osm(Segments *segments,index_t item,Ways *ways); static void print_turn_relation_osm(Relations *relations,index_t item,Segments *segments,Nodes *nodes); static void print_tail_osm(void); static void print_node_visualiser(Nodes *nodes,index_t item); static void print_segment_visualiser(Segments *segments,index_t item,Ways *ways); static void print_turn_relation_visualiser(Relations *relations,index_t item,Segments *segments,Nodes *nodes); static void print_errorlog_visualiser(ErrorLogs *errorlogs,index_t item); static char *RFC822Date(time_t t); static void print_usage(int detail,const char *argerr,const char *err); /*++++++++++++++++++++++++++++++++++++++ The main program for the file dumper. ++++++++++++++++++++++++++++++++++++++*/ int main(int argc,char** argv) { Nodes *OSMNodes; Segments *OSMSegments; Ways *OSMWays; Relations*OSMRelations; ErrorLogs*OSMErrorLogs=NULL; int arg; char *dirname=NULL,*prefix=NULL; char *nodes_filename,*segments_filename,*ways_filename,*relations_filename,*errorlogs_filename; int option_statistics=0; int option_visualiser=0,coordcount=0; double latmin=0,latmax=0,lonmin=0,lonmax=0; char *option_data=NULL; int option_dump=0; int option_dump_osm=0,option_no_super=0; int option_dump_visualiser=0; /* Parse the command line arguments */ for(arg=1;argfile.number); printf("Number(super)=%9"Pindex_t"\n",OSMNodes->file.snumber); printf("\n"); printf("Lat bins= %4d\n",(int)OSMNodes->file.latbins); printf("Lon bins= %4d\n",(int)OSMNodes->file.lonbins); printf("\n"); printf("Lat zero=%5d (%8.4f deg)\n",(int)OSMNodes->file.latzero,radians_to_degrees(latlong_to_radians(bin_to_latlong(OSMNodes->file.latzero)))); printf("Lon zero=%5d (%8.4f deg)\n",(int)OSMNodes->file.lonzero,radians_to_degrees(latlong_to_radians(bin_to_latlong(OSMNodes->file.lonzero)))); /* Examine the segments */ printf("\n"); printf("Segments\n"); printf("--------\n"); printf("\n"); printf("sizeof(Segment)=%9zu Bytes\n",sizeof(Segment)); printf("Number(total) =%9"Pindex_t"\n",OSMSegments->file.number); printf("Number(super) =%9"Pindex_t"\n",OSMSegments->file.snumber); printf("Number(normal) =%9"Pindex_t"\n",OSMSegments->file.nnumber); /* Examine the ways */ printf("\n"); printf("Ways\n"); printf("----\n"); printf("\n"); printf("sizeof(Way)=%9zu Bytes\n",sizeof(Way)); printf("Number =%9"Pindex_t"\n",OSMWays->file.number); printf("\n"); stat(ways_filename,&buf); printf("Total names=%9zu Bytes\n",(size_t)buf.st_size-sizeof(Ways)-OSMWays->file.number*sizeof(Way)); printf("\n"); printf("Included highways : %s\n",HighwaysNameList(OSMWays->file.highways)); printf("Included transports: %s\n",AllowedNameList(OSMWays->file.allow)); printf("Included properties: %s\n",PropertiesNameList(OSMWays->file.props)); /* Examine the relations */ printf("\n"); printf("Relations\n"); printf("---------\n"); printf("\n"); printf("sizeof(TurnRelation)=%9zu Bytes\n",sizeof(TurnRelation)); printf("Number =%9"Pindex_t"\n",OSMRelations->file.trnumber); if(errorlogs_filename) { printf("\n"); printf("Error Logs\n"); printf("----------\n"); printf("\n"); printf("Number(total) =%9"Pindex_t"\n",OSMErrorLogs->file.number); printf("Number(geographical) =%9"Pindex_t"\n",OSMErrorLogs->file.number_geo); printf("Number(non-geographical)=%9"Pindex_t"\n",OSMErrorLogs->file.number_nongeo); printf("\n"); stat(errorlogs_filename,&buf); #if !SLIM printf("Total strings=%9zu Bytes\n",(size_t)buf.st_size-(OSMErrorLogs->strings-(char*)OSMErrorLogs->data)); #else printf("Total strings=%9zu Bytes\n",(size_t)buf.st_size-(size_t)OSMErrorLogs->stringsoffset); #endif } } /* Print out internal data (in plain text format) */ if(option_dump) { index_t item; for(arg=1;argfile.number;item++) print_node(OSMNodes,item); } else if(!strncmp(argv[arg],"--node=",7)) { item=atoi(&argv[arg][7]); if(itemfile.number) print_node(OSMNodes,item); else printf("Invalid node number; minimum=0, maximum=%"Pindex_t".\n",OSMNodes->file.number-1); } else if(!strcmp(argv[arg],"--segment=all")) { for(item=0;itemfile.number;item++) print_segment(OSMSegments,item); } else if(!strncmp(argv[arg],"--segment=",10)) { item=atoi(&argv[arg][10]); if(itemfile.number) print_segment(OSMSegments,item); else printf("Invalid segment number; minimum=0, maximum=%"Pindex_t".\n",OSMSegments->file.number-1); } else if(!strcmp(argv[arg],"--way=all")) { for(item=0;itemfile.number;item++) print_way(OSMWays,item); } else if(!strncmp(argv[arg],"--way=",6)) { item=atoi(&argv[arg][6]); if(itemfile.number) print_way(OSMWays,item); else printf("Invalid way number; minimum=0, maximum=%"Pindex_t".\n",OSMWays->file.number-1); } else if(!strcmp(argv[arg],"--turn-relation=all")) { for(item=0;itemfile.trnumber;item++) print_turn_relation(OSMRelations,item,OSMSegments,OSMNodes); } else if(!strncmp(argv[arg],"--turn-relation=",16)) { item=atoi(&argv[arg][16]); if(itemfile.trnumber) print_turn_relation(OSMRelations,item,OSMSegments,OSMNodes); else printf("Invalid turn relation number; minimum=0, maximum=%"Pindex_t".\n",OSMRelations->file.trnumber-1); } else if(!strcmp(argv[arg],"--errorlog=all")) { for(item=0;itemfile.number;item++) print_errorlog(OSMErrorLogs,item); } else if(!strncmp(argv[arg],"--errorlog=",11)) { item=atoi(&argv[arg][11]); if(itemfile.number) print_errorlog(OSMErrorLogs,item); else printf("Invalid error log number; minimum=0, maximum=%"Pindex_t".\n",OSMErrorLogs->file.number-1); } } /* Print out internal data (in OSM XML format) */ if(option_dump_osm) { if(coordcount>0 && coordcount!=4) print_usage(0,NULL,"The --dump-osm option must have all of --latmin, --latmax, --lonmin, --lonmax or none.\n"); print_head_osm(coordcount,latmin,latmax,lonmin,lonmax); if(coordcount) print_region_osm(OSMNodes,OSMSegments,OSMWays,OSMRelations,latmin,latmax,lonmin,lonmax,option_no_super); else { index_t item; for(item=0;itemfile.number;item++) print_node_osm(OSMNodes,item); for(item=0;itemfile.number;item++) if(!option_no_super || IsNormalSegment(LookupSegment(OSMSegments,item,1))) print_segment_osm(OSMSegments,item,OSMWays); for(item=0;itemfile.trnumber;item++) print_turn_relation_osm(OSMRelations,item,OSMSegments,OSMNodes); } print_tail_osm(); } /* Print out internal data (in HTML format for the visualiser) */ if(option_dump_visualiser) { index_t item; if(!option_data) print_usage(0,NULL,"The --dump-visualiser option must have --data.\n"); for(arg=1;argfile.number) print_node_visualiser(OSMNodes,item); else printf("Invalid node number; minimum=0, maximum=%"Pindex_t".\n",OSMNodes->file.number-1); } else if(!strncmp(argv[arg],"--data=segment",14)) { item=atoi(&argv[arg][14]); if(itemfile.number) print_segment_visualiser(OSMSegments,item,OSMWays); else printf("Invalid segment number; minimum=0, maximum=%"Pindex_t".\n",OSMSegments->file.number-1); } else if(!strncmp(argv[arg],"--data=turn-relation",20)) { item=atoi(&argv[arg][20]); if(itemfile.trnumber) print_turn_relation_visualiser(OSMRelations,item,OSMSegments,OSMNodes); else printf("Invalid turn relation number; minimum=0, maximum=%"Pindex_t".\n",OSMRelations->file.trnumber-1); } else if(!strncmp(argv[arg],"--data=errorlog",15)) { item=atoi(&argv[arg][15]); if(itemfile.number) print_errorlog_visualiser(OSMErrorLogs,item); else printf("Invalid error log number; minimum=0, maximum=%"Pindex_t".\n",OSMErrorLogs->file.number-1); } } exit(EXIT_SUCCESS); } /*++++++++++++++++++++++++++++++++++++++ Print out the contents of a node from the routing database (as plain text). Nodes *nodes The set of nodes to use. index_t item The node index to print. ++++++++++++++++++++++++++++++++++++++*/ static void print_node(Nodes *nodes,index_t item) { Node *nodep=LookupNode(nodes,item,1); double latitude,longitude; GetLatLong(nodes,item,nodep,&latitude,&longitude); printf("Node %"Pindex_t"\n",item); printf(" firstseg=%"Pindex_t"\n",nodep->firstseg); printf(" latoffset=%d lonoffset=%d (latitude=%.6f longitude=%.6f)\n",nodep->latoffset,nodep->lonoffset,radians_to_degrees(latitude),radians_to_degrees(longitude)); printf(" allow=%02x (%s)\n",nodep->allow,AllowedNameList(nodep->allow)); if(IsSuperNode(nodep)) printf(" Super-Node\n"); if(nodep->flags & NODE_MINIRNDBT) printf(" Mini-roundabout\n"); } /*++++++++++++++++++++++++++++++++++++++ Print out the contents of a segment from the routing database (as plain text). Segments *segments The set of segments to use. index_t item The segment index to print. ++++++++++++++++++++++++++++++++++++++*/ static void print_segment(Segments *segments,index_t item) { Segment *segmentp=LookupSegment(segments,item,1); printf("Segment %"Pindex_t"\n",item); printf(" node1=%"Pindex_t" node2=%"Pindex_t"\n",segmentp->node1,segmentp->node2); printf(" next2=%"Pindex_t"\n",segmentp->next2); printf(" way=%"Pindex_t"\n",segmentp->way); printf(" distance=%d (%.3f km)\n",DISTANCE(segmentp->distance),distance_to_km(DISTANCE(segmentp->distance))); if(IsSuperSegment(segmentp) && IsNormalSegment(segmentp)) printf(" Super-Segment AND normal Segment\n"); else if(IsSuperSegment(segmentp) && !IsNormalSegment(segmentp)) printf(" Super-Segment\n"); if(IsOnewayTo(segmentp,segmentp->node1)) printf(" One-Way from node2 to node1\n"); if(IsOnewayTo(segmentp,segmentp->node2)) printf(" One-Way from node1 to node2\n"); } /*++++++++++++++++++++++++++++++++++++++ Print out the contents of a way from the routing database (as plain text). Ways *ways The set of ways to use. index_t item The way index to print. ++++++++++++++++++++++++++++++++++++++*/ static void print_way(Ways *ways,index_t item) { Way *wayp=LookupWay(ways,item,1); char *name=WayName(ways,wayp); printf("Way %"Pindex_t"\n",item); if(*name) printf(" name=%s\n",name); printf(" type=%02x (%s%s%s%s)\n",wayp->type, HighwayName(HIGHWAY(wayp->type)), wayp->type&Highway_OneWay?",One-Way":"", wayp->type&Highway_CycleBothWays?",Cycle-Both-Ways":"", wayp->type&Highway_Roundabout?",Roundabout":""); printf(" allow=%02x (%s)\n",wayp->allow,AllowedNameList(wayp->allow)); if(wayp->props) printf(" props=%02x (%s)\n",wayp->props,PropertiesNameList(wayp->props)); if(wayp->speed) printf(" speed=%d (%d km/hr)\n",wayp->speed,speed_to_kph(wayp->speed)); if(wayp->weight) printf(" weight=%d (%.1f tonnes)\n",wayp->weight,weight_to_tonnes(wayp->weight)); if(wayp->height) printf(" height=%d (%.1f m)\n",wayp->height,height_to_metres(wayp->height)); if(wayp->width) printf(" width=%d (%.1f m)\n",wayp->width,width_to_metres(wayp->width)); if(wayp->length) printf(" length=%d (%.1f m)\n",wayp->length,length_to_metres(wayp->length)); } /*++++++++++++++++++++++++++++++++++++++ Print out the contents of a turn relation from the routing database (as plain text). Relations *relations The set of relations to use. index_t item The turn relation index to print. Segments *segments The set of segments to use. Nodes *nodes The set of nodes to use. ++++++++++++++++++++++++++++++++++++++*/ static void print_turn_relation(Relations *relations,index_t item,Segments *segments,Nodes *nodes) { Segment *segmentp; TurnRelation *relationp=LookupTurnRelation(relations,item,1); Node *nodep=LookupNode(nodes,relationp->via,1); index_t from_way=NO_WAY,to_way=NO_WAY; index_t from_node=NO_NODE,to_node=NO_NODE; segmentp=FirstSegment(segments,nodep,1); do { index_t seg=IndexSegment(segments,segmentp); if(seg==relationp->from) { from_node=OtherNode(segmentp,relationp->from); from_way=segmentp->way; } if(seg==relationp->to) { to_node=OtherNode(segmentp,relationp->to); to_way=segmentp->way; } segmentp=NextSegment(segments,segmentp,relationp->via); } while(segmentp); printf("Relation %"Pindex_t"\n",item); printf(" from=%"Pindex_t" (segment) = %"Pindex_t" (way) = %"Pindex_t" (node)\n",relationp->from,from_way,from_node); printf(" via=%"Pindex_t" (node)\n",relationp->via); printf(" to=%"Pindex_t" (segment) = %"Pindex_t" (way) = %"Pindex_t" (node)\n",relationp->to,to_way,to_node); if(relationp->except) printf(" except=%02x (%s)\n",relationp->except,AllowedNameList(relationp->except)); } /*++++++++++++++++++++++++++++++++++++++ Print out the contents of an error log from the routing database (as plain text). ErrorLogs *errorlogs The set of error logs to use. index_t item The error log index to print. ++++++++++++++++++++++++++++++++++++++*/ static void print_errorlog(ErrorLogs *errorlogs,index_t item) { ErrorLog *errorlogp=LookupErrorLog(errorlogs,item,1); printf("Error Log %"Pindex_t"\n",item); if(itemfile.number_geo) { double latitude,longitude; GetErrorLogLatLong(errorlogs,item,errorlogp,&latitude,&longitude); printf(" latoffset=%d lonoffset=%d (latitude=%.6f longitude=%.6f)\n",errorlogp->latoffset,errorlogp->lonoffset,radians_to_degrees(latitude),radians_to_degrees(longitude)); } else printf(" No geographical information\n"); printf(" '%s'\n",LookupErrorLogString(errorlogs,item)); } /*++++++++++++++++++++++++++++++++++++++ Print out a header in OSM XML format. int coordcount If true then include a bounding box. double latmin The minimum latitude. double latmax The maximum latitude. double lonmin The minimum longitude. double lonmax The maximum longitude. ++++++++++++++++++++++++++++++++++++++*/ static void print_head_osm(int coordcount,double latmin,double latmax,double lonmin,double lonmax) { printf("\n"); printf("\n"); if(coordcount) printf(" \n", radians_to_degrees(latmin),radians_to_degrees(latmax),radians_to_degrees(lonmin),radians_to_degrees(lonmax)); } /*++++++++++++++++++++++++++++++++++++++ Print a region of the database in OSM XML format. Nodes *nodes The set of nodes to use. Segments *segments The set of segments to use. Ways *ways The set of ways to use. Relations *relations The set of relations to use. double latmin The minimum latitude. double latmax The maximum latitude. double lonmin The minimum longitude. double lonmax The maximum longitude. int option_no_super The option to print no super-segments. ++++++++++++++++++++++++++++++++++++++*/ static void print_region_osm(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations, double latmin,double latmax,double lonmin,double lonmax,int option_no_super) { ll_bin_t latminbin=latlong_to_bin(radians_to_latlong(latmin))-nodes->file.latzero; ll_bin_t latmaxbin=latlong_to_bin(radians_to_latlong(latmax))-nodes->file.latzero; ll_bin_t lonminbin=latlong_to_bin(radians_to_latlong(lonmin))-nodes->file.lonzero; ll_bin_t lonmaxbin=latlong_to_bin(radians_to_latlong(lonmax))-nodes->file.lonzero; ll_bin_t latb,lonb; index_t item,index1,index2; if(latminbin<0) latminbin=0; if(latmaxbin>nodes->file.latbins) latmaxbin=nodes->file.latbins-1; if(lonminbin<0) lonminbin=0; if(lonmaxbin>nodes->file.lonbins) lonmaxbin=nodes->file.lonbins-1; /* Loop through all of the nodes. */ for(latb=latminbin;latb<=latmaxbin;latb++) for(lonb=lonminbin;lonb<=lonmaxbin;lonb++) { ll_bin2_t llbin=lonb*nodes->file.latbins+latb; if(llbin<0 || llbin>(nodes->file.latbins*nodes->file.lonbins)) continue; index1=LookupNodeOffset(nodes,llbin); index2=LookupNodeOffset(nodes,llbin+1); for(item=index1;itemfile.latzero+latb)+off_to_latlong(nodep->latoffset)); double lon=latlong_to_radians(bin_to_latlong(nodes->file.lonzero+lonb)+off_to_latlong(nodep->lonoffset)); if(lat>latmin && latlonmin && lonlatmin && olatlonmin && olonoitem) if(!option_no_super || IsNormalSegment(segmentp)) print_segment_osm(segments,IndexSegment(segments,segmentp),ways); segmentp=NextSegment(segments,segmentp,item); } if(IsTurnRestrictedNode(nodep)) { index_t relindex=FindFirstTurnRelation1(relations,item); while(relindex!=NO_RELATION) { print_turn_relation_osm(relations,relindex,segments,nodes); relindex=FindNextTurnRelation1(relations,relindex); } } } } } } /*++++++++++++++++++++++++++++++++++++++ Print out the contents of a node from the routing database (in OSM XML format). Nodes *nodes The set of nodes to use. index_t item The node index to print. ++++++++++++++++++++++++++++++++++++++*/ static void print_node_osm(Nodes *nodes,index_t item) { Node *nodep=LookupNode(nodes,item,1); double latitude,longitude; int i; GetLatLong(nodes,item,nodep,&latitude,&longitude); if(nodep->allow==Transports_ALL && nodep->flags==0) printf(" \n",item+1,radians_to_degrees(latitude),radians_to_degrees(longitude)); else { printf(" \n",item+1,radians_to_degrees(latitude),radians_to_degrees(longitude)); if(nodep->flags & NODE_SUPER) printf(" \n"); if(nodep->flags & NODE_UTURN) printf(" \n"); if(nodep->flags & NODE_MINIRNDBT) printf(" \n"); if(nodep->flags & NODE_TURNRSTRCT) printf(" \n"); for(i=1;iallow & TRANSPORTS(i))) printf(" \n",TransportName(i)); printf(" \n"); } } /*++++++++++++++++++++++++++++++++++++++ Print out the contents of a segment from the routing database (as a way in OSM XML format). Segments *segments The set of segments to use. index_t item The segment index to print. Ways *ways The set of ways to use. ++++++++++++++++++++++++++++++++++++++*/ static void print_segment_osm(Segments *segments,index_t item,Ways *ways) { Segment *segmentp=LookupSegment(segments,item,1); Way *wayp=LookupWay(ways,segmentp->way,1); char *name=WayName(ways,wayp); int i; printf(" \n",item+1); if(IsOnewayTo(segmentp,segmentp->node1)) { printf(" \n",segmentp->node2+1); printf(" \n",segmentp->node1+1); } else { printf(" \n",segmentp->node1+1); printf(" \n",segmentp->node2+1); } if(IsSuperSegment(segmentp)) printf(" \n"); if(IsNormalSegment(segmentp)) printf(" \n"); printf(" \n",distance_to_km(DISTANCE(segmentp->distance))); if(wayp->type & Highway_OneWay) printf(" \n"); if(wayp->type & Highway_CycleBothWays) printf(" \n"); if(wayp->type & Highway_Roundabout) printf(" \n"); printf(" \n",HighwayName(HIGHWAY(wayp->type))); if(IsNormalSegment(segmentp) && *name) printf(" \n",ParseXML_Encode_Safe_XML(name)); for(i=1;iallow & TRANSPORTS(i)) printf(" \n",TransportName(i)); for(i=1;iprops & PROPERTIES(i)) printf(" \n",PropertyName(i)); if(wayp->speed) printf(" \n",speed_to_kph(wayp->speed)); if(wayp->weight) printf(" \n",weight_to_tonnes(wayp->weight)); if(wayp->height) printf(" \n",height_to_metres(wayp->height)); if(wayp->width) printf(" \n",width_to_metres(wayp->width)); if(wayp->length) printf(" \n",length_to_metres(wayp->length)); printf(" \n"); } /*++++++++++++++++++++++++++++++++++++++ Print out the contents of a turn relation from the routing database (in OSM XML format). Relations *relations The set of relations to use. index_t item The relation index to print. Segments *segments The set of segments to use. Nodes *nodes The set of nodes to use. ++++++++++++++++++++++++++++++++++++++*/ static void print_turn_relation_osm(Relations *relations,index_t item,Segments *segments,Nodes *nodes) { TurnRelation *relationp=LookupTurnRelation(relations,item,1); Segment *segmentp_from=LookupSegment(segments,relationp->from,1); Segment *segmentp_to =LookupSegment(segments,relationp->to ,2); double angle=TurnAngle(nodes,segmentp_from,segmentp_to,relationp->via); char *restriction; if(angle>150 || angle<-150) restriction="no_u_turn"; else if(angle>30) restriction="no_right_turn"; else if(angle<-30) restriction="no_left_turn"; else restriction="no_straight_on"; printf(" \n",item+1); printf(" \n"); printf(" \n",restriction); if(relationp->except) printf(" \n",AllowedNameList(relationp->except)); printf(" \n",relationp->from+1); printf(" \n",relationp->via+1); printf(" \n",relationp->to+1); printf(" \n"); } /*++++++++++++++++++++++++++++++++++++++ Print out a tail in OSM XML format. ++++++++++++++++++++++++++++++++++++++*/ static void print_tail_osm(void) { printf("\n"); } /*++++++++++++++++++++++++++++++++++++++ Print out the contents of a node from the routing database (in visualiser format). Nodes *nodes The set of nodes to use. index_t item The node index to print. ++++++++++++++++++++++++++++++++++++++*/ static void print_node_visualiser(Nodes *nodes,index_t item) { Node *nodep=LookupNode(nodes,item,1); double latitude,longitude; int i; GetLatLong(nodes,item,nodep,&latitude,&longitude); if(nodep->allow==Transports_ALL && nodep->flags==0) printf("<routino:node id='%"Pindex_t"' lat='%.7f' lon='%.7f' />\n",item+1,radians_to_degrees(latitude),radians_to_degrees(longitude)); else { printf("<routino:node id='%"Pindex_t"' lat='%.7f' lon='%.7f'>\n",item+1,radians_to_degrees(latitude),radians_to_degrees(longitude)); if(nodep->flags & NODE_SUPER) printf("   <tag k='routino:super' v='yes' />\n"); if(nodep->flags & NODE_UTURN) printf("   <tag k='routino:uturn' v='yes' />\n"); if(nodep->flags & NODE_MINIRNDBT) printf("   <tag k='junction' v='roundabout' />\n"); if(nodep->flags & NODE_TURNRSTRCT) printf("   <tag k='routino:turnrestriction' v='yes' />\n"); for(i=1;iallow & TRANSPORTS(i))) printf("   <tag k='%s' v='no' />\n",TransportName(i)); printf("</routino:node>\n"); } } /*++++++++++++++++++++++++++++++++++++++ Print out the contents of a segment from the routing database (as a way in visualiser format). Segments *segments The set of segments to use. index_t item The segment index to print. Ways *ways The set of ways to use. ++++++++++++++++++++++++++++++++++++++*/ static void print_segment_visualiser(Segments *segments,index_t item,Ways *ways) { Segment *segmentp=LookupSegment(segments,item,1); Way *wayp=LookupWay(ways,segmentp->way,1); char *name=WayName(ways,wayp); int i; printf("<routino:way id='%"Pindex_t"'>\n",item+1); if(IsOnewayTo(segmentp,segmentp->node1)) { printf("   <nd ref='%"Pindex_t"' />\n",segmentp->node2+1); printf("   <nd ref='%"Pindex_t"' />\n",segmentp->node1+1); } else { printf("   <nd ref='%"Pindex_t"' />\n",segmentp->node1+1); printf("   <nd ref='%"Pindex_t"' />\n",segmentp->node2+1); } if(IsSuperSegment(segmentp)) printf("   <tag k='routino:super' v='yes' />\n"); if(IsNormalSegment(segmentp)) printf("   <tag k='routino:normal' v='yes' />\n"); printf("   <tag k='routino:distance' v='%.3f km' />\n",distance_to_km(DISTANCE(segmentp->distance))); if(wayp->type & Highway_OneWay) printf("   <tag k='oneway' v='yes' />\n"); if(wayp->type & Highway_CycleBothWays) printf("   <tag k='cyclebothways' v='yes' />\n"); if(wayp->type & Highway_Roundabout) printf("   <tag k='roundabout' v='yes' />\n"); printf("   <tag k='highway' v='%s' />\n",HighwayName(HIGHWAY(wayp->type))); if(IsNormalSegment(segmentp) && *name) printf("   <tag k='name' v='%s' />\n",ParseXML_Encode_Safe_XML(name)); for(i=1;iallow & TRANSPORTS(i)) printf("   <tag k='%s' v='yes' />\n",TransportName(i)); for(i=1;iprops & PROPERTIES(i)) printf("   <tag k='%s' v='yes' />\n",PropertyName(i)); if(wayp->speed) printf("   <tag k='maxspeed' v='%d kph' />\n",speed_to_kph(wayp->speed)); if(wayp->weight) printf("   <tag k='maxweight' v='%.1f t' />\n",weight_to_tonnes(wayp->weight)); if(wayp->height) printf("   <tag k='maxheight' v='%.1f m' />\n",height_to_metres(wayp->height)); if(wayp->width) printf("   <tag k='maxwidth' v='%.1f m' />\n",width_to_metres(wayp->width)); if(wayp->length) printf("   <tag k='maxlength' v='%.1f m' />\n",length_to_metres(wayp->length)); printf("</routino:way>\n"); } /*++++++++++++++++++++++++++++++++++++++ Print out the contents of a turn relation from the routing database (in visualiser format). Relations *relations The set of relations to use. index_t item The relation index to print. Segments *segments The set of segments to use. Nodes *nodes The set of nodes to use. ++++++++++++++++++++++++++++++++++++++*/ static void print_turn_relation_visualiser(Relations *relations,index_t item,Segments *segments,Nodes *nodes) { TurnRelation *relationp=LookupTurnRelation(relations,item,1); Segment *segmentp_from=LookupSegment(segments,relationp->from,1); Segment *segmentp_to =LookupSegment(segments,relationp->to ,2); double angle=TurnAngle(nodes,segmentp_from,segmentp_to,relationp->via); char *restriction; if(angle>150 || angle<-150) restriction="no_u_turn"; else if(angle>30) restriction="no_right_turn"; else if(angle<-30) restriction="no_left_turn"; else restriction="no_straight_on"; printf("<routino:relation id='%"Pindex_t"'>\n",item+1); printf("   <tag k='type' v='restriction' />\n"); printf("   <tag k='restriction' v='%s'/>\n",restriction); if(relationp->except) printf("   <tag k='except' v='%s' />\n",AllowedNameList(relationp->except)); printf("   <member type='way' ref='%"Pindex_t"' role='from' />\n",relationp->from+1); printf("   <member type='node' ref='%"Pindex_t"' role='via' />\n",relationp->via+1); printf("   <member type='way' ref='%"Pindex_t"' role='to' />\n",relationp->to+1); printf("</routino:relation>\n"); } /*++++++++++++++++++++++++++++++++++++++ Print out an error log entry from the database (in visualiser format). ErrorLogs *errorlogs The set of error logs to use. index_t item The error log index to print. ++++++++++++++++++++++++++++++++++++++*/ static void print_errorlog_visualiser(ErrorLogs *errorlogs,index_t item) { char *string=LookupErrorLogString(errorlogs,item); printf("%s\n",ParseXML_Encode_Safe_XML(string)); } /*+ Conversion from time_t to date string (day of week). +*/ static const char* const weekdays[7]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"}; /*+ Conversion from time_t to date string (month of year). +*/ static const char* const months[12]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"}; /*++++++++++++++++++++++++++++++++++++++ Convert the time into an RFC 822 compliant date. char *RFC822Date Returns a pointer to a fixed string containing the date. time_t t The time. ++++++++++++++++++++++++++++++++++++++*/ static char *RFC822Date(time_t t) { static char value[32]; /* static allocation of return value */ char weekday[4]; char month[4]; struct tm *tim; tim=gmtime(&t); strcpy(weekday,weekdays[tim->tm_wday]); strcpy(month,months[tim->tm_mon]); /* Sun, 06 Nov 1994 08:49:37 GMT ; RFC 822, updated by RFC 1123 */ sprintf(value,"%3s, %02d %3s %4d %02d:%02d:%02d %s", weekday, tim->tm_mday, month, tim->tm_year+1900, tim->tm_hour, tim->tm_min, tim->tm_sec, "GMT" ); return(value); } /*++++++++++++++++++++++++++++++++++++++ Print out the usage information. int detail The level of detail to use: -1 = just version number, 0 = low detail, 1 = full details. const char *argerr The argument that gave the error (if there is one). const char *err Other error message (if there is one). ++++++++++++++++++++++++++++++++++++++*/ static void print_usage(int detail,const char *argerr,const char *err) { if(detail<0) { fprintf(stderr, "Routino version " ROUTINO_VERSION " " ROUTINO_URL ".\n" ); } if(detail>=0) { fprintf(stderr, "Usage: filedumper [--version]\n" " [--help]\n" " [--dir=] [--prefix=]\n" " [--statistics]\n" " [--visualiser --latmin= --latmax=\n" " --lonmin= --lonmax=\n" " --data=]\n" " [--dump [--node= ...]\n" " [--segment= ...]\n" " [--way= ...]\n" " [--turn-relation= ...]\n" " [--errorlog= ...]]\n" " [--dump-osm [--no-super]\n" " [--latmin= --latmax=\n" " --lonmin= --lonmax=]]\n" " [--dump-visualiser [--data=node]\n" " [--data=segment]\n" " [--data=turn-relation]\n" " [--data=errorlog]]\n"); if(argerr) fprintf(stderr, "\n" "Error with command line parameter: %s\n",argerr); if(err) fprintf(stderr, "\n" "Error: %s\n",err); } if(detail==1) fprintf(stderr, "\n" "--version Print the version of Routino.\n" "\n" "--help Prints this information.\n" "\n" "--dir= The directory containing the routing database.\n" "--prefix= The filename prefix for the routing database.\n" "\n" "--statistics Print statistics about the routing database.\n" "\n" "--visualiser Extract selected data from the routing database:\n" " --latmin= * the minimum latitude (degrees N).\n" " --latmax= * the maximum latitude (degrees N).\n" " --lonmin= * the minimum longitude (degrees E).\n" " --lonmax= * the maximum longitude (degrees E).\n" " --data= * the type of data to select.\n" "\n" " can be selected from:\n" " junctions = segment count at each junction.\n" " super = super-node and super-segments.\n" " waytype-* = segments of oneway, cyclebothways or roundabout type.\n" " highway-* = segments of the specified highway type.\n" " transport-* = segments allowing the specified transport type.\n" " barrier-* = nodes disallowing the specified transport type.\n" " turns = turn restrictions.\n" " speed = speed limits.\n" " weight = weight limits.\n" " height = height limits.\n" " width = width limits.\n" " length = length limits.\n" " property-* = segments with the specified property.\n" " errorlogs = errors logged during parsing.\n" "\n" "--dump Dump selected contents of the database.\n" " --node= * the node with the selected index.\n" " --segment= * the segment with the selected index.\n" " --way= * the way with the selected index.\n" " --turn-relation= * the turn relation with the selected index.\n" " --errorlog= * the error log with the selected index.\n" " Use 'all' instead of a number to get all of them.\n" "\n" "--dump-osm Dump all or part of the database as an XML file.\n" " --no-super * exclude the super-segments.\n" " --latmin= * the minimum latitude (degrees N).\n" " --latmax= * the maximum latitude (degrees N).\n" " --lonmin= * the minimum longitude (degrees E).\n" " --lonmax= * the maximum longitude (degrees E).\n" "\n" "--dump-visualiser Dump selected contents of the database in HTML.\n" " --data=node * the node with the selected index.\n" " --data=segment * the segment with the selected index.\n" " --data=turn-relation * the turn relation with the selected index.\n" " --data=errorlog * the error log with the selected index.\n"); exit(!detail); } routino-3.0/src/relationsx.h 644 233 144 11114 12563633052 11376 0/*************************************** A header file for the extended Relations structure. Part of the Routino routing software. ******************/ /****************** This file Copyright 2010-2015 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #ifndef RELATIONSX_H #define RELATIONSX_H /*+ To stop multiple inclusions. +*/ #include #include "types.h" #include "typesx.h" /* Data structures */ /*+ An extended structure containing a single route relation. +*/ struct _RouteRelX { relation_t id; /*+ The relation identifier. +*/ transports_t routes; /*+ The types of transports that that this relation is for. +*/ }; /*+ An extended structure containing a single turn restriction relation. +*/ struct _TurnRelX { relation_t id; /*+ The relation identifier. +*/ way_t from; /*+ The id of the starting way; initially the OSM value, later the SegmentX index. +*/ node_t via; /*+ The id of the via node; initially the OSM value, later the NodeX index. +*/ way_t to; /*+ The id of the ending way; initially the OSM value, later the SegmentX index. +*/ TurnRestriction restriction; /*+ The type of restriction. +*/ transports_t except; /*+ The types of transports that that this relation does not apply to. +*/ }; /*+ A structure containing a set of relations. +*/ struct _RelationsX { /* Route relations */ char *rrfilename; /*+ The name of the intermediate file (for the RouteRelX). +*/ char *rrfilename_tmp; /*+ The name of the temporary file (for the RouteRelX). +*/ int rrfd; /*+ The file descriptor of the open file (for the RouteRelX). +*/ index_t rrnumber; /*+ The number of extended route relations. +*/ index_t rrknumber; /*+ The number of extended route relations kept for next time. +*/ relation_t *rridata; /*+ The extended relation IDs (sorted by ID). +*/ offset_t *rrodata; /*+ The offset of the route relation in the file (used for error log). +*/ /* Turn restriction relations */ char *trfilename; /*+ The name of the intermediate file (for the TurnRelX). +*/ char *trfilename_tmp; /*+ The name of the temporary file (for the TurnRelX). +*/ int trfd; /*+ The file descriptor of the temporary file (for the TurnRelX). +*/ index_t trnumber; /*+ The number of extended turn restriction relations. +*/ index_t trknumber; /*+ The number of extended turn relations kept for next time. +*/ relation_t *tridata; /*+ The extended relation IDs (sorted by ID). +*/ }; /* Functions in relationsx.c */ RelationsX *NewRelationList(int append,int readonly); void FreeRelationList(RelationsX *relationsx,int keep); void AppendRouteRelationList(RelationsX* relationsx,relation_t id, transports_t routes, node_t *nodes,int nnodes, way_t *ways,int nways, relation_t *relations,int nrelations); void AppendTurnRelationList(RelationsX* relationsx,relation_t id, way_t from,way_t to,node_t via, TurnRestriction restriction,transports_t except); void FinishRelationList(RelationsX *relationsx); index_t IndexRouteRelX(RelationsX *relationsx,relation_t id); index_t IndexTurnRelX(RelationsX *relationsx,relation_t id); void SortRelationList(RelationsX *relationsx); void ProcessRouteRelations(RelationsX *relationsx,WaysX *waysx,int keep); void ProcessTurnRelations(RelationsX *relationsx,NodesX *nodesx,SegmentsX *segmentsx,WaysX *waysx,int keep); void RemovePrunedTurnRelations(RelationsX *relationsx,NodesX *nodesx); void SortTurnRelationListGeographically(RelationsX *relationsx,NodesX *nodesx,SegmentsX *segmentsx,int convert); void SaveRelationList(RelationsX* relationsx,const char *filename); #endif /* RELATIONSX_H */ routino-3.0/src/profiles.h 644 233 144 6050 12563633051 11013 0/*************************************** A header file for the profiles. Part of the Routino routing software. ******************/ /****************** This file Copyright 2008-2015 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #ifndef PROFILES_H #define PROFILES_H /*+ To stop multiple inclusions. +*/ #include "types.h" /* Data structures */ /*+ A data structure to hold a transport type profile. +*/ typedef struct _Profile { char *name; /*+ The name of the profile. +*/ /* The parts that are read from the XML file */ Transport transport; /*+ The type of transport. +*/ score_t highway[Highway_Count]; /*+ A floating point preference for travel on the highway. +*/ speed_t speed[Highway_Count]; /*+ The maximum speed on each type of highway. +*/ score_t props[Property_Count]; /*+ A floating point preference for ways with this attribute. +*/ int oneway; /*+ A flag to indicate if one-way restrictions apply. +*/ int turns; /*+ A flag to indicate if turn restrictions apply. +*/ weight_t weight; /*+ The minimum weight of the route. +*/ height_t height; /*+ The minimum height of vehicles on the route. +*/ width_t width; /*+ The minimum width of vehicles on the route. +*/ length_t length; /*+ The minimum length of vehicles on the route. +*/ /* The derived parts */ transports_t allow; /*+ The type of transport expressed as a bitmask. +*/ score_t props_yes[Property_Count]; /*+ A floating point preference for ways with this attribute. +*/ score_t props_no [Property_Count]; /*+ A floating point preference for ways without this attribute. +*/ score_t max_pref; /*+ The maximum preference for any highway type. +*/ speed_t max_speed; /*+ The maximum speed for any highway type. +*/ } Profile; /* Functions in profiles.c */ int ParseXMLProfiles(const char *filename,const char *name,int all); char **GetProfileNames(void); Profile *GetProfile(const char *name); void FreeXMLProfiles(void); int UpdateProfile(Profile *profile,Ways *ways); void PrintProfile(const Profile *profile); void PrintProfilesXML(void); void PrintProfilesJSON(void); void PrintProfilesPerl(void); #endif /* PROFILES_H */ routino-3.0/src/results.h 644 233 144 10704 12272250155 10707 0/*************************************** A header file for the results. Part of the Routino routing software. ******************/ /****************** This file Copyright 2008-2014 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #ifndef RESULTS_H #define RESULTS_H /*+ To stop multiple inclusions. +*/ #include #include "types.h" /* Constants */ /*+ A result is not currently queued. +*/ #define NOT_QUEUED (uint32_t)(0) /* Data structures */ typedef struct _Result Result; /*+ The result for a node. +*/ struct _Result { index_t node; /*+ The node for which this result applies. +*/ index_t segment; /*+ The segmemt used to get to the node for which this result applies. +*/ Result *prev; /*+ The previous result following the best path to get to this node via the segment. +*/ Result *next; /*+ The next result following the best path from this node that was reached via the segment. +*/ score_t score; /*+ The best actual weighted distance or duration score from the start to the node. +*/ score_t sortby; /*+ The best possible weighted distance or duration score from the start to the finish. +*/ uint32_t queued; /*+ The position of this result in the queue. +*/ Result *hashnext; /*+ The next result in the linked list for this hash bin. +*/ }; /*+ A list of results. +*/ typedef struct _Results { uint32_t nbins; /*+ The number of bins in the has table. +*/ uint32_t mask; /*+ A bit mask to select the bottom log2(nbins) bits. +*/ uint32_t number; /*+ The total number of occupied results. +*/ uint8_t ncollisions; /*+ The number of results allowed in each hash bin. +*/ uint8_t *count; /*+ An array of nbins counters of results in each hash bin. +*/ Result **point; /*+ An array of nbins linked lists of results for one hash bin. +*/ uint32_t ndata1; /*+ The size of the first dimension of the 'data' array. +*/ uint32_t ndata2; /*+ The size of the second dimension of the 'data' array. +*/ uint32_t nallocdata1; /*+ The amount of allocated space in the first dimension of the 'data' array. +*/ Result **data; /*+ An array of arrays containing the actual results, the first dimension is reallocated but the second dimension is not. Most importantly pointers into the real data don't change as more space is allocated (since realloc is not being used). +*/ index_t start_node; /*+ The start node. +*/ index_t prev_segment; /*+ The previous segment to get to the start node (if any). +*/ index_t finish_node; /*+ The finish node. +*/ index_t last_segment; /*+ The last segment (to arrive at the finish node). +*/ waypoint_t start_waypoint; /*+ The number of the starting waypoint. +*/ waypoint_t finish_waypoint; /*+ The number of the finish waypoint. +*/ } Results; /* Forward definition for opaque type */ typedef struct _Queue Queue; /* Results functions in results.c */ Results *NewResultsList(uint8_t log2bins); void ResetResultsList(Results *results); void FreeResultsList(Results *results); Result *InsertResult(Results *results,index_t node,index_t segment); Result *FindResult(Results *results,index_t node,index_t segment); Result *FirstResult(Results *results); Result *NextResult(Results *results,Result *result); /* Queue functions in queue.c */ Queue *NewQueueList(uint8_t log2bins); void ResetQueueList(Queue *queue); void FreeQueueList(Queue *queue); void InsertInQueue(Queue *queue,Result *result,score_t score); Result *PopFromQueue(Queue *queue); #endif /* RESULTS_H */ routino-3.0/src/Makefile 644 233 144 17326 12563637327 10521 0# Source code Makefile # # Part of the Routino routing software. # # This file Copyright 2008-2015 Andrew M. Bishop # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # # All configuration is in the top-level Makefile.conf include ../Makefile.conf # Sub-directories and sub-makefiles SUBDIRS=xml test # Compilation targets C=$(wildcard *.c) D=$(wildcard .deps/*.d) EXE=planetsplitter$(.EXE) planetsplitter-slim$(.EXE) router$(.EXE) router-slim$(.EXE) \ filedumperx$(.EXE) filedumper$(.EXE) filedumper-slim$(.EXE) \ router+lib$(.EXE) router+lib-slim$(.EXE) LIB=libroutino.so libroutino-slim.so ifeq ($(HOST),MINGW) LIB+=routino.dll routino-slim.dll LIB+=routino.def routino-slim.def LIB+=routino.lib routino-slim.lib endif INC=routino.h ######## all: all-local for dir in $(SUBDIRS); do \ ( cd $$dir && $(MAKE) $@ ); \ done all-local: $(EXE) $(LIB) ######## PLANETSPLITTER_OBJ=planetsplitter.o \ nodesx.o segmentsx.o waysx.o relationsx.o superx.o prunex.o \ ways.o types.o \ files.o logging.o logerror.o errorlogx.o \ results.o queue.o sorting.o \ xmlparse.o tagging.o \ uncompress.o osmxmlparse.o osmpbfparse.o osmo5mparse.o osmparser.o ifeq ($(HOST),MINGW) PLANETSPLITTER_OBJ+=mman-win32.o endif planetsplitter$(.EXE) : $(PLANETSPLITTER_OBJ) $(LD) $^ -o $@ $(LDFLAGS) ######## PLANETSPLITTER_SLIM_OBJ=planetsplitter-slim.o \ nodesx-slim.o segmentsx-slim.o waysx-slim.o relationsx-slim.o superx-slim.o prunex-slim.o \ ways.o types.o \ files.o logging.o logerror-slim.o errorlogx-slim.o \ results.o queue.o sorting.o \ xmlparse.o tagging.o \ uncompress.o osmxmlparse.o osmpbfparse.o osmo5mparse.o osmparser.o ifeq ($(HOST),MINGW) PLANETSPLITTER_SLIM_OBJ+=mman-win32.o endif planetsplitter-slim$(.EXE) : $(PLANETSPLITTER_SLIM_OBJ) $(LD) $^ -o $@ $(LDFLAGS) ######## ROUTER_OBJ=router.o \ nodes.o segments.o ways.o relations.o types.o fakes.o \ optimiser.o output.o \ files.o logging.o profiles.o xmlparse.o \ results.o queue.o translations.o ifeq ($(HOST),MINGW) ROUTER_OBJ+=mman-win32.o endif router$(.EXE) : $(ROUTER_OBJ) $(LD) $^ -o $@ $(LDFLAGS) ######## ROUTER_SLIM_OBJ=router-slim.o \ nodes-slim.o segments-slim.o ways-slim.o relations-slim.o types.o fakes-slim.o \ optimiser-slim.o output-slim.o \ files.o logging.o profiles.o xmlparse.o \ results.o queue.o translations.o ifeq ($(HOST),MINGW) ROUTER_SLIM_OBJ+=mman-win32.o endif router-slim$(.EXE) : $(ROUTER_SLIM_OBJ) $(LD) $^ -o $@ $(LDFLAGS) ######## FILEDUMPERX_OBJ=filedumperx.o \ files.o logging.o ifeq ($(HOST),MINGW) FILEDUMPERX_OBJ+=mman-win32.o endif filedumperx$(.EXE) : $(FILEDUMPERX_OBJ) $(LD) $^ -o $@ $(LDFLAGS) ######## FILEDUMPER_OBJ=filedumper.o \ nodes.o segments.o ways.o relations.o types.o fakes.o errorlog.o \ visualiser.o \ files.o logging.o xmlparse.o ifeq ($(HOST),MINGW) FILEDUMPER_OBJ+=mman-win32.o endif filedumper$(.EXE) : $(FILEDUMPER_OBJ) $(LD) $^ -o $@ $(LDFLAGS) ######## FILEDUMPER_SLIM_OBJ=filedumper-slim.o \ nodes-slim.o segments-slim.o ways-slim.o relations-slim.o types.o fakes-slim.o errorlog-slim.o \ visualiser-slim.o \ files.o logging.o xmlparse.o ifeq ($(HOST),MINGW) FILEDUMPER_SLIM_OBJ+=mman-win32.o endif filedumper-slim$(.EXE) : $(FILEDUMPER_SLIM_OBJ) $(LD) $^ -o $@ $(LDFLAGS) ######## %.o : %.c @[ -d .deps ] || mkdir .deps $(CC) -c $(CFLAGS) -DSLIM=0 -DROUTINO_DATADIR=\"$(datadir)\" $< -o $@ -MMD -MP -MF $(addprefix .deps/,$(addsuffix .d,$(basename $@))) %-slim.o : %.c @[ -d .deps ] || mkdir .deps $(CC) -c $(CFLAGS) -DSLIM=1 -DROUTINO_DATADIR=\"$(datadir)\" $< -o $@ -MMD -MP -MF $(addprefix .deps/,$(addsuffix .d,$(basename $@))) ######## ROUTER_LIB_OBJ=router+lib.o router+lib$(.EXE) : $(ROUTER_LIB_OBJ) libroutino.so $(LD) $^ -o $@ $(LDFLAGS) $(LDFLAGS_LDSO) router+lib-slim$(.EXE) : $(ROUTER_LIB_OBJ) libroutino-slim.so $(LD) $^ -o $@ $(LDFLAGS) $(LDFLAGS_LDSO) ######## LIBROUTINO_OBJ=routino-lib.o \ nodes-lib.o segments-lib.o ways-lib.o relations-lib.o types-lib.o fakes-lib.o \ optimiser-lib.o output-lib.o \ files-lib.o profiles-lib.o xmlparse-lib.o \ results-lib.o queue-lib.o translations-lib.o ifeq ($(HOST),MINGW) LIBROUTINO_OBJ+=mman-win32.o endif libroutino.so : $(LIBROUTINO_OBJ) $(LD) $^ -o $@ $(LDFLAGS) $(LDFLAGS_LIB) routino.dll : libroutino.so cp $< $@ routino.def : routino-lib.o dlltool -v --output-def $@ $< routino.lib : routino.dll routino.def dlltool -v --dllname routino.dll --def routino.def --output-lib $@ ######## LIBROUTINO_SLIM_OBJ=routino-slim-lib.o \ nodes-slim-lib.o segments-slim-lib.o ways-slim-lib.o relations-slim-lib.o types-lib.o fakes-slim-lib.o \ optimiser-slim-lib.o output-slim-lib.o \ files-lib.o profiles-lib.o xmlparse-lib.o \ results-lib.o queue-lib.o translations-lib.o ifeq ($(HOST),MINGW) LIBROUTINO_SLIM_OBJ+=mman-win32.o endif libroutino-slim.so : $(LIBROUTINO_SLIM_OBJ) $(LD) $^ -o $@ $(LDFLAGS) $(LDFLAGS_LIB) routino-slim.dll : libroutino-slim.so cp $< $@ routino-slim.def : routino-slim-lib.o dlltool -v --output-def $@ $< routino-slim.lib : routino-slim.dll routino-slim.def dlltool -v --dllname routino-slim.dll --def routino-slim.def --output-lib $@ ######## %-lib.o : %.c @[ -d .deps ] || mkdir .deps $(CC) -c $(CFLAGS) $(CFLAGS_LIB) -DSLIM=0 -DLIBROUTINO $< -o $@ -MMD -MP -MF $(addprefix .deps/,$(addsuffix .d,$(basename $@))) %-slim-lib.o : %.c @[ -d .deps ] || mkdir .deps $(CC) -c $(CFLAGS) $(CFLAGS_LIB) -DSLIM=1 -DLIBROUTINO $< -o $@ -MMD -MP -MF $(addprefix .deps/,$(addsuffix .d,$(basename $@))) ######## test: test-local for dir in $(SUBDIRS); do \ ( cd $$dir && $(MAKE) $@ ); \ done test-local: ######## install: install-local for dir in $(SUBDIRS); do \ ( cd $$dir && $(MAKE) $@ ); \ done install-local: all-local @[ -d $(DESTDIR)$(bindir) ] || mkdir -p $(DESTDIR)$(bindir) @for file in $(EXE); do \ if [ -f $$file ]; then \ echo cp $$file $(DESTDIR)$(bindir) ;\ cp -f $$file $(DESTDIR)$(bindir) ;\ fi ;\ done @[ -d $(DESTDIR)$(incdir) ] || mkdir -p $(DESTDIR)$(incdir) @for file in $(INC); do \ if [ -f $$file ]; then \ echo cp $$file $(DESTDIR)$(incdir) ;\ cp -f $$file $(DESTDIR)$(incdir) ;\ fi ;\ done @[ -d $(DESTDIR)$(libdir) ] || mkdir -p $(DESTDIR)$(libdir) @for file in $(LIB); do \ if [ -f $$file ]; then \ echo cp $$file $(DESTDIR)$(libdir) ;\ cp -f $$file $(DESTDIR)$(libdir) ;\ fi ;\ done ######## clean: clean-local for dir in $(SUBDIRS); do \ ( cd $$dir && $(MAKE) $@ ); \ done clean-local: rm -f *~ rm -f *.o rm -f $(EXE) rm -f $(LIB) rm -f $(D) rm -fr .deps rm -f core rm -f *.gcda *.gcno *.gcov gmon.out ######## distclean: distclean-local for dir in $(SUBDIRS); do \ ( cd $$dir && $(MAKE) $@ ); \ done distclean-local: clean-local ######## include $(D) ######## .PHONY:: all test install clean distclean .PHONY:: all-local test-local install-local clean-local distclean-local routino-3.0/src/relations.h 644 233 144 10517 12550223461 11207 0/*************************************** A header file for the relations. Part of the Routino routing software. ******************/ /****************** This file Copyright 2008-2015 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #ifndef RELATIONS_H #define RELATIONS_H /*+ To stop multiple inclusions. +*/ #include #include #include "types.h" #include "cache.h" #include "files.h" #include "profiles.h" /* Data structures */ /*+ A structure containing a single relation. +*/ struct _TurnRelation { index_t from; /*+ The segment that the path comes from. +*/ index_t via; /*+ The node that the path goes via. +*/ index_t to; /*+ The segment that the path goes to. +*/ transports_t except; /*+ The types of transports that that this relation does not apply to. +*/ }; /*+ A structure containing the header from the file. +*/ typedef struct _RelationsFile { index_t trnumber; /*+ The number of turn relations in total. +*/ } RelationsFile; /*+ A structure containing a set of relations (and pointers to mmap file). +*/ struct _Relations { RelationsFile file; /*+ The header data from the file. +*/ #if !SLIM char *data; /*+ The memory mapped data. +*/ TurnRelation *turnrelations; /*+ An array of nodes. +*/ #else int fd; /*+ The file descriptor for the file. +*/ offset_t troffset; /*+ The offset of the turn relations in the file. +*/ TurnRelation cached[2]; /*+ Two cached relations read from the file in slim mode. +*/ TurnRelationCache *cache; /*+ A RAM cache of turn relations read from the file. +*/ #endif index_t via_start; /*+ The first via node in the file. +*/ index_t via_end; /*+ The last via node in the file. +*/ }; /* Functions in relations.c */ Relations *LoadRelationList(const char *filename); void DestroyRelationList(Relations *relations); index_t FindFirstTurnRelation1(Relations *relations,index_t via); index_t FindNextTurnRelation1(Relations *relations,index_t current); index_t FindFirstTurnRelation2(Relations *relations,index_t via,index_t from); index_t FindNextTurnRelation2(Relations *relations,index_t current); int IsTurnAllowed(Relations *relations,index_t index,index_t via,index_t from,index_t to,transports_t transport); /* Macros and inline functions */ #if !SLIM /*+ Return a Relation pointer given a set of relations and an index. +*/ #define LookupTurnRelation(xxx,yyy,ppp) (&(xxx)->turnrelations[yyy]) #else /* Prototypes */ static inline TurnRelation *LookupTurnRelation(Relations *relations,index_t index,int position); CACHE_NEWCACHE_PROTO(TurnRelation) CACHE_DELETECACHE_PROTO(TurnRelation) CACHE_FETCHCACHE_PROTO(TurnRelation) CACHE_INVALIDATECACHE_PROTO(TurnRelation) /* Data type */ CACHE_STRUCTURE(TurnRelation) /* Inline functions */ CACHE_NEWCACHE(TurnRelation) CACHE_DELETECACHE(TurnRelation) CACHE_FETCHCACHE(TurnRelation) CACHE_INVALIDATECACHE(TurnRelation) /*++++++++++++++++++++++++++++++++++++++ Find the Relation information for a particular relation. TurnRelation *LookupTurnRelation Returns a pointer to the cached relation information. Relations *relations The set of relations to use. index_t index The index of the relation. int position The position in the cache to store this result. ++++++++++++++++++++++++++++++++++++++*/ static inline TurnRelation *LookupTurnRelation(Relations *relations,index_t index,int position) { relations->cached[position-1]=*FetchCachedTurnRelation(relations->cache,index,relations->fd,relations->troffset); return(&relations->cached[position-1]); } #endif #endif /* RELATIONS_H */ routino-3.0/src/errorlog.c 644 233 144 12674 12420524666 11052 0/*************************************** Error log data type functions. Part of the Routino routing software. ******************/ /****************** This file Copyright 2013 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #include #include #include "types.h" #include "errorlog.h" #include "files.h" /*++++++++++++++++++++++++++++++++++++++ Load in an error log list from a file. ErrorLogs *LoadErrorLogs Returns the error log list. const char *filename The name of the file to load. ++++++++++++++++++++++++++++++++++++++*/ ErrorLogs *LoadErrorLogs(const char *filename) { ErrorLogs *errorlogs; errorlogs=(ErrorLogs*)malloc(sizeof(ErrorLogs)); #if !SLIM errorlogs->data=MapFile(filename); /* Copy the ErrorLogsFile header structure from the loaded data */ errorlogs->file=*((ErrorLogsFile*)errorlogs->data); /* Set the pointers in the ErrorLogs structure. */ errorlogs->offsets =(index_t* )(errorlogs->data+sizeof(ErrorLogsFile)); errorlogs->errorlogs_geo =(ErrorLog*)(errorlogs->data+sizeof(ErrorLogsFile)+(errorlogs->file.latbins*errorlogs->file.lonbins+1)*sizeof(index_t)); errorlogs->errorlogs_nongeo=(ErrorLog*)(errorlogs->data+sizeof(ErrorLogsFile)+(errorlogs->file.latbins*errorlogs->file.lonbins+1)*sizeof(index_t)+errorlogs->file.number_geo*sizeof(ErrorLog)); errorlogs->strings =(char* )(errorlogs->data+sizeof(ErrorLogsFile)+(errorlogs->file.latbins*errorlogs->file.lonbins+1)*sizeof(index_t)+errorlogs->file.number*sizeof(ErrorLog)); #else errorlogs->fd=SlimMapFile(filename); /* Copy the ErrorLogsFile header structure from the loaded data */ SlimFetch(errorlogs->fd,&errorlogs->file,sizeof(ErrorLogsFile),0); errorlogs->offsetsoffset =sizeof(ErrorLogsFile); errorlogs->errorlogsoffset_geo =sizeof(ErrorLogsFile)+(errorlogs->file.latbins*errorlogs->file.lonbins+1)*sizeof(index_t); errorlogs->errorlogsoffset_nongeo=sizeof(ErrorLogsFile)+(errorlogs->file.latbins*errorlogs->file.lonbins+1)*sizeof(index_t)+errorlogs->file.number_geo*sizeof(ErrorLog); errorlogs->stringsoffset =sizeof(ErrorLogsFile)+(errorlogs->file.latbins*errorlogs->file.lonbins+1)*sizeof(index_t)+errorlogs->file.number*sizeof(ErrorLog); #endif return(errorlogs); } /*++++++++++++++++++++++++++++++++++++++ Destroy the node list. ErrorLogs *errorlogs The node list to destroy. ++++++++++++++++++++++++++++++++++++++*/ void DestroyErrorLogs(ErrorLogs *errorlogs) { #if !SLIM errorlogs->data=UnmapFile(errorlogs->data); #else errorlogs->fd=SlimUnmapFile(errorlogs->fd); #endif free(errorlogs); } /*++++++++++++++++++++++++++++++++++++++ Get the latitude and longitude associated with an error log. ErrorLogs *errorlogs The set of error logs to use. index_t index The errorlog index. ErrorLog *errorlogp A pointer to the error log. double *latitude Returns the latitude. double *longitude Returns the logitude. ++++++++++++++++++++++++++++++++++++++*/ void GetErrorLogLatLong(ErrorLogs *errorlogs,index_t index,ErrorLog *errorlogp,double *latitude,double *longitude) { ll_bin_t latbin,lonbin; ll_bin2_t bin=-1; ll_bin2_t start,end,mid; index_t offset; /* Binary search - search key nearest match below is required. * * # <- start | Check mid and move start or end if it doesn't match * # | * # | A lower bound match is wanted we can set end=mid-1 or * # <- mid | start=mid because we know that mid doesn't match. * # | * # | Eventually either end=start or end=start+1 and one of * # <- end | start or end is the wanted one. */ /* Search for offset */ start=0; end=errorlogs->file.lonbins*errorlogs->file.latbins; do { mid=(start+end)/2; /* Choose mid point */ offset=LookupErrorLogOffset(errorlogs,mid); if(offsetindex) /* Mid point is too high */ end=mid?(mid-1):mid; else /* Mid point is correct */ {bin=mid;break;} } while((end-start)>1); if(bin==-1) { offset=LookupErrorLogOffset(errorlogs,end); if(offset>index) bin=start; else bin=end; } while(bin<=(errorlogs->file.lonbins*errorlogs->file.latbins) && LookupErrorLogOffset(errorlogs,bin)==LookupErrorLogOffset(errorlogs,bin+1)) bin++; latbin=bin%errorlogs->file.latbins; lonbin=bin/errorlogs->file.latbins; /* Return the values */ if(errorlogp==NULL) errorlogp=LookupErrorLog(errorlogs,index,2); *latitude =latlong_to_radians(bin_to_latlong(errorlogs->file.latzero+latbin)+off_to_latlong(errorlogp->latoffset)); *longitude=latlong_to_radians(bin_to_latlong(errorlogs->file.lonzero+lonbin)+off_to_latlong(errorlogp->lonoffset)); } routino-3.0/src/osmpbfparse.c 644 233 144 75300 12563633051 11530 0/*************************************** A simple osm-specific PBF parser where the structure is hard-coded. Part of the Routino routing software. ******************/ /****************** This file Copyright 2012-2015 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #include #if defined(_MSC_VER) #include #include #define read(fd,address,length) _read(fd,address,(unsigned int)(length)) #define ssize_t SSIZE_T #else #include #endif #include #include #include #if defined(USE_GZIP) && USE_GZIP #include #endif #include "osmparser.h" #include "tagging.h" #include "logging.h" /* Inside a BlobHeader message */ #define PBF_VAL_BLOBHEADER_TYPE 1 #define PBF_VAL_BLOBHEADER_SIZE 3 /* Inside a Blob message */ #define PBF_VAL_BLOB_RAW_DATA 1 #define PBF_VAL_BLOB_RAW_SIZE 2 #define PBF_VAL_BLOB_ZLIB_DATA 3 /* Inside a HeaderBlock message */ #define PBF_VAL_REQUIRED_FEATURES 4 #define PBF_VAL_OPTIONAL_FEATURES 5 /* Inside a PrimitiveBlock message */ #define PBF_VAL_STRING_TABLE 1 #define PBF_VAL_PRIMITIVE_GROUP 2 #define PBF_VAL_GRANULARITY 17 #define PBF_VAL_LAT_OFFSET 19 #define PBF_VAL_LON_OFFSET 20 /* Inside a PrimitiveGroup message */ #define PBF_VAL_NODES 1 #define PBF_VAL_DENSE_NODES 2 #define PBF_VAL_WAYS 3 #define PBF_VAL_RELATIONS 4 /* Inside a StringTable message */ #define PBF_VAL_STRING 1 /* Inside a Node message */ #define PBF_VAL_NODE_ID 1 #define PBF_VAL_NODE_KEYS 2 #define PBF_VAL_NODE_VALS 3 #define PBF_VAL_NODE_LAT 8 #define PBF_VAL_NODE_LON 9 /* Inside a DenseNode message */ #define PBF_VAL_DENSE_NODE_ID 1 #define PBF_VAL_DENSE_NODE_LAT 8 #define PBF_VAL_DENSE_NODE_LON 9 #define PBF_VAL_DENSE_NODE_KEYS_VALS 10 /* Inside a Way message */ #define PBF_VAL_WAY_ID 1 #define PBF_VAL_WAY_KEYS 2 #define PBF_VAL_WAY_VALS 3 #define PBF_VAL_WAY_REFS 8 /* Inside a Relation message */ #define PBF_VAL_RELATION_ID 1 #define PBF_VAL_RELATION_KEYS 2 #define PBF_VAL_RELATION_VALS 3 #define PBF_VAL_RELATION_ROLES 8 #define PBF_VAL_RELATION_MEMIDS 9 #define PBF_VAL_RELATION_TYPES 10 /* Errors */ #define PBF_EOF 0 #define PBF_ERROR_UNEXP_EOF 100 #define PBF_ERROR_BLOB_HEADER_LEN 101 #define PBF_ERROR_BLOB_LEN 102 #define PBF_ERROR_NOT_OSM 103 #define PBF_ERROR_BLOB_BOTH 104 #define PBF_ERROR_BLOB_NEITHER 105 #define PBF_ERROR_NO_GZIP 106 #define PBF_ERROR_GZIP_INIT 107 #define PBF_ERROR_GZIP_INFLATE 108 #define PBF_ERROR_GZIP_WRONG_LEN 109 #define PBF_ERROR_GZIP_END 110 #define PBF_ERROR_UNSUPPORTED 111 #define PBF_ERROR_TOO_MANY_GROUPS 112 /* Local parsing variables (re-initialised for each file) */ static uint64_t byteno; static uint64_t nnodes,nways,nrelations; static uint32_t buffer_allocated,zbuffer_allocated; static unsigned char *buffer=NULL,*zbuffer=NULL; static unsigned char *buffer_ptr,*buffer_end; static int string_table_length=0,string_table_allocated=0; static unsigned char **string_table=NULL; static uint32_t *string_table_string_lengths=NULL; static int32_t granularity=100; static int64_t lat_offset=0,lon_offset=0; #define LENGTH_32M (32*1024*1024) /*++++++++++++++++++++++++++++++++++++++ Refill the data buffer and set the pointers. int buffer_refill Return 0 if everything is OK or 1 for EOF. int fd The file descriptor to read from. uint32_t bytes The number of bytes to read. ++++++++++++++++++++++++++++++++++++++*/ static inline int buffer_refill(int fd,uint32_t bytes) { ssize_t n; if(bytes>buffer_allocated) buffer=(unsigned char *)realloc(buffer,buffer_allocated=bytes); byteno+=bytes; buffer_ptr=buffer; buffer_end=buffer; do { n=read(fd,buffer_end,bytes); if(n<=0) return(1); buffer_end+=n; bytes-=n; } while(bytes>0); return(0); } #if defined(USE_GZIP) && USE_GZIP static int uncompress_pbf(unsigned char *data,uint32_t compressed,uint32_t uncompressed); #endif /* USE_GZIP */ static void process_string_table(unsigned char *data,uint32_t length); static void process_primitive_group(unsigned char *data,uint32_t length); static void process_nodes(unsigned char *data,uint32_t length); static void process_dense_nodes(unsigned char *data,uint32_t length); static void process_ways(unsigned char *data,uint32_t length); static void process_relations(unsigned char *data,uint32_t length); /* Macros to simplify the parser (and make it look more like the XML parser) */ #define BEGIN(xx) do{ state=(xx); goto finish_parsing; } while(0) #define BUFFER_CHARS_EOF(xx) do{ if(buffer_refill(fd,(xx))) BEGIN(PBF_EOF); } while(0) #define BUFFER_CHARS(xx) do{ if(buffer_refill(fd,(xx))) BEGIN(PBF_ERROR_UNEXP_EOF); } while(0) /* PBF decoding */ #define PBF_FIELD(xx) (int)(((xx)&0xFFF8)>>3) #define PBF_TYPE(xx) (int)((xx)&0x0007) #define PBF_LATITUDE(xx) (double)(1E-9*(granularity*(xx)+lat_offset)) #define PBF_LONGITUDE(xx) (double)(1E-9*(granularity*(xx)+lon_offset)) /*++++++++++++++++++++++++++++++++++++++ Parse a PBF int32 data value. uint32_t pbf_int32 Returns the integer value. unsigned char **ptr The pointer to read the data from. ++++++++++++++++++++++++++++++++++++++*/ static inline uint32_t pbf_int32(unsigned char **ptr) { uint32_t result=(**ptr)&0x7F; if((**ptr)&0x80) result+=((*++(*ptr))&0x7F)<<7; if((**ptr)&0x80) result+=((*++(*ptr))&0x7F)<<14; if((**ptr)&0x80) result+=((*++(*ptr))&0x7F)<<21; if((**ptr)&0x80) result+=((*++(*ptr))&0x7F)<<28; (*ptr)++; return(result); } /*++++++++++++++++++++++++++++++++++++++ Parse a PBF int64 data value. int64_t pbf_int64 Returns the integer value. unsigned char **ptr The pointer to read the data from. ++++++++++++++++++++++++++++++++++++++*/ static inline int64_t pbf_int64(unsigned char **ptr) { uint64_t result=(**ptr)&0x7F; if((**ptr)&0x80) result+=(uint64_t)((*++(*ptr))&0x7F)<<7; if((**ptr)&0x80) result+=(uint64_t)((*++(*ptr))&0x7F)<<14; if((**ptr)&0x80) result+=(uint64_t)((*++(*ptr))&0x7F)<<21; if((**ptr)&0x80) result+=(uint64_t)((*++(*ptr))&0x7F)<<28; if((**ptr)&0x80) result+=(uint64_t)((*++(*ptr))&0x7F)<<35; if((**ptr)&0x80) result+=(uint64_t)((*++(*ptr))&0x7F)<<42; if((**ptr)&0x80) result+=(uint64_t)((*++(*ptr))&0x7F)<<49; if((**ptr)&0x80) result+=(uint64_t)((*++(*ptr))&0x7F)<<56; if((**ptr)&0x80) result+=(uint64_t)((*++(*ptr))&0x7F)<<63; (*ptr)++; return(result); } /*++++++++++++++++++++++++++++++++++++++ Parse a PBF sint64 data value. int64_t pbf_sint64 Returns the integer value. unsigned char **ptr The pointer to read the data from. ++++++++++++++++++++++++++++++++++++++*/ static inline int64_t pbf_sint64(unsigned char **ptr) { int64_t result=((**ptr)&0x7E)>>1; int sign=(**ptr)&0x01; if((**ptr)&0x80) result+=(int64_t)((*++(*ptr))&0x7F)<<6; if((**ptr)&0x80) result+=(int64_t)((*++(*ptr))&0x7F)<<13; if((**ptr)&0x80) result+=(int64_t)((*++(*ptr))&0x7F)<<20; if((**ptr)&0x80) result+=(int64_t)((*++(*ptr))&0x7F)<<27; if((**ptr)&0x80) result+=(int64_t)((*++(*ptr))&0x7F)<<34; if((**ptr)&0x80) result+=(int64_t)((*++(*ptr))&0x7F)<<41; if((**ptr)&0x80) result+=(int64_t)((*++(*ptr))&0x7F)<<48; if((**ptr)&0x80) result+=(int64_t)((*++(*ptr))&0x7F)<<55; if((**ptr)&0x80) result+=(int64_t)((*++(*ptr))&0x7F)<<62; (*ptr)++; if(sign) result=-result-1; return(result); } /*++++++++++++++++++++++++++++++++++++++ Parse a PBF length delimited data value. unsigned char *pbf_length_delimited Returns a pointer to the start of the data. unsigned char **ptr The pointer to read the data from. uint32_t *length Returns the length of the data. ++++++++++++++++++++++++++++++++++++++*/ static inline unsigned char *pbf_length_delimited(unsigned char **ptr,uint32_t *length) { uint32_t len=pbf_int32(ptr); if(length) *length=len; *ptr+=len; return(*ptr-len); } /*++++++++++++++++++++++++++++++++++++++ Skip any pbf field from a message. unsigned char **ptr The pointer to read the data from. int type The type of the data. ++++++++++++++++++++++++++++++++++++++*/ static inline void pbf_skip(unsigned char **ptr,int type) { uint32_t length; switch(type) { case 0: /* varint */ while((**ptr)&0x80) (*ptr)++; (*ptr)++; break; case 1: /* 64-bit */ *ptr+=8; break; case 2: /* length delimited */ length=pbf_int32(ptr); *ptr+=length; break; case 3: /* deprecated */ break; case 4: /* deprecated */ break; case 5: /* 32-bit */ *ptr+=4; break; } } /*++++++++++++++++++++++++++++++++++++++ Parse the PBF and call the functions for each OSM item as seen. int ParsePBF Returns 0 if OK or something else in case of an error. int fd The file descriptor of the file to parse. ++++++++++++++++++++++++++++++++++++++*/ static int ParsePBF(int fd) { int state; unsigned char *error=NULL; /* Print the initial message */ printf_first("Reading: Bytes=0 Nodes=0 Ways=0 Relations=0"); /* The actual parser. */ byteno=0; nnodes=0,nways=0,nrelations=0; string_table_allocated=16384; string_table_length=0; string_table=(unsigned char **)malloc(string_table_allocated*sizeof(unsigned char *)); string_table_string_lengths=(uint32_t *)malloc(string_table_allocated*sizeof(uint32_t)); zbuffer_allocated=0; zbuffer=NULL; buffer_allocated=65536; buffer=(unsigned char*)malloc(buffer_allocated); buffer_ptr=buffer_end=buffer; while(1) { int32_t blob_header_length=0; int osm_data=0,osm_header=0; int32_t blob_length=0; uint32_t raw_size=0,compressed_size=0,uncompressed_size=0; unsigned char *raw_data=NULL,*zlib_data=NULL; uint32_t length; unsigned char *data; /* ================ Parsing states ================ */ BUFFER_CHARS_EOF(4); blob_header_length=(256*(256*(256*(int)buffer_ptr[0])+(int)buffer_ptr[1])+(int)buffer_ptr[2])+buffer_ptr[3]; buffer_ptr+=4; if(blob_header_length==0 || blob_header_length>LENGTH_32M) BEGIN(PBF_ERROR_BLOB_HEADER_LEN); BUFFER_CHARS(blob_header_length); osm_header=0; osm_data=0; while(buffer_ptrLENGTH_32M) BEGIN(PBF_ERROR_BLOB_LEN); if(!osm_data && !osm_header) BEGIN(PBF_ERROR_NOT_OSM); BUFFER_CHARS(blob_length); while(buffer_ptr(sizeof(primitive_group)/sizeof(primitive_group[0]))) BEGIN(PBF_ERROR_TOO_MANY_GROUPS); break; case PBF_VAL_GRANULARITY: /* int32 */ granularity=pbf_int32(&buffer_ptr); break; case PBF_VAL_LAT_OFFSET: /* int64 */ lat_offset=pbf_int64(&buffer_ptr); break; case PBF_VAL_LON_OFFSET: /* int64 */ lon_offset=pbf_int64(&buffer_ptr); break; default: pbf_skip(&buffer_ptr,PBF_TYPE(fieldtype)); } } if(nprimitive_groups) for(i=0;izbuffer_allocated) zbuffer=(unsigned char *)realloc(zbuffer,zbuffer_allocated=uncompressed); if(inflateInit2(&z,15+32)!=Z_OK) return(PBF_ERROR_GZIP_INIT); z.next_in=data; z.avail_in=compressed; z.next_out=zbuffer; z.avail_out=uncompressed; if(inflate(&z,Z_FINISH)!=Z_STREAM_END) return(PBF_ERROR_GZIP_INFLATE); if(z.avail_out!=0) return(PBF_ERROR_GZIP_WRONG_LEN); if(inflateEnd(&z)!=Z_OK) return(PBF_ERROR_GZIP_END); buffer_ptr=zbuffer; buffer_end=zbuffer+uncompressed; return(0); } #endif /* USE_GZIP */ /*++++++++++++++++++++++++++++++++++++++ Parse a PBF format OSM file (from planet download). int ParsePBFFile Returns 0 if OK or something else in case of an error. int fd The file descriptor of the file to read from. NodesX *OSMNodes The data structure of nodes to fill in. WaysX *OSMWays The data structure of ways to fill in. RelationsX *OSMRelations The data structure of relations to fill in. ++++++++++++++++++++++++++++++++++++++*/ int ParsePBFFile(int fd,NodesX *OSMNodes,WaysX *OSMWays,RelationsX *OSMRelations) { int retval; /* Initialise the parser */ InitialiseParser(OSMNodes,OSMWays,OSMRelations); /* Parse the file */ retval=ParsePBF(fd); /* Cleanup the parser */ CleanupParser(); return(retval); } routino-3.0/src/osmxmlparse.c 644 233 144 53263 12563633053 11567 0/*************************************** OSM XML file parser (either JOSM or planet) Part of the Routino routing software. ******************/ /****************** This file Copyright 2008-2015 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #include #include #include #include #include "osmparser.h" #include "xmlparse.h" #include "tagging.h" #include "logging.h" /* Local parsing variables (re-initialised for each file) */ static int current_mode=MODE_NORMAL; static uint64_t nnodes,nways,nrelations; static TagList *current_tags; /* The XML tag processing function prototypes */ //static int xmlDeclaration_function(const char *_tag_,int _type_,const char *version,const char *encoding); static int osmType_function(const char *_tag_,int _type_,const char *version); static int osmChangeType_function(const char *_tag_,int _type_,const char *version); //static int boundsType_function(const char *_tag_,int _type_); //static int boundType_function(const char *_tag_,int _type_); static int changesetType_function(const char *_tag_,int _type_); static int modifyType_function(const char *_tag_,int _type_); static int createType_function(const char *_tag_,int _type_); static int deleteType_function(const char *_tag_,int _type_); static int nodeType_function(const char *_tag_,int _type_,const char *id,const char *lat,const char *lon); static int wayType_function(const char *_tag_,int _type_,const char *id); static int relationType_function(const char *_tag_,int _type_,const char *id); static int tagType_function(const char *_tag_,int _type_,const char *k,const char *v); static int ndType_function(const char *_tag_,int _type_,const char *ref); static int memberType_function(const char *_tag_,int _type_,const char *type,const char *ref,const char *role); /* The XML tag definitions (forward declarations) */ static const xmltag xmlDeclaration_tag; static const xmltag osmType_tag; static const xmltag osmChangeType_tag; static const xmltag boundsType_tag; static const xmltag boundType_tag; static const xmltag changesetType_tag; static const xmltag modifyType_tag; static const xmltag createType_tag; static const xmltag deleteType_tag; static const xmltag nodeType_tag; static const xmltag wayType_tag; static const xmltag relationType_tag; static const xmltag tagType_tag; static const xmltag ndType_tag; static const xmltag memberType_tag; /* The XML tag definition values */ /*+ The complete set of tags at the top level for OSM. +*/ static const xmltag * const xml_osm_toplevel_tags[]={&xmlDeclaration_tag,&osmType_tag,NULL}; /*+ The complete set of tags at the top level for OSC. +*/ static const xmltag * const xml_osc_toplevel_tags[]={&xmlDeclaration_tag,&osmChangeType_tag,NULL}; /*+ The xmlDeclaration type tag. +*/ static const xmltag xmlDeclaration_tag= {"xml", 2, {"version","encoding"}, NULL, {NULL}}; /*+ The osmType type tag. +*/ static const xmltag osmType_tag= {"osm", 1, {"version"}, osmType_function, {&boundsType_tag,&boundType_tag,&changesetType_tag,&nodeType_tag,&wayType_tag,&relationType_tag,NULL}}; /*+ The osmChangeType type tag. +*/ static const xmltag osmChangeType_tag= {"osmChange", 1, {"version"}, osmChangeType_function, {&boundsType_tag,&modifyType_tag,&createType_tag,&deleteType_tag,NULL}}; /*+ The boundsType type tag. +*/ static const xmltag boundsType_tag= {"bounds", 0, {NULL}, NULL, {NULL}}; /*+ The boundType type tag. +*/ static const xmltag boundType_tag= {"bound", 0, {NULL}, NULL, {NULL}}; /*+ The changesetType type tag. +*/ static const xmltag changesetType_tag= {"changeset", 0, {NULL}, changesetType_function, {&tagType_tag,NULL}}; /*+ The modifyType type tag. +*/ static const xmltag modifyType_tag= {"modify", 0, {NULL}, modifyType_function, {&nodeType_tag,&wayType_tag,&relationType_tag,NULL}}; /*+ The createType type tag. +*/ static const xmltag createType_tag= {"create", 0, {NULL}, createType_function, {&nodeType_tag,&wayType_tag,&relationType_tag,NULL}}; /*+ The deleteType type tag. +*/ static const xmltag deleteType_tag= {"delete", 0, {NULL}, deleteType_function, {&nodeType_tag,&wayType_tag,&relationType_tag,NULL}}; /*+ The nodeType type tag. +*/ static const xmltag nodeType_tag= {"node", 3, {"id","lat","lon"}, nodeType_function, {&tagType_tag,NULL}}; /*+ The wayType type tag. +*/ static const xmltag wayType_tag= {"way", 1, {"id"}, wayType_function, {&ndType_tag,&tagType_tag,NULL}}; /*+ The relationType type tag. +*/ static const xmltag relationType_tag= {"relation", 1, {"id"}, relationType_function, {&memberType_tag,&tagType_tag,NULL}}; /*+ The tagType type tag. +*/ static const xmltag tagType_tag= {"tag", 2, {"k","v"}, tagType_function, {NULL}}; /*+ The ndType type tag. +*/ static const xmltag ndType_tag= {"nd", 1, {"ref"}, ndType_function, {NULL}}; /*+ The memberType type tag. +*/ static const xmltag memberType_tag= {"member", 3, {"type","ref","role"}, memberType_function, {NULL}}; /* The XML tag processing functions */ /*++++++++++++++++++++++++++++++++++++++ The function that is called when the XML declaration is seen int xmlDeclaration_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *version The contents of the 'version' attribute (or NULL if not defined). const char *encoding The contents of the 'encoding' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ //static int xmlDeclaration_function(const char *_tag_,int _type_,const char *version,const char *encoding) //{ // return(0); //} /*++++++++++++++++++++++++++++++++++++++ The function that is called when the osmType XSD type is seen int osmType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *version The contents of the 'version' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int osmType_function(const char *_tag_,int _type_,const char *version) { /* Print the initial message */ if(_type_&XMLPARSE_TAG_START) printf_first("Read: Lines=%"PRIu64" Nodes=%"PRIu64" Ways=%"PRIu64" Relations=%"PRIu64,ParseXML_LineNumber(),nnodes=0,nways=0,nrelations=0); /* Check the tag values */ if(_type_&XMLPARSE_TAG_START) { current_mode=MODE_NORMAL; if(!version || strcmp(version,"0.6")) XMLPARSE_MESSAGE(_tag_,"Invalid value for 'version' (only '0.6' accepted)"); } /* Print the final message */ if(_type_&XMLPARSE_TAG_END) printf_last("Read: Lines=%"PRIu64" Nodes=%"PRIu64" Ways=%"PRIu64" Relations=%"PRIu64,ParseXML_LineNumber(),nnodes,nways,nrelations); return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the osmChangeType XSD type is seen int osmChangeType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *version The contents of the 'version' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int osmChangeType_function(const char *_tag_,int _type_,const char *version) { /* Print the initial message */ if(_type_&XMLPARSE_TAG_START) printf_first("Read: Lines=%"PRIu64" Nodes=%"PRIu64" Ways=%"PRIu64" Relations=%"PRIu64,ParseXML_LineNumber(),nnodes=0,nways=0,nrelations=0); /* Check the tag values */ if(_type_&XMLPARSE_TAG_START) { if(!version || strcmp(version,"0.6")) XMLPARSE_MESSAGE(_tag_,"Invalid value for 'version' (only '0.6' accepted)"); } /* Print the final message */ if(_type_&XMLPARSE_TAG_END) printf_last("Read: Lines=%"PRIu64" Nodes=%"PRIu64" Ways=%"PRIu64" Relations=%"PRIu64,ParseXML_LineNumber(),nnodes,nways,nrelations); return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the boundsType XSD type is seen int boundsType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. ++++++++++++++++++++++++++++++++++++++*/ //static int boundsType_function(const char *_tag_,int _type_) //{ // return(0); //} /*++++++++++++++++++++++++++++++++++++++ The function that is called when the boundType XSD type is seen int boundType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. ++++++++++++++++++++++++++++++++++++++*/ //static int boundType_function(const char *_tag_,int _type_) //{ // return(0); //} /*++++++++++++++++++++++++++++++++++++++ The function that is called when the changesetType XSD type is seen int changesetType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. ++++++++++++++++++++++++++++++++++++++*/ static int changesetType_function(const char *_tag_,int _type_) { current_tags=NULL; return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the modifyType XSD type is seen int modifyType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. ++++++++++++++++++++++++++++++++++++++*/ static int modifyType_function(const char *_tag_,int _type_) { if(_type_&XMLPARSE_TAG_START) current_mode=MODE_MODIFY; return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the createType XSD type is seen int createType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. ++++++++++++++++++++++++++++++++++++++*/ static int createType_function(const char *_tag_,int _type_) { if(_type_&XMLPARSE_TAG_START) current_mode=MODE_CREATE; return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the deleteType XSD type is seen int deleteType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. ++++++++++++++++++++++++++++++++++++++*/ static int deleteType_function(const char *_tag_,int _type_) { if(_type_&XMLPARSE_TAG_START) current_mode=MODE_DELETE; return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the nodeType XSD type is seen int nodeType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *id The contents of the 'id' attribute (or NULL if not defined). const char *lat The contents of the 'lat' attribute (or NULL if not defined). const char *lon The contents of the 'lon' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int nodeType_function(const char *_tag_,int _type_,const char *id,const char *lat,const char *lon) { static int64_t llid; /* static variable to store attributes from tag until tag */ static double latitude,longitude; /* static variable to store attributes from tag until tag */ if(_type_&XMLPARSE_TAG_START) { nnodes++; if(!(nnodes%10000)) printf_middle("Reading: Lines=%"PRIu64" Nodes=%"PRIu64" Ways=%"PRIu64" Relations=%"PRIu64,ParseXML_LineNumber(),nnodes,nways,nrelations); current_tags=NewTagList(); /* Handle the node information */ XMLPARSE_ASSERT_INTEGER(_tag_,id); llid=atoll(id); /* need int64_t conversion */ if(current_mode!=MODE_DELETE) { XMLPARSE_ASSERT_FLOATING(_tag_,lat); latitude =atof(lat); XMLPARSE_ASSERT_FLOATING(_tag_,lon); longitude=atof(lon); } } if(_type_&XMLPARSE_TAG_END) { TagList *result=ApplyNodeTaggingRules(current_tags,llid); ProcessNodeTags(result,llid,latitude,longitude,current_mode); DeleteTagList(current_tags); current_tags=NULL; DeleteTagList(result); } return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the wayType XSD type is seen int wayType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *id The contents of the 'id' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int wayType_function(const char *_tag_,int _type_,const char *id) { static int64_t llid; /* static variable to store attributes from tag until tag */ if(_type_&XMLPARSE_TAG_START) { nways++; if(!(nways%1000)) printf_middle("Reading: Lines=%"PRIu64" Nodes=%"PRIu64" Ways=%"PRIu64" Relations=%"PRIu64,ParseXML_LineNumber(),nnodes,nways,nrelations); current_tags=NewTagList(); AddWayRefs(0); /* Handle the way information */ XMLPARSE_ASSERT_INTEGER(_tag_,id); llid=atoll(id); /* need int64_t conversion */ } if(_type_&XMLPARSE_TAG_END) { TagList *result=ApplyWayTaggingRules(current_tags,llid); ProcessWayTags(result,llid,current_mode); DeleteTagList(current_tags); current_tags=NULL; DeleteTagList(result); } return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the relationType XSD type is seen int relationType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *id The contents of the 'id' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int relationType_function(const char *_tag_,int _type_,const char *id) { static int64_t llid; /* static variable to store attributes from tag until tag */ if(_type_&XMLPARSE_TAG_START) { nrelations++; if(!(nrelations%1000)) printf_middle("Reading: Lines=%"PRIu64" Nodes=%"PRIu64" Ways=%"PRIu64" Relations=%"PRIu64,ParseXML_LineNumber(),nnodes,nways,nrelations); current_tags=NewTagList(); AddRelationRefs(0,0,0,NULL); /* Handle the relation information */ XMLPARSE_ASSERT_INTEGER(_tag_,id); llid=atoll(id); /* need int64_t conversion */ } if(_type_&XMLPARSE_TAG_END) { TagList *result=ApplyRelationTaggingRules(current_tags,llid); ProcessRelationTags(result,llid,current_mode); DeleteTagList(current_tags); current_tags=NULL; DeleteTagList(result); } return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the tagType XSD type is seen int tagType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *k The contents of the 'k' attribute (or NULL if not defined). const char *v The contents of the 'v' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int tagType_function(const char *_tag_,int _type_,const char *k,const char *v) { if(_type_&XMLPARSE_TAG_START && current_tags) { XMLPARSE_ASSERT_STRING(_tag_,k); XMLPARSE_ASSERT_STRING(_tag_,v); AppendTag(current_tags,k,v); } return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the ndType XSD type is seen int ndType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *ref The contents of the 'ref' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int ndType_function(const char *_tag_,int _type_,const char *ref) { if(_type_&XMLPARSE_TAG_START) { int64_t llid; XMLPARSE_ASSERT_INTEGER(_tag_,ref); llid=atoll(ref); /* need int64_t conversion */ AddWayRefs(llid); } return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the memberType XSD type is seen int memberType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *type The contents of the 'type' attribute (or NULL if not defined). const char *ref The contents of the 'ref' attribute (or NULL if not defined). const char *role The contents of the 'role' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int memberType_function(const char *_tag_,int _type_,const char *type,const char *ref,const char *role) { if(_type_&XMLPARSE_TAG_START) { int64_t llid; XMLPARSE_ASSERT_STRING(_tag_,type); XMLPARSE_ASSERT_INTEGER(_tag_,ref); llid=atoll(ref); /* need int64_t conversion */ if(!strcmp(type,"node")) AddRelationRefs(llid,0,0,role); else if(!strcmp(type,"way")) AddRelationRefs(0,llid,0,role); else if(!strcmp(type,"relation")) AddRelationRefs(0,0,llid,role); } return(0); } /*++++++++++++++++++++++++++++++++++++++ Parse an OSM XML file (from JOSM or planet download). int ParseOSMFile Returns 0 if OK or something else in case of an error. int fd The file descriptor of the file to read from. NodesX *OSMNodes The data structure of nodes to fill in. WaysX *OSMWays The data structure of ways to fill in. RelationsX *OSMRelations The data structure of relations to fill in. ++++++++++++++++++++++++++++++++++++++*/ int ParseOSMFile(int fd,NodesX *OSMNodes,WaysX *OSMWays,RelationsX *OSMRelations) { int retval; /* Initialise the parser */ InitialiseParser(OSMNodes,OSMWays,OSMRelations); /* Parse the file */ nnodes=0,nways=0,nrelations=0; current_tags=NULL; retval=ParseXML(fd,xml_osm_toplevel_tags,XMLPARSE_UNKNOWN_ATTR_IGNORE); /* Cleanup the parser */ CleanupParser(); return(retval); } /*++++++++++++++++++++++++++++++++++++++ Parse an OSC XML file (from planet download). int ParseOSCFile Returns 0 if OK or something else in case of an error. int fd The file descriptor of the file to read from. NodesX *OSMNodes The data structure of nodes to fill in. WaysX *OSMWays The data structure of ways to fill in. RelationsX *OSMRelations The data structure of relations to fill in. ++++++++++++++++++++++++++++++++++++++*/ int ParseOSCFile(int fd,NodesX *OSMNodes,WaysX *OSMWays,RelationsX *OSMRelations) { int retval; /* Initialise the parser */ InitialiseParser(OSMNodes,OSMWays,OSMRelations); /* Parse the file */ nnodes=0,nways=0,nrelations=0; current_tags=NULL; retval=ParseXML(fd,xml_osc_toplevel_tags,XMLPARSE_UNKNOWN_ATTR_IGNORE); /* Cleanup the parser */ CleanupParser(); return(retval); } routino-3.0/src/optimiser.c 644 233 144 162354 12563633051 11250 0/*************************************** Routing optimiser. Part of the Routino routing software. ******************/ /****************** This file Copyright 2008-2015 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #include "types.h" #include "nodes.h" #include "segments.h" #include "ways.h" #include "relations.h" #include "logging.h" #include "functions.h" #include "fakes.h" #include "results.h" #ifdef LIBROUTINO #include "routino.h" /*+ The function to be called to report on the routing progress. +*/ extern Routino_ProgressFunc progress_func; /*+ The current state of the routing progress. +*/ extern double progress_value; /*+ Set when the progress callback returns false in the routing function. +*/ extern int progress_abort; #endif /*+ To help when debugging +*/ #define DEBUG 0 /* Global variables */ /*+ The option not to print any progress information. +*/ extern int option_quiet; /*+ The option to calculate the quickest route insted of the shortest. +*/ extern int option_quickest; /* Local functions */ static Results *FindNormalRoute(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,Profile *profile,index_t start_node,index_t prev_segment,index_t finish_node); static Results *FindMiddleRoute(Nodes *supernodes,Segments *supersegments,Ways *superways,Relations *relations,Profile *profile,Results *begin,Results *end); static index_t FindSuperSegment(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,Profile *profile,index_t finish_node,index_t finish_segment); static Results *FindSuperRoute(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,Profile *profile,index_t start_node,index_t finish_node); static Results *FindStartRoutes(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,Profile *profile,index_t start_node,index_t prev_segment,index_t finish_node); static Results *FindFinishRoutes(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,Profile *profile,index_t finish_node); static Results *CombineRoutes(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,Profile *profile,Results *begin,Results *middle,Results *end); static void FixForwardRoute(Results *results,Result *finish_result); /*++++++++++++++++++++++++++++++++++++++ Find a complete route from a specified node to another node. Results *CalculateRoute Returns a set of results. Nodes *nodes The set of nodes to use. Segments *segments The set of segments to use. Ways *ways The set of ways to use. Relations *relations The set of relations to use. Profile *profile The profile containing the transport type, speeds and allowed highways. index_t start_node The start node. index_t prev_segment The previous segment before the start node. index_t finish_node The finish node. int start_waypoint The starting waypoint. int finish_waypoint The finish waypoint. ++++++++++++++++++++++++++++++++++++++*/ Results *CalculateRoute(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,Profile *profile, index_t start_node,index_t prev_segment,index_t finish_node, int start_waypoint,int finish_waypoint) { Results *complete=NULL; /* A special case if the first and last nodes are the same */ if(start_node==finish_node) { index_t fake_segment; Result *result1,*result2; complete=NewResultsList(8); if(prev_segment==NO_SEGMENT) { double lat,lon; distance_t distmin,dist1,dist2; index_t node1,node2; GetLatLong(nodes,start_node,NULL,&lat,&lon); prev_segment=FindClosestSegment(nodes,segments,ways,lat,lon,1,profile,&distmin,&node1,&node2,&dist1,&dist2); } fake_segment=CreateFakeNullSegment(segments,start_node,prev_segment,finish_waypoint); result1=InsertResult(complete,start_node,prev_segment); result2=InsertResult(complete,finish_node,fake_segment); result1->next=result2; complete->start_node=start_node; complete->prev_segment=prev_segment; complete->finish_node=finish_node; complete->last_segment=fake_segment; } else { Results *begin; /* Calculate the beginning of the route */ begin=FindStartRoutes(nodes,segments,ways,relations,profile,start_node,prev_segment,finish_node); if(begin) { /* Check if the end of the route was reached */ if(begin->finish_node!=NO_NODE) complete=begin; } else { if(prev_segment!=NO_SEGMENT) { /* Try again but allow a U-turn at the start waypoint - this solves the problem of facing a dead-end that contains no super-nodes. */ prev_segment=NO_SEGMENT; begin=FindStartRoutes(nodes,segments,ways,relations,profile,start_node,prev_segment,finish_node); } if(begin) { /* Check if the end of the route was reached */ if(begin->finish_node!=NO_NODE) complete=begin; } else { #ifndef LIBROUTINO fprintf(stderr,"Error: Cannot find initial section of route compatible with profile.\n"); #endif return(NULL); } } /* Calculate the rest of the route */ if(!complete) { Results *middle,*end; /* Calculate the end of the route */ end=FindFinishRoutes(nodes,segments,ways,relations,profile,finish_node); if(!end) { #ifndef LIBROUTINO fprintf(stderr,"Error: Cannot find final section of route compatible with profile.\n"); #endif return(NULL); } /* Calculate the middle of the route */ middle=FindMiddleRoute(nodes,segments,ways,relations,profile,begin,end); if(!middle && prev_segment!=NO_SEGMENT) { /* Try again but allow a U-turn at the start waypoint - this solves the problem of facing a dead-end that contains some super-nodes. */ FreeResultsList(begin); begin=FindStartRoutes(nodes,segments,ways,relations,profile,start_node,NO_SEGMENT,finish_node); if(begin) middle=FindMiddleRoute(nodes,segments,ways,relations,profile,begin,end); } if(!middle) { #ifndef LIBROUTINO fprintf(stderr,"Error: Cannot find super-route compatible with profile.\n"); #endif return(NULL); } complete=CombineRoutes(nodes,segments,ways,relations,profile,begin,middle,end); if(!complete) { #ifndef LIBROUTINO fprintf(stderr,"Error: Cannot create combined route following super-route.\n"); #endif return(NULL); } FreeResultsList(begin); FreeResultsList(middle); FreeResultsList(end); } } complete->start_waypoint=start_waypoint; complete->finish_waypoint=finish_waypoint; #if DEBUG Result *r=FindResult(complete,complete->start_node,complete->prev_segment); printf("The final route is:\n"); while(r) { printf(" node=%"Pindex_t" segment=%"Pindex_t" score=%f\n",r->node,r->segment,r->score); r=r->next; } #endif return(complete); } /*++++++++++++++++++++++++++++++++++++++ Find the optimum route between two nodes not passing through a super-node. Results *FindNormalRoute Returns a set of results. Nodes *nodes The set of nodes to use. Segments *segments The set of segments to use. Ways *ways The set of ways to use. Relations *relations The set of relations to use. Profile *profile The profile containing the transport type, speeds and allowed highways. index_t start_node The start node. index_t prev_segment The previous segment before the start node. index_t finish_node The finish node. ++++++++++++++++++++++++++++++++++++++*/ static Results *FindNormalRoute(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,Profile *profile,index_t start_node,index_t prev_segment,index_t finish_node) { Results *results; Queue *queue; score_t finish_score; double finish_lat,finish_lon; Result *finish_result; Result *result1,*result2; int force_uturn=0; #if DEBUG printf(" FindNormalRoute(...,start_node=%"Pindex_t" prev_segment=%"Pindex_t" finish_node=%"Pindex_t")\n",start_node,prev_segment,finish_node); #endif /* Set up the finish conditions */ finish_score=INF_SCORE; finish_result=NULL; if(IsFakeNode(finish_node)) GetFakeLatLong(finish_node,&finish_lat,&finish_lon); else GetLatLong(nodes,finish_node,NULL,&finish_lat,&finish_lon); /* Create the list of results and insert the first node into the queue */ results=NewResultsList(8); queue=NewQueueList(8); results->start_node=start_node; results->prev_segment=prev_segment; result1=InsertResult(results,results->start_node,results->prev_segment); InsertInQueue(queue,result1,0); /* Check for barrier at start waypoint - must perform U-turn */ if(prev_segment!=NO_SEGMENT && !IsFakeNode(start_node)) { Node *startp=LookupNode(nodes,start_node,1); if(!(startp->allow&profile->allow)) force_uturn=1; } /* Loop across all nodes in the queue */ while((result1=PopFromQueue(queue))) { Node *node1p=NULL; Segment *segmentp; index_t node1,seg1,seg1r; index_t turnrelation=NO_RELATION; /* score must be better than current best score */ if(result1->score>=finish_score) continue; node1=result1->node; seg1=result1->segment; if(IsFakeSegment(seg1)) seg1r=IndexRealSegment(seg1); else seg1r=seg1; if(!IsFakeNode(node1)) node1p=LookupNode(nodes,node1,1); /* lookup if a turn restriction applies */ if(profile->turns && node1p && IsTurnRestrictedNode(node1p)) turnrelation=FindFirstTurnRelation2(relations,node1,seg1r); /* Loop across all segments */ if(IsFakeNode(node1)) segmentp=FirstFakeSegment(node1); else segmentp=FirstSegment(segments,node1p,1); while(segmentp) { Node *node2p=NULL; Way *wayp; index_t node2,seg2,seg2r; score_t segment_pref,segment_score,cumulative_score; int i; node2=OtherNode(segmentp,node1); /* need this here because we use node2 at the end of the loop */ /* must be a normal segment */ if(!IsNormalSegment(segmentp)) goto endloop; /* must obey one-way restrictions (unless profile allows) */ if(profile->oneway && IsOnewayTo(segmentp,node1)) { if(profile->allow!=Transports_Bicycle) goto endloop; wayp=LookupWay(ways,segmentp->way,1); if(!(wayp->type&Highway_CycleBothWays)) goto endloop; } if(IsFakeNode(node1) || IsFakeNode(node2)) { seg2 =IndexFakeSegment(segmentp); seg2r=IndexRealSegment(seg2); } else { seg2 =IndexSegment(segments,segmentp); seg2r=seg2; } /* must perform U-turn in special cases */ if(force_uturn && node1==results->start_node) { if(seg2r!=result1->segment) goto endloop; } else /* must not perform U-turn (unless profile allows) */ if(profile->turns && (seg1==seg2 || seg1==seg2r || seg1r==seg2 || (seg1r==seg2r && IsFakeUTurn(seg1,seg2)))) goto endloop; /* must obey turn relations */ if(turnrelation!=NO_RELATION && !IsTurnAllowed(relations,turnrelation,node1,seg1r,seg2r,profile->allow)) goto endloop; if(!IsFakeNode(node2)) node2p=LookupNode(nodes,node2,2); /* must not pass over super-node */ if(node2!=finish_node && node2p && IsSuperNode(node2p)) goto endloop; wayp=LookupWay(ways,segmentp->way,1); /* mode of transport must be allowed on the highway */ if(!(wayp->allow&profile->allow)) goto endloop; /* must obey weight restriction (if exists) */ if(wayp->weight && wayp->weightweight) goto endloop; /* must obey height/width/length restriction (if exist) */ if((wayp->height && wayp->heightheight) || (wayp->width && wayp->width width ) || (wayp->length && wayp->lengthlength)) goto endloop; segment_pref=profile->highway[HIGHWAY(wayp->type)]; /* highway preferences must allow this highway */ if(segment_pref==0) goto endloop; for(i=1;ifile.props & PROPERTIES(i)) { if(wayp->props & PROPERTIES(i)) segment_pref*=profile->props_yes[i]; else segment_pref*=profile->props_no[i]; } /* profile preferences must allow this highway */ if(segment_pref==0) goto endloop; /* mode of transport must be allowed through node2 unless it is the final node */ if(node2p && node2!=finish_node && !(node2p->allow&profile->allow)) goto endloop; /* calculate the score for the segment and cumulative */ if(option_quickest==0) segment_score=(score_t)DISTANCE(segmentp->distance)/segment_pref; else segment_score=(score_t)Duration(segmentp,wayp,profile)/segment_pref; cumulative_score=result1->score+segment_score; /* score must be better than current best score */ if(cumulative_score>=finish_score) goto endloop; /* find whether the node/segment combination already exists */ result2=FindResult(results,node2,seg2); if(!result2) /* New end node/segment combination */ { result2=InsertResult(results,node2,seg2); result2->prev=result1; result2->score=cumulative_score; } else if(cumulative_scorescore) /* New score for end node/segment combination is better */ { result2->prev=result1; result2->score=cumulative_score; result2->segment=seg2; } else goto endloop; if(node2==finish_node) { finish_score=cumulative_score; finish_result=result2; results->finish_node=node2; results->last_segment=seg2; } else InsertInQueue(queue,result2,result2->score); endloop: if(IsFakeNode(node1)) segmentp=NextFakeSegment(segmentp,node1); else if(IsFakeNode(node2)) segmentp=NULL; /* cannot call NextSegment() with a fake segment */ else { segmentp=NextSegment(segments,segmentp,node1); if(!segmentp && IsFakeNode(finish_node)) segmentp=ExtraFakeSegment(node1,finish_node); } } } FreeQueueList(queue); /* Check it worked */ if(!finish_result) { #if DEBUG printf(" Failed\n"); #endif FreeResultsList(results); return(NULL); } FixForwardRoute(results,finish_result); #if DEBUG Result *r=FindResult(results,results->start_node,results->prev_segment); printf(" -------- normal route (between super-nodes)\n"); while(r) { printf(" node=%"Pindex_t" segment=%"Pindex_t" score=%f%s%s%s\n",r->node,r->segment,r->score, (IsSuperNode(LookupNode(nodes,r->node,1))?" (super)":""), (r->node==results->start_node&&r->segment==results->prev_segment?" (start)":""), (r->node==results->finish_node?" (finish)":"")); r=r->next; } #endif return(results); } /*++++++++++++++++++++++++++++++++++++++ Find the optimum route between two nodes where the start and end are a set of pre/post-routed super-nodes. Results *FindMiddleRoute Returns a set of results. Nodes *nodes The set of nodes to use. Segments *segments The set of segments to use. Ways *ways The set of ways to use. Relations *relations The set of relations to use. Profile *profile The profile containing the transport type, speeds and allowed highways. Results *begin The initial portion of the route. Results *end The final portion of the route. ++++++++++++++++++++++++++++++++++++++*/ static Results *FindMiddleRoute(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,Profile *profile,Results *begin,Results *end) { Results *results; Queue *queue; Result *finish_result; score_t finish_score; double finish_lat,finish_lon; Result *result1,*result2,*result3,*result4; int force_uturn=0; #ifdef LIBROUTINO int loopcount=0; #endif #if DEBUG printf(" FindMiddleRoute(...,[begin has %d nodes],[end has %d nodes])\n",begin->number,end->number); #endif #if !DEBUG && !defined(LIBROUTINO) if(!option_quiet) printf_first("Finding Middle Route: Super-Nodes checked = 0"); #endif /* Set up the finish conditions */ finish_score=INF_SCORE; finish_result=NULL; if(IsFakeNode(end->finish_node)) GetFakeLatLong(end->finish_node,&finish_lat,&finish_lon); else GetLatLong(nodes,end->finish_node,NULL,&finish_lat,&finish_lon); /* Create the list of results and insert the first node into the queue */ results=NewResultsList(20); queue=NewQueueList(12); results->start_node=begin->start_node; results->prev_segment=begin->prev_segment; if(begin->number==1 && begin->prev_segment!=NO_SEGMENT) { index_t superseg=FindSuperSegment(nodes,segments,ways,relations,profile,begin->start_node,begin->prev_segment); results->prev_segment=superseg; } result1=InsertResult(results,results->start_node,results->prev_segment); /* Insert the finish points of the beginning part of the path into the queue, translating the segments into super-segments. */ result3=FirstResult(begin); while(result3) { if((results->start_node!=result3->node || results->prev_segment!=result3->segment) && !IsFakeNode(result3->node) && IsSuperNode(LookupNode(nodes,result3->node,3))) { Result *result5=result1; index_t superseg=FindSuperSegment(nodes,segments,ways,relations,profile,result3->node,result3->segment); if(superseg!=result3->segment) { result5=InsertResult(results,result3->node,result3->segment); result5->score=result3->score; result5->prev=result1; } if(!FindResult(results,result3->node,superseg)) { result2=InsertResult(results,result3->node,superseg); result2->prev=result5; result2->score=result3->score; InsertInQueue(queue,result2,result3->score); if((result4=FindResult(end,result2->node,result2->segment))) { if((result2->score+result4->score)score+result4->score; finish_result=result2; } } } } result3=NextResult(begin,result3); } if(begin->number==1) InsertInQueue(queue,result1,0); /* Check for barrier at start waypoint - must perform U-turn */ if(begin->number==1 && results->prev_segment!=NO_SEGMENT) { Node *startp=LookupNode(nodes,result1->node,1); if(!(startp->allow&profile->allow)) force_uturn=1; } /* Loop across all nodes in the queue */ while((result1=PopFromQueue(queue))) { Node *node1p; Segment *segmentp; index_t node1,seg1; index_t turnrelation=NO_RELATION; /* score must be better than current best score */ if(result1->score>=finish_score) continue; node1=result1->node; seg1=result1->segment; node1p=LookupNode(nodes,node1,1); /* node1 cannot be a fake node (must be a super-node) */ /* lookup if a turn restriction applies */ if(profile->turns && IsTurnRestrictedNode(node1p)) /* node1 cannot be a fake node (must be a super-node) */ turnrelation=FindFirstTurnRelation2(relations,node1,seg1); /* Loop across all segments */ segmentp=FirstSegment(segments,node1p,1); /* node1 cannot be a fake node (must be a super-node) */ while(segmentp) { Node *node2p; Way *wayp; index_t node2,seg2; score_t segment_pref,segment_score,cumulative_score; int i; /* must be a super segment */ if(!IsSuperSegment(segmentp)) goto endloop; /* must obey one-way restrictions (unless profile allows) */ if(profile->oneway && IsOnewayTo(segmentp,node1)) { if(profile->allow!=Transports_Bicycle) goto endloop; wayp=LookupWay(ways,segmentp->way,1); if(!(wayp->type&Highway_CycleBothWays)) goto endloop; } seg2=IndexSegment(segments,segmentp); /* segment cannot be a fake segment (must be a super-segment) */ /* must perform U-turn in special cases */ if(force_uturn && node1==results->start_node) { if(seg2!=result1->segment) goto endloop; } else /* must not perform U-turn */ if(seg1==seg2) /* No fake segments, applies to all profiles */ goto endloop; /* must obey turn relations */ if(turnrelation!=NO_RELATION && !IsTurnAllowed(relations,turnrelation,node1,seg1,seg2,profile->allow)) goto endloop; wayp=LookupWay(ways,segmentp->way,1); /* mode of transport must be allowed on the highway */ if(!(wayp->allow&profile->allow)) goto endloop; /* must obey weight restriction (if exists) */ if(wayp->weight && wayp->weightweight) goto endloop; /* must obey height/width/length restriction (if exist) */ if((wayp->height && wayp->heightheight) || (wayp->width && wayp->width width ) || (wayp->length && wayp->lengthlength)) goto endloop; segment_pref=profile->highway[HIGHWAY(wayp->type)]; /* highway preferences must allow this highway */ if(segment_pref==0) goto endloop; for(i=1;ifile.props & PROPERTIES(i)) { if(wayp->props & PROPERTIES(i)) segment_pref*=profile->props_yes[i]; else segment_pref*=profile->props_no[i]; } /* profile preferences must allow this highway */ if(segment_pref==0) goto endloop; node2=OtherNode(segmentp,node1); node2p=LookupNode(nodes,node2,2); /* node2 cannot be a fake node (must be a super-node) */ /* mode of transport must be allowed through node2 unless it is the final node */ if(node2!=end->finish_node && !(node2p->allow&profile->allow)) goto endloop; /* calculate the score for the segment and cumulative */ if(option_quickest==0) segment_score=(score_t)DISTANCE(segmentp->distance)/segment_pref; else segment_score=(score_t)Duration(segmentp,wayp,profile)/segment_pref; cumulative_score=result1->score+segment_score; /* score must be better than current best score */ if(cumulative_score>=finish_score) goto endloop; /* find whether the node/segment combination already exists */ result2=FindResult(results,node2,seg2); if(!result2) /* New end node/segment pair */ { result2=InsertResult(results,node2,seg2); result2->prev=result1; result2->score=cumulative_score; } else if(cumulative_scorescore) /* New end node/segment pair is better */ { result2->prev=result1; result2->score=cumulative_score; } else goto endloop; if((result3=FindResult(end,node2,seg2))) { if((result2->score+result3->score)score+result3->score; finish_result=result2; results->finish_node=node2; results->last_segment=seg2; } } else { double lat,lon; distance_t direct; score_t potential_score; GetLatLong(nodes,node2,node2p,&lat,&lon); /* node2 cannot be a fake node (must be a super-node) */ direct=Distance(lat,lon,finish_lat,finish_lon); if(option_quickest==0) potential_score=result2->score+(score_t)direct/profile->max_pref; else potential_score=result2->score+(score_t)distance_speed_to_duration(direct,profile->max_speed)/profile->max_pref; if(potential_scorenumber); #endif FreeResultsList(results); return(NULL); } FixForwardRoute(results,finish_result); #if DEBUG Result *r=FindResult(results,results->start_node,results->prev_segment); printf(" -------- middle route (start route then via super-nodes/segments)\n"); while(r) { printf(" node=%"Pindex_t" segment=%"Pindex_t" score=%f%s%s%s\n",r->node,r->segment,r->score, (IsSuperNode(LookupNode(nodes,r->node,1))?" (super)":""), (r->node==results->start_node&&r->segment==results->prev_segment?" (start)":""), (r->node==results->finish_node?" (finish)":"")); r=r->next; } #endif #if !DEBUG && !defined(LIBROUTINO) if(!option_quiet) printf_last("Found Middle Route: Super-Nodes checked = %d",results->number); #endif return(results); } /*++++++++++++++++++++++++++++++++++++++ Find the super-segment that represents the route that contains a particular segment. index_t FindSuperSegment Returns the index of the super-segment. Nodes *nodes The set of nodes to use. Segments *segments The set of segments to use. Ways *ways The set of ways to use. Relations *relations The set of relations to use. Profile *profile The profile containing the transport type, speeds and allowed highways. index_t finish_node The super-node that the route ends at. index_t finish_segment The segment that the route ends with. ++++++++++++++++++++++++++++++++++++++*/ static index_t FindSuperSegment(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,Profile *profile,index_t finish_node,index_t finish_segment) { Node *supernodep; Segment *supersegmentp; if(IsFakeSegment(finish_segment)) finish_segment=IndexRealSegment(finish_segment); supernodep=LookupNode(nodes,finish_node,3); /* finish_node cannot be a fake node (must be a super-node) */ supersegmentp=LookupSegment(segments,finish_segment,4); /* finish_segment cannot be a fake segment. */ if(IsSuperSegment(supersegmentp)) return(finish_segment); /* Loop across all segments */ supersegmentp=FirstSegment(segments,supernodep,4); /* supernode cannot be a fake node (must be a super-node) */ while(supersegmentp) { if(IsSuperSegment(supersegmentp)) { Results *results; Result *result; index_t start_node; start_node=OtherNode(supersegmentp,finish_node); results=FindSuperRoute(nodes,segments,ways,relations,profile,start_node,finish_node); if(!results) continue; result=FindResult(results,finish_node,finish_segment); if(result && (distance_t)result->score==DISTANCE(supersegmentp->distance)) { FreeResultsList(results); return(IndexSegment(segments,supersegmentp)); } if(results) FreeResultsList(results); } supersegmentp=NextSegment(segments,supersegmentp,finish_node); /* finish_node cannot be a fake node (must be a super-node) */ } return(finish_segment); } /*++++++++++++++++++++++++++++++++++++++ Find the shortest route between two super-nodes using only normal nodes. This is effectively the same function as is used in superx.c when finding super-segments initially. Results *FindSuperRoute Returns a set of results. Nodes *nodes The set of nodes to use. Segments *segments The set of segments to use. Ways *ways The set of ways to use. Relations *relations The set of relations to use. Profile *profile The profile containing the transport type, speeds and allowed highways. index_t start_node The start node. index_t finish_node The finish node. ++++++++++++++++++++++++++++++++++++++*/ static Results *FindSuperRoute(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,Profile *profile,index_t start_node,index_t finish_node) { Results *results; Queue *queue; Result *result1,*result2; #if DEBUG printf(" FindSuperRoute(...,start_node=%"Pindex_t" finish_node=%"Pindex_t")\n",start_node,finish_node); #endif /* Create the list of results and insert the first node into the queue */ results=NewResultsList(8); queue=NewQueueList(8); results->start_node=start_node; results->prev_segment=NO_SEGMENT; result1=InsertResult(results,results->start_node,results->prev_segment); InsertInQueue(queue,result1,0); /* Loop across all nodes in the queue */ while((result1=PopFromQueue(queue))) { Node *node1p=NULL; Segment *segmentp; index_t node1,seg1; node1=result1->node; seg1=result1->segment; node1p=LookupNode(nodes,node1,3); /* node1 cannot be a fake node */ /* Loop across all segments */ segmentp=FirstSegment(segments,node1p,3); /* node1 cannot be a fake node */ while(segmentp) { Node *node2p=NULL; index_t node2,seg2; score_t cumulative_score; /* must be a normal segment */ if(!IsNormalSegment(segmentp)) goto endloop; /* must obey one-way restrictions */ if(IsOnewayTo(segmentp,node1)) { Way *wayp; if(profile->allow!=Transports_Bicycle) goto endloop; wayp=LookupWay(ways,segmentp->way,2); if(!(wayp->type&Highway_CycleBothWays)) goto endloop; } seg2=IndexSegment(segments,segmentp); /* must not perform U-turn */ if(seg1==seg2) goto endloop; node2=OtherNode(segmentp,node1); node2p=LookupNode(nodes,node2,4); /* node2 cannot be a fake node */ /* must not pass over super-node */ if(node2!=finish_node && IsSuperNode(node2p)) goto endloop; /* Specifically looking for the shortest route to emulate superx.c */ cumulative_score=result1->score+(score_t)DISTANCE(segmentp->distance); result2=FindResult(results,node2,seg2); if(!result2) /* New end node/segment combination */ { result2=InsertResult(results,node2,seg2); result2->prev=result1; result2->score=cumulative_score; } else if(cumulative_scorescore) /* New score for end node/segment combination is better */ { result2->prev=result1; result2->segment=seg2; result2->score=cumulative_score; } else goto endloop; /* don't route beyond a super-node. */ if(!IsSuperNode(node2p)) InsertInQueue(queue,result2,result2->score); endloop: segmentp=NextSegment(segments,segmentp,node1); } } FreeQueueList(queue); #if DEBUG Result *s=FirstResult(results); while(s) { if(s->node==finish_node) { Result *r=FindResult(results,s->node,s->segment); printf(" -------- super-route\n"); while(r) { printf(" node=%"Pindex_t" segment=%"Pindex_t" score=%f%s%s%s\n",r->node,r->segment,r->score, (IsSuperNode(LookupNode(nodes,r->node,1))?" (super)":""), (r->node==start_node?" (start)":""), (r->node==finish_node?" (finish)":"")); r=r->prev; } } s=NextResult(results,s); } #endif return(results); } /*++++++++++++++++++++++++++++++++++++++ Find all routes from a specified node to any super-node. Results *FindStartRoutes Returns a set of results. Nodes *nodes The set of nodes to use. Segments *segments The set of segments to use. Ways *ways The set of ways to use. Relations *relations The set of relations to use. Profile *profile The profile containing the transport type, speeds and allowed highways. index_t start_node The start node. index_t prev_segment The previous segment before the start node. index_t finish_node The finish node. ++++++++++++++++++++++++++++++++++++++*/ static Results *FindStartRoutes(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,Profile *profile,index_t start_node,index_t prev_segment,index_t finish_node) { Results *results; Queue *queue,*superqueue; Result *result1,*result2; Result *finish_result=NULL; score_t finish_score=INF_SCORE; int nsuper=0,force_uturn=0; #if DEBUG printf(" FindStartRoutes(...,start_node=%"Pindex_t" prev_segment=%"Pindex_t" finish_node=%"Pindex_t")\n",start_node,prev_segment,finish_node); #endif #if !DEBUG && !defined(LIBROUTINO) if(!option_quiet) printf_first("Finding Start Route: Nodes checked = 0"); #endif /* Create the list of results and insert the first node into the queue */ results=NewResultsList(8); queue=NewQueueList(8); superqueue=NewQueueList(8); results->start_node=start_node; results->prev_segment=prev_segment; result1=InsertResult(results,results->start_node,results->prev_segment); InsertInQueue(queue,result1,0); /* Check for barrier at start waypoint - must perform U-turn */ if(prev_segment!=NO_SEGMENT && !IsFakeNode(start_node)) { Node *startp=LookupNode(nodes,start_node,1); if(!(startp->allow&profile->allow)) force_uturn=1; } /* Loop across all nodes in the queue */ while((result1=PopFromQueue(queue))) { Node *node1p=NULL; Segment *segmentp; index_t node1,seg1,seg1r; index_t turnrelation=NO_RELATION; /* score must be better than current best score */ if(result1->score>=finish_score) continue; node1=result1->node; seg1=result1->segment; if(IsFakeSegment(seg1)) seg1r=IndexRealSegment(seg1); else seg1r=seg1; if(!IsFakeNode(node1)) node1p=LookupNode(nodes,node1,1); /* lookup if a turn restriction applies */ if(profile->turns && node1p && IsTurnRestrictedNode(node1p)) turnrelation=FindFirstTurnRelation2(relations,node1,seg1r); /* Loop across all segments */ if(IsFakeNode(node1)) segmentp=FirstFakeSegment(node1); else segmentp=FirstSegment(segments,node1p,1); while(segmentp) { Node *node2p=NULL; Way *wayp; index_t node2,seg2,seg2r; score_t segment_pref,segment_score,cumulative_score; int i; node2=OtherNode(segmentp,node1); /* need this here because we use node2 at the end of the loop */ /* must be a normal segment */ if(!IsNormalSegment(segmentp)) goto endloop; /* must obey one-way restrictions (unless profile allows) */ if(profile->oneway && IsOnewayTo(segmentp,node1)) { if(profile->allow!=Transports_Bicycle) goto endloop; wayp=LookupWay(ways,segmentp->way,1); if(!(wayp->type&Highway_CycleBothWays)) goto endloop; } if(IsFakeNode(node1) || IsFakeNode(node2)) { seg2 =IndexFakeSegment(segmentp); seg2r=IndexRealSegment(seg2); } else { seg2 =IndexSegment(segments,segmentp); seg2r=seg2; } /* must perform U-turn in special cases */ if(node1==start_node && force_uturn) { if(seg2r!=result1->segment) goto endloop; } else /* must not perform U-turn (unless profile allows) */ if(profile->turns && (seg1==seg2 || seg1==seg2r || seg1r==seg2 || (seg1r==seg2r && IsFakeUTurn(seg1,seg2)))) goto endloop; /* must obey turn relations */ if(turnrelation!=NO_RELATION && !IsTurnAllowed(relations,turnrelation,node1,seg1r,seg2r,profile->allow)) goto endloop; wayp=LookupWay(ways,segmentp->way,1); /* mode of transport must be allowed on the highway */ if(!(wayp->allow&profile->allow)) goto endloop; /* must obey weight restriction (if exists) */ if(wayp->weight && wayp->weightweight) goto endloop; /* must obey height/width/length restriction (if exists) */ if((wayp->height && wayp->heightheight) || (wayp->width && wayp->width width ) || (wayp->length && wayp->lengthlength)) goto endloop; segment_pref=profile->highway[HIGHWAY(wayp->type)]; /* highway preferences must allow this highway */ if(segment_pref==0) goto endloop; for(i=1;ifile.props & PROPERTIES(i)) { if(wayp->props & PROPERTIES(i)) segment_pref*=profile->props_yes[i]; else segment_pref*=profile->props_no[i]; } /* profile preferences must allow this highway */ if(segment_pref==0) goto endloop; if(!IsFakeNode(node2)) node2p=LookupNode(nodes,node2,2); /* mode of transport must be allowed through node2 unless it is the final node */ if(node2p && node2!=finish_node && !(node2p->allow&profile->allow)) goto endloop; /* calculate the score for the segment and cumulative */ if(option_quickest==0) segment_score=(score_t)DISTANCE(segmentp->distance)/segment_pref; else segment_score=(score_t)Duration(segmentp,wayp,profile)/segment_pref; /* prefer not to follow two fake segments when one would do (special case) */ if(IsFakeSegment(seg2)) segment_score*=1.01f; cumulative_score=result1->score+segment_score; /* score must be better than current best score */ if(cumulative_score>=finish_score) goto endloop; /* find whether the node/segment combination already exists */ result2=FindResult(results,node2,seg2); if(!result2) /* New end node/segment combination */ { result2=InsertResult(results,node2,seg2); result2->prev=result1; result2->score=cumulative_score; if(node2p && IsSuperNode(node2p)) nsuper++; } else if(cumulative_scorescore) /* New score for end node/segment combination is better */ { result2->prev=result1; result2->score=cumulative_score; } else goto endloop; if(node2==finish_node) { if(!finish_result) { Result *result3; while((result3=PopFromQueue(superqueue))) InsertInQueue(queue,result3,result3->score); } if(cumulative_scorefinish_node=node2; results->last_segment=seg2; } } if(finish_result || (node2p && !IsSuperNode(node2p))) InsertInQueue(queue,result2,result2->score); else if(node2p && IsSuperNode(node2p)) InsertInQueue(superqueue,result2,result2->score); endloop: if(IsFakeNode(node1)) segmentp=NextFakeSegment(segmentp,node1); else if(IsFakeNode(node2)) segmentp=NULL; /* cannot call NextSegment() with a fake segment */ else { segmentp=NextSegment(segments,segmentp,node1); if(!segmentp && IsFakeNode(finish_node)) segmentp=ExtraFakeSegment(node1,finish_node); } } } FreeQueueList(queue); FreeQueueList(superqueue); /* Check it worked */ if(results->number==1 || (nsuper==0 && !finish_result)) { #if DEBUG printf(" Failed (%d results, %d super)\n",results->number,nsuper); #endif #if !DEBUG && !defined(LIBROUTINO) if(!option_quiet) printf_last("Found Start Route: Nodes checked = %d - Fail",results->number); #endif FreeResultsList(results); return(NULL); } /* If we found the finish node then make a proper route */ if(finish_result) FixForwardRoute(results,finish_result); #if DEBUG Result *s=FirstResult(results); while(s) { if(s->node==finish_node || (!IsFakeNode(s->node) && IsSuperNode(LookupNode(nodes,s->node,1)))) { Result *r=FindResult(results,s->node,s->segment); printf(" -------- possible start route\n"); while(r) { printf(" node=%"Pindex_t" segment=%"Pindex_t" score=%f%s%s%s\n",r->node,r->segment,r->score, (IsSuperNode(LookupNode(nodes,r->node,1))?" (super)":""), (r->node==start_node&&r->segment==prev_segment?" (start)":""), (r->node==finish_node?" (finish)":"")); r=r->prev; } } s=NextResult(results,s); } #endif #if !DEBUG && !defined(LIBROUTINO) if(!option_quiet) printf_last("Found Start Route: Nodes checked = %d",results->number); #endif return(results); } /*++++++++++++++++++++++++++++++++++++++ Find all routes from any super-node to a specific node (by working backwards from the specific node to all super-nodes). Results *FindFinishRoutes Returns a set of results. Nodes *nodes The set of nodes to use. Segments *segments The set of segments to use. Ways *ways The set of ways to use. Relations *relations The set of relations to use. Profile *profile The profile containing the transport type, speeds and allowed highways. index_t finish_node The finishing node. ++++++++++++++++++++++++++++++++++++++*/ static Results *FindFinishRoutes(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,Profile *profile,index_t finish_node) { Results *results,*results2; Queue *queue; Result *result1,*result2,*result3; #if DEBUG printf(" FindFinishRoutes(...,finish_node=%"Pindex_t")\n",finish_node); #endif #if !DEBUG && !defined(LIBROUTINO) if(!option_quiet) printf_first("Finding Finish Route: Nodes checked = 0"); #endif /* Create the results and insert the finish node into the queue */ results=NewResultsList(8); queue=NewQueueList(8); results->finish_node=finish_node; result1=InsertResult(results,finish_node,NO_SEGMENT); InsertInQueue(queue,result1,0); /* Loop across all nodes in the queue */ while((result1=PopFromQueue(queue))) { Node *node1p=NULL; Segment *segmentp; index_t node1,seg1,seg1r; index_t turnrelation=NO_RELATION; node1=result1->node; seg1=result1->segment; if(seg1!=NO_SEGMENT && IsFakeSegment(seg1)) seg1r=IndexRealSegment(seg1); else seg1r=seg1; if(!IsFakeNode(node1)) node1p=LookupNode(nodes,node1,1); /* lookup if a turn restriction applies */ if(profile->turns && node1p && IsTurnRestrictedNode(node1p)) turnrelation=FindFirstTurnRelation1(relations,node1); /* working backwards => turn relation sort order doesn't help */ /* Loop across all segments */ if(IsFakeNode(node1)) segmentp=FirstFakeSegment(node1); else segmentp=FirstSegment(segments,node1p,1); while(segmentp) { Node *node2p=NULL; Way *wayp; index_t node2,seg2,seg2r; score_t segment_pref,segment_score,cumulative_score; int i; /* must be a normal segment unless node1 is a super-node (see below). */ if((IsFakeNode(node1) || !IsSuperNode(node1p)) && !IsNormalSegment(segmentp)) goto endloop; /* must be a super segment if node1 is a super-node to give starting super-segment for finding middle route. */ if((!IsFakeNode(node1) && IsSuperNode(node1p)) && !IsSuperSegment(segmentp)) goto endloop; /* must obey one-way restrictions (unless profile allows) */ if(profile->oneway && IsOnewayFrom(segmentp,node1)) /* working backwards => disallow oneway *from* node1 */ { if(profile->allow!=Transports_Bicycle) goto endloop; wayp=LookupWay(ways,segmentp->way,1); if(!(wayp->type&Highway_CycleBothWays)) goto endloop; } node2=OtherNode(segmentp,node1); if(IsFakeNode(node1) || IsFakeNode(node2)) { seg2 =IndexFakeSegment(segmentp); seg2r=IndexRealSegment(seg2); } else { seg2 =IndexSegment(segments,segmentp); seg2r=seg2; } /* must not perform U-turn (unless profile allows) */ if(profile->turns && seg1!=NO_SEGMENT) { if(IsFakeNode(node1) || !IsSuperNode(node1p)) { if(seg1==seg2 || seg1==seg2r || seg1r==seg2 || (seg1r==seg2r && IsFakeUTurn(seg1,seg2))) goto endloop; } else { index_t superseg=FindSuperSegment(nodes,segments,ways,relations,profile,node1,seg1); if(seg2==superseg) goto endloop; } } /* must obey turn relations */ if(turnrelation!=NO_RELATION && seg1!=NO_SEGMENT) { index_t turnrelation2=FindFirstTurnRelation2(relations,node1,seg2r); /* node2 -> node1 -> result1->next->node */ if(turnrelation2!=NO_RELATION && !IsTurnAllowed(relations,turnrelation2,node1,seg2r,seg1r,profile->allow)) goto endloop; } wayp=LookupWay(ways,segmentp->way,1); /* mode of transport must be allowed on the highway */ if(!(wayp->allow&profile->allow)) goto endloop; /* must obey weight restriction (if exists) */ if(wayp->weight && wayp->weightweight) goto endloop; /* must obey height/width/length restriction (if exist) */ if((wayp->height && wayp->heightheight) || (wayp->width && wayp->width width ) || (wayp->length && wayp->lengthlength)) goto endloop; segment_pref=profile->highway[HIGHWAY(wayp->type)]; /* highway preferences must allow this highway */ if(segment_pref==0) goto endloop; for(i=1;ifile.props & PROPERTIES(i)) { if(wayp->props & PROPERTIES(i)) segment_pref*=profile->props_yes[i]; else segment_pref*=profile->props_no[i]; } /* profile preferences must allow this highway */ if(segment_pref==0) goto endloop; if(!IsFakeNode(node2)) node2p=LookupNode(nodes,node2,2); /* mode of transport must be allowed through node2 */ if(node2p && !(node2p->allow&profile->allow)) goto endloop; /* calculate the score for the segment and cumulative */ if(option_quickest==0) segment_score=(score_t)DISTANCE(segmentp->distance)/segment_pref; else segment_score=(score_t)Duration(segmentp,wayp,profile)/segment_pref; /* prefer not to follow two fake segments when one would do (special case) */ if(IsFakeSegment(seg1)) segment_score*=1.01f; cumulative_score=result1->score+segment_score; /* find whether the node/segment combination already exists */ result2=FindResult(results,node2,seg2); if(!result2) /* New end node */ { result2=InsertResult(results,node2,seg2); result2->next=result1; /* working backwards */ result2->score=cumulative_score; } else if(cumulative_scorescore) /* New end node is better */ { result2->next=result1; /* working backwards */ result2->score=cumulative_score; } else goto endloop; if(IsFakeNode(node1) || !IsSuperNode(node1p)) InsertInQueue(queue,result2,result2->score); endloop: if(IsFakeNode(node1)) segmentp=NextFakeSegment(segmentp,node1); else segmentp=NextSegment(segments,segmentp,node1); } } FreeQueueList(queue); /* Check it worked */ if(results->number==1) { #if DEBUG printf(" Failed\n"); #endif #if !DEBUG && !defined(LIBROUTINO) if(!option_quiet) printf_last("Found Finish Route: Nodes checked = %d - Fail",results->number); #endif FreeResultsList(results); return(NULL); } /* Create a results structure with the node at the end of the segment opposite the start */ results2=NewResultsList(8); results2->finish_node=results->finish_node; result3=FirstResult(results); while(result3) { if(result3->next) { result2=InsertResult(results2,result3->next->node,result3->segment); result2->score=result3->next->score; } result3=NextResult(results,result3); } /* Fix up the result->next pointers */ result3=FirstResult(results); while(result3) { if(result3->next && result3->next->next) { result1=FindResult(results2,result3->next->node,result3->segment); result2=FindResult(results2,result3->next->next->node,result3->next->segment); result1->next=result2; } result3=NextResult(results,result3); } #if DEBUG Result *s=FirstResult(results2); while(s) { if(!IsFakeNode(s->node) && IsSuperNode(LookupNode(nodes,s->node,1))) { Result *r=FindResult(results2,s->node,s->segment); printf(" -------- possible finish route\n"); while(r) { printf(" node=%"Pindex_t" segment=%"Pindex_t" score=%f%s%s\n",r->node,r->segment,r->score, (IsSuperNode(LookupNode(nodes,r->node,1))?" (super)":""), (r->node==finish_node?" (finish)":"")); r=r->next; } } s=NextResult(results2,s); } #endif #if !DEBUG && !defined(LIBROUTINO) if(!option_quiet) printf_last("Found Finish Route: Nodes checked = %d",results->number); #endif FreeResultsList(results); return(results2); } /*++++++++++++++++++++++++++++++++++++++ Create an optimum route given the set of super-nodes to follow. Results *CombineRoutes Returns the results from joining the super-nodes. Nodes *nodes The set of nodes to use. Segments *segments The set of segments to use. Ways *ways The set of ways to use. Relations *relations The set of relations to use. Profile *profile The profile containing the transport type, speeds and allowed highways. Results *begin The set of results for the start of the route. Results *middle The set of results from the super-node route. Results *end The set of results for the end of the route. ++++++++++++++++++++++++++++++++++++++*/ static Results *CombineRoutes(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,Profile *profile,Results *begin,Results *middle,Results *end) { Result *midres,*comres; Results *combined; #if DEBUG printf(" CombineRoutes(...,[begin has %d nodes],[middle has %d nodes],[end has %d nodes])\n",begin->number,middle->number,end->number); #endif #if !DEBUG && !defined(LIBROUTINO) if(!option_quiet) printf_first("Finding Combined Route: Nodes = 0"); #endif combined=NewResultsList(10); combined->start_node=begin->start_node; combined->prev_segment=begin->prev_segment; /* Insert the start point */ midres=FindResult(middle,middle->start_node,middle->prev_segment); comres=InsertResult(combined,combined->start_node,combined->prev_segment); /* Insert the start of the route */ if(begin->number>1 && midres->next) { Result *begres; midres=FindResult(middle,midres->next->node,midres->next->segment); begres=FindResult(begin,midres->node,midres->segment); FixForwardRoute(begin,begres); if(midres->next && midres->next->node==midres->node) midres=midres->next; begres=FindResult(begin,begin->start_node,begin->prev_segment); begres=begres->next; do { Result *comres2; comres2=InsertResult(combined,begres->node,begres->segment); comres2->score=begres->score; comres2->prev=comres; begres=begres->next; comres=comres2; } while(begres); } /* Sort out the combined route */ while(midres->next) { Results *results=FindNormalRoute(nodes,segments,ways,relations,profile,comres->node,comres->segment,midres->next->node); Result *result; if(!results) { #if !DEBUG && !defined(LIBROUTINO) if(!option_quiet) printf_last("Found Combined Route: Nodes = %d - Fail",combined->number); #endif FreeResultsList(combined); return(NULL); } result=FindResult(results,midres->node,comres->segment); result=result->next; /* * midres midres->next * = = * ---*----------------------------------* = middle * * ---*----.----.----.----.----.----.----* = results * = * result * * ---*----.----.----.----.----.----.----* = combined * = = * comres comres2 */ do { Result *comres2; comres2=InsertResult(combined,result->node,result->segment); comres2->score=midres->score+result->score; comres2->prev=comres; result=result->next; comres=comres2; } while(result); FreeResultsList(results); midres=midres->next; } /* Insert the end of the route */ if(end->number>1) { Result *endres=FindResult(end,midres->node,midres->segment); while(endres->next) { Result *comres2; comres2=InsertResult(combined,endres->next->node,endres->next->segment); comres2->score=comres->score+(endres->score-endres->next->score); comres2->prev=comres; endres=endres->next; comres=comres2; } } /* Turn the route round */ combined->finish_node=comres->node; combined->last_segment=comres->segment; FixForwardRoute(combined,comres); #if DEBUG Result *r=FindResult(combined,combined->start_node,combined->prev_segment); printf(" -------- combined route (end-to-end)\n"); while(r) { printf(" node=%"Pindex_t" segment=%"Pindex_t" score=%f%s%s%s\n",r->node,r->segment,r->score, (IsSuperNode(LookupNode(nodes,r->node,1))?" (super)":""), (r->node==combined->start_node&&r->segment==combined->prev_segment?" (start)":""), (r->node==combined->finish_node?" (finish)":"")); r=r->next; } #endif #if !DEBUG && !defined(LIBROUTINO) if(!option_quiet) printf_last("Found Combined Route: Nodes = %d",combined->number); #endif return(combined); } /*++++++++++++++++++++++++++++++++++++++ Fix the forward route (i.e. setup next pointers for forward path from prev nodes on reverse path). Results *results The set of results to update. Result *finish_result The result for the finish point. ++++++++++++++++++++++++++++++++++++++*/ static void FixForwardRoute(Results *results,Result *finish_result) { Result *result2=finish_result; /* Erase the old route if there is one */ if(results->finish_node!=NO_NODE) { Result *result1=FirstResult(results); while(result1) { result1->next=NULL; result1=NextResult(results,result1); } } /* Create the forward links for the optimum path */ do { Result *result1; if(result2->prev) { index_t node1=result2->prev->node; index_t seg1=result2->prev->segment; result1=FindResult(results,node1,seg1); #ifndef LIBROUTINO logassert(!result1->next,"Unable to reverse route through results (report a bug)"); /* Bugs elsewhere can lead to infinite loop here. */ #endif result1->next=result2; result2=result1; } else result2=NULL; } while(result2); results->finish_node=finish_result->node; results->last_segment=finish_result->segment; } routino-3.0/src/sorting.h 644 233 144 4227 12524714232 10657 0/*************************************** Header file for sorting function prototypes Part of the Routino routing software. ******************/ /****************** This file Copyright 2008-2012 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #ifndef SORTING_H #define SORTING_H /*+ To stop multiple inclusions. +*/ #include #include "types.h" /* Constants */ /*+ The type, size and alignment of variable to store the variable length +*/ #define FILESORT_VARINT unsigned short #define FILESORT_VARSIZE sizeof(FILESORT_VARINT) #define FILESORT_VARALIGN sizeof(void*) /* Macros */ /*+ A macro to use as a last resort in the comparison function to preserve on the output the input order of items that compare equally. +*/ #define FILESORT_PRESERVE_ORDER(a,b) ( ((a)<(b)) ? -1 : +1) /* Functions in sorting.c */ index_t filesort_fixed(int fd_in,int fd_out,size_t itemsize,int (*pre_sort_function)(void*,index_t), int (*compare_function)(const void*,const void*), int (*post_sort_function)(void*,index_t)); index_t filesort_vary(int fd_in,int fd_out,int (*pre_sort_function)(void*,index_t), int (*compare_function)(const void*,const void*), int (*post_sort_function)(void*,index_t)); void filesort_heapsort(void **datap,size_t nitems,int(*compare)(const void*, const void*)); #endif /* SORTING_H */ routino-3.0/src/segments.c 644 233 144 24067 12563633052 11041 0/*************************************** Segment data type functions. Part of the Routino routing software. ******************/ /****************** This file Copyright 2008-2015 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #include #include #include "types.h" #include "nodes.h" #include "segments.h" #include "ways.h" #include "fakes.h" #include "files.h" #include "profiles.h" /*++++++++++++++++++++++++++++++++++++++ Load in a segment list from a file. Segments *LoadSegmentList Returns the segment list that has just been loaded. const char *filename The name of the file to load. ++++++++++++++++++++++++++++++++++++++*/ Segments *LoadSegmentList(const char *filename) { Segments *segments; segments=(Segments*)malloc(sizeof(Segments)); #if !SLIM segments->data=MapFile(filename); /* Copy the SegmentsFile structure from the loaded data */ segments->file=*((SegmentsFile*)segments->data); /* Set the pointers in the Segments structure. */ segments->segments=(Segment*)(segments->data+sizeof(SegmentsFile)); #else segments->fd=SlimMapFile(filename); /* Copy the SegmentsFile header structure from the loaded data */ SlimFetch(segments->fd,&segments->file,sizeof(SegmentsFile),0); segments->cache=NewSegmentCache(); #ifndef LIBROUTINO log_malloc(segments->cache,sizeof(*segments->cache)); #endif #endif return(segments); } /*++++++++++++++++++++++++++++++++++++++ Destroy the segment list. Segments *segments The segment list to destroy. ++++++++++++++++++++++++++++++++++++++*/ void DestroySegmentList(Segments *segments) { #if !SLIM segments->data=UnmapFile(segments->data); #else segments->fd=SlimUnmapFile(segments->fd); #ifndef LIBROUTINO log_free(segments->cache); #endif DeleteSegmentCache(segments->cache); #endif free(segments); } /*++++++++++++++++++++++++++++++++++++++ Find the closest segment from a specified node heading in a particular direction and optionally profile. index_t FindClosestSegmentHeading Returns the closest heading segment index. Nodes *nodes The set of nodes to use. Segments *segments The set of segments to use. Ways *ways The set of ways to use. index_t node1 The node to start from. double heading The desired heading from the node. Profile *profile The profile of the mode of transport (or NULL). ++++++++++++++++++++++++++++++++++++++*/ index_t FindClosestSegmentHeading(Nodes *nodes,Segments *segments,Ways *ways,index_t node1,double heading,Profile *profile) { Segment *segmentp; index_t best_seg=NO_SEGMENT; double best_difference=360; if(IsFakeNode(node1)) segmentp=FirstFakeSegment(node1); else { Node *nodep=LookupNode(nodes,node1,3); segmentp=FirstSegment(segments,nodep,1); } while(segmentp) { Way *wayp; index_t node2,seg2; double bearing,difference; node2=OtherNode(segmentp,node1); /* need this here because we use node2 at the end of the loop */ if(!IsNormalSegment(segmentp)) goto endloop; if(IsFakeNode(node1) || IsFakeNode(node2)) seg2=IndexFakeSegment(segmentp); else seg2=IndexSegment(segments,segmentp); wayp=LookupWay(ways,segmentp->way,1); if(!(wayp->allow&profile->allow)) goto endloop; if(profile->oneway && IsOnewayFrom(segmentp,node1)) { if(profile->allow!=Transports_Bicycle) goto endloop; if(!(wayp->type&Highway_CycleBothWays)) goto endloop; } bearing=BearingAngle(nodes,segmentp,node1); difference=(heading-bearing); if(difference<-180) difference+=360; if(difference> 180) difference-=360; if(difference<0) difference=-difference; if(differencespeed; speed_t speed2=profile->speed[HIGHWAY(wayp->type)]; distance_t distance=DISTANCE(segmentp->distance); if(speed1==0) { if(speed2==0) return(hours_to_duration(10)); else return distance_speed_to_duration(distance,speed2); } else /* if(speed1!=0) */ { if(speed2==0) return distance_speed_to_duration(distance,speed1); else if(speed1<=speed2) return distance_speed_to_duration(distance,speed1); else return distance_speed_to_duration(distance,speed2); } } /*++++++++++++++++++++++++++++++++++++++ Calculate the angle to turn at a junction from segment1 to segment2 at node. double TurnAngle Returns a value in the range -180 to +180 indicating the angle to turn. Nodes *nodes The set of nodes to use. Segment *segment1p The current segment. Segment *segment2p The next segment. index_t node The node at which they join. Straight ahead is zero, turning to the right is positive (e.g. +90 degrees) and turning to the left is negative (e.g. -90 degrees). Angles are calculated using flat Cartesian lat/long grid approximation (after scaling longitude due to latitude). ++++++++++++++++++++++++++++++++++++++*/ double TurnAngle(Nodes *nodes,Segment *segment1p,Segment *segment2p,index_t node) { double lat1,latm,lat2; double lon1,lonm,lon2; double angle1,angle2,angle; index_t node1,node2; node1=OtherNode(segment1p,node); node2=OtherNode(segment2p,node); if(IsFakeNode(node1)) GetFakeLatLong(node1,&lat1,&lon1); else GetLatLong(nodes,node1,NULL,&lat1,&lon1); if(IsFakeNode(node)) GetFakeLatLong(node,&latm,&lonm); else GetLatLong(nodes,node,NULL,&latm,&lonm); if(IsFakeNode(node2)) GetFakeLatLong(node2,&lat2,&lon2); else GetLatLong(nodes,node2,NULL,&lat2,&lon2); angle1=atan2((lonm-lon1)*cos(latm),(latm-lat1)); angle2=atan2((lon2-lonm)*cos(latm),(lat2-latm)); angle=angle2-angle1; angle=radians_to_degrees(angle); if(angle<-180) angle+=360; if(angle> 180) angle-=360; return(angle); } /*++++++++++++++++++++++++++++++++++++++ Calculate the bearing of a segment when heading to the given node. double BearingAngle Returns a value in the range 0 to 359 indicating the bearing. Nodes *nodes The set of nodes to use. Segment *segmentp The segment. index_t node The node to finish. Angles are calculated using flat Cartesian lat/long grid approximation (after scaling longitude due to latitude). ++++++++++++++++++++++++++++++++++++++*/ double BearingAngle(Nodes *nodes,Segment *segmentp,index_t node) { double lat1,lat2; double lon1,lon2; double angle; index_t node1,node2; node1=node; node2=OtherNode(segmentp,node); if(IsFakeNode(node1)) GetFakeLatLong(node1,&lat1,&lon1); else GetLatLong(nodes,node1,NULL,&lat1,&lon1); if(IsFakeNode(node2)) GetFakeLatLong(node2,&lat2,&lon2); else GetLatLong(nodes,node2,NULL,&lat2,&lon2); angle=atan2((lat2-lat1),(lon2-lon1)*cos(lat1)); angle=radians_to_degrees(angle); angle=270-angle; if(angle< 0) angle+=360; if(angle>360) angle-=360; return(angle); } routino-3.0/src/osmparser.h 644 233 144 4264 12311642544 11206 0/*************************************** Header file for OSM parser function prototype. Part of the Routino routing software. ******************/ /****************** This file Copyright 2008-2014 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #ifndef OSMPARSER_H #define OSMPARSER_H /*+ To stop multiple inclusions. +*/ #include #include "typesx.h" #include "xmlparse.h" #include "tagging.h" /* Constants */ #define MODE_NORMAL 3 #define MODE_CREATE 2 #define MODE_MODIFY 1 #define MODE_DELETE -1 /* Functions in osmxmlparse.c */ int ParseOSMFile(int fd,NodesX *OSMNodes,WaysX *OSMWays,RelationsX *OSMRelations); int ParseOSCFile(int fd,NodesX *OSMNodes,WaysX *OSMWays,RelationsX *OSMRelations); /* Functions in osmpbfparse.c */ int ParsePBFFile(int fd,NodesX *OSMNodes,WaysX *OSMWays,RelationsX *OSMRelations); /* Functions in osmo5mparse.c */ int ParseO5MFile(int fd,NodesX *OSMNodes,WaysX *OSMWays,RelationsX *OSMRelations); int ParseO5CFile(int fd,NodesX *OSMNodes,WaysX *OSMWays,RelationsX *OSMRelations); /* Functions in osmparser.c */ void InitialiseParser(NodesX *OSMNodes,WaysX *OSMWays,RelationsX *OSMRelations); void CleanupParser(void); void AddWayRefs(int64_t node_id); void AddRelationRefs(int64_t node_id,int64_t way_id,int64_t relation_id,const char *role); void ProcessNodeTags(TagList *tags,int64_t node_id,double latitude,double longitude,int mode); void ProcessWayTags(TagList *tags,int64_t way_id, int mode); void ProcessRelationTags(TagList *tags,int64_t relation_id,int mode); #endif /* OSMPARSER_H */ routino-3.0/src/output.c 644 233 144 133331 12572603217 10567 0/*************************************** Routing output generator. Part of the Routino routing software. ******************/ /****************** This file Copyright 2008-2015 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #include #include #include #include #include #include #include "types.h" #include "nodes.h" #include "segments.h" #include "ways.h" #include "functions.h" #include "fakes.h" #include "translations.h" #include "results.h" #include "xmlparse.h" #include "routino.h" /*+ To help when debugging +*/ #define DEBUG 0 /* Constants */ #define ROUTINO_POINT_IGNORE -1 /*+ Ignore this point. +*/ /* Global variables */ /*+ The option to calculate the quickest route insted of the shortest. +*/ int option_quickest=0; /*+ The options to select the format of the file output. +*/ int option_file_html=0,option_file_gpx_track=0,option_file_gpx_route=0,option_file_text=0,option_file_text_all=0,option_file_stdout=0; /*+ The options to select the format of the linked list output. +*/ int option_list_html=0,option_list_html_all=0,option_list_text=0,option_list_text_all=0; /* Local variables */ /*+ Heuristics for determining if a junction is important. +*/ static const char junction_other_way[Highway_Count][Highway_Count]= { /* M, T, P, S, T, U, R, S, T, C, P, S, F = Way type of route not taken */ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, /* Motorway */ { 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, /* Trunk */ { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, /* Primary */ { 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1 }, /* Secondary */ { 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1 }, /* Tertiary */ { 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1 }, /* Unclassified */ { 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1 }, /* Residential */ { 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1 }, /* Service */ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1 }, /* Track */ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1 }, /* Cycleway */ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* Path */ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* Steps */ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* Ferry */ }; /*++++++++++++++++++++++++++++++++++++++ Print the optimum route between two nodes. Routino_Output *PrintRoute Returns a linked list of data structures representing the route if required. Results **results The set of results to print (consecutive in array even if not consecutive waypoints). int nresults The number of results in the list. Nodes *nodes The set of nodes to use. Segments *segments The set of segments to use. Ways *ways The set of ways to use. Profile *profile The profile containing the transport type, speeds and allowed highways. Translation *translation The set of translated strings. ++++++++++++++++++++++++++++++++++++++*/ Routino_Output *PrintRoute(Results **results,int nresults,Nodes *nodes,Segments *segments,Ways *ways,Profile *profile,Translation *translation) { FILE *htmlfile=NULL,*gpxtrackfile=NULL,*gpxroutefile=NULL,*textfile=NULL,*textallfile=NULL; Routino_Output *listhead=NULL,*htmllist=NULL, *textlist=NULL,*textalllist=NULL,*htmlalllist=NULL; char *prev_bearing=NULL,*prev_wayname=NULL,*prev_waynameraw=NULL; index_t prev_node=NO_NODE; distance_t cum_distance=0; duration_t cum_duration=0; int point=0; int segment_count=0,route_count=0; int point_count=0; int roundabout=0; /* Open the files */ if(option_file_stdout) { if(option_file_html) htmlfile =stdout; if(option_file_gpx_track) gpxtrackfile=stdout; if(option_file_gpx_route) gpxroutefile=stdout; if(option_file_text) textfile =stdout; if(option_file_text_all) textallfile =stdout; } else { #if defined(_MSC_VER) || defined(__MINGW32__) const char *open_mode="wb"; #else const char *open_mode="w"; #endif if(option_quickest==0) { /* Print the result for the shortest route */ if(option_file_html) htmlfile =fopen("shortest.html",open_mode); if(option_file_gpx_track) gpxtrackfile=fopen("shortest-track.gpx",open_mode); if(option_file_gpx_route) gpxroutefile=fopen("shortest-route.gpx",open_mode); if(option_file_text) textfile =fopen("shortest.txt",open_mode); if(option_file_text_all) textallfile =fopen("shortest-all.txt",open_mode); #ifndef LIBROUTINO if(option_file_html && !htmlfile) fprintf(stderr,"Warning: Cannot open file 'shortest.html' for writing [%s].\n",strerror(errno)); if(option_file_gpx_track && !gpxtrackfile) fprintf(stderr,"Warning: Cannot open file 'shortest-track.gpx' for writing [%s].\n",strerror(errno)); if(option_file_gpx_route && !gpxroutefile) fprintf(stderr,"Warning: Cannot open file 'shortest-route.gpx' for writing [%s].\n",strerror(errno)); if(option_file_text && !textfile) fprintf(stderr,"Warning: Cannot open file 'shortest.txt' for writing [%s].\n",strerror(errno)); if(option_file_text_all && !textallfile) fprintf(stderr,"Warning: Cannot open file 'shortest-all.txt' for writing [%s].\n",strerror(errno)); #endif } else { /* Print the result for the quickest route */ if(option_file_html) htmlfile =fopen("quickest.html",open_mode); if(option_file_gpx_track) gpxtrackfile=fopen("quickest-track.gpx",open_mode); if(option_file_gpx_route) gpxroutefile=fopen("quickest-route.gpx",open_mode); if(option_file_text) textfile =fopen("quickest.txt",open_mode); if(option_file_text_all) textallfile =fopen("quickest-all.txt",open_mode); #ifndef LIBROUTINO if(option_file_html && !htmlfile) fprintf(stderr,"Warning: Cannot open file 'quickest.html' for writing [%s].\n",strerror(errno)); if(option_file_gpx_track && !gpxtrackfile) fprintf(stderr,"Warning: Cannot open file 'quickest-track.gpx' for writing [%s].\n",strerror(errno)); if(option_file_gpx_route && !gpxroutefile) fprintf(stderr,"Warning: Cannot open file 'quickest-route.gpx' for writing [%s].\n",strerror(errno)); if(option_file_text && !textfile) fprintf(stderr,"Warning: Cannot open file 'quickest.txt' for writing [%s].\n",strerror(errno)); if(option_file_text_all && !textallfile) fprintf(stderr,"Warning: Cannot open file 'quickest-all.txt' for writing [%s].\n",strerror(errno)); #endif } } /* Print the head of the files */ if(htmlfile) { fprintf(htmlfile,"\n"); fprintf(htmlfile,"\n"); if(translation->xml_copyright_creator[0] && translation->xml_copyright_creator[1]) fprintf(htmlfile,"\n",translation->xml_copyright_creator[0],translation->xml_copyright_creator[1]); if(translation->xml_copyright_source[0] && translation->xml_copyright_source[1]) fprintf(htmlfile,"\n",translation->xml_copyright_source[0],translation->xml_copyright_source[1]); if(translation->xml_copyright_license[0] && translation->xml_copyright_license[1]) fprintf(htmlfile,"\n",translation->xml_copyright_license[0],translation->xml_copyright_license[1]); fprintf(htmlfile,"\n"); fprintf(htmlfile,""); fprintf(htmlfile,translation->html_title,option_quickest?translation->xml_route_quickest:translation->xml_route_shortest); fprintf(htmlfile,"\n"); fprintf(htmlfile,"\n"); fprintf(htmlfile,"\n"); fprintf(htmlfile,"\n"); fprintf(htmlfile,"\n"); fprintf(htmlfile,"

"); fprintf(htmlfile,translation->html_title,option_quickest?translation->xml_route_quickest:translation->xml_route_shortest); fprintf(htmlfile,"

\n"); fprintf(htmlfile,"\n"); } if(gpxtrackfile) { fprintf(gpxtrackfile,"\n"); fprintf(gpxtrackfile,"\n"); fprintf(gpxtrackfile,"\n"); fprintf(gpxtrackfile,"%s : %s\n",translation->xml_copyright_creator[0],translation->xml_copyright_creator[1]); if(translation->xml_copyright_source[1]) { fprintf(gpxtrackfile,"\n",translation->xml_copyright_source[1]); if(translation->xml_copyright_license[1]) fprintf(gpxtrackfile,"%s\n",translation->xml_copyright_license[1]); fprintf(gpxtrackfile,"\n"); } fprintf(gpxtrackfile,"\n"); fprintf(gpxtrackfile,"\n"); fprintf(gpxtrackfile,""); fprintf(gpxtrackfile,translation->gpx_name,option_quickest?translation->xml_route_quickest:translation->xml_route_shortest); fprintf(gpxtrackfile,"\n"); fprintf(gpxtrackfile,""); fprintf(gpxtrackfile,translation->gpx_desc,option_quickest?translation->xml_route_quickest:translation->xml_route_shortest); fprintf(gpxtrackfile,"\n"); } if(gpxroutefile) { fprintf(gpxroutefile,"\n"); fprintf(gpxroutefile,"\n"); fprintf(gpxroutefile,"\n"); fprintf(gpxroutefile,"%s : %s\n",translation->xml_copyright_creator[0],translation->xml_copyright_creator[1]); if(translation->xml_copyright_source[1]) { fprintf(gpxroutefile,"\n",translation->xml_copyright_source[1]); if(translation->xml_copyright_license[1]) fprintf(gpxroutefile,"%s\n",translation->xml_copyright_license[1]); fprintf(gpxroutefile,"\n"); } fprintf(gpxroutefile,"\n"); fprintf(gpxroutefile,"\n"); fprintf(gpxroutefile,""); fprintf(gpxroutefile,translation->gpx_name,option_quickest?translation->xml_route_quickest:translation->xml_route_shortest); fprintf(gpxroutefile,"\n"); fprintf(gpxroutefile,""); fprintf(gpxroutefile,translation->gpx_desc,option_quickest?translation->xml_route_quickest:translation->xml_route_shortest); fprintf(gpxroutefile,"\n"); } if(textfile) { if(translation->raw_copyright_creator[0] && translation->raw_copyright_creator[1]) fprintf(textfile,"# %s : %s\n",translation->raw_copyright_creator[0],translation->raw_copyright_creator[1]); if(translation->raw_copyright_source[0] && translation->raw_copyright_source[1]) fprintf(textfile,"# %s : %s\n",translation->raw_copyright_source[0],translation->raw_copyright_source[1]); if(translation->raw_copyright_license[0] && translation->raw_copyright_license[1]) fprintf(textfile,"# %s : %s\n",translation->raw_copyright_license[0],translation->raw_copyright_license[1]); if((translation->raw_copyright_creator[0] && translation->raw_copyright_creator[1]) || (translation->raw_copyright_source[0] && translation->raw_copyright_source[1]) || (translation->raw_copyright_license[0] && translation->raw_copyright_license[1])) fprintf(textfile,"#\n"); fprintf(textfile,"#Latitude\tLongitude\tSection \tSection \tTotal \tTotal \tPoint\tTurn\tBearing\tHighway\n"); fprintf(textfile,"# \t \tDistance\tDuration\tDistance\tDuration\tType \t \t \t \n"); /* "%10.6f\t%11.6f\t%6.3f km\t%4.1f min\t%5.1f km\t%4.0f min\t%s\t %+d\t %+d\t%s\n" */ } if(textallfile) { if(translation->raw_copyright_creator[0] && translation->raw_copyright_creator[1]) fprintf(textallfile,"# %s : %s\n",translation->raw_copyright_creator[0],translation->raw_copyright_creator[1]); if(translation->raw_copyright_source[0] && translation->raw_copyright_source[1]) fprintf(textallfile,"# %s : %s\n",translation->raw_copyright_source[0],translation->raw_copyright_source[1]); if(translation->raw_copyright_license[0] && translation->raw_copyright_license[1]) fprintf(textallfile,"# %s : %s\n",translation->raw_copyright_license[0],translation->raw_copyright_license[1]); if((translation->raw_copyright_creator[0] && translation->raw_copyright_creator[1]) || (translation->raw_copyright_source[0] && translation->raw_copyright_source[1]) || (translation->raw_copyright_license[0] && translation->raw_copyright_license[1])) fprintf(textallfile,"#\n"); fprintf(textallfile,"#Latitude\tLongitude\t Node\tType\tSegment\tSegment\tTotal\tTotal \tSpeed\tBearing\tHighway\n"); fprintf(textallfile,"# \t \t \t \tDist \tDurat'n\tDist \tDurat'n\t \t \t \n"); /* "%10.6f\t%11.6f\t%8d%c\t%s\t%5.3f\t%5.2f\t%5.2f\t%5.1f\t%3d\t%4d\t%s\n" */ } /* Create the head of the linked list */ if(option_list_html) listhead=htmllist=calloc(sizeof(Routino_Output),1); if(option_list_html_all) listhead=htmlalllist=htmllist=calloc(sizeof(Routino_Output),1); if(option_list_text) listhead=textlist=calloc(sizeof(Routino_Output),1); if(option_list_text_all) listhead=textalllist=calloc(sizeof(Routino_Output),1); /* Loop through all the sections of the route and print them */ do { int first=1; int next_point=point; distance_t junc_distance=0; duration_t junc_duration=0; Result *result; #if DEBUG printf("Route section %d - waypoint %d to waypoint %d\n",point,results[point]->start_waypoint,results[point]->finish_waypoint); printf(" start_node=%"Pindex_t" prev_segment=%"Pindex_t"\n",results[point]->start_node,results[point]->prev_segment); printf(" finish_node=%"Pindex_t" last_segment=%"Pindex_t"\n",results[point]->finish_node,results[point]->last_segment); Result *r=FindResult(results[point],results[point]->start_node,results[point]->prev_segment); while(r) { printf(" node=%"Pindex_t" segment=%"Pindex_t" score=%f\n",r->node,r->segment,r->score); r=r->next; } #endif result=FindResult(results[point],results[point]->start_node,results[point]->prev_segment); /* Print the start of the segment */ if(gpxtrackfile) fprintf(gpxtrackfile,"\n"); /* Loop through all the points within a section of the route and print them */ do { double latitude,longitude; Node *resultnodep=NULL; index_t realsegment=NO_SEGMENT,next_realsegment=NO_SEGMENT; Segment *resultsegmentp=NULL,*next_resultsegmentp=NULL; Way *resultwayp=NULL,*next_resultwayp=NULL; Result *next_result; int important=ROUTINO_POINT_UNIMPORTANT; distance_t seg_distance=0; duration_t seg_duration=0; speed_t seg_speed=0; char *waynameraw=NULL,*wayname=NULL,*next_waynameraw=NULL,*next_wayname=NULL; int bearing_int=0,turn_int=0,next_bearing_int=0; char *turn=NULL,*turnraw=NULL,*next_bearing=NULL,*next_bearingraw=NULL; /* Calculate the information about this point */ if(IsFakeNode(result->node)) GetFakeLatLong(result->node,&latitude,&longitude); else { resultnodep=LookupNode(nodes,result->node,6); GetLatLong(nodes,result->node,resultnodep,&latitude,&longitude); } /* Calculate the next result */ next_result=result->next; if(!next_result) { next_point++; if(next_pointstart_node,results[next_point]->prev_segment); next_result=next_result->next; } } /* Calculate the information about this segment */ if(!first) /* not first point of a section of the route */ { if(IsFakeSegment(result->segment)) { resultsegmentp=LookupFakeSegment(result->segment); realsegment=IndexRealSegment(result->segment); } else { resultsegmentp=LookupSegment(segments,result->segment,2); realsegment=result->segment; } resultwayp=LookupWay(ways,resultsegmentp->way,1); seg_distance+=DISTANCE(resultsegmentp->distance); seg_duration+=Duration(resultsegmentp,resultwayp,profile); /* Calculate the cumulative distance/duration */ junc_distance+=seg_distance; junc_duration+=seg_duration; cum_distance+=seg_distance; cum_duration+=seg_duration; } /* Calculate the information about the next segment */ if(next_result) { if(IsFakeSegment(next_result->segment)) { next_resultsegmentp=LookupFakeSegment(next_result->segment); next_realsegment=IndexRealSegment(next_result->segment); } else { next_resultsegmentp=LookupSegment(segments,next_result->segment,1); next_realsegment=next_result->segment; } } /* Decide if this is a roundabout */ if(next_result) { next_resultwayp=LookupWay(ways,next_resultsegmentp->way,2); if(next_resultwayp->type&Highway_Roundabout) { if(roundabout==0) { roundabout++; important=ROUTINO_POINT_RB_ENTRY; } else { Segment *segmentp; if(resultnodep) segmentp=FirstSegment(segments,resultnodep,3); else segmentp=FirstFakeSegment(result->node); do { index_t othernode=OtherNode(segmentp,result->node); index_t thissegment; if(IsFakeNode(result->node)) thissegment=IndexFakeSegment(segmentp); else thissegment=IndexSegment(segments,segmentp); if(othernode!=prev_node && othernode!=next_result->node && thissegment!=realsegment && IsNormalSegment(segmentp)) { int canexit=1; if(profile->oneway && IsOnewayTo(segmentp,result->node)) { if(profile->allow!=Transports_Bicycle) canexit=0; else { Way *wayp=LookupWay(ways,segmentp->way,3); if(!(wayp->type&Highway_CycleBothWays)) canexit=0; } } if(canexit) { Way *wayp=LookupWay(ways,segmentp->way,3); if(!(wayp->type&Highway_Roundabout)) { roundabout++; important=ROUTINO_POINT_RB_NOT_EXIT; } } } if(resultnodep) segmentp=NextSegment(segments,segmentp,result->node); else segmentp=NextFakeSegment(segmentp,result->node); } while(segmentp); } } else if(roundabout) { roundabout++; important=ROUTINO_POINT_RB_EXIT; } } /* Decide if this is an important junction */ if(point_count==0) /* first point overall = Waypoint */ important=ROUTINO_POINT_WAYPOINT; else if(result->next==NULL) /* Waypoint */ important=ROUTINO_POINT_WAYPOINT; else if(first) /* first point of a section of the route */ important=ROUTINO_POINT_IGNORE; else if(roundabout) /* roundabout */ ; else if(realsegment==next_realsegment) /* U-turn */ important=ROUTINO_POINT_UTURN; else if(resultnodep && (resultnodep->flags&NODE_MINIRNDBT)) important=ROUTINO_POINT_MINI_RB; /* mini-roundabout */ else { Segment *segmentp=FirstSegment(segments,resultnodep,3); do { index_t seg=IndexSegment(segments,segmentp); if(seg!=realsegment && IsNormalSegment(segmentp)) { int cango=1; if(profile->oneway && IsOnewayTo(segmentp,result->node)) { if(profile->allow!=Transports_Bicycle) cango=0; else { Way *wayp=LookupWay(ways,segmentp->way,3); if(!(wayp->type&Highway_CycleBothWays)) cango=0; } } if(cango) { Way *wayp=LookupWay(ways,segmentp->way,3); if(seg==next_realsegment) /* the next segment that we follow */ { if(HIGHWAY(wayp->type)!=HIGHWAY(resultwayp->type)) if(importanttype)-1][HIGHWAY(wayp->type)-1]) if(importantnode); } while(segmentp); } /* Calculate the strings to be used */ if(!first && (textallfile || textalllist)) { waynameraw=WayName(ways,resultwayp); if(!*waynameraw) waynameraw=translation->raw_highway[HIGHWAY(resultwayp->type)]; bearing_int=(int)BearingAngle(nodes,resultsegmentp,result->node); seg_speed=profile->speed[HIGHWAY(resultwayp->type)]; } if(next_result && (important>ROUTINO_POINT_JUNCT_CONT || htmlalllist)) { if(!first && (htmlfile || htmllist || textfile || textlist)) { if(DISTANCE(resultsegmentp->distance)==0 || DISTANCE(next_resultsegmentp->distance)==0) turn_int=0; else turn_int=(int)TurnAngle(nodes,resultsegmentp,next_resultsegmentp,result->node); turn =translation->xml_turn[((202+turn_int)/45)%8]; turnraw=translation->notxml_turn[((202+turn_int)/45)%8]; } if(gpxroutefile || htmlfile || htmllist) { next_waynameraw=WayName(ways,next_resultwayp); if(!*next_waynameraw) next_waynameraw=translation->raw_highway[HIGHWAY(next_resultwayp->type)]; next_wayname=ParseXML_Encode_Safe_XML(next_waynameraw); } if(htmlfile || htmllist || gpxroutefile || textfile || textlist) { if(!first && DISTANCE(next_resultsegmentp->distance)==0) next_bearing_int=(int)BearingAngle(nodes,resultsegmentp,result->node); else next_bearing_int=(int)BearingAngle(nodes,next_resultsegmentp,next_result->node); next_bearing =translation->xml_heading[(4+(22+next_bearing_int)/45)%8]; next_bearingraw=translation->notxml_heading[(4+(22+next_bearing_int)/45)%8]; } } /* Print out the important points (junctions / waypoints) */ if(important>ROUTINO_POINT_JUNCT_CONT) { if(htmlfile) { char *type; if(important==ROUTINO_POINT_WAYPOINT) type=translation->html_waypoint; else if(important==ROUTINO_POINT_MINI_RB) type=translation->html_roundabout; else type=translation->html_junction; if(point_count>0) /* not the first point */ { /* *N*: *latitude* *longitude* */ fprintf(htmlfile,"
Follow *highway name* for *distance* km, *time* min [*distance* km, *time* minutes] */ fprintf(htmlfile,translation->html_segment, (roundabout>1?translation->html_roundabout:prev_wayname), distance_to_km(junc_distance),duration_to_minutes(junc_duration)); fprintf(htmlfile,translation->html_subtotal, distance_to_km(cum_distance),duration_to_minutes(cum_duration)); } /*
%d: %.6f %.6f\n", point_count+1, radians_to_degrees(latitude),radians_to_degrees(longitude)); if(point_count==0) /* first point */ { /*
Start at Waypoint, head *heading* */ fprintf(htmlfile,translation->html_start, translation->html_waypoint, next_bearing); } else if(next_result) /* middle point */ { if(roundabout>1 && important!=ROUTINO_POINT_WAYPOINT) { /*
leave roundabout, take the *Nth* exit heading *heading* */ fprintf(htmlfile,translation->html_rbnode, translation->html_roundabout, translation->xml_ordinal[roundabout-2], next_bearing); } else { /*
At junction, go *direction* heading *heading* */ fprintf(htmlfile,translation->html_node, type, turn, next_bearing); } } else /* end point */ { /*
Stop at Waypoint */ fprintf(htmlfile,translation->html_stop, translation->html_waypoint); /*
Total *distance* km, *time* minutes */ fprintf(htmlfile,translation->html_total, distance_to_km(cum_distance),duration_to_minutes(cum_duration)); } } if(htmllist) { int strl; char *type; if(important==ROUTINO_POINT_WAYPOINT) type=translation->nothtml_waypoint; else if(important==ROUTINO_POINT_MINI_RB) type=translation->nothtml_roundabout; else type=translation->nothtml_junction; if(point_count>0) /* not the first point */ { /* Follow: *highway name* for *distance* km, *time* min */ strl=strlen(translation->nothtml_segment)+ strlen(roundabout>1?translation->nothtml_roundabout:prev_waynameraw)+8+8+1; htmllist->desc2=malloc(strl); sprintf(htmllist->desc2,translation->nothtml_segment, (roundabout>1?translation->nothtml_roundabout:prev_waynameraw), distance_to_km(junc_distance),duration_to_minutes(junc_duration)); /* *distance* km, *time* minutes */ strl=strlen(translation->nothtml_subtotal)+8+8+1; htmllist->desc3=malloc(strl); sprintf(htmllist->desc3,translation->nothtml_subtotal, distance_to_km(cum_distance),duration_to_minutes(cum_duration)); if(htmlalllist) htmllist=htmlalllist; htmllist->next=calloc(sizeof(Routino_Output),1); htmllist=htmllist->next; if(htmlalllist) htmlalllist=htmllist; } htmllist->lon=longitude; htmllist->lat=latitude; htmllist->type=important; htmllist->dist=distance_to_km(cum_distance); htmllist->time=duration_to_minutes(cum_duration); if(point_count==0) /* first point */ { /* Start: At Waypoint, head *heading* */ strl=strlen(translation->nothtml_start)+ strlen(translation->nothtml_waypoint)+strlen(next_bearingraw)+1; htmllist->desc1=malloc(strl); sprintf(htmllist->desc1,translation->nothtml_start, translation->nothtml_waypoint, next_bearingraw); htmllist->name=strcpy(malloc(strlen(next_waynameraw)+1),next_waynameraw); } else if(next_result) /* middle point */ { if(roundabout>1 && important!=ROUTINO_POINT_WAYPOINT) { /* At: Roundabout, take the *Nth* exit heading *heading* */ strl=strlen(translation->nothtml_rbnode)+ strlen(translation->nothtml_roundabout)+strlen(translation->notxml_ordinal[roundabout-2])+strlen(next_bearingraw)+1; htmllist->desc1=malloc(strl); sprintf(htmllist->desc1,translation->nothtml_rbnode, translation->nothtml_roundabout, translation->notxml_ordinal[roundabout-2], next_bearingraw); } else { /* At: Junction, go *direction* heading *heading* */ strl=strlen(translation->nothtml_node)+ strlen(type)+strlen(turnraw)+strlen(next_bearingraw)+1; htmllist->desc1=malloc(strl); sprintf(htmllist->desc1,translation->nothtml_node, type, turnraw, next_bearingraw); } htmllist->turn=turn_int; htmllist->name=strcpy(malloc(strlen(next_waynameraw)+1),next_waynameraw); } else /* end point */ { /* Stop: At Waypoint */ strl=strlen(translation->nothtml_stop)+ strlen(translation->nothtml_waypoint)+1; htmllist->desc1=malloc(strl); sprintf(htmllist->desc1,translation->nothtml_stop, translation->nothtml_waypoint); /* Total: *distance* km, *time* minutes */ strl=strlen(translation->nothtml_total)+8+8+1; htmllist->desc2=malloc(strl); sprintf(htmllist->desc2,translation->nothtml_total, distance_to_km(cum_distance),duration_to_minutes(cum_duration)); htmllist->turn=turn_int; } htmllist->bearing=next_bearing_int; } if(gpxroutefile) { if(point_count>0) /* not first point */ { fprintf(gpxroutefile,""); fprintf(gpxroutefile,translation->gpx_step, prev_bearing, prev_wayname, distance_to_km(junc_distance),duration_to_minutes(junc_duration)); fprintf(gpxroutefile,"\n"); } if(point_count==0) /* first point */ { fprintf(gpxroutefile,"%s\n", radians_to_degrees(latitude),radians_to_degrees(longitude), translation->gpx_start); } else if(!next_result) /* end point */ { fprintf(gpxroutefile,"%s\n", radians_to_degrees(latitude),radians_to_degrees(longitude), translation->gpx_finish); fprintf(gpxroutefile,""); fprintf(gpxroutefile,translation->gpx_final, distance_to_km(cum_distance),duration_to_minutes(cum_duration)); fprintf(gpxroutefile,"\n"); } else /* middle point */ { if(important==ROUTINO_POINT_WAYPOINT) fprintf(gpxroutefile,"%s%d\n", radians_to_degrees(latitude),radians_to_degrees(longitude), translation->gpx_inter,++segment_count); else fprintf(gpxroutefile,"%s%03d\n", radians_to_degrees(latitude),radians_to_degrees(longitude), translation->gpx_trip,++route_count); } } if(textfile) { char *type; if(important==ROUTINO_POINT_WAYPOINT) type="Waypt"; else type="Junct"; if(point_count==0) /* first point */ { fprintf(textfile,"%10.6f\t%11.6f\t%6.3f km\t%4.1f min\t%5.1f km\t%4.0f min\t%s\t\t %+d\t%s\n", radians_to_degrees(latitude),radians_to_degrees(longitude), 0.0,0.0,0.0,0.0, type, ((22+next_bearing_int)/45+4)%8-4, next_waynameraw); } else if(!next_result) /* end point */ { fprintf(textfile,"%10.6f\t%11.6f\t%6.3f km\t%4.1f min\t%5.1f km\t%4.0f min\t%s\t\t\t\n", radians_to_degrees(latitude),radians_to_degrees(longitude), distance_to_km(junc_distance),duration_to_minutes(junc_duration), distance_to_km(cum_distance),duration_to_minutes(cum_duration), type); } else /* middle point */ { fprintf(textfile,"%10.6f\t%11.6f\t%6.3f km\t%4.1f min\t%5.1f km\t%4.0f min\t%s\t %+d\t %+d\t%s\n", radians_to_degrees(latitude),radians_to_degrees(longitude), distance_to_km(junc_distance),duration_to_minutes(junc_duration), distance_to_km(cum_distance),duration_to_minutes(cum_duration), type, (22+turn_int)/45, ((22+next_bearing_int)/45+4)%8-4, next_waynameraw); } } if(textlist) { textlist->lon=longitude; textlist->lat=latitude; textlist->type=important; if(point_count==0) /* first point */ { textlist->next=calloc(sizeof(Routino_Output),1); textlist->bearing=next_bearing_int; textlist->name=strcpy(malloc(strlen(next_waynameraw)+1),next_waynameraw); } else if(!next_result) /* end point */ { textlist->next=NULL; textlist->dist=distance_to_km(cum_distance); textlist->time=duration_to_minutes(cum_duration); } else /* middle point */ { textlist->next=calloc(sizeof(Routino_Output),1); textlist->dist=distance_to_km(cum_distance); textlist->time=duration_to_minutes(cum_duration); textlist->turn=turn_int; textlist->bearing=next_bearing_int; textlist->name=strcpy(malloc(strlen(next_waynameraw)+1),next_waynameraw); } textlist=textlist->next; } junc_distance=0; junc_duration=0; if(htmlfile || htmllist || gpxroutefile) { if(prev_wayname) free(prev_wayname); if(next_wayname) prev_wayname=strcpy((char*)malloc(strlen(next_wayname)+1),next_wayname); else prev_wayname=NULL; if(prev_waynameraw) free(prev_waynameraw); if(next_waynameraw) prev_waynameraw=strcpy((char*)malloc(strlen(next_waynameraw)+1),next_waynameraw); else prev_waynameraw=NULL; } if(gpxroutefile) prev_bearing=next_bearing; if(roundabout>1) roundabout=0; } else { if(htmlalllist) { htmlalllist->next=calloc(sizeof(Routino_Output),1); htmlalllist=htmlalllist->next; htmlalllist->lon=longitude; htmlalllist->lat=latitude; htmlalllist->type=important; htmlalllist->dist=distance_to_km(cum_distance); htmlalllist->time=duration_to_minutes(cum_duration); htmlalllist->turn=turn_int; htmlalllist->bearing=next_bearing_int; } } /* Print out all of the results */ if(gpxtrackfile) fprintf(gpxtrackfile,"\n", radians_to_degrees(latitude),radians_to_degrees(longitude)); if(important>ROUTINO_POINT_IGNORE) { if(textallfile) { char *type; if(important==ROUTINO_POINT_WAYPOINT) type="Waypt"; else if(important==ROUTINO_POINT_UTURN) type="U-turn"; else if(important==ROUTINO_POINT_MINI_RB) type="Mini-RB"; else if(important==ROUTINO_POINT_CHANGE) type="Change"; else if(important==ROUTINO_POINT_JUNCT_CONT || important==ROUTINO_POINT_RB_NOT_EXIT) type="Junct-"; else if(important==ROUTINO_POINT_UNIMPORTANT) type="Inter"; else type="Junct"; if(point_count==0) /* first point */ { fprintf(textallfile,"%10.6f\t%11.6f\t%8d%c\t%s\t%5.3f\t%5.2f\t%5.2f\t%5.1f\t\t\t\n", radians_to_degrees(latitude),radians_to_degrees(longitude), IsFakeNode(result->node)?(NODE_FAKE-result->node):result->node, (resultnodep && IsSuperNode(resultnodep))?'*':' ',type, 0.0,0.0,0.0,0.0); } else /* not the first point */ { fprintf(textallfile,"%10.6f\t%11.6f\t%8d%c\t%s\t%5.3f\t%5.2f\t%5.2f\t%5.1f\t%3d\t%4d\t%s\n", radians_to_degrees(latitude),radians_to_degrees(longitude), IsFakeNode(result->node)?(NODE_FAKE-result->node):result->node, (resultnodep && IsSuperNode(resultnodep))?'*':' ',type, distance_to_km(seg_distance),duration_to_minutes(seg_duration), distance_to_km(cum_distance),duration_to_minutes(cum_duration), speed_to_kph(seg_speed), bearing_int, waynameraw); } } if(textalllist) { if(point_count==0) /* first point */ ; else /* not the first point */ { textalllist->next=calloc(sizeof(Routino_Output),1); textalllist=textalllist->next; textalllist->dist=distance_to_km(cum_distance); textalllist->time=duration_to_minutes(cum_duration); textalllist->speed=speed_to_kph(seg_speed); textalllist->bearing=next_bearing_int; textalllist->name=strcpy(malloc(strlen(waynameraw)+1),waynameraw); } textalllist->lon=longitude; textalllist->lat=latitude; textalllist->type=important; } } if(wayname && wayname!=waynameraw) free(wayname); result=next_result; if(important>ROUTINO_POINT_JUNCT_CONT) point_count++; first=0; } while(point==next_point); /* Print the end of the segment */ if(gpxtrackfile) fprintf(gpxtrackfile,"\n"); point=next_point; if(result) prev_node=result->node; else prev_node=NO_NODE; } while(point\n"); if((translation->xml_copyright_creator[0] && translation->xml_copyright_creator[1]) || (translation->xml_copyright_source[0] && translation->xml_copyright_source[1]) || (translation->xml_copyright_license[0] && translation->xml_copyright_license[1])) { fprintf(htmlfile,"

\n"); fprintf(htmlfile,"\n"); if(translation->xml_copyright_creator[0] && translation->xml_copyright_creator[1]) fprintf(htmlfile,"
%s:%s\n",translation->xml_copyright_creator[0],translation->xml_copyright_creator[1]); if(translation->xml_copyright_source[0] && translation->xml_copyright_source[1]) fprintf(htmlfile,"
%s:%s\n",translation->xml_copyright_source[0],translation->xml_copyright_source[1]); if(translation->xml_copyright_license[0] && translation->xml_copyright_license[1]) fprintf(htmlfile,"
%s:%s\n",translation->xml_copyright_license[0],translation->xml_copyright_license[1]); fprintf(htmlfile,"
\n"); } fprintf(htmlfile,"\n"); fprintf(htmlfile,"\n"); } if(gpxtrackfile) { fprintf(gpxtrackfile,"\n"); fprintf(gpxtrackfile,"\n"); } if(gpxroutefile) { fprintf(gpxroutefile,"\n"); fprintf(gpxroutefile,"\n"); } /* Close the files */ if(!option_file_stdout) { if(htmlfile) fclose(htmlfile); if(gpxtrackfile) fclose(gpxtrackfile); if(gpxroutefile) fclose(gpxroutefile); if(textfile) fclose(textfile); if(textallfile) fclose(textallfile); } return(listhead); } routino-3.0/src/tagging.h 644 233 144 5110 12153161715 10602 0/*************************************** The data types for the tagging rules. Part of the Routino routing software. ******************/ /****************** This file Copyright 2010-2013 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #ifndef TAGGING_H #define TAGGING_H /*+ To stop multiple inclusions. +*/ #include /* Data types */ typedef struct _TaggingRuleList TaggingRuleList; /*+ A structure to contain the tagging rule/action. +*/ typedef struct _TaggingRule { int action; /*+ A flag to indicate the type of action. +*/ char *k; /*+ The tag key (or NULL). +*/ char *v; /*+ The tag value (or NULL). +*/ char *message; /*+ The message string for logerror (or NULL). +*/ TaggingRuleList *rulelist; /*+ The sub-rules belonging to this rule. +*/ } TaggingRule; /*+ A structure to contain the list of rules and associated information. +*/ struct _TaggingRuleList { TaggingRule *rules; /*+ The array of rules. +*/ int nrules; /*+ The number of rules. +*/ }; /*+ A structure to hold a list of tags to be processed. +*/ typedef struct _TagList { int ntags; /*+ The number of tags. +*/ char **k; /*+ The list of tag keys. +*/ char **v; /*+ The list of tag values. +*/ } TagList; /* Functions in tagging.c */ int ParseXMLTaggingRules(const char *filename); void DeleteXMLTaggingRules(void); TagList *NewTagList(void); void DeleteTagList(TagList *tags); void AppendTag(TagList *tags,const char *k,const char *v); void ModifyTag(TagList *tags,const char *k,const char *v); void DeleteTag(TagList *tags,const char *k); char *StringifyTag(TagList *tags); TagList *ApplyNodeTaggingRules(TagList *tags,int64_t id); TagList *ApplyWayTaggingRules(TagList *tags,int64_t id); TagList *ApplyRelationTaggingRules(TagList *tags,int64_t id); #endif /* TAGGING_H */ routino-3.0/src/xmlparse.h 644 233 144 10145 12563633052 11044 0/*************************************** A simple XML parser Part of the Routino routing software. ******************/ /****************** This file Copyright 2010-2015 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #ifndef XMLPARSE_H #define XMLPARSE_H /*+ To stop multiple inclusions. +*/ #include #include /*+ The maximum number of attributes per tag. +*/ #define XMLPARSE_MAX_ATTRS 16 /*+ The maximum number of subtags per tag. +*/ #define XMLPARSE_MAX_SUBTAGS 16 /*+ A flag to indicate the start and/or end of a tag. +*/ #define XMLPARSE_TAG_START 1 #define XMLPARSE_TAG_END 2 /*+ A forward definition of the xmltag +*/ typedef struct _xmltag xmltag; /*+ A structure to hold the definition of a tag. +*/ struct _xmltag { const char * const name; /*+ The name of the tag - must be in lower case. +*/ const int nattributes; /*+ The number of valid attributes for the tag. +*/ const char * const attributes[XMLPARSE_MAX_ATTRS]; /*+ The valid attributes for the tag. +*/ int (*callback)(); /*+ The callback function when the tag is seen. +*/ const xmltag * const subtags[XMLPARSE_MAX_SUBTAGS]; /*+ The list of valid tags contained within this one (null terminated). +*/ }; /* XML Parser options */ #define XMLPARSE_UNKNOWN_ATTRIBUTES 0x0003 #define XMLPARSE_UNKNOWN_ATTR_ERROR 0x0000 /* Flag an error and exit. */ #define XMLPARSE_UNKNOWN_ATTR_ERRNONAME 0x0001 /* Flag an error and exit unless a namespace is specified. */ #define XMLPARSE_UNKNOWN_ATTR_WARN 0x0002 /* Warn about the problem and continue. */ #define XMLPARSE_UNKNOWN_ATTR_IGNORE 0x0003 /* Ignore the potential problem. */ #define XMLPARSE_RETURN_ATTR_ENCODED 0x0004 /* Return the XML attribute strings without decoding them. */ /* XML parser functions */ int ParseXML(int fd,const xmltag * const *tags,int options); uint64_t ParseXML_LineNumber(void); void ParseXML_SetError(const char *format, ...); char *ParseXML_GetError(void); char *ParseXML_Decode_Entity_Ref(const char *string); char *ParseXML_Decode_Char_Ref(const char *string); char *ParseXML_Encode_Safe_XML(const char *string); int ParseXML_IsInteger(const char *string); int ParseXML_IsFloating(const char *string); /* Macros to simplify the callback functions */ #define XMLPARSE_MESSAGE(tag,message) \ do \ { \ ParseXML_SetError(message " in <%s> tag.",tag); \ return(1); \ } \ while(0) #define XMLPARSE_INVALID(tag,attribute) \ do \ { \ ParseXML_SetError("Invalid value for '" #attribute "' attribute in <%s> tag.",tag); \ return(1); \ } \ while(0) #define XMLPARSE_ASSERT_STRING(tag,attribute) \ do \ { \ if(!attribute) \ { \ ParseXML_SetError("'" #attribute "' attribute must be specified in <%s> tag.",tag); \ return(1); \ } \ } \ while(0) #define XMLPARSE_ASSERT_INTEGER(tag,attribute) \ do \ { \ if(!attribute || !*attribute || !ParseXML_IsInteger(attribute)) \ { \ ParseXML_SetError("'" #attribute "' attribute must be a integer in <%s> tag.",tag); \ return(1); \ } \ } \ while(0) #define XMLPARSE_ASSERT_FLOATING(tag,attribute) \ do \ { \ if(!attribute || !*attribute || !ParseXML_IsFloating(attribute)) \ { \ ParseXML_SetError("'" #attribute "' attribute must be a number in <%s> tag.",tag); \ return(1); \ } \ } \ while(0) #endif /* XMLPARSE_H */ routino-3.0/src/routino.c 644 233 144 50632 12572103560 10704 0/*************************************** Routino library functions file. Part of the Routino routing software. ******************/ /****************** This file Copyright 2015 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #include #include "routino.h" #include "types.h" #include "nodes.h" #include "segments.h" #include "ways.h" #include "relations.h" #include "fakes.h" #include "results.h" #include "functions.h" #include "profiles.h" #include "translations.h" /* Global variables */ /*+ Contains the libroutino API version number. +*/ DLL_PUBLIC int Routino_APIVersion=ROUTINO_API_VERSION; /*+ Contains the error number of the most recent Routino function (one of the ROUTINO_ERROR_* values). +*/ DLL_PUBLIC int Routino_errno=ROUTINO_ERROR_NONE; /*+ The function to be called to report on the routing progress. +*/ Routino_ProgressFunc progress_func=NULL; /*+ The current state of the routing progress. +*/ double progress_value=0; /*+ Set when the progress callback returns false in the routing function. +*/ int progress_abort=0; /*+ The option to calculate the quickest route insted of the shortest. +*/ extern int option_quickest; /*+ The options to select the format of the file output. +*/ extern int option_file_html,option_file_gpx_track,option_file_gpx_route,option_file_text,option_file_text_all,option_file_stdout; /*+ The options to select the format of the linked list output. +*/ extern int option_list_html,option_list_html_all,option_list_text,option_list_text_all; /* Static variables */ static distance_t distmax=km_to_distance(1); /* Local types */ struct _Routino_Database { Nodes *nodes; Segments *segments; Ways *ways; Relations *relations; }; struct _Routino_Waypoint { index_t segment; index_t node1,node2; distance_t dist1,dist2; }; /*++++++++++++++++++++++++++++++++++++++ Check the version of the library used by the caller against the library version int Routino_Check_API_Version Returns ROUTINO_ERROR_NONE if OK or ROUTINO_ERROR_WRONG_VERSION if there is an error. int caller_version The version of the API used in the caller. This function should not be called directly, use the macro Routino_CheckAPIVersion() which takes no arguments. ++++++++++++++++++++++++++++++++++++++*/ DLL_PUBLIC int Routino_Check_API_Version(int caller_version) { if(caller_version==Routino_APIVersion) return(ROUTINO_ERROR_NONE); else return(ROUTINO_ERROR_WRONG_API_VERSION); } /*++++++++++++++++++++++++++++++++++++++ Load a database of files for Routino to use for routing. Routino_Database *Routino_LoadDatabase Returns a pointer to the database. const char *dirname The pathname of the directory containing the database files. const char *prefix The prefix of the database files. ++++++++++++++++++++++++++++++++++++++*/ DLL_PUBLIC Routino_Database *Routino_LoadDatabase(const char *dirname,const char *prefix) { char *nodes_filename; char *segments_filename; char *ways_filename; char *relations_filename; Routino_Database *database=NULL; nodes_filename =FileName(dirname,prefix,"nodes.mem"); segments_filename =FileName(dirname,prefix,"segments.mem"); ways_filename =FileName(dirname,prefix,"ways.mem"); relations_filename=FileName(dirname,prefix,"relations.mem"); if(!ExistsFile(nodes_filename) || !ExistsFile(nodes_filename) || !ExistsFile(nodes_filename) || !ExistsFile(nodes_filename)) Routino_errno=ROUTINO_ERROR_NO_DATABASE_FILES; else { database=calloc(sizeof(Routino_Database),1); database->nodes =LoadNodeList (nodes_filename); database->segments =LoadSegmentList (segments_filename); database->ways =LoadWayList (ways_filename); database->relations=LoadRelationList(relations_filename); } free(nodes_filename); free(segments_filename); free(ways_filename); free(relations_filename); if(!database->nodes || !database->segments || !database->ways || !database->relations) { Routino_UnloadDatabase(database); database=NULL; Routino_errno=ROUTINO_ERROR_BAD_DATABASE_FILES; } if(database) { Routino_errno=ROUTINO_ERROR_NONE; return(database); } else return(NULL); } /*++++++++++++++++++++++++++++++++++++++ Close the database files that were opened by a call to Routino_LoadDatabase(). Routino_Database *database The database to close. ++++++++++++++++++++++++++++++++++++++*/ DLL_PUBLIC void Routino_UnloadDatabase(Routino_Database *database) { if(!database) Routino_errno=ROUTINO_ERROR_NO_DATABASE; else { if(database->nodes) DestroyNodeList (database->nodes); if(database->segments) DestroySegmentList (database->segments); if(database->ways) DestroyWayList (database->ways); if(database->relations) DestroyRelationList(database->relations); free(database); Routino_errno=ROUTINO_ERROR_NONE; } } /*++++++++++++++++++++++++++++++++++++++ Parse a Routino XML file containing profiles, must be called before selecting a profile. int Routino_ParseXMLProfiles Returns non-zero in case of an error or zero if there was no error. const char *filename The full pathname of the file to read. ++++++++++++++++++++++++++++++++++++++*/ DLL_PUBLIC int Routino_ParseXMLProfiles(const char *filename) { int retval; retval=ParseXMLProfiles(filename,NULL,1); if(retval==1) retval=ROUTINO_ERROR_NO_PROFILES_XML; else if(retval==2) retval=ROUTINO_ERROR_BAD_PROFILES_XML; Routino_errno=retval; return(retval); } /*++++++++++++++++++++++++++++++++++++++ Return a list of the profile names that have been loaded from the XML file. char **Routino_GetProfileNames Returns a NULL terminated list of strings - all allocated. ++++++++++++++++++++++++++++++++++++++*/ DLL_PUBLIC char **Routino_GetProfileNames(void) { Routino_errno=ROUTINO_ERROR_NONE; return(GetProfileNames()); } /*++++++++++++++++++++++++++++++++++++++ Select a specific routing profile from the set of Routino profiles that have been loaded from the XML file or NULL in case of an error. Routino_Profile *Routino_GetProfile Returns a pointer to an internal data structure - do not free. const char *name The name of the profile to select. ++++++++++++++++++++++++++++++++++++++*/ DLL_PUBLIC Routino_Profile *Routino_GetProfile(const char *name) { Profile *profile=GetProfile(name); if(profile) Routino_errno=ROUTINO_ERROR_NONE; else Routino_errno=ROUTINO_ERROR_NO_SUCH_PROFILE; return(profile); } /*++++++++++++++++++++++++++++++++++++++ Free the internal memory that was allocated for the Routino profiles loaded from the XML file. ++++++++++++++++++++++++++++++++++++++*/ DLL_PUBLIC void Routino_FreeXMLProfiles(void) { Routino_errno=ROUTINO_ERROR_NONE; FreeXMLProfiles(); } /*++++++++++++++++++++++++++++++++++++++ Parse a Routino XML file containing translations, must be called before selecting a translation. int Routino_ParseXMLTranslations Returns non-zero in case of an error or zero if there was no error. const char *filename The full pathname of the file to read. ++++++++++++++++++++++++++++++++++++++*/ DLL_PUBLIC int Routino_ParseXMLTranslations(const char *filename) { int retval; retval=ParseXMLTranslations(filename,NULL,1); if(retval==1) retval=ROUTINO_ERROR_NO_TRANSLATIONS_XML; else if(retval==2) retval=ROUTINO_ERROR_BAD_TRANSLATIONS_XML; Routino_errno=retval; return(retval); } /*++++++++++++++++++++++++++++++++++++++ Return a list of the translation languages that have been loaded from the XML file. char **Routino_GetTranslationLanguages Returns a NULL terminated list of strings - all allocated. ++++++++++++++++++++++++++++++++++++++*/ DLL_PUBLIC char **Routino_GetTranslationLanguages(void) { Routino_errno=ROUTINO_ERROR_NONE; return(GetTranslationLanguages()); } /*++++++++++++++++++++++++++++++++++++++ Return a list of the full names of the translation languages that have been loaded from the XML file. char **Routino_GetTranslationLanguageFullNames Returns a NULL terminated list of strings - all allocated. ++++++++++++++++++++++++++++++++++++++*/ DLL_PUBLIC char **Routino_GetTranslationLanguageFullNames(void) { Routino_errno=ROUTINO_ERROR_NONE; return(GetTranslationLanguageFullNames()); } /*++++++++++++++++++++++++++++++++++++++ Select a specific translation from the set of Routino translations that have been loaded from the XML file or NULL in case of an error. Routino_Translation *Routino_GetTranslation Returns a pointer to an internal data structure - do not free. const char *language The language to select (as a country code, e.g. 'en', 'de') or an empty string for the first in the file or NULL for the built-in English version. ++++++++++++++++++++++++++++++++++++++*/ DLL_PUBLIC Routino_Translation *Routino_GetTranslation(const char *language) { Translation *translation=GetTranslation(language); if(translation) Routino_errno=ROUTINO_ERROR_NONE; else Routino_errno=ROUTINO_ERROR_NO_SUCH_TRANSLATION; return(translation); } /*++++++++++++++++++++++++++++++++++++++ Free the internal memory that was allocated for the Routino translations loaded from the XML file. ++++++++++++++++++++++++++++++++++++++*/ DLL_PUBLIC void Routino_FreeXMLTranslations(void) { Routino_errno=ROUTINO_ERROR_NONE; FreeXMLTranslations(); } /*++++++++++++++++++++++++++++++++++++++ Create a fully formed Routino Profile from a Routino User Profile. Routino_Profile *Routino_CreateProfileFromUserProfile Returns an allocated Routino Profile. Routino_UserProfile *profile The user specified profile to convert (not modified by this). ++++++++++++++++++++++++++++++++++++++*/ DLL_PUBLIC Routino_Profile *Routino_CreateProfileFromUserProfile(Routino_UserProfile *profile) { Routino_Profile *rprofile=calloc(1,sizeof(Routino_Profile)); int i; Routino_errno=ROUTINO_ERROR_NONE; if(profile->transport<=0 || profile->transport>=Transport_Count) Routino_errno=ROUTINO_ERROR_BAD_USER_PROFILE; else rprofile->transport=profile->transport; for(i=1;ihighway[i]<0 || profile->highway[i]>1) Routino_errno=ROUTINO_ERROR_BAD_USER_PROFILE; else rprofile->highway[i]=profile->highway[i]; if(profile->speed[i]<=0) Routino_errno=ROUTINO_ERROR_BAD_USER_PROFILE; else rprofile->speed[i]=kph_to_speed(profile->speed[i]); } for(i=1;iprops[i]<0 || profile->props[i]>1) Routino_errno=ROUTINO_ERROR_BAD_USER_PROFILE; else rprofile->props[i]=profile->props[i]; } if(profile->weight<=0) Routino_errno=ROUTINO_ERROR_BAD_USER_PROFILE; else rprofile->weight=tonnes_to_weight(profile->weight); if(profile->height<=0) Routino_errno=ROUTINO_ERROR_BAD_USER_PROFILE; else rprofile->height=metres_to_height(profile->height); if(profile->width<=0) Routino_errno=ROUTINO_ERROR_BAD_USER_PROFILE; else rprofile->width=metres_to_width(profile->width); if(profile->length<=0) Routino_errno=ROUTINO_ERROR_BAD_USER_PROFILE; else rprofile->length=metres_to_length(profile->length); if(Routino_errno==ROUTINO_ERROR_NONE) return(rprofile); free(rprofile); return(NULL); } /*++++++++++++++++++++++++++++++++++++++ Create a Routino User Profile from a Routino Profile loaded from an XML file. Routino_UserProfile *Routino_CreateUserProfileFromProfile Returns an allocated Routino User Profile. Routino_Profile *profile The Routino Profile to convert (not modified by this). ++++++++++++++++++++++++++++++++++++++*/ DLL_PUBLIC Routino_UserProfile *Routino_CreateUserProfileFromProfile(Routino_Profile *profile) { Routino_UserProfile *uprofile=calloc(1,sizeof(Routino_UserProfile)); int i; Routino_errno=ROUTINO_ERROR_NONE; uprofile->transport=profile->transport; for(i=1;ihighway[i]=profile->highway[i]; uprofile->speed[i]=speed_to_kph(profile->speed[i]); } for(i=1;iprops[i]=profile->props[i]; uprofile->weight=weight_to_tonnes(profile->weight); uprofile->height=height_to_metres(profile->height); uprofile->width=width_to_metres(profile->width); uprofile->length=length_to_metres(profile->length); return(uprofile); } /*++++++++++++++++++++++++++++++++++++++ Validates that a selected routing profile is valid for use with the selected routing database. int Routino_ValidateProfile Returns zero if OK or something else in case of an error. Routino_Database *database The Routino database to use. Routino_Profile *profile The Routino profile to validate. ++++++++++++++++++++++++++++++++++++++*/ DLL_PUBLIC int Routino_ValidateProfile(Routino_Database *database,Routino_Profile *profile) { Routino_errno=ROUTINO_ERROR_NONE; if(UpdateProfile(profile,database->ways)) Routino_errno=ROUTINO_ERROR_PROFILE_DATABASE_ERR; return(Routino_errno); } /*++++++++++++++++++++++++++++++++++++++ Finds the nearest point in the database to the specified latitude and longitude. Routino_Waypoint *Routino_FindWaypoint Returns a pointer to a newly allocated Routino waypoint or NULL if none could be found. Routino_Database *database The Routino database to use. Routino_Profile *profile The Routino profile to use. double latitude The latitude in degrees of the point. double longitude The longitude in degrees of the point. ++++++++++++++++++++++++++++++++++++++*/ DLL_PUBLIC Routino_Waypoint *Routino_FindWaypoint(Routino_Database *database,Routino_Profile *profile,double latitude,double longitude) { distance_t dist; Routino_Waypoint *waypoint; if(!database) { Routino_errno=ROUTINO_ERROR_NO_DATABASE; return(NULL); } if(!profile) { Routino_errno=ROUTINO_ERROR_NO_PROFILE; return(NULL); } if(!profile->allow) { Routino_errno=ROUTINO_ERROR_NOTVALID_PROFILE; return(NULL); } waypoint=calloc(sizeof(Routino_Waypoint),1); waypoint->segment=FindClosestSegment(database->nodes,database->segments,database->ways, degrees_to_radians(latitude),degrees_to_radians(longitude),distmax,profile, &dist,&waypoint->node1,&waypoint->node2,&waypoint->dist1,&waypoint->dist2); if(waypoint->segment==NO_SEGMENT) { free(waypoint); Routino_errno=ROUTINO_ERROR_NO_NEARBY_HIGHWAY; return(NULL); } Routino_errno=ROUTINO_ERROR_NONE; return(waypoint); } /*++++++++++++++++++++++++++++++++++++++ Calculate a route using a loaded database, chosen profile, chosen translation and set of waypoints. Routino_Output *Routino_CalculateRoute Returns the head of a linked list of route data (if requested) or NULL. Routino_Database *database The loaded database to use. Routino_Profile *profile The chosen routing profile to use. Routino_Translation *translation The chosen translation information to use. Routino_Waypoint **waypoints The set of waypoints. int nwaypoints The number of waypoints. int options The set of routing options (ROUTINO_ROUTE_*) ORed together. Routino_ProgressFunc progress A function to be called occasionally to report progress or NULL. ++++++++++++++++++++++++++++++++++++++*/ DLL_PUBLIC Routino_Output *Routino_CalculateRoute(Routino_Database *database,Routino_Profile *profile,Routino_Translation *translation, Routino_Waypoint **waypoints,int nwaypoints,int options,Routino_ProgressFunc progress) { int waypoint; index_t start_node,finish_node=NO_NODE; index_t join_segment=NO_SEGMENT; Results **results; Routino_Output *output=NULL; /* Check the input data */ if(!database) { Routino_errno=ROUTINO_ERROR_NO_DATABASE; return(NULL); } if(!profile) { Routino_errno=ROUTINO_ERROR_NO_PROFILE; return(NULL); } if(!profile->allow) { Routino_errno=ROUTINO_ERROR_NOTVALID_PROFILE; return(NULL); } if(!translation) { Routino_errno=ROUTINO_ERROR_NO_TRANSLATION; return(NULL); } /* Extract the options */ if(options&ROUTINO_ROUTE_QUICKEST) option_quickest=1; else option_quickest=0; if(options&ROUTINO_ROUTE_FILE_HTML) option_file_html=1; else option_file_html=0; if(options&ROUTINO_ROUTE_FILE_GPX_TRACK) option_file_gpx_track=1; else option_file_gpx_track=0; if(options&ROUTINO_ROUTE_FILE_GPX_ROUTE) option_file_gpx_route=1; else option_file_gpx_route=0; if(options&ROUTINO_ROUTE_FILE_TEXT) option_file_text=1; else option_file_text=0; if(options&ROUTINO_ROUTE_FILE_TEXT_ALL) option_file_text_all=1; else option_file_text_all=0; if(options&ROUTINO_ROUTE_FILE_STDOUT) option_file_stdout=1; else option_file_stdout=0; if(option_file_stdout && (option_file_html+option_file_gpx_track+option_file_gpx_route+option_file_text+option_file_text_all)!=1) { Routino_errno=ROUTINO_ERROR_BAD_OPTIONS; return(NULL); } if(options&ROUTINO_ROUTE_LIST_HTML) option_list_html=1; else option_list_html=0; if(options&ROUTINO_ROUTE_LIST_HTML_ALL) option_list_html_all=1; else option_list_html_all=0; if(options&ROUTINO_ROUTE_LIST_TEXT) option_list_text=1; else option_list_text=0; if(options&ROUTINO_ROUTE_LIST_TEXT_ALL) option_list_text_all=1; else option_list_text_all=0; if((option_list_html+option_list_html_all+option_list_text+option_list_text_all)>1) { Routino_errno=ROUTINO_ERROR_BAD_OPTIONS; return(NULL); } /* Set up the progress callback */ progress_func=progress; progress_value=0.0; progress_abort=0; /* Loop through all pairs of waypoints */ results=calloc(sizeof(Results*),nwaypoints); for(waypoint=0;waypointnodes,database->segments,waypoint+1, LookupSegment(database->segments,waypoints[waypoint]->segment,1), waypoints[waypoint]->node1,waypoints[waypoint]->node2,waypoints[waypoint]->dist1,waypoints[waypoint]->dist2); if(waypoint==0) continue; results[waypoint-1]=CalculateRoute(database->nodes,database->segments,database->ways,database->relations, profile,start_node,join_segment,finish_node,waypoint,waypoint+1); if(!results[waypoint-1]) { if(progress_func && progress_abort) Routino_errno=ROUTINO_ERROR_PROGRESS_ABORTED; else Routino_errno=ROUTINO_ERROR_NO_ROUTE_1+waypoint-1; goto tidy_and_exit; } join_segment=results[waypoint-1]->last_segment; } if(progress_func) { progress_value=(double)waypoint/(double)(nwaypoints+1); if(!progress_func(progress_value)) { Routino_errno=ROUTINO_ERROR_PROGRESS_ABORTED; goto tidy_and_exit; } } /* Print the route */ output=PrintRoute(results,nwaypoints-1,database->nodes,database->segments,database->ways,profile,translation); if(progress_func && !progress_func(1.0)) { Routino_errno=ROUTINO_ERROR_PROGRESS_ABORTED; goto tidy_and_exit; } /* Tidy up and exit */ tidy_and_exit: DeleteFakeNodes(); for(waypoint=0;waypointnext; if(output->name) free(output->name); if(output->desc1) free(output->desc1); if(output->desc2) free(output->desc2); if(output->desc3) free(output->desc3); free(output); output=next; } } routino-3.0/src/ways.c 644 233 144 6601 12563633051 10150 0/*************************************** Way data type functions. Part of the Routino routing software. ******************/ /****************** This file Copyright 2008-2015 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #include #include "ways.h" #include "files.h" /*++++++++++++++++++++++++++++++++++++++ Load in a way list from a file. Ways *LoadWayList Returns the way list. const char *filename The name of the file to load. ++++++++++++++++++++++++++++++++++++++*/ Ways *LoadWayList(const char *filename) { Ways *ways; ways=(Ways*)malloc(sizeof(Ways)); #if !SLIM ways->data=MapFile(filename); /* Copy the WaysFile structure from the loaded data */ ways->file=*((WaysFile*)ways->data); /* Set the pointers in the Ways structure. */ ways->ways =(Way *)(ways->data+sizeof(WaysFile)); ways->names=(char*)(ways->data+sizeof(WaysFile)+ways->file.number*sizeof(Way)); #else ways->fd=SlimMapFile(filename); /* Copy the WaysFile header structure from the loaded data */ SlimFetch(ways->fd,&ways->file,sizeof(WaysFile),0); ways->namesoffset=sizeof(WaysFile)+ways->file.number*sizeof(Way); memset(ways->ncached,0,sizeof(ways->ncached)); ways->cache=NewWayCache(); #ifndef LIBROUTINO log_malloc(ways->cache,sizeof(*ways->cache)); #endif #endif return(ways); } /*++++++++++++++++++++++++++++++++++++++ Destroy the way list. Ways *ways The way list to destroy. ++++++++++++++++++++++++++++++++++++++*/ void DestroyWayList(Ways *ways) { #if !SLIM ways->data=UnmapFile(ways->data); #else ways->fd=SlimUnmapFile(ways->fd); #ifndef LIBROUTINO log_free(ways->cache); #endif DeleteWayCache(ways->cache); #endif free(ways); } /*++++++++++++++++++++++++++++++++++++++ Return 0 if the two ways are the same (in respect of their types and limits), otherwise return positive or negative to allow sorting. int WaysCompare Returns a comparison. Way *way1p The first way. Way *way2p The second way. ++++++++++++++++++++++++++++++++++++++*/ int WaysCompare(Way *way1p,Way *way2p) { if(way1p==way2p) return(0); if(way1p->type!=way2p->type) return((int)way1p->type - (int)way2p->type); if(way1p->allow!=way2p->allow) return((int)way1p->allow - (int)way2p->allow); if(way1p->props!=way2p->props) return((int)way1p->props - (int)way2p->props); if(way1p->speed!=way2p->speed) return((int)way1p->speed - (int)way2p->speed); if(way1p->weight!=way2p->weight) return((int)way1p->weight - (int)way2p->weight); if(way1p->height!=way2p->height) return((int)way1p->height - (int)way2p->height); if(way1p->width!=way2p->width) return((int)way1p->width - (int)way2p->width); if(way1p->length!=way2p->length) return((int)way1p->length - (int)way2p->length); return(0); } routino-3.0/src/errorlogx.h 644 233 144 4555 12152346535 11225 0/*************************************** Header file for error log file data types and processing function prototypes. Part of the Routino routing software. ******************/ /****************** This file Copyright 2013 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #ifndef ERRORLOGX_H #define ERRORLOGX_H /*+ To stop multiple inclusions. +*/ #include #include "types.h" #include "typesx.h" /*+ A structure containing information for an error message during processing. +*/ typedef struct _ErrorLogX { latlong_t latitude; /*+ The error message latitude. +*/ latlong_t longitude; /*+ The error message longitude. +*/ uint32_t offset; /*+ The offset of the error message from the beginning of the text file. +*/ uint32_t length; /*+ The length of the error message in the text file. +*/ } ErrorLogX; /*+ A structure containing a set of error logs (memory format). +*/ typedef struct _ErrorLogsX { index_t number; /*+ The number of error logs. +*/ index_t latbins; /*+ The number of bins containing latitude. +*/ index_t lonbins; /*+ The number of bins containing longitude. +*/ ll_bin_t latzero; /*+ The bin number of the furthest south bin. +*/ ll_bin_t lonzero; /*+ The bin number of the furthest west bin. +*/ } ErrorLogsX; /* Error log processing functions in errorlogx.c */ ErrorLogsX *NewErrorLogList(void); void FreeErrorLogList(ErrorLogsX *errorlogsx); void ProcessErrorLogs(ErrorLogsX *errorlogsx,NodesX *nodesx,WaysX *waysx,RelationsX *relationsx); void SortErrorLogsGeographically(ErrorLogsX *errorlogsx); void SaveErrorLogs(ErrorLogsX *errorlogsx,char *filename); #endif /* ERRORLOGX_H */ routino-3.0/src/typesx.h 644 233 144 6725 12440117164 10531 0/*************************************** Type definitions for eXtended types. Part of the Routino routing software. ******************/ /****************** This file Copyright 2008-2014 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #ifndef TYPESX_H #define TYPESX_H /*+ To stop multiple inclusions. +*/ #include #include #include #include /* Constants and macros for handling them */ /*+ An undefined node ID. +*/ #define NO_NODE_ID ((node_t)~0) /*+ An undefined way ID. +*/ #define NO_WAY_ID ((way_t)~0) /*+ An undefined relation ID. +*/ #define NO_RELATION_ID ((relation_t)~0) /*+ The maximum number of segments per node (used to size temporary storage). +*/ #define MAX_SEG_PER_NODE 64 /* Bit mask macro types and functions */ #define BitMask uint32_t #define LengthBitMask(xx) (1+(xx)/32) #define AllocBitMask(xx) (BitMask*)calloc(LengthBitMask(xx),sizeof(BitMask)) #define ClearAllBits(xx,yy) memset((xx), 0,(1+(yy)/32)*sizeof(BitMask)) #define SetAllBits(xx,yy) memset((xx),~0,(1+(yy)/32)*sizeof(BitMask)) #define ClearBit(xx,yy) (xx)[(yy)/32]&=~(((BitMask)1)<<((yy)%32)) #define SetBit(xx,yy) (xx)[(yy)/32]|= (((BitMask)1)<<((yy)%32)) #define IsBitSet(xx,yy) ((xx)[(yy)/32]& (((BitMask)1)<<((yy)%32))) /* Simple Types */ /*+ A node identifier - must be at least as large as index_t. +*/ typedef uint32_t node_t; /*+ A way identifier - must be at least as large as index_t. +*/ typedef uint32_t way_t; /*+ A relation identifier - must be at least as large as index_t. +*/ typedef uint32_t relation_t; /*+ A printf formatting string for a node_t type (this should match the node_t definition above). +*/ #define Pnode_t PRIu32 /* PRIu32 and PRIu64 are defined in intypes.h */ /*+ A printf formatting string for a way_t type (this should match the way_t definition above). +*/ #define Pway_t PRIu32 /* PRIu32 and PRIu64 are defined in intypes.h */ /*+ A printf formatting string for a relation_t type (this should match the relation_t definition above). +*/ #define Prelation_t PRIu32 /* PRIu32 and PRIu64 are defined in intypes.h */ /* Enumerated types */ /*+ Turn restrictions. +*/ typedef enum _TurnRestriction { TurnRestrict_None =0, TurnRestrict_no_right_turn, TurnRestrict_no_left_turn, TurnRestrict_no_u_turn, TurnRestrict_no_straight_on, TurnRestrict_only_right_turn, TurnRestrict_only_left_turn, TurnRestrict_only_straight_on } TurnRestriction; /* Data structures */ typedef struct _NodeX NodeX; typedef struct _NodesX NodesX; typedef struct _SegmentX SegmentX; typedef struct _SegmentsX SegmentsX; typedef struct _WayX WayX; typedef struct _WaysX WaysX; typedef struct _RouteRelX RouteRelX; typedef struct _TurnRelX TurnRelX; typedef struct _RelationsX RelationsX; #endif /* TYPESX_H */ routino-3.0/src/ways.h 644 233 144 12367 12550223461 10177 0/*************************************** A header file for the ways. Part of the Routino routing software. ******************/ /****************** This file Copyright 2008-2015 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #ifndef WAYS_H #define WAYS_H /*+ To stop multiple inclusions. +*/ #include #include #include "types.h" #include "cache.h" #include "files.h" /* Data structures */ /*+ A structure containing a single way (members ordered to minimise overall size). +*/ struct _Way { index_t name; /*+ The offset of the name of the way in the names array. +*/ transports_t allow; /*+ The type of traffic allowed on the way. +*/ highway_t type; /*+ The highway type of the way. +*/ properties_t props; /*+ The properties of the way. +*/ speed_t speed; /*+ The defined maximum speed limit of the way. +*/ weight_t weight; /*+ The defined maximum weight of traffic on the way. +*/ height_t height; /*+ The defined maximum height of traffic on the way. +*/ width_t width; /*+ The defined maximum width of traffic on the way. +*/ length_t length; /*+ The defined maximum length of traffic on the way. +*/ }; /*+ A structure containing the header from the file. +*/ typedef struct _WaysFile { index_t number; /*+ The number of ways. +*/ highways_t highways; /*+ The types of highways that were seen when parsing. +*/ transports_t allow; /*+ The types of traffic that were seen when parsing. +*/ properties_t props; /*+ The properties that were seen when parsing. +*/ } WaysFile; /*+ A structure containing a set of ways (and pointers to mmap file). +*/ struct _Ways { WaysFile file; /*+ The header data from the file. +*/ #if !SLIM char *data; /*+ The memory mapped data. +*/ Way *ways; /*+ An array of ways. +*/ char *names; /*+ An array of characters containing the names. +*/ #else int fd; /*+ The file descriptor for the file. +*/ offset_t namesoffset; /*+ The offset of the names within the file. +*/ Way cached[3]; /*+ Two cached nodes read from the file in slim mode. +*/ char *ncached[3]; /*+ The cached way name. +*/ WayCache *cache; /*+ A RAM cache of ways read from the file. +*/ #endif }; /* Functions in ways.c */ Ways *LoadWayList(const char *filename); void DestroyWayList(Ways *ways); int WaysCompare(Way *way1p,Way *way2p); /* Macros and inline functions */ #if !SLIM /*+ Return a Way* pointer given a set of ways and an index. +*/ #define LookupWay(xxx,yyy,zzz) (&(xxx)->ways[yyy]) /*+ Return the name of a way given the Way pointer and a set of ways. +*/ #define WayName(xxx,yyy) (&(xxx)->names[(yyy)->name]) #else static inline Way *LookupWay(Ways *ways,index_t index,int position); static inline char *WayName(Ways *ways,Way *wayp); CACHE_NEWCACHE_PROTO(Way) CACHE_DELETECACHE_PROTO(Way) CACHE_FETCHCACHE_PROTO(Way) CACHE_INVALIDATECACHE_PROTO(Way) /* Data type */ CACHE_STRUCTURE(Way) /* Inline functions */ CACHE_NEWCACHE(Way) CACHE_DELETECACHE(Way) CACHE_FETCHCACHE(Way) CACHE_INVALIDATECACHE(Way) /*++++++++++++++++++++++++++++++++++++++ Find the Way information for a particular way. Way *LookupWay Returns a pointer to the cached way information. Ways *ways The set of ways to use. index_t index The index of the way. int position The position in the cache to store the value. ++++++++++++++++++++++++++++++++++++++*/ static inline Way *LookupWay(Ways *ways,index_t index,int position) { ways->cached[position-1]=*FetchCachedWay(ways->cache,index,ways->fd,sizeof(WaysFile)); return(&ways->cached[position-1]); } /*++++++++++++++++++++++++++++++++++++++ Find the name of a way. char *WayName Returns a pointer to the name of the way. Ways *ways The set of ways to use. Way *wayp The Way pointer. ++++++++++++++++++++++++++++++++++++++*/ static inline char *WayName(Ways *ways,Way *wayp) { int position=(int)(wayp-&ways->cached[-1]); int n=0; if(!ways->ncached[position-1]) ways->ncached[position-1]=(char*)malloc(64); while(!SlimFetch(ways->fd,ways->ncached[position-1]+n,64,ways->namesoffset+wayp->name+n)) { int i; for(i=n;incached[position-1][i]==0) goto exitloop; n+=64; ways->ncached[position-1]=(char*)realloc((void*)ways->ncached[position-1],n+64); } exitloop: return(ways->ncached[position-1]); } #endif #endif /* WAYS_H */ routino-3.0/src/logerror.c 644 233 144 11432 12563633053 11040 0/*************************************** Error logging functions Part of the Routino routing software. ******************/ /****************** This file Copyright 2013, 2015 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #include #include #include #include "typesx.h" #include "files.h" #include "logging.h" /* Global variables */ /*+ The name of the error log file. +*/ char *errorlogfilename=NULL; /*+ The name of the binary error log file. +*/ char *errorbinfilename=NULL; /* Local variables (re-initialised by open_errorlog() function) */ /*+ The file handle for the error log file. +*/ static FILE *errorlogfile=NULL; /*+ The file descriptor for the binary error log file. +*/ static int errorbinfile=-1; /*+ The offset of the error message in the error log file. +*/ static offset_t errorfileoffset=0; /*++++++++++++++++++++++++++++++++++++++ Create the error log file. const char *filename The name of the file to create. int append The option to append to an existing file. int bin The option to enable a binary log file. ++++++++++++++++++++++++++++++++++++++*/ void open_errorlog(const char *filename,int append,int bin) { /* Text log file */ errorlogfilename=(char*)malloc(strlen(filename)+8); strcpy(errorlogfilename,filename); #if defined(_MSC_VER) || defined(__MINGW32__) errorlogfile=fopen(errorlogfilename,append?"ab":"wb"); #else errorlogfile=fopen(errorlogfilename,append?"a" :"w" ); #endif if(!errorlogfile) { fprintf(stderr,"Cannot open file '%s' for writing [%s].\n",errorlogfilename,strerror(errno)); exit(EXIT_FAILURE); } /* Binary log file */ if(bin) { errorbinfilename=(char*)malloc(strlen(filename)+8); sprintf(errorbinfilename,"%s.tmp",filename); errorfileoffset=0; if(append) { if(ExistsFile(filename)) errorfileoffset=SizeFile(filename); errorbinfile=OpenFileBufferedAppend(errorbinfilename); } else errorbinfile=OpenFileBufferedNew(errorbinfilename); } else errorbinfile=-1; } /*++++++++++++++++++++++++++++++++++++++ Close the error log file. ++++++++++++++++++++++++++++++++++++++*/ void close_errorlog(void) { if(errorlogfile) { fclose(errorlogfile); if(errorbinfile!=-1) CloseFileBuffered(errorbinfile); } } /*++++++++++++++++++++++++++++++++++++++ Log a message to the error log file. const char *format The format string. ... The other arguments. ++++++++++++++++++++++++++++++++++++++*/ void logerror(const char *format, ...) { va_list ap; if(!errorlogfile) return; va_start(ap,format); errorfileoffset+=vfprintf(errorlogfile,format,ap); va_end(ap); } /*++++++++++++++++++++++++++++++++++++++ Store the node information in the binary log file for this message. node_t logerror_node Returns the node identifier. node_t id The node identifier. ++++++++++++++++++++++++++++++++++++++*/ node_t logerror_node(node_t id) { if(errorbinfile!=-1) { ErrorLogObject error={0}; error.id=id; error.type='N'; error.offset=errorfileoffset; WriteFileBuffered(errorbinfile,&error,sizeof(ErrorLogObject)); } return(id); } /*++++++++++++++++++++++++++++++++++++++ Store the way information in the binary log file for this message. way_t logerror_way Returns the way identifier. way_t id The way identifier. ++++++++++++++++++++++++++++++++++++++*/ way_t logerror_way(way_t id) { if(errorbinfile!=-1) { ErrorLogObject error={0}; error.id=id; error.type='W'; error.offset=errorfileoffset; WriteFileBuffered(errorbinfile,&error,sizeof(ErrorLogObject)); } return(id); } /*++++++++++++++++++++++++++++++++++++++ Store the relation information in the binary log file for this message. relation_t logerror_relation Returns the relation identifier. relation_t id The relation identifier. ++++++++++++++++++++++++++++++++++++++*/ relation_t logerror_relation(relation_t id) { if(errorbinfile!=-1) { ErrorLogObject error={0}; error.id=id; error.type='R'; error.offset=errorfileoffset; WriteFileBuffered(errorbinfile,&error,sizeof(ErrorLogObject)); } return(id); } routino-3.0/src/nodesx.c 644 233 144 53131 12563633051 10505 0/*************************************** Extented Node data type functions. Part of the Routino routing software. ******************/ /****************** This file Copyright 2008-2015 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #include #include #include "types.h" #include "nodes.h" #include "typesx.h" #include "nodesx.h" #include "segmentsx.h" #include "waysx.h" #include "files.h" #include "logging.h" #include "sorting.h" /* Global variables */ /*+ The command line '--tmpdir' option or its default value. +*/ extern char *option_tmpdirname; /* Local variables */ /*+ Temporary file-local variables for use by the sort functions (re-initialised for each sort). +*/ static NodesX *sortnodesx; static latlong_t lat_min,lat_max,lon_min,lon_max; /* Local functions */ static int sort_by_id(NodeX *a,NodeX *b); static int deduplicate_and_index_by_id(NodeX *nodex,index_t index); static int update_id(NodeX *nodex,index_t index); static int sort_by_lat_long(NodeX *a,NodeX *b); static int index_by_lat_long(NodeX *nodex,index_t index); /*++++++++++++++++++++++++++++++++++++++ Allocate a new node list (create a new file or open an existing one). NodesX *NewNodeList Returns a pointer to the node list. int append Set to 1 if the file is to be opened for appending. int readonly Set to 1 if the file is to be opened for reading. ++++++++++++++++++++++++++++++++++++++*/ NodesX *NewNodeList(int append,int readonly) { NodesX *nodesx; nodesx=(NodesX*)calloc(1,sizeof(NodesX)); logassert(nodesx,"Failed to allocate memory (try using slim mode?)"); /* Check calloc() worked */ nodesx->filename =(char*)malloc(strlen(option_tmpdirname)+32); nodesx->filename_tmp=(char*)malloc(strlen(option_tmpdirname)+40); /* allow %p to be up to 20 bytes */ sprintf(nodesx->filename ,"%s/nodesx.parsed.mem",option_tmpdirname); sprintf(nodesx->filename_tmp,"%s/nodesx.%p.tmp" ,option_tmpdirname,(void*)nodesx); if(append || readonly) if(ExistsFile(nodesx->filename)) { offset_t size; size=SizeFile(nodesx->filename); nodesx->number=size/sizeof(NodeX); RenameFile(nodesx->filename,nodesx->filename_tmp); } if(append) nodesx->fd=OpenFileBufferedAppend(nodesx->filename_tmp); else if(!readonly) nodesx->fd=OpenFileBufferedNew(nodesx->filename_tmp); else nodesx->fd=-1; #if SLIM nodesx->cache=NewNodeXCache(); log_malloc(nodesx->cache,sizeof(*nodesx->cache)); #endif return(nodesx); } /*++++++++++++++++++++++++++++++++++++++ Free a node list. NodesX *nodesx The set of nodes to be freed. int keep If set then the results file is to be kept. ++++++++++++++++++++++++++++++++++++++*/ void FreeNodeList(NodesX *nodesx,int keep) { if(keep) RenameFile(nodesx->filename_tmp,nodesx->filename); else DeleteFile(nodesx->filename_tmp); free(nodesx->filename); free(nodesx->filename_tmp); if(nodesx->idata) { log_free(nodesx->idata); free(nodesx->idata); } if(nodesx->gdata) { log_free(nodesx->gdata); free(nodesx->gdata); } if(nodesx->pdata) { log_free(nodesx->pdata); free(nodesx->pdata); } if(nodesx->super) { log_free(nodesx->super); free(nodesx->super); } #if SLIM log_free(nodesx->cache); DeleteNodeXCache(nodesx->cache); #endif free(nodesx); } /*++++++++++++++++++++++++++++++++++++++ Append a single node to an unsorted node list. NodesX *nodesx The set of nodes to modify. node_t id The node identifier from the original OSM data. double latitude The latitude of the node. double longitude The longitude of the node. transports_t allow The allowed traffic types through the node. nodeflags_t flags The flags to set for this node. ++++++++++++++++++++++++++++++++++++++*/ void AppendNodeList(NodesX *nodesx,node_t id,double latitude,double longitude,transports_t allow,nodeflags_t flags) { NodeX nodex; nodex.id=id; nodex.latitude =radians_to_latlong(latitude); nodex.longitude=radians_to_latlong(longitude); nodex.allow=allow; nodex.flags=flags; WriteFileBuffered(nodesx->fd,&nodex,sizeof(NodeX)); nodesx->number++; logassert(nodesx->numberfd!=-1) nodesx->fd=CloseFileBuffered(nodesx->fd); } /*++++++++++++++++++++++++++++++++++++++ Find a particular node index. index_t IndexNodeX Returns the index of the extended node with the specified id. NodesX *nodesx The set of nodes to use. node_t id The node id to look for. ++++++++++++++++++++++++++++++++++++++*/ index_t IndexNodeX(NodesX *nodesx,node_t id) { index_t start=0; index_t end=nodesx->number-1; index_t mid; if(nodesx->number==0) /* No nodes */ return(NO_NODE); if(ididata[start]) /* Key is before start */ return(NO_NODE); if(id>nodesx->idata[end]) /* Key is after end */ return(NO_NODE); /* Binary search - search key exact match only is required. * * # <- start | Check mid and move start or end if it doesn't match * # | * # | Since an exact match is wanted we can set end=mid-1 * # <- mid | or start=mid+1 because we know that mid doesn't match. * # | * # | Eventually either end=start or end=start+1 and one of * # <- end | start or end is the wanted one. */ do { mid=(start+end)/2; /* Choose mid point */ if(nodesx->idata[mid]idata[mid]>id) /* Mid point is too high */ end=mid?(mid-1):mid; else /* Mid point is correct */ return(mid); } while((end-start)>1); if(nodesx->idata[start]==id) /* Start is correct */ return(start); if(nodesx->idata[end]==id) /* End is correct */ return(end); return(NO_NODE); } /*++++++++++++++++++++++++++++++++++++++ Sort the node list. NodesX *nodesx The set of nodes to modify. ++++++++++++++++++++++++++++++++++++++*/ void SortNodeList(NodesX *nodesx) { int fd; index_t xnumber; /* Print the start message */ printf_first("Sorting Nodes"); /* Re-open the file read-only and a new file writeable */ fd=ReplaceFileBuffered(nodesx->filename_tmp,&nodesx->fd); /* Allocate the array of indexes */ nodesx->idata=(node_t*)malloc(nodesx->number*sizeof(node_t)); log_malloc(nodesx->idata,nodesx->number*sizeof(node_t)); logassert(nodesx->idata,"Failed to allocate memory (try using slim mode?)"); /* Check malloc() worked */ /* Sort the nodes by ID and index them */ xnumber=nodesx->number; sortnodesx=nodesx; nodesx->number=filesort_fixed(nodesx->fd,fd,sizeof(NodeX),NULL, (int (*)(const void*,const void*))sort_by_id, (int (*)(void*,index_t))deduplicate_and_index_by_id); nodesx->knumber=nodesx->number; /* Close the files */ nodesx->fd=CloseFileBuffered(nodesx->fd); CloseFileBuffered(fd); /* Print the final message */ printf_last("Sorted Nodes: Nodes=%"Pindex_t" Duplicates=%"Pindex_t,xnumber,xnumber-nodesx->number); } /*++++++++++++++++++++++++++++++++++++++ Sort the nodes into id order. int sort_by_id Returns the comparison of the id fields. NodeX *a The first extended node. NodeX *b The second extended node. ++++++++++++++++++++++++++++++++++++++*/ static int sort_by_id(NodeX *a,NodeX *b) { node_t a_id=a->id; node_t b_id=b->id; if(a_idb_id) return(1); else return(-FILESORT_PRESERVE_ORDER(a,b)); /* latest version first */ } /*++++++++++++++++++++++++++++++++++++++ Create the index of identifiers and discard duplicate nodes. int deduplicate_and_index_by_id Return 1 if the value is to be kept, otherwise 0. NodeX *nodex The extended node. index_t index The number of sorted nodes that have already been written to the output file. ++++++++++++++++++++++++++++++++++++++*/ static int deduplicate_and_index_by_id(NodeX *nodex,index_t index) { static node_t previd; /* internal variable (reset by first call in each sort; index==0) */ if(index==0 || nodex->id!=previd) { previd=nodex->id; if(nodex->flags&NODE_DELETED) return(0); else { sortnodesx->idata[index]=nodex->id; return(1); } } else return(0); } /*++++++++++++++++++++++++++++++++++++++ Remove any nodes that are not part of a highway. NodesX *nodesx The set of nodes to modify. WaysX *waysx The set of ways to use. int keep If set to 1 then keep the old data file otherwise delete it. ++++++++++++++++++++++++++++++++++++++*/ void RemoveNonHighwayNodes(NodesX *nodesx,WaysX *waysx,int keep) { BitMask *usednode; NodeX nodex; index_t i,total=0,highway=0,nothighway=0; int fd; /* Print the start message */ printf_first("Checking Ways for unused Nodes: Ways=0 Highway Nodes=0"); /* Allocate the node usage bitmask */ usednode=AllocBitMask(nodesx->number); log_malloc(usednode,LengthBitMask(nodesx->number)*sizeof(BitMask)); logassert(usednode,"Failed to allocate memory (try using slim mode?)"); /* Check AllocBitMask() worked */ /* Re-open the file read-only */ waysx->fd=ReOpenFileBuffered(waysx->filename_tmp); /* Loop through the ways and mark the used nodes */ for(i=0;inumber;i++) { WayX wayx; FILESORT_VARINT waysize; node_t node; ReadFileBuffered(waysx->fd,&waysize,FILESORT_VARSIZE); ReadFileBuffered(waysx->fd,&wayx,sizeof(WayX)); while(!ReadFileBuffered(waysx->fd,&node,sizeof(node_t)) && node!=NO_NODE_ID) { index_t index=IndexNodeX(nodesx,node); waysize-=sizeof(node_t); if(index!=NO_NODE) { if(!IsBitSet(usednode,index)) highway++; SetBit(usednode,index); } } waysize-=sizeof(node_t)+sizeof(WayX); SkipFileBuffered(waysx->fd,waysize); if(!((i+1)%1000)) printf_middle("Checking Ways for unused Nodes: Ways=%"Pindex_t" Highway Nodes=%"Pindex_t,i+1,highway); } /* Free the now-unneeded index */ log_free(nodesx->idata); free(nodesx->idata); nodesx->idata=NULL; /* Close the file */ waysx->fd=CloseFileBuffered(waysx->fd); /* Print the final message */ printf_last("Checked Ways for unused Nodes: Ways=%"Pindex_t" Highway Nodes=%"Pindex_t,waysx->number,highway); /* Print the start message */ printf_first("Removing unused Nodes: Nodes=0"); /* Allocate the array of indexes */ nodesx->idata=(node_t*)malloc(highway*sizeof(node_t)); log_malloc(nodesx->idata,highway*sizeof(node_t)); logassert(nodesx->idata,"Failed to allocate memory (try using slim mode?)"); /* Check malloc() worked */ highway=0; /* Re-open the file read-only and a new file writeable */ if(keep) { RenameFile(nodesx->filename_tmp,nodesx->filename); nodesx->fd=ReOpenFileBuffered(nodesx->filename); fd=OpenFileBufferedNew(nodesx->filename_tmp); } else fd=ReplaceFileBuffered(nodesx->filename_tmp,&nodesx->fd); /* Modify the on-disk image */ while(!ReadFileBuffered(nodesx->fd,&nodex,sizeof(NodeX))) { if(!IsBitSet(usednode,total)) nothighway++; else { nodesx->idata[highway]=nodex.id; WriteFileBuffered(fd,&nodex,sizeof(NodeX)); highway++; } total++; if(!(total%10000)) printf_middle("Removing unused Nodes: Nodes=%"Pindex_t" Highway=%"Pindex_t" not-Highway=%"Pindex_t,total,highway,nothighway); } nodesx->number=highway; /* Close the files */ nodesx->fd=CloseFileBuffered(nodesx->fd); CloseFileBuffered(fd); /* Free the now-unneeded index */ log_free(usednode); free(usednode); /* Print the final message */ printf_last("Removed unused Nodes: Nodes=%"Pindex_t" Highway=%"Pindex_t" not-Highway=%"Pindex_t,total,highway,nothighway); } /*++++++++++++++++++++++++++++++++++++++ Remove any nodes that have been pruned. NodesX *nodesx The set of nodes to prune. SegmentsX *segmentsx The set of segments to use. ++++++++++++++++++++++++++++++++++++++*/ void RemovePrunedNodes(NodesX *nodesx,SegmentsX *segmentsx) { NodeX nodex; index_t total=0,pruned=0,notpruned=0; int fd; if(nodesx->number==0) return; /* Print the start message */ printf_first("Deleting Pruned Nodes: Nodes=0 Pruned=0"); /* Allocate the array of indexes */ nodesx->pdata=(index_t*)malloc(nodesx->number*sizeof(index_t)); log_malloc(nodesx->pdata,nodesx->number*sizeof(index_t)); logassert(nodesx->pdata,"Failed to allocate memory (try using slim mode?)"); /* Check malloc() worked */ /* Re-open the file read-only and a new file writeable */ fd=ReplaceFileBuffered(nodesx->filename_tmp,&nodesx->fd); /* Modify the on-disk image */ while(!ReadFileBuffered(nodesx->fd,&nodex,sizeof(NodeX))) { if(segmentsx->firstnode[total]==NO_SEGMENT) { pruned++; nodesx->pdata[total]=NO_NODE; } else { nodesx->pdata[total]=notpruned; WriteFileBuffered(fd,&nodex,sizeof(NodeX)); notpruned++; } total++; if(!(total%10000)) printf_middle("Deleting Pruned Nodes: Nodes=%"Pindex_t" Pruned=%"Pindex_t,total,pruned); } nodesx->number=notpruned; /* Close the files */ nodesx->fd=CloseFileBuffered(nodesx->fd); CloseFileBuffered(fd); /* Free the no-longer required memory */ if(segmentsx->firstnode) { log_free(segmentsx->firstnode); free(segmentsx->firstnode); segmentsx->firstnode=NULL; } /* Print the final message */ printf_last("Deleted Pruned Nodes: Nodes=%"Pindex_t" Pruned=%"Pindex_t,total,pruned); } /*++++++++++++++++++++++++++++++++++++++ Sort the node list geographically. NodesX *nodesx The set of nodes to modify. ++++++++++++++++++++++++++++++++++++++*/ void SortNodeListGeographically(NodesX *nodesx) { int fd; ll_bin_t lat_min_bin,lat_max_bin,lon_min_bin,lon_max_bin; if(nodesx->number==0) return; /* Print the start message */ printf_first("Sorting Nodes Geographically"); /* Work out the range of data */ lat_min=radians_to_latlong( 2); lat_max=radians_to_latlong(-2); lon_min=radians_to_latlong( 4); lon_max=radians_to_latlong(-4); /* Allocate the memory for the geographical index array */ nodesx->gdata=(index_t*)malloc(nodesx->number*sizeof(index_t)); log_malloc(nodesx->gdata,nodesx->number*sizeof(index_t)); logassert(nodesx->gdata,"Failed to allocate memory (try using slim mode?)"); /* Check malloc() worked */ /* Re-open the file read-only and a new file writeable */ fd=ReplaceFileBuffered(nodesx->filename_tmp,&nodesx->fd); /* Sort nodes geographically and index them */ sortnodesx=nodesx; filesort_fixed(nodesx->fd,fd,sizeof(NodeX),(int (*)(void*,index_t))update_id, (int (*)(const void*,const void*))sort_by_lat_long, (int (*)(void*,index_t))index_by_lat_long); /* Close the files */ nodesx->fd=CloseFileBuffered(nodesx->fd); CloseFileBuffered(fd); /* Work out the number of bins */ if(nodesx->super) { lat_min_bin=latlong_to_bin(lat_min); lon_min_bin=latlong_to_bin(lon_min); lat_max_bin=latlong_to_bin(lat_max); lon_max_bin=latlong_to_bin(lon_max); nodesx->latzero=lat_min_bin; nodesx->lonzero=lon_min_bin; nodesx->latbins=(lat_max_bin-lat_min_bin)+1; nodesx->lonbins=(lon_max_bin-lon_min_bin)+1; } /* Free the memory */ if(nodesx->super) { log_free(nodesx->super); free(nodesx->super); nodesx->super=NULL; } /* Print the final message */ printf_last("Sorted Nodes Geographically: Nodes=%"Pindex_t,nodesx->number); } /*++++++++++++++++++++++++++++++++++++++ Update the node ids. int update_id Return 1 if the value is to be kept, otherwise 0. NodeX *nodex The extended node. index_t index The number of unsorted nodes that have been read from the input file. ++++++++++++++++++++++++++++++++++++++*/ static int update_id(NodeX *nodex,index_t index) { nodex->id=index; if(sortnodesx->super && IsBitSet(sortnodesx->super,index)) nodex->flags|=NODE_SUPER; return(1); } /*++++++++++++++++++++++++++++++++++++++ Sort the nodes into latitude and longitude order (first by longitude bin number, then by latitude bin number and then by exact longitude and then by exact latitude). int sort_by_lat_long Returns the comparison of the latitude and longitude fields. NodeX *a The first extended node. NodeX *b The second extended node. ++++++++++++++++++++++++++++++++++++++*/ static int sort_by_lat_long(NodeX *a,NodeX *b) { ll_bin_t a_lon=latlong_to_bin(a->longitude); ll_bin_t b_lon=latlong_to_bin(b->longitude); if(a_lonb_lon) return(1); else { ll_bin_t a_lat=latlong_to_bin(a->latitude); ll_bin_t b_lat=latlong_to_bin(b->latitude); if(a_latb_lat) return(1); else { if(a->longitudelongitude) return(-1); else if(a->longitude>b->longitude) return(1); else { if(a->latitudelatitude) return(-1); else if(a->latitude>b->latitude) return(1); } return(FILESORT_PRESERVE_ORDER(a,b)); } } } /*++++++++++++++++++++++++++++++++++++++ Create the index between the sorted and unsorted nodes. int index_by_lat_long Return 1 if the value is to be kept, otherwise 0. NodeX *nodex The extended node. index_t index The number of sorted nodes that have already been written to the output file. ++++++++++++++++++++++++++++++++++++++*/ static int index_by_lat_long(NodeX *nodex,index_t index) { sortnodesx->gdata[nodex->id]=index; if(sortnodesx->super) { if(nodex->latitudelatitude; if(nodex->latitude>lat_max) lat_max=nodex->latitude; if(nodex->longitudelongitude; if(nodex->longitude>lon_max) lon_max=nodex->longitude; } return(1); } /*++++++++++++++++++++++++++++++++++++++ Save the final node list database to a file. NodesX *nodesx The set of nodes to save. const char *filename The name of the file to save. SegmentsX *segmentsx The set of segments to use. ++++++++++++++++++++++++++++++++++++++*/ void SaveNodeList(NodesX *nodesx,const char *filename,SegmentsX *segmentsx) { index_t i; int fd; NodesFile nodesfile={0}; index_t super_number=0; ll_bin2_t latlonbin=0,maxlatlonbins; index_t *offsets; /* Print the start message */ printf_first("Writing Nodes: Nodes=0"); /* Allocate the memory for the geographical offsets array */ offsets=(index_t*)malloc((nodesx->latbins*nodesx->lonbins+1)*sizeof(index_t)); logassert(offsets,"Failed to allocate memory (try using slim mode?)"); /* Check malloc() worked */ latlonbin=0; /* Re-open the file */ nodesx->fd=ReOpenFileBuffered(nodesx->filename_tmp); /* Write out the nodes data */ fd=OpenFileBufferedNew(filename); SeekFileBuffered(fd,sizeof(NodesFile)+(nodesx->latbins*nodesx->lonbins+1)*sizeof(index_t)); for(i=0;inumber;i++) { NodeX nodex; Node node={0}; ll_bin_t latbin,lonbin; ll_bin2_t llbin; ReadFileBuffered(nodesx->fd,&nodex,sizeof(NodeX)); /* Create the Node */ node.latoffset=latlong_to_off(nodex.latitude); node.lonoffset=latlong_to_off(nodex.longitude); node.firstseg=segmentsx->firstnode[i]; node.allow=nodex.allow; node.flags=nodex.flags; if(node.flags&NODE_SUPER) super_number++; /* Work out the offsets */ latbin=latlong_to_bin(nodex.latitude )-nodesx->latzero; lonbin=latlong_to_bin(nodex.longitude)-nodesx->lonzero; llbin=lonbin*nodesx->latbins+latbin; for(;latlonbin<=llbin;latlonbin++) offsets[latlonbin]=i; /* Write the data */ WriteFileBuffered(fd,&node,sizeof(Node)); if(!((i+1)%10000)) printf_middle("Writing Nodes: Nodes=%"Pindex_t,i+1); } /* Close the file */ nodesx->fd=CloseFileBuffered(nodesx->fd); /* Finish off the offset indexing and write them out */ maxlatlonbins=nodesx->latbins*nodesx->lonbins; for(;latlonbin<=maxlatlonbins;latlonbin++) offsets[latlonbin]=nodesx->number; SeekFileBuffered(fd,sizeof(NodesFile)); WriteFileBuffered(fd,offsets,(nodesx->latbins*nodesx->lonbins+1)*sizeof(index_t)); free(offsets); /* Write out the header structure */ nodesfile.number=nodesx->number; nodesfile.snumber=super_number; nodesfile.latbins=nodesx->latbins; nodesfile.lonbins=nodesx->lonbins; nodesfile.latzero=nodesx->latzero; nodesfile.lonzero=nodesx->lonzero; SeekFileBuffered(fd,0); WriteFileBuffered(fd,&nodesfile,sizeof(NodesFile)); CloseFileBuffered(fd); /* Free the memory in the segments */ log_free(segmentsx->firstnode); free(segmentsx->firstnode); segmentsx->firstnode=NULL; /* Print the final message */ printf_last("Wrote Nodes: Nodes=%"Pindex_t,nodesx->number); } routino-3.0/src/errorlog.h 644 233 144 14565 12550223461 11051 0/*************************************** Header file for error log file data types and associated function prototypes. Part of the Routino routing software. ******************/ /****************** This file Copyright 2013-2015 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #ifndef ERRORLOG_H #define ERRORLOG_H /*+ To stop multiple inclusions. +*/ #include #include #include "types.h" #include "typesx.h" #include "files.h" /*+ A structure containing information for an error message in the file. +*/ typedef struct _ErrorLog { ll_off_t latoffset; /*+ The error message latitude offset within its bin. +*/ ll_off_t lonoffset; /*+ The error message longitude offset within its bin. +*/ uint32_t offset; /*+ The offset of the error message from the beginning of the text section. +*/ uint32_t length; /*+ The length of the error message in the text section. +*/ } ErrorLog; /*+ A structure containing the header from the error log file. +*/ typedef struct _ErrorLogsFile { index_t number; /*+ The total number of error messages. +*/ index_t number_geo; /*+ The number of error messages with a geographical location. +*/ index_t number_nongeo; /*+ The number of error messages without a geographical location. +*/ ll_bin_t latbins; /*+ The number of bins containing latitude. +*/ ll_bin_t lonbins; /*+ The number of bins containing longitude. +*/ ll_bin_t latzero; /*+ The bin number of the furthest south bin. +*/ ll_bin_t lonzero; /*+ The bin number of the furthest west bin. +*/ } ErrorLogsFile; /*+ A structure containing a set of error log messages read from the file. +*/ typedef struct _ErrorLogs { ErrorLogsFile file; /*+ The header data from the file. +*/ #if !SLIM char *data; /*+ The memory mapped data in the file. +*/ index_t *offsets; /*+ A pointer to the array of offsets in the file. +*/ ErrorLog *errorlogs_geo; /*+ A pointer to the array of geographical error logs in the file. +*/ ErrorLog *errorlogs_nongeo; /*+ A pointer to the array of non-geographical error logs in the file. +*/ char *strings; /*+ A pointer to the array of error strings in the file. +*/ #else int fd; /*+ The file descriptor for the file. +*/ offset_t offsetsoffset; /*+ An allocated array with a copy of the file offsets. +*/ offset_t errorlogsoffset_geo; /*+ The offset of the geographical error logs within the file. +*/ offset_t errorlogsoffset_nongeo; /*+ The offset of the non-geographical error logs within the file. +*/ offset_t stringsoffset; /*+ The offset of the error strings within the file. +*/ ErrorLog cached[2]; /*+ Some cached error logs read from the file in slim mode. +*/ char cachestring[1024]; /*+ A cached copy of the error string read from the file in slim mode. +*/ #endif } ErrorLogs; /* Error log functions in errorlog.c */ ErrorLogs *LoadErrorLogs(const char *filename); void DestroyErrorLogs(ErrorLogs *errorlogs); void GetErrorLogLatLong(ErrorLogs *errorlogs,index_t index,ErrorLog *errorlogp,double *latitude,double *longitude); /* Macros and inline functions */ #if !SLIM /*+ Return an ErrorLog pointer given a set of errorlogs and an index. +*/ #define LookupErrorLog(xxx,yyy,ppp) (&(xxx)->errorlogs_geo[yyy]) /*+ Return the offset of a geographical region given a set of errorlogs. +*/ #define LookupErrorLogOffset(xxx,yyy) ((xxx)->offsets[yyy]) /*+ Return the string for an error log. +*/ #define LookupErrorLogString(xxx,yyy) (&(xxx)->strings[(xxx)->errorlogs_geo[yyy].offset]) #else /* Prototypes */ static inline ErrorLog *LookupErrorLog(ErrorLogs *errorlogs,index_t index,int position); static inline index_t LookupErrorLogOffset(ErrorLogs *errorlogs,index_t index); static inline char *LookupErrorLogString(ErrorLogs *errorlogs,index_t index); /* Inline functions */ /*++++++++++++++++++++++++++++++++++++++ Find the ErrorLog information for a particular error log. ErrorLog *LookupErrorLog Returns a pointer to the cached error log information. ErrorLogs *errorlogs The set of errorlogs to use. index_t index The index of the error log. int position The position in the cache to store the value. ++++++++++++++++++++++++++++++++++++++*/ static inline ErrorLog *LookupErrorLog(ErrorLogs *errorlogs,index_t index,int position) { SlimFetch(errorlogs->fd,&errorlogs->cached[position-1],sizeof(ErrorLog),errorlogs->errorlogsoffset_geo+(offset_t)index*sizeof(ErrorLog)); return(&errorlogs->cached[position-1]); } /*++++++++++++++++++++++++++++++++++++++ Find the offset of error logs in a geographical region. index_t LookupErrorLogOffset Returns the index offset. ErrorLogs *errorlogs The set of error logs to use. index_t index The index of the offset. ++++++++++++++++++++++++++++++++++++++*/ static inline index_t LookupErrorLogOffset(ErrorLogs *errorlogs,index_t index) { index_t offset; SlimFetch(errorlogs->fd,&offset,sizeof(index_t),errorlogs->offsetsoffset+(offset_t)index*sizeof(index_t)); return(offset); } /*++++++++++++++++++++++++++++++++++++++ Find the string associated with a particular error log. char *LookupErrorLogString Returns the error string. ErrorLogs *errorlogs The set of error logs to use. index_t index The index of the string. ++++++++++++++++++++++++++++++++++++++*/ static inline char *LookupErrorLogString(ErrorLogs *errorlogs,index_t index) { ErrorLog *errorlog=LookupErrorLog(errorlogs,index,2); SlimFetch(errorlogs->fd,errorlogs->cachestring,errorlog->length,errorlogs->stringsoffset+errorlog->offset); return(errorlogs->cachestring); } #endif #endif /* ERRORLOG_H */ routino-3.0/src/mman-win32.c 644 233 144 12565 12531126220 11071 0/*************************************** Windows 32 memory management functions from https://code.google.com/p/mman-win32 File header comment created by Andrew M. Bishop, all source code unchanged from original. ******************/ /****************** Copyright (c) 2010,2012 Viktor Kutuzov Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ***************************************/ #include #include #include #include "mman-win32.h" #ifndef FILE_MAP_EXECUTE #define FILE_MAP_EXECUTE 0x0020 #endif /* FILE_MAP_EXECUTE */ static int __map_mman_error(const DWORD err, const int deferr) { if (err == 0) return 0; //TODO: implement return err; } static DWORD __map_mmap_prot_page(const int prot) { DWORD protect = 0; if (prot == PROT_NONE) return protect; if ((prot & PROT_EXEC) != 0) { protect = ((prot & PROT_WRITE) != 0) ? PAGE_EXECUTE_READWRITE : PAGE_EXECUTE_READ; } else { protect = ((prot & PROT_WRITE) != 0) ? PAGE_READWRITE : PAGE_READONLY; } return protect; } static DWORD __map_mmap_prot_file(const int prot) { DWORD desiredAccess = 0; if (prot == PROT_NONE) return desiredAccess; if ((prot & PROT_READ) != 0) desiredAccess |= FILE_MAP_READ; if ((prot & PROT_WRITE) != 0) desiredAccess |= FILE_MAP_WRITE; if ((prot & PROT_EXEC) != 0) desiredAccess |= FILE_MAP_EXECUTE; return desiredAccess; } void* mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off) { HANDLE fm, h; void * map = MAP_FAILED; #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable: 4293) #endif const DWORD dwFileOffsetLow = (sizeof(off_t) <= sizeof(DWORD)) ? (DWORD)off : (DWORD)(off & 0xFFFFFFFFL); const DWORD dwFileOffsetHigh = (sizeof(off_t) <= sizeof(DWORD)) ? (DWORD)0 : (DWORD)((off >> 32) & 0xFFFFFFFFL); const DWORD protect = __map_mmap_prot_page(prot); const DWORD desiredAccess = __map_mmap_prot_file(prot); const off_t maxSize = off + (off_t)len; const DWORD dwMaxSizeLow = (sizeof(off_t) <= sizeof(DWORD)) ? (DWORD)maxSize : (DWORD)(maxSize & 0xFFFFFFFFL); const DWORD dwMaxSizeHigh = (sizeof(off_t) <= sizeof(DWORD)) ? (DWORD)0 : (DWORD)((maxSize >> 32) & 0xFFFFFFFFL); #ifdef _MSC_VER #pragma warning(pop) #endif errno = 0; if (len == 0 /* Unsupported flag combinations */ || (flags & MAP_FIXED) != 0 /* Usupported protection combinations */ || prot == PROT_EXEC) { errno = EINVAL; return MAP_FAILED; } h = ((flags & MAP_ANONYMOUS) == 0) ? (HANDLE)_get_osfhandle(fildes) : INVALID_HANDLE_VALUE; if ((flags & MAP_ANONYMOUS) == 0 && h == INVALID_HANDLE_VALUE) { errno = EBADF; return MAP_FAILED; } fm = CreateFileMapping(h, NULL, protect, dwMaxSizeHigh, dwMaxSizeLow, NULL); if (fm == NULL) { errno = __map_mman_error(GetLastError(), EPERM); return MAP_FAILED; } map = MapViewOfFile(fm, desiredAccess, dwFileOffsetHigh, dwFileOffsetLow, len); CloseHandle(fm); if (map == NULL) { errno = __map_mman_error(GetLastError(), EPERM); return MAP_FAILED; } return map; } int munmap(void *addr, size_t len) { if (UnmapViewOfFile(addr)) return 0; errno = __map_mman_error(GetLastError(), EPERM); return -1; } int mprotect(void *addr, size_t len, int prot) { DWORD newProtect = __map_mmap_prot_page(prot); DWORD oldProtect = 0; if (VirtualProtect(addr, len, newProtect, &oldProtect)) return 0; errno = __map_mman_error(GetLastError(), EPERM); return -1; } int msync(void *addr, size_t len, int flags) { if (FlushViewOfFile(addr, len)) return 0; errno = __map_mman_error(GetLastError(), EPERM); return -1; } int mlock(const void *addr, size_t len) { if (VirtualLock((LPVOID)addr, len)) return 0; errno = __map_mman_error(GetLastError(), EPERM); return -1; } int munlock(const void *addr, size_t len) { if (VirtualUnlock((LPVOID)addr, len)) return 0; errno = __map_mman_error(GetLastError(), EPERM); return -1; } routino-3.0/src/errorlogx.c 644 233 144 62403 12563633053 11234 0/*************************************** Error log processing functions. Part of the Routino routing software. ******************/ /****************** This file Copyright 2013-2015 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #include "typesx.h" #include "nodesx.h" #include "waysx.h" #include "relationsx.h" #include "errorlogx.h" #include "errorlog.h" #include "files.h" #include "sorting.h" /* Global variables */ /*+ The name of the error log file. +*/ extern char *errorlogfilename; /*+ The name of the binary error log file. +*/ extern char *errorbinfilename; /* Local variables */ /*+ Temporary file-local variables for use by the sort functions (re-initialised for each sort). +*/ static latlong_t lat_min,lat_max,lon_min,lon_max; /* Local functions */ static void reindex_nodes(NodesX *nodesx); static void reindex_ways(WaysX *waysx); static void reindex_relations(RelationsX *relationsx); static int lookup_lat_long_node(NodesX *nodesx,node_t node,latlong_t *latitude,latlong_t *longitude); static int lookup_lat_long_way(WaysX *waysx,NodesX *nodesx,way_t way,latlong_t *latitude,latlong_t *longitude,index_t error); static int lookup_lat_long_relation(RelationsX *relationsx,WaysX *waysx,NodesX *nodesx,relation_t relation,latlong_t *latitude,latlong_t *longitude,index_t error); static int sort_by_lat_long(ErrorLogX *a,ErrorLogX *b); static int measure_lat_long(ErrorLogX *errorlogx,index_t index); /*++++++++++++++++++++++++++++++++++++++ Allocate a new error log list (create a new file). ErrorLogsX *NewErrorLogList Returns a pointer to the error log list. ++++++++++++++++++++++++++++++++++++++*/ ErrorLogsX *NewErrorLogList(void) { ErrorLogsX *errorlogsx; errorlogsx=(ErrorLogsX*)calloc(1,sizeof(ErrorLogsX)); logassert(errorlogsx,"Failed to allocate memory (try using slim mode?)"); /* Check calloc() worked */ return(errorlogsx); } /*++++++++++++++++++++++++++++++++++++++ Free an error log list. ErrorLogsX *errorlogsx The set of error logs to be freed. ++++++++++++++++++++++++++++++++++++++*/ void FreeErrorLogList(ErrorLogsX *errorlogsx) { free(errorlogsx); } /*++++++++++++++++++++++++++++++++++++++ Process the binary error log. ErrorLogsX *errorlogsx The set of error logs to update. NodesX *nodesx The set of nodes. WaysX *waysx The set of ways. RelationsX *relationsx The set of relations. ++++++++++++++++++++++++++++++++++++++*/ void ProcessErrorLogs(ErrorLogsX *errorlogsx,NodesX *nodesx,WaysX *waysx,RelationsX *relationsx) { int oldfd,newfd; uint32_t offset=0; int nerrorlogobjects=0; int finished; ErrorLogObject errorlogobjects[8]; /* Re-index the nodes, ways and relations */ printf_first("Re-indexing the Data: Nodes=0 Ways=0 Route-Relations=0 Turn-Relations=0"); reindex_nodes(nodesx); printf_middle("Re-indexing the Data: Nodes=%"Pindex_t" Ways=0 Route-Relations=0 Turn-Relations=0",nodesx->number); reindex_ways(waysx); printf_middle("Re-indexing the Data: Nodes=%"Pindex_t" Ways=%"Pindex_t" Route-Relations=0 Turn-Relations=0",nodesx->number,waysx->number); reindex_relations(relationsx); printf_last("Re-indexed the Data: Nodes=%"Pindex_t" Ways=%"Pindex_t" Route-Relations=%"Pindex_t" Turn-Relations=%"Pindex_t,nodesx->number,waysx->number,relationsx->rrnumber,relationsx->trnumber); /* Print the start message */ printf_first("Calculating Coordinates: Errors=0"); /* Map into memory / open the files */ #if !SLIM nodesx->data=MapFile(nodesx->filename); #else nodesx->fd=SlimMapFile(nodesx->filename); InvalidateNodeXCache(nodesx->cache); #endif waysx->fd=ReOpenFileBuffered(waysx->filename); relationsx->rrfd=ReOpenFileBuffered(relationsx->rrfilename); relationsx->trfd=ReOpenFileBuffered(relationsx->trfilename); /* Open the binary log file read-only and a new file writeable */ newfd=ReplaceFileBuffered(errorbinfilename,&oldfd); /* Loop through the file and merge the raw data into coordinates */ errorlogsx->number=0; do { ErrorLogObject errorlogobject; finished=ReadFileBuffered(oldfd,&errorlogobject,sizeof(ErrorLogObject)); if(finished) errorlogobject.offset=SizeFile(errorlogfilename); if(offset!=errorlogobject.offset) { ErrorLogX errorlogx; latlong_t errorlat=NO_LATLONG,errorlon=NO_LATLONG; /* Calculate suitable coordinates */ if(nerrorlogobjects==1) { if(errorlogobjects[0].type=='N') { node_t node=(node_t)errorlogobjects[0].id; lookup_lat_long_node(nodesx,node,&errorlat,&errorlon); } else if(errorlogobjects[0].type=='W') { way_t way=(way_t)errorlogobjects[0].id; lookup_lat_long_way(waysx,nodesx,way,&errorlat,&errorlon,errorlogsx->number); } else if(errorlogobjects[0].type=='R') { relation_t relation=(relation_t)errorlogobjects[0].type; lookup_lat_long_relation(relationsx,waysx,nodesx,relation,&errorlat,&errorlon,errorlogsx->number); } } else { latlong_t latitude[8],longitude[8]; int i; int ncoords=0,nnodes=0,nways=0,nrelations=0; for(i=0;inumber)) ncoords++; } } if(nrelations==0) /* only nodes and/or ways */ ; else if(ncoords) /* some good nodes and/or ways, possibly relations */ ; else /* if(nrelations) */ { for(i=0;inumber)) ncoords++; } } if(ncoords) { errorlat=0; errorlon=0; for(i=0;inumber++; offset=errorlogobject.offset; nerrorlogobjects=0; if(!(errorlogsx->number%10000)) printf_middle("Calculating Coordinates: Errors=%"Pindex_t,errorlogsx->number); } /* Store for later */ logassert(nerrorlogobjects<8,"Too many error log objects for one error message."); /* Only a limited amount of information stored. */ errorlogobjects[nerrorlogobjects]=errorlogobject; nerrorlogobjects++; } while(!finished); /* Unmap from memory / close the files */ #if !SLIM nodesx->data=UnmapFile(nodesx->data); #else nodesx->fd=SlimUnmapFile(nodesx->fd); #endif waysx->fd=CloseFileBuffered(waysx->fd); relationsx->rrfd=CloseFileBuffered(relationsx->rrfd); relationsx->trfd=CloseFileBuffered(relationsx->trfd); CloseFileBuffered(oldfd); CloseFileBuffered(newfd); /* Print the final message */ printf_last("Calculated Coordinates: Errors=%"Pindex_t,errorlogsx->number); } /*++++++++++++++++++++++++++++++++++++++ Re-index the nodes that were kept. NodesX *nodesx The set of nodes to process (contains the filename and number of nodes). ++++++++++++++++++++++++++++++++++++++*/ static void reindex_nodes(NodesX *nodesx) { int fd; index_t index=0; NodeX nodex; nodesx->number=nodesx->knumber; nodesx->idata=(node_t*)malloc(nodesx->number*sizeof(node_t)); log_malloc(nodesx->idata,nodesx->number*sizeof(node_t)); /* Get the node id for each node in the file. */ fd=ReOpenFileBuffered(nodesx->filename); while(!ReadFileBuffered(fd,&nodex,sizeof(NodeX))) { nodesx->idata[index]=nodex.id; index++; } CloseFileBuffered(fd); } /*++++++++++++++++++++++++++++++++++++++ Re-index the ways that were kept. WaysX *waysx The set of ways to process (contains the filename and number of ways). ++++++++++++++++++++++++++++++++++++++*/ static void reindex_ways(WaysX *waysx) { FILESORT_VARINT waysize; int fd; offset_t position=0; index_t index=0; waysx->number=waysx->knumber; waysx->idata=(way_t*)malloc(waysx->number*sizeof(way_t)); waysx->odata=(offset_t*)malloc(waysx->number*sizeof(offset_t)); log_malloc(waysx->idata,waysx->number*sizeof(way_t)); log_malloc(waysx->odata,waysx->number*sizeof(offset_t)); /* Get the way id and the offset for each way in the file */ fd=ReOpenFileBuffered(waysx->filename); while(!ReadFileBuffered(fd,&waysize,FILESORT_VARSIZE)) { WayX wayx; ReadFileBuffered(fd,&wayx,sizeof(WayX)); waysx->idata[index]=wayx.id; waysx->odata[index]=position+FILESORT_VARSIZE+sizeof(WayX); index++; SkipFileBuffered(fd,waysize-sizeof(WayX)); position+=waysize+FILESORT_VARSIZE; } CloseFileBuffered(fd); } /*++++++++++++++++++++++++++++++++++++++ Re-index the relations that were kept. RelationsX *relationsx The set of relations to process (contains the filenames and numbers of relations). ++++++++++++++++++++++++++++++++++++++*/ static void reindex_relations(RelationsX *relationsx) { FILESORT_VARINT relationsize; int fd; offset_t position=0; index_t index; TurnRelX turnrelx; /* Route relations */ relationsx->rrnumber=relationsx->rrknumber; relationsx->rridata=(relation_t*)malloc(relationsx->rrnumber*sizeof(relation_t)); relationsx->rrodata=(offset_t*)malloc(relationsx->rrnumber*sizeof(offset_t)); log_malloc(relationsx->rridata,relationsx->rrnumber*sizeof(relation_t)); log_malloc(relationsx->rrodata,relationsx->rrnumber*sizeof(offset_t)); /* Get the relation id and the offset for each relation in the file */ fd=ReOpenFileBuffered(relationsx->rrfilename); index=0; while(!ReadFileBuffered(fd,&relationsize,FILESORT_VARSIZE)) { RouteRelX routerelx; ReadFileBuffered(fd,&routerelx,sizeof(RouteRelX)); relationsx->rridata[index]=routerelx.id; relationsx->rrodata[index]=position+FILESORT_VARSIZE+sizeof(RouteRelX); index++; SkipFileBuffered(fd,relationsize-sizeof(RouteRelX)); position+=relationsize+FILESORT_VARSIZE; } CloseFileBuffered(fd); /* Turn relations */ relationsx->trnumber=relationsx->trknumber; relationsx->tridata=(relation_t*)malloc(relationsx->trnumber*sizeof(relation_t)); log_malloc(relationsx->tridata,relationsx->trnumber*sizeof(relation_t)); /* Get the relation id and the offset for each relation in the file */ fd=ReOpenFileBuffered(relationsx->trfilename); index=0; while(!ReadFileBuffered(fd,&turnrelx,sizeof(TurnRelX))) { relationsx->tridata[index]=turnrelx.id; index++; } CloseFileBuffered(fd); } /*++++++++++++++++++++++++++++++++++++++ Lookup a node's latitude and longitude. int lookup_lat_long_node Returns 1 if a node was found. NodesX *nodesx The set of nodes to use. node_t node The node number. latlong_t *latitude Returns the latitude. latlong_t *longitude Returns the longitude. ++++++++++++++++++++++++++++++++++++++*/ static int lookup_lat_long_node(NodesX *nodesx,node_t node,latlong_t *latitude,latlong_t *longitude) { index_t index=IndexNodeX(nodesx,node); if(index==NO_NODE) return 0; else { NodeX *nodex=LookupNodeX(nodesx,index,1); *latitude =nodex->latitude; *longitude=nodex->longitude; return 1; } } /*++++++++++++++++++++++++++++++++++++++ Lookup a way's latitude and longitude. int lookup_lat_long_way Returns 1 if a way was found. WaysX *waysx The set of ways to use. NodesX *nodesx The set of nodes to use. way_t way The way number. latlong_t *latitude Returns the latitude. latlong_t *longitude Returns the longitude. index_t error The index of the error in the complete set of errors. ++++++++++++++++++++++++++++++++++++++*/ static int lookup_lat_long_way(WaysX *waysx,NodesX *nodesx,way_t way,latlong_t *latitude,latlong_t *longitude,index_t error) { index_t index=IndexWayX(waysx,way); if(index==NO_WAY) return 0; else { int count=1; offset_t offset=waysx->odata[index]; node_t node1,node2,prevnode,node; latlong_t latitude1,longitude1,latitude2,longitude2; SeekFileBuffered(waysx->fd,offset); /* Choose a random pair of adjacent nodes */ if(ReadFileBuffered(waysx->fd,&node1,sizeof(node_t)) || node1==NO_NODE_ID) return 0; if(ReadFileBuffered(waysx->fd,&node2,sizeof(node_t)) || node2==NO_NODE_ID) return lookup_lat_long_node(nodesx,node1,latitude,longitude); prevnode=node2; while(!ReadFileBuffered(waysx->fd,&node,sizeof(node_t)) && node!=NO_NODE_ID) { count++; if((error%count)==0) /* A 1/count chance */ { node1=prevnode; node2=node; } prevnode=node; } if(!lookup_lat_long_node(nodesx,node1,&latitude1,&longitude1)) return lookup_lat_long_node(nodesx,node2,latitude,longitude); if(!lookup_lat_long_node(nodesx,node2,&latitude2,&longitude2)) return lookup_lat_long_node(nodesx,node1,latitude,longitude); *latitude =(latitude1 +latitude2 )/2; *longitude=(longitude1+longitude2)/2; return 1; } } /*++++++++++++++++++++++++++++++++++++++ Lookup a relation's latitude and longitude. int lookup_lat_long_relation Returns 1 if a relation was found. RelationsX *relationsx The set of relations to use. WaysX *waysx The set of ways to use. NodesX *nodesx The set of nodes to use. relation_t relation The relation number. latlong_t *latitude Returns the latitude. latlong_t *longitude Returns the longitude. index_t error The index of the error in the complete set of errors. ++++++++++++++++++++++++++++++++++++++*/ static int lookup_lat_long_relation(RelationsX *relationsx,WaysX *waysx,NodesX *nodesx,relation_t relation,latlong_t *latitude,latlong_t *longitude,index_t error) { index_t index=IndexRouteRelX(relationsx,relation); if(index==NO_RELATION) { index=IndexTurnRelX(relationsx,relation); if(index==NO_RELATION) return 0; else { TurnRelX turnrelx; SeekFileBuffered(relationsx->trfd,index*sizeof(TurnRelX)); ReadFileBuffered(relationsx->trfd,&turnrelx,sizeof(TurnRelX)); if(lookup_lat_long_node(nodesx,turnrelx.via,latitude,longitude)) return 1; if(lookup_lat_long_way(waysx,nodesx,turnrelx.from,latitude,longitude,error)) return 1; if(lookup_lat_long_way(waysx,nodesx,turnrelx.to,latitude,longitude,error)) return 1; return 0; } } else { int count; offset_t offset=relationsx->rrodata[index]; node_t node=NO_NODE_ID,tempnode; way_t way=NO_WAY_ID,tempway; relation_t relation=NO_RELATION_ID,temprelation; SeekFileBuffered(relationsx->rrfd,offset); /* Choose a random node */ count=0; while(!ReadFileBuffered(relationsx->rrfd,&tempnode,sizeof(node_t)) && tempnode!=NO_NODE_ID) { count++; if((error%count)==0) /* A 1/count chance */ node=tempnode; } if(lookup_lat_long_node(nodesx,node,latitude,longitude)) return 1; /* Choose a random way */ count=0; while(!ReadFileBuffered(relationsx->rrfd,&tempway,sizeof(way_t)) && tempway!=NO_WAY_ID) { count++; if((error%count)==0) /* A 1/count chance */ way=tempway; } if(lookup_lat_long_way(waysx,nodesx,way,latitude,longitude,error)) return 1; /* Choose a random relation */ count=0; while(!ReadFileBuffered(relationsx->rrfd,&temprelation,sizeof(relation_t)) && temprelation!=NO_RELATION_ID) { count++; if((error%count)==0) /* A 1/count chance */ relation=temprelation; } return lookup_lat_long_relation(relationsx,waysx,nodesx,relation,latitude,longitude,error); } } /*++++++++++++++++++++++++++++++++++++++ Sort the error logs geographically. ErrorLogsX *errorlogsx The set of error logs to sort. ++++++++++++++++++++++++++++++++++++++*/ void SortErrorLogsGeographically(ErrorLogsX *errorlogsx) { int oldfd,newfd; ll_bin_t lat_min_bin,lat_max_bin,lon_min_bin,lon_max_bin; /* Print the start message */ printf_first("Sorting Errors Geographically"); /* Work out the range of data */ lat_min=radians_to_latlong( 2); lat_max=radians_to_latlong(-2); lon_min=radians_to_latlong( 4); lon_max=radians_to_latlong(-4); /* Re-open the file read-only and a new file writeable */ newfd=ReplaceFileBuffered(errorbinfilename,&oldfd); /* Sort errors geographically */ filesort_fixed(oldfd,newfd,sizeof(ErrorLogX),NULL, (int (*)(const void*,const void*))sort_by_lat_long, (int (*)(void*,index_t))measure_lat_long); /* Close the files */ CloseFileBuffered(oldfd); CloseFileBuffered(newfd); /* Work out the number of bins */ lat_min_bin=latlong_to_bin(lat_min); lon_min_bin=latlong_to_bin(lon_min); lat_max_bin=latlong_to_bin(lat_max); lon_max_bin=latlong_to_bin(lon_max); errorlogsx->latzero=lat_min_bin; errorlogsx->lonzero=lon_min_bin; errorlogsx->latbins=(lat_max_bin-lat_min_bin)+1; errorlogsx->lonbins=(lon_max_bin-lon_min_bin)+1; /* Print the final message */ printf_last("Sorted Errors Geographically: Errors=%"Pindex_t,errorlogsx->number); } /*++++++++++++++++++++++++++++++++++++++ Sort the errors into latitude and longitude order (first by longitude bin number, then by latitude bin number and then by exact longitude and then by exact latitude). int sort_by_lat_long Returns the comparison of the latitude and longitude fields. ErrorLogX *a The first error location. ErrorLogX *b The second error location. ++++++++++++++++++++++++++++++++++++++*/ static int sort_by_lat_long(ErrorLogX *a,ErrorLogX *b) { ll_bin_t a_lon=latlong_to_bin(a->longitude); ll_bin_t b_lon=latlong_to_bin(b->longitude); if(a_lonb_lon) return(1); else { ll_bin_t a_lat=latlong_to_bin(a->latitude); ll_bin_t b_lat=latlong_to_bin(b->latitude); if(a_latb_lat) return(1); else { if(a->longitudelongitude) return(-1); else if(a->longitude>b->longitude) return(1); else { if(a->latitudelatitude) return(-1); else if(a->latitude>b->latitude) return(1); } return(FILESORT_PRESERVE_ORDER(a,b)); } } } /*++++++++++++++++++++++++++++++++++++++ Measure the extent of the data. int measure_lat_long Return 1 if the value is to be kept, otherwise 0. ErrorLogX *errorlogx The error location. index_t index The number of sorted error locations that have already been written to the output file. ++++++++++++++++++++++++++++++++++++++*/ static int measure_lat_long(ErrorLogX *errorlogx,index_t index) { if(errorlogx->latitude!=NO_LATLONG) { if(errorlogx->latitudelatitude; if(errorlogx->latitude>lat_max) lat_max=errorlogx->latitude; if(errorlogx->longitudelongitude; if(errorlogx->longitude>lon_max) lon_max=errorlogx->longitude; } return(1); } /*++++++++++++++++++++++++++++++++++++++ Save the binary error log. ErrorLogsX *errorlogsx The set of error logs to write. char *filename The name of the final file to write. ++++++++++++++++++++++++++++++++++++++*/ void SaveErrorLogs(ErrorLogsX *errorlogsx,char *filename) { ErrorLogsFile errorlogsfile; ErrorLogX errorlogx; int oldfd,newfd; ll_bin2_t latlonbin=0,maxlatlonbins; index_t *offsets; index_t number=0,number_geo=0,number_nongeo=0; offset_t size; /* Print the start message */ printf_first("Writing Errors: Geographical=0 Non-geographical=0"); /* Allocate the memory for the geographical offsets array */ offsets=(index_t*)malloc((errorlogsx->latbins*errorlogsx->lonbins+1)*sizeof(index_t)); logassert(offsets,"Failed to allocate memory (try using slim mode?)"); /* Check malloc() worked */ latlonbin=0; /* Re-open the file */ oldfd=ReOpenFileBuffered(errorbinfilename); newfd=OpenFileBufferedNew(filename); /* Write out the geographical errors */ SeekFileBuffered(newfd,sizeof(ErrorLogsFile)+(errorlogsx->latbins*errorlogsx->lonbins+1)*sizeof(index_t)); while(!ReadFileBuffered(oldfd,&errorlogx,sizeof(ErrorLogX))) { ErrorLog errorlog={0}; ll_bin_t latbin,lonbin; ll_bin2_t llbin; if(errorlogx.latitude==NO_LATLONG) continue; /* Create the ErrorLog */ errorlog.latoffset=latlong_to_off(errorlogx.latitude); errorlog.lonoffset=latlong_to_off(errorlogx.longitude); errorlog.offset=errorlogx.offset; errorlog.length=errorlogx.length; /* Work out the offsets */ latbin=latlong_to_bin(errorlogx.latitude )-errorlogsx->latzero; lonbin=latlong_to_bin(errorlogx.longitude)-errorlogsx->lonzero; llbin=lonbin*errorlogsx->latbins+latbin; for(;latlonbin<=llbin;latlonbin++) offsets[latlonbin]=number_geo; /* Write the data */ WriteFileBuffered(newfd,&errorlog,sizeof(ErrorLog)); number_geo++; number++; if(!(number%10000)) printf_middle("Writing Errors: Geographical=%"Pindex_t" Non-geographical=%"Pindex_t,number_geo,number_nongeo); } /* Write out the non-geographical errors */ SeekFileBuffered(oldfd,0); while(!ReadFileBuffered(oldfd,&errorlogx,sizeof(ErrorLogX))) { ErrorLog errorlog={0}; if(errorlogx.latitude!=NO_LATLONG) continue; /* Create the ErrorLog */ errorlog.latoffset=0; errorlog.lonoffset=0; errorlog.offset=errorlogx.offset; errorlog.length=errorlogx.length; /* Write the data */ WriteFileBuffered(newfd,&errorlog,sizeof(ErrorLog)); number_nongeo++; number++; if(!(number%10000)) printf_middle("Writing Errors: Geographical=%"Pindex_t" Non-geographical=%"Pindex_t,number_geo,number_nongeo); } /* Close the input file */ CloseFileBuffered(oldfd); DeleteFile(errorbinfilename); /* Append the text from the log file */ size=SizeFile(errorlogfilename); oldfd=ReOpenFileBuffered(errorlogfilename); while(size) { int i; char buffer[4096]; offset_t chunksize=(size>(offset_t)sizeof(buffer)?(offset_t)sizeof(buffer):size); ReadFileBuffered(oldfd,buffer,chunksize); for(i=0;ilatbins*errorlogsx->lonbins; for(;latlonbin<=maxlatlonbins;latlonbin++) offsets[latlonbin]=number_geo; SeekFileBuffered(newfd,sizeof(ErrorLogsFile)); WriteFileBuffered(newfd,offsets,(errorlogsx->latbins*errorlogsx->lonbins+1)*sizeof(index_t)); free(offsets); /* Write out the header structure */ errorlogsfile.number =number; errorlogsfile.number_geo =number_geo; errorlogsfile.number_nongeo=number_nongeo; errorlogsfile.latbins=errorlogsx->latbins; errorlogsfile.lonbins=errorlogsx->lonbins; errorlogsfile.latzero=errorlogsx->latzero; errorlogsfile.lonzero=errorlogsx->lonzero; SeekFileBuffered(newfd,0); WriteFileBuffered(newfd,&errorlogsfile,sizeof(ErrorLogsFile)); CloseFileBuffered(newfd); /* Print the final message */ printf_last("Wrote Errors: Geographical=%"Pindex_t" Non-geographical=%"Pindex_t,number_geo,number_nongeo); } routino-3.0/src/superx.h 644 233 144 2420 12064636364 10521 0/*************************************** Header for super-node and super-segment functions. Part of the Routino routing software. ******************/ /****************** This file Copyright 2008-2011 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #ifndef SUPERX_H #define SUPERX_H /*+ To stop multiple inclusions. +*/ #include "typesx.h" /* Functions in superx.c */ void ChooseSuperNodes(NodesX *nodesx,SegmentsX *segmentsx,WaysX *waysx); SegmentsX *CreateSuperSegments(NodesX *nodesx,SegmentsX *segmentsx,WaysX *waysx); SegmentsX *MergeSuperSegments(SegmentsX *segmentsx,SegmentsX *supersegmentsx); #endif /* SUPERX_H */ routino-3.0/src/segmentsx.c 644 233 144 62556 12563633051 11235 0/*************************************** Extended Segment data type functions. Part of the Routino routing software. ******************/ /****************** This file Copyright 2008-2015 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #include #include #include #include "types.h" #include "segments.h" #include "ways.h" #include "typesx.h" #include "nodesx.h" #include "segmentsx.h" #include "waysx.h" #include "files.h" #include "logging.h" #include "sorting.h" /* Global variables */ /*+ The command line '--tmpdir' option or its default value. +*/ extern char *option_tmpdirname; /* Local variables */ /*+ Temporary file-local variables for use by the sort functions (re-initialised for each sort). +*/ static NodesX *sortnodesx; static SegmentsX *sortsegmentsx; static WaysX *sortwaysx; /* Local functions */ static int sort_by_id(SegmentX *a,SegmentX *b); static int delete_pruned(SegmentX *segmentx,index_t index); static int deduplicate_super(SegmentX *segmentx,index_t index); static int geographically_index(SegmentX *segmentx,index_t index); static distance_t DistanceX(NodeX *nodex1,NodeX *nodex2); /*++++++++++++++++++++++++++++++++++++++ Allocate a new segment list (create a new file or open an existing one). SegmentsX *NewSegmentList Returns the segment list. ++++++++++++++++++++++++++++++++++++++*/ SegmentsX *NewSegmentList(void) { SegmentsX *segmentsx; segmentsx=(SegmentsX*)calloc(1,sizeof(SegmentsX)); logassert(segmentsx,"Failed to allocate memory (try using slim mode?)"); /* Check calloc() worked */ segmentsx->filename_tmp=(char*)malloc(strlen(option_tmpdirname)+40); /* allow %p to be up to 20 bytes */ sprintf(segmentsx->filename_tmp,"%s/segmentsx.%p.tmp",option_tmpdirname,(void*)segmentsx); segmentsx->fd=OpenFileBufferedNew(segmentsx->filename_tmp); #if SLIM segmentsx->cache=NewSegmentXCache(); log_malloc(segmentsx->cache,sizeof(*segmentsx->cache)); #endif return(segmentsx); } /*++++++++++++++++++++++++++++++++++++++ Free a segment list. SegmentsX *segmentsx The set of segments to be freed. ++++++++++++++++++++++++++++++++++++++*/ void FreeSegmentList(SegmentsX *segmentsx) { DeleteFile(segmentsx->filename_tmp); free(segmentsx->filename_tmp); if(segmentsx->usedway) { log_free(segmentsx->usedway); free(segmentsx->usedway); } if(segmentsx->firstnode) { log_free(segmentsx->firstnode); free(segmentsx->firstnode); } if(segmentsx->next1) { log_free(segmentsx->next1); free(segmentsx->next1); } #if SLIM log_free(segmentsx->cache); DeleteSegmentXCache(segmentsx->cache); #endif free(segmentsx); } /*++++++++++++++++++++++++++++++++++++++ Append a single segment to an unsorted segment list. SegmentsX *segmentsx The set of segments to modify. index_t way The index of the way that the segment belongs to. index_t node1 The index of the first node in the segment. index_t node2 The index of the second node in the segment. distance_t distance The distance between the nodes (or just the flags). ++++++++++++++++++++++++++++++++++++++*/ void AppendSegmentList(SegmentsX *segmentsx,index_t way,index_t node1,index_t node2,distance_t distance) { SegmentX segmentx; if(node1>node2) { index_t temp; temp=node1; node1=node2; node2=temp; if(distance&(ONEWAY_2TO1|ONEWAY_1TO2)) distance^=ONEWAY_2TO1|ONEWAY_1TO2; } segmentx.node1=node1; segmentx.node2=node2; segmentx.next2=NO_SEGMENT; segmentx.way=way; segmentx.distance=distance; WriteFileBuffered(segmentsx->fd,&segmentx,sizeof(SegmentX)); segmentsx->number++; logassert(segmentsx->numberfd!=-1) segmentsx->fd=CloseFileBuffered(segmentsx->fd); } /*++++++++++++++++++++++++++++++++++++++ Find the first extended segment with a particular starting node index. SegmentX *FirstSegmentX Returns a pointer to the first extended segment with the specified id. SegmentsX *segmentsx The set of segments to use. index_t nodeindex The node index to look for. int position A flag to pass through. ++++++++++++++++++++++++++++++++++++++*/ SegmentX *FirstSegmentX(SegmentsX *segmentsx,index_t nodeindex,int position) { index_t index=segmentsx->firstnode[nodeindex]; SegmentX *segmentx; if(index==NO_SEGMENT) return(NULL); segmentx=LookupSegmentX(segmentsx,index,position); return(segmentx); } /*++++++++++++++++++++++++++++++++++++++ Find the next segment with a particular starting node index. SegmentX *NextSegmentX Returns a pointer to the next segment with the same id. SegmentsX *segmentsx The set of segments to use. SegmentX *segmentx The current segment. index_t nodeindex The node index. ++++++++++++++++++++++++++++++++++++++*/ SegmentX *NextSegmentX(SegmentsX *segmentsx,SegmentX *segmentx,index_t nodeindex) { #if SLIM int position=1+(segmentx-&segmentsx->cached[0]); #endif if(segmentx->node1==nodeindex) { if(segmentsx->next1) { index_t index=IndexSegmentX(segmentsx,segmentx); if(segmentsx->next1[index]==NO_SEGMENT) return(NULL); segmentx=LookupSegmentX(segmentsx,segmentsx->next1[index],position); return(segmentx); } else { #if SLIM index_t index=IndexSegmentX(segmentsx,segmentx); index++; if(index>=segmentsx->number) return(NULL); segmentx=LookupSegmentX(segmentsx,index,position); #else segmentx++; if(IndexSegmentX(segmentsx,segmentx)>=segmentsx->number) return(NULL); #endif if(segmentx->node1!=nodeindex) return(NULL); return(segmentx); } } else { if(segmentx->next2==NO_SEGMENT) return(NULL); return(LookupSegmentX(segmentsx,segmentx->next2,position)); } } /*++++++++++++++++++++++++++++++++++++++ Sort the segment list. SegmentsX *segmentsx The set of segments to sort. ++++++++++++++++++++++++++++++++++++++*/ void SortSegmentList(SegmentsX *segmentsx) { int fd; /* Print the start message */ printf_first("Sorting Segments"); /* Re-open the file read-only and a new file writeable */ fd=ReplaceFileBuffered(segmentsx->filename_tmp,&segmentsx->fd); /* Sort by node indexes */ segmentsx->number=filesort_fixed(segmentsx->fd,fd,sizeof(SegmentX),NULL, (int (*)(const void*,const void*))sort_by_id, NULL); /* Close the files */ segmentsx->fd=CloseFileBuffered(segmentsx->fd); CloseFileBuffered(fd); /* Print the final message */ printf_last("Sorted Segments: Segments=%"Pindex_t,segmentsx->number); } /*++++++++++++++++++++++++++++++++++++++ Sort the segments into id order, first by node1 then by node2, finally by distance. int sort_by_id Returns the comparison of the node fields. SegmentX *a The first segment. SegmentX *b The second segment. ++++++++++++++++++++++++++++++++++++++*/ static int sort_by_id(SegmentX *a,SegmentX *b) { index_t a_id1=a->node1; index_t b_id1=b->node1; if(a_id1b_id1) return(1); else /* if(a_id1==b_id1) */ { index_t a_id2=a->node2; index_t b_id2=b->node2; if(a_id2b_id2) return(1); else { distance_t a_distance=DISTANCE(a->distance); distance_t b_distance=DISTANCE(b->distance); if(a_distanceb_distance) return(1); else { distance_t a_distflag=DISTFLAG(a->distance); distance_t b_distflag=DISTFLAG(b->distance); if(a_distflagb_distflag) return(1); else return(FILESORT_PRESERVE_ORDER(a,b)); /* preserve order */ } } } } /*++++++++++++++++++++++++++++++++++++++ Process segments (non-trivial duplicates). SegmentsX *segmentsx The set of segments to modify. NodesX *nodesx The set of nodes to use. WaysX *waysx The set of ways to use. ++++++++++++++++++++++++++++++++++++++*/ void ProcessSegments(SegmentsX *segmentsx,NodesX *nodesx,WaysX *waysx) { index_t duplicate=0,good=0,total=0; index_t prevnode1=NO_NODE,prevnode2=NO_NODE; index_t prevway=NO_WAY; distance_t prevdist=0; SegmentX segmentx; int fd; /* Print the start message */ printf_first("Processing Segments: Segments=0 Duplicates=0"); /* Map into memory / open the file */ #if !SLIM nodesx->data=MapFile(nodesx->filename_tmp); #else nodesx->fd=SlimMapFile(nodesx->filename_tmp); InvalidateNodeXCache(nodesx->cache); #endif /* Allocate the way usage bitmask */ segmentsx->usedway=AllocBitMask(waysx->number); log_malloc(segmentsx->usedway,LengthBitMask(waysx->number)*sizeof(BitMask)); logassert(segmentsx->usedway,"Failed to allocate memory (try using slim mode?)"); /* Check AllocBitMask() worked */ /* Re-open the file read-only and a new file writeable */ fd=ReplaceFileBuffered(segmentsx->filename_tmp,&segmentsx->fd); /* Modify the on-disk image */ while(!ReadFileBuffered(segmentsx->fd,&segmentx,sizeof(SegmentX))) { if(prevnode1==segmentx.node1 && prevnode2==segmentx.node2) { node_t id1=nodesx->idata[segmentx.node1]; node_t id2=nodesx->idata[segmentx.node2]; if(prevway==segmentx.way) { way_t id=waysx->idata[segmentx.way]; logerror("Segment connecting nodes %"Pnode_t" and %"Pnode_t" in way %"Pway_t" is duplicated.\n",logerror_node(id1),logerror_node(id2),logerror_way(id)); } else { if(!(prevdist&SEGMENT_AREA) && !(segmentx.distance&SEGMENT_AREA)) logerror("Segment connecting nodes %"Pnode_t" and %"Pnode_t" is duplicated.\n",logerror_node(id1),logerror_node(id2)); if(!(prevdist&SEGMENT_AREA) && (segmentx.distance&SEGMENT_AREA)) logerror("Segment connecting nodes %"Pnode_t" and %"Pnode_t" is duplicated (discarded the area).\n",logerror_node(id1),logerror_node(id2)); if((prevdist&SEGMENT_AREA) && !(segmentx.distance&SEGMENT_AREA)) logerror("Segment connecting nodes %"Pnode_t" and %"Pnode_t" is duplicated (discarded the non-area).\n",logerror_node(id1),logerror_node(id2)); if((prevdist&SEGMENT_AREA) && (segmentx.distance&SEGMENT_AREA)) logerror("Segment connecting nodes %"Pnode_t" and %"Pnode_t" is duplicated (both are areas).\n",logerror_node(id1),logerror_node(id2)); } duplicate++; } else { NodeX *nodex1=LookupNodeX(nodesx,segmentx.node1,1); NodeX *nodex2=LookupNodeX(nodesx,segmentx.node2,2); prevnode1=segmentx.node1; prevnode2=segmentx.node2; prevway=segmentx.way; prevdist=DISTANCE(segmentx.distance); /* Mark the ways which are used */ SetBit(segmentsx->usedway,segmentx.way); /* Set the distance but keep the other flags except for area */ segmentx.distance=DISTANCE(DistanceX(nodex1,nodex2))|DISTFLAG(segmentx.distance); segmentx.distance&=~SEGMENT_AREA; /* Write the modified segment */ WriteFileBuffered(fd,&segmentx,sizeof(SegmentX)); good++; } total++; if(!(total%10000)) printf_middle("Processing Segments: Segments=%"Pindex_t" Duplicates=%"Pindex_t,total,duplicate); } segmentsx->number=good; /* Close the files */ segmentsx->fd=CloseFileBuffered(segmentsx->fd); CloseFileBuffered(fd); /* Unmap from memory / close the file */ #if !SLIM nodesx->data=UnmapFile(nodesx->data); #else nodesx->fd=SlimUnmapFile(nodesx->fd); #endif /* Print the final message */ printf_last("Processed Segments: Segments=%"Pindex_t" Duplicates=%"Pindex_t,total,duplicate); } /*++++++++++++++++++++++++++++++++++++++ Index the segments by creating the firstnode index and filling in the segment next2 parameter. SegmentsX *segmentsx The set of segments to modify. NodesX *nodesx The set of nodes to use. WaysX *waysx The set of ways to use. ++++++++++++++++++++++++++++++++++++++*/ void IndexSegments(SegmentsX *segmentsx,NodesX *nodesx,WaysX *waysx) { index_t index,start=0,i; SegmentX *segmentx_list=NULL; #if SLIM index_t length=0; #endif if(segmentsx->number==0) return; /* Print the start message */ printf_first("Indexing Segments: Segments=0"); /* Allocate the array of indexes */ segmentsx->firstnode=(index_t*)malloc(nodesx->number*sizeof(index_t)); log_malloc(segmentsx->firstnode,nodesx->number*sizeof(index_t)); logassert(segmentsx->firstnode,"Failed to allocate memory (try using slim mode?)"); /* Check malloc() worked */ for(i=0;inumber;i++) segmentsx->firstnode[i]=NO_SEGMENT; /* Map into memory / open the files */ #if !SLIM segmentsx->data=MapFileWriteable(segmentsx->filename_tmp); #else segmentsx->fd=SlimMapFileWriteable(segmentsx->filename_tmp); segmentx_list=(SegmentX*)malloc(1024*sizeof(SegmentX)); #endif /* Read through the segments in reverse order (in chunks to help slim mode) */ for(index=segmentsx->number-1;index!=NO_SEGMENT;index--) { SegmentX *segmentx; if((index%1024)==1023 || index==(segmentsx->number-1)) { start=1024*(index/1024); #if !SLIM segmentx_list=LookupSegmentX(segmentsx,start,1); #else length=index-start+1; SlimFetch(segmentsx->fd,segmentx_list,length*sizeof(SegmentX),start*sizeof(SegmentX)); #endif } segmentx=segmentx_list+(index-start); if(nodesx->pdata) { segmentx->node1=nodesx->pdata[segmentx->node1]; segmentx->node2=nodesx->pdata[segmentx->node2]; } if(waysx->cdata) segmentx->way=waysx->cdata[segmentx->way]; segmentx->next2=segmentsx->firstnode[segmentx->node2]; segmentsx->firstnode[segmentx->node1]=index; segmentsx->firstnode[segmentx->node2]=index; if(!(index%10000)) printf_middle("Indexing Segments: Segments=%"Pindex_t,segmentsx->number-index); #if SLIM if(index==start) SlimReplace(segmentsx->fd,segmentx_list,length*sizeof(SegmentX),start*sizeof(SegmentX)); #endif } /* Unmap from memory / close the files */ #if !SLIM segmentsx->data=UnmapFile(segmentsx->data); #else segmentsx->fd=SlimUnmapFile(segmentsx->fd); free(segmentx_list); #endif /* Free the memory */ if(nodesx->pdata) { log_free(nodesx->pdata); free(nodesx->pdata); nodesx->pdata=NULL; } if(waysx->cdata) { log_free(waysx->cdata); free(waysx->cdata); waysx->cdata=NULL; } /* Print the final message */ printf_last("Indexed Segments: Segments=%"Pindex_t,segmentsx->number); } /*++++++++++++++++++++++++++++++++++++++ Prune the deleted segments while resorting the list. SegmentsX *segmentsx The set of segments to sort and modify. WaysX *waysx The set of ways to check. ++++++++++++++++++++++++++++++++++++++*/ void RemovePrunedSegments(SegmentsX *segmentsx,WaysX *waysx) { int fd; index_t xnumber; if(segmentsx->number==0) return; /* Print the start message */ printf_first("Sorting and Pruning Segments"); /* Allocate the way usage bitmask */ segmentsx->usedway=AllocBitMask(waysx->number); log_malloc(segmentsx->usedway,LengthBitMask(waysx->number)*sizeof(BitMask)); logassert(segmentsx->usedway,"Failed to allocate memory (try using slim mode?)"); /* Check AllocBitMask() worked */ /* Re-open the file read-only and a new file writeable */ fd=ReplaceFileBuffered(segmentsx->filename_tmp,&segmentsx->fd); /* Sort by node indexes */ xnumber=segmentsx->number; sortsegmentsx=segmentsx; segmentsx->number=filesort_fixed(segmentsx->fd,fd,sizeof(SegmentX),(int (*)(void*,index_t))delete_pruned, (int (*)(const void*,const void*))sort_by_id, NULL); /* Close the files */ segmentsx->fd=CloseFileBuffered(segmentsx->fd); CloseFileBuffered(fd); /* Print the final message */ printf_last("Sorted and Pruned Segments: Segments=%"Pindex_t" Deleted=%"Pindex_t,xnumber,xnumber-segmentsx->number); } /*++++++++++++++++++++++++++++++++++++++ Delete the pruned segments. int delete_pruned Return 1 if the value is to be kept, otherwise 0. SegmentX *segmentx The extended segment. index_t index The number of unsorted segments that have been read from the input file. ++++++++++++++++++++++++++++++++++++++*/ static int delete_pruned(SegmentX *segmentx,index_t index) { if(IsPrunedSegmentX(segmentx)) return(0); SetBit(sortsegmentsx->usedway,segmentx->way); return(1); } /*++++++++++++++++++++++++++++++++++++++ Remove the duplicate super-segments. SegmentsX *segmentsx The set of super-segments to modify. WaysX *waysx The set of ways to use. ++++++++++++++++++++++++++++++++++++++*/ void DeduplicateSuperSegments(SegmentsX *segmentsx,WaysX *waysx) { int fd; index_t xnumber; if(waysx->number==0) return; /* Print the start message */ printf_first("Sorting and Deduplicating Super-Segments"); /* Map into memory / open the file */ #if !SLIM waysx->data=MapFile(waysx->filename_tmp); #else waysx->fd=SlimMapFile(waysx->filename_tmp); InvalidateWayXCache(waysx->cache); #endif /* Re-open the file read-only and a new file writeable */ fd=ReplaceFileBuffered(segmentsx->filename_tmp,&segmentsx->fd); /* Sort by node indexes */ xnumber=segmentsx->number; sortsegmentsx=segmentsx; sortwaysx=waysx; segmentsx->number=filesort_fixed(segmentsx->fd,fd,sizeof(SegmentX),NULL, (int (*)(const void*,const void*))sort_by_id, (int (*)(void*,index_t))deduplicate_super); /* Close the files */ segmentsx->fd=CloseFileBuffered(segmentsx->fd); CloseFileBuffered(fd); /* Unmap from memory / close the file */ #if !SLIM waysx->data=UnmapFile(waysx->data); #else waysx->fd=SlimUnmapFile(waysx->fd); #endif /* Print the final message */ printf_last("Sorted and Deduplicated Super-Segments: Super-Segments=%"Pindex_t" Duplicate=%"Pindex_t,xnumber,xnumber-segmentsx->number); } /*++++++++++++++++++++++++++++++++++++++ De-duplicate super-segments. int deduplicate_super Return 1 if the value is to be kept, otherwise 0. SegmentX *segmentx The extended super-segment. index_t index The number of sorted super-segments that have already been written to the output file. ++++++++++++++++++++++++++++++++++++++*/ static int deduplicate_super(SegmentX *segmentx,index_t index) { static int nprev; /* internal variable (reset by first call in each sort; index==0) */ static index_t prevnode1,prevnode2; /* internal variable (reset by first call in each sort; index==0) */ static SegmentX prevsegx[MAX_SEG_PER_NODE]; /* internal variable (reset by first call in each sort; index==0) */ static Way prevway[MAX_SEG_PER_NODE]; /* internal variable (reset by first call in each sort; index==0) */ WayX *wayx=LookupWayX(sortwaysx,segmentx->way,1); int isduplicate=0; if(index==0 || segmentx->node1!=prevnode1 || segmentx->node2!=prevnode2) { nprev=1; prevnode1=segmentx->node1; prevnode2=segmentx->node2; prevsegx[0]=*segmentx; prevway[0] =wayx->way; } else { int offset; for(offset=0;offsetdistance)==DISTFLAG(prevsegx[offset].distance)) if(!WaysCompare(&prevway[offset],&wayx->way)) { isduplicate=1; break; } } if(isduplicate) { nprev--; for(;offsetway; nprev++; } } return(!isduplicate); } /*++++++++++++++++++++++++++++++++++++++ Sort the segments geographically after updating the node indexes. SegmentsX *segmentsx The set of segments to modify. NodesX *nodesx The set of nodes to use. ++++++++++++++++++++++++++++++++++++++*/ void SortSegmentListGeographically(SegmentsX *segmentsx,NodesX *nodesx) { int fd; if(segmentsx->number==0) return; /* Print the start message */ printf_first("Sorting Segments Geographically"); /* Re-open the file read-only and a new file writeable */ fd=ReplaceFileBuffered(segmentsx->filename_tmp,&segmentsx->fd); /* Update the segments with geographically sorted node indexes and sort them */ sortnodesx=nodesx; filesort_fixed(segmentsx->fd,fd,sizeof(SegmentX),(int (*)(void*,index_t))geographically_index, (int (*)(const void*,const void*))sort_by_id, NULL); /* Close the files */ segmentsx->fd=CloseFileBuffered(segmentsx->fd); CloseFileBuffered(fd); /* Print the final message */ printf_last("Sorted Segments Geographically: Segments=%"Pindex_t,segmentsx->number); } /*++++++++++++++++++++++++++++++++++++++ Update the segment indexes. int geographically_index Return 1 if the value is to be kept, otherwise 0. SegmentX *segmentx The extended segment. index_t index The number of unsorted segments that have been read from the input file. ++++++++++++++++++++++++++++++++++++++*/ static int geographically_index(SegmentX *segmentx,index_t index) { segmentx->node1=sortnodesx->gdata[segmentx->node1]; segmentx->node2=sortnodesx->gdata[segmentx->node2]; if(segmentx->node1>segmentx->node2) { index_t temp; temp=segmentx->node1; segmentx->node1=segmentx->node2; segmentx->node2=temp; if(segmentx->distance&(ONEWAY_2TO1|ONEWAY_1TO2)) segmentx->distance^=ONEWAY_2TO1|ONEWAY_1TO2; } return(1); } /*++++++++++++++++++++++++++++++++++++++ Save the segment list to a file. SegmentsX *segmentsx The set of segments to save. const char *filename The name of the file to save. ++++++++++++++++++++++++++++++++++++++*/ void SaveSegmentList(SegmentsX *segmentsx,const char *filename) { index_t i; int fd; SegmentsFile segmentsfile={0}; index_t super_number=0,normal_number=0; /* Print the start message */ printf_first("Writing Segments: Segments=0"); /* Re-open the file */ segmentsx->fd=ReOpenFileBuffered(segmentsx->filename_tmp); /* Write out the segments data */ fd=OpenFileBufferedNew(filename); SeekFileBuffered(fd,sizeof(SegmentsFile)); for(i=0;inumber;i++) { SegmentX segmentx; Segment segment={0}; ReadFileBuffered(segmentsx->fd,&segmentx,sizeof(SegmentX)); segment.node1 =segmentx.node1; segment.node2 =segmentx.node2; segment.next2 =segmentx.next2; segment.way =segmentx.way; segment.distance=segmentx.distance; if(IsSuperSegment(&segment)) super_number++; if(IsNormalSegment(&segment)) normal_number++; WriteFileBuffered(fd,&segment,sizeof(Segment)); if(!((i+1)%10000)) printf_middle("Writing Segments: Segments=%"Pindex_t,i+1); } /* Write out the header structure */ segmentsfile.number=segmentsx->number; segmentsfile.snumber=super_number; segmentsfile.nnumber=normal_number; SeekFileBuffered(fd,0); WriteFileBuffered(fd,&segmentsfile,sizeof(SegmentsFile)); CloseFileBuffered(fd); /* Close the file */ segmentsx->fd=CloseFileBuffered(segmentsx->fd); /* Print the final message */ printf_last("Wrote Segments: Segments=%"Pindex_t,segmentsx->number); } /*++++++++++++++++++++++++++++++++++++++ Calculate the distance between two nodes. distance_t DistanceX Returns the distance between the extended nodes. NodeX *nodex1 The starting node. NodeX *nodex2 The end node. ++++++++++++++++++++++++++++++++++++++*/ static distance_t DistanceX(NodeX *nodex1,NodeX *nodex2) { double dlon = latlong_to_radians(nodex1->longitude) - latlong_to_radians(nodex2->longitude); double dlat = latlong_to_radians(nodex1->latitude) - latlong_to_radians(nodex2->latitude); double lat1 = latlong_to_radians(nodex1->latitude); double lat2 = latlong_to_radians(nodex2->latitude); double a1,a2,a,sa,c,d; if(dlon==0 && dlat==0) return 0; a1 = sin (dlat / 2); a2 = sin (dlon / 2); a = a1 * a1 + cos (lat1) * cos (lat2) * a2 * a2; sa = sqrt (a); if (sa <= 1.0) {c = 2 * asin (sa);} else {c = 2 * asin (1.0);} d = 6378.137 * c; return km_to_distance(d); } routino-3.0/src/types.h 644 233 144 34323 12416231346 10356 0/*************************************** Type definitions Part of the Routino routing software. ******************/ /****************** This file Copyright 2008-2014 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #ifndef TYPES_H #define TYPES_H /*+ To stop multiple inclusions. +*/ #include #include #include #ifndef M_PI #define M_PI 3.14159265358979323846 #endif /* Constants and macros for handling them */ /*+ The number of waypoints allowed to be specified. +*/ #define NWAYPOINTS 99 /*+ An undefined waypoint index. +*/ #define NO_WAYPOINT ((waypoint_t)~0) /*+ An undefined node index. +*/ #define NO_NODE ((index_t)~0) /*+ An undefined segment index. +*/ #define NO_SEGMENT ((index_t)~0) /*+ An undefined way index. +*/ #define NO_WAY ((index_t)~0) /*+ An undefined relation index. +*/ #define NO_RELATION ((index_t)~0) /*+ An undefined location. +*/ #define NO_LATLONG ((latlong_t)0x80000000) /*+ The lowest number allowed for a fake node. +*/ #define NODE_FAKE ((index_t)0xffff0000) /*+ The lowest number allowed for a fake segment. +*/ #define SEGMENT_FAKE ((index_t)0xffff0000) /*+ The latitude and longitude conversion factor from floating point (radians) to integer. +*/ #define LAT_LONG_SCALE (1024*65536) /*+ The latitude and longitude integer range within each bin. +*/ #define LAT_LONG_BIN 65536 /*+ A flag to mark a node as a super-node. +*/ #define NODE_SUPER ((nodeflags_t)0x8000) /*+ A flag to mark a node as suitable for a U-turn. +*/ #define NODE_UTURN ((nodeflags_t)0x4000) /*+ A flag to mark a node as a mini-roundabout. +*/ #define NODE_MINIRNDBT ((nodeflags_t)0x2000) /*+ A flag to mark a node as a turn relation via node. +*/ #define NODE_TURNRSTRCT ((nodeflags_t)0x1000) /*+ A flag to mark a node as adjacent to a turn relation via node. +*/ #define NODE_TURNRSTRCT2 ((nodeflags_t)0x0800) /*+ A flag to mark a node as deleted. +*/ #define NODE_DELETED ((nodeflags_t)0x0400) /*+ A flag to mark a segment as being part of an area (must be the highest valued flag). +*/ #define SEGMENT_AREA ((distance_t)0x80000000) /*+ A flag to mark a segment as one-way from node1 to node2. +*/ #define ONEWAY_1TO2 ((distance_t)0x40000000) /*+ A flag to mark a segment as one-way from node2 to node1. +*/ #define ONEWAY_2TO1 ((distance_t)0x20000000) /*+ A flag to mark a segment as a super-segment. +*/ #define SEGMENT_SUPER ((distance_t)0x10000000) /*+ A flag to mark a segment as a normal segment. +*/ #define SEGMENT_NORMAL ((distance_t)0x08000000) /*+ The real distance ignoring the other flags. +*/ #define DISTANCE(xx) ((distance_t)((xx)&(~(SEGMENT_AREA|ONEWAY_1TO2|ONEWAY_2TO1|SEGMENT_SUPER|SEGMENT_NORMAL)))) /*+ The distance flags selecting only the flags. +*/ #define DISTFLAG(xx) ((distance_t)((xx)&(SEGMENT_AREA|ONEWAY_1TO2|ONEWAY_2TO1|SEGMENT_SUPER|SEGMENT_NORMAL))) /*+ A very large almost infinite distance. +*/ #define INF_DISTANCE DISTANCE(~0) /*+ A very large almost infinite score. +*/ #define INF_SCORE (score_t)1E30 /*+ A flag to mark a deleted way. +*/ #define WAY_DELETED ((highway_t)~0) /*+ A flag to mark a deleted relation. +*/ #define RELATION_DELETED ((transports_t)~0) /* Simple Types */ /*+ A waypoint index. +*/ typedef uint16_t waypoint_t; /*+ A node, segment, way or relation index. +*/ typedef uint32_t index_t; /*+ A printf formatting string for an index_t type (this should match the index_t definition above). +*/ #define Pindex_t PRIu32 /* PRIu32 and PRIu64 are defined in intypes.h */ /*+ A node latitude or longitude (range: +/-pi*LAT_LONG_SCALE = +/-3.14*1024*65536 = ~29 bits). +*/ typedef int32_t latlong_t; /*+ A node latitude or longitude bin number (range: +/-pi*LAT_LONG_SCALE/LAT_LONG_BIN = +/-3.14*1024 = ~13 bits). +*/ typedef int16_t ll_bin_t; /*+ A node latitude and longitude bin number (range: +/-(pi*LAT_LONG_SCALE/LAT_LONG_BIN)^2 = +/-(3.14*1024)^2 = ~26 bits). +*/ typedef int32_t ll_bin2_t; /*+ A node latitude or longitude offset (range: 0 -> LAT_LONG_BIN-1 = 0 -> 65535 = 16 bits). +*/ typedef uint16_t ll_off_t; /*+ Conversion from a latlong (integer latitude or longitude) to a bin number. +*/ #define latlong_to_bin(xxx) (ll_bin_t)((latlong_t)((xxx)&~(LAT_LONG_BIN-1))/LAT_LONG_BIN) /*+ Conversion from a bin number to a latlong (integer latitude or longitude). +*/ #define bin_to_latlong(xxx) ((latlong_t)(xxx)*LAT_LONG_BIN) /*+ Conversion from a latlong (integer latitude or longitude) to a bin offset. +*/ #define latlong_to_off(xxx) (ll_off_t)((latlong_t)(xxx)&(LAT_LONG_BIN-1)) /*+ Conversion from a bin offset to a latlong (integer latitude or longitude). +*/ #define off_to_latlong(xxx) ((latlong_t)(xxx)) /*+ Conversion from a latitude or longitude in radians to a latlong (integer latitude or longitude). +*/ #define radians_to_latlong(xxx) ((latlong_t)floor((xxx)*LAT_LONG_SCALE+0.5)) /*+ Conversion from a latlong (integer latitude or longitude) to a latitude or longitude in radians. +*/ #define latlong_to_radians(xxx) ((double)(xxx)/LAT_LONG_SCALE) /*+ Conversion from radians to degrees. +*/ #define radians_to_degrees(xxx) ((xxx)*(180.0/M_PI)) /*+ Conversion from degrees to radians. +*/ #define degrees_to_radians(xxx) ((xxx)*(M_PI/180.0)) /*+ Node flags. +*/ typedef uint16_t nodeflags_t; /*+ A distance, measured in metres (will not overflow for any earth-based distance). +*/ typedef uint32_t distance_t; /*+ A duration, measured in 1/10th seconds (will not overflow for 13 years). +*/ typedef uint32_t duration_t; /*+ A routing optimisation score. +*/ typedef float score_t; /*+ Conversion from distance_t to kilometres. +*/ #define distance_to_km(xx) ((double)(xx)/1000.0) /*+ Conversion from kilometres to distance_t. +*/ #define km_to_distance(xx) ((distance_t)((double)(xx)*1000.0)) /*+ Conversion from duration_t to minutes. +*/ #define duration_to_minutes(xx) ((double)(xx)/600.0) /*+ Conversion from duration_t to hours. +*/ #define duration_to_hours(xx) ((double)(xx)/36000.0) /*+ Conversion from hours to duration_t. +*/ #define hours_to_duration(xx) ((duration_t)((double)(xx)*36000.0)) /*+ Conversion from distance_t and speed_t to duration_t. +*/ #define distance_speed_to_duration(xx,yy) ((duration_t)(((double)(xx)/(double)(yy))*(36000.0/1000.0))) /*+ The type of a highway. +*/ typedef uint8_t highway_t; /*+ The different types of a highway. +*/ typedef enum _Highway { Highway_None = 0, Highway_Motorway = 1, Highway_Trunk = 2, Highway_Primary = 3, Highway_Secondary = 4, Highway_Tertiary = 5, Highway_Unclassified = 6, Highway_Residential = 7, Highway_Service = 8, Highway_Track = 9, Highway_Cycleway = 10, Highway_Path = 11, Highway_Steps = 12, Highway_Ferry = 13, Highway_Count = 14, /* One more than the number of highway types. */ Highway_CycleBothWays = 16, Highway_OneWay = 32, Highway_Roundabout = 64, Highway_Area = 128 } Highway; #define HIGHWAY(xx) ((xx)&0x0f) /*+ A bitmask of multiple highway types. +*/ typedef uint16_t highways_t; #define HIGHWAYS(xx) (1<<(HIGHWAY(xx)-1)) /*+ The different types of a highway as a bitmask. +*/ typedef enum _Highways { Highways_None = 0, Highways_Motorway = HIGHWAYS(Highway_Motorway ), Highways_Trunk = HIGHWAYS(Highway_Trunk ), Highways_Primary = HIGHWAYS(Highway_Primary ), Highways_Secondary = HIGHWAYS(Highway_Secondary ), Highways_Tertiary = HIGHWAYS(Highway_Tertiary ), Highways_Unclassified = HIGHWAYS(Highway_Unclassified), Highways_Residential = HIGHWAYS(Highway_Residential ), Highways_Service = HIGHWAYS(Highway_Service ), Highways_Track = HIGHWAYS(Highway_Track ), Highways_Cycleway = HIGHWAYS(Highway_Cycleway ), Highways_Path = HIGHWAYS(Highway_Path ), Highways_Steps = HIGHWAYS(Highway_Steps ), Highways_Ferry = HIGHWAYS(Highway_Ferry ) } Highways; /*+ The type of a transport. +*/ typedef uint8_t transport_t; /*+ The different types of transport. +*/ typedef enum _Transport { Transport_None = 0, Transport_Foot = 1, Transport_Horse = 2, Transport_Wheelchair = 3, Transport_Bicycle = 4, Transport_Moped = 5, Transport_Motorcycle = 6, Transport_Motorcar = 7, Transport_Goods = 8, Transport_HGV = 9, Transport_PSV = 10, Transport_Count = 11 /*+ One more than the number of transport types. +*/ } Transport; /*+ A bitmask of multiple transport types. +*/ typedef uint16_t transports_t; #define TRANSPORTS(xx) (1<<((xx)-1)) /*+ The different types of transport as a bitmask. +*/ typedef enum _Transports { Transports_None = 0, Transports_Foot = TRANSPORTS(Transport_Foot ), Transports_Horse = TRANSPORTS(Transport_Horse ), Transports_Wheelchair = TRANSPORTS(Transport_Wheelchair), Transports_Bicycle = TRANSPORTS(Transport_Bicycle ), Transports_Moped = TRANSPORTS(Transport_Moped ), Transports_Motorcycle = TRANSPORTS(Transport_Motorcycle), Transports_Motorcar = TRANSPORTS(Transport_Motorcar ), Transports_Goods = TRANSPORTS(Transport_Goods ), Transports_HGV = TRANSPORTS(Transport_HGV ), Transports_PSV = TRANSPORTS(Transport_PSV ), Transports_ALL = TRANSPORTS(Transport_Count )-1 } Transports; /*+ The type of a property. +*/ typedef uint8_t property_t; /*+ The different types of property. +*/ typedef enum _Property { Property_None = 0, Property_Paved = 1, Property_Multilane = 2, Property_Bridge = 3, Property_Tunnel = 4, Property_FootRoute = 5, Property_BicycleRoute = 6, Property_Count = 7 /* One more than the number of property types. */ } Property; /*+ A bitmask of multiple properties. +*/ typedef uint8_t properties_t; #define PROPERTIES(xx) (1<<((xx)-1)) /*+ The different properties as a bitmask. +*/ typedef enum _Properties { Properties_None = 0, Properties_Paved = PROPERTIES(Property_Paved ), Properties_Multilane = PROPERTIES(Property_Multilane ), Properties_Bridge = PROPERTIES(Property_Bridge ), Properties_Tunnel = PROPERTIES(Property_Tunnel ), Properties_FootRoute = PROPERTIES(Property_FootRoute ), Properties_BicycleRoute = PROPERTIES(Property_BicycleRoute ), Properties_ALL = PROPERTIES(Property_Count )-1 } Properties; /*+ The speed limit of a way, measured in km/hour. +*/ typedef uint8_t speed_t; /*+ The maximum weight of a way, measured in multiples of 0.2 tonnes. +*/ typedef uint8_t weight_t; /*+ The maximum height of a way, measured in multiples of 0.1 metres. +*/ typedef uint8_t height_t; /*+ The maximum width of a way, measured in multiples of 0.1 metres. +*/ typedef uint8_t width_t; /*+ The maximum length of a way, measured in multiples of 0.1 metres. +*/ typedef uint8_t length_t; /*+ Conversion of km/hr to speed_t - simple inline function with error checking. +*/ inline static speed_t kph_to_speed(double xxx); inline static speed_t kph_to_speed(double xxx) { if(xxx>255) return(255); if(xxx<0) return(0); return((speed_t)xxx); } /*+ Conversion of speed_t to km/hr. +*/ #define speed_to_kph(xxx) (int)(xxx) /*+ Conversion of tonnes to weight_t - simple inline function with error checking. +*/ inline static weight_t tonnes_to_weight(double xxx); inline static weight_t tonnes_to_weight(double xxx) { if(xxx>51) return(255); if(xxx<0) return(0); return((weight_t)(xxx*5)); } /*+ Conversion of weight_t to tonnes. +*/ #define weight_to_tonnes(xxx) ((double)(xxx)/5.0) /*+ Conversion of metres to height_t - simple inline function with error checking. +*/ inline static height_t metres_to_height(double xxx); inline static height_t metres_to_height(double xxx) { if(xxx>25.5) return(255); if(xxx<0) return(0); return((height_t)(xxx*10)); } /*+ Conversion of height_t to metres. +*/ #define height_to_metres(xxx) ((double)(xxx)/10.0) /*+ Conversion of metres to width_t - simple inline function with error checking. +*/ inline static width_t metres_to_width(double xxx); inline static width_t metres_to_width(double xxx) { if(xxx>25.5) return(255); if(xxx<0) return(0); return((width_t)(xxx*10)); } /*+ Conversion of width_t to metres. +*/ #define width_to_metres(xxx) ((double)(xxx)/10.0) /*+ Conversion of metres to length_t - simple inline function with error checking. +*/ inline static length_t metres_to_length(double xxx); inline static length_t metres_to_length(double xxx) { if(xxx>25.5) return(255); if(xxx<0) return(0); return((length_t)(xxx*10)); } /*+ Conversion of length_t to metres. +*/ #define length_to_metres(xxx) ((double)(xxx)/10.0) /* Data structures */ typedef struct _Node Node; typedef struct _Nodes Nodes; typedef struct _Segment Segment; typedef struct _Segments Segments; typedef struct _Way Way; typedef struct _Ways Ways; typedef struct _TurnRelation TurnRelation; typedef struct _Relations Relations; /* Functions in types.c */ Highway HighwayType(const char *highway); Transport TransportType(const char *transport); Property PropertyType(const char *property); const char *HighwayName(Highway highway); const char *TransportName(Transport transport); const char *PropertyName(Property property); const char *HighwaysNameList(highways_t highways); const char *AllowedNameList(transports_t allowed); const char *PropertiesNameList(properties_t properties); const char *HighwayList(void); const char *TransportList(void); const char *PropertyList(void); #endif /* TYPES_H */ routino-3.0/src/nodes.c 644 233 144 44017 12563633052 10321 0/*************************************** Node data type functions. Part of the Routino routing software. ******************/ /****************** This file Copyright 2008-2015 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #include #include #include "types.h" #include "nodes.h" #include "segments.h" #include "ways.h" #include "files.h" #include "profiles.h" /* Local functions */ static int valid_segment_for_profile(Ways *ways,Segment *segmentp,Profile *profile); /*++++++++++++++++++++++++++++++++++++++ Load in a node list from a file. Nodes *LoadNodeList Returns the node list. const char *filename The name of the file to load. ++++++++++++++++++++++++++++++++++++++*/ Nodes *LoadNodeList(const char *filename) { Nodes *nodes; #if SLIM size_t sizeoffsets; #endif nodes=(Nodes*)malloc(sizeof(Nodes)); #if !SLIM nodes->data=MapFile(filename); /* Copy the NodesFile header structure from the loaded data */ nodes->file=*((NodesFile*)nodes->data); /* Set the pointers in the Nodes structure. */ nodes->offsets=(index_t*)(nodes->data+sizeof(NodesFile)); nodes->nodes =(Node* )(nodes->data+sizeof(NodesFile)+(nodes->file.latbins*nodes->file.lonbins+1)*sizeof(index_t)); #else nodes->fd=SlimMapFile(filename); /* Copy the NodesFile header structure from the loaded data */ SlimFetch(nodes->fd,&nodes->file,sizeof(NodesFile),0); sizeoffsets=(nodes->file.latbins*nodes->file.lonbins+1)*sizeof(index_t); nodes->offsets=(index_t*)malloc(sizeoffsets); #ifndef LIBROUTINO log_malloc(nodes->offsets,sizeoffsets); #endif SlimFetch(nodes->fd,nodes->offsets,sizeoffsets,sizeof(NodesFile)); nodes->nodesoffset=(offset_t)(sizeof(NodesFile)+sizeoffsets); nodes->cache=NewNodeCache(); #ifndef LIBROUTINO log_malloc(nodes->cache,sizeof(*nodes->cache)); #endif #endif return(nodes); } /*++++++++++++++++++++++++++++++++++++++ Destroy the node list. Nodes *nodes The node list to destroy. ++++++++++++++++++++++++++++++++++++++*/ void DestroyNodeList(Nodes *nodes) { #if !SLIM nodes->data=UnmapFile(nodes->data); #else nodes->fd=SlimUnmapFile(nodes->fd); #ifndef LIBROUTINO log_free(nodes->offsets); #endif free(nodes->offsets); #ifndef LIBROUTINO log_free(nodes->cache); #endif DeleteNodeCache(nodes->cache); #endif free(nodes); } /*++++++++++++++++++++++++++++++++++++++ Find the closest node given its latitude, longitude and the profile of the mode of transport that must be able to move to/from this node. index_t FindClosestNode Returns the closest node. Nodes *nodes The set of nodes to search. Segments *segments The set of segments to use. Ways *ways The set of ways to use. double latitude The latitude to look for. double longitude The longitude to look for. distance_t distance The maximum distance to look from the specified coordinates. Profile *profile The profile of the mode of transport. distance_t *bestdist Returns the distance to the best node. ++++++++++++++++++++++++++++++++++++++*/ index_t FindClosestNode(Nodes *nodes,Segments *segments,Ways *ways,double latitude,double longitude, distance_t distance,Profile *profile,distance_t *bestdist) { ll_bin_t latbin=latlong_to_bin(radians_to_latlong(latitude ))-nodes->file.latzero; ll_bin_t lonbin=latlong_to_bin(radians_to_latlong(longitude))-nodes->file.lonzero; int delta=0,count; index_t i,index1,index2; index_t bestn=NO_NODE; distance_t bestd=INF_DISTANCE; /* Find the maximum distance to search */ double dlat=DeltaLat(longitude,distance); double dlon=DeltaLon(latitude ,distance); double minlat=latitude -dlat; double maxlat=latitude +dlat; double minlon=longitude-dlon; double maxlon=longitude+dlon; ll_bin_t minlatbin=latlong_to_bin(radians_to_latlong(minlat))-nodes->file.latzero; ll_bin_t maxlatbin=latlong_to_bin(radians_to_latlong(maxlat))-nodes->file.latzero; ll_bin_t minlonbin=latlong_to_bin(radians_to_latlong(minlon))-nodes->file.lonzero; ll_bin_t maxlonbin=latlong_to_bin(radians_to_latlong(maxlon))-nodes->file.lonzero; ll_off_t minlatoff=latlong_to_off(radians_to_latlong(minlat)); ll_off_t maxlatoff=latlong_to_off(radians_to_latlong(maxlat)); ll_off_t minlonoff=latlong_to_off(radians_to_latlong(minlon)); ll_off_t maxlonoff=latlong_to_off(radians_to_latlong(maxlon)); /* Start with the bin containing the location, then spiral outwards. */ do { ll_bin_t latb,lonb; ll_bin2_t llbin; count=0; for(latb=latbin-delta;latb<=latbin+delta;latb++) { if(latb<0 || latb>=nodes->file.latbins || latbmaxlatbin) continue; for(lonb=lonbin-delta;lonb<=lonbin+delta;lonb++) { if(lonb<0 || lonb>=nodes->file.lonbins || lonbmaxlonbin) continue; if(abs(latb-latbin)file.latbins+latb; index1=LookupNodeOffset(nodes,llbin); index2=LookupNodeOffset(nodes,llbin+1); for(i=index1;ilatoffsetlatoffset>maxlatoff) continue; if(lonb==minlonbin && nodep->lonoffsetlonoffset>maxlonoff) continue; lat=latlong_to_radians(bin_to_latlong(nodes->file.latzero+latb)+off_to_latlong(nodep->latoffset)); lon=latlong_to_radians(bin_to_latlong(nodes->file.lonzero+lonb)+off_to_latlong(nodep->lonoffset)); dist=Distance(lat,lon,latitude,longitude); if(distfile.latzero; ll_bin_t lonbin=latlong_to_bin(radians_to_latlong(longitude))-nodes->file.lonzero; int delta=0,count; index_t i,index1,index2; index_t bestn1=NO_NODE,bestn2=NO_NODE; distance_t bestd=INF_DISTANCE,bestd1=INF_DISTANCE,bestd2=INF_DISTANCE; index_t bests=NO_SEGMENT; /* Find the maximum distance to search */ double dlat=DeltaLat(longitude,distance); double dlon=DeltaLon(latitude ,distance); double minlat=latitude -dlat; double maxlat=latitude +dlat; double minlon=longitude-dlon; double maxlon=longitude+dlon; ll_bin_t minlatbin=latlong_to_bin(radians_to_latlong(minlat))-nodes->file.latzero; ll_bin_t maxlatbin=latlong_to_bin(radians_to_latlong(maxlat))-nodes->file.latzero; ll_bin_t minlonbin=latlong_to_bin(radians_to_latlong(minlon))-nodes->file.lonzero; ll_bin_t maxlonbin=latlong_to_bin(radians_to_latlong(maxlon))-nodes->file.lonzero; ll_off_t minlatoff=latlong_to_off(radians_to_latlong(minlat)); ll_off_t maxlatoff=latlong_to_off(radians_to_latlong(maxlat)); ll_off_t minlonoff=latlong_to_off(radians_to_latlong(minlon)); ll_off_t maxlonoff=latlong_to_off(radians_to_latlong(maxlon)); /* Start with the bin containing the location, then spiral outwards. */ do { ll_bin_t latb,lonb; ll_bin2_t llbin; count=0; for(latb=latbin-delta;latb<=latbin+delta;latb++) { if(latb<0 || latb>=nodes->file.latbins || latbmaxlatbin) continue; for(lonb=lonbin-delta;lonb<=lonbin+delta;lonb++) { if(lonb<0 || lonb>=nodes->file.lonbins || lonbmaxlonbin) continue; if(abs(latb-latbin)file.latbins+latb; index1=LookupNodeOffset(nodes,llbin); index2=LookupNodeOffset(nodes,llbin+1); for(i=index1;ilatoffsetlatoffset>maxlatoff) continue; if(lonb==minlonbin && nodep->lonoffsetlonoffset>maxlonoff) continue; lat1=latlong_to_radians(bin_to_latlong(nodes->file.latzero+latb)+off_to_latlong(nodep->latoffset)); lon1=latlong_to_radians(bin_to_latlong(nodes->file.lonzero+lonb)+off_to_latlong(nodep->lonoffset)); dist1=Distance(lat1,lon1,latitude,longitude); if(dist1=0 && dist3b>=0) distp=sqrt((double)dist1*(double)dist1-dist3a*dist3a); else if(dist3a>0) { distp=dist2; dist3a=dist3; dist3b=0; } else /* if(dist3b>0) */ { distp=dist1; dist3a=0; dist3b=dist3; } } if(distp<(double)bestd) { bests=IndexSegment(segments,segmentp); if(segmentp->node1==i) { bestn1=i; bestn2=OtherNode(segmentp,i); bestd1=(distance_t)dist3a; bestd2=(distance_t)dist3b; } else { bestn1=OtherNode(segmentp,i); bestn2=i; bestd1=(distance_t)dist3b; bestd2=(distance_t)dist3a; } bestd=(distance_t)distp; } } segmentp=NextSegment(segments,segmentp,i); } while(segmentp); } /* dist1 < distance */ } count++; } } delta++; } while(count); *bestdist=bestd; *bestnode1=bestn1; *bestnode2=bestn2; *bestdist1=bestd1; *bestdist2=bestd2; return(bests); } /*++++++++++++++++++++++++++++++++++++++ Check if the transport defined by the profile is allowed on the segment. int valid_segment_for_profile Return 1 if it is or 0 if not. Ways *ways The set of ways to use. Segment *segmentp The segment to check. Profile *profile The profile to check. ++++++++++++++++++++++++++++++++++++++*/ static int valid_segment_for_profile(Ways *ways,Segment *segmentp,Profile *profile) { Way *wayp=LookupWay(ways,segmentp->way,1); score_t segment_pref; int i; /* mode of transport must be allowed on the highway */ if(!(wayp->allow&profile->allow)) return(0); /* must obey weight restriction (if exists) */ if(wayp->weight && wayp->weightweight) return(0); /* must obey height/width/length restriction (if exists) */ if((wayp->height && wayp->heightheight) || (wayp->width && wayp->width width ) || (wayp->length && wayp->lengthlength)) return(0); segment_pref=profile->highway[HIGHWAY(wayp->type)]; for(i=1;ifile.props & PROPERTIES(i)) { if(wayp->props & PROPERTIES(i)) segment_pref*=profile->props_yes[i]; else segment_pref*=profile->props_no[i]; } /* profile preferences must allow this highway */ if(segment_pref==0) return(0); /* Must be OK */ return(1); } /*++++++++++++++++++++++++++++++++++++++ Get the latitude and longitude associated with a node. Nodes *nodes The set of nodes to use. index_t index The node index. Node *nodep A pointer to the node if already available. double *latitude Returns the latitude. double *longitude Returns the logitude. ++++++++++++++++++++++++++++++++++++++*/ void GetLatLong(Nodes *nodes,index_t index,Node *nodep,double *latitude,double *longitude) { ll_bin_t latbin,lonbin; ll_bin2_t bin=-1; ll_bin2_t start,end,mid; index_t offset; /* Binary search - search key nearest match below is required. * * # <- start | Check mid and move start or end if it doesn't match * # | * # | A lower bound match is wanted we can set end=mid-1 or * # <- mid | start=mid because we know that mid doesn't match. * # | * # | Eventually either end=start or end=start+1 and one of * # <- end | start or end is the wanted one. */ /* Search for offset */ start=0; end=nodes->file.lonbins*nodes->file.latbins; do { mid=(start+end)/2; /* Choose mid point */ offset=LookupNodeOffset(nodes,mid); if(offsetindex) /* Mid point is too high */ end=mid?(mid-1):mid; else /* Mid point is correct */ {bin=mid;break;} } while((end-start)>1); if(bin==-1) { offset=LookupNodeOffset(nodes,end); if(offset>index) bin=start; else bin=end; } while(bin<=(nodes->file.lonbins*nodes->file.latbins) && LookupNodeOffset(nodes,bin)==LookupNodeOffset(nodes,bin+1)) bin++; latbin=bin%nodes->file.latbins; lonbin=bin/nodes->file.latbins; /* Return the values */ if(nodep==NULL) nodep=LookupNode(nodes,index,4); *latitude =latlong_to_radians(bin_to_latlong(nodes->file.latzero+latbin)+off_to_latlong(nodep->latoffset)); *longitude=latlong_to_radians(bin_to_latlong(nodes->file.lonzero+lonbin)+off_to_latlong(nodep->lonoffset)); } routino-3.0/src/segmentsx.h 644 233 144 15576 12550012612 11230 0/*************************************** A header file for the extended segments. Part of the Routino routing software. ******************/ /****************** This file Copyright 2008-2015 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #ifndef SEGMENTSX_H #define SEGMENTSX_H /*+ To stop multiple inclusions. +*/ #include #include "types.h" #include "typesx.h" #include "cache.h" #include "files.h" /* Data structures */ /*+ An extended structure used for processing. +*/ struct _SegmentX { index_t node1; /*+ The NodeX index of the starting node. +*/ index_t node2; /*+ The NodeX index of the finishing node. +*/ index_t next2; /*+ The index of the next segment with the same node2. +*/ index_t way; /*+ The WayX index of the way. +*/ distance_t distance; /*+ The distance between the nodes. +*/ }; /*+ A structure containing a set of segments (memory format). +*/ struct _SegmentsX { char *filename_tmp; /*+ The name of the temporary file (for the SegmentsX). +*/ int fd; /*+ The file descriptor of the open file (for the SegmentsX). +*/ index_t number; /*+ The number of extended segments still being considered. +*/ #if !SLIM SegmentX *data; /*+ The extended segment data (when mapped into memory). +*/ #else SegmentX cached[4]; /*+ Four cached extended segments read from the file in slim mode. +*/ index_t incache[4]; /*+ The indexes of the cached extended segments. +*/ SegmentXCache *cache; /*+ A RAM cache of extended segments read from the file. +*/ #endif index_t *firstnode; /*+ The first segment index for each node. +*/ index_t *next1; /*+ The index of the next segment with the same node1 (used while pruning). +*/ BitMask *usedway; /*+ A flag to indicate if a way is used (used for removing pruned ways). +*/ }; /* Functions in segmentsx.c */ SegmentsX *NewSegmentList(void); void FreeSegmentList(SegmentsX *segmentsx); void AppendSegmentList(SegmentsX *segmentsx,index_t way,index_t node1,index_t node2,distance_t distance); void FinishSegmentList(SegmentsX *segmentsx); SegmentX *FirstSegmentX(SegmentsX *segmentsx,index_t nodeindex,int position); SegmentX *NextSegmentX(SegmentsX *segmentsx,SegmentX *segmentx,index_t nodeindex); void SortSegmentList(SegmentsX *segmentsx); void IndexSegments(SegmentsX *segmentsx,NodesX *nodesx,WaysX *waysx); void ProcessSegments(SegmentsX *segmentsx,NodesX *nodesx,WaysX *waysx); void RemovePrunedSegments(SegmentsX *segmentsx,WaysX *waysx); void DeduplicateSuperSegments(SegmentsX *segmentsx,WaysX *waysx); void SortSegmentListGeographically(SegmentsX *segmentsx,NodesX *nodesx); void SaveSegmentList(SegmentsX *segmentsx,const char *filename); /* Macros / inline functions */ /*+ Return true if this is a pruned segment. +*/ #define IsPrunedSegmentX(xxx) ((xxx)->node1==NO_NODE) #if !SLIM #define LookupSegmentX(segmentsx,index,position) &(segmentsx)->data[index] #define IndexSegmentX(segmentsx,segmentx) (index_t)((segmentx)-&(segmentsx)->data[0]) #define PutBackSegmentX(segmentsx,segmentx) while(0) { /* nop */ } #define ReLookupSegmentX(segmentsx,segmentx) while(0) { /* nop */ } #else /* Prototypes */ static inline SegmentX *LookupSegmentX(SegmentsX *segmentsx,index_t index,int position); static inline index_t IndexSegmentX(SegmentsX *segmentsx,SegmentX *segmentx); static inline void PutBackSegmentX(SegmentsX *segmentsx,SegmentX *segmentx); static inline void ReLookupSegmentX(SegmentsX *segmentsx,SegmentX *segmentx); CACHE_NEWCACHE_PROTO(SegmentX) CACHE_DELETECACHE_PROTO(SegmentX) CACHE_FETCHCACHE_PROTO(SegmentX) CACHE_REPLACECACHE_PROTO(SegmentX) CACHE_INVALIDATECACHE_PROTO(SegmentX) /* Data type */ CACHE_STRUCTURE(SegmentX) /* Inline functions */ CACHE_NEWCACHE(SegmentX) CACHE_DELETECACHE(SegmentX) CACHE_FETCHCACHE(SegmentX) CACHE_REPLACECACHE(SegmentX) CACHE_INVALIDATECACHE(SegmentX) /*++++++++++++++++++++++++++++++++++++++ Lookup a particular extended segment with the specified id from the file on disk. SegmentX *LookupSegmentX Returns a pointer to a cached copy of the extended segment. SegmentsX *segmentsx The set of segments to use. index_t index The segment index to look for. int position The position in the cache to use. ++++++++++++++++++++++++++++++++++++++*/ static inline SegmentX *LookupSegmentX(SegmentsX *segmentsx,index_t index,int position) { segmentsx->cached[position-1]=*FetchCachedSegmentX(segmentsx->cache,index,segmentsx->fd,0); segmentsx->incache[position-1]=index; return(&segmentsx->cached[position-1]); } /*++++++++++++++++++++++++++++++++++++++ Find the extended segment index for a particular extended segment pointer. index_t IndexSegmentX Returns the index of the extended segment. SegmentsX *segmentsx The set of segments to use. SegmentX *segmentx The extended segment whose index is to be found. ++++++++++++++++++++++++++++++++++++++*/ static inline index_t IndexSegmentX(SegmentsX *segmentsx,SegmentX *segmentx) { int position1=segmentx-&segmentsx->cached[0]; return(segmentsx->incache[position1]); } /*++++++++++++++++++++++++++++++++++++++ Put back an extended segment's data into the file on disk. SegmentsX *segmentsx The set of segments to use. SegmentX *segmentx The extended segment to be put back. ++++++++++++++++++++++++++++++++++++++*/ static inline void PutBackSegmentX(SegmentsX *segmentsx,SegmentX *segmentx) { int position1=segmentx-&segmentsx->cached[0]; ReplaceCachedSegmentX(segmentsx->cache,segmentx,segmentsx->incache[position1],segmentsx->fd,0); } /*++++++++++++++++++++++++++++++++++++++ Lookup an extended segment's data from the disk into file again after the disk was updated. SegmentsX *segmentsx The set of segments to use. SegmentX *segmentx The extended segment to refresh. ++++++++++++++++++++++++++++++++++++++*/ static inline void ReLookupSegmentX(SegmentsX *segmentsx,SegmentX *segmentx) { int position1=segmentx-&segmentsx->cached[0]; segmentsx->cached[position1]=*FetchCachedSegmentX(segmentsx->cache,segmentsx->incache[position1],segmentsx->fd,0); } #endif /* SLIM */ #endif /* SEGMENTSX_H */ routino-3.0/src/planetsplitter.c 644 233 144 54405 12574073721 12270 0/*************************************** OSM planet file splitter. Part of the Routino routing software. ******************/ /****************** This file Copyright 2008-2015 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #include #include #include #include #include "version.h" #include "types.h" #include "ways.h" #include "typesx.h" #include "nodesx.h" #include "segmentsx.h" #include "waysx.h" #include "relationsx.h" #include "superx.h" #include "prunex.h" #include "files.h" #include "logging.h" #include "errorlogx.h" #include "functions.h" #include "osmparser.h" #include "tagging.h" #include "uncompress.h" /* Global variables */ /*+ The name of the temporary directory. +*/ char *option_tmpdirname=NULL; /*+ The amount of RAM to use for filesorting. +*/ size_t option_filesort_ramsize=0; /*+ The number of threads to use for filesorting. +*/ int option_filesort_threads=1; /* Local functions */ static void print_usage(int detail,const char *argerr,const char *err); /*++++++++++++++++++++++++++++++++++++++ The main program for the planetsplitter. ++++++++++++++++++++++++++++++++++++++*/ int main(int argc,char** argv) { NodesX *OSMNodes; SegmentsX *OSMSegments,*SuperSegments=NULL,*MergedSegments=NULL; WaysX *OSMWays; RelationsX *OSMRelations; int iteration=0,quit=0; int max_iterations=5; char *dirname=NULL,*prefix=NULL,*tagging=NULL,*errorlog=NULL; int option_parse_only=0,option_process_only=0; int option_append=0,option_keep=0,option_changes=0; int option_filenames=0; int option_prune_isolated=500,option_prune_short=5,option_prune_straight=3; int arg; printf_program_start(); /* Parse the command line arguments */ for(arg=1;arg9?"=":""); fflush(stdout); if(iteration==0) { /* Select the super-nodes */ ChooseSuperNodes(OSMNodes,OSMSegments,OSMWays); /* Select the super-segments */ SuperSegments=CreateSuperSegments(OSMNodes,OSMSegments,OSMWays); nsuper=OSMSegments->number; } else { SegmentsX *SuperSegments2; /* Index the super-segments */ IndexSegments(SuperSegments,OSMNodes,OSMWays); /* Select the super-nodes */ ChooseSuperNodes(OSMNodes,SuperSegments,OSMWays); /* Select the super-segments */ SuperSegments2=CreateSuperSegments(OSMNodes,SuperSegments,OSMWays); nsuper=SuperSegments->number; FreeSegmentList(SuperSegments); SuperSegments=SuperSegments2; } /* Sort the super-segments and remove duplicates */ DeduplicateSuperSegments(SuperSegments,OSMWays); /* Check for end condition */ if(SuperSegments->number==nsuper) quit=1; iteration++; if(iteration>max_iterations) quit=1; } while(!quit); /* Combine the super-segments */ printf("\nCombine Segments and Super-Segments\n===================================\n\n"); fflush(stdout); /* Merge the super-segments */ MergedSegments=MergeSuperSegments(OSMSegments,SuperSegments); FreeSegmentList(OSMSegments); FreeSegmentList(SuperSegments); OSMSegments=MergedSegments; /* Cross reference the nodes and segments */ printf("\nCross-Reference Nodes and Segments\n==================================\n\n"); fflush(stdout); /* Sort the nodes and segments geographically */ SortNodeListGeographically(OSMNodes); SortSegmentListGeographically(OSMSegments,OSMNodes); /* Re-index the segments */ IndexSegments(OSMSegments,OSMNodes,OSMWays); /* Sort the turn relations geographically */ SortTurnRelationListGeographically(OSMRelations,OSMNodes,OSMSegments,1); /* Output the results */ printf("\nWrite Out Database Files\n========================\n\n"); fflush(stdout); /* Write out the nodes */ SaveNodeList(OSMNodes,FileName(dirname,prefix,"nodes.mem"),OSMSegments); /* Write out the segments */ SaveSegmentList(OSMSegments,FileName(dirname,prefix,"segments.mem")); /* Write out the ways */ SaveWayList(OSMWays,FileName(dirname,prefix,"ways.mem")); /* Write out the relations */ SaveRelationList(OSMRelations,FileName(dirname,prefix,"relations.mem")); /* Free the memory (delete the temporary files) */ FreeSegmentList(OSMSegments); /* Close the error log file and process the data */ if(errorlog) { close_errorlog(); if(option_keep) { ErrorLogsX *OSMErrorLogs; printf("\nCreate Error Log\n================\n\n"); fflush(stdout); OSMErrorLogs=NewErrorLogList(); ProcessErrorLogs(OSMErrorLogs,OSMNodes,OSMWays,OSMRelations); SortErrorLogsGeographically(OSMErrorLogs); SaveErrorLogs(OSMErrorLogs,FileName(dirname,prefix,"errorlogs.mem")); FreeErrorLogList(OSMErrorLogs); } } /* Free the memory (delete the temporary files) */ FreeNodeList(OSMNodes,0); FreeWayList(OSMWays,0); FreeRelationList(OSMRelations,0); printf("\n"); fflush(stdout); printf_program_end(); exit(EXIT_SUCCESS); } /*++++++++++++++++++++++++++++++++++++++ Print out the usage information. int detail The level of detail to use: -1 = just version number, 0 = low detail, 1 = full details. const char *argerr The argument that gave the error (if there is one). const char *err Other error message (if there is one). ++++++++++++++++++++++++++++++++++++++*/ static void print_usage(int detail,const char *argerr,const char *err) { if(detail<0) { fprintf(stderr, "Routino version " ROUTINO_VERSION " " ROUTINO_URL ".\n" ); } if(detail>=0) { fprintf(stderr, "Usage: planetsplitter [--version]\n" " [--help]\n" " [--dir=] [--prefix=]\n" #if defined(USE_PTHREADS) && USE_PTHREADS " [--sort-ram-size=] [--sort-threads=]\n" #else " [--sort-ram-size=]\n" #endif " [--tmpdir=]\n" " [--tagging=]\n" " [--loggable] [--logtime] [--logmemory]\n" " [--errorlog[=]]\n" " [--parse-only | --process-only]\n" " [--append] [--keep] [--changes]\n" " [--max-iterations=]\n" " [--prune-none]\n" " [--prune-isolated=]\n" " [--prune-short=]\n" " [--prune-straight=]\n" " [ ... | ...\n" " | ...\n" " | ... | ..." #if defined(USE_BZIP2) && USE_BZIP2 "\n | ..." #endif #if defined(USE_GZIP) && USE_GZIP "\n | ..." #endif #if defined(USE_XZ) && USE_XZ "\n | ..." #endif "]\n"); if(argerr) fprintf(stderr, "\n" "Error with command line parameter: %s\n",argerr); if(err) fprintf(stderr, "\n" "Error: %s\n",err); } if(detail==1) fprintf(stderr, "\n" "--version Print the version of Routino.\n" "\n" "--help Prints this information.\n" "\n" "--dir= The directory containing the routing database.\n" "--prefix= The filename prefix for the routing database.\n" "\n" "--sort-ram-size= The amount of RAM (in MB) to use for data sorting\n" #if SLIM " (defaults to 64MB otherwise.)\n" #else " (defaults to 256MB otherwise.)\n" #endif #if defined(USE_PTHREADS) && USE_PTHREADS "--sort-threads= The number of threads to use for data sorting.\n" #endif "\n" "--tmpdir= The directory name for temporary files.\n" " (defaults to the '--dir' option directory.)\n" "\n" "--tagging= The name of the XML file containing the tagging rules\n" " (defaults to 'tagging.xml' with '--dir' and\n" " '--prefix' options or the file installed in\n" " '" ROUTINO_DATADIR "').\n" "\n" "--loggable Print progress messages suitable for logging to file.\n" "--logtime Print the elapsed time for each processing step.\n" "--logmemory Print the max allocated/mapped memory for each step.\n" "--errorlog[=] Log parsing errors to 'error.log' or the given name\n" " (the '--dir' and '--prefix' options are applied).\n" "\n" "--parse-only Parse the OSM/OSC file(s) and store the results.\n" "--process-only Process the stored results from previous option.\n" "--append Parse the OSM file(s) and append to existing results.\n" "--keep Keep the intermediate files after parsing & sorting.\n" "--changes Parse the data as an OSC file and apply the changes.\n" "\n" "--max-iterations= The number of iterations for finding super-nodes\n" " (defaults to 5).\n" "\n" "--prune-none Disable the prune options below, they are re-enabled\n" " by adding them to the command line after this option.\n" "--prune-isolated= Remove access from small disconnected segment groups\n" " (defaults to removing groups under 500m).\n" "--prune-short= Remove short segments (defaults to removing segments\n" " up to a maximum length of 5m).\n" "--prune-straight= Remove nodes in almost straight highways (defaults to\n" " removing nodes up to 3m offset from a straight line).\n" "\n" ", , , , \n" " The name(s) of the file(s) to read and parse.\n" " Filenames ending '.pbf' read as PBF, filenames ending\n" " '.o5m' or '.o5c' read as O5M/O5C, others as XML.\n" #if defined(USE_BZIP2) && USE_BZIP2 " Filenames ending '.bz2' will be bzip2 uncompressed.\n" #endif #if defined(USE_GZIP) && USE_GZIP " Filenames ending '.gz' will be gzip uncompressed.\n" #endif #if defined(USE_XZ) && USE_XZ " Filenames ending '.xz' will be xz uncompressed.\n" #endif "\n" " defaults to all but can be set to:\n" "%s" "\n" " can be selected from:\n" "%s" "\n" " can be selected from:\n" "%s", TransportList(),HighwayList(),PropertyList()); exit(!detail); } routino-3.0/src/mman-win32.h 644 233 144 5064 12531126220 11052 0/*************************************** Windows 32 memory management functions from https://code.google.com/p/mman-win32 File header comment created by Andrew M. Bishop, all source code unchanged from original. ******************/ /****************** Copyright (c) 2010,2012 Viktor Kutuzov Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ***************************************/ #ifndef _SYS_MMAN_H_ #define _SYS_MMAN_H_ #ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later. #define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows. #endif /* All the headers include this file. */ #ifndef _MSC_VER #include <_mingw.h> #endif #include #ifdef __cplusplus extern "C" { #endif #define PROT_NONE 0 #define PROT_READ 1 #define PROT_WRITE 2 #define PROT_EXEC 4 #define MAP_FILE 0 #define MAP_SHARED 1 #define MAP_PRIVATE 2 #define MAP_TYPE 0xf #define MAP_FIXED 0x10 #define MAP_ANONYMOUS 0x20 #define MAP_ANON MAP_ANONYMOUS #define MAP_FAILED ((void *)-1) /* Flags for msync. */ #define MS_ASYNC 1 #define MS_SYNC 2 #define MS_INVALIDATE 4 void* mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off); int munmap(void *addr, size_t len); int mprotect(void *addr, size_t len, int prot); int msync(void *addr, size_t len, int flags); int mlock(const void *addr, size_t len); int munlock(const void *addr, size_t len); #ifdef __cplusplus }; #endif #endif /* _SYS_MMAN_H_ */ routino-3.0/src/profiles.c 644 233 144 106707 12563633673 11072 0/*************************************** Load the profiles from a file and the functions for handling them. Part of the Routino routing software. ******************/ /****************** This file Copyright 2008-2015 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #include #include #include #include #include "types.h" #include "ways.h" #include "files.h" #include "profiles.h" #include "xmlparse.h" /* Local variables (re-intialised by FreeXMLProfiles() function) */ /*+ The profiles that have been loaded from file. +*/ static Profile **loaded_profiles=NULL; /*+ The number of profiles that have been loaded from file. +*/ static int nloaded_profiles=0; /* Local variables (re-initialised for each file) */ /*+ Store all of the profiles. +*/ static int store_all; /*+ The profile name that is to be stored. +*/ static const char *store_name; /*+ This current profile is to be stored. +*/ static int store; /* The XML tag processing function prototypes */ //static int xmlDeclaration_function(const char *_tag_,int _type_,const char *version,const char *encoding); //static int RoutinoProfilesType_function(const char *_tag_,int _type_); static int profileType_function(const char *_tag_,int _type_,const char *name,const char *transport); //static int speedsType_function(const char *_tag_,int _type_); //static int preferencesType_function(const char *_tag_,int _type_); //static int propertiesType_function(const char *_tag_,int _type_); //static int restrictionsType_function(const char *_tag_,int _type_); static int speedType_function(const char *_tag_,int _type_,const char *highway,const char *kph); static int preferenceType_function(const char *_tag_,int _type_,const char *highway,const char *percent); static int propertyType_function(const char *_tag_,int _type_,const char *type,const char *percent); static int onewayType_function(const char *_tag_,int _type_,const char *obey); static int turnsType_function(const char *_tag_,int _type_,const char *obey); static int weightType_function(const char *_tag_,int _type_,const char *limit); static int heightType_function(const char *_tag_,int _type_,const char *limit); static int widthType_function(const char *_tag_,int _type_,const char *limit); static int lengthType_function(const char *_tag_,int _type_,const char *limit); /* The XML tag definitions (forward declarations) */ static const xmltag xmlDeclaration_tag; static const xmltag RoutinoProfilesType_tag; static const xmltag profileType_tag; static const xmltag speedsType_tag; static const xmltag preferencesType_tag; static const xmltag propertiesType_tag; static const xmltag restrictionsType_tag; static const xmltag speedType_tag; static const xmltag preferenceType_tag; static const xmltag propertyType_tag; static const xmltag onewayType_tag; static const xmltag turnsType_tag; static const xmltag weightType_tag; static const xmltag heightType_tag; static const xmltag widthType_tag; static const xmltag lengthType_tag; /* The XML tag definition values */ /*+ The complete set of tags at the top level. +*/ static const xmltag * const xml_toplevel_tags[]={&xmlDeclaration_tag,&RoutinoProfilesType_tag,NULL}; /*+ The xmlDeclaration type tag. +*/ static const xmltag xmlDeclaration_tag= {"xml", 2, {"version","encoding"}, NULL, {NULL}}; /*+ The RoutinoProfilesType type tag. +*/ static const xmltag RoutinoProfilesType_tag= {"routino-profiles", 0, {NULL}, NULL, {&profileType_tag,NULL}}; /*+ The profileType type tag. +*/ static const xmltag profileType_tag= {"profile", 2, {"name","transport"}, profileType_function, {&speedsType_tag,&preferencesType_tag,&propertiesType_tag,&restrictionsType_tag,NULL}}; /*+ The speedsType type tag. +*/ static const xmltag speedsType_tag= {"speeds", 0, {NULL}, NULL, {&speedType_tag,NULL}}; /*+ The preferencesType type tag. +*/ static const xmltag preferencesType_tag= {"preferences", 0, {NULL}, NULL, {&preferenceType_tag,NULL}}; /*+ The propertiesType type tag. +*/ static const xmltag propertiesType_tag= {"properties", 0, {NULL}, NULL, {&propertyType_tag,NULL}}; /*+ The restrictionsType type tag. +*/ static const xmltag restrictionsType_tag= {"restrictions", 0, {NULL}, NULL, {&onewayType_tag,&turnsType_tag,&weightType_tag,&heightType_tag,&widthType_tag,&lengthType_tag,NULL}}; /*+ The speedType type tag. +*/ static const xmltag speedType_tag= {"speed", 2, {"highway","kph"}, speedType_function, {NULL}}; /*+ The preferenceType type tag. +*/ static const xmltag preferenceType_tag= {"preference", 2, {"highway","percent"}, preferenceType_function, {NULL}}; /*+ The propertyType type tag. +*/ static const xmltag propertyType_tag= {"property", 2, {"type","percent"}, propertyType_function, {NULL}}; /*+ The onewayType type tag. +*/ static const xmltag onewayType_tag= {"oneway", 1, {"obey"}, onewayType_function, {NULL}}; /*+ The turnsType type tag. +*/ static const xmltag turnsType_tag= {"turns", 1, {"obey"}, turnsType_function, {NULL}}; /*+ The weightType type tag. +*/ static const xmltag weightType_tag= {"weight", 1, {"limit"}, weightType_function, {NULL}}; /*+ The heightType type tag. +*/ static const xmltag heightType_tag= {"height", 1, {"limit"}, heightType_function, {NULL}}; /*+ The widthType type tag. +*/ static const xmltag widthType_tag= {"width", 1, {"limit"}, widthType_function, {NULL}}; /*+ The lengthType type tag. +*/ static const xmltag lengthType_tag= {"length", 1, {"limit"}, lengthType_function, {NULL}}; /* The XML tag processing functions */ /*++++++++++++++++++++++++++++++++++++++ The function that is called when the XML declaration is seen int xmlDeclaration_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *version The contents of the 'version' attribute (or NULL if not defined). const char *encoding The contents of the 'encoding' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ //static int xmlDeclaration_function(const char *_tag_,int _type_,const char *version,const char *encoding) //{ // return(0); //} /*++++++++++++++++++++++++++++++++++++++ The function that is called when the RoutinoProfilesType XSD type is seen int RoutinoProfilesType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. ++++++++++++++++++++++++++++++++++++++*/ //static int RoutinoProfilesType_function(const char *_tag_,int _type_) //{ // return(0); //} /*++++++++++++++++++++++++++++++++++++++ The function that is called when the profileType XSD type is seen int profileType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *name The contents of the 'name' attribute (or NULL if not defined). const char *transport The contents of the 'transport' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int profileType_function(const char *_tag_,int _type_,const char *name,const char *transport) { if(_type_&XMLPARSE_TAG_START) { Transport transporttype; int i; XMLPARSE_ASSERT_STRING(_tag_,name); if(store_all) store=1; else if(store_name && !strcmp(store_name,name)) store=1; else store=0; if(store) { for(i=0;iname)) XMLPARSE_MESSAGE(_tag_,"profile name must be unique"); XMLPARSE_ASSERT_STRING(_tag_,transport); transporttype=TransportType(transport); if(transporttype==Transport_None) XMLPARSE_INVALID(_tag_,transport); if((nloaded_profiles%16)==0) loaded_profiles=(Profile**)realloc((void*)loaded_profiles,(nloaded_profiles+16)*sizeof(Profile*)); nloaded_profiles++; loaded_profiles[nloaded_profiles-1]=(Profile*)calloc(1,sizeof(Profile)); loaded_profiles[nloaded_profiles-1]->name=strcpy(malloc(strlen(name)+1),name); loaded_profiles[nloaded_profiles-1]->transport=transporttype; } } if(_type_&XMLPARSE_TAG_END && store) store=0; return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the speedsType XSD type is seen int speedsType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. ++++++++++++++++++++++++++++++++++++++*/ //static int speedsType_function(const char *_tag_,int _type_) //{ // return(0); //} /*++++++++++++++++++++++++++++++++++++++ The function that is called when the preferencesType XSD type is seen int preferencesType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. ++++++++++++++++++++++++++++++++++++++*/ //static int preferencesType_function(const char *_tag_,int _type_) //{ // return(0); //} /*++++++++++++++++++++++++++++++++++++++ The function that is called when the propertiesType XSD type is seen int propertiesType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. ++++++++++++++++++++++++++++++++++++++*/ //static int propertiesType_function(const char *_tag_,int _type_) //{ // return(0); //} /*++++++++++++++++++++++++++++++++++++++ The function that is called when the restrictionsType XSD type is seen int restrictionsType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. ++++++++++++++++++++++++++++++++++++++*/ //static int restrictionsType_function(const char *_tag_,int _type_) //{ // return(0); //} /*++++++++++++++++++++++++++++++++++++++ The function that is called when the speedType XSD type is seen int speedType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *highway The contents of the 'highway' attribute (or NULL if not defined). const char *kph The contents of the 'kph' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int speedType_function(const char *_tag_,int _type_,const char *highway,const char *kph) { if(_type_&XMLPARSE_TAG_START && store) { double speed; Highway highwaytype; XMLPARSE_ASSERT_STRING(_tag_,highway); highwaytype=HighwayType(highway); if(highwaytype==Highway_None) XMLPARSE_INVALID(_tag_,highway); XMLPARSE_ASSERT_FLOATING(_tag_,kph); speed=atof(kph); if(speed<0) XMLPARSE_INVALID(_tag_,kph); loaded_profiles[nloaded_profiles-1]->speed[highwaytype]=kph_to_speed(speed); } return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the preferenceType XSD type is seen int preferenceType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *highway The contents of the 'highway' attribute (or NULL if not defined). const char *percent The contents of the 'percent' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int preferenceType_function(const char *_tag_,int _type_,const char *highway,const char *percent) { if(_type_&XMLPARSE_TAG_START && store) { Highway highwaytype; double p; XMLPARSE_ASSERT_STRING(_tag_,highway); highwaytype=HighwayType(highway); if(highwaytype==Highway_None) XMLPARSE_INVALID(_tag_,highway); XMLPARSE_ASSERT_FLOATING(_tag_,percent); p=atof(percent); if(p<0 || p>100) XMLPARSE_INVALID(_tag_,percent); loaded_profiles[nloaded_profiles-1]->highway[highwaytype]=(score_t)(p/100); } return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the propertyType XSD type is seen int propertyType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *type The contents of the 'type' attribute (or NULL if not defined). const char *percent The contents of the 'percent' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int propertyType_function(const char *_tag_,int _type_,const char *type,const char *percent) { if(_type_&XMLPARSE_TAG_START && store) { Property property; double p; XMLPARSE_ASSERT_STRING(_tag_,type); property=PropertyType(type); if(property==Property_None) XMLPARSE_INVALID(_tag_,type); XMLPARSE_ASSERT_FLOATING(_tag_,percent); p=atof(percent); if(p<0 || p>100) XMLPARSE_INVALID(_tag_,percent); loaded_profiles[nloaded_profiles-1]->props[property]=(score_t)(p/100); } return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the onewayType XSD type is seen int onewayType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *obey The contents of the 'obey' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int onewayType_function(const char *_tag_,int _type_,const char *obey) { if(_type_&XMLPARSE_TAG_START && store) { int o; XMLPARSE_ASSERT_INTEGER(_tag_,obey); o=atoi(obey); loaded_profiles[nloaded_profiles-1]->oneway=!!o; } return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the turnsType XSD type is seen int turnsType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *obey The contents of the 'obey' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int turnsType_function(const char *_tag_,int _type_,const char *obey) { if(_type_&XMLPARSE_TAG_START && store) { int o; XMLPARSE_ASSERT_INTEGER(_tag_,obey); o=atoi(obey); loaded_profiles[nloaded_profiles-1]->turns=!!o; } return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the weightType XSD type is seen int weightType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *limit The contents of the 'limit' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int weightType_function(const char *_tag_,int _type_,const char *limit) { if(_type_&XMLPARSE_TAG_START && store) { double l; XMLPARSE_ASSERT_FLOATING(_tag_,limit); l=atof(limit); if(l<0) XMLPARSE_INVALID(_tag_,limit); loaded_profiles[nloaded_profiles-1]->weight=tonnes_to_weight(l); } return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the heightType XSD type is seen int heightType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *limit The contents of the 'limit' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int heightType_function(const char *_tag_,int _type_,const char *limit) { if(_type_&XMLPARSE_TAG_START && store) { double l; XMLPARSE_ASSERT_FLOATING(_tag_,limit); l=atof(limit); if(l<0) XMLPARSE_INVALID(_tag_,limit); loaded_profiles[nloaded_profiles-1]->height=metres_to_height(l); } return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the widthType XSD type is seen int widthType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *limit The contents of the 'limit' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int widthType_function(const char *_tag_,int _type_,const char *limit) { if(_type_&XMLPARSE_TAG_START && store) { double l; XMLPARSE_ASSERT_FLOATING(_tag_,limit); l=atof(limit); if(l<0) XMLPARSE_INVALID(_tag_,limit); loaded_profiles[nloaded_profiles-1]->width=metres_to_width(l); } return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the lengthType XSD type is seen int lengthType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *limit The contents of the 'limit' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int lengthType_function(const char *_tag_,int _type_,const char *limit) { if(_type_&XMLPARSE_TAG_START && store) { double l; XMLPARSE_ASSERT_FLOATING(_tag_,limit); l=atof(limit); if(l<0) XMLPARSE_INVALID(_tag_,limit); loaded_profiles[nloaded_profiles-1]->length=metres_to_length(l); } return(0); } /*++++++++++++++++++++++++++++++++++++++ The XML profile parser. int ParseXMLProfiles Returns 0 if OK or something else in case of an error. const char *filename The name of the file to read. const char *name The name of the profile to read. int all Set to true to load all the profiles. ++++++++++++++++++++++++++++++++++++++*/ int ParseXMLProfiles(const char *filename,const char *name,int all) { int fd; int retval; if(!ExistsFile(filename)) return(1); fd=OpenFile(filename); /* Delete the existing profiles */ if(nloaded_profiles) FreeXMLProfiles(); /* Initialise variables used for parsing */ store_all=all; store_name=name; store=0; /* Parse the file */ retval=ParseXML(fd,xml_toplevel_tags,XMLPARSE_UNKNOWN_ATTR_ERRNONAME); CloseFile(fd); if(retval) { FreeXMLProfiles(); return(2); } return(0); } /*++++++++++++++++++++++++++++++++++++++ Return a list of the profile names that have been loaded from the XML file. char **GetProfileNames Returns a NULL terminated list of strings - all allocated. ++++++++++++++++++++++++++++++++++++++*/ char **GetProfileNames(void) { char **list=calloc(1+nloaded_profiles,sizeof(char*)); int i; for(i=0;iname)+1),loaded_profiles[i]->name); return(list); } /*++++++++++++++++++++++++++++++++++++++ Get a named profile. Profile *GetProfile Returns a pointer to the profile. const char *name The name of the profile. ++++++++++++++++++++++++++++++++++++++*/ Profile *GetProfile(const char *name) { int i; for(i=0;iname,name)) return(loaded_profiles[i]); return(NULL); } /*++++++++++++++++++++++++++++++++++++++ Free the memory allocated when reading the profiles. ++++++++++++++++++++++++++++++++++++++*/ void FreeXMLProfiles(void) { int i; if(!loaded_profiles) return; for(i=0;iname) free(loaded_profiles[i]->name); free(loaded_profiles[i]); } free(loaded_profiles); loaded_profiles=NULL; nloaded_profiles=0; } /*++++++++++++++++++++++++++++++++++++++ Update a profile with the highway preference scaling factors. int UpdateProfile Returns 1 in case of a problem. Profile *profile The profile to be updated. Ways *ways The set of ways to use. ++++++++++++++++++++++++++++++++++++++*/ int UpdateProfile(Profile *profile,Ways *ways) { int i; /* Check the allowed transport type */ profile->allow=TRANSPORTS(profile->transport); if(!(profile->allow & ways->file.allow)) return(1); /* Normalise the highway preferences into the range ~0 -> 1 */ profile->max_pref=0; for(i=1;ihighway[i]<0) profile->highway[i]=0; if(profile->highway[i]>1) profile->highway[i]=1; if(profile->highway[i]>profile->max_pref) profile->max_pref=profile->highway[i]; } /* Normalise the property preferences into the range ~0 -> 1 */ for(i=1;iprops[i]<0) profile->props[i]=0; if(profile->props[i]>1) profile->props[i]=1; profile->props_yes[i]=profile->props[i]; profile->props_no [i]=1-profile->props_yes[i]; /* Squash the properties; selecting 60% preference without the sqrt() allows routes 50% longer on highways with the property compared to ones without. With the sqrt() function the ratio is only 22% allowing finer control. */ profile->props_yes[i]=(score_t)sqrt(profile->props_yes[i]); profile->props_no [i]=(score_t)sqrt(profile->props_no[i] ); if(profile->props_yes[i]<0.01f) profile->props_yes[i]=0.01f; if(profile->props_no[i]<0.01f) profile->props_no[i]=0.01f; } /* Find the fastest preferred speed */ profile->max_speed=0; for(i=1;ispeed[i]<0.01f) profile->speed[i]=0.01f; if(profile->speed[i]>profile->max_speed) profile->max_speed=profile->speed[i]; } /* Find the most preferred property combination */ for(i=1;ifile.props & PROPERTIES(i)) { if(profile->props_yes[i]>profile->props_no[i]) profile->max_pref*=profile->props_yes[i]; else profile->max_pref*=profile->props_no[i]; } return(0); } /*++++++++++++++++++++++++++++++++++++++ Print out a profile. const Profile *profile The profile to print. ++++++++++++++++++++++++++++++++++++++*/ void PrintProfile(const Profile *profile) { int i; printf("Profile\n=======\n"); printf("\n"); printf("Transport: %s\n",TransportName(profile->transport)); printf("\n"); for(i=1;ihighway[i]*100)); printf("\n"); for(i=1;ihighway[i]) printf("Speed on %-12s: %3d km/h / %2.0f mph\n",HighwayName(i),profile->speed[i],(double)profile->speed[i]/1.6); printf("\n"); for(i=1;iprops[i]*100)); printf("\n"); printf("Obey one-way : %s\n",profile->oneway?"yes":"no"); printf("Obey turns : %s\n",profile->turns?"yes":"no"); printf("Minimum weight: %.1f tonnes\n",weight_to_tonnes(profile->weight)); printf("Minimum height: %.1f metres\n",height_to_metres(profile->height)); printf("Minimum width : %.1f metres\n",width_to_metres(profile->width)); printf("Minimum length: %.1f metres\n",length_to_metres(profile->length)); } /*++++++++++++++++++++++++++++++++++++++ Print out all of the loaded profiles as XML for use as program input. ++++++++++++++++++++++++++++++++++++++*/ void PrintProfilesXML(void) { int i,j; char *padding=" "; printf("\n"); printf("\n"); printf("\n"); printf("\n"); for(j=0;j\n",loaded_profiles[j]->name,TransportName(loaded_profiles[j]->transport)); printf(" \n"); for(i=1;i\n",HighwayName(i),padding+8+strlen(HighwayName(i)),loaded_profiles[j]->speed[i]); printf(" \n"); printf(" \n"); for(i=1;i\n",HighwayName(i),padding+8+strlen(HighwayName(i)),loaded_profiles[j]->highway[i]*100); printf(" \n"); printf(" \n"); for(i=1;i\n",PropertyName(i),padding+8+strlen(PropertyName(i)),loaded_profiles[j]->props[i]*100); printf(" \n"); printf(" \n"); printf(" \n",loaded_profiles[j]->oneway); printf(" \n",loaded_profiles[j]->turns); printf(" \n",weight_to_tonnes(loaded_profiles[j]->weight)); printf(" \n",height_to_metres(loaded_profiles[j]->height)); printf(" \n",width_to_metres(loaded_profiles[j]->width)); printf(" \n",length_to_metres(loaded_profiles[j]->length)); printf(" \n"); printf(" \n"); printf("\n"); } printf("\n"); } /*++++++++++++++++++++++++++++++++++++++ Print out all of the loaded profiles as JavaScript Object Notation for use in a web page. ++++++++++++++++++++++++++++++++++++++*/ void PrintProfilesJSON(void) { int i,j; printf("var routino={ // contains all default Routino options (generated using \"--help-profile-json\").\n"); printf("\n"); printf(" // Default transport type\n"); printf(" transport: \"motorcar\",\n"); printf("\n"); printf(" // Transport types\n"); printf(" transports: { "); for(j=0;jtransport),j+1); printf(" },\n"); printf("\n"); printf(" // Highway types\n"); printf(" highways: { "); for(i=1;itransport),(int)(0.5+loaded_profiles[j]->highway[i]*100)); printf(" }%s\n",i==(Highway_Count-1)?"":","); } printf(" },\n"); printf("\n"); printf(" // Speed limits\n"); printf(" profile_speed: {\n"); for(i=1;itransport),loaded_profiles[j]->speed[i]); printf(" }%s\n",i==(Highway_Count-1)?"":","); } printf(" },\n"); printf("\n"); printf(" // Highway properties\n"); printf(" profile_property: {\n"); for(i=1;itransport),(int)(0.5+loaded_profiles[j]->props[i]*100)); printf(" }%s\n",i==(Property_Count-1)?"":","); } printf(" },\n"); printf("\n"); printf(" // Restrictions\n"); printf(" profile_restrictions: {\n"); printf(" %12s: { ","oneway"); for(j=0;jtransport),loaded_profiles[j]->oneway); printf(" },\n"); printf(" %12s: { ","turns"); for(j=0;jtransport),loaded_profiles[j]->turns); printf(" },\n"); printf(" %12s: { ","weight"); for(j=0;jtransport),weight_to_tonnes(loaded_profiles[j]->weight)); printf(" },\n"); printf(" %12s: { ","height"); for(j=0;jtransport),height_to_metres(loaded_profiles[j]->height)); printf(" },\n"); printf(" %12s: { ","width"); for(j=0;jtransport),width_to_metres(loaded_profiles[j]->width)); printf(" },\n"); printf(" %12s: { ","length"); for(j=0;jtransport),length_to_metres(loaded_profiles[j]->length)); printf(" }\n"); printf(" }\n"); printf("\n"); printf("}; // end of routino variable\n"); } /*++++++++++++++++++++++++++++++++++++++ Print out all of the loaded profiles as Perl for use in a web CGI. ++++++++++++++++++++++++++++++++++++++*/ void PrintProfilesPerl(void) { int i,j; printf("$routino={ # contains all default Routino options (generated using \"--help-profile-perl\").\n"); printf("\n"); printf(" # Default transport type\n"); printf(" transport => \"motorcar\",\n"); printf("\n"); printf(" # Transport types\n"); printf(" transports => { "); for(j=0;j %d",j==0?"":", ",TransportName(loaded_profiles[j]->transport),j+1); printf(" },\n"); printf("\n"); printf(" # Highway types\n"); printf(" highways => { "); for(i=1;i %d",i==1?"":", ",HighwayName(i),i); printf(" },\n"); printf("\n"); printf(" # Property types\n"); printf(" properties => { "); for(i=1;i %d",i==1?"":", ",PropertyName(i),i); printf(" },\n"); printf("\n"); printf(" # Restriction types\n"); printf(" restrictions => { oneway => 1, turns => 2, weight => 3, height => 4, width => 5, length => 6 },\n"); printf("\n"); printf(" # Allowed highways\n"); printf(" profile_highway => {\n"); for(i=1;i {",HighwayName(i)); for(j=0;j %3d",j==0?"":", ",TransportName(loaded_profiles[j]->transport),(int)(0.5+loaded_profiles[j]->highway[i]*100)); printf(" }%s\n",i==(Highway_Count-1)?"":","); } printf(" },\n"); printf("\n"); printf(" # Speed limits\n"); printf(" profile_speed => {\n"); for(i=1;i {",HighwayName(i)); for(j=0;j %3d",j==0?"":", ",TransportName(loaded_profiles[j]->transport),loaded_profiles[j]->speed[i]); printf(" }%s\n",i==(Highway_Count-1)?"":","); } printf(" },\n"); printf("\n"); printf(" # Highway properties\n"); printf(" profile_property => {\n"); for(i=1;i {",PropertyName(i)); for(j=0;j %3d",j==0?"":", ",TransportName(loaded_profiles[j]->transport),(int)(0.5+loaded_profiles[j]->props[i]*100)); printf(" }%s\n",i==(Property_Count-1)?"":","); } printf(" },\n"); printf("\n"); printf(" # Restrictions\n"); printf(" profile_restrictions => {\n"); printf(" %12s => {","oneway"); for(j=0;j %4d",j==0?"":", ",TransportName(loaded_profiles[j]->transport),loaded_profiles[j]->oneway); printf(" },\n"); printf(" %12s => {","turns"); for(j=0;j %4d",j==0?"":", ",TransportName(loaded_profiles[j]->transport),loaded_profiles[j]->turns); printf(" },\n"); printf(" %12s => {","weight"); for(j=0;j %4.1f",j==0?"":", ",TransportName(loaded_profiles[j]->transport),weight_to_tonnes(loaded_profiles[j]->weight)); printf(" },\n"); printf(" %12s => {","height"); for(j=0;j %4.1f",j==0?"":", ",TransportName(loaded_profiles[j]->transport),height_to_metres(loaded_profiles[j]->height)); printf(" },\n"); printf(" %12s => {","width"); for(j=0;j %4.1f",j==0?"":", ",TransportName(loaded_profiles[j]->transport),width_to_metres(loaded_profiles[j]->width)); printf(" },\n"); printf(" %12s => {","length"); for(j=0;j %4.1f",j==0?"":", ",TransportName(loaded_profiles[j]->transport),length_to_metres(loaded_profiles[j]->length)); printf(" }\n"); printf(" }\n"); printf("\n"); printf("}; # end of routino variable\n"); } routino-3.0/src/osmo5mparse.c 644 233 144 44632 12563633053 11467 0/*************************************** A simple o5m/o5c parser. Part of the Routino routing software. ******************/ /****************** This file Copyright 2012-2015 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #include #if defined(_MSC_VER) #include #include #define read(fd,address,length) _read(fd,address,(unsigned int)(length)) #define ssize_t SSIZE_T #else #include #endif #include #include #include #include #include "osmparser.h" #include "tagging.h" #include "logging.h" /* At the top level */ #define O5M_FILE_NODE 0x10 #define O5M_FILE_WAY 0x11 #define O5M_FILE_RELATION 0x12 #define O5M_FILE_BOUNDING_BOX 0xdb #define O5M_FILE_TIMESTAMP 0xdc #define O5M_FILE_HEADER 0xe0 #define O5M_FILE_SYNC 0xee #define O5M_FILE_JUMP 0xef #define O5M_FILE_END 0xfe #define O5M_FILE_RESET 0xff /* Errors */ #define O5M_EOF 0 #define O5M_ERROR_UNEXP_EOF 100 #define O5M_ERROR_RESET_NOT_FIRST 101 #define O5M_ERROR_HEADER_NOT_FIRST 102 #define O5M_ERROR_EXPECTED_O5M 103 #define O5M_ERROR_EXPECTED_O5C 104 #define O5M_ERROR_FILE_LEVEL 105 /* Local parsing variables (re-initialised for each file) */ static uint64_t byteno=0; static uint64_t nnodes=0,nways=0,nrelations=0; static int64_t id=0; static int32_t lat=0; static int32_t lon=0; static int64_t timestamp=0; static int64_t node_refid=0,way_refid=0,relation_refid=0; static int mode_change=MODE_NORMAL; static uint32_t buffer_allocated; static unsigned char *buffer=NULL; static unsigned char *buffer_ptr,*buffer_end; static int string_table_start=0; static unsigned char **string_table=NULL; #define STRING_TABLE_ALLOCATED 15000 /*++++++++++++++++++++++++++++++++++++++ Refill the data buffer and set the pointers. int buffer_refill Return 0 if everything is OK or 1 for EOF. int fd The file descriptor to read from. uint32_t bytes The number of bytes to read. ++++++++++++++++++++++++++++++++++++++*/ static inline int buffer_refill(int fd,uint32_t bytes) { ssize_t n,m; uint32_t totalbytes; m=buffer_end-buffer_ptr; if(m) memmove(buffer,buffer_ptr,m); totalbytes=bytes+m; if(totalbytes>buffer_allocated) buffer=(unsigned char *)realloc(buffer,buffer_allocated=totalbytes); byteno+=bytes; buffer_ptr=buffer; buffer_end=buffer+m; do { n=read(fd,buffer_end,bytes); if(n<=0) return(1); buffer_end+=n; bytes-=n; } while(bytes>0); return(0); } static void process_node(void); static void process_way(void); static void process_relation(void); static void process_info(void); static unsigned char *process_string(int pair,unsigned char **buf_ptr,unsigned char **string1,unsigned char **string2); /* Macros to simplify the parser (and make it look more like the XML parser) */ #define BEGIN(xx) do{ state=(xx); goto finish_parsing; } while(0) #define BUFFER_CHARS(xx) do{ if(buffer_refill(fd,(xx))) BEGIN(O5M_ERROR_UNEXP_EOF); } while(0) /* O5M decoding */ #define O5M_LATITUDE(xx) (double)(1E-7*(xx)) #define O5M_LONGITUDE(xx) (double)(1E-7*(xx)) /*++++++++++++++++++++++++++++++++++++++ Parse an O5M int32 data value. uint32_t o5m_int32 Returns the integer value. unsigned char **ptr The pointer to read the data from. ++++++++++++++++++++++++++++++++++++++*/ static inline uint32_t o5m_int32(unsigned char **ptr) { uint32_t result=(**ptr)&0x7F; if((**ptr)&0x80) result+=((*++(*ptr))&0x7F)<<7; if((**ptr)&0x80) result+=((*++(*ptr))&0x7F)<<14; if((**ptr)&0x80) result+=((*++(*ptr))&0x7F)<<21; if((**ptr)&0x80) result+=((*++(*ptr))&0x7F)<<28; (*ptr)++; return(result); } /*++++++++++++++++++++++++++++++++++++++ Parse an O5M int32 data value. int32_t o5m_sint32 Returns the integer value. unsigned char **ptr The pointer to read the data from. ++++++++++++++++++++++++++++++++++++++*/ static inline int32_t o5m_sint32(unsigned char **ptr) { int64_t result=((**ptr)&0x7E)>>1; int sign=(**ptr)&0x01; if((**ptr)&0x80) result+=(int64_t)((*++(*ptr))&0x7F)<<6; if((**ptr)&0x80) result+=(int64_t)((*++(*ptr))&0x7F)<<13; if((**ptr)&0x80) result+=(int64_t)((*++(*ptr))&0x7F)<<20; if((**ptr)&0x80) result+=(int64_t)((*++(*ptr))&0x7F)<<27; (*ptr)++; if(sign) result=-result-1; return(result); } /*++++++++++++++++++++++++++++++++++++++ Parse an O5M int64 data value. int64_t o5m_int64 Returns the integer value. unsigned char **ptr The pointer to read the data from. ++++++++++++++++++++++++++++++++++++++*/ static inline int64_t o5m_int64(unsigned char **ptr) { uint64_t result=(**ptr)&0x7F; if((**ptr)&0x80) result+=(uint64_t)((*++(*ptr))&0x7F)<<7; if((**ptr)&0x80) result+=(uint64_t)((*++(*ptr))&0x7F)<<14; if((**ptr)&0x80) result+=(uint64_t)((*++(*ptr))&0x7F)<<21; if((**ptr)&0x80) result+=(uint64_t)((*++(*ptr))&0x7F)<<28; if((**ptr)&0x80) result+=(uint64_t)((*++(*ptr))&0x7F)<<35; if((**ptr)&0x80) result+=(uint64_t)((*++(*ptr))&0x7F)<<42; if((**ptr)&0x80) result+=(uint64_t)((*++(*ptr))&0x7F)<<49; if((**ptr)&0x80) result+=(uint64_t)((*++(*ptr))&0x7F)<<56; if((**ptr)&0x80) result+=(uint64_t)((*++(*ptr))&0x7F)<<63; (*ptr)++; return(result); } /*++++++++++++++++++++++++++++++++++++++ Parse an O5M sint64 data value. int64_t o5m_sint64 Returns the integer value. unsigned char **ptr The pointer to read the data from. ++++++++++++++++++++++++++++++++++++++*/ static inline int64_t o5m_sint64(unsigned char **ptr) { int64_t result=((**ptr)&0x7E)>>1; int sign=(**ptr)&0x01; if((**ptr)&0x80) result+=(int64_t)((*++(*ptr))&0x7F)<<6; if((**ptr)&0x80) result+=(int64_t)((*++(*ptr))&0x7F)<<13; if((**ptr)&0x80) result+=(int64_t)((*++(*ptr))&0x7F)<<20; if((**ptr)&0x80) result+=(int64_t)((*++(*ptr))&0x7F)<<27; if((**ptr)&0x80) result+=(int64_t)((*++(*ptr))&0x7F)<<34; if((**ptr)&0x80) result+=(int64_t)((*++(*ptr))&0x7F)<<41; if((**ptr)&0x80) result+=(int64_t)((*++(*ptr))&0x7F)<<48; if((**ptr)&0x80) result+=(int64_t)((*++(*ptr))&0x7F)<<55; if((**ptr)&0x80) result+=(int64_t)((*++(*ptr))&0x7F)<<62; (*ptr)++; if(sign) result=-result-1; return(result); } /*++++++++++++++++++++++++++++++++++++++ Parse the O5M and call the functions for each OSM item as seen. int ParseO5M Returns 0 if OK or something else in case of an error. int fd The file descriptor of the file to parse. int changes Set to 1 if this is expected to be a changes file, otherwise zero. ++++++++++++++++++++++++++++++++++++++*/ static int ParseO5M(int fd,int changes) { int i; int state; int number_reset=0; int error; /* Print the initial message */ printf_first("Reading: Bytes=0 Nodes=0 Ways=0 Relations=0"); /* The actual parser. */ nnodes=0,nways=0,nrelations=0; if(changes) mode_change=MODE_MODIFY; string_table_start=0; string_table=(unsigned char **)malloc(STRING_TABLE_ALLOCATED*sizeof(unsigned char *)); for(i=0;i. ***************************************/ #include #include #include #if defined(USE_PTHREADS) && USE_PTHREADS #include #endif #include "types.h" #include "logging.h" #include "files.h" #include "sorting.h" /* Global variables */ /*+ The command line '--tmpdir' option or its default value. +*/ extern char *option_tmpdirname; /*+ The amount of RAM to use for filesorting. +*/ extern size_t option_filesort_ramsize; /*+ The number of filesorting threads allowed. +*/ extern int option_filesort_threads; /* Thread data type definitions */ /*+ A data type for holding data for a thread. +*/ typedef struct _thread_data { #if defined(USE_PTHREADS) && USE_PTHREADS pthread_t thread; /*+ The thread identifier. +*/ int running; /*+ A flag indicating the current state of the thread. +*/ #endif char *data; /*+ The main data array. +*/ void **datap; /*+ An array of pointers to the data objects. +*/ size_t n; /*+ The number of pointers. +*/ char *filename; /*+ The name of the file to write the results to. +*/ size_t itemsize; /*+ The size of each item. +*/ int (*compare)(const void*,const void*); /*+ The comparison function. +*/ } thread_data; /* Thread variables */ #if defined(USE_PTHREADS) && USE_PTHREADS static pthread_mutex_t running_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t running_cond = PTHREAD_COND_INITIALIZER; #endif /* Thread helper functions */ static void *filesort_fixed_heapsort_thread(thread_data *thread); static void *filesort_vary_heapsort_thread(thread_data *thread); /*++++++++++++++++++++++++++++++++++++++ A function to sort the contents of a file of fixed length objects using a limited amount of RAM. The data is sorted using a "Merge sort" http://en.wikipedia.org/wiki/Merge_sort and in particular an "external sort" http://en.wikipedia.org/wiki/External_sorting. The individual sort steps and the merge step both use a "Heap sort" http://en.wikipedia.org/wiki/Heapsort. The combination of the two should work well if the data is already partially sorted. index_t filesort_fixed Returns the number of objects kept. int fd_in The file descriptor of the input file (opened for reading and at the beginning). int fd_out The file descriptor of the output file (opened for writing and empty). size_t itemsize The size of each item in the file that needs sorting. int (*pre_sort_function)(void *,index_t) If non-NULL then this function is called for each item before they have been sorted. The second parameter is the number of objects previously read from the input file. If the function returns 1 then the object is kept and it is sorted, otherwise it is ignored. int (*compare_function)(const void*, const void*) The comparison function. This is identical to qsort if the data to be sorted is an array of things not pointers. int (*post_sort_function)(void *,index_t) If non-NULL then this function is called for each item after they have been sorted. The second parameter is the number of objects already written to the output file. If the function returns 1 then the object is written to the output file., otherwise it is ignored. ++++++++++++++++++++++++++++++++++++++*/ index_t filesort_fixed(int fd_in,int fd_out,size_t itemsize,int (*pre_sort_function)(void*,index_t), int (*compare_function)(const void*,const void*), int (*post_sort_function)(void*,index_t)) { int *fds=NULL,*heap=NULL; int nfiles=0,ndata=0; index_t count_out=0,count_in=0,total=0; size_t nitems; char *data; void **datap; thread_data *threads; size_t item; int i,more=1; #if defined(USE_PTHREADS) && USE_PTHREADS int nthreads=0; #endif /* Allocate the RAM buffer and other bits */ nitems=SizeFileFD(fd_in)/itemsize; if(nitems==0) return(0); if((nitems*(itemsize+sizeof(void*)))1) { /* Find a spare slot (one *must* be unused at all times) */ pthread_mutex_lock(&running_mutex); for(thread=0;thread1) { pthread_mutex_lock(&running_mutex); while(nthreads==(option_filesort_threads-1)) { for(i=0;i1 && nthreads) { pthread_mutex_lock(&running_mutex); pthread_cond_wait(&running_cond,&running_mutex); for(i=0;i1) { int newindex; int temp; newindex=index/2; if(compare_function(datap[heap[index]],datap[heap[newindex]])>=0) break; temp=heap[index]; heap[index]=heap[newindex]; heap[newindex]=temp; index=newindex; } } /* Repeatedly pull out the root of the heap and refill from the same file */ ndata=nfiles; do { int index=1; if(!post_sort_function || post_sort_function(datap[heap[index]],count_out)) { WriteFileBuffered(fd_out,datap[heap[index]],itemsize); count_out++; } if(ReadFileBuffered(fds[heap[index]],datap[heap[index]],itemsize)) { heap[index]=heap[ndata]; ndata--; } /* Bubble down the new value */ while((2*index)=0) newindex=newindex+1; if(compare_function(datap[heap[index]],datap[heap[newindex]])<=0) break; temp=heap[newindex]; heap[newindex]=heap[index]; heap[index]=temp; index=newindex; } if((2*index)==ndata) { int newindex; int temp; newindex=2*index; if(compare_function(datap[heap[index]],datap[heap[newindex]])<=0) ; /* break */ else { temp=heap[newindex]; heap[newindex]=heap[index]; heap[index]=temp; } } } while(ndata>0); /* Tidy up */ tidy_and_exit: if(fds) { for(i=0;i1) { /* Find a spare slot (one *must* be unused at all times) */ pthread_mutex_lock(&running_mutex); for(thread=0;threadlargestitemsize) largestitemsize=itemsize; ramused+=itemsize; ramused =FILESORT_VARALIGN*((ramused+FILESORT_VARSIZE-1)/FILESORT_VARALIGN); ramused+=FILESORT_VARALIGN-FILESORT_VARSIZE; total++; threads[thread].n++; } else ramused-=FILESORT_VARSIZE; count_in++; if(ReadFileBuffered(fd_in,&nextitemsize,FILESORT_VARSIZE)) { more=0; break; } } /* No new data read in this time round */ if(threads[thread].n==0) break; /* Sort the data pointers using a heap sort (potentially in a thread) */ if(more==0 && nfiles==0) threads[thread].filename[0]=0; else sprintf(threads[thread].filename,"%s/filesort.%d.tmp",option_tmpdirname,nfiles); #if defined(USE_PTHREADS) && USE_PTHREADS /* Shortcut if only one file, don't write to disk */ if(more==0 && nfiles==0) filesort_heapsort(threads[thread].datap,threads[thread].n,threads[thread].compare); else if(option_filesort_threads>1) { pthread_mutex_lock(&running_mutex); while(nthreads==(option_filesort_threads-1)) { for(i=0;i1 && nthreads) { pthread_mutex_lock(&running_mutex); pthread_cond_wait(&running_cond,&running_mutex); for(i=0;i1) { int newindex; int temp; newindex=index/2; if(compare_function(datap[heap[index]],datap[heap[newindex]])>=0) break; temp=heap[index]; heap[index]=heap[newindex]; heap[newindex]=temp; index=newindex; } } /* Repeatedly pull out the root of the heap and refill from the same file */ ndata=nfiles; do { int index=1; FILESORT_VARINT itemsize; if(!post_sort_function || post_sort_function(datap[heap[index]],count_out)) { itemsize=*(FILESORT_VARINT*)((char*)datap[heap[index]]-FILESORT_VARSIZE); WriteFileBuffered(fd_out,(char*)datap[heap[index]]-FILESORT_VARSIZE,itemsize+FILESORT_VARSIZE); count_out++; } if(ReadFileBuffered(fds[heap[index]],&itemsize,FILESORT_VARSIZE)) { heap[index]=heap[ndata]; ndata--; } else { *(FILESORT_VARINT*)((char*)datap[heap[index]]-FILESORT_VARSIZE)=itemsize; ReadFileBuffered(fds[heap[index]],datap[heap[index]],itemsize); } /* Bubble down the new value */ while((2*index)=0) newindex=newindex+1; if(compare_function(datap[heap[index]],datap[heap[newindex]])<=0) break; temp=heap[newindex]; heap[newindex]=heap[index]; heap[index]=temp; index=newindex; } if((2*index)==ndata) { int newindex; int temp; newindex=2*index; if(compare_function(datap[heap[index]],datap[heap[newindex]])<=0) ; /* break */ else { temp=heap[newindex]; heap[newindex]=heap[index]; heap[index]=temp; } } } while(ndata>0); /* Tidy up */ tidy_and_exit: if(fds) { for(i=0;idatap,thread->n,thread->compare); /* Create a temporary file and write the result */ fd=OpenFileBufferedNew(thread->filename); for(item=0;itemn;item++) WriteFileBuffered(fd,thread->datap[item],thread->itemsize); CloseFileBuffered(fd); #if defined(USE_PTHREADS) && USE_PTHREADS if(option_filesort_threads>1) { pthread_mutex_lock(&running_mutex); thread->running=2; pthread_cond_signal(&running_cond); pthread_mutex_unlock(&running_mutex); } #endif return(NULL); } /*++++++++++++++++++++++++++++++++++++++ A wrapper function that can be run in a thread for variable data. void *filesort_vary_heapsort_thread Returns NULL (required to return void*). thread_data *thread The data to be processed in this thread. ++++++++++++++++++++++++++++++++++++++*/ static void *filesort_vary_heapsort_thread(thread_data *thread) { int fd; size_t item; /* Sort the data pointers using a heap sort */ filesort_heapsort(thread->datap,thread->n,thread->compare); /* Create a temporary file and write the result */ fd=OpenFileBufferedNew(thread->filename); for(item=0;itemn;item++) { FILESORT_VARINT itemsize=*(FILESORT_VARINT*)((char*)thread->datap[item]-FILESORT_VARSIZE); WriteFileBuffered(fd,(char*)thread->datap[item]-FILESORT_VARSIZE,itemsize+FILESORT_VARSIZE); } CloseFileBuffered(fd); #if defined(USE_PTHREADS) && USE_PTHREADS if(option_filesort_threads>1) { pthread_mutex_lock(&running_mutex); thread->running=2; pthread_cond_signal(&running_cond); pthread_mutex_unlock(&running_mutex); } #endif return(NULL); } /*++++++++++++++++++++++++++++++++++++++ A function to sort an array of pointers efficiently. The data is sorted using a "Heap sort" http://en.wikipedia.org/wiki/Heapsort, in particular, this is good because it can operate in-place and doesn't allocate more memory like using qsort() does. void **datap A pointer to the array of pointers to sort. size_t nitems The number of items of data to sort. int (*compare_function)(const void*, const void*) The comparison function. This is identical to qsort if the data to be sorted is an array of things not pointers. ++++++++++++++++++++++++++++++++++++++*/ void filesort_heapsort(void **datap,size_t nitems,int(*compare_function)(const void*, const void*)) { void **datap1=&datap[-1]; size_t item; /* Fill the heap by pretending to insert the data that is already there */ for(item=2;item<=nitems;item++) { size_t index=item; /* Bubble up the new value (upside-down, put largest at top) */ while(index>1) { int newindex; void *temp; newindex=index/2; if(compare_function(datap1[index],datap1[newindex])<=0) /* reversed comparison to filesort_fixed() above */ break; temp=datap1[index]; datap1[index]=datap1[newindex]; datap1[newindex]=temp; index=newindex; } } /* Repeatedly pull out the root of the heap and swap with the bottom item */ for(item=nitems;item>1;item--) { size_t index=1; void *temp; temp=datap1[index]; datap1[index]=datap1[item]; datap1[item]=temp; /* Bubble down the new value (upside-down, put largest at top) */ while((2*index)<(item-1)) { int newindex; void *temp; newindex=2*index; if(compare_function(datap1[newindex],datap1[newindex+1])<=0) /* reversed comparison to filesort_fixed() above */ newindex=newindex+1; if(compare_function(datap1[index],datap1[newindex])>=0) /* reversed comparison to filesort_fixed() above */ break; temp=datap1[newindex]; datap1[newindex]=datap1[index]; datap1[index]=temp; index=newindex; } if((2*index)==(item-1)) { int newindex; void *temp; newindex=2*index; if(compare_function(datap1[index],datap1[newindex])>=0) /* reversed comparison to filesort_fixed() above */ ; /* break */ else { temp=datap1[newindex]; datap1[newindex]=datap1[index]; datap1[index]=temp; } } } } routino-3.0/src/xml/ 40755 233 144 0 12575036711 7605 5routino-3.0/src/xml/test/ 40755 233 144 0 12531652211 10553 5routino-3.0/src/xml/test/bad-unexpected-right-angle.xml 644 233 144 213 12064636364 16370 0 > routino-3.0/src/xml/test/bad-xml-header-at-end.xml 644 233 144 202 12064636364 15217 0 routino-3.0/src/xml/test/bad-tag-attr-space-before-equal.xml 644 233 144 222 12064636364 17206 0 routino-3.0/src/xml/test/bad-tag-attr-space-after-equal.xml 644 233 144 222 12064636364 17045 0 routino-3.0/src/xml/test/bad-tag-attr-no-quotes.xml 644 233 144 217 12064636364 15504 0 routino-3.0/src/xml/test/bad-comment-extra-double-dash.xml 644 233 144 205 12064636364 16776 0 routino-3.0/src/xml/test/bad-tag-level-nesting.xml 644 233 144 203 12064636364 15351 0 routino-3.0/src/xml/test/bad-end-tag-space-at-end.xml 644 233 144 204 12064636364 15603 0 routino-3.0/src/xml/test/bad-double-quote-attr-left-angle.xml 644 233 144 233 12064636364 17420 0 routino-3.0/src/xml/test/bad-xml-header-at-begin.xml 644 233 144 204 12064636364 15537 0 routino-3.0/src/xml/test/bad-attr-entity-ref.xml 644 233 144 252 12064636364 15066 0 routino-3.0/src/xml/test/bad-unbalanced-tag-start-end.xml 644 233 144 203 12064636364 16570 0 routino-3.0/src/xml/test/bad-single-quote-attr-invalid-utf8.xml 644 233 144 233 12064636364 17723 0 routino-3.0/src/xml/test/bad-unexpected-end-tag.xml 644 233 144 204 12064636364 15506 0 routino-3.0/src/xml/test/bad-double-quote-attr-right-angle.xml 644 233 144 233 12064636364 17603 0 routino-3.0/src/xml/test/bad-unexpected-attribute-name.xml 644 233 144 225 12064636364 17113 0 routino-3.0/src/xml/test/test.xsd 644 233 144 2512 12064636364 12302 0 routino-3.0/src/xml/test/bad-end-tag-space-at-begin1.xml 644 233 144 204 12064636364 16202 0 routino-3.0/src/xml/test/bad-double-quote-attr-invalid-ascii.xml 644 233 144 233 12064636364 20116 0 routino-3.0/src/xml/test/bad-xml-header-not-first.xml 644 233 144 203 12064636364 15775 0 routino-3.0/src/xml/test/bad-start-tag-space-at-begin.xml 644 233 144 204 12064636364 16510 0 < level1> routino-3.0/src/xml/test/bad-double-quote-attr-invalid-utf8.xml 644 233 144 233 12064636364 17714 0 routino-3.0/src/xml/test/bad-end-tag-with-attr.xml 644 233 144 221 12064636364 15264 0 routino-3.0/src/xml/test/bad-text-outside.xml 644 233 144 235 12064636364 14467 0 text routino-3.0/src/xml/test/bad-single-quote-attr-invalid-ascii.xml 644 233 144 233 12064636364 20125 0 routino-3.0/src/xml/test/bad-comment-ends-triple-dash.xml 644 233 144 203 12064636364 16627 0 routino-3.0/src/xml/test/bad-end-tag-space-at-begin2.xml 644 233 144 204 12064636364 16203 0 < /level1> routino-3.0/src/xml/test/bad-unexpected-left-angle.xml 644 233 144 213 12064636364 16205 0 < routino-3.0/src/xml/test/bad-single-quote-attr-left-angle.xml 644 233 144 233 12064636364 17427 0 routino-3.0/src/xml/test/bad-single-quote-attr-right-angle.xml 644 233 144 233 12064636364 17612 0 routino-3.0/src/xml/test/good.xml 644 233 144 252 12064636364 12234 0 routino-3.0/src/xml/test/bad-early-end-of-file.xml 644 233 144 173 12064636364 15231 0 routino-3.0/src/xml/test/bad-double-quote-attr-amp.xml 644 233 144 233 12064636364 16157 0 routino-3.0/src/xml/test/bad-single-quote-attr-amp.xml 644 233 144 233 12064636364 16166 0 routino-3.0/src/xml/Makefile 644 233 144 5524 12563637433 11274 0# XML test programs Makefile # # Part of the Routino routing software. # # This file Copyright 2010-2015 Andrew M. Bishop # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # # All configuration is in the top-level Makefile.conf include ../../Makefile.conf # Compilation targets XMLDIR=../../xml X=$(notdir $(wildcard $(XMLDIR)/*.xsd)) C=$(foreach f,$(X),$(addsuffix -skeleton.c,$(basename $f))) D=$(wildcard .deps/*.d) O=$(foreach f,$(C),$(addsuffix .o,$(basename $f))) E=$(foreach f,$(C),$(addsuffix $(.EXE),$(basename $f))) EXE=xsd-to-xmlparser$(.EXE) ######## all: $(EXE) $(C) $(E) ######## xsd-to-xmlparser$(.EXE) : xsd-to-xmlparser.o ../xmlparse.o $(LD) $^ -o $@ $(LDFLAGS) ######## %-skeleton.c : $(XMLDIR)/%.xsd xsd-to-xmlparser$(.EXE) -./xsd-to-xmlparser < $< > $@ @test -s $@ || rm $@ %-skeleton$(.EXE) : %-skeleton.o ../xmlparse.o $(LD) $^ -o $@ $(LDFLAGS) .SECONDARY : $(O) ######## ../xmlparse.o : ../xmlparse.c ../xmlparse.h cd .. && $(MAKE) xmlparse.o ######## %.o : %.c @[ -d .deps ] || mkdir .deps $(CC) -c $(CFLAGS) -I.. $< -o $@ -MMD -MP -MF $(addprefix .deps/,$(addsuffix .d,$(basename $@))) ######## test: test-skeleton$(.EXE) @status=true ;\ echo "" ;\ for good in test/good*.xml; do \ echo "Testing: $$good ... " ;\ if ./test-skeleton < $$good > /dev/null; then echo "... passed"; else echo "... FAILED"; status=false; fi ;\ echo "" ;\ done ;\ for bad in test/bad*.xml; do \ echo "Testing: $$bad ... " ;\ if ./test-skeleton < $$bad > /dev/null; then echo "... FAILED"; status=false; else echo "... passed"; fi ;\ echo "" ;\ done ;\ if $$status; then echo "Success: all tests passed"; else echo "Warning: Some tests FAILED"; fi ;\ $$status test-skeleton$(.EXE) : test-skeleton.o ../xmlparse.o $(LD) $^ -o $@ $(LDFLAGS) test-skeleton.c : test/test.xsd xsd-to-xmlparser$(.EXE) ./xsd-to-xmlparser < $< | sed -e 's/XMLPARSE_UNKNOWN_ATTR_WARN/XMLPARSE_UNKNOWN_ATTR_ERROR/' > $@ ######## install: ######## clean: rm -f *~ rm -f *.o rm -f $(EXE) rm -f $(E) test-skeleton$(.EXE) rm -f $(D) .deps/test-skeleton.d rm -f $(C) test-skeleton.c rm -fr .deps rm -f core rm -f *.gcda *.gcno *.gcov gmon.out ######## distclean: clean ######## include $(D) ######## .PHONY:: all test install clean distclean routino-3.0/src/xml/xsd-to-xmlparser.c 644 233 144 40276 12563633053 13246 0/*************************************** $Header: /home/amb/CVS/routino/src/xml/xsd-to-xmlparser.c,v 1.10 2010-04-23 18:41:20 amb Exp $ An XML parser for simplified XML Schema Definitions to create XML parser skeletons. Part of the Routino routing software. ******************/ /****************** This file Copyright 2010-2015 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #include #if !defined(_MSC_VER) #include #endif #include #include #include #include "xmlparse.h" /*+ A forward definition of the xmltagx +*/ typedef struct _xmltagx xmltagx; /*+ A structure to hold the extended definition of a tag. +*/ struct _xmltagx { char *name; /*+ The name of the tag. +*/ char *type; /*+ The type of the tag. +*/ int nattributes; /*+ The number of valid attributes for the tag. +*/ char *attributes[XMLPARSE_MAX_ATTRS]; /*+ The valid attributes for the tag. +*/ int nsubtagsx; /*+ The number of valid attributes for the tag. +*/ xmltagx *subtagsx[XMLPARSE_MAX_SUBTAGS]; /*+ The list of types for the subtags contained within this one. +*/ }; /* The local variables and functions */ int ntagsx=0; xmltagx **tagsx=NULL; char *currenttype=NULL; static char *safe(const char *name); /* The XML tag processing function prototypes */ static int xmlDeclaration_function(const char *_tag_,int _type_,const char *version,const char *encoding); static int schemaType_function(const char *_tag_,int _type_,const char *elementFormDefault,const char *xmlns_xsd); static int elementType_function(const char *_tag_,int _type_,const char *name,const char *type,const char *minOccurs,const char *maxOccurs); static int complexType_function(const char *_tag_,int _type_,const char *name); static int sequenceType_function(const char *_tag_,int _type_); static int attributeType_function(const char *_tag_,int _type_,const char *name,const char *type); /* The XML tag definitions (forward declarations) */ static const xmltag xmlDeclaration_tag; static const xmltag schemaType_tag; static const xmltag elementType_tag; static const xmltag complexType_tag; static const xmltag sequenceType_tag; static const xmltag attributeType_tag; /* The XML tag definition values */ /*+ The complete set of tags at the top level. +*/ static const xmltag * const xml_toplevel_tags[]={&xmlDeclaration_tag,&schemaType_tag,NULL}; /*+ The xmlDeclaration type tag. +*/ static const xmltag xmlDeclaration_tag= {"xml", 2, {"version","encoding"}, xmlDeclaration_function, {NULL}}; /*+ The schemaType type tag. +*/ static const xmltag schemaType_tag= {"xsd:schema", 2, {"elementFormDefault","xmlns:xsd"}, schemaType_function, {&elementType_tag,&complexType_tag,NULL}}; /*+ The elementType type tag. +*/ static const xmltag elementType_tag= {"xsd:element", 4, {"name","type","minOccurs","maxOccurs"}, elementType_function, {NULL}}; /*+ The complexType type tag. +*/ static const xmltag complexType_tag= {"xsd:complexType", 1, {"name"}, complexType_function, {&sequenceType_tag,&attributeType_tag,NULL}}; /*+ The sequenceType type tag. +*/ static const xmltag sequenceType_tag= {"xsd:sequence", 0, {NULL}, sequenceType_function, {&elementType_tag,NULL}}; /*+ The attributeType type tag. +*/ static const xmltag attributeType_tag= {"xsd:attribute", 2, {"name","type"}, attributeType_function, {NULL}}; /* The XML tag processing functions */ /*++++++++++++++++++++++++++++++++++++++ The function that is called when the XML declaration is seen int xmlDeclaration_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *version The contents of the 'version' attribute (or NULL if not defined). const char *encoding The contents of the 'encoding' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int xmlDeclaration_function(const char *_tag_,int _type_,const char *version,const char *encoding) { /* Add the XML declaration as a tag. */ currenttype=NULL; elementType_function("xsd:element",XMLPARSE_TAG_START|XMLPARSE_TAG_END,"xml","xmlDeclaration",NULL,NULL); complexType_function("xsd:complexType",XMLPARSE_TAG_START,"xmlDeclaration"); attributeType_function("xsd:attribute",XMLPARSE_TAG_START|XMLPARSE_TAG_END,"version",NULL); attributeType_function("xsd:attribute",XMLPARSE_TAG_START|XMLPARSE_TAG_END,"encoding",NULL); complexType_function("xsd:complexType",XMLPARSE_TAG_END,NULL); currenttype=NULL; return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the schemaType XSD type is seen int schemaType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *elementFormDefault The contents of the 'elementFormDefault' attribute (or NULL if not defined). const char *xmlns_xsd The contents of the 'xmlns:xsd' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int schemaType_function(const char *_tag_,int _type_,const char *elementFormDefault,const char *xmlns_xsd) { return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the elementType XSD type is seen int elementType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *name The contents of the 'name' attribute (or NULL if not defined). const char *type The contents of the 'type' attribute (or NULL if not defined). const char *minOccurs The contents of the 'minOccurs' attribute (or NULL if not defined). const char *maxOccurs The contents of the 'maxOccurs' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int elementType_function(const char *_tag_,int _type_,const char *name,const char *type,const char *minOccurs,const char *maxOccurs) { xmltagx *tagx=NULL; int i; if(_type_==XMLPARSE_TAG_END) return(0); for(i=0;itype) && !strcmp(name,tagsx[i]->name)) tagx=tagsx[i]; if(!tagx) { ntagsx++; tagsx=(xmltagx**)realloc((void*)tagsx,ntagsx*sizeof(xmltagx*)); tagsx[ntagsx-1]=(xmltagx*)calloc(1,sizeof(xmltagx)); tagsx[ntagsx-1]->name=strcpy(malloc(strlen(name)+1),name); tagsx[ntagsx-1]->type=strcpy(malloc(strlen(type)+1),type); tagx=tagsx[ntagsx-1]; } if(!currenttype) return(0); for(i=0;itype,currenttype)) { tagsx[i]->subtagsx[tagsx[i]->nsubtagsx]=tagx; tagsx[i]->nsubtagsx++; if(tagsx[i]->nsubtagsx==XMLPARSE_MAX_SUBTAGS) {fprintf(stderr,"Too many subtags seen for type '%s'.\n",currenttype); exit(1);} } return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the complexType XSD type is seen int complexType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *name The contents of the 'name' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int complexType_function(const char *_tag_,int _type_,const char *name) { if(_type_==XMLPARSE_TAG_END) return(0); currenttype=strcpy(realloc(currenttype,strlen(name)+1),name); return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the sequenceType XSD type is seen int sequenceType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. ++++++++++++++++++++++++++++++++++++++*/ static int sequenceType_function(const char *_tag_,int _type_) { return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the attributeType XSD type is seen int attributeType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *name The contents of the 'name' attribute (or NULL if not defined). const char *type The contents of the 'type' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int attributeType_function(const char *_tag_,int _type_,const char *name,const char *type) { int i; if(_type_==XMLPARSE_TAG_END) return(0); for(i=0;itype,currenttype)) { tagsx[i]->attributes[tagsx[i]->nattributes]=strcpy(malloc(strlen(name)+1),name); tagsx[i]->nattributes++; if(tagsx[i]->nattributes==XMLPARSE_MAX_ATTRS) {fprintf(stderr,"Too many attributes seen for type '%s'.\n",currenttype); exit(1);} } return(0); } /*++++++++++++++++++++++++++++++++++++++ The XML Schema Definition XML parser and C program generator. ++++++++++++++++++++++++++++++++++++++*/ int main(int argc,char **argv) { int i,j; /* Parse the XSD file */ if(ParseXML(STDIN_FILENO,xml_toplevel_tags,XMLPARSE_UNKNOWN_ATTR_IGNORE)) { fprintf(stderr,"Cannot parse XML file - exiting.\n"); exit(1); } /* Print the header */ printf("/***************************************\n"); printf(" An automatically generated skeleton XML parser.\n"); printf("\n"); printf(" Automatically generated by xsd-to-xmlparser.\n"); printf(" ***************************************/\n"); printf("\n"); printf("\n"); printf("#include \n"); printf("#if !defined(_MSC_VER)\n"); printf("#include \n"); printf("#endif\n"); printf("\n"); printf("#include \"xmlparse.h\"\n"); /* Print the function prototypes */ printf("\n"); printf("\n"); printf("/* The XML tag processing function prototypes */\n"); printf("\n"); for(i=0;itype)); for(j=0;jnattributes;j++) printf(",const char *%s",safe(tagsx[i]->attributes[j])); printf(");\n"); } /* Print the xmltag variables */ printf("\n"); printf("\n"); printf("/* The XML tag definitions (forward declarations) */\n"); printf("\n"); for(i=0;itype)); printf("\n"); printf("\n"); printf("/* The XML tag definition values */\n"); printf("\n"); printf("/*+ The complete set of tags at the top level. +*/\n"); printf("static const xmltag * const xml_toplevel_tags[]={"); printf("&%s_tag,",safe(tagsx[0]->type)); printf("&%s_tag,",safe(tagsx[1]->type)); printf("NULL};\n"); for(i=0;itype); printf("static const xmltag %s_tag=\n",safe(tagsx[i]->type)); printf(" {\"%s\",\n",tagsx[i]->name); printf(" %d, {",tagsx[i]->nattributes); for(j=0;jnattributes;j++) printf("%s\"%s\"",(j?",":""),tagsx[i]->attributes[j]); printf("%s},\n",(tagsx[i]->nattributes?"":"NULL")); printf(" %s_function,\n",safe(tagsx[i]->type)); printf(" {"); for(j=0;jnsubtagsx;j++) printf("&%s_tag,",safe(tagsx[i]->subtagsx[j]->type)); printf("NULL}};\n"); } /* Print the functions */ printf("\n"); printf("\n"); printf("/* The XML tag processing functions */\n"); for(i=0;itype); printf("\n"); printf(" int %s_function Returns 0 if no error occured or something else otherwise.\n",safe(tagsx[i]->type)); printf("\n"); printf(" const char *_tag_ Set to the name of the element tag that triggered this function call.\n"); printf("\n"); printf(" int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag.\n"); for(j=0;jnattributes;j++) { printf("\n"); printf(" const char *%s The contents of the '%s' attribute (or NULL if not defined).\n",safe(tagsx[i]->attributes[j]),tagsx[i]->attributes[j]); } printf(" ++++++++++++++++++++++++++++++++++++++*/\n"); printf("\n"); printf("static int %s_function(const char *_tag_,int _type_",safe(tagsx[i]->type)); for(j=0;jnattributes;j++) printf(",const char *%s",safe(tagsx[i]->attributes[j])); printf(")\n"); printf("{\n"); if(i==(ntagsx-1)) /* XML tag */ { printf(" printf(\"nattributes;j++) { char *safename=safe(tagsx[i]->attributes[j]); printf(" if(%s) printf(\" %s=\\\"%%s\\\"\",ParseXML_Encode_Safe_XML(%s));\n",safename,tagsx[i]->attributes[j],safename); } printf(" printf(\" ?>\\n\");\n"); } else { printf(" printf(\"<%%s%%s\",(_type_==XMLPARSE_TAG_END)?\"/\":\"\",_tag_);\n"); for(j=0;jnattributes;j++) { char *safename=safe(tagsx[i]->attributes[j]); printf(" if(%s) printf(\" %s=\\\"%%s\\\"\",ParseXML_Encode_Safe_XML(%s));\n",safename,tagsx[i]->attributes[j],safename); } printf(" printf(\"%%s>\\n\",(_type_==(XMLPARSE_TAG_START|XMLPARSE_TAG_END))?\" /\":\"\");\n"); } printf(" return(0);\n"); printf("}\n"); } /* Print the main function */ printf("\n"); printf("\n"); printf("/*++++++++++++++++++++++++++++++++++++++\n"); printf(" A skeleton XML parser.\n"); printf(" ++++++++++++++++++++++++++++++++++++++*/\n"); printf("\n"); printf("int main(int argc,char **argv)\n"); printf("{\n"); printf(" if(ParseXML(STDIN_FILENO,xml_toplevel_tags,XMLPARSE_UNKNOWN_ATTR_WARN))\n"); printf(" return(1);\n"); printf(" else\n"); printf(" return(0);\n"); printf("}\n"); return(0); } /*++++++++++++++++++++++++++++++++++++++ A function to return a safe C identifier from an XML tag or attribute name. char *safe Returns the safe name in a private string (only use once). const char *name The name to convert. ++++++++++++++++++++++++++++++++++++++*/ static char *safe(const char *name) { static char *safe=NULL; /* static allocation of return value */ int i; safe=realloc(safe,strlen(name)+1); for(i=0;name[i];i++) if(isalnum(name[i])) safe[i]=name[i]; else safe[i]='_'; safe[i]=0; return(safe); } routino-3.0/src/visualiser.c 644 233 144 76764 12563633052 11415 0/*************************************** Extract data from Routino. Part of the Routino routing software. ******************/ /****************** This file Copyright 2008-2015 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #include #include #include #include "types.h" #include "nodes.h" #include "segments.h" #include "ways.h" #include "relations.h" #include "errorlog.h" #include "typesx.h" #include "visualiser.h" /* Limit types */ #define SPEED_LIMIT 1 #define WEIGHT_LIMIT 2 #define HEIGHT_LIMIT 3 #define WIDTH_LIMIT 4 #define LENGTH_LIMIT 5 /* Local types */ typedef void (*callback_t)(index_t node,double latitude,double longitude); /* Local variables (intialised by entry-point function before later use) */ static Nodes *OSMNodes; static Segments *OSMSegments; static Ways *OSMWays; static Relations *OSMRelations; static double LatMin; static double LatMax; static double LonMin; static double LonMax; static int limit_type=0; static Highway highways=Highway_None; static Transports transports=Transports_None; static Properties properties=Properties_None; static highway_t waytype=0; /* Local functions */ static void find_all_nodes(Nodes *nodes,callback_t callback); static void output_junctions(index_t node,double latitude,double longitude); static void output_super(index_t node,double latitude,double longitude); static void output_waytype(index_t node,double latitude,double longitude); static void output_highway(index_t node,double latitude,double longitude); static void output_transport(index_t node,double latitude,double longitude); static void output_barrier(index_t node,double latitude,double longitude); static void output_turnrestriction(index_t node,double latitude,double longitude); static void output_limits(index_t node,double latitude,double longitude); static void output_property(index_t node,double latitude,double longitude); /*++++++++++++++++++++++++++++++++++++++ Output the data for junctions (--data=junctions). Nodes *nodes The set of nodes to use. Segments *segments The set of segments to use. Ways *ways The set of ways to use. Relations *relations The set of relations to use. double latmin The minimum latitude. double latmax The maximum latitude. double lonmin The minimum longitude. double lonmax The maximum longitude. ++++++++++++++++++++++++++++++++++++++*/ void OutputJunctions(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,double latmin,double latmax,double lonmin,double lonmax) { /* Use local variables so that the callback doesn't need to pass them backwards and forwards */ OSMNodes=nodes; OSMSegments=segments; OSMWays=ways; OSMRelations=relations; LatMin=latmin; LatMax=latmax; LonMin=lonmin; LonMax=lonmax; /* Iterate through the nodes and process them */ find_all_nodes(nodes,(callback_t)output_junctions); } /*++++++++++++++++++++++++++++++++++++++ Process a single node and output all those that are junctions (called as a callback). index_t node The node to output. double latitude The latitude of the node. double longitude The longitude of the node. ++++++++++++++++++++++++++++++++++++++*/ static void output_junctions(index_t node,double latitude,double longitude) { Node *nodep=LookupNode(OSMNodes,node,1); Segment *segmentp; Way *firstwayp; int count=0,difference=0; segmentp=FirstSegment(OSMSegments,nodep,1); firstwayp=LookupWay(OSMWays,segmentp->way,1); do { Way *wayp=LookupWay(OSMWays,segmentp->way,2); if(IsNormalSegment(segmentp)) count++; if(WaysCompare(firstwayp,wayp)) difference=1; segmentp=NextSegment(OSMSegments,segmentp,node); } while(segmentp); if(count!=2 || difference) printf("node%"Pindex_t" %.6f %.6f %d\n",node,radians_to_degrees(latitude),radians_to_degrees(longitude),count); } /*++++++++++++++++++++++++++++++++++++++ Output the data for super-nodes and super-segments (--data=super). Nodes *nodes The set of nodes to use. Segments *segments The set of segments to use. Ways *ways The set of ways to use. Relations *relations The set of relations to use. double latmin The minimum latitude. double latmax The maximum latitude. double lonmin The minimum longitude. double lonmax The maximum longitude. ++++++++++++++++++++++++++++++++++++++*/ void OutputSuper(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,double latmin,double latmax,double lonmin,double lonmax) { /* Use local variables so that the callback doesn't need to pass them backwards and forwards */ OSMNodes=nodes; OSMSegments=segments; OSMWays=ways; OSMRelations=relations; LatMin=latmin; LatMax=latmax; LonMin=lonmin; LonMax=lonmax; /* Iterate through the nodes and process them */ find_all_nodes(nodes,(callback_t)output_super); } /*++++++++++++++++++++++++++++++++++++++ Process a single node and output all that are super-nodes and all connected super-segments (called as a callback). index_t node The node to output. double latitude The latitude of the node. double longitude The longitude of the node. ++++++++++++++++++++++++++++++++++++++*/ static void output_super(index_t node,double latitude,double longitude) { Node *nodep=LookupNode(OSMNodes,node,1); Segment *segmentp; if(!IsSuperNode(nodep)) return; printf("node%"Pindex_t" %.6f %.6f\n",node,radians_to_degrees(latitude),radians_to_degrees(longitude)); segmentp=FirstSegment(OSMSegments,nodep,1); do { if(IsSuperSegment(segmentp)) { index_t othernode=OtherNode(segmentp,node); double lat,lon; GetLatLong(OSMNodes,othernode,NULL,&lat,&lon); if(node>othernode || (latLatMax || lonLonMax)) printf("segment%"Pindex_t" %.6f %.6f\n",IndexSegment(OSMSegments,segmentp),radians_to_degrees(lat),radians_to_degrees(lon)); } segmentp=NextSegment(OSMSegments,segmentp,node); } while(segmentp); } /*++++++++++++++++++++++++++++++++++++++ Output the data for segments of special highway types (--data=waytype-oneway etc). Nodes *nodes The set of nodes to use. Segments *segments The set of segments to use. Ways *ways The set of ways to use. Relations *relations The set of relations to use. double latmin The minimum latitude. double latmax The maximum latitude. double lonmin The minimum longitude. double lonmax The maximum longitude. highway_t mask A bit mask that must match the highway type. ++++++++++++++++++++++++++++++++++++++*/ void OutputWaytype(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,double latmin,double latmax,double lonmin,double lonmax,highway_t mask) { /* Use local variables so that the callback doesn't need to pass them backwards and forwards */ OSMNodes=nodes; OSMSegments=segments; OSMWays=ways; OSMRelations=relations; LatMin=latmin; LatMax=latmax; LonMin=lonmin; LonMax=lonmax; /* Iterate through the nodes and process them */ waytype=mask; find_all_nodes(nodes,(callback_t)output_waytype); } /*++++++++++++++++++++++++++++++++++++++ Process a single node and output all connected segments of a particular special highway type (called as a callback). index_t node The node to output. double latitude The latitude of the node. double longitude The longitude of the node. ++++++++++++++++++++++++++++++++++++++*/ static void output_waytype(index_t node,double latitude,double longitude) { Node *nodep=LookupNode(OSMNodes,node,1); Segment *segmentp; segmentp=FirstSegment(OSMSegments,nodep,1); do { if(IsNormalSegment(segmentp)) { Way *wayp=LookupWay(OSMWays,segmentp->way,1); if(wayp->type&waytype) { index_t othernode=OtherNode(segmentp,node); double lat,lon; GetLatLong(OSMNodes,othernode,NULL,&lat,&lon); if(node>othernode || (latLatMax || lonLonMax)) { if(IsOnewayFrom(segmentp,node)) printf("segment%"Pindex_t" %.6f %.6f %.6f %.6f\n",IndexSegment(OSMSegments,segmentp),radians_to_degrees(latitude),radians_to_degrees(longitude),radians_to_degrees(lat),radians_to_degrees(lon)); else if(IsOnewayFrom(segmentp,othernode)) printf("segment%"Pindex_t" %.6f %.6f %.6f %.6f\n",IndexSegment(OSMSegments,segmentp),radians_to_degrees(lat),radians_to_degrees(lon),radians_to_degrees(latitude),radians_to_degrees(longitude)); } } } segmentp=NextSegment(OSMSegments,segmentp,node); } while(segmentp); } /*++++++++++++++++++++++++++++++++++++++ Output the data for segments of a particular highway type (--data=highway-primary etc). Nodes *nodes The set of nodes to use. Segments *segments The set of segments to use. Ways *ways The set of ways to use. Relations *relations The set of relations to use. double latmin The minimum latitude. double latmax The maximum latitude. double lonmin The minimum longitude. double lonmax The maximum longitude. Highway highway The type of highway. ++++++++++++++++++++++++++++++++++++++*/ void OutputHighway(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,double latmin,double latmax,double lonmin,double lonmax,Highway highway) { /* Use local variables so that the callback doesn't need to pass them backwards and forwards */ OSMNodes=nodes; OSMSegments=segments; OSMWays=ways; OSMRelations=relations; LatMin=latmin; LatMax=latmax; LonMin=lonmin; LonMax=lonmax; /* Iterate through the nodes and process them */ highways=highway; find_all_nodes(nodes,(callback_t)output_highway); } /*++++++++++++++++++++++++++++++++++++++ Process a single node and output all connected segments that are of a particular highway type (called as a callback). index_t node The node to output. double latitude The latitude of the node. double longitude The longitude of the node. ++++++++++++++++++++++++++++++++++++++*/ static void output_highway(index_t node,double latitude,double longitude) { Node *nodep=LookupNode(OSMNodes,node,1); Segment *segmentp; segmentp=FirstSegment(OSMSegments,nodep,1); do { if(IsNormalSegment(segmentp)) { Way *wayp=LookupWay(OSMWays,segmentp->way,1); if(HIGHWAY(wayp->type)==highways) { index_t othernode=OtherNode(segmentp,node); double lat,lon; GetLatLong(OSMNodes,othernode,NULL,&lat,&lon); if(node>othernode || (latLatMax || lonLonMax)) printf("segment%"Pindex_t" %.6f %.6f %.6f %.6f\n",IndexSegment(OSMSegments,segmentp),radians_to_degrees(latitude),radians_to_degrees(longitude),radians_to_degrees(lat),radians_to_degrees(lon)); } } segmentp=NextSegment(OSMSegments,segmentp,node); } while(segmentp); } /*++++++++++++++++++++++++++++++++++++++ Output the data for segments allowed for a particular type of traffic (--data=transport-motorcar etc). Nodes *nodes The set of nodes to use. Segments *segments The set of segments to use. Ways *ways The set of ways to use. Relations *relations The set of relations to use. double latmin The minimum latitude. double latmax The maximum latitude. double lonmin The minimum longitude. double lonmax The maximum longitude. Transport transport The type of transport. ++++++++++++++++++++++++++++++++++++++*/ void OutputTransport(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,double latmin,double latmax,double lonmin,double lonmax,Transport transport) { /* Use local variables so that the callback doesn't need to pass them backwards and forwards */ OSMNodes=nodes; OSMSegments=segments; OSMWays=ways; OSMRelations=relations; LatMin=latmin; LatMax=latmax; LonMin=lonmin; LonMax=lonmax; /* Iterate through the nodes and process them */ transports=TRANSPORTS(transport); find_all_nodes(nodes,(callback_t)output_transport); } /*++++++++++++++++++++++++++++++++++++++ Process a single node and output all connected segments for a particular traffic type (called as a callback). index_t node The node to output. double latitude The latitude of the node. double longitude The longitude of the node. ++++++++++++++++++++++++++++++++++++++*/ static void output_transport(index_t node,double latitude,double longitude) { Node *nodep=LookupNode(OSMNodes,node,1); Segment *segmentp; segmentp=FirstSegment(OSMSegments,nodep,1); do { if(IsNormalSegment(segmentp)) { Way *wayp=LookupWay(OSMWays,segmentp->way,1); if(wayp->allow&transports) { index_t othernode=OtherNode(segmentp,node); double lat,lon; GetLatLong(OSMNodes,othernode,NULL,&lat,&lon); if(node>othernode || (latLatMax || lonLonMax)) printf("segment%"Pindex_t" %.6f %.6f %.6f %.6f\n",IndexSegment(OSMSegments,segmentp),radians_to_degrees(latitude),radians_to_degrees(longitude),radians_to_degrees(lat),radians_to_degrees(lon)); } } segmentp=NextSegment(OSMSegments,segmentp,node); } while(segmentp); } /*++++++++++++++++++++++++++++++++++++++ Output the data for nodes disallowed for a particular type of traffic (--data=barrier). Nodes *nodes The set of nodes to use. Segments *segments The set of segments to use. Ways *ways The set of ways to use. Relations *relations The set of relations to use. double latmin The minimum latitude. double latmax The maximum latitude. double lonmin The minimum longitude. double lonmax The maximum longitude. Transport transport The type of transport. ++++++++++++++++++++++++++++++++++++++*/ void OutputBarrier(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,double latmin,double latmax,double lonmin,double lonmax,Transport transport) { /* Use local variables so that the callback doesn't need to pass them backwards and forwards */ OSMNodes=nodes; OSMSegments=segments; OSMWays=ways; OSMRelations=relations; LatMin=latmin; LatMax=latmax; LonMin=lonmin; LonMax=lonmax; /* Iterate through the nodes and process them */ transports=TRANSPORTS(transport); find_all_nodes(nodes,(callback_t)output_barrier); } /*++++++++++++++++++++++++++++++++++++++ Process a single node and output those that are barriers (called as a callback). index_t node The node to output. double latitude The latitude of the node. double longitude The longitude of the node. ++++++++++++++++++++++++++++++++++++++*/ static void output_barrier(index_t node,double latitude,double longitude) { Node *nodep=LookupNode(OSMNodes,node,1); if(!(nodep->allow&transports)) printf("node%"Pindex_t" %.6f %.6f\n",node,radians_to_degrees(latitude),radians_to_degrees(longitude)); } /*++++++++++++++++++++++++++++++++++++++ Output the data for turn restrictions (--data=turns). Nodes *nodes The set of nodes to use. Segments *segments The set of segments to use. Ways *ways The set of ways to use. Relations *relations The set of relations to use. double latmin The minimum latitude. double latmax The maximum latitude. double lonmin The minimum longitude. double lonmax The maximum longitude. ++++++++++++++++++++++++++++++++++++++*/ void OutputTurnRestrictions(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,double latmin,double latmax,double lonmin,double lonmax) { /* Use local variables so that the callback doesn't need to pass them backwards and forwards */ OSMNodes=nodes; OSMSegments=segments; OSMWays=ways; OSMRelations=relations; LatMin=latmin; LatMax=latmax; LonMin=lonmin; LonMax=lonmax; /* Iterate through the nodes and process them */ find_all_nodes(nodes,(callback_t)output_turnrestriction); } /*++++++++++++++++++++++++++++++++++++++ Process a single node and output those that are 'via' nodes for a turn restriction and the associated segments (called as a callback). index_t node The node to output. double latitude The latitude of the node. double longitude The longitude of the node. ++++++++++++++++++++++++++++++++++++++*/ static void output_turnrestriction(index_t node,double latitude,double longitude) { Node *nodep=LookupNode(OSMNodes,node,1); index_t turnrelation=NO_RELATION; if(!IsTurnRestrictedNode(nodep)) return; turnrelation=FindFirstTurnRelation1(OSMRelations,node); do { TurnRelation *relation; Segment *from_segmentp,*to_segmentp; index_t from_node,to_node; double from_lat,from_lon,to_lat,to_lon; relation=LookupTurnRelation(OSMRelations,turnrelation,1); from_segmentp=LookupSegment(OSMSegments,relation->from,1); to_segmentp =LookupSegment(OSMSegments,relation->to ,2); from_node=OtherNode(from_segmentp,node); to_node =OtherNode(to_segmentp ,node); GetLatLong(OSMNodes,from_node,NULL,&from_lat,&from_lon); GetLatLong(OSMNodes,to_node ,NULL,&to_lat ,&to_lon); printf("turn-relation%"Pindex_t" %.6f %.6f %.6f %.6f %.6f %.6f\n", turnrelation, radians_to_degrees(from_lat),radians_to_degrees(from_lon), radians_to_degrees(latitude),radians_to_degrees(longitude), radians_to_degrees(to_lat),radians_to_degrees(to_lon)); turnrelation=FindNextTurnRelation1(OSMRelations,turnrelation); } while(turnrelation!=NO_RELATION); } /*++++++++++++++++++++++++++++++++++++++ Output the data for speed limits (--data=speed). Nodes *nodes The set of nodes to use. Segments *segments The set of segments to use. Ways *ways The set of ways to use. Relations *relations The set of relations to use. double latmin The minimum latitude. double latmax The maximum latitude. double lonmin The minimum longitude. double lonmax The maximum longitude. ++++++++++++++++++++++++++++++++++++++*/ void OutputSpeedLimits(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,double latmin,double latmax,double lonmin,double lonmax) { /* Use local variables so that the callback doesn't need to pass them backwards and forwards */ OSMNodes=nodes; OSMSegments=segments; OSMWays=ways; OSMRelations=relations; LatMin=latmin; LatMax=latmax; LonMin=lonmin; LonMax=lonmax; /* Iterate through the nodes and process them */ limit_type=SPEED_LIMIT; find_all_nodes(nodes,(callback_t)output_limits); } /*++++++++++++++++++++++++++++++++++++++ Output the data for weight limits (--data=weight). Nodes *nodes The set of nodes to use. Segments *segments The set of segments to use. Ways *ways The set of ways to use. Relations *relations The set of relations to use. double latmin The minimum latitude. double latmax The maximum latitude. double lonmin The minimum longitude. double lonmax The maximum longitude. ++++++++++++++++++++++++++++++++++++++*/ void OutputWeightLimits(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,double latmin,double latmax,double lonmin,double lonmax) { /* Use local variables so that the callback doesn't need to pass them backwards and forwards */ OSMNodes=nodes; OSMSegments=segments; OSMWays=ways; OSMRelations=relations; LatMin=latmin; LatMax=latmax; LonMin=lonmin; LonMax=lonmax; /* Iterate through the nodes and process them */ limit_type=WEIGHT_LIMIT; find_all_nodes(nodes,(callback_t)output_limits); } /*++++++++++++++++++++++++++++++++++++++ Output the data for height limits (--data=height). Nodes *nodes The set of nodes to use. Segments *segments The set of segments to use. Ways *ways The set of ways to use. Relations *relations The set of relations to use. double latmin The minimum latitude. double latmax The maximum latitude. double lonmin The minimum longitude. double lonmax The maximum longitude. ++++++++++++++++++++++++++++++++++++++*/ void OutputHeightLimits(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,double latmin,double latmax,double lonmin,double lonmax) { /* Use local variables so that the callback doesn't need to pass them backwards and forwards */ OSMNodes=nodes; OSMSegments=segments; OSMWays=ways; OSMRelations=relations; LatMin=latmin; LatMax=latmax; LonMin=lonmin; LonMax=lonmax; /* Iterate through the nodes and process them */ limit_type=HEIGHT_LIMIT; find_all_nodes(nodes,(callback_t)output_limits); } /*++++++++++++++++++++++++++++++++++++++ Output the data for width limits (--data=width). Nodes *nodes The set of nodes to use. Segments *segments The set of segments to use. Ways *ways The set of ways to use. Relations *relations The set of relations to use. double latmin The minimum latitude. double latmax The maximum latitude. double lonmin The minimum longitude. double lonmax The maximum longitude. ++++++++++++++++++++++++++++++++++++++*/ void OutputWidthLimits(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,double latmin,double latmax,double lonmin,double lonmax) { /* Use local variables so that the callback doesn't need to pass them backwards and forwards */ OSMNodes=nodes; OSMSegments=segments; OSMWays=ways; OSMRelations=relations; LatMin=latmin; LatMax=latmax; LonMin=lonmin; LonMax=lonmax; /* Iterate through the nodes and process them */ limit_type=WIDTH_LIMIT; find_all_nodes(nodes,(callback_t)output_limits); } /*++++++++++++++++++++++++++++++++++++++ Output the data for length limits (--data=length). Nodes *nodes The set of nodes to use. Segments *segments The set of segments to use. Ways *ways The set of ways to use. Relations *relations The set of relations to use. double latmin The minimum latitude. double latmax The maximum latitude. double lonmin The minimum longitude. double lonmax The maximum longitude. ++++++++++++++++++++++++++++++++++++++*/ void OutputLengthLimits(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,double latmin,double latmax,double lonmin,double lonmax) { /* Use local variables so that the callback doesn't need to pass them backwards and forwards */ OSMNodes=nodes; OSMSegments=segments; OSMWays=ways; OSMRelations=relations; LatMin=latmin; LatMax=latmax; LonMin=lonmin; LonMax=lonmax; /* Iterate through the nodes and process them */ limit_type=LENGTH_LIMIT; find_all_nodes(nodes,(callback_t)output_limits); } /*++++++++++++++++++++++++++++++++++++++ Process a single node and output those and connected segments that have a speed, weight, height, width or length limit change (called as a callback). index_t node The node to output. double latitude The latitude of the node. double longitude The longitude of the node. ++++++++++++++++++++++++++++++++++++++*/ static void output_limits(index_t node,double latitude,double longitude) { Node *nodep=LookupNode(OSMNodes,node,1); Segment *segmentp,segmentps[MAX_SEG_PER_NODE]; index_t segments[MAX_SEG_PER_NODE]; int limits[MAX_SEG_PER_NODE]; int count=0; int i,j,same=0; segmentp=FirstSegment(OSMSegments,nodep,1); do { if(IsNormalSegment(segmentp) && countway,1); segmentps[count]=*segmentp; segments [count]=IndexSegment(OSMSegments,segmentp); switch(limit_type) { case SPEED_LIMIT: limits[count]=wayp->speed; break; case WEIGHT_LIMIT: limits[count]=wayp->weight; break; case HEIGHT_LIMIT: limits[count]=wayp->height; break; case WIDTH_LIMIT: limits[count]=wayp->width; break; case LENGTH_LIMIT: limits[count]=wayp->length; break; } if(limits[count] || HIGHWAY(wayp->type)way,1); if(wayp->props&properties) { index_t othernode=OtherNode(segmentp,node); double lat,lon; GetLatLong(OSMNodes,othernode,NULL,&lat,&lon); if(node>othernode || (latLatMax || lonLonMax)) printf("segment%"Pindex_t" %.6f %.6f %.6f %.6f\n",IndexSegment(OSMSegments,segmentp),radians_to_degrees(latitude),radians_to_degrees(longitude),radians_to_degrees(lat),radians_to_degrees(lon)); } } segmentp=NextSegment(OSMSegments,segmentp,node); } while(segmentp); } /*++++++++++++++++++++++++++++++++++++++ A function to iterate through all nodes and call a callback function for each one. Nodes *nodes The set of nodes to use. callback_t callback The callback function for each node. ++++++++++++++++++++++++++++++++++++++*/ static void find_all_nodes(Nodes *nodes,callback_t callback) { ll_bin_t latminbin=latlong_to_bin(radians_to_latlong(LatMin))-nodes->file.latzero; ll_bin_t latmaxbin=latlong_to_bin(radians_to_latlong(LatMax))-nodes->file.latzero; ll_bin_t lonminbin=latlong_to_bin(radians_to_latlong(LonMin))-nodes->file.lonzero; ll_bin_t lonmaxbin=latlong_to_bin(radians_to_latlong(LonMax))-nodes->file.lonzero; ll_bin_t latb,lonb; index_t i,index1,index2; /* Loop through all of the nodes. */ if(latminbin<0) latminbin=0; if(latmaxbin>nodes->file.latbins) latmaxbin=nodes->file.latbins-1; if(lonminbin<0) lonminbin=0; if(lonmaxbin>nodes->file.lonbins) lonmaxbin=nodes->file.lonbins-1; for(latb=latminbin;latb<=latmaxbin;latb++) for(lonb=lonminbin;lonb<=lonmaxbin;lonb++) { ll_bin2_t llbin=lonb*nodes->file.latbins+latb; if(llbin<0 || llbin>(nodes->file.latbins*nodes->file.lonbins)) continue; index1=LookupNodeOffset(nodes,llbin); index2=LookupNodeOffset(nodes,llbin+1); for(i=index1;ifile.latzero+latb)+off_to_latlong(nodep->latoffset)); double lon=latlong_to_radians(bin_to_latlong(nodes->file.lonzero+lonb)+off_to_latlong(nodep->lonoffset)); if(lat>LatMin && latLonMin && lonfile.latzero; ll_bin_t latmaxbin=latlong_to_bin(radians_to_latlong(latmax))-errorlogs->file.latzero; ll_bin_t lonminbin=latlong_to_bin(radians_to_latlong(lonmin))-errorlogs->file.lonzero; ll_bin_t lonmaxbin=latlong_to_bin(radians_to_latlong(lonmax))-errorlogs->file.lonzero; ll_bin_t latb,lonb; index_t i,index1,index2; /* Loop through all of the error logs. */ for(latb=latminbin;latb<=latmaxbin;latb++) for(lonb=lonminbin;lonb<=lonmaxbin;lonb++) { ll_bin2_t llbin=lonb*errorlogs->file.latbins+latb; if(llbin<0 || llbin>(errorlogs->file.latbins*errorlogs->file.lonbins)) continue; index1=LookupErrorLogOffset(errorlogs,llbin); index2=LookupErrorLogOffset(errorlogs,llbin+1); if(index2>errorlogs->file.number_geo) index2=errorlogs->file.number_geo; for(i=index1;ifile.latzero+latb)+off_to_latlong(errorlogp->latoffset)); double lon=latlong_to_radians(bin_to_latlong(errorlogs->file.lonzero+lonb)+off_to_latlong(errorlogp->lonoffset)); if(lat>latmin && latlonmin && lon. ***************************************/ #ifndef PRUNEX_H #define PRUNEX_H /*+ To stop multiple inclusions. +*/ #include "types.h" #include "typesx.h" /* Functions in prunex.c */ void StartPruning(NodesX *nodesx,SegmentsX *segmentsx,WaysX *waysx); void FinishPruning(NodesX *nodesx,SegmentsX *segmentsx,WaysX *waysx); void PruneIsolatedRegions(NodesX *nodesx,SegmentsX *segmentsx,WaysX *waysx,distance_t minimum); void PruneShortSegments(NodesX *nodesx,SegmentsX *segmentsx,WaysX *waysx,distance_t minimum); void PruneStraightHighwayNodes(NodesX *nodesx,SegmentsX *segmentsx,WaysX *waysx,distance_t maximum); #endif /* PRUNEX_H */ routino-3.0/src/files.c 644 233 144 57621 12563634053 10322 0/*************************************** Functions to handle files. Part of the Routino routing software. ******************/ /****************** This file Copyright 2008-2015 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #if defined(_MSC_VER) #include #include #define read(fd,address,length) _read(fd,address,(unsigned int)(length)) #define write(fd,address,length) _write(fd,address,(unsigned int)(length)) #define open _open #define close _close #define unlink _unlink #define ssize_t SSIZE_T #else #include #endif #include #include #include #include #include #include #if defined(_MSC_VER) || defined(__MINGW32__) #undef lseek #undef stat #undef fstat #define lseek _lseeki64 #define stat _stati64 #define fstat _fstati64 #endif #if defined(_MSC_VER) || defined(__MINGW32__) #include "mman-win32.h" #else #include #endif #include #include "files.h" /*+ A structure to contain the list of memory mapped files. +*/ struct mmapinfo { const char *filename; /*+ The name of the file (the index of the list). +*/ int fd; /*+ The file descriptor used when it was opened. +*/ char *address; /*+ The address the file was mapped to. +*/ size_t length; /*+ The length of the file. +*/ }; /*+ The list of memory mapped files. +*/ static struct mmapinfo *mappedfiles; /*+ The number of mapped files. +*/ static int nmappedfiles=0; #define BUFFLEN 4096 /*+ A structure to contain the list of file buffers. +*/ struct filebuffer { char buffer[BUFFLEN]; /*+ The data buffer. +*/ size_t pointer; /*+ The read/write pointer for the file buffer. +*/ size_t length; /*+ The read pointer for the file buffer. +*/ int reading; /*+ A flag to indicate if the file is for reading. +*/ }; /*+ The list of file buffers. +*/ static struct filebuffer **filebuffers=NULL; /*+ The number of allocated file buffer pointers. +*/ static int nfilebuffers=0; #if defined(_MSC_VER) || defined(__MINGW32__) /*+ A structure to contain the list of opened files to record which are to be deleted when closed. +*/ struct openedfile { const char *filename; /*+ The name of the file. +*/ int delete; /*+ Set to non-zero value if the file is to be deleted when closed. +*/ }; /*+ The list of opened files. +*/ static struct openedfile **openedfiles=NULL; /*+ The number of allocated opened file buffer pointers. +*/ static int nopenedfiles=0; #endif /* Local functions */ static void CreateFileBuffer(int fd,int read_write); #if defined(_MSC_VER) || defined(__MINGW32__) static void CreateOpenedFile(int fd,const char *filename); #endif /*++++++++++++++++++++++++++++++++++++++ Return a filename composed of the dirname, prefix and name. char *FileName Returns a pointer to memory allocated to the filename. const char *dirname The directory name. const char *prefix The file prefix. const char *name The main part of the name. ++++++++++++++++++++++++++++++++++++++*/ char *FileName(const char *dirname,const char *prefix, const char *name) { char *filename=(char*)malloc((dirname?strlen(dirname):0)+1+(prefix?strlen(prefix):0)+1+strlen(name)+1); sprintf(filename,"%s%s%s%s%s",dirname?dirname:"",dirname?"/":"",prefix?prefix:"",prefix?"-":"",name); return(filename); } /*++++++++++++++++++++++++++++++++++++++ Open a file read-only and map it into memory. void *MapFile Returns the address of the file or exits in case of an error. const char *filename The name of the file to open. ++++++++++++++++++++++++++++++++++++++*/ void *MapFile(const char *filename) { int fd; struct stat buf; offset_t size; void *address; /* Open the file */ #if defined(_MSC_VER) || defined(__MINGW32__) fd=open(filename,O_RDONLY|O_BINARY|O_RANDOM); #else fd=open(filename,O_RDONLY); #endif if(fd<0) { #ifdef LIBROUTINO return(NULL); #else fprintf(stderr,"Cannot open file '%s' for reading [%s].\n",filename,strerror(errno)); exit(EXIT_FAILURE); #endif } /* Get its size */ if(stat(filename,&buf)) { #ifdef LIBROUTINO return(NULL); #else fprintf(stderr,"Cannot stat file '%s' [%s].\n",filename,strerror(errno)); exit(EXIT_FAILURE); #endif } size=buf.st_size; /* Map the file */ address=mmap(NULL,size,PROT_READ,MAP_SHARED,fd,0); if(address==MAP_FAILED) { close(fd); #ifdef LIBROUTINO return(NULL); #else fprintf(stderr,"Cannot mmap file '%s' for reading [%s].\n",filename,strerror(errno)); exit(EXIT_FAILURE); #endif } #ifndef LIBROUTINO log_mmap(size); #endif /* Store the information about the mapped file */ mappedfiles=(struct mmapinfo*)realloc((void*)mappedfiles,(nmappedfiles+1)*sizeof(struct mmapinfo)); mappedfiles[nmappedfiles].filename=filename; mappedfiles[nmappedfiles].fd=fd; mappedfiles[nmappedfiles].address=address; mappedfiles[nmappedfiles].length=size; nmappedfiles++; return(address); } /*++++++++++++++++++++++++++++++++++++++ Open a file read-write and map it into memory. void *MapFileWriteable Returns the address of the file or exits in case of an error. const char *filename The name of the file to open. ++++++++++++++++++++++++++++++++++++++*/ void *MapFileWriteable(const char *filename) { int fd; struct stat buf; offset_t size; void *address; /* Open the file */ #if defined(_MSC_VER) || defined(__MINGW32__) fd=open(filename,O_RDWR|O_BINARY|O_RANDOM); #else fd=open(filename,O_RDWR); #endif if(fd<0) { #ifdef LIBROUTINO return(NULL); #else fprintf(stderr,"Cannot open file '%s' for reading and writing [%s].\n",filename,strerror(errno)); exit(EXIT_FAILURE); #endif } /* Get its size */ if(stat(filename,&buf)) { #ifdef LIBROUTINO return(NULL); #else fprintf(stderr,"Cannot stat file '%s' [%s].\n",filename,strerror(errno)); exit(EXIT_FAILURE); #endif } size=buf.st_size; /* Map the file */ address=mmap(NULL,size,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0); if(address==MAP_FAILED) { close(fd); #ifdef LIBROUTINO return(NULL); #else fprintf(stderr,"Cannot mmap file '%s' for reading and writing [%s].\n",filename,strerror(errno)); exit(EXIT_FAILURE); #endif } #ifndef LIBROUTINO log_mmap(size); #endif /* Store the information about the mapped file */ mappedfiles=(struct mmapinfo*)realloc((void*)mappedfiles,(nmappedfiles+1)*sizeof(struct mmapinfo)); mappedfiles[nmappedfiles].filename=filename; mappedfiles[nmappedfiles].fd=fd; mappedfiles[nmappedfiles].address=address; mappedfiles[nmappedfiles].length=size; nmappedfiles++; return(address); } /*++++++++++++++++++++++++++++++++++++++ Unmap a file and close it. void *UnmapFile Returns NULL (for similarity to the MapFile function). const void *address The address of the mapped file in memory. ++++++++++++++++++++++++++++++++++++++*/ void *UnmapFile(const void *address) { int i; for(i=0;ii) memmove(&mappedfiles[i],&mappedfiles[i+1],(nmappedfiles-i)*sizeof(struct mmapinfo)); return(NULL); } /*++++++++++++++++++++++++++++++++++++++ Open an existing file on disk for reading. int SlimMapFile Returns the file descriptor if OK or exits in case of an error. const char *filename The name of the file to open. ++++++++++++++++++++++++++++++++++++++*/ int SlimMapFile(const char *filename) { int fd; /* Open the file */ #if defined(_MSC_VER) || defined(__MINGW32__) fd=open(filename,O_RDONLY|O_BINARY|O_RANDOM); #else fd=open(filename,O_RDONLY); #endif if(fd<0) { #ifdef LIBROUTINO return(-1); #else fprintf(stderr,"Cannot open file '%s' for reading [%s].\n",filename,strerror(errno)); exit(EXIT_FAILURE); #endif } CreateFileBuffer(fd,0); return(fd); } /*++++++++++++++++++++++++++++++++++++++ Open an existing file on disk for reading or writing. int SlimMapFileWriteable Returns the file descriptor if OK or exits in case of an error. const char *filename The name of the file to open. ++++++++++++++++++++++++++++++++++++++*/ int SlimMapFileWriteable(const char *filename) { int fd; /* Open the file */ #if defined(_MSC_VER) || defined(__MINGW32__) fd=open(filename,O_RDWR|O_BINARY|O_RANDOM); #else fd=open(filename,O_RDWR); #endif if(fd<0) { #ifdef LIBROUTINO return(-1); #else fprintf(stderr,"Cannot open file '%s' for reading and writing [%s].\n",filename,strerror(errno)); exit(EXIT_FAILURE); #endif } CreateFileBuffer(fd,0); return(fd); } /*++++++++++++++++++++++++++++++++++++++ Close a file on disk. int SlimUnmapFile returns -1 (for similarity to the UnmapFile function). int fd The file descriptor to close. ++++++++++++++++++++++++++++++++++++++*/ int SlimUnmapFile(int fd) { close(fd); return(-1); } /*++++++++++++++++++++++++++++++++++++++ Open a new file on disk for writing (with buffering). int OpenFileBufferedNew Returns the file descriptor if OK or exits in case of an error. const char *filename The name of the file to create. ++++++++++++++++++++++++++++++++++++++*/ int OpenFileBufferedNew(const char *filename) { int fd; /* Open the file */ #if defined(_MSC_VER) || defined(__MINGW32__) fd=open(filename,O_WRONLY|O_CREAT|O_TRUNC|O_BINARY|O_RANDOM,S_IREAD|S_IWRITE); #else fd=open(filename,O_WRONLY|O_CREAT|O_TRUNC ,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); #endif if(fd<0) { #ifdef LIBROUTINO return(-1); #else fprintf(stderr,"Cannot open file '%s' for writing [%s].\n",filename,strerror(errno)); exit(EXIT_FAILURE); #endif } CreateFileBuffer(fd,-1); #if defined(_MSC_VER) || defined(__MINGW32__) CreateOpenedFile(fd,filename); #endif return(fd); } /*++++++++++++++++++++++++++++++++++++++ Open a new or existing file on disk for appending (with buffering). int OpenFileBufferedAppend Returns the file descriptor if OK or exits in case of an error. const char *filename The name of the file to create or open. ++++++++++++++++++++++++++++++++++++++*/ int OpenFileBufferedAppend(const char *filename) { int fd; /* Open the file */ #if defined(_MSC_VER) || defined(__MINGW32__) fd=open(filename,O_WRONLY|O_CREAT|O_APPEND|O_BINARY|O_RANDOM,S_IREAD|S_IWRITE); #else fd=open(filename,O_WRONLY|O_CREAT|O_APPEND ,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); #endif if(fd<0) { #ifdef LIBROUTINO return(-1); #else fprintf(stderr,"Cannot open file '%s' for appending [%s].\n",filename,strerror(errno)); exit(EXIT_FAILURE); #endif } CreateFileBuffer(fd,-1); #if defined(_MSC_VER) || defined(__MINGW32__) CreateOpenedFile(fd,filename); #endif return(fd); } /*++++++++++++++++++++++++++++++++++++++ Open an existing file on disk for reading (with buffering). int ReOpenFileBuffered Returns the file descriptor if OK or exits in case of an error. const char *filename The name of the file to open. ++++++++++++++++++++++++++++++++++++++*/ int ReOpenFileBuffered(const char *filename) { int fd; /* Open the file */ #if defined(_MSC_VER) || defined(__MINGW32__) fd=open(filename,O_RDONLY|O_BINARY|O_RANDOM); #else fd=open(filename,O_RDONLY); #endif if(fd<0) { #ifdef LIBROUTINO return(-1); #else fprintf(stderr,"Cannot open file '%s' for reading [%s].\n",filename,strerror(errno)); exit(EXIT_FAILURE); #endif } CreateFileBuffer(fd,1); #if defined(_MSC_VER) || defined(__MINGW32__) CreateOpenedFile(fd,filename); #endif return(fd); } /*++++++++++++++++++++++++++++++++++++++ Open an existing file on disk for reading (with buffering), delete it and open a new file on disk for writing (with buffering). int ReplaceFileBuffered Returns the file descriptor of the new writable file. const char *filename The name of the file to open, delete and replace. int *oldfd Returns the file descriptor of the old, readable file. ++++++++++++++++++++++++++++++++++++++*/ int ReplaceFileBuffered(const char *filename,int *oldfd) { int newfd; #if defined(_MSC_VER) || defined(__MINGW32__) char *filename2; filename2=strcpy(malloc(strlen(filename)+2),filename); strcat(filename2,"2"); RenameFile(filename,filename2); *oldfd=ReOpenFileBuffered(filename2); DeleteFile(filename2); #else *oldfd=ReOpenFileBuffered(filename); DeleteFile(filename); #endif newfd=OpenFileBufferedNew(filename); return(newfd); } /*++++++++++++++++++++++++++++++++++++++ Write data to a file descriptor (via a buffer). int WriteFileBuffered Returns 0 if OK or something else in case of an error. int fd The file descriptor to write to. const void *address The address of the data to be written. size_t length The length of data to write. ++++++++++++++++++++++++++++++++++++++*/ int WriteFileBuffered(int fd,const void *address,size_t length) { #ifndef LIBROUTINO logassert(fd!=-1,"File descriptor is in error - report a bug"); logassert(fdreading,"File descriptor was not opened for writing - report a bug"); #endif /* Write the data */ if((filebuffers[fd]->pointer+length)>BUFFLEN) { if(write(fd,filebuffers[fd]->buffer,filebuffers[fd]->pointer)!=(ssize_t)filebuffers[fd]->pointer) return(-1); filebuffers[fd]->pointer=0; } if(length>=BUFFLEN) { if(write(fd,address,length)!=(ssize_t)length) return(-1); return(0); } memcpy(filebuffers[fd]->buffer+filebuffers[fd]->pointer,address,length); filebuffers[fd]->pointer+=length; return(0); } /*++++++++++++++++++++++++++++++++++++++ Read data from a file descriptor (via a buffer). int ReadFileBuffered Returns 0 if OK or something else in case of an error. int fd The file descriptor to read from. void *address The address the data is to be read into. size_t length The length of data to read. ++++++++++++++++++++++++++++++++++++++*/ int ReadFileBuffered(int fd,void *address,size_t length) { #ifndef LIBROUTINO logassert(fd!=-1,"File descriptor is in error - report a bug"); logassert(fdreading,"File descriptor was not opened for reading - report a bug"); #endif /* Read the data */ if((filebuffers[fd]->pointer+length)>filebuffers[fd]->length) if(filebuffers[fd]->pointerlength) { memcpy(address,filebuffers[fd]->buffer+filebuffers[fd]->pointer,filebuffers[fd]->length-filebuffers[fd]->pointer); address=(char*)address+filebuffers[fd]->length-filebuffers[fd]->pointer; length-=filebuffers[fd]->length-filebuffers[fd]->pointer; filebuffers[fd]->pointer=0; filebuffers[fd]->length=0; } if(length>=BUFFLEN) { if(read(fd,address,length)!=(ssize_t)length) return(-1); return(0); } if(filebuffers[fd]->pointer==filebuffers[fd]->length) { ssize_t len=read(fd,filebuffers[fd]->buffer,BUFFLEN); if(len<=0) return(-1); filebuffers[fd]->length=len; filebuffers[fd]->pointer=0; } if(filebuffers[fd]->length==0) return(-1); memcpy(address,filebuffers[fd]->buffer+filebuffers[fd]->pointer,length); filebuffers[fd]->pointer+=length; return(0); } /*++++++++++++++++++++++++++++++++++++++ Seek to a position in a file descriptor that uses a buffer. int SeekFileBuffered Returns 0 if OK or something else in case of an error. int fd The file descriptor to seek within. offset_t position The position to seek to. ++++++++++++++++++++++++++++++++++++++*/ int SeekFileBuffered(int fd,offset_t position) { #ifndef LIBROUTINO logassert(fd!=-1,"File descriptor is in error - report a bug"); logassert(fdreading) if(write(fd,filebuffers[fd]->buffer,filebuffers[fd]->pointer)!=(ssize_t)filebuffers[fd]->pointer) return(-1); filebuffers[fd]->pointer=0; filebuffers[fd]->length=0; if(lseek(fd,position,SEEK_SET)!=position) return(-1); return(0); } /*++++++++++++++++++++++++++++++++++++++ Skip forward by an offset in a file descriptor that uses a buffer. int SkipFileBuffered Returns 0 if OK or something else in case of an error. int fd The file descriptor to skip within. offset_t skip The amount to skip forward. ++++++++++++++++++++++++++++++++++++++*/ int SkipFileBuffered(int fd,offset_t skip) { #ifndef LIBROUTINO logassert(fd!=-1,"File descriptor is in error - report a bug"); logassert(fdreading,"File descriptor was not opened for reading - report a bug"); #endif /* Skip the data - needs to be optimised */ if((filebuffers[fd]->pointer+skip)>filebuffers[fd]->length) { skip-=(offset_t)(filebuffers[fd]->length-filebuffers[fd]->pointer); filebuffers[fd]->pointer=0; filebuffers[fd]->length=0; if(lseek(fd,skip,SEEK_CUR)==-1) return(-1); } else filebuffers[fd]->pointer+=skip; return(0); } /*++++++++++++++++++++++++++++++++++++++ Get the size of a file. offset_t SizeFile Returns the file size if OK or exits in case of an error. const char *filename The name of the file to check. ++++++++++++++++++++++++++++++++++++++*/ offset_t SizeFile(const char *filename) { struct stat buf; if(stat(filename,&buf)) { #ifdef LIBROUTINO return(-1); #else fprintf(stderr,"Cannot stat file '%s' [%s].\n",filename,strerror(errno)); exit(EXIT_FAILURE); #endif } return(buf.st_size); } /*++++++++++++++++++++++++++++++++++++++ Get the size of a file from a file descriptor. offset_t SizeFileFD Returns the file size if OK or exits in case of an error. int fd The file descriptor to check. ++++++++++++++++++++++++++++++++++++++*/ offset_t SizeFileFD(int fd) { struct stat buf; if(fstat(fd,&buf)) { #ifdef LIBROUTINO return(-1); #else fprintf(stderr,"Cannot stat file descriptor '%d' [%s].\n",fd,strerror(errno)); exit(EXIT_FAILURE); #endif } return(buf.st_size); } /*++++++++++++++++++++++++++++++++++++++ Check if a file exists. int ExistsFile Returns 1 if the file exists and 0 if not. const char *filename The name of the file to check. ++++++++++++++++++++++++++++++++++++++*/ int ExistsFile(const char *filename) { struct stat buf; if(stat(filename,&buf)) return(0); else return(1); } /*++++++++++++++++++++++++++++++++++++++ Close a file on disk (and flush the buffer). int CloseFileBuffered returns -1 (for similarity to the *OpenFileBuffered* functions). int fd The file descriptor to close. ++++++++++++++++++++++++++++++++++++++*/ int CloseFileBuffered(int fd) { #ifndef LIBROUTINO logassert(fdreading) if(write(fd,filebuffers[fd]->buffer,filebuffers[fd]->pointer)!=(ssize_t)filebuffers[fd]->pointer) return(-1); close(fd); free(filebuffers[fd]); filebuffers[fd]=NULL; #if defined(_MSC_VER) || defined(__MINGW32__) #ifndef LIBROUTINO logassert(fddelete) unlink(openedfiles[fd]->filename); free(openedfiles[fd]); openedfiles[fd]=NULL; #endif return(-1); } /*++++++++++++++++++++++++++++++++++++++ Open an existing file on disk for reading (in a simple mode). int OpenFile Returns the file descriptor if OK or exits in case of an error. const char *filename The name of the file to open. ++++++++++++++++++++++++++++++++++++++*/ int OpenFile(const char *filename) { int fd; /* Open the file */ #if defined(_MSC_VER) || defined(__MINGW32__) fd=open(filename,O_RDONLY|O_BINARY|O_RANDOM); #else fd=open(filename,O_RDONLY); #endif if(fd<0) { #ifdef LIBROUTINO return(-1); #else fprintf(stderr,"Cannot open file '%s' for reading [%s].\n",filename,strerror(errno)); exit(EXIT_FAILURE); #endif } #if defined(_MSC_VER) || defined(__MINGW32__) CreateOpenedFile(fd,filename); #endif return(fd); } /*++++++++++++++++++++++++++++++++++++++ Close a file on disk (that was opened in simple mode). int fd The file descriptor to close. ++++++++++++++++++++++++++++++++++++++*/ void CloseFile(int fd) { close(fd); #if defined(_MSC_VER) || defined(__MINGW32__) #ifndef LIBROUTINO logassert(fddelete) unlink(openedfiles[fd]->filename); free(openedfiles[fd]); openedfiles[fd]=NULL; #endif } /*++++++++++++++++++++++++++++++++++++++ Delete a file from disk. int DeleteFile Returns 0 if OK. const char *filename The name of the file to delete. ++++++++++++++++++++++++++++++++++++++*/ int DeleteFile(const char *filename) { #if defined(_MSC_VER) || defined(__MINGW32__) int fd; for(fd=0;fdfilename,filename)) { openedfiles[fd]->delete=1; return(0); } #endif unlink(filename); return(0); } /*++++++++++++++++++++++++++++++++++++++ Rename a file on disk. int RenameFile Returns 0 if OK. const char *oldfilename The old name of the file before renaming. const char *newfilename The new name of the file after renaming. ++++++++++++++++++++++++++++++++++++++*/ int RenameFile(const char *oldfilename,const char *newfilename) { rename(oldfilename,newfilename); return(0); } /*++++++++++++++++++++++++++++++++++++++ Create a file buffer. int fd The file descriptor. int read_write A flag set to 1 for reading, -1 for writing and 0 for unbuffered. ++++++++++++++++++++++++++++++++++++++*/ static void CreateFileBuffer(int fd,int read_write) { if(nfilebuffers<=fd) { int i; filebuffers=(struct filebuffer**)realloc((void*)filebuffers,(fd+1)*sizeof(struct filebuffer*)); for(i=nfilebuffers;i<=fd;i++) filebuffers[i]=NULL; nfilebuffers=fd+1; } if(read_write) { filebuffers[fd]=(struct filebuffer*)calloc(sizeof(struct filebuffer),1); filebuffers[fd]->reading=(read_write==1); } } #if defined(_MSC_VER) || defined(__MINGW32__) /*++++++++++++++++++++++++++++++++++++++ Create an opened file record. int fd The file descriptor. const char *filename The name of the file. ++++++++++++++++++++++++++++++++++++++*/ static void CreateOpenedFile(int fd,const char *filename) { if(nopenedfiles<=fd) { int i; openedfiles=(struct openedfile**)realloc((void*)openedfiles,(fd+1)*sizeof(struct openedfile*)); for(i=nopenedfiles;i<=fd;i++) openedfiles[i]=NULL; nopenedfiles=fd+1; } openedfiles[fd]=(struct openedfile*)calloc(sizeof(struct openedfile),1); openedfiles[fd]->filename=strcpy(malloc(strlen(filename)+1),filename); openedfiles[fd]->delete=0; } #endif routino-3.0/src/osmparser.c 644 233 144 101702 12563633051 11236 0/*************************************** OSM file parser (either JOSM or planet) Part of the Routino routing software. ******************/ /****************** This file Copyright 2008-2015 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #include #include #include #include #include "types.h" #include "typesx.h" #include "nodesx.h" #include "waysx.h" #include "relationsx.h" #include "osmparser.h" #include "tagging.h" #include "logging.h" /* Macros */ /*+ Checks if a value in the XML is one of the allowed values for true. +*/ #define ISTRUE(xx) (!strcmp(xx,"true") || !strcmp(xx,"yes") || !strcmp(xx,"1")) /*+ Checks if a value in the XML is one of the allowed values for false. +*/ #define ISFALSE(xx) (!strcmp(xx,"false") || !strcmp(xx,"no") || !strcmp(xx,"0")) /* Local parsing variables (re-initialised for each file) */ static NodesX *nodes; static WaysX *ways; static RelationsX *relations; static node_t *way_nodes; static int way_nnodes; static node_t *relation_nodes; static int relation_nnodes; static way_t *relation_ways; static int relation_nways; static relation_t *relation_relations; static int relation_nrelations; static way_t relation_from; static way_t relation_to; static node_t relation_via; /* Local parsing functions */ static double parse_speed(way_t id,const char *k,const char *v); static double parse_weight(way_t id,const char *k,const char *v); static double parse_length(way_t id,const char *k,const char *v); /*++++++++++++++++++++++++++++++++++++++ Initialise the OSM parser by initialising the local variables. NodesX *OSMNodes The data structure of nodes to fill in. WaysX *OSMWays The data structure of ways to fill in. RelationsX *OSMRelations The data structure of relations to fill in. ++++++++++++++++++++++++++++++++++++++*/ void InitialiseParser(NodesX *OSMNodes,WaysX *OSMWays,RelationsX *OSMRelations) { /* Copy the function parameters and initialise the variables */ nodes=OSMNodes; ways=OSMWays; relations=OSMRelations; way_nodes=(node_t*)malloc(256*sizeof(node_t)); relation_nodes =(node_t *)malloc(256*sizeof(node_t)); relation_ways =(way_t *)malloc(256*sizeof(way_t)); relation_relations=(relation_t*)malloc(256*sizeof(relation_t)); } /*++++++++++++++++++++++++++++++++++++++ Clean up the memory after parsing. ++++++++++++++++++++++++++++++++++++++*/ void CleanupParser(void) { /* Free the variables */ free(way_nodes); free(relation_nodes); free(relation_ways); free(relation_relations); } /*++++++++++++++++++++++++++++++++++++++ Add node references to a way. int64_t node_id The node ID to add or zero to clear the list. ++++++++++++++++++++++++++++++++++++++*/ void AddWayRefs(int64_t node_id) { if(node_id==0) way_nnodes=0; else { node_t id; if(way_nnodes && (way_nnodes%256)==0) way_nodes=(node_t*)realloc((void*)way_nodes,(way_nnodes+256)*sizeof(node_t)); id=(node_t)node_id; logassert((int64_t)id==node_id,"Node ID too large (change node_t to 64-bits?)"); /* check node id can be stored in node_t data type. */ way_nodes[way_nnodes++]=id; } } /*++++++++++++++++++++++++++++++++++++++ Add node, way or relation references to a relation. int64_t node_id The node ID to add or zero if it is not a node. int64_t way_id The way ID to add or zero if it is not a way. int64_t relation_id The relation ID to add or zero if it is not a relation. const char *role The role played by this referenced item or NULL. If all of node_id, way_id and relation_id are zero then the list is cleared. ++++++++++++++++++++++++++++++++++++++*/ void AddRelationRefs(int64_t node_id,int64_t way_id,int64_t relation_id,const char *role) { if(node_id==0 && way_id==0 && relation_id==0) { relation_nnodes=0; relation_nways=0; relation_nrelations=0; relation_from=NO_WAY_ID; relation_via=NO_NODE_ID; relation_to=NO_WAY_ID; } else if(node_id!=0) { node_t id; id=(node_t)node_id; logassert((int64_t)id==node_id,"Node ID too large (change node_t to 64-bits?)"); /* check node id can be stored in node_t data type. */ if(relation_nnodes && (relation_nnodes%256)==0) relation_nodes=(node_t*)realloc((void*)relation_nodes,(relation_nnodes+256)*sizeof(node_t)); relation_nodes[relation_nnodes++]=id; if(role) { if(!strcmp(role,"via")) relation_via=id; } } else if(way_id!=0) { way_t id; id=(way_t)way_id; logassert((int64_t)id==way_id,"Way ID too large (change way_t to 64-bits?)"); /* check way id can be stored in way_t data type. */ if(relation_nways && (relation_nways%256)==0) relation_ways=(way_t*)realloc((void*)relation_ways,(relation_nways+256)*sizeof(way_t)); relation_ways[relation_nways++]=id; if(role) { if(!strcmp(role,"from")) relation_from=id; else if(!strcmp(role,"to")) relation_to=id; } } else /* if(relation_id!=0) */ { relation_t id; id=(relation_t)relation_id; logassert((int64_t)id==relation_id,"Relation ID too large (change relation_t to 64-bits?)"); /* check relation id can be stored in relation_t data type. */ if(relation_nrelations && (relation_nrelations%256)==0) relation_relations=(relation_t*)realloc((void*)relation_relations,(relation_nrelations+256)*sizeof(relation_t)); relation_relations[relation_nrelations++]=relation_id; } } /*++++++++++++++++++++++++++++++++++++++ Process the tags associated with a node. TagList *tags The list of node tags. int64_t node_id The id of the node. double latitude The latitude of the node. double longitude The longitude of the node. int mode The mode of operation to take (create, modify, delete). ++++++++++++++++++++++++++++++++++++++*/ void ProcessNodeTags(TagList *tags,int64_t node_id,double latitude,double longitude,int mode) { transports_t allow=Transports_ALL; nodeflags_t flags=0; node_t id; int i; /* Convert id */ id=(node_t)node_id; logassert((int64_t)id==node_id,"Node ID too large (change node_t to 64-bits?)"); /* check node id can be stored in node_t data type. */ /* Delete */ if(mode==MODE_DELETE) { AppendNodeList(nodes,id,degrees_to_radians(latitude),degrees_to_radians(longitude),allow,NODE_DELETED); return; } /* Parse the tags */ for(i=0;intags;i++) { int recognised=0; char *k=tags->k[i]; char *v=tags->v[i]; switch(*k) { case 'b': if(!strcmp(k,"bicycle")) { if(ISFALSE(v)) allow&=~Transports_Bicycle; else if(!ISTRUE(v)) logerror("Node %"Pnode_t" has an unrecognised tag 'bicycle' = '%s' (after tagging rules); using 'yes'.\n",logerror_node(id),v); recognised=1; break; } break; case 'f': if(!strcmp(k,"foot")) { if(ISFALSE(v)) allow&=~Transports_Foot; else if(!ISTRUE(v)) logerror("Node %"Pnode_t" has an unrecognised tag 'foot' = '%s' (after tagging rules); using 'yes'.\n",logerror_node(id),v); recognised=1; break; } break; case 'g': if(!strcmp(k,"goods")) { if(ISFALSE(v)) allow&=~Transports_Goods; else if(!ISTRUE(v)) logerror("Node %"Pnode_t" has an unrecognised tag 'goods' = '%s' (after tagging rules); using 'yes'.\n",logerror_node(id),v); recognised=1; break; } break; case 'h': if(!strcmp(k,"horse")) { if(ISFALSE(v)) allow&=~Transports_Horse; else if(!ISTRUE(v)) logerror("Node %"Pnode_t" has an unrecognised tag 'horse' = '%s' (after tagging rules); using 'yes'.\n",logerror_node(id),v); recognised=1; break; } if(!strcmp(k,"hgv")) { if(ISFALSE(v)) allow&=~Transports_HGV; else if(!ISTRUE(v)) logerror("Node %"Pnode_t" has an unrecognised tag 'hgv' = '%s' (after tagging rules); using 'yes'.\n",logerror_node(id),v); recognised=1; break; } break; case 'm': if(!strcmp(k,"moped")) { if(ISFALSE(v)) allow&=~Transports_Moped; else if(!ISTRUE(v)) logerror("Node %"Pnode_t" has an unrecognised tag 'moped' = '%s' (after tagging rules); using 'yes'.\n",logerror_node(id),v); recognised=1; break; } if(!strcmp(k,"motorcycle")) { if(ISFALSE(v)) allow&=~Transports_Motorcycle; else if(!ISTRUE(v)) logerror("Node %"Pnode_t" has an unrecognised tag 'motorcycle' = '%s' (after tagging rules); using 'yes'.\n",logerror_node(id),v); recognised=1; break; } if(!strcmp(k,"motorcar")) { if(ISFALSE(v)) allow&=~Transports_Motorcar; else if(!ISTRUE(v)) logerror("Node %"Pnode_t" has an unrecognised tag 'motorcar' = '%s' (after tagging rules); using 'yes'.\n",logerror_node(id),v); recognised=1; break; } break; case 'p': if(!strcmp(k,"psv")) { if(ISFALSE(v)) allow&=~Transports_PSV; else if(!ISTRUE(v)) logerror("Node %"Pnode_t" has an unrecognised tag 'psv' = '%s' (after tagging rules); using 'yes'.\n",logerror_node(id),v); recognised=1; break; } break; case 'r': if(!strcmp(k,"roundabout")) { if(ISTRUE(v)) flags|=NODE_MINIRNDBT; else logerror("Node %"Pnode_t" has an unrecognised tag 'roundabout' = '%s' (after tagging rules); using 'no'.\n",id,v); recognised=1; break; } break; case 'w': if(!strcmp(k,"wheelchair")) { if(ISFALSE(v)) allow&=~Transports_Wheelchair; else if(!ISTRUE(v)) logerror("Node %"Pnode_t" has an unrecognised tag 'wheelchair' = '%s' (after tagging rules); using 'yes'.\n",logerror_node(id),v); recognised=1; break; } break; default: break; } if(!recognised) logerror("Node %"Pnode_t" has an unrecognised tag '%s' = '%s' (after tagging rules); ignoring it.\n",logerror_node(id),k,v); } /* Create the node */ AppendNodeList(nodes,id,degrees_to_radians(latitude),degrees_to_radians(longitude),allow,flags); } /*++++++++++++++++++++++++++++++++++++++ Process the tags associated with a way. TagList *tags The list of way tags. int64_t way_id The id of the way. int mode The mode of operation to take (create, modify, delete). ++++++++++++++++++++++++++++++++++++++*/ void ProcessWayTags(TagList *tags,int64_t way_id,int mode) { Way way={0}; int oneway=0,area=0; int roundabout=0,lanes=0,cyclebothways=0; char *name=NULL,*ref=NULL,*refname=NULL; way_t id; int i; /* Convert id */ id=(way_t)way_id; logassert((int64_t)id==way_id,"Way ID too large (change way_t to 64-bits?)"); /* check way id can be stored in way_t data type. */ /* Delete */ if(mode==MODE_DELETE || mode==MODE_MODIFY) { way.type=WAY_DELETED; AppendWayList(ways,id,&way,way_nodes,way_nnodes,""); } if(mode==MODE_DELETE) return; /* Sanity check */ if(way_nnodes==0) { logerror("Way %"Pway_t" has no nodes.\n",logerror_way(id)); return; } if(way_nnodes==1) { logerror_node(way_nodes[0]); /* Extra logerror information since way isn't stored */ logerror("Way %"Pway_t" has only one node.\n",logerror_way(id)); return; } /* Parse the tags - just look for highway */ for(i=0;intags;i++) { char *k=tags->k[i]; char *v=tags->v[i]; if(!strcmp(k,"highway")) { way.type=HighwayType(v); if(way.type==Highway_None) logerror("Way %"Pway_t" has an unrecognised highway type '%s' (after tagging rules); ignoring it.\n",logerror_way(id),v); break; } } /* Don't continue if this is not a highway (bypass error logging) */ if(way.type==Highway_None) return; /* Parse the tags - look for the others */ for(i=0;intags;i++) { int recognised=0; char *k=tags->k[i]; char *v=tags->v[i]; switch(*k) { case 'a': if(!strcmp(k,"area")) { if(ISTRUE(v)) area=1; else if(!ISFALSE(v)) logerror("Way %"Pway_t" has an unrecognised tag 'area' = '%s' (after tagging rules); using 'no'.\n",logerror_way(id),v); recognised=1; break; } break; case 'b': if(!strcmp(k,"bicycle")) { if(ISTRUE(v)) way.allow|=Transports_Bicycle; else if(!ISFALSE(v)) logerror("Way %"Pway_t" has an unrecognised tag 'bicycle' = '%s' (after tagging rules); using 'no'.\n",logerror_way(id),v); recognised=1; break; } if(!strcmp(k,"bicycleroute")) { if(ISTRUE(v)) way.props|=Properties_BicycleRoute; else if(!ISFALSE(v)) logerror("Way %"Pway_t" has an unrecognised tag 'bicycleroute' = '%s' (after tagging rules); using 'no'.\n",logerror_way(id),v); recognised=1; break; } if(!strcmp(k,"bridge")) { if(ISTRUE(v)) way.props|=Properties_Bridge; else if(!ISFALSE(v)) logerror("Way %"Pway_t" has an unrecognised tag 'bridge' = '%s' (after tagging rules); using 'no'.\n",logerror_way(id),v); recognised=1; break; } break; case 'c': if(!strcmp(k,"cyclebothways")) { if(ISTRUE(v)) cyclebothways=1; else if(!ISFALSE(v)) logerror("Way %"Pway_t" has an unrecognised tag 'cyclebothways' = '%s' (after tagging rules); using 'no'.\n",logerror_way(id),v); recognised=1; break; } break; case 'f': if(!strcmp(k,"foot")) { if(ISTRUE(v)) way.allow|=Transports_Foot; else if(!ISFALSE(v)) logerror("Way %"Pway_t" has an unrecognised tag 'foot' = '%s' (after tagging rules); using 'no'.\n",logerror_way(id),v); recognised=1; break; } if(!strcmp(k,"footroute")) { if(ISTRUE(v)) way.props|=Properties_FootRoute; else if(!ISFALSE(v)) logerror("Way %"Pway_t" has an unrecognised tag 'footroute' = '%s' (after tagging rules); using 'no'.\n",logerror_way(id),v); recognised=1; break; } break; case 'g': if(!strcmp(k,"goods")) { if(ISTRUE(v)) way.allow|=Transports_Goods; else if(!ISFALSE(v)) logerror("Way %"Pway_t" has an unrecognised tag 'goods' = '%s' (after tagging rules); using 'no'.\n",logerror_way(id),v); recognised=1; break; } break; case 'h': if(!strcmp(k,"highway")) {recognised=1; break;} if(!strcmp(k,"horse")) { if(ISTRUE(v)) way.allow|=Transports_Horse; else if(!ISFALSE(v)) logerror("Way %"Pway_t" has an unrecognised tag 'horse' = '%s' (after tagging rules); using 'no'.\n",logerror_way(id),v); recognised=1; break; } if(!strcmp(k,"hgv")) { if(ISTRUE(v)) way.allow|=Transports_HGV; else if(!ISFALSE(v)) logerror("Way %"Pway_t" has an unrecognised tag 'hgv' = '%s' (after tagging rules); using 'no'.\n",logerror_way(id),v); recognised=1; break; } break; case 'l': if(!strcmp(k,"lanes")) { int en=0; float lanesf; if(sscanf(v,"%f%n",&lanesf,&en)==1 && en && !v[en]) lanes=(int)lanesf; else logerror("Way %"Pway_t" has an unrecognised tag 'lanes' = '%s' (after tagging rules); ignoring it.\n",logerror_way(id),v); recognised=1; break; } break; case 'm': if(!strncmp(k,"max",3)) { if(!strcmp(k+3,"speed")) { way.speed=kph_to_speed(parse_speed(id,k,v)); recognised=1; break; } if(!strcmp(k+3,"weight")) { way.weight=tonnes_to_weight(parse_weight(id,k,v)); recognised=1; break; } if(!strcmp(k+3,"height")) { way.height=metres_to_height(parse_length(id,k,v)); recognised=1; break; } if(!strcmp(k+3,"width")) { way.width=metres_to_height(parse_length(id,k,v)); recognised=1; break; } if(!strcmp(k+3,"length")) { way.length=metres_to_height(parse_length(id,k,v)); recognised=1; break; } } if(!strcmp(k,"moped")) { if(ISTRUE(v)) way.allow|=Transports_Moped; else if(!ISFALSE(v)) logerror("Way %"Pway_t" has an unrecognised tag 'moped' = '%s' (after tagging rules); using 'no'.\n",logerror_way(id),v); recognised=1; break; } if(!strcmp(k,"motorcycle")) { if(ISTRUE(v)) way.allow|=Transports_Motorcycle; else if(!ISFALSE(v)) logerror("Way %"Pway_t" has an unrecognised tag 'motorcycle' = '%s' (after tagging rules); using 'no'.\n",logerror_way(id),v); recognised=1; break; } if(!strcmp(k,"motorcar")) { if(ISTRUE(v)) way.allow|=Transports_Motorcar; else if(!ISFALSE(v)) logerror("Way %"Pway_t" has an unrecognised tag 'motorcar' = '%s' (after tagging rules); using 'no'.\n",logerror_way(id),v); recognised=1; break; } if(!strcmp(k,"multilane")) { if(ISTRUE(v)) way.props|=Properties_Multilane; else if(!ISFALSE(v)) logerror("Way %"Pway_t" has an unrecognised tag 'multilane' = '%s' (after tagging rules); using 'no'.\n",logerror_way(id),v); recognised=1; break; } break; case 'n': if(!strcmp(k,"name")) { name=v; recognised=1; break; } break; case 'o': if(!strcmp(k,"oneway")) { if(ISTRUE(v)) oneway=1; else if(!strcmp(v,"-1")) oneway=-1; else if(!ISFALSE(v)) logerror("Way %"Pway_t" has an unrecognised tag 'oneway' = '%s' (after tagging rules); using 'no'.\n",logerror_way(id),v); recognised=1; break; } break; case 'p': if(!strcmp(k,"paved")) { if(ISTRUE(v)) way.props|=Properties_Paved; else if(!ISFALSE(v)) logerror("Way %"Pway_t" has an unrecognised tag 'paved' = '%s' (after tagging rules); using 'no'.\n",logerror_way(id),v); recognised=1; break; } if(!strcmp(k,"psv")) { if(ISTRUE(v)) way.allow|=Transports_PSV; else if(!ISFALSE(v)) logerror("Way %"Pway_t" has an unrecognised tag 'psv' = '%s' (after tagging rules); using 'no'.\n",logerror_way(id),v); recognised=1; break; } break; case 'r': if(!strcmp(k,"ref")) { ref=v; recognised=1; break; } if(!strcmp(k,"roundabout")) { if(ISTRUE(v)) roundabout=1; else if(!ISFALSE(v)) logerror("Way %"Pway_t" has an unrecognised tag 'roundabout' = '%s' (after tagging rules); using 'no'.\n",logerror_way(id),v); recognised=1; break; } break; case 't': if(!strcmp(k,"tunnel")) { if(ISTRUE(v)) way.props|=Properties_Tunnel; else if(!ISFALSE(v)) logerror("Way %"Pway_t" has an unrecognised tag 'tunnel' = '%s' (after tagging rules); using 'no'.\n",logerror_way(id),v); recognised=1; break; } break; case 'w': if(!strcmp(k,"wheelchair")) { if(ISTRUE(v)) way.allow|=Transports_Wheelchair; else if(!ISFALSE(v)) logerror("Way %"Pway_t" has an unrecognised tag 'wheelchair' = '%s' (after tagging rules); using 'no'.\n",logerror_way(id),v); recognised=1; break; } break; default: break; } if(!recognised) logerror("Way %"Pway_t" has an unrecognised tag '%s' = '%s' (after tagging rules); ignoring it.\n",logerror_way(id),k,v); } /* Create the way */ if(area && oneway) { logerror("Way %"Pway_t" is an area and oneway; ignoring area tag.\n",logerror_way(id)); area=0; } if(cyclebothways && !oneway) { logerror("Way %"Pway_t" is cyclebothways but not oneway; ignoring cyclebothways tag.\n",logerror_way(id)); cyclebothways=0; } if(roundabout && !oneway) { logerror("Way %"Pway_t" is roundabout but not oneway; adding oneway tag.\n",logerror_way(id)); oneway=1; } if(!way.allow) return; if(cyclebothways) way.type|=Highway_CycleBothWays; if(oneway) { way.type|=Highway_OneWay; if(oneway==-1) for(i=0;i1) way.props|=Properties_Multilane; if(oneway && lanes==1) way.props&=~Properties_Multilane; } if(ref && name) { refname=(char*)malloc(strlen(ref)+strlen(name)+4); sprintf(refname,"%s (%s)",name,ref); } else if(ref && !name) refname=ref; else if(!ref && name) refname=name; else /* if(!ref && !name) */ refname=""; AppendWayList(ways,id,&way,way_nodes,way_nnodes,refname); if(ref && name) free(refname); } /*++++++++++++++++++++++++++++++++++++++ Process the tags associated with a relation. TagList *tags The list of relation tags. int64_t relation_id The id of the relation. int mode The mode of operation to take (create, modify, delete). ++++++++++++++++++++++++++++++++++++++*/ void ProcessRelationTags(TagList *tags,int64_t relation_id,int mode) { transports_t routes=Transports_None; transports_t except=Transports_None; int relation_turn_restriction=0; TurnRestriction restriction=TurnRestrict_None; relation_t id; int i; /* Convert id */ id=(relation_t)relation_id; logassert((int64_t)id==relation_id,"Relation ID too large (change relation_t to 64-bits?)"); /* check relation id can be stored in relation_t data type. */ /* Delete */ if(mode==MODE_DELETE || mode==MODE_MODIFY) { AppendRouteRelationList(relations,id,RELATION_DELETED, relation_nodes,relation_nnodes, relation_ways,relation_nways, relation_relations,relation_nrelations); AppendTurnRelationList(relations,id, relation_from,relation_to,relation_via, restriction,RELATION_DELETED); } if(mode==MODE_DELETE) return; /* Sanity check */ if(relation_nnodes==0 && relation_nways==0 && relation_nrelations==0) { logerror("Relation %"Prelation_t" has no nodes, ways or relations.\n",logerror_relation(id)); return; } /* Parse the tags */ for(i=0;intags;i++) { int recognised=0; char *k=tags->k[i]; char *v=tags->v[i]; switch(*k) { case 'b': if(!strcmp(k,"bicycleroute")) { if(ISTRUE(v)) routes|=Transports_Bicycle; else if(!ISFALSE(v)) logerror("Relation %"Prelation_t" has an unrecognised tag 'bicycleroute' = '%s' (after tagging rules); using 'no'.\n",logerror_relation(id),v); recognised=1; break; } break; case 'e': if(!strcmp(k,"except")) { for(i=1;i. ***************************************/ #ifndef LOGGING_H #define LOGGING_H /*+ To stop multiple inclusions. +*/ #include #include "typesx.h" /* Data structures */ /*+ A structure containing a single object as written by the logerror_*() functions. +*/ typedef struct _ErrorLogObject { char type; /*+ The type of the object. +*/ uint64_t id; /*+ The id of the object. +*/ uint32_t offset; /*+ The offset of the error message from the beginning of the text file. +*/ } ErrorLogObject; /* Variables */ extern int option_loggable; extern int option_logtime; extern int option_logmemory; /* Runtime progress logging functions in logging.c */ void printf_program_start(void); void printf_program_end(void); #ifdef __GNUC__ void printf_first(const char *format, ...) __attribute__ ((format (printf, 1, 2))); void printf_middle(const char *format, ...) __attribute__ ((format (printf, 1, 2))); void printf_last(const char *format, ...) __attribute__ ((format (printf, 1, 2))); void fprintf_first(FILE *file,const char *format, ...) __attribute__ ((format (printf, 2, 3))); void fprintf_middle(FILE *file,const char *format, ...) __attribute__ ((format (printf, 2, 3))); void fprintf_last(FILE *file,const char *format, ...) __attribute__ ((format (printf, 2, 3))); #else void printf_first(const char *format, ...); void printf_middle(const char *format, ...); void printf_last(const char *format, ...); void fprintf_first(FILE *file,const char *format, ...); void fprintf_middle(FILE *file,const char *format, ...); void fprintf_last(FILE *file,const char *format, ...); #endif void log_malloc(void *address,size_t size); void log_free(void *address); void log_mmap(size_t size); void log_munmap(size_t size); /* Error logging functions in logerror.c */ void open_errorlog(const char *filename,int append,int bin); void close_errorlog(void); #ifdef __GNUC__ void logerror(const char *format, ...) __attribute__ ((format (printf, 1, 2))); #else void logerror(const char *format, ...); #endif node_t logerror_node (node_t id); way_t logerror_way (way_t id); relation_t logerror_relation(relation_t id); /* Runtime fatal error assertion in logging.c */ #define logassert(xx,yy) do { if(!(xx)) _logassert(yy,__FILE__,__LINE__); } while(0) void _logassert(const char *message,const char *file,int line); #endif /* LOGGING_H */ routino-3.0/src/relationsx.c 644 233 144 124157 12563633052 11425 0/*************************************** Extended Relation data type functions. Part of the Routino routing software. ******************/ /****************** This file Copyright 2010-2015 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #include #include #include "types.h" #include "segments.h" #include "relations.h" #include "nodesx.h" #include "segmentsx.h" #include "waysx.h" #include "relationsx.h" #include "files.h" #include "logging.h" #include "sorting.h" /* Global variables */ /*+ The command line '--tmpdir' option or its default value. +*/ extern char *option_tmpdirname; /* Local variables */ /*+ Temporary file-local variables for use by the sort functions (re-initialised for each sort). +*/ static SegmentsX *sortsegmentsx; static NodesX *sortnodesx; /* Local functions */ static int sort_route_by_id(RouteRelX *a,RouteRelX *b); static int deduplicate_route_by_id(RouteRelX *relationx,index_t index); static int sort_turn_by_id(TurnRelX *a,TurnRelX *b); static int deduplicate_turn_by_id(TurnRelX *relationx,index_t index); static int geographically_index(TurnRelX *relationx,index_t index); static int geographically_index_convert_segments(TurnRelX *relationx,index_t index); static int sort_by_via(TurnRelX *a,TurnRelX *b); /*++++++++++++++++++++++++++++++++++++++ Allocate a new relation list (create a new file or open an existing one). RelationsX *NewRelationList Returns the relation list. int append Set to 1 if the file is to be opened for appending. int readonly Set to 1 if the file is to be opened for reading. ++++++++++++++++++++++++++++++++++++++*/ RelationsX *NewRelationList(int append,int readonly) { RelationsX *relationsx; relationsx=(RelationsX*)calloc(1,sizeof(RelationsX)); logassert(relationsx,"Failed to allocate memory (try using slim mode?)"); /* Check calloc() worked */ /* Route Relations */ relationsx->rrfilename =(char*)malloc(strlen(option_tmpdirname)+32); relationsx->rrfilename_tmp=(char*)malloc(strlen(option_tmpdirname)+48); /* allow %p to be up to 20 bytes */ sprintf(relationsx->rrfilename ,"%s/relationsx.route.parsed.mem",option_tmpdirname); sprintf(relationsx->rrfilename_tmp,"%s/relationsx.route.%p.tmp" ,option_tmpdirname,(void*)relationsx); if(append || readonly) if(ExistsFile(relationsx->rrfilename)) { FILESORT_VARINT relationsize; int rrfd; rrfd=ReOpenFileBuffered(relationsx->rrfilename); while(!ReadFileBuffered(rrfd,&relationsize,FILESORT_VARSIZE)) { SkipFileBuffered(rrfd,relationsize); relationsx->rrnumber++; } CloseFileBuffered(rrfd); RenameFile(relationsx->rrfilename,relationsx->rrfilename_tmp); } if(append) relationsx->rrfd=OpenFileBufferedAppend(relationsx->rrfilename_tmp); else if(!readonly) relationsx->rrfd=OpenFileBufferedNew(relationsx->rrfilename_tmp); else relationsx->rrfd=-1; /* Turn Restriction Relations */ relationsx->trfilename =(char*)malloc(strlen(option_tmpdirname)+32); relationsx->trfilename_tmp=(char*)malloc(strlen(option_tmpdirname)+48); /* allow %p to be up to 20 bytes */ sprintf(relationsx->trfilename ,"%s/relationsx.turn.parsed.mem",option_tmpdirname); sprintf(relationsx->trfilename_tmp,"%s/relationsx.turn.%p.tmp" ,option_tmpdirname,(void*)relationsx); if(append || readonly) if(ExistsFile(relationsx->trfilename)) { offset_t size; size=SizeFile(relationsx->trfilename); relationsx->trnumber=size/sizeof(TurnRelX); RenameFile(relationsx->trfilename,relationsx->trfilename_tmp); } if(append) relationsx->trfd=OpenFileBufferedAppend(relationsx->trfilename_tmp); else if(!readonly) relationsx->trfd=OpenFileBufferedNew(relationsx->trfilename_tmp); else relationsx->trfd=-1; return(relationsx); } /*++++++++++++++++++++++++++++++++++++++ Free a relation list. RelationsX *relationsx The set of relations to be freed. int keep If set then the results file is to be kept. ++++++++++++++++++++++++++++++++++++++*/ void FreeRelationList(RelationsX *relationsx,int keep) { /* Route relations */ if(keep) RenameFile(relationsx->rrfilename_tmp,relationsx->rrfilename); else DeleteFile(relationsx->rrfilename_tmp); free(relationsx->rrfilename); free(relationsx->rrfilename_tmp); if(relationsx->rridata) { log_free(relationsx->rridata); free(relationsx->rridata); } if(relationsx->rrodata) { log_free(relationsx->rrodata); free(relationsx->rrodata); } /* Turn Restriction relations */ if(keep) RenameFile(relationsx->trfilename_tmp,relationsx->trfilename); else DeleteFile(relationsx->trfilename_tmp); free(relationsx->trfilename); free(relationsx->trfilename_tmp); if(relationsx->tridata) { log_free(relationsx->tridata); free(relationsx->tridata); } free(relationsx); } /*++++++++++++++++++++++++++++++++++++++ Append a single relation to an unsorted route relation list. RelationsX* relationsx The set of relations to process. relation_t id The ID of the relation. transports_t routes The types of routes that this relation is for. node_t *nodes The array of nodes that are members of the relation. int nnodes The number of nodes that are members of the relation. way_t *ways The array of ways that are members of the relation. int nways The number of ways that are members of the relation. relation_t *relations The array of relations that are members of the relation. int nrelations The number of relations that are members of the relation. ++++++++++++++++++++++++++++++++++++++*/ void AppendRouteRelationList(RelationsX* relationsx,relation_t id, transports_t routes, node_t *nodes,int nnodes, way_t *ways,int nways, relation_t *relations,int nrelations) { RouteRelX relationx={0}; FILESORT_VARINT size; node_t nonode=NO_NODE_ID; way_t noway=NO_WAY_ID; relation_t norelation=NO_RELATION_ID; relationx.id=id; relationx.routes=routes; size=sizeof(RouteRelX)+(nnodes+1)*sizeof(node_t)+(nways+1)*sizeof(way_t)+(nrelations+1)*sizeof(relation_t); WriteFileBuffered(relationsx->rrfd,&size,FILESORT_VARSIZE); WriteFileBuffered(relationsx->rrfd,&relationx,sizeof(RouteRelX)); WriteFileBuffered(relationsx->rrfd,nodes ,nnodes*sizeof(node_t)); WriteFileBuffered(relationsx->rrfd,&nonode, sizeof(node_t)); WriteFileBuffered(relationsx->rrfd,ways ,nways*sizeof(way_t)); WriteFileBuffered(relationsx->rrfd,&noway, sizeof(way_t)); WriteFileBuffered(relationsx->rrfd,relations ,nrelations*sizeof(relation_t)); WriteFileBuffered(relationsx->rrfd,&norelation, sizeof(relation_t)); relationsx->rrnumber++; logassert(relationsx->rrnumber!=0,"Too many route relations (change index_t to 64-bits?)"); /* Zero marks the high-water mark for relations. */ } /*++++++++++++++++++++++++++++++++++++++ Append a single relation to an unsorted turn restriction relation list. RelationsX* relationsx The set of relations to process. relation_t id The ID of the relation. way_t from The way that the turn restriction starts from. way_t to The way that the restriction finished on. node_t via The node that the turn restriction passes through. TurnRestriction restriction The type of restriction. transports_t except The set of transports allowed to bypass the restriction. ++++++++++++++++++++++++++++++++++++++*/ void AppendTurnRelationList(RelationsX* relationsx,relation_t id, way_t from,way_t to,node_t via, TurnRestriction restriction,transports_t except) { TurnRelX relationx={0}; relationx.id=id; relationx.from=from; relationx.to=to; relationx.via=via; relationx.restriction=restriction; relationx.except=except; WriteFileBuffered(relationsx->trfd,&relationx,sizeof(TurnRelX)); relationsx->trnumber++; logassert(relationsx->trnumber!=0,"Too many turn relations (change index_t to 64-bits?)"); /* Zero marks the high-water mark for relations. */ } /*++++++++++++++++++++++++++++++++++++++ Finish appending relations and change the filename over. RelationsX *relationsx The relations that have been appended. ++++++++++++++++++++++++++++++++++++++*/ void FinishRelationList(RelationsX *relationsx) { if(relationsx->rrfd!=-1) relationsx->rrfd =CloseFileBuffered(relationsx->rrfd); if(relationsx->trfd!=-1) relationsx->trfd=CloseFileBuffered(relationsx->trfd); } /*++++++++++++++++++++++++++++++++++++++ Find a particular route relation index. index_t IndexRouteRelX Returns the index of the route relation with the specified id. RelationsX *relationsx The set of relations to process. relation_t id The relation id to look for. ++++++++++++++++++++++++++++++++++++++*/ index_t IndexRouteRelX(RelationsX *relationsx,relation_t id) { index_t start=0; index_t end=relationsx->rrnumber-1; index_t mid; if(relationsx->rrnumber==0) /* There are no route relations */ return(NO_RELATION); if(idrridata[start]) /* Key is before start */ return(NO_RELATION); if(id>relationsx->rridata[end]) /* Key is after end */ return(NO_RELATION); /* Binary search - search key exact match only is required. * * # <- start | Check mid and move start or end if it doesn't match * # | * # | Since an exact match is wanted we can set end=mid-1 * # <- mid | or start=mid+1 because we know that mid doesn't match. * # | * # | Eventually either end=start or end=start+1 and one of * # <- end | start or end is the wanted one. */ do { mid=(start+end)/2; /* Choose mid point */ if(relationsx->rridata[mid]rridata[mid]>id) /* Mid point is too high */ end=mid?(mid-1):mid; else /* Mid point is correct */ return(mid); } while((end-start)>1); if(relationsx->rridata[start]==id) /* Start is correct */ return(start); if(relationsx->rridata[end]==id) /* End is correct */ return(end); return(NO_RELATION); } /*++++++++++++++++++++++++++++++++++++++ Find a particular route relation index. index_t IndexTurnRelX Returns the index of the turn relation with the specified id. RelationsX *relationsx The set of relations to process. relation_t id The relation id to look for. ++++++++++++++++++++++++++++++++++++++*/ index_t IndexTurnRelX(RelationsX *relationsx,relation_t id) { index_t start=0; index_t end=relationsx->trnumber-1; index_t mid; if(relationsx->trnumber==0) /* There are no route relations */ return(NO_RELATION); if(idtridata[start]) /* Key is before start */ return(NO_RELATION); if(id>relationsx->tridata[end]) /* Key is after end */ return(NO_RELATION); /* Binary search - search key exact match only is required. * * # <- start | Check mid and move start or end if it doesn't match * # | * # | Since an exact match is wanted we can set end=mid-1 * # <- mid | or start=mid+1 because we know that mid doesn't match. * # | * # | Eventually either end=start or end=start+1 and one of * # <- end | start or end is the wanted one. */ do { mid=(start+end)/2; /* Choose mid point */ if(relationsx->tridata[mid]tridata[mid]>id) /* Mid point is too high */ end=mid?(mid-1):mid; else /* Mid point is correct */ return(mid); } while((end-start)>1); if(relationsx->tridata[start]==id) /* Start is correct */ return(start); if(relationsx->tridata[end]==id) /* End is correct */ return(end); return(NO_RELATION); } /*++++++++++++++++++++++++++++++++++++++ Sort the list of relations. RelationsX* relationsx The set of relations to process. ++++++++++++++++++++++++++++++++++++++*/ void SortRelationList(RelationsX* relationsx) { /* Route Relations */ if(relationsx->rrnumber) { index_t rrxnumber; int rrfd; /* Print the start message */ printf_first("Sorting Route Relations"); /* Re-open the file read-only and a new file writeable */ rrfd=ReplaceFileBuffered(relationsx->rrfilename_tmp,&relationsx->rrfd); /* Sort the relations */ rrxnumber=relationsx->rrnumber; relationsx->rrnumber=filesort_vary(relationsx->rrfd,rrfd,NULL, (int (*)(const void*,const void*))sort_route_by_id, (int (*)(void*,index_t))deduplicate_route_by_id); relationsx->rrknumber=relationsx->rrnumber; /* Close the files */ relationsx->rrfd=CloseFileBuffered(relationsx->rrfd); CloseFileBuffered(rrfd); /* Print the final message */ printf_last("Sorted Route Relations: Relations=%"Pindex_t" Duplicates=%"Pindex_t,rrxnumber,rrxnumber-relationsx->rrnumber); } /* Turn Restriction Relations. */ if(relationsx->trnumber) { index_t trxnumber; int trfd; /* Print the start message */ printf_first("Sorting Turn Relations"); /* Re-open the file read-only and a new file writeable */ trfd=ReplaceFileBuffered(relationsx->trfilename_tmp,&relationsx->trfd); /* Sort the relations */ trxnumber=relationsx->trnumber; relationsx->trnumber=filesort_fixed(relationsx->trfd,trfd,sizeof(TurnRelX),NULL, (int (*)(const void*,const void*))sort_turn_by_id, (int (*)(void*,index_t))deduplicate_turn_by_id); relationsx->trknumber=relationsx->trnumber; /* Close the files */ relationsx->trfd=CloseFileBuffered(relationsx->trfd); CloseFileBuffered(trfd); /* Print the final message */ printf_last("Sorted Turn Relations: Relations=%"Pindex_t" Duplicates=%"Pindex_t,trxnumber,trxnumber-relationsx->trnumber); } } /*++++++++++++++++++++++++++++++++++++++ Sort the route relations into id order. int sort_route_by_id Returns the comparison of the id fields. RouteRelX *a The first extended relation. RouteRelX *b The second extended relation. ++++++++++++++++++++++++++++++++++++++*/ static int sort_route_by_id(RouteRelX *a,RouteRelX *b) { relation_t a_id=a->id; relation_t b_id=b->id; if(a_idb_id) return(1); else return(-FILESORT_PRESERVE_ORDER(a,b)); /* latest version first */ } /*++++++++++++++++++++++++++++++++++++++ Deduplicate the route relations using the id after sorting. int deduplicate_route_by_id Return 1 if the value is to be kept, otherwise 0. RouteRelX *relationx The extended relation. index_t index The number of sorted relations that have already been written to the output file. ++++++++++++++++++++++++++++++++++++++*/ static int deduplicate_route_by_id(RouteRelX *relationx,index_t index) { static relation_t previd; /* internal variable (reset by first call in each sort; index==0) */ if(index==0 || relationx->id!=previd) { previd=relationx->id; if(relationx->routes==RELATION_DELETED) return(0); else return(1); } else return(0); } /*++++++++++++++++++++++++++++++++++++++ Sort the turn restriction relations into id order. int sort_turn_by_id Returns the comparison of the id fields. TurnRelX *a The first extended relation. TurnRelX *b The second extended relation. ++++++++++++++++++++++++++++++++++++++*/ static int sort_turn_by_id(TurnRelX *a,TurnRelX *b) { relation_t a_id=a->id; relation_t b_id=b->id; if(a_idb_id) return(1); else return(-FILESORT_PRESERVE_ORDER(a,b)); /* latest version first */ } /*++++++++++++++++++++++++++++++++++++++ Deduplicate the turn restriction relations using the id after sorting. int deduplicate_turn_by_id Return 1 if the value is to be kept, otherwise 0. TurnRelX *relationx The extended relation. index_t index The number of sorted relations that have already been written to the output file. ++++++++++++++++++++++++++++++++++++++*/ static int deduplicate_turn_by_id(TurnRelX *relationx,index_t index) { static relation_t previd; /* internal variable (reset by first call in each sort; index==0) */ if(index==0 || relationx->id!=previd) { previd=relationx->id; if(relationx->except==RELATION_DELETED) return(0); else return(1); } else return(0); } /*++++++++++++++++++++++++++++++++++++++ Process the route relations and apply the information to the ways. RelationsX *relationsx The set of relations to use. WaysX *waysx The set of ways to modify. int keep If set to 1 then keep the old data file otherwise delete it. ++++++++++++++++++++++++++++++++++++++*/ void ProcessRouteRelations(RelationsX *relationsx,WaysX *waysx,int keep) { RouteRelX *unmatched=NULL,*lastunmatched=NULL; int nunmatched=0,lastnunmatched=0,iteration=1; if(waysx->number==0) return; /* Map into memory / open the files */ #if !SLIM waysx->data=MapFileWriteable(waysx->filename_tmp); #else waysx->fd=SlimMapFileWriteable(waysx->filename_tmp); InvalidateWayXCache(waysx->cache); #endif /* Re-open the file read-only */ relationsx->rrfd=ReOpenFileBuffered(relationsx->rrfilename_tmp); /* Read through the file. */ do { int ways=0,relations=0; index_t i; /* Print the start message */ printf_first("Processing Route Relations (%d): Relations=0 Modified Ways=0",iteration); SeekFileBuffered(relationsx->rrfd,0); for(i=0;irrnumber;i++) { FILESORT_VARINT size; RouteRelX relationx; way_t wayid; node_t nodeid; relation_t relationid; transports_t routes=Transports_None; /* Read each route relation */ ReadFileBuffered(relationsx->rrfd,&size,FILESORT_VARSIZE); ReadFileBuffered(relationsx->rrfd,&relationx,sizeof(RouteRelX)); /* Decide what type of route it is */ if(iteration==1) { relations++; routes=relationx.routes; } else { int j; for(j=0;jrrfd,&nodeid,sizeof(node_t)) && nodeid!=NO_NODE_ID) ; /* Loop through the ways */ while(!ReadFileBuffered(relationsx->rrfd,&wayid,sizeof(way_t)) && wayid!=NO_WAY_ID) { /* Update the ways that are listed for the relation */ if(routes) { index_t way=IndexWayX(waysx,wayid); if(way!=NO_WAY) { WayX *wayx=LookupWayX(waysx,way,1); if(routes&Transports_Foot) { if(!(wayx->way.allow&Transports_Foot)) { logerror("Route Relation %"Prelation_t" for Foot contains Way %"Pway_t" that does not allow Foot transport; overriding.\n",logerror_relation(relationx.id),logerror_way(wayid)); wayx->way.allow|=Transports_Foot; } wayx->way.props|=Properties_FootRoute; } if(routes&Transports_Bicycle) { if(!(wayx->way.allow&Transports_Bicycle)) { logerror("Route Relation %"Prelation_t" for Bicycle contains Way %"Pway_t" that does not allow Bicycle transport; overriding.\n",logerror_relation(relationx.id),logerror_way(wayid)); wayx->way.allow|=Transports_Bicycle; } wayx->way.props|=Properties_BicycleRoute; } PutBackWayX(waysx,wayx); ways++; } else logerror("Route Relation %"Prelation_t" contains Way %"Pway_t" that does not exist in the Routino database (not a highway?).\n",logerror_relation(relationx.id),logerror_way(wayid)); } } /* Loop through the relations */ while(!ReadFileBuffered(relationsx->rrfd,&relationid,sizeof(relation_t)) && relationid!=NO_RELATION_ID) { /* Add the relations that are listed for this relation to the list for next time */ if(relationid==relationx.id) logerror("Relation %"Prelation_t" contains itself.\n",logerror_relation(relationx.id)); else if(routes) { if(nunmatched%256==0) unmatched=(RouteRelX*)realloc((void*)unmatched,(nunmatched+256)*sizeof(RouteRelX)); unmatched[nunmatched].id=relationid; unmatched[nunmatched].routes=routes; nunmatched++; } } if(!((i+1)%1000)) printf_middle("Processing Route Relations (%d): Relations=%"Pindex_t" Modified Ways=%"Pindex_t,iteration,relations,ways); } if(lastunmatched) free(lastunmatched); lastunmatched=unmatched; lastnunmatched=nunmatched; unmatched=NULL; nunmatched=0; /* Print the final message */ printf_last("Processed Route Relations (%d): Relations=%"Pindex_t" Modified Ways=%"Pindex_t,iteration,relations,ways); } while(lastnunmatched && iteration++<8); if(lastunmatched) free(lastunmatched); /* Close the file */ relationsx->rrfd=CloseFileBuffered(relationsx->rrfd); if(keep) RenameFile(relationsx->rrfilename_tmp,relationsx->rrfilename); /* Unmap from memory / close the files */ #if !SLIM waysx->data=UnmapFile(waysx->data); #else waysx->fd=SlimUnmapFile(waysx->fd); #endif } /*++++++++++++++++++++++++++++++++++++++ Process the turn relations to update them with node/segment information. RelationsX *relationsx The set of relations to modify. NodesX *nodesx The set of nodes to use. SegmentsX *segmentsx The set of segments to use. WaysX *waysx The set of ways to use. int keep If set to 1 then keep the old data file otherwise delete it. ++++++++++++++++++++++++++++++++++++++*/ void ProcessTurnRelations(RelationsX *relationsx,NodesX *nodesx,SegmentsX *segmentsx,WaysX *waysx,int keep) { int trfd; index_t i,total=0,deleted=0; if(nodesx->number==0 || segmentsx->number==0) return; /* Print the start message */ printf_first("Processing Turn Relations: Relations=0 Deleted=0 Added=0"); /* Map into memory / open the files */ #if !SLIM nodesx->data=MapFileWriteable(nodesx->filename_tmp); segmentsx->data=MapFile(segmentsx->filename_tmp); waysx->data=MapFile(waysx->filename_tmp); #else nodesx->fd=SlimMapFileWriteable(nodesx->filename_tmp); segmentsx->fd=SlimMapFile(segmentsx->filename_tmp); waysx->fd=SlimMapFile(waysx->filename_tmp); InvalidateNodeXCache(nodesx->cache); InvalidateSegmentXCache(segmentsx->cache); InvalidateWayXCache(waysx->cache); #endif /* Re-open the file read-only and a new file writeable */ if(keep) { RenameFile(relationsx->trfilename_tmp,relationsx->trfilename); relationsx->trfd=ReOpenFileBuffered(relationsx->trfilename); trfd=OpenFileBufferedNew(relationsx->trfilename_tmp); } else trfd=ReplaceFileBuffered(relationsx->trfilename_tmp,&relationsx->trfd); /* Process all of the relations */ for(i=0;itrnumber;i++) { TurnRelX relationx; NodeX *nodex; SegmentX *segmentx; index_t via,from,to; ReadFileBuffered(relationsx->trfd,&relationx,sizeof(TurnRelX)); via =IndexNodeX(nodesx,relationx.via); from=IndexWayX(waysx,relationx.from); to =IndexWayX(waysx,relationx.to); if(via==NO_NODE) { logerror("Turn Relation %"Prelation_t" contains Node %"Pnode_t" that does not exist in the Routino database (not a highway node?).\n",logerror_relation(relationx.id),logerror_node(relationx.via)); deleted++; goto endloop; } if(from==NO_WAY) { logerror("Turn Relation %"Prelation_t" contains Way %"Pway_t" that does not exist in the Routino database (not a highway?).\n",logerror_relation(relationx.id),logerror_way(relationx.from)); deleted++; goto endloop; } if(to==NO_WAY) { logerror("Turn Relation %"Prelation_t" contains Way %"Pway_t" that does not exist in the Routino database (not a highway?).\n",logerror_relation(relationx.id),logerror_way(relationx.to)); deleted++; goto endloop; } relationx.via =via; relationx.from=from; relationx.to =to; if(relationx.restriction==TurnRestrict_no_right_turn || relationx.restriction==TurnRestrict_no_left_turn || relationx.restriction==TurnRestrict_no_u_turn || relationx.restriction==TurnRestrict_no_straight_on) { index_t node_from=NO_NODE,node_to=NO_NODE; int oneway_from=0,oneway_to=0,vehicles_from=1,vehicles_to=1; /* Find the segments that join the node 'via' */ segmentx=FirstSegmentX(segmentsx,relationx.via,1); while(segmentx) { if(segmentx->way==relationx.from) { WayX *wayx=LookupWayX(waysx,segmentx->way,1); if(node_from!=NO_NODE) /* Only one segment can be on the 'from' way */ { logerror("Turn Relation %"Prelation_t" is not stored because the 'via' node is not at the end of the 'from' way.\n",logerror_relation(relationx.id)); deleted++; goto endloop; } node_from=OtherNode(segmentx,relationx.via); if(IsOnewayFrom(segmentx,relationx.via)) oneway_from=1; /* not allowed */ if(!(wayx->way.allow&(Transports_Bicycle|Transports_Moped|Transports_Motorcycle|Transports_Motorcar|Transports_Goods|Transports_HGV|Transports_PSV))) vehicles_from=0; /* not allowed */ } if(segmentx->way==relationx.to) { WayX *wayx=LookupWayX(waysx,segmentx->way,1); if(node_to!=NO_NODE) /* Only one segment can be on the 'to' way */ { logerror("Turn Relation %"Prelation_t" is not stored because the 'via' node is not at the end of the 'to' way.\n",logerror_relation(relationx.id)); deleted++; goto endloop; } node_to=OtherNode(segmentx,relationx.via); if(IsOnewayTo(segmentx,relationx.via)) oneway_to=1; /* not allowed */ if(!(wayx->way.allow&(Transports_Bicycle|Transports_Moped|Transports_Motorcycle|Transports_Motorcar|Transports_Goods|Transports_HGV|Transports_PSV))) vehicles_to=0; /* not allowed */ } segmentx=NextSegmentX(segmentsx,segmentx,relationx.via); } if(node_from==NO_NODE) logerror("Turn Relation %"Prelation_t" is not stored because the 'via' node is not part of the 'from' way.\n",logerror_relation(relationx.id)); if(node_to==NO_NODE) logerror("Turn Relation %"Prelation_t" is not stored because the 'via' node is not part of the 'to' way.\n",logerror_relation(relationx.id)); if(oneway_from) logerror("Turn Relation %"Prelation_t" is not needed because the 'from' way is oneway away from the 'via' node.\n",logerror_relation(relationx.id)); if(oneway_to) logerror("Turn Relation %"Prelation_t" is not needed because the 'to' way is oneway towards the 'via' node.\n",logerror_relation(relationx.id)); if(!vehicles_from) logerror("Turn Relation %"Prelation_t" is not needed because the 'from' way does not allow vehicles.\n",logerror_relation(relationx.id)); if(!vehicles_to) logerror("Turn Relation %"Prelation_t" is not needed because the 'to' way does not allow vehicles.\n",logerror_relation(relationx.id)); if(oneway_from || oneway_to || !vehicles_from || !vehicles_to || node_from==NO_NODE || node_to==NO_NODE) { deleted++; goto endloop; } /* Write the results */ relationx.from=node_from; relationx.to =node_to; WriteFileBuffered(trfd,&relationx,sizeof(TurnRelX)); total++; } else { index_t node_from=NO_NODE,node_to=NO_NODE,node_other[MAX_SEG_PER_NODE]; int nnodes_other=0,i; int oneway_from=0,vehicles_from=1; /* Find the segments that join the node 'via' */ segmentx=FirstSegmentX(segmentsx,relationx.via,1); while(segmentx) { if(segmentx->way==relationx.from) { WayX *wayx=LookupWayX(waysx,segmentx->way,1); if(node_from!=NO_NODE) /* Only one segment can be on the 'from' way */ { logerror("Turn Relation %"Prelation_t" is not stored because the 'via' node is not at the end of the 'from' way.\n",logerror_relation(relationx.id)); deleted++; goto endloop; } node_from=OtherNode(segmentx,relationx.via); if(IsOnewayFrom(segmentx,relationx.via)) oneway_from=1; /* not allowed */ if(!(wayx->way.allow&(Transports_Bicycle|Transports_Moped|Transports_Motorcycle|Transports_Motorcar|Transports_Goods|Transports_HGV|Transports_PSV))) vehicles_from=0; /* not allowed */ } if(segmentx->way==relationx.to) { if(node_to!=NO_NODE) /* Only one segment can be on the 'to' way */ { logerror("Turn Relation %"Prelation_t" is not stored because the 'via' node is not at the end of the 'to' way.\n",logerror_relation(relationx.id)); deleted++; goto endloop; } node_to=OtherNode(segmentx,relationx.via); } if(segmentx->way!=relationx.from && segmentx->way!=relationx.to) { WayX *wayx=LookupWayX(waysx,segmentx->way,1); if(IsOnewayTo(segmentx,relationx.via)) ; /* not allowed */ else if(!(wayx->way.allow&(Transports_Bicycle|Transports_Moped|Transports_Motorcycle|Transports_Motorcar|Transports_Goods|Transports_HGV|Transports_PSV))) ; /* not allowed */ else { logassert(nnodes_otherflags|=NODE_TURNRSTRCT; PutBackNodeX(nodesx,nodex); segmentx=FirstSegmentX(segmentsx,relationx.via,1); while(segmentx) { index_t othernode=OtherNode(segmentx,relationx.via); nodex=LookupNodeX(nodesx,othernode,1); nodex->flags|=NODE_TURNRSTRCT2; PutBackNodeX(nodesx,nodex); segmentx=NextSegmentX(segmentsx,segmentx,relationx.via); } endloop: if(!((i+1)%1000)) printf_middle("Processing Turn Relations: Relations=%"Pindex_t" Deleted=%"Pindex_t" Added=%"Pindex_t,i+1,deleted,total-relationsx->trnumber+deleted); } /* Close the files */ relationsx->trfd=CloseFileBuffered(relationsx->trfd); CloseFileBuffered(trfd); /* Free the now-unneeded indexes */ log_free(nodesx->idata); free(nodesx->idata); nodesx->idata=NULL; log_free(waysx->idata); free(waysx->idata); waysx->idata=NULL; log_free(segmentsx->firstnode); free(segmentsx->firstnode); segmentsx->firstnode=NULL; /* Unmap from memory / close the files */ #if !SLIM nodesx->data=UnmapFile(nodesx->data); segmentsx->data=UnmapFile(segmentsx->data); waysx->data=UnmapFile(waysx->data); #else nodesx->fd=SlimUnmapFile(nodesx->fd); segmentsx->fd=SlimUnmapFile(segmentsx->fd); waysx->fd=SlimUnmapFile(waysx->fd); #endif /* Print the final message */ printf_last("Processed Turn Relations: Relations=%"Pindex_t" Deleted=%"Pindex_t" Added=%"Pindex_t,total,deleted,total-relationsx->trnumber+deleted); relationsx->trnumber=total; } /*++++++++++++++++++++++++++++++++++++++ Remove pruned turn relations and update the node indexes after pruning nodes. RelationsX *relationsx The set of relations to modify. NodesX *nodesx The set of nodes to use. ++++++++++++++++++++++++++++++++++++++*/ void RemovePrunedTurnRelations(RelationsX *relationsx,NodesX *nodesx) { TurnRelX relationx; index_t total=0,pruned=0,notpruned=0; int trfd; if(relationsx->trnumber==0) return; /* Print the start message */ printf_first("Deleting Pruned Turn Relations: Relations=0 Pruned=0"); /* Re-open the file read-only and a new file writeable */ trfd=ReplaceFileBuffered(relationsx->trfilename_tmp,&relationsx->trfd); /* Process all of the relations */ while(!ReadFileBuffered(relationsx->trfd,&relationx,sizeof(TurnRelX))) { relationx.from=nodesx->pdata[relationx.from]; relationx.via =nodesx->pdata[relationx.via]; relationx.to =nodesx->pdata[relationx.to]; if(relationx.from==NO_NODE || relationx.via==NO_NODE || relationx.to==NO_NODE) pruned++; else { WriteFileBuffered(trfd,&relationx,sizeof(TurnRelX)); notpruned++; } total++; if(!(total%1000)) printf_middle("Deleting Pruned Turn Relations: Relations=%"Pindex_t" Pruned=%"Pindex_t,total,pruned); } relationsx->trnumber=notpruned; /* Close the files */ relationsx->trfd=CloseFileBuffered(relationsx->trfd); CloseFileBuffered(trfd); /* Print the final message */ printf_last("Deleted Pruned Turn Relations: Relations=%"Pindex_t" Pruned=%"Pindex_t,total,pruned); } /*++++++++++++++++++++++++++++++++++++++ Sort the turn relations geographically after updating the node indexes. RelationsX *relationsx The set of relations to modify. NodesX *nodesx The set of nodes to use. SegmentsX *segmentsx The set of segments to use. int convert Set to 1 to convert the segments as well as sorting them (the second time it is called). ++++++++++++++++++++++++++++++++++++++*/ void SortTurnRelationListGeographically(RelationsX *relationsx,NodesX *nodesx,SegmentsX *segmentsx,int convert) { int trfd; if(segmentsx->number==0) return; /* Print the start message */ printf_first("Sorting Turn Relations Geographically"); /* Map into memory / open the files */ #if !SLIM segmentsx->data=MapFile(segmentsx->filename_tmp); #else segmentsx->fd=SlimMapFile(segmentsx->filename_tmp); InvalidateSegmentXCache(segmentsx->cache); #endif /* Re-open the file read-only and a new file writeable */ trfd=ReplaceFileBuffered(relationsx->trfilename_tmp,&relationsx->trfd); /* Update the segments with geographically sorted node indexes and sort them */ sortnodesx=nodesx; sortsegmentsx=segmentsx; if(!convert) filesort_fixed(relationsx->trfd,trfd,sizeof(TurnRelX),(int (*)(void*,index_t))geographically_index, (int (*)(const void*,const void*))sort_by_via, NULL); else filesort_fixed(relationsx->trfd,trfd,sizeof(TurnRelX),(int (*)(void*,index_t))geographically_index_convert_segments, (int (*)(const void*,const void*))sort_by_via, NULL); /* Close the files */ relationsx->trfd=CloseFileBuffered(relationsx->trfd); CloseFileBuffered(trfd); /* Unmap from memory / close the files */ #if !SLIM segmentsx->data=UnmapFile(segmentsx->data); #else segmentsx->fd=SlimUnmapFile(segmentsx->fd); #endif /* Free the memory */ if(nodesx->gdata) { log_free(nodesx->gdata); free(nodesx->gdata); nodesx->gdata=NULL; } /* Print the final message */ printf_last("Sorted Turn Relations Geographically: Turn Relations=%"Pindex_t,relationsx->trnumber); } /*++++++++++++++++++++++++++++++++++++++ Update the turn relation indexes. int geographically_index Return 1 if the value is to be kept, otherwise 0. TurnRelX *relationx The extended turn relation. index_t index The number of unsorted turn relations that have been read from the input file. ++++++++++++++++++++++++++++++++++++++*/ static int geographically_index(TurnRelX *relationx,index_t index) { relationx->from=sortnodesx->gdata[relationx->from]; relationx->via =sortnodesx->gdata[relationx->via]; relationx->to =sortnodesx->gdata[relationx->to]; return(1); } /*++++++++++++++++++++++++++++++++++++++ Update the turn relation indexes and replace them with segments. int geographically_index_convert_segments Return 1 if the value is to be kept, otherwise 0. TurnRelX *relationx The extended turn relation. index_t index The number of unsorted turn relations that have been read from the input file. ++++++++++++++++++++++++++++++++++++++*/ static int geographically_index_convert_segments(TurnRelX *relationx,index_t index) { SegmentX *segmentx; index_t from_node,via_node,to_node; from_node=sortnodesx->gdata[relationx->from]; via_node =sortnodesx->gdata[relationx->via]; to_node =sortnodesx->gdata[relationx->to]; segmentx=FirstSegmentX(sortsegmentsx,via_node,1); do { if(OtherNode(segmentx,via_node)==from_node) relationx->from=IndexSegmentX(sortsegmentsx,segmentx); if(OtherNode(segmentx,via_node)==to_node) relationx->to=IndexSegmentX(sortsegmentsx,segmentx); segmentx=NextSegmentX(sortsegmentsx,segmentx,via_node); } while(segmentx); relationx->via=via_node; return(1); } /*++++++++++++++++++++++++++++++++++++++ Sort the turn restriction relations into via index order (then by from and to segments). int sort_by_via Returns the comparison of the via, from and to fields. TurnRelX *a The first extended relation. TurnRelX *b The second extended relation. ++++++++++++++++++++++++++++++++++++++*/ static int sort_by_via(TurnRelX *a,TurnRelX *b) { index_t a_id=a->via; index_t b_id=b->via; if(a_idb_id) return(1); else { index_t a_id=a->from; index_t b_id=b->from; if(a_idb_id) return(1); else { index_t a_id=a->to; index_t b_id=b->to; if(a_idb_id) return(1); else return(FILESORT_PRESERVE_ORDER(a,b)); } } } /*++++++++++++++++++++++++++++++++++++++ Save the relation list to a file. RelationsX* relationsx The set of relations to save. const char *filename The name of the file to save. ++++++++++++++++++++++++++++++++++++++*/ void SaveRelationList(RelationsX* relationsx,const char *filename) { index_t i; int fd; RelationsFile relationsfile={0}; /* Print the start message */ printf_first("Writing Relations: Turn Relations=0"); /* Re-open the file read-only */ relationsx->trfd=ReOpenFileBuffered(relationsx->trfilename_tmp); /* Write out the relations data */ fd=OpenFileBufferedNew(filename); SeekFileBuffered(fd,sizeof(RelationsFile)); for(i=0;itrnumber;i++) { TurnRelX relationx; TurnRelation relation={0}; ReadFileBuffered(relationsx->trfd,&relationx,sizeof(TurnRelX)); relation.from=relationx.from; relation.via=relationx.via; relation.to=relationx.to; relation.except=relationx.except; WriteFileBuffered(fd,&relation,sizeof(TurnRelation)); if(!((i+1)%1000)) printf_middle("Writing Relations: Turn Relations=%"Pindex_t,i+1); } /* Write out the header structure */ relationsfile.trnumber=relationsx->trnumber; SeekFileBuffered(fd,0); WriteFileBuffered(fd,&relationsfile,sizeof(RelationsFile)); CloseFileBuffered(fd); /* Close the file */ relationsx->trfd=CloseFileBuffered(relationsx->trfd); /* Print the final message */ printf_last("Wrote Relations: Turn Relations=%"Pindex_t,relationsx->trnumber); } routino-3.0/src/uncompress.h 644 233 144 2131 12302106364 11353 0/*************************************** Function prototypes for file uncompression. Part of the Routino routing software. ******************/ /****************** This file Copyright 2012-2014 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #ifndef UNCOMPRESS_H #define UNCOMPRESS_H /*+ To stop multiple inclusions. +*/ int Uncompress_Bzip2(int filefd); int Uncompress_Gzip(int filefd); int Uncompress_Xz(int filefd); #endif /* UNCOMPRESS_H */ routino-3.0/doc/ 40755 233 144 0 12575035327 6765 5routino-3.0/doc/USAGE.txt 644 233 144 64255 12574076067 10447 0 Routino : Usage =============== There are five programs that make up this software. The first one takes the planet.osm datafile from OpenStreetMap (or other source of data using the same formats) and converts it into a local database. The second program uses the database to determine an optimum route between two points. The third program allows visualisation of the data and statistics to be extracted. The fourth program allows dumping the raw parsed data for test purposes and the fifth is a test program for the tag transformations. planetsplitter -------------- This program reads in the OSM format XML file and splits it up to create the database that is used for routing. Usage: planetsplitter [--version] [--help] [--dir=] [--prefix=] [--sort-ram-size=] [--sort-threads=] [--tmpdir=] [--tagging=] [--loggable] [--logtime] [--logmemory] [--errorlog[=]] [--parse-only | --process-only] [--append] [--keep] [--changes] [--max-iterations=] [--prune-none] [--prune-isolated=] [--prune-short=] [--prune-straight=] [ ... | ... | ... | ... | ... | ... | ... | ...] --version Print the version of Routino. --help Prints out the help information. --dir= Sets the directory name in which to save the results. Defaults to the current directory. --prefix= Sets the filename prefix for the files that are created. Defaults to no prefix. --sort-ram-size= Specifies the amount of RAM (in MB) to use for sorting the data. If not specified then 64 MB will be used in slim mode or 256 MB otherwise. --sort-threads= The number of threads to use for data sorting (the sorting memory is shared between the threads - too many threads and not enough memory will reduce the performance). --tmpdir= Specifies the name of the directory to store the temporary disk files. If not specified then it defaults to either the value of the --dir option or the current directory. --tagging= Sets the filename containing the list of tagging rules in XML format for the parsing the input files. If the file doesn't exist then dirname, prefix and "profiles.xml" will be combined and used, if that doesn't exist then the file '/usr/local/share/routino/profiles.xml' (or custom installation location) will be used. --loggable Print progress messages that are suitable for logging to a file; normally an incrementing counter is printed which is more suitable for real-time display than logging. --logtime Print the elapsed time for each processing step (minutes, seconds and milliseconds). --logmemory Print the maximum allocated and mapped memory for each processing step (MBytes). --errorlog[=] Log OSM parsing and processing errors to 'error.log' or the specified file name (the '--dir' and '--prefix' options are applied). If the --append option is used then the existing log file will be appended, otherwise a new one will be created. If the --keep option is also used a geographically searchable database of error logs is created for use in the visualiser. --parse-only Parse the input files and store the data in intermediate files but don't process the data into a routing database. This option must be used with the --append option for all except the first file. --process-only Don't read in any files but process the existing intermediate files created by using the --parse-only option. --append Parse the input file and append the result to the existing intermediate files; the appended file can be either an OSM file or an OSC change file. --keep Store a set of intermediate files after parsing the OSM files, sorting and removing duplicates; this allows appending an OSC file and re-processing later. --changes This option indicates that the data being processed contains one or more OSC (OSM changes) files, they must be applied in time sequence if more than one is used. This option implies --append when parsing data files and --keep when processing data. --max-iterations= The maximum number of iterations to use when generating super-nodes and super-segments. Defaults to 5 which is normally enough. --prune-none Disable the prune options below, they can be re-enabled by adding them to the command line after this option. --prune-isolated= Remove the access permissions for a transport type from small disconnected groups of segments and remove the segments if they end up with no access permission (defaults to removing groups under 500m). --prune-short= Remove short segments (defaults to removing segments up to a maximum length of 5m). --prune-straight= Remove nodes in almost straight highways (defaults to removing nodes up to 3m offset from a straight line). , , , , Specifies the filename(s) to read data from. Filenames ending '.pbf' will be read as PBF, filenames ending in '.o5m' or '.o5c' will be read as O5M/O5C, otherwise as XML. Filenames ending '.bz2' will be bzip2 uncompressed (if bzip2 support compiled in). Filenames ending '.gz' will be gzip uncompressed (if gzip support compiled in). Filenames ending '.xz' will be xz uncompressed (if xz support compiled in). Note: In version 2.5 of Routino the ability to read data from the standard input has been removed. This is because there is now the ability to read compressed files (bzip2, gzip, xz) and PBF files directly. Also using standard input the file type cannot be auto-detected from the filename. Example usage 1: planetsplitter --dir=data --prefix=gb great_britain.osm This will generate the output files 'data/gb-nodes.mem', 'data/gb-segments.mem' and 'data/gb-ways.mem'. Multiple filenames can be specified on the command line and they will all be read in, combined and processed together. Example usage 2: planetsplitter --dir=data --prefix=gb --parse-only great_britain_part1.osm planetsplitter --dir=data --prefix=gb --parse-only --append great_britain_part2.osm planetsplitter --dir=data --prefix=gb --parse-only --append ... planetsplitter --dir=data --prefix=gb --process-only This will generate the same output files as the first example but parsing the input files is performed separately from the data processing. The first file read in must not use the --append option but the later ones must. Example usage 3: planetsplitter --dir=data --prefix=gb --keep great_britain.osm planetsplitter --dir=data --prefix=gb --changes great_britain.osc This will generate the same output files as the first example. The first command will process the complete file and keep some intermediate data for later. The second command will apply a set of changes to the stored intermediate data and keep the updated intermediate files for repeating this step later with more change data. The parsing and processing can be split into multiple commands as it was in example 2 with the --keep option used with --process-only for the initial OSM file(s) and the --changes option used with --parse-only or --process-only for every OSC file. router ------ This program performs the calculation of the optimum routes using the database generated by the planetsplitter program. Usage: router [--version] [--help | --help-profile | --help-profile-xml | --help-profile-json | --help-profile-perl ] [--dir=] [--prefix=] [--profiles=] [--translations=] [--exact-nodes-only] [--quiet | [--loggable] [--logtime] [--logmemory]] [--output-html] [--output-gpx-track] [--output-gpx-route] [--output-text] [--output-text-all] [--output-none] [--output-stdout] [--profile=] [--transport=] [--shortest | --quickest] --lon1= --lat1= --lon2= --lon2= [ ... --lon99= --lon99=] [--reverse] [--loop] [--heading=] [--highway-= ...] [--speed-= ...] [--property-= ...] [--oneway=(0|1)] [--turns=(0|1)] [--weight=] [--height=] [--width=] [--length=] --version Print the version of Routino. --help Prints out the help information. --help-profile Prints out the selected transport profile (type, speed limits, highway preferences etc.) --help-profile-xml Prints out all the loaded profiles as an XML file in the same format that can be loaded in. --help-profile-json Prints out all the loaded profiles in JavaScript Object Notation (JSON) format for use in the interactive webpage. --help-profile-perl Prints out all the loaded profiles as a Perl object for use in the router CGI. --dir= Sets the directory name in which to read the local database. Defaults to the current directory. --prefix= Sets the filename prefix for the files in the local database. Defaults to no prefix. --profiles= Sets the filename containing the list of routing profiles in XML format. If the file doesn't exist then dirname, prefix and "profiles.xml" will be combined and used, if that doesn't exist then the file '/usr/local/share/routino/profiles.xml' (or custom installation location) will be used. --translations= Sets the filename containing the list of translations in XML format for the output files. If the file doesn't exist then dirname, prefix and "translations.xml" will be combined and used, if that doesn't exist then the file '/usr/local/share/routino/translations.xml' (or custom installation location) will be used. --exact-nodes-only When processing the specified latitude and longitude points only select the nearest node instead of finding the nearest point within a segment (quicker but less accurate unless the points are already near nodes). --quiet Don't generate any screen output while running (useful for running in a script). --loggable Print progress messages that are suitable for logging to a file; normally an incrementing counter is printed which is more suitable for real-time display than logging. --logtime Print the elapsed time for each processing step (minutes, seconds and milliseconds). --logmemory Print the maximum allocated and mapped memory for each processing step (MBytes). --language= Select the language specified from the file of translations. If this option is not given and the file exists then the first language in the file will be used. If this option is not given and no file exists the compiled-in default language (English) will be used. --output-html --output-gpx-track --output-gpx-route --output-text --output-text-all Generate the selected output file formats (HTML, GPX track file, GPX route file, plain text route and/or plain text with all nodes). If no output is specified then all are generated, specifying any automatically disables those not specified. --output-none Do not generate any output or read in any translations files. --output-stdout Write to stdout instead of a file (requires exactly one output format option, implies '--quiet'). --profile= Specifies the name of the profile to use. --transport= Select the type of transport to use, can be set to: + foot = Foot + horse = Horse + wheelchair = Wheelchair + bicycle = Bicycle + moped = Moped (Small motorcycle, limited speed) + motorcycle = Motorcycle + motorcar = Motorcar + goods = Goods (Small lorry, van) + hgv = HGV (Heavy Goods Vehicle - large lorry) + psv = PSV (Public Service Vehicle - bus, coach) Defaults to 'motorcar', this option also selects the default profile information if the '--profile' option is not given and a profile matching the transport name is found. --shortest Find the shortest route between the waypoints. --quickest Find the quickest route between the waypoints. --lon1=, --lat1= --lon2=, --lat2= ... --lon99=, --lat99= The location of the waypoints that make up the start, middle and end points of the route. Up to 99 waypoints can be specified and the route will pass through each of the specified ones in sequence. The algorithm will use the closest node or point within a segment that allows the specified traffic type. --reverse Find a route between the waypoints in reverse order. --loop Find a route that returns to the first waypoint after the last one. --heading= Specifies the initial direction of travel at the start of the route (from the lowest numbered waypoint) as a compass bearing from 0 to 360 degrees. --highway-= Selects the percentage preference for using each particular type of highway. The value of can be selected from: + motorway = Motorway + trunk = Trunk + primary = Primary + secondary = Secondary + tertiary = Tertiary + unclassified = Unclassified + residential = Residential + service = Service + track = Track + cycleway = Cycleway + path = Path + steps = Steps + ferry = Ferry Default value depends on the profile selected by the --transport option. --speed-= Selects the speed limit in km/hour for each type of highway. Default value depends on the profile selected by the --transport option. --property-= Selects the percentage preference for using each particular highway property The value of can be selected from: + paved = Paved (suitable for normal wheels) + multilane = Multiple lanes + bridge = Bridge + tunnel = Tunnel + footroute = A route marked for foot travel + bicycleroute = A route marked for bicycle travel Default value depends on the profile selected by the --transport option. --oneway=[0|1] Selects if the direction of oneway streets are to be obeyed (useful to not obey them when walking). Default value depends on the profile selected by the --transport option. --turns=[0|1] Selects if turn restrictions are to be obeyed (useful to not obey them when walking). Default value depends on the profile selected by the --transport option. --weight= Specifies the weight of the mode of transport in tonnes; ensures that the weight limit on the highway is not exceeded. Default value depends on the profile selected by the --transport option. --height= Specifies the height of the mode of transport in metres; ensures that the height limit on the highway is not exceeded. Default value depends on the profile selected by the --transport option. --width= Specifies the width of the mode of transport in metres; ensures that the width limit on the highway is not exceeded. Default value depends on the profile selected by the --transport option. --length= Specifies the length of the mode of transport in metres; ensures that the length limit on the highway is not exceeded. Default value depends on the profile selected by the --transport option. The meaning of the parameter in the command line options is slightly different for the highway preferences and the property preferences. For the highway preference consider the choice between two possible highways between the start and finish when looking for the shortest route. If highway A has a preference of 100% and highway B has a preference of 90% then highway A will be chosen even if it is up to 11% longer (100/90 = 111%). For the highway properties each highway either has a particular property or not. If the preference for the property is 60% then a highway with the property has a preference of 77% (sqrt(60%)) and one without has a preference of 63% (sqrt(100-60%)). A highway with the property will be chosen even if it is up to 22% longer than one without the property (77/63 = 122%). The overall preference for each highway segment is the product of the preference for the highway type and all of the preferences for the highway properties. Example usage (motorcycle journey, scenic route, not very fast): router --dir=data --prefix=gb --transport=motorcycle --highway-motorway=0 \ --highway-trunk=0 --speed-primary=80 --speed-secondary=80 --quickest This will use the files 'data/gb-nodes.mem', 'data/gb-segments.mem' and 'data/gb-ways.mem' to find the quickest route by motorcycle not using motorways or trunk roads and not exceeding 80 km/hr. filedumper ---------- This program is used to extract statistics from the database, extract particular information for visualisation purposes or for dumping the database contents. Usage: filedumper [--version] [--help] [--dir=] [--prefix=] [--statistics] [--visualiser --latmin= --latmax= --lonmin= --lonmax= --data=] [--dump [--node= ...] [--segment= ...] [--way= ...] [--turn-relation= ...] [--errorlog= ...]] [--dump-osm [--no-super] [--latmin= --latmax= --lonmin= --lonmax=]] [--dump-visualiser [--data=node] [--data=segment] [--data=turn-relation] [--data=errorlog]] --version Print the version of Routino. --help Prints out the help information. --dir= Sets the directory name in which to read the local database. Defaults to the current directory. --prefix= Sets the filename prefix for the files in the local database. --statistics Prints out statistics about the database files. --visualiser Selects a data visualiser mode which will output a set of data according to the other parameters below. --latmin= --latmax= The range of latitudes to print the data for. --lonmin= --lonmax= The range of longitudes to print the data for. --data= The type of data to output, can be selected from: o junctions = segment count at each junction. o super = super-node and super-segments. o waytype-* = segments of oneway, cyclebothways or roundabout type. o highway-* = segments of the specified highway type (e.g. highway-primary to display segments ofprimary roads). o transport-* = segments allowing the specified transport type (e.g. transport-foot to display segments accessible on foot). o turns = turn restrictions. o speed = speed limits. o weight = weight limits. o height = height limits. o width = width limits. o length = length limits. o property-* = segments having the specified property (e.g. property-paved to display segments of paved highway). o errorlogs = errors logged during parsing. --dump Selects a data dumping mode which allows looking at individual items in the databases (specifying 'all' instead of a number dumps all of them). More than one of the following parameters can be specified on the command line. --node= Prints the information about the selected node number (internal number, not the node id number in the original source file). --segment= Prints the information about the selected segment number. --way= Prints the information about the selected way number (internal number, not the way id number in the original source file). --turn-relation= Prints the information about the selected turn relation number (internal number, not the relation id number in the original source file). --errorlog= Prints the information about the selected error log that was stored when the data was parsed. --osm-dump Dumps the contents of the database as an OSM format XML file, the whole database will be dumped unless the latitude and longitude ranges are specified. --no-super The super segments will not be output. --latmin= --latmax= The range of latitudes to dump the data for. --lonmin= --lonmax= The range of longitudes to dump the data for. --dump-visualiser Dumps the contents of the database as HTML formatted items for display in the visualiser web page. --data=node Prints the information about the selected node number (internal node number, not from the original source file). --data=segment Prints the information about the selected segment number as if it was a way (internal segment number, unrelated to original source file). --data=turn-relation Prints the information about the selected turn relation number (internal turn relation number, not from the original source file). --data=errorlog Prints the information about the selected error log that was stored when the data was parsed. filedumperx ----------- This program is a modified version of filedumper that will dump out the contents of the intermediate data that is saved by planetsplitter after processing using the --keep or --changes option. This is intended for test purposes only and gives no useful information about the routing database. Usage: filedumperx [--version] [--help] [--dir=] [--prefix=] [--dump [--nodes] [--ways] [--route-relations] [--turn-relations]] --version Print the version of Routino. --help Prints out the help information. --dir= Sets the directory name in which to read the local database. Defaults to the current directory. --prefix= Sets the filename prefix for the files in the local database. --dump Dumps the complete set of data in the intermediate files that are written by planetsplitter using the --keep or --changes options. --nodes Dumps the node data. --ways Dumps the way data. --route-relations Dumps the route relation data. --turn-relations Dumps the turn relation data. -------- Copyright 2008-2015 Andrew M. Bishop. routino-3.0/doc/NEWS.txt 644 233 144 101315 12575035327 10357 0Version 3.0 of Routino released : Sat Sep 12 2015 ------------------------------------------------- Bug fixes: Use a single definition of MAX_SEG_PER_NODE to avoid confusion. Fix bug with built-in translation strings if no XML translations available. Fix bug with makefiles related to creating new translations. Remove some pthread code that was still there when compiling without pthreads. Fix a use-after-free memory error and use of uninitialised allocated memory. Ensure that allocated strings are long enough for temporary filenames. Programs: Add a '--version' option to all of the programs. Source Code: Various C language cleanups including using '-pedantic' compiler option. Various changes to allow compiling with Microsoft Visual Studio C compiler. Various changes to allow compiling with MinGW or Cygwin on Microsoft Windows. Makefile updates: 'make clean' = release, 'make distclean' = SVN repository. API: Create a library API that can perform routing functions. OSM tagging: Remove cycle_barrier and bicycle_barrier since they do not block bicycles. Translations: Updated Dutch and German translations. Added Hungarian and Polish translations provided through translation web page. Documentation: Add meta tags to HTML to help mobile devices, tidy up the CSS. Create instructions for compiling on Microsoft Windows. Create API description for Routino library usage. Web pages: Allow drag-and-drop of waypoints within the list and onto the map. Note: This version is compatible with databases from versions 2.7.1 - 2.7.3. Version 2.7.3 of Routino released : Sat Nov 8 2014 -------------------------------------------------- Bug fixes: Limit the property preference ratio to 100 instead of 10000. Don't allocate memory for sorting that won't be used. planetsplitter: Added an option to print out the allocated/mapped memory at each step. Speed up database generation by compacting results after each pruning step. Speed up database generation by sorting nodes geographically before pruning. Reduce memory use while generating the database. router: Added the options to print out time and allocated/mapped memory at each step. Translations: Updated German translations. Note: This version is compatible with databases from versions 2.7.1 & 2.7.2. Version 2.7.2 of Routino released : Thu June 26 2014 ---------------------------------------------------- Bug fixes: Make the visualiser display all segments including those crossing the border. Fix two errors that cause crashes only on 64-bit systems. planetsplitter / router: Increase the size of the caches for the slim programs by a factor of four. Translations: Updated Russian translations. Updated German translations. Note: This version is compatible with databases from version 2.7.1. Version 2.7.1 of Routino released : Sat May 17 2014 --------------------------------------------------- Bug fixes: Fix typo in documentation for command to get SVN version. Fix router crash when waypoint is on roundabout. Don't duplicate super-segments when merging them with normal segments. Change routing instructions for bicycle if highways allow cycling both ways. Make translation script work with older versions of Perl. Fix router crash if fewer than two waypoints are specified. Revert router speed decrease with special-case tagging rules. Fix web page search function when it returns non-ASCII text. Fix router failure due to invalid assumption about allowed U-turn. Fix bug with updating XML files in web/data directory (Makefile error). Fix router web page error due to absence of cyclebothways property entry. Fix results error if a waypoint node was passed again on way to next waypoint. Fix router crash when route contains consecutive coincident waypoints. Fix bug with slightly incorrect distances when pruning short segments. Test cases: Create new test case for roundabout waypoint bug fixed in this version. Create new test case for invalid U-turn assumption bug fixed in this version. Create new test case for cycling both ways. Create new test case for consecutive coincident waypoints. router: Remove cyclebothways as a property that can be used as a routing preference. Web pages: Disallow route calculation if fewer than two waypoints are selected. Update visualiser for change of cyclebothways handling. Translations: Updated Russian translations. Updated German translations. Note: This version is not compatible with databases from previous versions. Version 2.7 of Routino released : Sat Mar 22 2014 ------------------------------------------------- Bug fixes: Fix web-page CGI bug that did not allow more than 9 waypoints to be routed. Fix typo in documentation strings in filedumper program. Fix error in function prototype that stopped 64-bit node type being used. Don't lose super-segments when merging them with normal segments. Don't exceed the database lat/long limits when searching for visualiser data. planetsplitter: Don't overflow (and wrap-around) conversions of lengths, weights etc. Add some new formats of length, weight and speed parsing. Add .xz uncompression as a compile-time option (default is disabled). router: Remove ancient undocumented option to specify lat/lon without --lat/--lon. Add a '--output-stdout' option to output the route in a selected format. Add a '--reverse' option to calculate a route in the reverse order. Add a '--loop' option to calculate a route that returns to the first waypoint. Output valid HTML4 (use strict DTD and use numeric entity for apostrophe). OSM tagging: Allow bicycles both ways on certain oneway roads if tagging allows. Handle "access=bus" like "access=psv". Configuration Files: Updated Dutch translations. Updates to the XML parser tagging rules. Added French translations for the routing output. Documentation: Update the algorithm documentation for finding the shortest path. Update documentation HTML to strict 4.01 DTD. Web pages: Some changes to HTML, CSS formatting and Javascript to improve usability. Added a French translation of the router web page. Add the option to choose between OpenLayers and Leaflet for map rendering. Check compatible with OpenLayers v2.13.1 and make this the default. Create the router and visualiser pages from templates and translated phrases. Note: This version has removed specific support for IE6 and IE7 browsers. Note: This version is compatible with databases from version 2.6 (although cycling both ways on one-way highways requires a database update). Version 2.6 of Routino released : Sat Jul 6 2013 ------------------------------------------------ Bug fixes: Force '...' in tagging rules to match even with no input tags. Built-in translations for GPX-route file gave nonsense durations. Handle some cases that potentially caused divide by zero (not crashes). Compilation: All configuration is now contained in the top level file Makefile.conf. Default to using -ffast-math option for faster maths and glibc workaround. Code improvements: Improve router internal data structures to increase performance. Add another layer of caching to significantly speed up slim mode operation. Add a layer of file buffering to significantly speed up reading/writing. Enable more compile-time warnings and fix them. planetsplitter: Create a binary log file to allow searching for errors geographically. Simplify processing for changes (segment files not kept). Don't prune isolated regions for transport types we don't have. Web pages (visualiser): Allow displaying the error logs on the map. Allow selecting any item displayed and showing more information about it. Extras: Create a separate directory to put extra (non-essential) programs and scripts. * tagmodifier - a tagging rule testing program. * errorlog - a script to summarise the planetsplitter error log. * plot-time - a script to plot a graph of the planetsplitter execution time. * find-fixme - search an OSM file for "fixme" tags and display them on a map. Note: This version is not compatible with databases from previous versions. Version 2.5.1 of Routino released : Sat Apr 20 2013 --------------------------------------------------- Bug fixes: Stop contradictory log error messages about 'access=foot' etc. Move the HTML charset definition to within the first 1024 bytes of file. Don't prune short segments in some cases that would change routing. Fix bug with pruning straight highways around loops. Fix some bugs with installation documents and scripts. Fix Javascript to work with OpenLayers v2.11 again. Fix XML character quoting for special characters in 7-bit ASCII range. Fix bug with parsing XML containing UTF-8 characters four bytes long. Fix two bugs for simple routes with the option of not passing a super-node. planetsplitter: Improve the pruning of straight highways (detect larger straight sections). Configuration Files: Accept some more tag values for OSM file parsing. Handle alternate forms of mini roundabouts (junction=roundabout). Note: This version is compatible with databases from version 2.4 / 2.4.1 / 2.5. Version 2.5 of Routino released : Sun Feb 9 2013 ------------------------------------------------ General: Replace 'motorbike' with 'motorcycle' everywhere. planetsplitter/tagmodifier: Major changes to file reading: Faster XML parser. Reads PBF files natively (not for changes, not tagmodifier). Reads o5m/o5c files natively (not tagmodifier). Reads bzip2 or gzip compressed files natively (if compiled for them). Data can no longer be read from standard input. planetsplitter: Report errors with self-intersecting ways, clarify some other error messages. Configuration Files: Tagging configuration can now use an rule. The tagging configuration and rules can be nested. Change the way that the multilane property is derived from the lanes tag. Accept some more tag values for OSM file parsing. German translation now supports roundabouts. Documentation: Describe numerical limits (OSM identifiers and maximum database size). Web pages: Allow different data and tile attributions for each map source. Include MapQuest as an optional tile source. Web pages (visualiser): Allow plotting segments of highways that have a particular property. Note: Starting with this version the planetsplitter and tagmodifier programs will no longer read data from standard input. Note: Existing mapprops.js files need to be updated for this version. Note: This version is compatible with databases from version 2.4 / 2.4.1. Version 2.4.1 of Routino released : Mon Dec 17 2012 --------------------------------------------------- Bug fixes: Fix error with finding routes with low preference values (router). Fix error when searching for default profiles.xml (router). Fix bug with printing log messages when output is not stdout (tagmodifier). Stop various crashes if trying to process file with no data (planetsplitter). Note: This version is compatible with databases from version 2.4. Version 2.4 of Routino released : Sat Dec 8 2012 ------------------------------------------------ Bug fixes: Fix pruning short segments in slim mode (gave different results to non-slim). Fix error with segment lengths for some segments from ways that are areas. Fix latent bug with route relations when compiled for 64-bit way/relation IDs. router/planetsplitter: Replace all debugging "assert" statements with fatal error messages. planetsplitter: Delete ways that are not used from the output files (names remain though). Delete turn relations that are not used from the output files. Speed up the processing, mainly by reducing the number of I/O operations. Change the pruning of isolated regions to look at each transport type. Slim and normal mode now give identical results (sorting preserves order). Log some more error cases, clarify some existing ones. Added a --append option which must be used to append files to existing data. Added a --keep option which can be used to keep parsed, sorted data. Added a --changes option to allow appending OSM change files (.osc files). Configuration Files: Accept some more tag values for OSM file parsing. summarise-log.pl Can now generate an HTML version with links to OSM information for each item. Deleted obsoleted files: The CGI scripts customrouter.cgi and customvisualiser.cgi have been removed. The noscript.cgi and noscript.html web pages have been removed. Note: Files deprecated in version 2.3 have been removed in version 2.4. Note: This version is not compatible with databases from previous versions. Version 2.3.2 of Routino released : Sat Oct 6 2012 -------------------------------------------------- Bug fixes: Fix for highway type visualiser (was missing one-way segments). Fix a real-life routing problem with oneway streets and super-segments. Find a route even if an end waypoint forbids the specified transport. Include the final junction in the HTML output (was missed in some cases). Test cases: Create new test cases for two bugs fixed in this version. router: Improve the error message for some cases of failing to route. planetsplitter: Log an error if a foot/bicycle way doesn't allow foot/bicycle transport. Do not mark nodes as super-nodes if they allow no transport types through. Web pages (visualiser): Allow plotting nodes that block each transport type. Configuration Files: Change the default license/copyright notice in the translations.xml file. Note: This version is compatible with databases from versions 2.2 or 2.3/2.3.1. Version 2.3.1 of Routino released : Sat Aug 11 2012 --------------------------------------------------- Bug fixes: Create marker-XXX-grey.png icon which gets used before Javascript removes it. Provide full set of 99 marker icons instead of just 19. Add more limit icons (0.0-0.9, 20.0-40.0 and 161-200). Fix router web page problem with placing initial marker (coords not updated). Hide waypoints so that they are not visible when Javascript adds them to HTML. Fix web page font problems by choosing an explicit font pixel-size in the CSS. Fix potential crash in XML files containing lots of key/value pairs in a tag. Web pages (router): Unused waypoints show as blank rather than 0,0. Add a button to insert a waypoint to close the loop. Write the command line and execution time to the log file. Note: This version is compatible with databases from versions 2.2 or 2.3. Version 2.3 of Routino released : Sat Jul 21 2012 ------------------------------------------------- Bug fixes: Handle OSM files that contain changesets (don't raise an error). Force bicyle/foot routes to allow bicycle/foot transport. Fix problem running CGIs on Macs (md5 program name). Fix bug with pruning straight highways (uninitialised data). Fix bug with XML parsing error log (could miss some unrecognised tags). Web pages (all): Make compatible with OpenLayers v2.12 (but don't change the install script). Make all HTML files standards compliant. Allow the HTML files to parse the query string instead of using a CGI. Move all user-editable parameters to paths.pl and mapprops.js. Web pages (router): Add a button to put a marker at the current location (Javascript geolocation). Add a button to centre the map on a given marker. Automatically insert the waypoints in the HTML from the JavaScript. Added a German language router web page translation. Add buttons to switch between lat/long and placename with Nominatim lookups. Web pages (visualiser): Allow plotting segments of each highway type. Allow plotting segments accessible to each transport type. planetsplitter: Add a new '--logtime' option that prints the elapsed time of each step. Make the sort functions multi-threaded (run-time option). Improve the XML parsing speed slightly. Note: This version is compatible with databases from versions 2.2. Note: Existing mapprops.js and paths.pl files need to be updated to include new items for this version. Note: Existing OpenLayers installations must be updated if they were installed with older Routino provided script (the old OpenLayers.js will not work). Note: The CGI scripts customrouter.cgi and customvisualiser.cgi are deprecated and will be removed in version 2.4 Note: The noscript.cgi and noscript.html web pages are deprecated and will be removed in version 2.4 Version 2.2 of Routino released : Sat Mar 3 2012 ------------------------------------------------ Bug fixes: Fix some Makefile bugs. Fix XML parsing (previously it allowed invalid XML comments). Fix errors in HTML and GPX output files (highway names and bearings). Fix errors in visualiser CGI related to oneway streets and in slim mode. Ensure that no non-initialised memory is written to disk. OSM tagging: Parse information about roundabouts and store it in the database. Documentation: Update documentation to reflect changes in program usage and function. Web pages: Change to OpenLayers v2.11. Move the map preferences (ranges and URLs) to a separate file. Prepare the visualiser.html web page for translation. The customrouter script should now pick up the preferred language. planetsplitter: When discarding duplicate segments prefer to discard those that are areas. Ensure that XML file is OSM version 0.6 format. Add a new option to prune nodes and/or segments (enabled by default) - that form a small isolated sub-network. - that are very short. - that are not needed to represent a straight highway. router: Change the format of the text file output (not the all points text file). Output better HTML directions for roundabouts (e.g. take second exit). Describe mini-roundabouts as "roundabout" rather than "junction". filedumper: Ensure that all nodes needed for segments are included when dumping a region. Include a bounding box when dumping a region. *** Important Note: The tagging.xml files from Routino v2.1.1 or earlier *** *** contain invalid XML that will not be allowed by Routino v2.2 or later. *** Note: The format of the text file output has changed in this version. Note: This version is not compatible with databases from earlier versions. Version 2.1.2 of Routino released : Sat Nov 12 2011 --------------------------------------------------- Bug fixes: Speed up the routing by a factor of 3 for slim mode by copying data to RAM. Speed up routing & reduce memory use by a factor of 2.5 by stopping earlier. Delete profiles.js and profiles.pl when cleaning up (make clean). Improve output for translated versions (highway type names and text files). Fix the summarise-log.pl script for segments which are loops. Fix invalid XML syntax in tagging.xml file. Configuration Files: Add extra tagging rules to handle problems found in the error log for UK. Added Russian translations for output files. Documentation: Improve the documentation for the tagging rule configuration file. Note: This version is compatible with databases from version 2.1 or 2.1.1. Version 2.1.1 of Routino released : Sun Oct 23 2011 --------------------------------------------------- Bug fixes: Speed up the routing by a factor of 5 by improving data handling functions. Speed up database generation by reducing the default number of iterations. Fix the handling of the 'except' tag on turn restrictions. Fix the 'make install' option for the XML files. Add some more typecasts when printing data from filedumper program. Make the CGI script more robust if shortest/fastest is not passed in. Note: This version is compatible with databases from version 2.1. Version 2.1 of Routino released : Mon Oct 3 2011 ------------------------------------------------ Bug fixes: Fix bug in pathological cases with binary search (don't crash). Make stricter checks for closest nodes just like in v2.0.3 for segments. Fix routing bug where start node is a super-node and finish is close by. OSM tagging: More testing of turn relations; invalid or useless ones are discarded. An error log file can be generated to record parsing and processing errors. Configuration Files: Add new options in the tagging rules XML file. Add extra tagging rules to handle many problems found in the error log for UK. Create special-use tagging rule files for walking, riding and driving. Test cases: Create new test case for bug fixed in v2.0.3. Save expected results to allow future regressions to be found. Note: This version is not compatible with databases from earlier versions. Version 2.0.3 of Routino released : Thu Aug 4 2011 -------------------------------------------------- Bug fixes: Handle start node being a super-node with no previous segment (don't crash). Make stricter checks against the profile when finding the closest segment. Find a valid route if the start and end point are the same location. Choose the better route if one with and one without super-nodes are available. Note: This version is compatible with databases from versions 2.0, 2.0.x. Version 2.0.2 of Routino released : Sun June 26 2011 ---------------------------------------------------- Bug fixes: Fix error with handling ferry routes (were ignored). Force roundabouts to be one-way (was present in v1.5.1). Handle super-nodes with no segments when processing (don't crash). Code improvements: Use C99 standard by default and fix related warnings. More code tidy-up for 32/64 bit node and index types. Free some memory in various places (not serious leaks). Note: This version is compatible with databases from versions 2.0, 2.0.1. Version 2.0.1 of Routino released : Tue June 7 2011 --------------------------------------------------- Bug fixes: Turn relations that specify missing nodes/ways are deleted (don't crash). Shorten the messages printed by planetsplitter to keep below 80 characters. Code improvements: Various code tidy-ups and 32/64 bit node and index improvements. OSM Tagging: Check whether node/way/relation IDs fit in 32-bits (code ready for 64-bits). Note: This version is compatible with databases from version 2.0. Version 2.0 of Routino released : Mon May 30 2011 ------------------------------------------------- Bug fixes: Fix mis-spelling with surface=asphalt tag Routes between two waypoints on the same segment now work. Fix reading of numeric entities from XML files (store as UTF-8 internally). Fix turn description in HTML file (angles were biased to the right). Fix possibility of occasionally missing turn information from output files. Test cases: Added test cases for routing in slim and non-slim modes. Documentation: Update documentation to reflect changes in program usage and function. Install the license file in the documentation directory. OSM tagging: Process the tags associated with turn restriction relations. Remove the roundabout type from the parsing. Add parsing of mini-roundabouts. Configuration Files: Update profiles with new options related to turn restrictions. Web pages: Change to OpenLayers v2.10. Visualiser can display turn restrictions. Put the profile information into separate files and auto-generate them. planetsplitter: Store information about turn restriction relations. Quite a large code re-organisation - now faster and uses less memory. router: Take turn restriction relations into account when routing. Continue same direction of travel at each waypoint (unless dead-end). Add a new option to specify an initial direction to start travel. filedumper: Print out statistics about what highways are included in the database. Version 1.5.1 of Routino released : Sat Nov 13 2010 --------------------------------------------------- Bug fixes: Ensure that enough memory is allocated for filenames. Fix bug that sometimes causes crash when processing route relations. Documentation: Update documentation to reflect changes in program usage and function. Programs: Add an option to make the output more suitable for a log file. Documentation: Update documentation to reflect changes in program usage. Version 1.5 of Routino released : Sat Oct 30 2010 ------------------------------------------------- Bug fixes: Check that number of nodes/segments/ways doesn't exceed numerical limits. Allow 32-bit systems to seek within files larger than 4GB. Allow nearly 4G nodes to be stored instead of 2G before. Added rules to makefile for installation (paths specified in top-level). Stricter checking of UTF-8 in XML files and better UTF-8 output. Improve error message if parsing of command line options fail. Fix bugs in router's --help-profile-json and --help-profile-perl options. Rename heapsort function to allow compilation on Mac OS with no change. Reduce impact of property preferences close to 50% by using sqrt(). Documentation: Update documentation to reflect changes in program usage and function. OSM tagging: Traffic restrictions on nodes are now included in default tagging file. Added processing for ferry routes (as pseudo-highway type 'ferry'). Process foot and bicycle route relations to create new properties. Configuration Files: Added Dutch output translations. Added ferry information to profiles. Added foot and bicycle route relation processing. planetsplitter: The slim mode now includes the output data as well as the temporary data. The slim mode is now a separate executable and not a command line option. Traffic restrictions on nodes are now understood when parsing OSM files. Falls back to installed tagging.xml configuration file as last resort. router: Added a slim mode (as a separate executable and not a command line option). Traffic will not be routed through a node that does not allow it. Falls back to installed profiles.xml & translations.xml files as last resort. filedumper: Added a slim mode (as a separate executable and not a command line option). Web pages: Added Dutch translation of router.html. Version 1.4.1 of Routino released : Sat Jul 10 2010 --------------------------------------------------- Bug fixes: Don't crash if start and finish are the same point. Don't crash if several translations but --language option not used. Don't crash if middle part of route cannot be found. Don't allocate so much memory for intermediate nodes; routes much faster. Fix problem with finding closest segment to the specified point. Documentation: Provide HTML versions of the documentation (copy to web directory at install). Change URL for website to http://www.routino.org/. Configuration Files: Added German output translations. planetsplitter Slight change to algorithm for finding super-nodes. Web pages: Provide HTML versions of the documentation. Change URL for website to http://www.routino.org/. Provide updated HTML files, the same as on the website. Change to OpenLayers v2.9.1 and build custom version if Python available. Version 1.4 of Routino released : Mon May 31 2010 ------------------------------------------------- Bug fixes: Speed up start/via/stop point within segment search algorithm. If no segment is found don't try routing but exit with error. Improve the error messages by adding operating system error info to them. Rewrite of tagging rules fixes bug with wheelchair access allow/deny. Files greater than 2GB can be read/written on 32-bit systems. Fix bug with profile preferences when optimising a route. Stricter check on profile validity before starting routing. planetsplitter: Add --parse-only and --process-only options (for incremental parsing). Allow filenames to be specified on command line (default is still stdin). Improved the '--help' information to describe all options. Remove --transport, --not-highway, --not-property options (use config file). Use tag transformation rules in configuration file not hard-coded. router: Removed compiled-in profiles and use profiles loaded from XML file. Improved the '--help' information to describe all options. Change the name of the --profile-json and --profile-perl options. Allow selection of the outputs to generate (or none). Added HTML route instructions output. GPX route file contains instructions at each waypoint. Read in XML file of translated words/phrases for outputs. Added options to specify file of translations and language to use. Remove copyright.txt file and put information into translations file. filedumper: Improved the '--help' information to describe all options. Added the option to dump an OSM file containing database contents. Web Pages: Combined generic map CSS into one file (not copied in two). Much better support for IE6/7/8 with browser detection but not perfect. Re-organised and tidied up the Javascript. Added button next to waypoints to centre it on map. Added button next to waypoints to set as home location (uses browsser cookie). Create shorter URLs for custom map (ignore default values). Reduced and clarified the amount of editing to customise the Javascript. Made it easier to translate by moving text out of Javascript (not visualiser). Prepared for translated versions of web page (Apache Multiviews). Added option to select language of output. Use HTML output from router to get translated instructions. Version 1.3 of Routino released : Thu Jan 21 2010 ------------------------------------------------- Bug fixes: Ensure output even if the distance between two adjacent route points is small. Correct the determination of waypoints for abbreviated output. Check the command line values for filedumper --dump options. Made the verbose output consistent between different places. OSM tagging: Recognise "designation" tag to determine designated paths. Recognise "steps" tag to determine the highway type. Recognise "wheelchair" tag to determine if wheelchairs are allowed on highway. Recognise "moped" tag to determine if mopeds are allowed on a highway. Recognise "surface" and "paved" tags to determine if a highway is paved. Recognise "lanes" tag to determine if a highway has multiple lanes. Recognise "bridge" tag to determine if a highway is a bridge. Recognise "tunnel" tag to determine if a highway is a tunnel. New Features: Remove "bridleway" and "footway" highway types and use "path" highway instead. Added "steps" as a new highway type separate from the "path" type. Added "wheelchair" and "moped" to the list of possible transports. Added "paved", "multilane", "bridge", "tunnel" to list of highway properties. Web Pages: Updated for new features listed above. Added popup to display instructions for each step in route on mouse-over. Added buttons next to waypoints for: add / remove / move up / move down. Highlight user selectable parts of form in yellow on mouse-over. A few small changes, improved CSS, improved Javascript. router: For each waypoint choose closest point on a segment and not just closest node. Added the ability to set preferences based on highway properties. Changed the text output formats to include bearing and turn information. Version 1.2 of Routino released : Wed Oct 21 2009 ------------------------------------------------- OSM tagging: Recognise tags "vehicle" and "motor_vehicle". Handle duplicate ways in the input OSM file (e.g. concatenation of 2 files). Database: Identical ways are combined to reduce database size (~80% fewer ways stored). Routing: Fix weight, height, width, length restriction routing. Allow up to 99 waypoints to be specified instead of 9. Visualiser: Don't display speed limits for tracks and paths unless a value is set. Draw all super-segments that cross the selected boundary. Web Pages: A few small changes, improved CSS, improved Javascript. Changed marker colour when waypoint not selected. planetsplitter: Optional slim mode uses minimal memory at the expense of temporary files. router: Less CPU time for routing (~30% less). filedumper: Allow dumping individual nodes, segments and ways (for debug). Version 1.1 of Routino released : Sat Jun 13 2009 ------------------------------------------------- Inputs: Improve parsing of OSM file (imperial units). Ignore nodes that are missing from the input OSM file. Outputs: Create GPX route files as well as GPX track files. Read in an optional copyright.txt file and include contents in output. Make better choices about what to output in the abbreviated text file. Routing: Allow generating a route with intermediate waypoints. Use preferences for highway types instead of yes/no choice. Choice of closest node to start/finish points ensures transport allowed. Visualiser: Added data extraction function for viewing routing database data. Web Pages: Include full set of web pages for creating customised online router. Documentation: Included NEWS.txt file. Included documentation for installation of web pages. Version 1.0 of Routino released : Wed Apr 08 2009 ------------------------------------------------- First version. routino-3.0/doc/INSTALL-MS-WIN.txt 644 233 144 13422 12572106465 11641 0 Routino : Installation on MS Windows ==================================== Using Cygwin ------------ Cygwin is a large collection of GNU and Open Source tools which provide functionality similar to a Linux distribution on Windows. A Cygwin DLL provides substantial POSIX API functionality therefore providing direct compatibility for most UNIX source code. Since Cygwin aims to replicate a Linux-like system on Windows it is the simplest method of compiling Routino. The disadvantage is that all programs compiled with Cygwin require a number of runtime Cygwin libraries which may introduce a runtime speed penalty. The installer for Cygwin can be downloaded from http://cygwin.org/; there are 32-bit and 64-bit versions available. For compiling Routino the Cygwin installer should be run and the following packages selected (any dependencies will be automatically be selected at the next step): * base packages * gcc-core (in 'Devel' menu) * make (in 'Devel' menu) * libbz2-devel (in 'Libs' menu) * zlib-devel (in 'Libs' menu) * perl (in 'Perl' menu) To compile Routino open the "Cygwin Terminal" change to the Routino source directory and compile using the make command. The programs that are compiled 'planetsplitter', 'router' will require the Cygwin runtime to be able to run them. The library 'libroutino.so' should be usable with other Cygwin compiled programs. Native Compilation ------------------ Routino has limited support in the source code for compiling on Microsoft Windows. This includes a set of functions that can replace the mmap() and munmap() UNIX functions which are not available on Microsoft Windows. The source code should be downloaded, either as a release version file or from subversion - no instructions are provided for this step. The release versions include some files (mainly the web icons) which are not included in the subversion source (and which may be difficult to create on Windows). Using Microsoft Visual C - - - - - - - - - - - - The Routino source code (for the router at least) has been modified so that it will compile with the Microsoft Visual C compiler. Compiling Routino with MSVC is not supported directly since there is only support for using Makefiles in Routino. The files that need to be compiled for the Routino router can be found from the Makefile in the src directory listed in the 'ROUTER_OBJ' variable. To compile the router in slim mode the pre-processor definition 'SLIM=0' must be set and for non-slim mode 'SLIM=1' must be set. The default directory for the Routino data files must be set in the 'ROUTINO_DATADIR' pre-processor variable. If the router command line '--data' option is going to be used then this variable can be set to any value. Since Microsoft Visual C does not fully support the C99 standard it is necessary to tell the compiler how to handle the inline functions. This can be done by passing in the command line option '-Dinline=__inline' to the C compiler. Using MinGW - - - - - - MinGW is the "Minimalist GNU for Windows" which includes some of the common GNU programs; principally gcc and related programs for software development. The installer for MinGW can be downloaded from 'http://mingw.org/'. For compiling Routino the MinGW installer should be run and the following packages selected: * mingw-base * msys-base * mingw32-pthreads-w32 * mingw32-libz (dev package) * msys-perl To compile Routino open a DOS command window and set the path to the installed MinGW and MSYS software. For example if MinGW was installed in the 'C:/MinGW' directory then the path needs to be set to 'C:\MinGW\bin;C:\MinGW\MSYS\1.0\bin'. From within this DOS command window change to the Routino source directory and compile using the MinGW version of make with this command 'mingw32-make'. After compiling Routino a set of library files are created ('routino.dll', 'routino.def' and 'routino.lib'). These should be usable for linking with programs compiled with MSVC. Using MinGW-W64 - - - - - - - - MinGW-w64 is an alernative implementation of the same concept as MinGW but allows for compilation to 32-bit or 64-bit executables. The website for MinGW-w64 is 'http://mingw-w64.org/' but the downloads are available from 'http://win-builds.org/'. Installation of MinGW-w64 is slightly different from that for MinGW but a similar set of packages will be required. The compilation method for MinGW-w64 is the same as for MinGW and the same files will be compiled, the only difference is that by default a 64-bit version will be created. Limitations - - - - - - A native Microsoft Windows compilation of Routino is more complicated than compiling on Linux, other UNIX system or Cygwin. This is probably not an option if you are unfamiliar with software development on Microsoft Windows. The size of files that can be accessed with an MSVC or MinGW (32-bit) compiled version of Routino is limited to 32-bits (less than 4 GB). The MinGW-w64 compiler on 64-bit is able to handle larger files (bigger than 4 GB). The Windows operating system does not have a function equivalent to the 'fork()' function on UNIX. This means that it is not possible to use the planetsplitter program's built-in file decompression with an MSVC or MinGW compiled version of Routino. Example Web Pages ----------------- No instructions are available for using the Routino example web pages with the Microsoft Web server (IIS). For information on setting up Apache see the "Example Web Pages" section of the main installation instructions. -------- Copyright 2008-2015 Andrew M. Bishop. routino-3.0/doc/html/ 40755 233 144 0 12575035402 7723 5routino-3.0/doc/html/data.html 644 233 144 14225 12520734766 11573 0 Routino : Data

Routino : Data

Data

A router relies on data to be able to find a route.

OpenStreetMap Data

The data that is collected by the OpenStreetMap project consists of nodes, ways and relations.
Node
A node is a point that has a latitude and longitude and attributes that describe what type of point it is (part of a way or a place of interest for example).
Way
A way is a collection of nodes that when joined together define something (for example a road, a railway, a boundary, a building, a lake etc). The ways also have attributes that define them (speed limits, type of road and restrictions for example).
Relation
A relation is a collection of items (usually ways) that are related to each other for some reason (highways that make up a route for example).
The OpenStreetMap Wiki explains the data much better than I can.

Router Data

The information that is needed by a routing algorithm is only a subset of the information that is collected by the OpenStreetMap project. For routing what is required is information about the location of roads (or other highways), the connections between the highways and the properties of those highways.
Location of highways (nodes)
The locations of things is provided by the nodes from the OpenStreetMap data. The nodes are the only things that have coordinates in OpenStreetMap and everything else is made up by reference to them. Not all of the nodes are useful, only the ones that are part of highways. The location of the nodes is stored but none of the other attributes are currently used by the router.
Location of highways (ways)
The location of the highways is defined in the OpenStreetMap data by the ways. Only the highway ways are useful and the other ways are discarded. What remains is lists of nodes that join together to form a section of highway. This is further split into segments which are individual parts of a way connected by two nodes.
Properties of highways (tags)
The ways that belong to highways are extracted from the data in the previous step and for each way the useful information for routing is stored. For the router the useful information is the type of highway, the speed limit, the allowed types of transport and other restrictions (one-way, minimum height, maximum weight etc).
Connections between highways
The connections between highways are defined in the OpenStreetMap data by ways that share nodes. Since the ways may join in the middle and not just the ends it is the segments defined above that are not part of the OpenStreetMap data that are most important.
The information that is extracted from the OpenStreetMap data is stored in an optimised way that allows the routing to be performed quickly.

Interpreting Data Tags

The tags are the information that is attached to the nodes and ways in OpenStreetMap. The router needs to interpret these tags and use them when deciding what type of traffic can use a highway (for example).

There are no well defined rules in OpenStreetMap about tagging, but there is guidance on the OpenStreetMap Wiki "Map_Features" page. This describes a set of recommended tags but these are not universally used so it is up to each application how to interpret them.

The tagging rules that the router uses are very important in controlling how the router works. With Routino the data tags can be modified when the data is imported to allow customisation of the information used for routing.

Problems With OpenStreetMap Data

The route that can be found is only as good as the data that is available. This is not intended as a criticism of the OpenStreetMap data; it is generally good.

There are some problems that are well known and which affect the router. For example highways might be missing because nobody has mapped them. A highway may be wrongly tagged with incorrect properties, or a highway might be missing important tags for routing (e.g. speed limits). There can also be problems with highways that should join but don't because they do not share nodes.

A lot of these problems can be found using the interactive data visualiser that uses the same Routino routing database.

routino-3.0/doc/html/output.html 644 233 144 37671 12520735062 12222 0 Routino : Output

Routino : Output

Router Output

There are three different formats of output from the router, HTML, GPX (GPS eXchange) XML format and plain text with a total of five possible output files:
  • HTML route instructions for each interesting junction.
  • GPX track file containing every node.
  • GPX route file with waypoints at interesting junctions.
  • Plain text description with the interesting junctions.
  • Plain text file with every node.
The "interesting junctions" referred to above are junctions where the route changes to a different type of highway, more than two highways of the same type meet, or where the route meets but does not take a more major highway. When the route follows a major road this definition eliminates all junctions with minor roads.

The output files are written to the current directory and are named depending on the selection of shortest or quickest route. For the shortest route the file names are "shortest.html", "shortest-track.gpx", "shortest-route.gpx", "shortest.txt" and "shortest-all.txt", for the quickest route the names are "quickest.html", "quickest-track.gpx", "quickest-route.gpx", "quickest.txt" and "quickest-all.txt".

The HTML file and GPX files are written out according to the selected language using the translations contained in the translations.xml configuration file. The text files contains untranslated header lines (in English) but the data is translated.

HTML Route Instructions

The HTML route instructions file contains one line for the description of each of the interesting junctions in the route and one line for each of the highways that connect them. The coordinates are also included in the file but are not visible because of the style definitions.

An example HTML file output is below (some parts are missing, for example the style definitions):

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML>
<!-- Creator : Routino - http://www.routino.org/ -->
<!-- Source : Based on OpenStreetMap data from http://www.openstreetmap.org/ -->
<!-- License : http://www.openstreetmap.org/copyright -->
<HEAD>
<TITLE>Shortest Route</TITLE>
...
</HEAD>
<BODY>
<H1>Shortest Route</H1>
<table>
<tr class='c'><td class='l'>1:<td class='r'>51.524658 -0.127877
<tr class='n'><td class='l'>Start:<td class='r'>At <span class='w'>Waypoint</span>, head <span class='b'>South-East</span>
<tr class='s'><td class='l'>Follow:<td class='r'><span class='h'>Woburn Place (A4200)</span> for <span class='d'>0.251 km, 0.3 min</span> [<span class='j'>0.3 km, 0 minutes</span>]
<tr class='c'><td class='l'>2:<td class='r'>51.522811 -0.125781
<tr class='n'><td class='l'>At:<td class='r'>Junction, go <span class='t'>Straight on</span> heading <span class='b'>South-East</span>
<tr class='s'><td class='l'>Follow:<td class='r'><span class='h'>Russell Square (A4200)</span> for <span class='d'>0.186 km, 0.2 min</span> [<span class='j'>0.4 km, 1 minutes</span>]
<tr class='c'><td class='l'>3:<td class='r'>51.521482 -0.124123
<tr class='n'><td class='l'>At:<td class='r'>Junction, go <span class='t'>Straight on</span> heading <span class='b'>South-East</span>
<tr class='s'><td class='l'>Follow:<td class='r'><span class='h'>Southampton Row (A4200)</span> for <span class='d'>0.351 km, 0.4 min</span> [<span class='j'>0.8 km, 1 minutes</span>]
...
<tr class='c'><td class='l'>21:<td class='r'>51.477678 -0.106792
<tr class='n'><td class='l'>At:<td class='r'>Junction, go <span class='t'>Slight left</span> heading <span class='b'>South-East</span>
<tr class='s'><td class='l'>Follow:<td class='r'><span class='h'>Vassall Road</span> for <span class='d'>0.138 km, 0.2 min</span> [<span class='j'>6.3 km, 6 minutes</span>]
<tr class='c'><td class='l'>22:<td class='r'>51.478015 -0.104870
<tr class='n'><td class='l'>At:<td class='r'>Junction, go <span class='t'>Straight on</span> heading <span class='b'>East</span>
<tr class='s'><td class='l'>Follow:<td class='r'><span class='h'>Vassall Road</span> for <span class='d'>0.087 km, 0.1 min</span> [<span class='j'>6.4 km, 6 minutes</span>]
<tr class='c'><td class='l'>23:<td class='r'>51.478244 -0.103651
<tr class='n'><td class='l'>Stop:<td class='r'>At <span class='w'>Waypoint</span>
<tr class='t'><td class='l'>Total:<td class='r'><span class='j'>6.4 km, 6 minutes</span>
</table>
</BODY>
</HTML>

GPX Track File

The GPX track file contains a track with all of the individual nodes that the route passes through.

An example GPX track file output is below:

<?xml version="1.0" encoding="UTF-8"?>
<gpx version="1.1" creator="Routino" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.topografix.com/GPX/1/1" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd">
<metadata>
<desc>Creator : Routino - http://www.routino.org/</desc>
<copyright author="Based on OpenStreetMap data from http://www.openstreetmap.org/">
<license>http://www.openstreetmap.org/copyright</license>
</copyright>
</metadata>
<trk>
<name>Shortest route</name>
<desc>Shortest route between 'start' and 'finish' waypoints</desc>
<trkpt lat="51.524658" lon="-0.127877"/>
<trkpt lat="51.523768" lon="-0.126918"/>
<trkpt lat="51.522811" lon="-0.125781"/>
...
<trkpt lat="51.478015" lon="-0.104870"/>
<trkpt lat="51.478127" lon="-0.104174"/>
<trkpt lat="51.478244" lon="-0.103651"/>
</trkseg>
</trk>
</gpx>

GPX Route File

The GPX route file contains a route (ordered set of waypoints) with all of the interesting junctions that the route passes through and a description of the route to take from that point.

An example GPX route file output is below:

<?xml version="1.0" encoding="UTF-8"?>
<gpx version="1.1" creator="Routino" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.topografix.com/GPX/1/1" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd">
<metadata>
<desc>Creator : Routino - http://www.routino.org/</desc>
<copyright author="Based on OpenStreetMap data from http://www.openstreetmap.org/">
<license>http://www.openstreetmap.org/copyright</license>
</copyright>
</metadata>
<rte>
<name>Shortest route</name>
<desc>Shortest route between 'start' and 'finish' waypoints</desc>
<rtept lat="51.524658" lon="-0.127877">
  <name>START</name>
  <desc>South-East on 'Woburn Place (A4200)' for 0.251 km, 0.3 min</desc>
</rtept>
<rtept lat="51.522811" lon="-0.125781">
  <name>TRIP001</name>
  <desc>South-East on 'Russell Square (A4200)' for 0.186 km, 0.2 min</desc>
</rtept>
<rtept lat="51.521482" lon="-0.124123">
  <name>TRIP002</name>
  <desc>South-East on 'Southampton Row (A4200)' for 0.351 km, 0.4 min</desc>
</rtept>
...
<rtept lat="51.477678" lon="-0.106792">
  <name>TRIP020</name>
  <desc>South-East on 'Vassall Road' for 0.138 km, 0.2 min</desc>
</rtept>
<rtept lat="51.478015" lon="-0.104870">
  <name>TRIP021</name>
  <desc>East on 'Vassall Road' for 0.087 km, 0.1 min</desc>
</rtept>
<rtept lat="51.478244" lon="-0.103651">
  <name>FINISH</name>
  <desc>Total Journey 6.4 km, 6 minutes</desc>
</rtept>
</rte>
</gpx>

Text File

The text file format contains one entry for all of the interesting junctions in the route and is intended to be easy to interpret, for example for creating other output formats.

An example text file output is below:

# Creator : Routino - http://www.routino.org/
# Source : Based on OpenStreetMap data from http://www.openstreetmap.org/
# License : http://www.openstreetmap.org/copyright
#
#Latitude   Longitude  Section   Section  Total    Total    Point Turn Bearing Highway
#                      Distance  Duration Distance Duration Type
 51.524658  -0.127877  0.000 km  0.0 min  0.0 km   0 min    Waypt  +3          Woburn Place (A4200)
 51.522811  -0.125781  0.251 km  0.3 min  0.3 km   0 min    Junct  +0  +3      Russell Square (A4200)
 51.521482  -0.124123  0.186 km  0.2 min  0.4 km   1 min    Junct  +0  +3      Southampton Row (A4200)
...
 51.477678  -0.106792  0.204 km  0.2 min  6.1 km   5 min    Junct  +0  +3      Vassall Road
 51.478015  -0.104870  0.138 km  0.2 min  6.3 km   6 min    Junct  +0  +2      Vassall Road
 51.478244  -0.103651  0.087 km  0.1 min  6.4 km   6 min    Waypt

The text file output contains a header (indicated by the lines starting with '#') and then one line for each waypoint or junction. Each line contains the information for the current node and the next segment to be followed. For each of the lines the individual fields contain the following:
Item Description
Latitude Location of the node (degrees)
Longitude Location of the node (degrees)
Section Distance The distance travelled on the section of the journey that ends at this node.
Section Duration The duration of travel on the section of the journey that ends at this node.
Total Distance The total distance travelled up to this point.
Total Duration The total duration of travel up to this point.
Point Type The type of point; either a waypoint Waypt or junction Junct.
Turn The direction to turn at this point (missing for the first line since the journey has not started yet and for the last line because it has finished). This can take one of nine values between -4 and +4 defined by: 0 = Straight, +2 = Right, -2 = Left and +/-4 = Reverse.
Bearing The direction to head from this point (missing for the last line since the journey has finished). This can take one of nine values between -4 and +4 defined by: 0 = North, +2 = East, -2 = West and +/-4 = South.
Highway The name (or description) of the highway to follow from this point (missing on the last line since the journey has finished).

The individual items are separated by tabs but some of the items contain spaces as well.

All Nodes Text File

The all nodes text file format contains one entry for each of the nodes on the route.

An example all nodes text file output is below:

# Creator : Routino - http://www.routino.org/
# Source : Based on OpenStreetMap data from http://www.openstreetmap.org/
# License : http://www.openstreetmap.org/copyright
#
#Latitude   Longitude  Node      Type   Segment Segment Total Total   Speed Bearing Highway
#                                       Dist    Durat'n Dist  Durat'n
 51.524658  -0.127877  8439703*  Waypt   0.000  0.00    0.00   0.0   
 51.523768  -0.126918  8439948*  Junct-  0.119  0.15    0.12   0.1     96    146    Woburn Place (A4200)
 51.522811  -0.125781  8440207*  Junct   0.132  0.17    0.25   0.3     96    143    Woburn Place (A4200)
...
 51.478015  -0.104870  8529638*  Change  0.138  0.17    6.26   5.6     48     74    Vassall Road
 51.478127  -0.104174  8529849*  Junct-  0.049  0.04    6.31   5.7     64     75    Vassall Road
 51.478244  -0.103651  8530008   Waypt   0.038  0.04    6.35   5.7     64     70    Vassall Road

The all nodes text file output contains a header (indicated by the lines starting with '#') and then one line for each node and the segment that was used to reach it. This file therefore contains exactly the same model as is used internally to define a route (a series of results each of which is a node and the segment leading to it). For each of the lines the individual fields contain the following:
Item Description
Latitude Location of the node in degrees.
Longitude Location of the node in degrees.
Node The internal node number and an indicator "*" if the node is a super-node.
Type The type of point; a waypoint Waypt, important junction Junct, unimportant junction Junct-, change of highway Change or intermediate node Inter.
Segment Distance The distance travelled on the segment defined on this line.
Segment Duration The duration of travel on the segment defined on this line.
Total Distance The total distance travelled up to this point.
Total Duration The total duration of travel up to this point.
Speed The speed of travel on the segment defined on this line (missing on the first line).
Bearing The direction that the segment defined on this line travels in degrees (missing on the first line).
Highway The name (or description) of the highway segment (missing on the first line).

routino-3.0/doc/html/installation.html 644 233 144 35453 12563643757 13377 0 Routino : Installation

Routino : Installation

Quick Start Guide

The instructions below are a complete list of the minimum required to get Routino installed and running under Apache on Debian Linux. Other Linux versions will be similar and other UNIX based systems will also be similar although may have distinct differences. There is some support in Routino for compiling on Microsoft Windows which has its own installation instructions.

These instructions should not be considered as complete or a secure installation for the reasons given in more detail in the Configuration of Web Files section below.

The starting point for the installation is in the Routino source code directory after it has been uncompressed. Most of the steps will need to be run as the root user.

The first thing to do is to install the packages which are required for compilation of Routino as described in the Pre-Requisites section below.

apt-get install gcc make libc6-dev libz-dev libbz2-dev
After this the programs can be compiled:
make
The files for the web interface can now be copied to the web server directory. On Debian this is /var/www and the files changed to be owned by the user Apache runs as.
cp -a web /var/www/routino
chown -R www-data:www-data /var/www/routino
To be able to use Routino some data will need to be processed and a script is provided for this. This will download the data for the UK which may take a while and then process it.
cd /var/www/routino/data
sh -x create.sh
The routino web pages also requires either the OpenLayers or Leaflet Javascript library to be downloaded and installed and scripts are provided for this.
cd /var/www/routino/www/openlayers
sh -x install.sh
cd /var/www/routino/www/leaflet
sh -x install.sh
To make full use of the location search feature on the Routino web page you will need to install some extra perl packages.
apt-get install libwww-perl liburi-perl libjson-pp-perl
Finally to make the web pages work you will need to add the extra lines to the Apache configuration file as described in the Configuration of Web Server section below. You don't have to use vi and can use any text editor.
vi /etc/apache2/sites-enabled/000-default
apache2ctl restart
Now everything should be set up and the web page should work if accessed at http://localhost/routino/www/routino/router.html.

When everything is working you should read the rest of this document carefully and make the following changes:

  • Download your choice of OSM data - edit the file data/create.sh and run it again.
  • Edit the www/routino/mapprops.js file to match the downloaded data and personal map preferences.
  • Move the files in the web server directory so that only the contents of the www directory are accessible by the web server.
  • Edit the file www/routino/paths.pl to reference the new file locations.

Pre-Requisites

The programs are written in standard C language with minimal external requirements so only a small set of development tools are required (gcc, make). The compilation tools to use and the command line options are defined in the file Makefile.conf.

There is some support for multi-threading that uses pthreads and additional development libraries for this may be required (on Linux this might be part of the standard C language development files). The multi-threading is enabled by default but can be disabled at compile time by commenting out two lines in the file Makefile.conf.

To use the built-in gzip file decompression function and to process all PBF format files the zlib (or libz) development library is required (on Linux this might be in a package called libz-dev). The gzip function is enabled by default but can be disabled by commenting out two lines in the file Makefile.conf.

To use the built-in bzip2 file decompression functions the bzip2 (or libbz2) development library is required (on Linux this might be in a package called libbz2-dev). The bzip2 function is enabled by default but can be disabled by commenting out two lines in the file Makefile.conf.

To use the built-in xz file decompression functions the liblzma development library is required (on Linux this might be in a package called liblzma-dev). The xz function is not enabled by default but can be enabled by uncommenting two lines in the file Makefile.conf.

To compile the source code from subversion requires the Perl Graphics::Magick module to generate the web page icons (on Linux this might be in a package called libgraphics-magick-perl). The released source code packages contains the icons so this package is not required for compilation.

To use the web page interface an http server is required. Instructions below are for Apache but any server that supports CGIs should work.

The web pages use the Perl scripting language and a number of the default Perl modules. To use the search function on the router web page the Perl module JSON::PP must be installed (on Linux this might be in a package called libjson-pp-perl if not part of the standard Perl installation).

Compilation

To compile the programs just type make at the top level of the source tree.

This program has been written to run on Linux, no cross-platform compatibility has been specifically included but on the other hand other platforms have not knowingly been excluded either.

Any information on improving the compilation process on anything other than x86 Linux is welcome.

Installation

After compilation the executable files are copied into the directory web/bin and the default XML configuration files are copied into the directory web/data. This is in preparation for using the supplied example web pages but is also a useful location to copy the files from for normal use.

The required executable files are planetsplitter, router and filedumper and the *-slim versions of the same files. They can be copied to any location and need no special installation environment. The filedumperx executable is for debugging and not required.

The configuration files are called profiles.xml, tagging.xml and translations.xml. The names of the configuration files can be specified on the command line but by default are also looked for in the directory that contains the routing database with these names.

Example Web Page

The directory web contains a set of files that can be used to create a working set of web pages with interfaces to the routing algorithm.

The files in the web directory will require copying to a location that is accessible by a web server. After copying the files some of them need to be edited; search through the files for lines that contain the words "EDIT THIS" and make appropriate edits (more details below).

Configuration of Web Files

The assumption in this description is that the whole of the directory called web is copied into a directory that is accessible by an Apache web server.

This is not a secure configuration but an easy one to configure.
Only the directory www should be accessible by the web server. Do not use this configuration unmodified in a public web server.

The directory structure is as follows:

   web/
    |
    + /bin/                    <- The Routino executable files (when compiled).
    |
    + /data/                   <- The Routino database and default configuration
    |                             files.
    |
    + /results/                <- An empty directory to store the results.
    |
    + /www/                    <- The files that must be available to the web
        |                         server are below this level.
        |
        + /openlayers/         <- A directory to hold the OpenLayers library
        |                         (optional; leaflet can be used instead).
        |
        + /leaflet/            <- A directory to hold the Leaflet library.
        |                         (optional; openlayers can be used instead).
        |
        + /routino/            <- The main HTML, Javascript, CSS and CGI files.
            |
            + /documentation/  <- The HTML version of the Routino documentation.
The directory bin will be filled by running the compilation process. For a secure installation the bin directory should be outside of the web server, the file www/routino/paths.pl contains the path to the bin directory.

The directory data must contain the Routino database and is also the default location for the configuration files. The routing database is created by downloading the OSM files for the region of interest and running the planetsplitter program. There is a script in the directory that will download the OSM files and create the required database. The script should be edited to set the names of the files to be downloaded. For a secure installation the data directory should be outside of the web server, the file www/routino/paths.pl contains the path to the data directory.

The directory results is a temporary directory that it used to hold the GPX and text files generated by the Routino router. The directory must be writable by the web server process since it is the CGI scripts that are run by the web server that writes the results here. For a secure installation the results directory should be outside of the web server, the file www/routino/paths.pl contains the path to the results directory.

The directory www and its sub-directories are the only ones that need to be within the web server accessible directory.

A Javascript map drawing library is required and either OpenLayers or Leaflet can be used. The library is loaded dynamically when the HTML is opened based on the value that is selected in mapprops.js.

The directory www/openlayers is for the OpenLayers Javascript library that can be downloaded from http://www.openlayers.org/. (This version of Routino has been tested with OpenLayers library versions 2.12 and 2.13.1). The file www/openlayers/OpenLayers.js and the directories www/openlayers/img/ and www/openlayers/theme/ must all exist. There is a script in the www/openlayers directory that will automatically download the files, create an optimised OpenLayers.js and copy the files to the required locations.

The directory www/leaflet is for the Leaflet Javascript library that can be downloaded from http://leafletjs.com/. (This version of Routino has been tested with Leaflet library versions 0.7.1 and 0.7.2). The files www/leaflet/leaflet.js and www/leaflet/leaflet.css and the directory www/leaflet/images/ must all exist. There is a script in the www/leaflet directory that will automatically download the files.

The directory www/routino contains the main HTML, Javascript and CSS files as well as the CGI scripts that perform the server-side routing functions. The description below lists all of the files that contain editable information.

paths.pl
This contains the names of the directories that contain the executable files, router database and temporary results; the prefix for the routing database; and the names of the executables.
mapprops.js
The parameters in this file control the Javascript map library (defaults to OpenLayers), the boundary of the visible map (defaults to UK), the minimum and maximum zoom levels (defaults to between 4 and 15 inclusive), the source of map tiles (defaults to the main OpenStreetMap tile server), the data editing and browsing URLs (default to the OpenStreetMap website) and the number of waypoints allowed (defaults to 9).

The directory www/routino/documentation contains the HTML version of the Routino documentation.

Configuration of Web Server

The file www/routino/.htaccess contains all of the Apache configuration options that are required to get the example web pages running. The only problem is that because of the way that the AllowOverride option works one of the configuration options has been commented out. This must be enabled in the main Apache server configuration file.

If you have copied the routino web directory into /var/www and named it routino then the entry that you need in your Apache configuration file is this one:

     <Directory /var/www/routino>
         AllowOverride All
         Options +ExecCGI
     </Directory>
This can be placed anywhere between the <VirtualHost *:80> and </VirtualHost> tags which should be at the start and end of the file.
routino-3.0/doc/html/style.css 644 233 144 15022 12520735320 11625 0/* // Routino web page style sheet. // // Part of the Routino routing software. // // This file Copyright 2008-2015 Andrew M. Bishop // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . */ /*----------------------------------*/ /* Body HTML formatting */ /*----------------------------------*/ BODY { /* fonts and text styles */ font-family: sans-serif; font-size: medium; /* margins, borders, padding and sizes */ padding: 0; margin: 0; } A.ext { /* fonts and text styles */ text-decoration: underline; } PRE { /* fonts and text styles */ font-family: monospace; } PRE.boxed { /* margins, borders, padding and sizes */ padding: 0.5em; border: solid; border-width: thin; } /*-----------------------------------*/ /* Header HTML formatting */ /*-----------------------------------*/ DIV.header { /* margins, borders, padding and sizes */ padding: 0; padding-top: 0.5em; padding-bottom: 0.5em; border-width: 0; border-bottom: solid; border-bottom-width: thin; margin: 0; /* text alignment */ text-align: center; /* floats */ clear: left; } DIV.header H1 { /* fonts and text styles */ font-size: 150%; font-weight: bold; text-decoration: underline; /* margins, borders, padding and sizes */ padding: 0.25em; border: 0; margin: 0; } /*-----------------------------------*/ /* Footer HTML formatting */ /*-----------------------------------*/ DIV.footer { /* fonts and text styles */ font-size: 80%; /* margins, borders, padding and sizes */ padding: 0; padding-top: 0.5em; padding-bottom: 0.5em; border-width: 0; border-top: solid; border-top-width: thin; margin: 0; /* text alignment */ text-align: center; /* floats */ clear: left; } /*-----------------------------------*/ /* Content HTML formatting */ /*-----------------------------------*/ DIV.content { /* margins, borders, padding and sizes */ padding: 0.5em; border-width: 0; } DIV.content H1 { /* fonts and text styles */ font-size: 150%; font-weight: bold; /* margins, borders, padding and sizes */ padding: 0; margin-top: 1em; margin-bottom: 0.25em; } DIV.content H2 { /* fonts and text styles */ font-size: 140%; font-weight: bold; /* margins, borders, padding and sizes */ padding: 0; margin-top: 0.75em; margin-bottom: 0.25em; } DIV.content H3 { /* fonts and text styles */ font-size: 120%; font-weight: bold; /* margins, borders, padding and sizes */ padding: 0; margin-top: 0.75em; margin-bottom: 0.25em; } DIV.content H4 { /* fonts and text styles */ font-size: 110%; font-weight: bold; /* margins, borders, padding and sizes */ padding: 0; margin-top: 0.5em; margin-bottom: 0.125em; } DIV.content P.center { /* text alignment */ text-align: center; } DIV.content OL, DIV.content UL, DIV.content DIR, DIV.content MENU, DIV.content DL { /* margins, borders, padding and sizes */ padding-top: 0; padding-bottom: 0; margin-top: 0.25em; margin-bottom: 0.25em; } DIV.content UL UL, DIV.content UL OL, DIV.content UL DL, DIV.content OL UL, DIV.content OL OL, DIV.content OL DL, DIV.content DL UL, DIV.content DL OL, DIV.content DL DL { /* margins, borders, padding and sizes */ padding-top: 0; padding-bottom: 0; margin-top: 0; margin-bottom: 0; } DIV.content FORM { /* margins, borders, padding and sizes */ padding: 0.5em; margin: 0.5em; } DIV.content INPUT { /* margins, borders, padding and sizes */ padding: 0; border: 1px solid; margin: 1px; } DIV.content BUTTON { /* margins, borders, padding and sizes */ padding: 0; border: 1px solid; margin: 1px; } DIV.content INPUT.left { /* text alignment */ text-align: left; } DIV.content INPUT.center { /* text alignment */ text-align: center; } DIV.content INPUT.right { /* text alignment */ text-align: right; } DIV.content TABLE { /* margins, borders, padding and sizes */ padding: 0; border: 2px solid; margin: 0; margin-left: auto; margin-right: auto; border-collapse: collapse; } DIV.content TABLE.center { /* text alignment */ text-align: center; } DIV.content TABLE.noborder { /* margins, borders, padding and sizes */ margin-left: auto; margin-right: auto; border: 0; } DIV.content TABLE.noborder-left { /* margins, borders, padding and sizes */ margin-left: 0; margin-right: auto; border: 0; } DIV.content CAPTION { /* position */ caption-side: bottom; /* text alignment */ text-align: center; /* fonts and text styles */ font-weight: bold; } DIV.content TD, DIV.content TH { /* margins, borders, padding and sizes */ border: 1px solid; } DIV.content TABLE.noborder TD, DIV.content TABLE.noborder TH { /* margins, borders, padding and sizes */ border: 0; } DIV.content TABLE.noborder-left TD, DIV.content TABLE.noborder-left TH { /* margins, borders, padding and sizes */ border: 0; } DIV.content TD.left, DIV.content TH.left, DIV.content TR.left { /* text alignment */ text-align: left; } DIV.content TD.center, DIV.content TH.center, DIV.content TR.center { /* text alignment */ text-align: center; } DIV.content TD.right, DIV.content TH.right, DIV.content TR.right { /* text alignment */ text-align: right; } DIV.content IMG.center { display: block; /* margins, borders, padding and sizes */ margin-left: auto; margin-right: auto; } DIV.content IMG { /* margins, borders, padding and sizes */ border: 0px; } /*------------------------------------------------*/ /* */ /* Special case layout for narrow screens */ /* */ /*------------------------------------------------*/ @media screen and (max-width:640px) { /*----------------------------------*/ /* Body HTML formatting */ /*----------------------------------*/ BODY { /* fonts and text styles */ font-size: small; } } routino-3.0/doc/html/index.html 644 233 144 10252 12563643544 11765 0 Routino : Documentation

Routino : Documentation

Data

A good router relies on good data and the OpenStreetMap data is a good source. There are however a number of things that need to be considered about the data used.

Tagging

In addition to the raw data the way that are tags are used is also important. With Routino the tagging rules are contained in a configuration file and can easily be customised to change the interpretation of each tag.

Program Usage

There are four programs that make up this software, two create the routing database and use the information in it and the other two perform additional functions. Full instructions for using the four programs are provided.

Configuration Files

When the programs are run they read in one or more configuration files. These files contain information about the routing preferences (types of highways, preferred speeds etc), tagging rules and translation information for the outputs.

Output Files

The final result of running the router is one or more output files that contain the calculated route.

Numerical Limits

When processing data there are numerical limits for the range of data identifiers that can be handled and the size of the database.

Algorithm

The algorithm that is used by Routino takes the OpenStreetMap data and creates a local database of the important information for rapid routing.

Installation

The Routino source code comes with a set of files that can be used to create a working server very easily. The full information about installation describes how to compile the programs and install them on UNIX-like systems such as Linux.

MS Windows Installation

Routino can also be compiled and used on Microsoft Windows systems (with some limitations). There are specific MS Windows installation instructions describing how to compile the programs.

Library

The Routino routing algorithm is also available as a shared library that can be linked with other programs to allow routing from within them.
routino-3.0/doc/html/example0.png 644 233 144 351656 11541143677 12246 0‰PNG  IHDRôA^#X oFFs6È *8 pHYs  ÒÝ~ü vpAgŽÌdKž€IDATxÚìÝuTÉú7ðou1‚k„AâBÜÝ]‰»+qwÙdã¾wwWbDˆ$ „·ƺëýc&{É{w×ïÝ„úp§Ó]tÏ<ÓÝ©©®zŠ€a†a¦°êÆ~¼D¼¬_„+Ò[ŤÍÇvªþ°”"pg‘JNË°×ØÎôÈx^¸(ÎC#TC)éa‰žÏXæ£.•.ysÇó™ÇG J(‡Ñ¸Ü`R_h º—é# ÄϘp<”žùW†a†a )_8@ƒ÷È€“G”¦¡Í^²rÓü'MœY«UégÎ{m—)_Cež&l×W7Å Š+²FÀ<Œ8±îõ›øéëÝ·Zs%ù}ÿdWËŽIlÃxR‚¬Ç8q/}OHÀƒ jýÍ0ÿ Vqg†a¦ð)Ø .Â-'­¡GÓ“[Šøöw˜ ‘N([³Wie·eŠŸà ±ûIgŒÏ×ЉGémZLfÓRžm˜¢÷1–:úó«ƒRŽ»ÑýYÇ×?§Ì–Yµ‚<#=…ºŒ&£?Žã2‘#Ì!² <ó÷cw†a†a +b©¸Ã" Ç'âÚ‘ƒd–EÇÑhKÁ g<†;¹Œ.U­Tð˜Þ å_úãêHóaú£zѨàsȯ¤Œ´Ÿì®´YþX½ÜØ~WÌSMlõ•/#ʽr}“SײΖ¨pŸž¡oñÖAQtµ¾„µÄ3ë„e†a†a V+£(œ‰?aiAa®8ž‚µ½Ö:ï7nv7Öz^º^ë‰A¾ÞgIþW^Ÿk7næCI’ =c“%ßý©kºŽã¶£ª¾í´ÞáAèæŸÓòÎç[«æ’Î\urÈ\QTÑ%˜Š+x xp–¯ìaþ«¸3 Ã0 Ãü$ࡇW‘CA%FÐx[Š´Yäè6©C­eŠÕôñqw×8‡óº†ƕʕҟ$žäûñs?_Èn’7hùô;¥^5ÝõìTìÏùyŸô–ý<ˆ¸Bï¡–¡vâ¢õiemðÌ_ð, Ã0 Ã0¿Ã rHÀÓÈÄZ:•pƒBjª…žoÖ§}̹¸óæ“ɱŠ÷º ¿ÜDÿ•Õ›Š>q¼c{¢-’¯7–7?³Û­8"mÒôXIWŸ´Z¿òE‡JŽrHâcr^ÚÒAt(váÞñ;ÈÒ›—‘h¤!Çò °ñ…kqg†a†ùûXºÓX:´¸C ®1 ÂñWzE-EìŽÉ ÒØ>öFû¿Z½K©5>Ÿ]c컡±i£9_;Îf~­j¡h(«pÅÉÃÈŒø)foº–öøØå¦ï}ziÏÐ6\sR‰4„®ÇQº­1_‡|Ö‘¦0cw†a†a˜\ÁþèY˜Žž|R¤ÇhkzÉRÄµšª“¢úÈ*Ukû ýP91pˆËI‡Í$“"?ÄÐ^ð ¨ ˆ“&J:¤6ézvZ´wB½5;ïŽy~éÓ»vŸvX•¹èÃ-#X+>¡‰(ƒãxx–!¾°aw†a†a˜VÁ!­ž°…‘‚V\y²Å/4•-z9-µ]7òEµŸƒÓ}¨d¨¦ÈTT‘¥™7åæõ&;¡¯(³ U®—û™ƒ ÄtýÄܨ6ñg–:ߎ~¹!²aÒ¦´uÖÆ0âJSÚ…~Àh¬ƒRH ƒ föüØXÅa†aæß§@5šTÇvLàNr‰Zp:ÇR¤ÂHÞŽk&Ù×*WÆ¡cRÉ:>ý¥ÛäÞR—ü.ù{ Ò'ü .S#£’‘ÆÑSêÞ-Ïsß;®¬ñâÕºá_Ì™_,û!Â!tŽP3° ‰ÈŽ%—üQ±Š;Ã0 Ã0Ì¿[ÁN,Ap†-çLìIèr¥'ÑÓ,t+þѣµÞ”îܼb`†— À@:R¿ÃXÅ|…Ë!_ÈÙhÅtÙØ¬Á¹tô×Òû¼UýüúÎâ—ËS6k/ê·YöCnq•à@*ãºÑ¢Ôi:ýˆ÷°…-8ä ‡õŒÿþ±Š;Ã0 Ã0Ì’¥¶%Î’b’LÀuüL.’Þh"Þ¡±–Žà~%Ùm&U-æ:õUeVjá9Ôå5@š¡†öNþLã.åisI6é!="ÙŸ˜¾>[¿mÿ½uïêì*÷$çýåÍtõ³¯­m=îTE]ÌÁ}ܰ&—K/ù#œJ Ã0 Ã0Ìž¥ún‚½Qþ|ÙB* 3h=d)ÂÇ“4òÓ a!õ4#–V½¬)]ʳ»Ë $˜˜ÞÍ)â\YMîžäÓ›ÇÒlj®4I¨?nÏ›§/Þ¿'ud1;¶Vtc1/õ—”â"‰-w€TˆTÛ´Sm}£î½j™Î.~Ò/aÝÔ¥a> _?>Ó­]Îý…Á=WGGí>Y¯L§-2íÂ}¸–Ò÷Æ_$ŸÈ04†ß×ä•Ö ñÌw‚G\`4è gíï Ã0 Ã0ÿU<8œÅ$ÂyHâ’IK<’–äÇqʜц1¦¦·ÞÇoû²éŜ܊٣¦Ö÷.^ÏþB9_»÷«²>'_®ï[,³ÊU•DzÙùqò´Ï/3½Ë,VoQÚ®è\¥|ZoÃ)íª3eÚýÆÆB'ñ>A‹\‰/8ŽCŠ•ˆÀ+˜ B´lemñJD#YÖ±‰a†aæ?ˆP@ïÄu"]…Öb5‹ãi8[ÄûgÝb_eÄævÝËè¤lX9ÀX$Íy«zzJHshŠAkŠÔ¹Kó3¨‹Ñ¨eÎ2t®™'•ÙàåºôBm(ïäÄ©¿,øuÑÃkoïžqïê ¨3mo}9ùœœÌ$âl)æb§µ%Þ3öqýyù|þ)÷Î0S(/ú¡\aWHù­*Ï0 Ã0 Ãü»È Ê‚ñ&јÍå’)ä©pFœO7ZŠ”›áçσ´(s¸s‘znã]]Ûª3¡/] ȼøû9’´6º5—oí>ý ø´"ÛÕ¿HfŽÒæY½M¾¹«5Ï_QBê·Ç<¶ØÈ¼Ë¦rÚ‘êÆ6J„²bFdîG×ÔÊ+nD|õæÌ¸7©‰©y±ÆDóËѹQ¤6ÒÄDš†Š¸x|Aòa´ke¼ÿS‡*6òSŸ‘‡|` *!ãp÷Yh†a†aþ%rHÁÃÌDoTãús‰JÜ(V yt)}!è|Š#Jyìø¢åøÒŸ»oot,ð¹|¾J#?ˆ£in¤lþj-5$ :÷6fÈêÕGŸ¸'I©‹‹ëðzÛ¶Š–¶ÞòMï7½ Nouö—ŽQÍB[•kŸ›æ|ƾ…ú²é\~ñU Yåòž“]Ò÷·ê¶¶Áµ·ó?glœø 3êó!ÅKÏ k…[¢³åås/È8â@:¤åáŒv,;Íÿ–Ä^PäÈ´ÖŠ{”…«¸3 Ã0 ÃüKd€³TÙ¹²¹ˆCшÅÅ^üJTs¹=á}ן+o}º¦«oYM¼ÃxåÀl/nЦ™+3kêüȯï|;q[‘³å_µ{ØìMù/ÖYT—ØVŠ›ž\)‹ ì³Ü³tu0Ì\bæÚˆ‰O®½uÿîë´¾nsJœöSå÷‡ge<~2ËÍMµÃóý µjTö q­^l€Û‚Q¥«f¥œ^7à~ѨÑF¿hwËTF”‹O¬D;I_®&9dn/£›Ðûp 6B‚|6cëÄþ¤Â,³†›ô@Yø²¯O Ã0 Ã0ò[jbm…¾õèB´äF¢!*ÁK”оÐà-@ò.ˆ¸•áÒ~W¹…Ý’, ø¬PùÈ}a¼x <–'WMÝš×äÐÈkžo>®zp¸ò“×|¾˜3ÞrnyCpÑ4#û^^ cÇw{>ÈÜ$¸¬»gÑŽ;U¾¥ì=+;n˜øÊ5ùÜt\Á#ìÝõ,,vêˆ>U•Á+:¼*i,ï®qd[Äœ—ïa¬/”¯‹Ã«Ä{põÞï&®ÓF¾«šºî×û£ê^Š‹m™4ëË"­ZHÂAÌÆ5<¥‰ƒux‡ ä~3íóŸÐ¬ˆÿý¢Û­gܼÄv†a†a˜¿A 8ëò@´DiþCýuÁªCK÷©;#§µhj¯}pq爧”F˜Ço¦ôÖ¯ãNPa¿-ƒœ^7´ÚO[†\¯Õ:¸¢÷%‡·÷@4x‰i\or—(ˆ‘˜Dz¬}âWŸEëæQ]dB…pï1íUµ]ýÎrMH ÞɈÄû¹àÞJz¸L²û<ïXƒ‹~é>Ù«[+J es—õ-™¿oVµ^G(ß¼ßxJ—4äüòéÈCí.L(^³té ¶ãä}¥C î¿MRIù ÷°ÞºJÁRLþÇt«V:±¸õã$ápƒÅ„ù†¥7ž]„ Ã0L!gi_WA)Ú¡6üÈÒÈSÒ‘Ö"Mp }+t/ÑÃååÞ×3§7‹Ê¥kŽø•Ò»''€Òˆ ãC(½_b‚ñË´“†ø­3âEõÅíÜcl—<‘{F¶î`<¡rÈÀ£(œ¡–´åD£'líšS©2ýòðÅ$JidµIõ‡Ù·m_¶C"‰à劒V8„™ü¯ä éYð(þµÇhn®{ÝÊ·Ú¤Ï×&]ì*Pº¸ÜÀÞ”ÎÛÜ7;ïüŒ#=—Pºàqÿ•”.<> YLؘ·ƒÇºU,¹Ùe”ò‹¢zÁ½qÙd)†Y¨‡2ð4Öä’„¥ÿ7r<äK@†5Ü]H|`1a €â·K,‘p'ÃÉp#«È*4à £u«Rv12ßœ9_ÛŸÞâ-É:²Í œ9NìÌaæ;c`jÝèë¸Ö¤Ë_l9¨Z~ñRGVÌ_ݪ~ÝåÃ#Ó(4¾¥·‡õ¢ô^« ýß>Ü;«oóy_ú?ª¾ÑNÑ>vÚ‚{àìÈ*|â$R²íÖð¿Ý]-+6ð“9ëÖ²F¯ã)½ó0ì}úÐÒžE SÍfÖ}n$ÙÄmQ ~p„ äÜRÒ :®)ƒ÷÷é÷Þ±½fÀü„†}*%®šP²ËJë&˜–ÍiÔ'$?bV÷^×éàyõúî§tѹäÍÎÑy6Œm]½FÉyξÊfòãß¼—F$1ärqκªà„SÌ?gr½ZÆ2kˆ“>„µª2€ËâP`•=‹ ówœ9íØ™Ã0Ìw†ûÿÛˆ¹=„’@lÆxÔ³®!d ^6®ÒÏû§‹~¶k?Ö\éÚæÑ)½ç6¡5¥wž‡)½Ó1ìX²Ãn&ŽÏéú¬’OÑÎ{Ô6ßì¹9‘ãæ£ jÂ×zlîÚ© ð“¸-d¡eEƒÎŒ^~Zï µFøS¹}RóݶÓÛ7ýˆÙ‰¨‰’pÇ.LG3ë>-¿›ÀEI)lÆ8n i„ì‚ñ©d?WÝbiµ&é!{3í§fwGéÂŒ)?¡ßfmß™>=£(?µßBJw¸":xtÅö'f×*V:Ùv–¼Ÿ´kÁ½I¶s=È |Æ$t¶®RC ;Ñþa‹k4vªäjYæÕd `1)Ô,³Žá‚á¸:žv<-âNÝ)à~Ìý HQ¤kù‚m¨ ³{ámYtèèÐQ"wÙî²pßî¾P|Q|!ÉìÌaæOç¯+Ê 8„$…„!šÌ'ø¦çz“•ݽ?Ÿ=òÓÓv¥ÅÅáÇÆè)X4¾/¥·VÛMé½Á&¾¾÷zßž3:÷ÒU9n¯SGʧ܃d#?…“7d žXWYÚõÿîN%Üòš8XZ⃪z÷rØŸy(|@J#'‘›Ñk²:ÿ¤ª¨(±öªE8Æþï¤iË'¯…üò€t(XÐWïð@Óú§^M‚BºÅu óìIé’ŠƒJ˜+ÍÙÜg¦nÊÌýjQ:ÿm¿XJäö?þ.ll|'Œ®R­|ðM¹ú¦Í–o{ﱇŒÃU,G}‡»uÏ:Ôü6Žjí_Ýϱä2iÊ‚Æpí¹önY®&­&•;²óÈÎyk»®íÚc‹s¢s"I€=ìÉg2ˆ B}1Æzæ´áÚ`†õÌiW­ÔxÔí¨ÛÂá붬ÛÒ3Þ9Æ9†$@ 5ùD†!hÈ"Æ0ÌÿXj+–b(jñ·¹h²ÿ¯ 6é]¹÷ɳE—Üj»˜¶ ?6–£4Â4~'¥·3ÃFSz'6LÿÁá`µþƒ'TèQɱˆÔi–ê›AœäˆÇä é‡p…=”Ö Ü?Sa%µ‘‰¥–e%'_%éô˜üº¸{OJ¬™x6©Þ‘ô'Üò]•›,ƒhI¢Â–?Üî·×PÞp#¹ ¸FáÒ×£Xøl³¿¬ë_?»‚WÆç©qÝ{QºÈuÀbziÞ¾÷uÑ3ãz#ç¦ö@éûAN¯U£üÛÌð¨[ºl´Ë2e¦<ë›ÃÖ#GH}Ž#2ܲ®’Y_ «þ¾}i«×­h ÿd‘±,&…Zk´Fk Æ`Øä†âY•Ô*©|ÀÙf¯·îͺ7Cû8p:`ÄÌÙ¡d(«¸3_‘Ïäó×ñ¥u¥uÀ‘›Gnn8³!kCÖðIŽk×ZÏœî¤/é‹,b ÃüXZµí ‚ }Ñ%9/² é¤<’¿VR¥%ùõ\‰g«µö9^jµºÓVý/W‡Ž)½;~|"¥SÆ·¦ôv£0åÓ [7õXÚÿYËÚ¥Ž8¶Ð¼Rh ŠÀ½#‡ð† ÔÖ¼çÿ_oõR-”AÞ‹ëAú[V\)½‚ï0‚Ò£'nÝÃûu¨êùØ>Ïú¦’F¸úìßRVA qÇ çß™X°Hñ]>ê Kl¯ªö!/ìyç0JŸxœÒù-ûMÌ[5ãdÏ™”.Ú¿¥‹n 0¾WŽ ìä6)³Öõ2-<[ÙVF~+²‰TÀNt@-”€lØÊüŹ =?6ÊE 8BÃÇ3™ 5d²ÈR×q×­×l1Y1eµ×F\ëä¼¼Ùòf=r;è<  šíDÛ‰Üs2†Œ!uqgPœ…±àb¸’eYnö²ÙË %×Zwj@¯aS†M©ÑÚv¦íLî9‘^"±hÎ"Æ0Ì)Ы۲¢.²°Œ£\#Ò鯋·\WÝ¿x¹³Å—:·ëGé­ñãNSz§sØaJï¬ {NéÝnã“"Wþò¡»û V«JCÚÿ¦‹KåBHS’F&àu•¥²þhG–ã½ÉSÔC%xîLÑ5éBÓïš&Ô ô¶)lb“:•=½­ùÔÉÒ7ÿál‰·¼»’ÄÏ9±Á‚ëÝ_ªïÛLÕ¹ÞÚr'>D輊Òűƒ¤‚ý\UŸ›ù‡gµëuSl?w_ß*”.®>°RÔÄš]ÛÎY_,ŸäÓÔ¾…ºô7G)K¼ðœkIJ!jÈ~¤ËÚâ¯9÷55³ °±P‰]é…ôþD‚Hxð *^Å+[m;½íô®—ÏóŸçÇŒ«Y­fµ†Ö4RÜsî9÷†EŒ)ˆOä%jËrß­}·¼–™™Ñxú–é[æ‡[ÏœÁÜ`nê¢.BYĆù*Ø¶Ý •áÃ/á’o2šó¹Çäx·² ¶l¸;wÃæ® ¯¤ŒºCé½ÚzQñö”Þ¢ãÞ=í»ur›K¶¼TÚס–:Y¾¦à~H:™Œ·ø€ƒ€òð‡‹uî¢ié+áÄu ¡–YZ§ïìU»JMJo%Ž‹¦ w~ ‹²¾Í„2Ö1iä2ióOTÜÿêˆÖßÍPžÄ «1’ëMª ©`A¯wv U}¦—®ëZöЧÁ7u­Hé )]P¢€¶Ä mÏS⎹Q}ÛRºäæ ŸZOØÖeÅÜI +”sô·©!ÿ6N®9@\ð3†ZWYž\NK5nYK¦â‹pƒ¬«ò0½Ùõ^8‘Ùd6™mYv~èüÐY»7}oúžŒ+3¯Ì¼´¯¬´¬´t%¬ÅZ%‰$‘$B9{ˆÅ|Å_à/ðÇ,Ë=ô|Ð#2ê—¨_^ÝšL'ÓIe,gWƒ«ÁÕ@(BÑ‘EŒa˜®@Û°+ì¡$~ˆÁl¢'3[° âª¬-¿©M›šjßRW§­œÕñ$¥7¿ŒkOiÄ®ñ£(h3¾¥wF„Œ´ß<¢›qÄÝö[ʵPdÊnóßT|%Ãø.$ gðÚ[W)!ÿïV(¹fä±¾ën}¼ Ћͮ§Œù™ÒˆSã§üÜiØ…Ú›áG(ÉÒ 7þÍ]OäIXIÆá*~–¸q.dUÁ".Nʇ åŒÙu§•sxë5VÞ1Ò%û-£ó<ú®×þbÍNãÞ¯¥ ðH(6>¬³qJFíƒenúÝp,£ù¥àÞÈ.Da;YHl@ƒo¶r…¤6ò¤Ü°um&;èlle±–þLd8.|;)<ÈKò’¼´,{íñÚãµçŒéŒéŒé\õsÕÏU÷ºçuÏëäCNz“Þ„}Ác¾Áoç·óÖÙ—CÅP1TŒ.]*ºÔôäéÉÓ­ùdÈur\Ç0 Ã01†aþ dɳNê ?ño¸ÏähÁ"|(7‘,ïOš'–oc}É.S)½qzìAJ#RÆo¢ôöݰ.”Þ¾Öæá¦_%¡½+7m¦š¡¸-1ÜçDV!™Œ!®Øe]õ57ùÿ¤ÚH:€be¹œ¿ß¯Î{ôQ—?Œ*CéÝW|ÏvYò¡ím8òôÀýÿÈ‹(øTÁŽP“xèpžœE¾æ[$V³ÝæÓĵKOûÐ"¬w§”.5à¥óŽ÷C¾Ë,ÒkžPq®}Ÿë”þ´~p‘íøÄ.n‹»7æ*… én“ðÍgÚšœ&89QüÖi§0 l5êCûãž«l7ª¾žo‘ƒ³ì>P8q]¹®œ5÷j°"X¬¸'½'½'=RåH•#U”­”­”­¬E᱈1ñ5ø¼uÈiÛ~mûµí÷¼ÞózÏë-Œ]»0ÖÚÒSUQqYĆù—œ)GëJPÍTÌîÆ7h°îÑÑ_+ww ôV‹qÓ(0ßCéݱã(½AÇž{òf«mî{åÕUíWÜ’* î‡ïÉ-#SѵáÈ!ù· 0ý×­ÁhÔµ,Ú ªz²FÙÍÏUMé½¶F5Úµ¼÷HtF%x_Ä`:üà»ÿø«’€$àq¡hÀ?!Ùߦ?qÞ­\+¿<%©vB™KïãÇì4ƒÒEqKP:_Û_’ûlFóž!”ÎoÛo4¥‹’–ýÜÒò®yóš6ØSa„·Áî’ê›ö|)²„à!†¢*¡œÔ­ÅiC¾†ê” ’ÀC2Ô@ Ên… ã3¤²Að ÃüÓ,U2L°SÑ®èˆMînö×T‡:GÕ¸¨UõÒcËšƒ¸VÄç´%@Þc< ¡¡á~%LÜf{nÙË{‡Þ^ïã`Й4ÂeËîùÙÜn²HŒ¦ý¨½°GœH‡[’* "þ<•¤»x…Ï–hè*é?›Ö&4ù2(7ª4œ–«ÚjҕβN£m¯)®¤αӗ"vxŒ©¨ˆÅÿÁWe†"(:ã® "ÝO¯‘\P\&OÈPÒ9­Žn”¡ñÜõ[í=x{}`»Jö£úרÔ! ¯ÿ ÷ŽÉ”7 35ô0Õ3Ìs¹«ú¬x>3¦q½JºÁ¥BŠÖüåýÃÓoÆoïóØ+Æ3îVVù¼qr Ÿp\!]Ñ@ÜAÀ90@°VåÿLŸÞ?³i*iÊ'ª"¤«~ë¹55H »':J(¡¤éDjMöä°Éa“Ã&òš¼&¯³d5Èj€EX„EäyFžá Þ€ Ne¾%‡rË¢åÌ!“Éd2™V¥UiU¤! i@ L0ÁÄÆ0Ì?‰ŽHp c8xLvœ¢ZÞhh#ÍYÿ•e«šGß|›øùù<@¨-”§åÅ~ÔtçÊþcãŽ{¦¥Ÿòj1yò¤Þ»Ÿ^š]Ì 3í.“÷d$^âæ¡•°QEЃԌáÖ–[ÌÂJ_r¡·¼*ó¡w*ùlvQ-HˆÒGñT2Å'Ó£ŽíËSâGbÿkn–hY~j Å1ô儉èʵ%åð!5KWÅPñŽ[/ÜêÛêtnÉ„ÌÓ¥#6'FçÖNWì’÷-àb$fÞ&¿ˆÎÉpÂe„ê‹}è:†ŽI;v íò‡³F~œqÔ»7ƒžO®ßpk‡ó‹û{~y#÷é¦OÅÒMÊ`…·LÈm¬5Ô2¸‹(=ä#gðMòBb®wèŸÞüØâýKW (ºJ“«ìCG¡†Ò(^Ü6Ò\Eâ…×ÖÎOpßæûÿs’È.Ijñ¥Ume‹$j¤¸AÆ“(Öǽ°QC µ¥3 ‚Œ`ÇÁŽƒ‹¹b®˜›y-óZæ5$æo°…-l-‹dF†‘z¤©G-ZÑVÔ:¸™ê©žêÙœx ÃüÃä‚'§¸¦äšØSäèÆJ_Ç»ž­Ó§Â@ÏvZ‹÷\O^7-e_гÔNŒEÆÅ­Ð@,K;‹Ý {kÿx‹ï·ßs ² #H:YŠƒÔ@ÍïÏ|rÊ–áȾ éDŸâî¥lÝ‘-Dr›IW¨p„J¡…þÞe±`äã‰<Ú >è ØÎ¨ÃËÈR˜Þ1¿¸á×íx‚؇†¼Úýa]×^¥¹âGË«ÅÏ+w»È:ç39F*j{æ®×Ù{ìÑtPú‡+Èú^«ÐÂÍ6ÏGƘ~[ü}zçå“gÉlV’!»HUá<}E}Ñ{q‘HBDôÏvfHÀIêóåUi²ÅËDåÛ0ÕPÓqŠÝ ;Ø}iÎ)9%§tÙî²Ýe»øX|,>NU§ªS¿>düÓÆÌŸF.r‘k=M¶Ñmt›eˆ*iBš&$ŠD‘(ËV¢ ¢`§Ã0ÿËW}O¸@-Rq:-Ž‡èƒ›½6õ.Ù‡›/o*±·í%)ô¢F¦"óM–Þ¼F2ŸoDŒæVBej a‚ðÃ<1 ‚Ò8‡ç–L]ic³«ë/’²‡éÊÕílú-áâ©[T…Òì#:‹-1 ³´ÁÔ?a]Ï2°ÕÒòŠÃ¸)€¦7ɼÁvî(yGöh9c óÈmxŒì¡Ïº¾«×§jùSþჄ(£+ï)¶ÖM˜™3 -õ Áe‰ò˜âÒ´ÄFÅ+þ4¸XÈýÀ¸­òÇ­Þ®ÞFçŤ½}˜Þ;g>\Ü'›ð›IC2ÝÄíô><ð yÐý‰¶RãÏžCÌCM•WZ'º—ÚqëI*»?:ÍÑük9ÉrÉrÉòÃ6‡mÛDž‹<y®TR©¤RÖyÑH{Òž´gcþW•«ÊUµ,‡´ iÒæV‰[%n•ØÞt{ÓíMízÛõ¶³æþ'-IKÒ’EŒa˜€% £—1?a(jy~r9¥¾Ÿå~æá0:0¢Ìø€¤Gö ¬å˜iÛZÑG°åˆ¢~ôh\i²yPÃ2_Þc¹í§÷Uöoè7Ò‡'½¹5yí…ÎÇÔCl¦JûYÊ“aÄÛ¾›·gy2ky:ë ”8‰îhÈqDŽ[ Ú…̵—¹\¤ßáçÕG„´=Jéü›ýSºpÝ€¢ºÒ3'öò6GÍÉês„Ò%§û´hbr×5+v7;^ÅÏ+ÍÎ_Õ«àÞølNFf“ZØ)ÖU6þ¯¶r¢5©¦9$%}fYEkàœFh dw‰B¤8Š£¸eQ¦–©ejÛÛÛs¸9Üž±!cCÆkÉ)ÿæÉH†u¢%aˆ0D".—‹Ë¹±ÜXn,YCÖ¯“„xÂÃ0 ó7XÚÚÍ òvÜjò“± ·‡NoXv˜]²ÃI›ÃøPãÔ‚ˆSïËg8äœÖ'öäÖÑDcþÝ1¶ÄTœ@òaL£Ù~ú É´E¬Ç…¢ \Æ©k»ÖrX¦L„=Ô“{X‡ÐïçíâkîdäB‡®8„pQ¤ÔF$£µ¤W›Ì¢ú|cÊnɳÊï:‡dlŠ:}pÈý“k"ê=¬ž û’`ó¦«\ËI\¸vù~ÚHýyµfºM©q=k¿,“÷T5¼vÛ{‹tÎUªÔßy‰]ÁN4Ò¹ô6úb ™…;XMŽ#{0•ñ5û"ÿß>¯8@œAßÛ•çH«XV‰‡h[Ì@\`Ïî…È,€5ã‡K+—V.­dkdkdkÒÖ¥­K[g˜j˜j˜j-y÷pŒùJ(¿~á'2"#2Keª¨ŠªÐýÑßZÒ#Œ,` Ãü](((ù…TÅi±‰xŠÖvÈ×l—?m;º–Öw5Š2ä²~¦vœñêÆ1'ýž·Gº ð9Öüë?tÏÒȱ=GÔµ3~I*–º4O`9úx¤;%¨^:¾ÓlU¢è#1æ¯Ñ=tÝcYΙ?2¤ñ ñ ñ ÙÆlc–=”=”Y·¡j ‹Ã0l åÊ“=DGO‚èÖúu|?–zðÙµ>q‹È—kûíMhõZúÁ/cš¢ üh)Ú{¬ù×lã°7øÕÜ n Ê¢\RÆd]È_ŒDÚ«nvýl’Ü;:¶U6³'-PþÖ¯4߯¿ú*Fw¢5¦‹é4 ÕPnp䛒änÞec¬¹ùÎ~O;Æ>©wu[Þù&½•¸•þôzRZÚVùB©œ?/É–†J¤ÚÃyyùÅݧi–Ù„U®³©\·HóÐS­.kÐÔ½2|+9ôR â8zD,A—Ñt.–Œ'EH+ÂL4…?Šþ§Ûà9€¾¢>¶µäOdîȇ fúC° pb² •©˜ k›ºÓ§)NSdf™YfNß¾;}·¡¸¡¸¡¸õQãC<ÄC0æwxcô7úý…ËÂeá²lŽlŽl¿œ_Î/·–ôƒüXÀ†ù,• ¬GWaŽJ'I÷Jjp#º»7Ì üDzóm¸Pã0Cys©W.T|ÝÞ\M"Æò®逺C…"J‰H…qOñ)ÈŒ+ùi@ödxÍïq2ïnc5h „ŒfÒrt1œ` ›*–Á£(DD# ÙÂEÚ™Þ ýp‹ùä©§3˜> U·&>îs¿j×Íü™=}ÝuÓãáÚ„5_bT•õPœ¬$“ ×ô‚Qê0GÑWV~ÂÕz(WíÞ²ÁÝZ×ÞoY±jnÕ¾ž/‹ÅèRšDÏ  æc(j¢Ì É)I¹µÍU M›Ð˜j0"°ƒ÷#‡©È…FqAgó×;öÅÒo€ÁRa¦ÛÑS…'´'½íhZœ„ÈqÓ˜*JÄ+»Bžî|çß8oç’KzÎ>°ìZ¿‡üÇ©+äÕ$ç¸'¼NvYRW¤‹6ÔqÜn#ȬRgN¹ök÷ mÊí;¯½¿ì%·óÐÛqFäè4Ç5%äy…L·Î¸+·ÎØú/Vá9€>§Áš¥òXi’t"ã!¬«L¡aiGŸ˜aYáòÑå£ËG™D&‘I2ªfTÍ¨Š¡Š¡¤!iHâu•a~O RbYo‰·Ä[4œ†Óp®W„+Âõàzp=¬% d|g†ù8a‚€ý¸†w4 Þ˜9<½²ÜIÉuÅ]é>ì[С‡‚oì‹ ÍÙ¦kf¼Ãoâò‰?]G3Ñ¿ÍAAšN+a¡%qaÂʔṓò–苚‚ÇFz×o³ÇQû’pÊù8 w8üðiH v¦IFò1§qW4Sêà:ú¢©¤=BveMÓ/5Æî÷|Êûq•ƒ6O>S»÷œ£·¶Ý[·ês’"Z¾GªæwI.ñwu;òFëÖiÎÊÎHªõ"ç¬x bjýø×„v65ëVY´–s؉î£ZZ hOšã f‘ÏÐã"V *[_Ï?5c«¥â^Ѷ‘üä¤4™û‰»#ˆ$NаûF¡¹à)ÙH6’¨Šª¨ê\Ò¹¤sIù ù ùŠÔ²©eSËZZR¹/Üî "6æwüŠ_ñ«eQÛAÛAÛÁ¨2ªŒ*¥L)SÊdSdSd_“jÕC=Ôccæ‰AI4Œ't)݇HßæZ;u›§5ùÞ¦F1–ÞÕVÈÓÔÛ?ëô*PÂU±¥ÖÄ‘…l¢z‰*èXKw‘ØÁIyYÕµ)ù£L"@·ànÀLïúö’ýü=n¿µÊh …î¼2X¶@ìÀEóqñ!íMáqîÄ‘àaq÷²g¡ïÆ×ß»½ù…ES÷]ºêv¯z|¹/­•}mdÜQ>61”1%A@<. ôªV§¤æÚ¢~¥š•Úy¯ÃÒÚ +Ùqsr£çÑó¨$hDL˜a\™K<á %äÖW%ÿ÷7à/FQoRv[ê/Mà—péÖ-¬«L¡ÑmÐF+ŽÇâ>îã¾½Â^a¯0›Ì&³)«CV‡¬ÐB -Æb,Æâ ¾à ó; ¶¸ŸÏŠgÅ âñÈrÜ@n 7в•hˆ†°¦†aþ˜rH¸(Ò—<‚3Ú`cè Fgû;ÞuŠUe?—ã¾¼±=fûÇõ©3òn 2‚áŠFÃqKâÈÂ0êNØB€›˜šþkvKý©Ì¹DÀ¯¸WdƒÓpU€]¼Ê_VÒ2m: | éÙE ü¶,nEKLSh&ª iÈãÕd Ö?4' yÇ\_ŸŠRôö'®‡>=À]¿vûLÜÙÏMä¤Nüy=…£L¦;¤É_hóD2‡ï×»jåƒÞ78·ÈÛ¹²Ã’ÚÅ*ìôèíxŠNB5ôÕt6ýÈ 5‘Aúá,¡=‚Qì›®4ÔOé¼kýì>Ä„ÝîlãrZåª(c-߇1›Ý7 …§xЧA™ÄIâ$qÚ|uóÕÍWÛ=¶{lWëi­§µžZ ò| ÈÆüâH‰ef¸u9êrô”ý)ûSöWdWdWdÅSЧ·Vë9žã9žEŒa˜?BN’f¸'(ÀÙ½R%È^>^ÿëÆîèÏÂø³ºQ×ÈèZµ5etE~ÁŒA#îçAªÂrH uÜ‘ž¸oY>å»hh›Ñ”Þ]>Þd”_¹ÌÉÉÉÉNξŸ}?ûª%S)íM{ÓÞ,bÌ¡+è ºÂ²œçççmècècè£ R©‚­E›¢)š²ˆ1 ó;l¡‚ŒèÉ%2ýÐ5ëêÊ/ò\]þcÉuîý1žó$«ïëž=Ojü eôþ/a†:T|DÛ ˜ iÜ,#ÖR = †<®B²Sö`€æc€”J2¸îþ‹Š~´ÿZü%v>ìtû†¥{• DëÀÖ{臥Â&ZŸžÅ*4G¢%×°ÍPa׃§Â»-¤éöCÊ. õšW *RÍivàÞ ëh}zš<Çtâ”Dë+±ùm`+á„4’z¨É¥ÒFÒñ|'n}é¬â^x,ÅR¬¶œ¬šhM´f¡&FcÛ8¯V^-ݾœ9r)©Mj“Räù@²HmR›Ô&ăxX§Ñy€x€8€˜‰™˜‰vh‡vB‚X€ ‘¤ Ѳ( Q.Ê…{œgGr¹'ܲzèá 5ÔPCY¡<Æ0Ìßfê'(ÅŸDšŒŸ±·Mh%-F‘šd§àb¼.D”„wx;ØpÀ4@xÂwã“ ô)Š`z¡Žže’)<2‘Ãë/ñ3úâ1M¤Ý`¤ð­ý&ÙlÅà[ò„lAOË`Vvêýn<ÿò;F˜0—ñˆª(Ex‰7çIVkóL?™SOÏ~3!qx]Ÿ­ÇÏ¿ì¹üˆíÍ›×*¼µûè,¿-”Ü‘5–%Hºå·×rúÊ_¤#ù~µåÂ|ßû<8¡Õ½ÝÎ#ë´­WÑçû@º 0FÔÑ<Ô nX‰á$×ÑhÏѦ´8í&=-u”ƒŠt<ŽB+éÇ­ Ìð^ïPñøŒ¢!1Ùšûœù{è l‚ËxhN?Ò1¤,~Áx®8qÅcº¡¸³÷øóÑï5Iß)^êÜ »»^V†{ƶúôÜæ¸,@rŠ/ÁŸæ/›!æÃæD±‹8³gjH~À˜«aý65;w¬_7±~b ÞN®MéŒÃÊS3ê"«qŒëÍÞÖû¼ôgiGI^õÁ›^Ÿ¾{ïñÇê©+Èy|À>Ú>èÎ>©ÖS<…Æc<.Øm´ÛHL“FLáwÖ~©ýRÿ‡ÆáÆá†3Ç,;Øþ`{æ¬Y3øºæÃæÃ†c&ÞÄ›Ï {…½Â^ã>ã>ã>!DB(¥”þgnk°k¸T.•KERŸ·x‹·–a‘ô}E_!ш¶T:ƒÄà^ᕵü;¼Ã;E£hâ‡8d#ÙÈCò¬ËÈ@rƒd! YÈüÿ~Ò‘†4ä£ š >ðùÈ5Ô ˆD$¤¸‹»p†Ü`[ØÂÁZ9v€`Øüá²ì`g]v‚œ€Àö°'¾Ä—øÂ npCAxÃÞÖ’%P% ”DI”„J(IIR’”„+\áŠ`#ØúÕ«<Ê£¼%b¢RTŠJüŒŸñó¿òq©GªGkƒÖÍ|ï:Úu´[ÈêÍ«7¯jû¸ùãæqsÓ•éJñ3]MWÓf˜‹¹È`—#Ãj–Ê&¸d®"i*zˆéÅ_N8ÝðÈ +;–7t4-¼³úý—“ÝÜñv,ù•TÁ:ˆ>@+Bk ÷“º¸DCé 4 Øêåeíµvç«>3ùQ*QæyûãƒÌ?×þ4*âð"âJîb<=BôÅDlÄm½RÁ/vƒçud>ñ t"}kY-SóE¹Ín•°÷<:úfµ´àþõw—ºÏàÉ:I7äOו6“ÜæÌd®ô†|°l¦¾£Amt½äs8)ã§·ðB{7úcû”ÕäÂ*‘@xÙ?Wì]þíb~|ð€Wq•sg‰³D§b‘Å"kt.þ¹øçñ÷± ñ$ªsTç…Ux.ð¬QÓf´ÍèàˆÜ„Ü„´éù½ó{ë í í í´´´ô·õ·õ·u)º]Šn½n½n½î˜î˜î˜~Š~Š~о‚¾‚¾‚!ÓiÈÌ7å›òMú™ú™ú™ú^ú^ú^ú}€>ÀpÅpÅpECCC¯Ñkô]¼.^Ÿ?"Dþa´0Zm™êùÀ>÷{÷ø‡#ÖýÑŸÜ$7É|Áì¤*ª¢€³<¡š´Ð\BúÑ,š…º´?íO;á.àvc7vÿ+åQ‘øµkÊ?ðW–/'–¯4GpG –$)$…¤Øl¶Ùl³YÒKÒKÒKþFþFþF.—Ëår›6lÈ—É—É—Ùt³éfÓëÃõáú(‡*‡*nÉKÉKÙM êÔ5æ²Ø[ìýdeº:]íu¼Ä7ÄÙ®S\§HïIß“n¨Àõàz ßa˜BÇRew +ðYl!n¤å=BˆÊ£QÉJg½÷¡”x†.Ï·×Ý7MÚrvÅË©X‡q8B)$à`‚¹ðe’ùg8KL²šæ‡’¦×ÉÛìU‡ Ž6¶ƒ—+ömœR§g­Ë÷'çHkÜ  @]¼’å©…¥æ¬ƒÔRe'æc7T'©Æ_„FâÖS¢“p ÑHXÑ.,Hô®1¸LHbàÚæ/?x¾H™a´Ñ F Cº¡QÏR5}Þ·XÄsÔÉ+Qâ¾ymï¨pi¾&sc -´áGâI§Ð)€‘ y#Ý$ݤ¤ß¥ßeØÓ1§£á£C3‡fü[ÕÕõ!Í8Í8YI$Hê!™.™.™.Y'Y'YÇ—àKð%¤·¥·¥·¥nR7©›d¶d¶d¶¤„¤„¤„±˜±˜±˜I0 &ÁxÄxÄxÄXÆXÆXÆXÞXÞXÞXÉXÉXÉTÝTÝTÝ8Ó8Ó8ÓÔÐÔÐÔÐ0Í0Í0Íàdp28™“ÌIæ$ÃcÃcÃcí í í } } }¼éyÓó¦777äÏž;\ÛCÛCÛC_F_F_F[R[R[2·En‹Ü†–†–†–ÚCÚCÚCyùyùyù:ª£:*žOŠ'Eƒh âqƒ¸Að<Oñ®xW¼+¬ÖkÄÑâhq4¶a¶Y«¿*¨ÐDz@zàðDë„uØ'™*™ ššâvq;fö ù:ÒßÚj>‘L$ùëüuþ:™L&“Éü~¿ƒ„‘0ÆÏåçòsÉX2–Œå³ùl>[=N=N=NrLrLrLù\ù\ù\~U~U~UqLqLqL‘¦HS¤ÉÉÉ©ÒTiª4É]É]É]uWuWuWþ%ÿ’©ž¡ž¡ž!   .¡.¡.ÁãñÇ4n7×’kɵ”?—?—?çs‹¹Å²j²j²j–nNRµT-UKR…T![#[#[#›$›$›$k'k'kG6 dƒtœtg²o;Þ‹<yfZŽÃ;‡w†û^õ½Ú4së°­Ã^„¨Ô È8œÃ9ªg"Ã0p…lÈDŽ`8¡ŸÛŒ¯ÙÜw¶OÇbsý0ƒ;DΟö¾íüNö®KÒ•ìUpÆPІX3n±*ûoŽÓ[ˆ… Õ êîëk›F~l•º8o›¼Ï9¦9¬T+Q/Ubê‚,y¾„äÓdeýeþu–ÈOEÌÄVa•R f¢Ê“fØéxT˜N Šæ:yñvrbRƒÅçxܘT«öä2­ëÍóiåÞ÷” ’¶1\Ö'¥àb‡Æåt~‡¾©¸Û­W“¹¡3‹}¡QE A2IJѲÑä…>Bõ!Î.ÎnÇð¸½q{?¤YõeÕ­u»³vgEvÏðÏð·yo»Ãv‡ÍA› 6”ͯ¯¯T5T5T5ä ¹B®Py«¼UÞêÇêÇêÇ6{möÚ쵉³‰³‰““““––V”W”W”WœTœTœ”—‘—‘—Q¼S¼S¼“½–½–½V$+’Éš»š»š»®+\W¸®°1ÚmŒ‰ƒÄA¹T¹T¹Tô=EO±ØFl#îw‰»èsúœ>¨@*‡ŠCé\:—ΈĂ`'ØYnLb±‡ØC˜.L¦S_êK}óä/È_ ÷Ñûè}t¥t¥t¥òüóüóüóóóuº]„V¦•iey¯ò^å½ÒnÐnÈÝ£ýEû MñJóJ»=Ûw¢ïD"^/j¦b¥º¾¾ñúFšGJ—”.Õf©Õbº2^¯é/Ý'Ý'ݧT‚JN‘N‘NQßQßQß‘ý,ûYö³*R©Š”í—í—íW6T6T6”š¥f©Y3D3D3„Sp NAê’º¤.I%©$•ÛÍíæv““ä$9ÉMã¦qÓˆ±#v\9®WŽ|&ŸÉgKurŠœ"§¸.‚‹ [Ȳ…ïÄwâ;aV`˜?̦ãè8:.~þüüùBM¡¦PSŸ¥ÏÒg™ÏšÏšÏ———¶¶¶Zb’Y&³Lf™ümùÛò·QUQ•>Tª}c°1ؼpÍóÈóxï¡x®x®›hšašaøì¶Öm­K;ãuãu¾"ôÐ ðR‰Lv12L¡e=è+”ûÒ©R“ägnG÷mfV'v`¶ÉÏ 17Ùßýj7aâXjCGJd¼ Ùn6 ù´ aAôWœÃ ,Cq¸æ•È2Ýx_ê“WÖºê1!‚7ò4ä=4N骕/òßÒ>á‚zÄêîÿ¾¡À²&˜±·ð‚·:£ ‚P”MòÈ$sIQM‹^»Ÿ>áÞáÚ*ã%›QyDÐäf fz&ÜY.Rß'Œáå·-îum|eEX´ ‘.è‚Ï$‡ä`SÞÖ¼­èsyûåí™Bu¡:s¦rªrª$)B!5,xÚôiÓŒTGuÖ¿*e݃¥uA‘ˆD¤u¹j Æ_–xOâ)k/k/k/SÈ2…<\.—•••­”­”­”ieZ™V>M>M>M1C1C1Câ+ñ•øÊÏËÏËϫʩʩÊ)æ+æ+æ«*ª*ª*ZÚ€5•5•5•UíUíUí±ŠXE¬r‰r‰r‰ººº"\®Wª”*¥J=I=I=IYZYZYÚæµÍk›×ª+ª+ª+.¶.¶.¶üD~"?‘ûÈ}ä>rœçÀ ç†sÃ-#c¹õÜz\Vx)¼nÜXvcÙÈs>|. +o×Í®[‰—9a9aË©sÕ¹g×Ôˆ¬¹8 ouÞêO#q¸ ´-AKˆÅ‹âEZŒ£Å„•ÂJa%¦Ñ4ZÌsÄñ²xY¼,&ˆ b‚e(°¸CÜ!îÈnœÝ8»±y‚y‚y‚.M—¦K3º]Œ.z½¿ÞßÒUɸӸӸS7P7P7ÐÜÉÜÉÜ)/>/>/^Ø l6äÅåÅåÅwwwçÍÍ››7W(æ†æ†æ†ŠËÅåâr}{}{}{ËCgCgCgá´pZ8mL6&“Má¦pS¸q€q€q€å)ŠÁh0Œ´íA{éBº1+ß=ßÝX¥Y£f¤·CCÄiÓ:^.àà½ç½ë{Wy$défÃ>¨‡hD³‹‘a 1 wd/úÑ¥t8âªÏ(õÌC^;¬üP¯–¨˜øêBLÝ”¢—×=äâë“îD!BxB/"Ák,þÆ>\Æn!÷…ËŠ]éá„~_ÆänÃ>•EkæË—ë²YU-ÑH3b$«AÁ‚øŸe€Áº|oðI8EÕt)ò1 ½¹¢d†S{º‡Ou‹‘ÈBôÔD4ë^¢HÑãæW¿Sªl“ýþ}Št$ÆJ³7ö>%}(›+q]Ò3<ïiÈÔ½—óKÈ|À>ÚŒ Nýññ2^Æ; FÁ(¤— +V­ÖöÛwî¸E¢Hé]ºwé^1\ ÏÛÂuçºsQÔ‡úP5ú Ú“f¤ifÉ$c©¦“ž¤'é‰>–íhÿµŒ¸@\ . —éez™^¥WéÕÿôû² Ää&s“¹É|ŸÄ'q7¸Ü ®;×ëÎky-¯åªsÕ¹ê6Î6Î6Î6^6^6^ʪʪʪêjêjêj6ƒlÙ RµQµQµQ Q Q Ѩ5jZSESE=V1B1®¢rˆrÈ…ÀúêOXš$+%+婺|=ø×(}}}ý;!DiñK^l^ì—™ÚòÚòùûŒ&£ÉhҞממ7O5O5OÍy—ó.çÉÁä`rÐúh}´>†††ÚUÚUÚU¦¦¦¹ rä.Û‹íÅöôýD? …‹ÂE:…N¡SÄzb=±ž¥«½F¯ÑkÂa°ÑÿûgçÉy’’’88¸üàò¡¡’PIèÜCÕU?ä±¹óæÎ{jéSõ©4çqËqGñ–]‰ SèX†ô‰  dqº–¦£ïQçy›Z©;¤6,ð»YK7Ë?yWÅûŸx;® ²Åt? áï €ä=Œ 0—BÅ÷>·ÜP*u‹fap{/@ž#óS©å7®þ:åõ–E7ßð~\o2X(*>¢q¯ÏBøßÿ¼Àƒ€ƒ"DîéMdânú€ºá8¢‘È¿#ùdq7ß  X*î”.tïo£Wë²Õ¿Îu°Åó'„ëÇõãú¡=ÚCUúHé#%]yvåÙ¥¤Ñ¢÷¥¹¹¹X¶’d™aù«øXÐ0 ³0 áG8áG8Ò˜4&ÉR²”,%—Éer™PB åêqõ¸zÜRn)·”‹â¢¸(Žr”£|[¾-ß–;ÂáŽpÕ¸j\5²’¬$+IRTÀLÁ”ÿfû7êßHse_‰}%zÎÞÜms·¾CôÐÓaYs±¹ÈWøS|Ê0,YbH#Òˆ4"»È.²‹ëÌuæ:sÓ¹éÜt¾_‡¯Ã·æ[ó­9gà \"—È%r[¹­ÜVK'®×€kÀ©8§"È#òˆ¬"«È*Ò”4%MIR…TA"‘MÒHçe9xè­Ð[½ƒ^¸¾pZ>õÀÔ³¾ÆÄî(‚â(Ž2ìBd˜ÂŒÈ Ä¡ÊÂ#¨®wC‡;™sÎôzW̺}/¬{j‡“ý†Ø{ùº©Ó°³Ðy¸ˆA6ûòïDâÇ'Ïa[HCw4x4ýŽvÛ‰6mu[|¹êš)Ÿ†– \%¿/A†¢7°¥YðþÇÎê8„¡3ß—\ - ù¶{´ÂWæ žã‹^¡`†ÔRFâ Õ_Ð_0ö1565+++KËJËÊËâ8Žã-fb&:``Á?|¬+~æaæY‡Â\.ðS€u«åµMÂ$Lúfo7p7 ‚ *k–wPàá‘õ €e«%©¢#áhI‰h]cI¼h [Ø¢8Š£¸%" $ePeà?øY“0Z’*–Gy”'±$–ŒÇxŒGþ¹Mç6™¶5}ßô}é4ÏPÏPõÚ¯w¾¾è÷ÚëµWN1¾ߣMhºƒv¤é3KÚJ¼Æk¼¶&–|ЧxjM@ù/ñÉHF2}KßÒ·HE*RñÏñÜš˜Ò ÖT•ùÈG>´ÐBkMg©‡zkÞL0á#>â#>à>ÐLšI3±‹±Øº|×qÝztKÊKÂÊÿ[%TB¥ßYïØ¡ZѶh†fHÏišÓ4m”©¨©¨.Èa¶ÃlU^ã5^ $Jb j ¼‡8v12L¡biü±R¾Ð£©Íu%hU1‹êXÍäõCs”ÂÅçâìÂm8÷*Öı²¹¿¸ë˦ÑÙϳÖÞӊ ¹.ÜO¨/NhØA…v,xž«ÃÊR•Ã< À<(8%µ;¦(&sCuxÃÕÚ\Ï.ŒÂàü‚_,ÕDÝ$Ý$ݤüÏùŸó?+)))w*w*wZKŽÃ8Œcƒ¼¾¦“ÚKíIe³Ú¬Î½d 4æÔµYn³œvÂu\G¤#éC^¨fF(0kÖ”¬)YS¨šª©Ú.Ö.Ö.ÖÒµÉú É2ýÃ0…+ $3чTÇ\ôGµFB%w¯.Á¶%nºÔB7Ik’~Ý#r\ÂÒ'bž¥Ì"M‰+E{ñ'L¬­ýwIÁƒ#9ä<†‹qtœÞØ•Um׬¶­ï£Æ•KM-ƒÏ»3ósçmÖÈ~7‰ÜRœ¬&åp °_Xÿü¸ßªæÞc}‹©Ozå>ðL“÷ÜnÚCó©„ÖÇeÜÇ}Vëû>. 8 c±Vîλpí$k¸Áä½…>X‚1¨Ž’,L?6zžž§çÑMÑÔ` 06þlüYž(O”'Ê×Ë×Ë×[J’¶¤-iË"Æü Qˆ‚¥kL}L}L}²Ó²Ó²Ó¤õ¥õ¥õF9Œre-9#0‚Œa K™yÄ8T.µÆ£o½>Fzv§!⯴XB¥äg9Ž%Ý*[{1 ­‰xƒž áï°Ìo8"€öÀN®9E<Üiá_ê:Æ¢+™, ÉÙ­Ý· Ç¾ºw{¡!6Q'’D2!bVáxð…êÉðwK‚ ¸À”Ö¦ %—ù&Ü.õYyéö¬;ú‡Æ·HÇ4ôÀjÜÅk¬Ö%\Â%r‰\"—,VVVÊ·É·É·)î+î+¾Î÷ÙmÐñYؘ?Bch ± 652525ÊqÉqÉqñ°ó°ó°³mdÛȶ‘¥$éFº‘nlÆ>†) $äî’nä®°ö£ovmåZÚƒÿY±FzÀ8ï~pI%͹¤M5Î#kÈ)œ¢Aô)Ú°þ!ÌùÚÜ82ZøU¬Dç4]]9±JÉ}E§¨94æõõ¯3î_®Y3Á ù ©(£åàìFü}\FÁp†ú`‰¬6·‰Ë±í-÷‘vµö”š‹º(ÏÂôƒ;„C8DâH‰³dP1Î2Î2Î’{˽åÞòòò¯m¢–ìì ó³äÉáÁƒ7ž1ž1žÉ(—Q.£œlllã-Ç[Ž·¬%Gc4F³€1L¡`©²ï$f,¼·Ñíþ+Šn·lÞ»òŠbPVäi\Ÿ}!¿ÝÎöZ¿n‰ý˜àA@­-ÊÌ…(O7à^‘k¤;b»l¨Q¢—ÜE3Q^1œ;7bç… u_Ë„Òâ{M“¸Šh$ DVeÿ~p‚ ìO{ÓÅ¿–Ëд“'KKZ{JÍD}Vqÿá%  dY@à-Þâm~Éü’ù%-=Ú™ŠLÅ×Që±ë­)æXºÊ 777åÔÉ©“SG2F2F2Æ6ß6ß6ßZ²+º¢+ à P®d<é†ò8Ûˆí8¾Ž“¿Îã‹g’½žKûó;Ž>ºù%vZœ!Ù'ç*¹O6£5ÐX3Ì_S0ß À•"{ˆVt#é齊.°×·~^£‘¯?šš«ˆO¿8|ŽÍ~âÉ­ªïîáR‘Nîbé‚8$#‡…ðûÂ!ΰƒúc±”ã–r¶såQ²ëù0ƒ°÷ÂpÙìÄNX³Çhƒ´AÚ s+s+s+å$å$¥5‡:UR%U ^ðbacþ%K}0‚,”Ê å³FeÊ%ÍfH3f9Ìr˜e=õ“Ád0 Ãüà8p $‡Ð_ð_ÓëÊ,EˆäV—1õU%®£·8Œ.3¦h{n¨uµÍ›QâXêJc¸vä:!ÃzÜd-ÂÈ ®ÐТèDE&ò o7¡öd¿4ç3îå4Ýq‘Oå._Ô> ñßÕþô,ûg$s'JélêÃú´— ".ÄNÖ÷Ú{a\ÔôÄb\'r‰ŒÂ,lÇ=öuè{Ä!ΰ¥ioºRÖ˜_Kk&Ès¤±–Ídê³ É Ë\¤ÝEÝEÝEá“ðIø¤ŒWÆ+ã-Ých ¢A¬âÎü шF4é@:–žî9¥rJå”’Ö”Ö”Ö´]b»Äv‰e~V²,$ ­3¶2 óã± |TBæÒ¸…ËØ‚>ãÛe”3a,¹LDl7—“w»x,êƒñ±¹–è…ÍdiŒÖ˜‚ã`£×ÿˆF˜¹@²‹ä /‘ÔœTmàãÜ¿ø,Ç·ô(F£ÊcúvcjåŽÏ–}ìJ*!sAÏAÂòó|¯,w;úý°˜ßÊ-åÒ5eo¥Ö®2˜Æ§×p ×,‹ÚPm¨6Tx!¼^(¥J©Rj£´.ê¢.Š а€1(±ˆ%Ä8Xzºgzfzfz’&¤ iâÐÜ¡¹Cs˼ô0=L³ÎW óà ‚r§8)M³P ?WR2ƽ{õ¡%·yôÁ#šA‰ó“sfê^úmš¡*Š‹ÛÅJTgmQfþš%?ÏHt@”#~p–ôç‡pö—¶z_:$Cøî„'ËÈì_Ÿyúb¨OÐ=ØB&¡Þ"0C`Í%ßë‡ ØÓ«´]Lüøµ\†mªî"DмŽyóªhõáZ_ÍvÍv;_Í#Í#ÍEë$Û˰ ëXÀæGBÚ~² £¬áYvŠû£K5cÞ˜._^=uâ²½·Oˆ—nDnŸLœÅp!ZÜJa3¤þ!Kßô2(gô¢ qŸÈ-'G5ìШÜuôBCø¢µ¹±¼;çR™¨b_4o/8Œëˆµ&åd¾s\–«ÞÑhÇ}$Ùä,@/Sµ:LvFÒ)ÈC¾H)¥uÑ,çÃŽFÓh4†š†šÆ™ÒÕÒÕ*££££Ç\ÆaÉ@KIHI‹ó7Ψ0FÃà/”ÎÙ™³37('7'7û¡$[’-ü…Fb+ZçòýGg?˜Ä4“‹id‹ØÚ¯e‘Uv*¨`iN´d%›%õwxÁ:‹é|Fò;ܨóÀÇÊ¢Oì¶áޤ?üb¯{渾±=?vÎJâ–s™ÄW|FC©šÍ;ûã‘d¹ë‰1”ä“aøU<¤]‹rë.ÿ™ßKäd-é¾ýÃù³¯ŒÂkq]€¹èêx8¤±I¬~ØS#ë¥^g4$œBÅCêkÒM’ 6-%Å$®ÖRíLXÅýGW°\:Ò!P5Uc#Æ`­Oëíð3ÌìvÀüDˆ€5w»À„3ÌRZ«a„ Br»´£Ú›ïë|^žý ‹~狱{éqÝi§ê. œ¨È}2‘ÅÍòµ‡âH=ñ­Có+ø—¨ãz°Ú¦’[Ý«£Ønê&h3&V‡Ÿ}ûQÅ0ˆ.ÃÈ aý\\öL}š1 9Ä‘<ºÒm4_’';)m¤p•Tå+Y ‘Öd-î Ã0 Ãü#¨Ú`³„ã%ä¾I+”_DŽÌ\oPUl·» èçµÑÁÁ¼ÁØBY¡\Ô†?­@a7>"¹'Ö[PÂß>Üõˆf?Â%÷8ÿ#n7"cÃÒ2²“ôU¹2 O©+Úâaf #?..k´>ÈX ¶Xˆâú„A¸´9o’ûð«¸ÖRmŒb,X Ãü°8pàà8€ÏÚ«æßâ bŠ@xC‰¨ÿgëcÓSU´§n¸©;Ž£1*WQâ¦Kd z±„¸‘–ƒÜa[H#&Ždã<†‹¯iOjï|ÑnMp—"õN”˜‹ò¦qB›\!㤶ÿÑ:7~ÙxŽ/¤I#˱—ÅNº§e¾/DуÆÚæcüm2†8¡}oûû6A2ëd(t(N┲ÿ̆ùaÈ!ÿmy1Ö\%W‘ÉphKª’ª¨fݪ†šÍ;È0ÿD¬*BuÃMľ–ÆïÏHʬ[hLAk‡ö•:ôqGbÈTz¸Ñu±Ý*UªÌÆ2ÿÚ£ŠºXYòÀ„ îhM§à(ïÁ'ÓFضO/w~¤¿Ðb8*ĉÎ;«^¨öº¯y°0^L†3lÁa>vâ%Úì¤û±qù]Í'…»y.ÆÁ¦Çü®@ýigT6Iêh)DÒ[x H a!cæŽpt¶Ù¶Ùüʱ•c%{*-½‡x‘9YºÐ@ˆÊ,` óOš€ ¸IF'ìÐß4>¾ïþicÖç­,*Ÿ')ܧX/'˰TJ²ÉyŒ,t­ÇDPî gOBh°¨öŒ²Šz•æ/sñ"=QÅ£<ß¿M«}òÄíRï¼ÑÕP\üLGPÈXŸˆÂ‚ÓŸ66_Ñu2 2‡óI¤Q4Vt8esH>ÕZjŽãT±Š;Ã0? r„ pGd>2¡ÛØbc‹Mœ¹òÂÊ GRÝž»=7 °L#E\‰+*±ˆ1Ì?É2‘P4ƨ"“?àh_HÛÊ ™_ãQé•#QåàIz9Ùdm}/ ,ï² ÇÁòû2 ¿LôÓóÈÅEŒ(‘ñ€Txˆ(šl iž[µšÜ3ÏÓè à„$Ž«{eè#1!ó­<±a¦+W‡œ&¼h¦Ó¨'›h©°áòç›Ï áÚãPóup¤;á!¡¶´³mmE©#Œ!"˜XV™<ºòP!rlÁxb¶Á ÑvÖ­Í' HRaÃ*ZŒ££ÑíèS4DC4¦ù4wp $ ßåÀMKdDˆe¾2_™¯ãÇ!ŽC,_Z’C’C’C~»G²ûÃü{¤" zZ•ÄV,@?$½þ~^z@žSº§v˜z€Ë~õ½ óÞmpåÉa‚Y«Jƒ$ =Ì{ >ŠÃëpÑ,p—0„á:£³èì´Ói§ýÉäâÉÅŸ”y{äí‘[{µµ´µäöè†n†f4„† ðà{{‹$‚D -MKÃů—_/©¡“¡“!äcjÔ:©u‚ÁÆf—+Ö®X;´´.^Ÿ±›KàøÞßûK¦? RéAéAÛïû½ï· MÑcEuì®Ø¤Øä=˺ÓÇÄ áv‹ñIã“FÜÕwÖwNqÈ={ZדºPêBŠ’¢¤(b!ê3ôú ÎGçCJ‘R¤”¥5Ý,7ËÍò\>—ÏåqçqÞRé'uHRGwNwNwÎò·ä9FޡРu¥®Ô5×3×3×ÓÜÄÜÄÜ„Ü 7È ´Fk´_Š/Å—¹ƒr嫉ÕÄj8ŒÃ8Œ8€ĸ÷üëù×u­¹Æ\¡BV³¬f‰M¿„| ù 2µQ–pîïAŠ‘b¥ 3]ʺ” (ÛcA[—Ý]rwID×¥O–>é’Eª“êÄ‘N èïòMºÁ ™@è«é«™J4ŽmÖ4mjÚÔ4¤Ú¤Ú¼Øà–ç–çq.oTÞ(®1çÉyJö8H$’‘±ë““*[/O”'z+55ýhk~©Ø«Øk<7xnÉÝúúNs¹4.Mšfm „Gx„ld#›\"—È%’NÒI:áa7vc7:¢#:{bOì!ƒ 2K =®á®‘äù@’ƒä Í¡94Ä™8gbKl‰­õåf! YØ€ Ø€²(‹²d-YKÖb=Öc=b‹XÔDMÔÄ|Áqµ¸Z(kûØö±Û§SEN™¢ä†sÃéEz1»Ì¼UóV HuJuÂM¢"*:‹‚â»Ël°k±§q§ÝmÝmÝmåwäwäwÒíÒíÒí ­OEâ!²»ÃüÛÌÄVDp£‰ž$ #¨‚^{õ%î^ú¼ªª‘>¯Tõ5ƒÓ+Û5qð!ÿ³!ÇŒ`xÃÏ€ï` *Äš>›Ê™¹9äw€ÔÇU±:݇êb=ñ=,‚ޱ¾™–ÍhåÐâC‚—ô(š€ûBGF$<¬œ¸çVÿç’úq#È ²GˆwÑÖ/â>d—ù?X+î¹å ¦÷„Ù¢¹Mú“朑„!ZsOÖQ à€V€V± ýÝâ‡;"L&›×åWͯšÙÁ\Ò\R[iHCz£7>À6àüßòÐüùYòrœÅYx½ï2Ée’Ë£òòu³g/ΚrS~Sžôdé…¥Ζ ›è&á1M§éö½°ÜRn)ÞÓpÎÝióS›Ÿô+… ²Eç¡óì/þ øYžíÛ=ZùO׺Þn‰&B6ªª¶;­ôOø„O´-mKÛ***ªF¨F¨FÐxOãéz€È$2‰L¤ Ò‘æ¤9iné™M¯Ñkôšr„r„r„âââ•S9•[öIî“û侯Vc«±•DH"$´6­Mkã$Nâ$Â…p!šÛšÛšÛü6~¿v¤iGÒž´'íÅâGñ£ÜQî(Ûá|ÝùºçÙ÷ô=-Y©Q¥F‚ÌÌ’ö „GâPd#›ûHè÷6Ô˜€€åd9Ynùå¶Òm¥ÛJÙ Ù Ù‹´i/Ò^>>>Y{ÿG"‘ìfÆ0ÿ6ðàè|šˆî°ƒ ò§Ûc¦hGc¨°¼ð®åÇúp©p8:\ã5l ùUTU°¾ð€ŠÂj´Du#jò“Iu’B–q­‰ «ÌׄGt˜8YL¦D`4X ’üÎÅ×Ü•7r}h_Gi {Ø}JY¿˜ûñ×m5‡äF¹Ïþ:W—Gï1^5yîW™4 ü:¶ŠaÐûFùþ~çÄ£óôýÅÜyÎÑ>óÅg/ï}ª^Ÿ÷–2äâñ}¶ ÿpǹãÜqËr¥•Tjð:åuÊë”]®»\w¹Z£ÚŽ´#í¾Ë·W¥Qš[Æ-ã6YVôÜwp¿¾oï½½ã51kbÖ¤F…áS®üKå_¤“Úä´É‘6i2¯É<.¥}íöµeaÁ݃»ó¿÷w×ar‡ÉÕ&¯ª°ªBØ^q½âJu²Ûe·‹3‘ed„;¸ÿïòÚLâ’¸$8Á NcÆŒ xõáÕ‡WÆ6Û`lk¡hD#½Ð ½ Ñm‹aþ+ˆ0ÉR‰÷»U´‚Ý!ý¨Ë3FfSzê^Õ®¬Ü±•µäTâ…#Aò_ÈHVð*( ÅlBwr´ÂM\#Òž{Î'uðûÐÿïÙeù6þa.6=¼] ü°°úÀ5úŸ¨·°të‰ÖœÒ߇Ò[Ã:O/?&Ï×qÓ£ǪìV²¿Á]oS]>Œï =fàê¢:ì¡€ŒÍ¥Ãü¥Å=ÜhJ4Û ]DOn6©FŠpR"!jçáJ£b¯õ|žLj¡ {:ÃXY’:ÀÁ:d™7Ï1Ï1…bfP#¿ßÀ­‡F<–¬”¬”Ä1BŒðH ûîßû-ÜB.£1ü"G6ÍÃ` ¶ns£õd Cæ`vá!£1”É?JiI¬YÐߟR€áÓALiYß=Ñ“Kâ’8‰xG¼#.*³¯Ì¾–‘[un5Üù¡ô¡tò´ìÞÙ½_I%®WIsŠ9Åüé;ûìÜà7Kˬ¨nÜ*¸UPø)ü~É1É1É1–E|K¾%ßRÐ :AÇ.w†ù÷¢í1 §° Ä„Ý_Þæ.O Ê:ïë MÅ$ÿ„¢Ïì'){ÈWIzèÎú˜Gãf£:`&ÎÿÛ^„eò#ËÌ£5Qîd3©‚sÜ)Ò˜\%5I6Yb6 ŢÍèÔ,Íþe­Ý7I%|Ä[¥j•,½tjñQN³BJ:»»WÚȹöòûX4Ìnߊ"&;µÛI·U¶]é'þ3 ô‡¸…P€ &—]æØWT®R±}Ûf WÕ:0íxýü_ ÑŸï’hF^P-2©zÙ€Tæ/÷{óHS5q5)îIÊ“|Âa$é«.%o/„«¡9J (ž± X‡ëíÂ.ìÒ­Ò­Ò4œ†Ó{æ†æ†æV¸ƒ;¸#æ‹ùb>µ¡6tèòÞ5ЀÃ*¬‚ȹqnhAôD_z^€Žt#Ý —ŠKñv¥]éØÃáП¼+Ôs<Çsú޾£¯é ú‚ ú¹ú¹¹ sÞç¼ÿÌ‘™dfþ¬Æj¡nÔ®@ôA¨5'ü÷" a_‹¯Åׂ!¢¹¡¹¡¹aîdîdî”s"çDÎ ä!y–ð¨ú¨Ï.w†ù7KBt¨Œ@¸š|ÌõEÍ—ã>•îúÙ»‹c?»…ª3²Àråü?ºÄßÝû*6ùwŠ4#Ù"¡³(ù[i³|;ÇH/4Aæ¢?ª“¤ª /𣔵*ìG(©‘ÖÆzZšCEt›e÷Öƒw}áPWé[ü½ÇcÛö>F÷±¶6•ÇŽwûTqtÀW¿²>~Ýœ;Ø*USåÎÒéî ë-ÙüI®6 Ľ)AÜú‘n7ŸÖ–4þ’0 e|Nû¤©éñù7ï yZ5%öl…ˆÊ+Pw± yÂ¥qe±[,"V ýQ>,§óÕ×Á©] ÁÆdÓKa‚XÆæÄoIºŽÜ´m*.­‡5˜ 3J/,Á5ÖæÎð…/|éSú”>µ¬P‡©ÃÔaæsæsæs¹$—ä~må=8ñC½÷\ä~­‚‹_Ä/8g]_Õ+Ó][ÎBÖw1z¡6j£¶8Z-ŽF]ÔE]ÕKÕKõSA"H¨D©‹ÔGb;¶ãz£7Î}gUvÙMv“Ýt2L'«_«_«_k¦i¦i¦eÚeÚeÚeöÌì™ÙÓR’V¢•h%v¡ÿéX¦ÎÒAñ%¸Z\­¯Wžx[¼»¨ˆŠˆù¦$óg‹$d‘_Heœ¡éN4xÔôÍ¢”~];´,Š]¶ëÔíåWËžö;䬹;íUÏd#w‹Š}"èÿ×=¯`«yÁ•L"žØÏÍ%>d?DìÈ6q…,Fо´4ØŽ}8õW¯hX¬’c…²å}—:;—úT|®“¤ŒŸoó}Ÿ îemi™¾?;…ñÔeåöè$Ö££<Æ€jA£É½„R€¹ºØ8#7Õ=/$®srÃìôG%Þä¥x<«ÿî@jN‚/{rÅ—Í↥·þöyCNÂðwìþíÕ8¿uÒûSE3ÿ1_[ÜóÕLɦ¢\,B¶‚&ØK~ÅLÍMù#™µÇ'iƒ “}&û²ngÝκ}0û`öAtAta}Y_ÖÛ° ÛÄ¡ññ Ïàš¨‰·[,¶p,ÏZžÕÙ õ‰³’³’%c2§fNÕ&¡-Ú"UPoEµç§C -x6„-Çe,ÀQðïç$?ÎÙ˜bûõb޵Ý~—敊Ür¬|ºÉ_I¶)·h†éú?œÅ@{ÌÄ\E ľ¿ý¼6~æ• §”«ï¼ÝbŸÛTÇ!¦ª©ÊúÚ<­ôÜm‰U¿J+Ý­¾:eØw4k{Xõ4”¬H?r[ЮxØô:‘boa¶¦ï»Í_ç<‰Yó17#ë}­ä5¹KcvˆÉèíñú4’€IDATN‘ñâùã7SÒ‹lÔRà `÷ï#ö*΢W0JÄ…Òý¬1Ç‚X v˜ÕâsØæ‡4cê‚…ºßì‰cWä;¨¡ŸsR­Ù§Y¯;Í+ˆ¤9$DAúšm”?‘½†7Jè‰ÊpÃq‰\àÔG}ÔN¥¥¥ë6è6è6XXXê[^Ã5\Vh„Fh$¨ìÒ Ò Ò †Ã ‡Wg«³ÕÙ… 7n²}lÛOx³du‘œ%g‰>דÙ³+fWÌ^˜½0{ñ!èCЇ ,Ï,Ï,Oý¦ º ‹8(~6hcÚÞ<Çs¤Še’eë¾tïÒ½ &HçHçHfNñšâ5«yæÔÌ©$†ž 'Øžñ ÓÀ§×ùi`Iðb‹Ã’ž¤MÍO‹¯úùYNg›EŽgÍ*xî*uËâŠÙ"E°ìc¡UFHáYLÃx¤HkIlé(›5æå Ë×[Z‘Ú·©X~¹}׊šÒq–“Ê™»Ü²v¸ciolgn`YÃh& ¤ÇèYø25Æ"&°ø‹ì8 â;é6i‚”{ÔtÒX“w2÷D?~W*}ô£Å/­¾4}½ðã®Ì_d,+Ø÷¾irnnñä Aŧr–´À-d#J¸Áæx„—øŒì^²5X›Ú¥ºÃ¼…X€öú”;‹]ã÷Tv‘ÿƒsÐU «GjÓ4+ù|'HÈ"(šG^š”½ÑÊñ¤*‚‰:»H1„Ç¡PÈæ0×g¿ÎB–P˜ m]%âJ\‰+#Œ0ÂÕáêpu¤o¤o¤otµuµuµÕ¯Ô¯Ô¯ô ¶D½%!“Ìr,ÇrøÁ~æÍš?4=czÆôL^ã¼Æy §N+œ&”¬b«Ø*¶J¨n+ŽŸtÈr"Ñ´©ñ~Ìû1jÖj_«}UiªYªÙçùó¦oÇc»¯×Ækãõ-“…°1‘Ÿžª¨Šªx‰—x)9!9!9!“‡ÉôW´W´W”••q‡p¨D*µ Ð Ð=ÑSZFZFZÆö íAÛƒê£ê£ê£©ƒR¥ÒçJš€ ˜ Úe♇"ñxI’†ˆ#¦ÄT7öÜås—1±4±”~?güœñ]†©‡©‡iRÎ¥œK9w¯Ó½N÷:‘£ä(9ʶ²­l«þj¢ÛÌ[˜Ã5fpqh„L.“>!ÊÚh/éj†Êz¼ã¥÷dcPnÙìǧ¾¬’ŸùåÙ¥77SÞÕÿò"§<æã2êßw]±ÆúãÙôµ#u(ÈB’ÈZ±`ÖˆÁž±öüAÞƒ-D(6a;ìÁa'´X-ú—‹”~H韭LVç(gè˜ëjpLò’{oœ$'­€·ÈB!Æ¡NI GùP\¡IB’p'pNp‚“Pƒóû(£bñˆPQU``“1“‘-d ÙBDA¾=‹-ÛJ ð€‡à$•H%R‰É'“O&ŸÔóÕóÕóS¤4Hi Ú3Ø 6CTÙR„t„=d1ŽË…=UPUI8’pdé)÷Sî§`½Ñz£õÆ©§>žú¸Œwï2Þ̃y02ˆ "ƒô*»àõ.òß"‡0P{W÷”wã(OB\–Øí7ñì(­U¡ÖfÅ0y‘túÞwÙç¹ìi¦<Ùùî·–ïv Ï)ÂÄá #½&†’ ¤î¾D†ø‚3Î/áÝXª¶n$Ÿ¬ËçƒY[þ ?NâÞ꿃*R¢ÿ#§·ò£ú%®’Ú¤86€Í5:,;.)eÖÙàtPUõ(²•t€·ø< 0é‡Q;I;I;E)E)E)m%m%m¥’ä#±[°eÃü ó7ÌwØâ°ÅaK“¨&QM¢ægÍÏšŸ5Ùe²Ëd—Ô=©{R÷ Ñ “2)“ê¯#ì·ˆü…Ðjä3–òIl,l2+<ë¸Ö·¨à~Îy»CªÙ(ÞÏØõSÂǤGQ\&Í!ég:„koë"øR,œÙb:«ËŽ¡.$¿I¤xä79¡DÅEäã®)þGv7ågõh•àŽk,“U7,%ÙÀ(¦É|¤Áz_®h‚ê¢àDŠ—U">ćøH–H–H–°Ïì3û¬íªíªíªo™‚¤ˆ+TFeT% % % åZ¹V®ÕÆiã´qªµªµªµú–%1Åg4AáP>W>W>×¾Ÿ}?û~ª‰ª‰ª‰©Ñ©Ñ©Ñ«l*›Ê¦ŠÃ¡ ¨ÚBV«j¨†jô=GÏ)”NJ§¥—>\úðÅØc_Œ­êZÕµªë¤+“®Lº"K‘¥ÈRô{ƒOðOô×ÃèÿJ@ìÈ 2¥aS×8»¦íJ­p™oqœ¹ªÏj†O#}I_Ò7UªNU/Ö,Ö,Ö|êü©ó§Î-ÛâîÄkL¬ÁÖ³õl=)CÊ2úpU!•­8?ü5¸Â¦ü"öžõÀ|En]yÅýö\yY{ÉDò ÎØú’70cŒ&GûŠÙrÞt4‰šŽc¢í\äWæGÅ]¡|¯~  \xOfÀÚè$®œÜ8MzPâ!´!P^¢àDà g8 ‡’ý’ý’ýF­ZµÖ=Ô=Ô=,hZд ©¾åmÜÆíÿÂ7,þø5 (©NªÃ™ô'ýQ…T%UQ÷û} úà@ÔAáP6V6V6ÖÀßÀßÀ_C5TC‹EŠ¢o>î'q'KXïŠ-5Ÿ;?w~N2HÉÈÕåêruÚ«Ú«Ú«ú¥]*R‘*‡†šV9ä‚“^ è…7Kß,}³tEé¥W”Î[Ÿ·>o}—‚.] zŒè1¢ÇfŬ˜•Q•¡ú O±ÙCTßÿ“”‡+,Xv‰9¢1»É¹jjç^¸¥[Æ/ÔœÏÏTÅ>Ÿòv[ê=´C}¸³ÌƒÍE õéED~Q~PWr(Ô©Â Å*1sÖÖ྄ãdFçd3%núFðwBlaU¦•iey%y%y%Þœ7çÍÕëÔëÔßì—qˆCÜá20ý£×yÈÏž±gèβƒ\#Å¢¦ß àÁ‹[ä©H*’ŠÂ±¤·¤·¤·ü¦ü¦ü¦–i™–©^ª^ª^ê›ÞÄMÜ, ],À ¡·ä89ŽæÞæÞ¦«É<2wMm”Ú(y+`ºŠzå!_%Áú®…Z>˜æƒéú~xð àAÀ–s[Îm9Çæó‡Çì³o̾Æ3Ïh<ƒÉäGÒ2´ Õ§¸… ` Šó?H xÀ(¨aiy¬¤b­NÙ¹£\aœÙ Ï^µëɨ˜g_;ážá#ŸÊÆ3Gq9%"òCpjÖ[%§¦ÊÀU÷žÝ`5¤ù²]Ò^&GdC¥–®di‚ªbÉ/ý¶2€ gÃÙpÞ7ä ÉJ²’¬¤ 4&è[Ãø{z®¿#¡EP{bµR)m¡ª¥ª¥«ÌçÎSyªeª%o C" Ÿðé×þIYËa9‚§/ÁF°ºãºãºãÄŠX+®W«§oê8à#>âãŸü%*¢"*¢*¡’>ZÈ#ì¸Â®Ä“xO}ËÒ(Òz×<ä!O¨{ªÿ—|ä³ì>“Ëä2éÏ÷â{±>vcìÆx´2¡&ÔÑ1aFÂŒô=º ]{ŠX€E˜‡yØ'Þâ%sëì;±;ù\>—Ï%;ÉN²ód¥“•NV*õ¦Ô›Roúš÷5ïkÈY KÛž¶=m{ŒŒŒ?9AN¬'ëÉzêw`„åœÈŸ!ä1&2f„AU:•ù`oUÁÄH> ÏÈTh>D}•çžK,J[ŸßŒøsì`YÆ‚‰áÃ"â TŒœÊ$u.‘Êpã§± LgÙ6IuSµ¼Št¨¾Ñ ôDSQp"Ä‘8GáX2B2B2ÂhŸÑ>£}:•N¥Sæææ ¯ ™Ýÿ _±éKD}æÒ¸4L골Ϣêölß³}Ã!¿Õ~«:! iH#„|S!ïŠp,í,í,ílàcàcà£qÔ8j‹êÕ+Ò+îì;ÅNýøæb¶0¡ØÖ@ Ä@ÜÃ=Ü#H#Òˆ<'ÏÉsjKm©-ÝIwÒœ3çÌ9sk¸5Ü.•KåR麅n!„Bð ¯ð C1Cõ³f0ƒû¾°/ì&»Én²Ýl7ÛÍÖ±ulþø;ÅNé_ e¡,¥PŠ%ò£øQ|ŸŠí+¶çž—Xj`¨óÃÃOÍ2cþæzv=M=A3d ïÈ2áwJ­ˆ”ôUÄ …ÇqÇáø'âDœ¶)·)·)ï¸wàÞggg›¹És“ç&Ûï¶ßm¿[PÙ Oxò­2´sFäÏ‚F‘^$ÕQNM‡×˜ì2NÒC¶Sò‹yCöáñµ—Ò/ƒÑ PÐUPÕ7S‘ˆÈ¯Œ¤ø¶SÖ1eúlÑþŒ±18•$_ÁÉŒ%+«°!xKBŽL}Ïú,ò[„I_Ìô‚Ò‰H¬E:ÒÙ)tA´†%,¿/Ÿŧ¤„ÝXÃVHG:Òéz‡.“×’×’yê¶ë¶ëÎ+µJ­2}ÐK…(DéýÈÿJËÕlÌÆl\Ã5Œ²ÚhµÑ<@õQõ‘w‘½“½+µ §qšZü-\•T~á$aìyÀåˆDDËJÉJIÉ}å¾Ò½Ú—Ú—ê$õ1õ1åfÒt Õˆñ##Y&Ëdɤ iBü0 £0 ­Ð ­‹8Ïó<ϳƬ1k¬w/¯¨¡?¡ÿôÉÅþýº’®¤+åÇäÇäǸÜîÌIæ$s’.’.’.’œ‘œ‘œ1ijÒÔ¤©¡³¡³¡³U€U€U€eeeb§b§b§IªIªQ«H«ÈÒ=¥ÎRçó'*´ªÐÊ×^ñUñµJè½÷Z¬íå>É}’nwè¦ÐM¨Aú‘~P‹ño%aW‚‚ i@IwÒt/¨RP¥ Êò·Ëß.këcëcëãÙÖ³­gÛ@Ã@Ã@ÃÙíf·›ÝN9V9V9VŸËv°Ó»Õ‰›þ}I”,,09é9µ±¿ÒOéÇ"€©ØsXÂzE\PÜ‹s‡pˆËä2¹LÅ%Å%Å%Ó{¦÷LïÉOÈOÈO(f+f+f+F)F)Fï2Þe¼Ëð´áiÃÓfkÌÖ˜­1]gºÎt±¥±¥±¥â±â±â±Å,‹Y³Œ^½0zaòÅä‹ÉÓE¦‹LÈëÈëÈë ±ˆ%³È,2‹ô$=IOÚ–¶¥mÙGöQ;è¯Q_ëÇŠÇŠHcrŸÜwí4ÅiJ#×ÏÃ?ßùùMìÁò§qš‰áÊÿ+A}_ÏÖ³õÔŸúSÿ¯_=¾z,+»¬ì²²Ëë/¯¿¼¾¯¹¯¹¯ùØÀ±cWq«¸Uq&ÎÄYï6#˜ëéþ»33Èpb‚ݺIütÖÅr¹I‘¢t7ûS¦†P²wØšÙ%cTáâ—–ï2ÓA…•è[xŽDQâ""¼F²…?4ãù¼wî%ÕÍ<“«òáÒ!;Ë M³äS¤Õa)Îó·Ù ¶³°DÅý¬ì/ñ‡± aÍuä:ª“ 2 2’ª* •†ÉréNéNMM•Ì7JJõnŸ.p ·–[«9Sô¨èQòVŽqŒó4 5 …CfÌàóø<äÁîâÞýÛ Œhˆ†X03fÆ,Êœ,s²l§vÛ=žër²áɆ§ÞGeFe>øæìñŸÑ~YÅÝ ^ñÖ¼5ïÍùsþ˜Ö-5ïéø§ã§~(l^Ø\éë?Ïžbþ맯ŸÚå»ò]ªZZ÷0^m¼ZqÅú¹õsëç&ƒM› 6¹erËä–Q°Q°Q°A€A€A€‘»‘»‘»qeãÊÆú f#fÄŒ˜ÑU£«FWž=7znmmMf“Ùd¶æ¸æ¸æ¸®Š®Š®Š&Q“¨IT«ÕjµZ{\{\{\{J{J{J{W{W{7¿F~ü™Ÿ3?g~Îß–¿-[þÁüƒù3·gnÏÜžÕ3«gVϱ…có÷gìËØ§VÙ¾³}~É;Ê;ªüýôké×^޲Ûi·“¯;¨;(‹Bjû¡#:â‚X6ì AÕRFnç·óÛ©u ÑñÑñÑñkÜ׸¯qŸ7lÞ°yúõëÖ¯[¿ä²Ée“Ëžyxæá™t]F—ñUùª|UÌÃ<Ì+á#ò/þ  HwòXgÁ>2yÅ:¥c-:»Û4R8á I"3Ÿž‹»’Âeì̵UîÆ006Š­Åm,GQ€""€1HGŽð‡æ†n3ÎuPíÑX˜‡ô“ ß‘©L–È?JË£4вgŽ5(k˜ŠâûCê  øÅüb¾ 7“› Ó¶Ú¶Úܰ§ÕžV[S é¤éÄ.¯Øºb«×ÎÍn4Ó}Èœ5ØÊ 31SSƒ1ÆÈÒÐÇ#8‚Ò苾øà»ÌwYrF²c²ãáù‡òiÓ:ÄvˆÕt qq—— íÚ]µ•®£ëГËý jR 6þQ…ᘃ9˜é4ÝiºcE]–.« o‚[‚[´ ©Aj°lA"¨Š?Åïú¥G¬à²5#i{¾ ߆7­Y1²LFy¾<P@7ÓÍ=V8­8fâçîçî²­ÔÑRG»¶× Ñ Éu—””M’ì“ì“ì“ô—ô—ô—¼¼¼`çØ9v®ÐªÐªÐªpuáêÂÕ…× ¯^/p.p.pN M M -r)r)rÉ_”¿(‘ò…ò…òEQFQFQFÞž¼=y{òçæÏÍŸ›_?¿~~ýÌüÌüÌüìñÙã³Ç$$$¸¸¸¦K–>,×*×*׊ËåÇò:^ÇëØ ¶‚­Ð÷næ}ëh25ÊH*8Œrü$3,3,<³TF©Œ”caÑaÑÒ<ŒÅX­;óa>ø"*îÿS°bÿäCÎ7ç›óÍ9 ΂³¸Ýäv“ÛMlfÙ̲™5ùêä«“¯úËýåþò¯V_­¾ZÝœqsÆÍ´­Gëñ^ÃSÙEëû¿Š Rp¤Q’¸ˆBÆ{n-uÜÒØÌ×:C1 N´ iôÌ)îiŠJõE³Yw“ž£Æ¤.ïϯe%!‡•ˆÈ_‚`qÿ¦¸süxÞÈ|¯ùÞ2ªV¨ZaÙDI´$Ú0åÝ›wo¶gN¸0á‚ã3•+ûÌPÕTÕL/Gª*ÜÐÇØ‰d Á4½›z75 UeÓʦ {¤ìIÙ“|xïá½í[˜š²9HC<õ^¢ ó0óøx>žOòŠ8´shçØ qˆ#[¿ò_ùÔ¾ì{[@ÈX,Â",ú¥G¬`?´‚F0oæíê§ê§ò“&ýMú»»¨¨è¶f¼Éx£ë¬½ ½ð9'õrêå§s^ä¼øü8¯e^Ë‚«¹&¹&¹&¹7soæÞÌ©”S)§RaNaNaN¡K¡K¡K¡i¡i¡iQÕ¢ªEUóeù²|™*K•¥ÊR^R^R^Êšÿ4ÿ©6V«ýßÓþðÿáÌ9œÃ¹Î4@4ÐûÀ>°€ZÐÁt0µ~Þéy'í¨¦#›Žl9³cHÇ¡3¾_ø~ñ»Ûnwz]…”'åɶ™mf9â4ö?‹2òán”n”n¹@. ASƒ¦MutwtwtïW¾_ù~å'¦LL™˜’‘‘J»Ð.´ †?Ãÿª»sÿ³Ðutût“øNX-N×lRžØ@ Ù‚þ¬©²¦fVÔÏ´;˜ 4 çHy\ᯠ–¢ðDD$ˆ+fq·ÑMãËæ]Qei4¸LÆñXˆ…Ü ´l„ü$wƒVTIuçù`Tƒƒx#ý Œ Ø!±ʇ’÷²æ²æFV97sn,‹ïßáCÓå¦Ë §$¤$Ü« ñÑøä¶ÆŒ!% ‡4iIZ’žl/ÛË6ää©ì$ ƒ‰4ª‡j™–!ŠßÇïÃS´@ Pd"ó¯ ê")$…¤°z¬«g©´TZ*­ÎX±:“––––––L’I2ÂjYMV“Õ7¾!ƒ @2X @ð€[Æ-˪šÝ"»E(ß?Ü0ÜðTâ›îoºëò"æGÌßû‘McÓ´Ô7Õ7µgP„"ý 4ÿ–Ã8üÇû-Ä›xoú𾦝á ox³ Ä‚ôªù,Á¶mcÛpqÁF0›Íf³Ùú+ç 9úòõ…(D!’„$d »Ùv†5%“È$ÔUöVöÎ(SÔ´¨if-sosoI4yL£K` lVaà^ˆ®€ÿ“s›Á6lÃ6æÏü™?ú¡úm ݺ%Ôþý!ûC­¹Ö\kn27™›ÌM¼?ñþÄûi>i>i>¤)iJš²Ûì6»-­þóSX€¶,6˜ffe¼DÒàn¥sŽwÄSv7y}ÊÒ<ÙËÅï|2^â9,Ê÷â£l æ Ñ#aqHC.<@A5fü¾MÞÕmt¢CÈJñN,ÙÜÁÐHvFvƒ›J›©4:Ï“*°ƒ¹xý!RHA|¶“›ËÍEoÝEÝŤ»o Þl,xßâ}‹Ä¬÷ Þ7¸¸õéS͵×__ݲGqÀDL„¬ÄôTd3n͸å˜p&áÌÖ¸ôméÛ Ãë·ªßJÒ8Ö5ÖUí¬w‡÷ ÿš/E>“Ïä33fÆÌØ.Å.Å.ÅfœÍ8›qéÒ;¤wH}”ú(õ‘àNÃ,™%— @2’A‰LVž|&ŸÑ Z­É-cÓÖ¦ííÖyÑyÑŸœ³i6-Z·/nŸ*HUAU9üp…hD#š#bDëÓú´>¶` ¶`6`Ûζ³í8‚#8²…l!Îã<ÎãŽá›Çæ±yì;Äé>ê>ê>â2.ã²>;{qW„&h‚&?|nôGÿªð@;È",ß'ß§p¡uWd*2ͱú¬>Bá|…r±øÎÿ<¼¾ðšRTEUT 0©Ôj‡5µÖÔZSË®]»U'VXuâü·óßÎ;寔Sní/Ú_´ŸT'ÕIuÁ"X„0êmù"Ä2u1’™@nh9Ñx¿ç•Òƒ¬: Æh–8+mt^…·û>?É~ENKä}ÙYv ÀQQx""Ä"9Ѐ¯¹©ëÏçæVP™¨ïÁˆ "Ñl?”×™$ÈR#É=®MÐ{¶—…Ì) ðˆD$TTJ¥xίæWcôµe×–ñ]¦}˜ö¡ŒÖë¬×d×ã™g|,õ±=J*“Êü2ˆ B2ÛÄ6¡ðçï"©@*/ì5{Í/Ÿ¾|Z[Õ{¹÷r·¶,:ä7 ­ZCÕ4¾(¾Hís8‡&|… Ñws Ä(@Ã<‡yóìÚÚµµkûnû ï6¤nOÝžºžð„'3d†Ìðç–ô_Â'|¥Ýh7:…¿Íßæ¯¾½÷ö^ÙЙa3Ö;e®Ë\w©Ê…ä É·|03È4œÇyÜÁ%\Â3˜Ã©Xˆ…XÈ>±Oì“N«Óê´è†nè¦÷ö‚×÷ŠËK±?FqœÂ)œúoõóÎn’Ý$» †°!ŠcŠcŠch‹¶h‹$ ÕQÕÅAñK ì¶qàÀñ |Ÿ@Æ1dLê¤ÔI©“­^´zÑêÕMW7]Ý´þåú—ë_§§§]ydå‘•GØ3öŒ=C(BŠ1ƒ1¢×û" #È!AE”‚UíNØesŸdO9-À^3·¨— Šô·#í¾ ÷‚&‘óº*Ì™‰*»ˆÈÿ¹™W™Uh‹š,#±,Ï\Å4}2€ÈøYì S™¼“·’zÈÌéú@å` SQqÿCr‘ ±ˆ%ÖÌ“y²ÇiÒ™›¸sÖµeÊÑ”£!=_Í~5{]S ^Àõs}#4*}ìÞÅŽ±cl[²M²ÌÉ¥À¥ ý”ŒnÝ2´‘6‘6Ë€ÝAôAôB/Üý+¡¢ç\ÀØÂ¶666Æ Œ7Hýšú5õ«ÆTcª1åŒ9cÎXç­óÖy‹RHÁ†0<€3œ!‘%Ë’Uæ…|!Ÿ|™oÈ7ÌþÈ=çž#…å°dòùŽð…Œ@PˆÂ¿£¦ü”JLþ˜ü1ùcø[ü-þ–É“&HÒ„4Ê6郛E~GP°Il›Dƒh J¨”P)¡ÒRÏ¥žK=—Ÿ[~nù¹{<ìñ0sLæ˜Ì1»k»&W…«ÂUÑ-×-×-ÇtLÇtQ}ÿ´ÐGU”… á*¾4\Se™Óy<&H.KVµ×žyT7Úå‹3: eÙn–‹Áà@A /JRDä±HC6鉓X Bžk£6Ñ„t1Ò5`‡˜Ú4Y.µ—ºpkiªþ}åa3Q|ˆœ܇9ÌA¥ÒíZå`åà̽:syÞRò˜g¼A¬A,1Ä\€ƒ~û؆Aï: :è¦é¦é¦!©Huñsñsñ+Œ)Œ)ŒùôôÓÓOO…mq¶—íe{õžÙ"RH!×û”'! ZC¹¡Üx"‰ ’^…Ʌɪ~º]6°†¬!ÒŠù@Íýû!÷;ÎŽ³ã¦ÏLŸ™>£¥h)ZJÿ²¨¸ÿš ú”‘Gø#üÚ‹ö¢½žÆ>}»©ú¦ê›ª«©© ,5°ÔÀR­LZ™´2ѽнн •ieZYo8+­þ–h…Šì ³ÃtÉ n)5©_ª’£ÃÔ'UÈå"U[í»{"ý’ãžâ¿}`=Á‹‹‘ÿ Åk¤#‡z“½d*²PUn3•…æ@¹Î‰_À>š3¸({,%tÍÐ¿Ï ¶0Å÷‡“ðøÏF6xfÎÌÉ8bLŒéL2žŒ§/X}V÷°ð-U u š¤È·‡Ë`ð@,biGr\§Ž¬ kƒXt@$ëíOE(ú z× ½ÐKÈ="¿#¿#¿SºwéÞ¥{FFF¿oý¾õûÖxxÁJ³Ò¬´þ»‰ž¾‚g9Àà‰Áƒ'¬kÄ)m”6J›ÿ¥îæFäFäFð3ù™üLÓ$Ó$Ó$½â%`#‰ƒâ—C°‘ ¾ïçqçykÞš·¢XÏÕË>Ë>«`lÁØ‚±Ÿo¾ýù¶¾øy/Ö‹õ¦GP/vb'v 'Œ_¿6~ÍrY.Ë-à ø¾Ä÷1 ißœ|twtwtw”þJ¥?ÝJ·Ò­ÉÉÉú–bpªH± UÔFmÔRj¶i¶i¶­ [¶2ìy©ç¥ž—*s»Ìí2·çv›Ûmn7 g g g>ˆâƒôŽ7*¨ ú¥g: Ü™/›Œsxˆ—ø\Û¿Âp{_úÔÐ^Ú]èBžÖ~=ük>Þá32hYº—äá ’)C‘ßB76§q_8U0I3[›kM3í$êJH4¬YÒ,ºØÈÌE‘‰üÔ³o¹Þs½çzOvNvNvî“Ë'—O.Õ ªT×[„\"RH!eWØvE/È“ò“ò“Ì—ù2_e-e-e­ßÇ7xƒ7¡¦œ¦œ¦\®.W—«“l’l’l2;lvØì[Žù¾è‹¾â Ñ­ Ký l›@¦)dJ†:C¡^ôpÑÃEß{¼÷xïQûhí£µNÞ;yïä½Ü*n·ŠÜ$7ÉMD! QúÚ¿‚c^ñ>ÖByØQs²†¤ð˜?34©fD¥—++em¹`C1½° ëUÑã¸I‰1ÙcˆTÀ ÈCá/^[CDä ‚ÝœmÆS¼NLP{kN2™6C—CSI¹à5>™4pw‘ŸáQ,r)‡R¥(G9Ê%™$™$™°Sì;…²(‹²ÈCòD±ý€7Àv±]lq'îÄ]¿õ_ÂRU ÇZ;­Ö®À´À´ÀT2Y2Y2Ùx–ñ,ãYú¡äGüˆŸ8D¾ ¿lb«Ùj¶š6§ÍiówYï²Þe­º´êÒªKÙ ³f/lÖ2¬eذ#ÃŽ ;Â:²Ž¬#B§Ð)XÕXý?hw/®¦»Á&$† CwŸÆ’Ü º,áǰ¬ ÛÊR0Âe…-oê_^åZÕü_–=Ò-Q-árZÃwö_¬s„ljŒfEl”8èDDþˆo“Èöqª…™š]5õ-m?]çG×Ñ6â1Âüž‘ÙŠ"ùI®ö°‡=z£7z»Wv¯ì^™kÄ5⽟ö~ÚûiÂc†x/âÅRY*KŦGðè=†c8&œ0œi8Óp&»À.° … ;vÂ&l¦ÜÇ/ø‚/¡îˆîˆîHÑ›¢7Eo¸<.Ë3:etÊè[.ù†hˆ†ˆG<âÅ¡!¢Ÿ[Š©ï¼;ïλsžœ'çùØÿ±ÿcÿŠŠŠiEÓŠ¦ .=¸ôàÒI™I™I™—,/Y^²¤Ôƒzð^Ãkô¥šWœ’cã (Ð Q P Ž$ÇPâC²ÈJÒµá¥óäw±j:°]ߺ%Ÿ-Êõ´idqG~»Û“Þ%î7k%= ¦}ÿá4{_°_70ÏÓÄÝÊLë–½;¿Q³°}Ä”š""¿‡>‹ Ä™o®2ÙÞÊTUR>Ô6Úåô*BBðÊ<ÍÀUvN™ÈOŠP u[ÁV h©Š¥*–ª(á$œ„{¿÷ýÞ÷{'Ò4$ ‹{<‹è]ŒÎâ,ÎêŹÉp“á&V‘Ud‹Úµ)jSâûøïñ^ðZÖ¾Ò¾Ò¾Ê×åëòu’I¤Àô¥éKÓ—ú–ÝÑÝÅA!ò;ªäNìÄNT'ÕIÉX2–Œ=—.ÿ\þñ¯Ç¿ÿ*í$í$í```QWQWQWÁoå·ò[éºnÐï þœ*)÷Í}ÀVLFS*%Ëħ[Éz–’ÊØ‚³ˆB,Â6‡½E7¾1ŸÎžèrù lŸËÛ‘&níêx¯w»5wèÀÕu´BÇJ×ÒÖ®îø®ò˜R•ì“{^­šê—ß»QÅþ-V•]`y¡lEí6–£k‹»¸KlHQãœ^>0k‹ˆüÈ7‹ûÞ³ßÛmÛ¼íì½Ç´~ÜøLÙ)¥–êm±@¦S„É›´#©¨’´£bÏ|lžõY×Nzº0òAë‰/z‡vÈ+Èqúú"ÏúmÌäýÇß$$u™Ž¦£ÉRAe'¤€ü°;!¦jùåùæ*³Ž=B48PÐkÍ`Í]åWíK]$DMnì5ûhÞÄ ”ÌJ™ÈÏ ù@>‚%Ì®±]c»Æ¦á¦á¦á_;š}5Ëê˜Õ1«£ð˜d£Ø(1øéÿ ¸Ê¼Æk¼”x“Ö&­MZ³çì9{ž·$oIÞ’ßÇOø„O$†ÄAU*0)0)0á¦qÓ¸iÆ[Œ·oÑ·l…Vh% ‘€°ƒ'­eGÙQjKm©mÖ´¬iYÓ–í[¶oÙ¾wƒß ~7¸W‹«ÅMÓMÓMÓIßHßHß°ú¬>«ýØýZΙâŽ.I8…áô­DšIrÕÉG4Àhœ`ÃÙ´ãSÙ8X³ìúÀm±MqÀð„4°y^­j®Óæù Œ¯zvÁâãí+Ý0^3©ËžÛË×)º–ÝFf7jeÒɧ9Ê:x9t5]EöÊ!IðŒLÔNº5WÒÖô?cy=!ÖxºËZÉííLó:;·½ëÔÁm–/Ý÷ÎiL•MÏnôÓe†jáÙsµÏ*^Ô±SÚÕ¯S4nó¸Í#{Ípžá<ƒ)v*v*v2cfÌŒé+úо‚<àQ\æâù5ù¶Êߌ0ÄB |A¼ºöšrªö‰Î „¼Â9€Å"Ñ\i`&SÀpЂÓO3â~²ÈO± ÄPœ}}}Íš˜51kò¥å—–_ZjjjÒEt]ÄàðD‰ý€ð T *1—˜KÌÙN¶“íÔ¾×¾×¾/ñ}ÌAr° °s0sÔCÕCÕC©Žê¨Îà¨ÁQƒ£ú–•Q•ÅA!òO!¨’†0„!ŸÊ§ò©´­GëŇƇƇ.òZäµÈkÅõ×W\o½¾õúÖë“ë'×O®¿ùÓæO›?qï¸wÜ;Ý5Ý5Ý5ýrQ¸ë§%(äÂ9K˜ÂÍQ®h‰Úp%k0>„’˜Hœ]Å0¬ÄMá¿ ˜‹W R¥d =[=Á#Á¶oý•åÙõŽVléhUshùݶµÜû»¬²Ø€þÔŸTÇj2›,#P, :¨æj—¾¹ò±0ÓéU÷36¾¨˜à’v'ôfì’¯¯^&¾k”á’žv#ß]/u˜YLoÎö"ƒð;Ðy³³¬ê“ë…ÜxoÌç_ísµÏeû/»¾ìJº5µûÔîS½êß«¯~£uo×½]÷vMÜš¸5q÷Ëß/¿¼LÖ“õd½Y_TßE~5¾YÜp¡œ}@ÚkÍx+fZ8Pã¡ëFd4˜ŽãŠtižô!a|Ñûp•` s¼D*²EQŠü· A$ˆ±–ÂR Í Í ÍF8Œp‘­ÊVe«¾<ÿòüËs!k; ca,ìmZ¿2Ų7d'Ù©x£x£xâX‹Ê¿š5ÿj‰ïc@œ‰3qNäMÌ›˜7Q2]2]2]ñZñZñmq"TÊüˆø¨÷fùgPB ¥PÜM7X7X7˜^§×éõ /,¼°Ðî½Ý{»÷Ãö Û7lßH»‘v#퉊DÃããcêL]©#ŸÅ§ñjâ‹|¬¦=é="G”ƒ®*ï̺êÀÞ3à.}û@ÃÍroI×¶vLùȪ¼vªÜ$¾zç”ÊCݺXŸq¬b}ÕøªÕjÛ“@€3&ÞÚÃÐÌÐUû*?jâ3‡ç–R. —™röΜ$„ ‰ôuá‡á_+äº|ÎOwÎOÄ3`ªÿèI cð”ø¡<Ø0¬ÂMleçð‚ÍÇ>„èÖó'Y0aŽúùö íÕA‡GèþèON¤Ý‹ž/z¾h6þÚøkã»Íx<ãñŒÇM§4ÒtÊ"—E.‹\öxíñÚãu0ú`ôÁh}1¬;ä¹#‰ÓÖç#ùâ0ùßæ›âžŠ(1UàˆƒAn^ õl €”²’ý4ì32”J%ó •šéÚ;Xþh‰¶8„ë¢(EþkÅQE7tC7Ë]–»,w9-qZâ´$çKΗœ/‰;w$î@/ôB/¦aVÒr'ÿ5R %¡$TÚCÚCÚ#1#5‰šDMb‰ï£†/™ßJ©ž/<_x^µ[µ[µÛÈÈÈÈÈH(AÅwæ;óõ2F—ˆÈ¿z7íÃ>ìãwð;ød/ÙKöî6ÝmºÛÔa—Ã.‡]]*u©Ô¥úŒ~3úΨ1Ñ}b¹Iw&xÇß§it%ÍæmxŽ7×óß'*³íƲär­\^Zœ¨¸¶´¿eo'¯²¶VršPnŸK¸Å9I¸t.G©+’JZd+ÜZ“>ÔæÅ&\ùü §A|•Ïw³;†ËãN¦ÈïsQÞŸ‹žÎ{]5e{~|Ñ'Íi¬ÇŽï}9 np„©$Ó‘ÇÌ›À¾ ;ñ6ìZ±xlAf‚‚€G0 ù»òÂåá;ıCô=BdöÍì›ÙwúÄé§Oz~èù¡çtvÐÙqÆ=÷¨l˲-˶\ï³Þg½O¦o¦o¦/ÑѱҬ4+­WÜE¼Èÿ4ßwÂæ²ÛxŽƒ0rü•ê|`¬p¤¹|JMÈS¤U ‰†h‘¹hŒª ¢â.òß„\%WÉU–ŲX–y†y†y†“½“½“ý;ù;ù;yb÷Äî‰ÝõŠ{&Ëd™¢ÄþшF´Á.p ±!6ÄáGx‰ïÝ\ÁáPSMSMSM¢ Ñ„HfHfHf`!b! gá,Þð†·¨¸‹üËŠ©+f$Fb$’„$v‰]b—6FlŒØøÌ¹†s §ÔºUêÖ¨ï6cÐŒ&SON-=uД•™6™SsÍË•sñ´èÐ\V#Ê¥Bݵ^NöÓ<Ç»¾´Œ.ŸäzØ¢“ékÅ<€ ÄLeýYRTtíøH@+åãóåWQ¯w.ÅýZúÓñÎ>ÛgžÚ'¦Ì‡Rw?K(~ÿ¾§¿ÙÁÆd)ƒcÄ¡$yc;δ¬!Öi»êæ°†¸ˆEÈF0Öÿ`êÿyŠ´”l¾/ß—ïK2I&ÉÔYê,u–;±;ñ^û^û^```Ö©q§Æ;õtêéÔs…Û ·no¸7ÜކÒPʧñi|Ú£=ÚÃF0B! Q(I‘ÿ%$?ÜBAˆÁáDv¥ºÕfcÛÒ[\)JL–Ê9i©¯òYÑ#ÌEcTÓ¦ý¢è ÓgÕ¥xŒÇ8ÈRY*ϱ–ÃKȲ!4•¦Ò¨‚*°œUôï’ ¾b¯Ø+"#2"c‘,’E"ÉH† *¨†0„éó-¤"©zÅQpêˆE,bY*Ke‰ˆF4Ô¤©ÞYê,u:nÐÜ ¹Ü)=-=-íŠz¹z¹š#Ȳ“…³pv -Ñ-‘ d YÈB6²‘­?þùíñ‚¥Êæ0×+&0‰>3Œ1Œa,„ÊéÿËÎ3˜ÁLŸ=Z8/ȳ-Ú¢­ sJ)¥LÑXÑX!áKñ¥x¯¼‚¼‚<ŠA„ð¿_q § ¯ª¼¦¼¦¼¦Z¡Z¡ZaðÅà‹ÁySySySUUU B…x»‹üËssfÎÌ™b­ÌVf+7]Ütõ„™A3wû¨1Öh¯Ê¦Ou¨t“¨•ËSHsn£rXÀú¼O˜Tjbdô±l&ÛÀÒ“dóçTò£¬„·ISgåmxöêtòÕÛŸž¯Jì¾åufJë .—Sš©¼5·t¥ôß*ÒóÔˆT!6ˆÀ ÞƒídÕÙ–Š8†[ˆc³Ù[ôd™2%x0T°ëÿôîÏšŠÛÅYY2Kf‰1ƒ1ô"½H/ÞÜÜ|ž÷yÞçyQQQ5Ï×<_óüšñkƯ¿YºYºYz­Þµz×êaæaž~>fHÑúþóPÜIµ ºÀåQNˆF4âpW‘-´â/õø1wìD!A8̹©¬¤vcÙ¬ºàK»Ñ5´šéhùHi}ÀQ2‹ø¢šèuð‹b SØxÒt Ær¥\i’/%R¢R([*[j?õ¯ dUæÿª¨Šªÿòw0†1,‹ÏÉnžnžåóHCÒPÞ.neÜÊΰ€>±j¬HDBæD! Qä¹F®‘ëä:¹Nn’›ä&»Ãî°;Â67‚Œ`v‚`'p‡qX&ˆ± }ÑÝØÝˆÔ_üà?ÁV†hˆ†ú2"UQUI]R—ÔÕç~n†fh{ØÃíÐíô¹q„<â°€…^¥.‡r(G:’ŽD¿PfYGÖÏñÏÙ6†Á%\Â%¶”-eK…BB8‚#8",rþ$—b)– ‡ºçºçºPooCkI $P®Sû©ý´Áú–rÈ¿/J l7ÛÍvc b`Ñš¢5EkŠ&M,šhccc8ÕpªáTQ!½IoÒ[ô«ù·¬ïB]ç"VÄŠ¨õ#]>]ût-aÜæ…›Í×zξ`LÀhÛӎ͆?«Ú™Î½wöΫç3ÖŒCm®2ˆH~¬Ó'ÈŸV-êPB™ô€ˆæo4© ž¼ÎI _þÙ:»Ö÷û²f莽A-H]’‹Æû²s¬¿€ÇzaÊ£·>‰¤î_´—ÿçd%ƒ 2lÁláÛóíùöÜWî+÷5fAÌ‚˜S§„O Ÿ9`怙|‰/ñ%sræäÌÉqë4ÖiìAõAõAµÖ\k®5§Ïésúœ¯Á×àkè¯ÿ7ßz1j寥øòIx®Á|Z ø~€­ 0C‘(¶?âÅÁ+|DyÈ­«Š×\e†ØÊb»+uà h“÷²šjè†Ãâƒíƒ‡J(‘-´(„’3kï6M`<ŽàÊçgäg¤•?•{*wì`¥V©UºôñîãíU­«Äú¥(+çíË{•÷*ÿ‹pë*]•®Jט˜ÂÒ„4!M Þ¼)x£&j¢&üH~$?2Ï4Ï4ÏTPjÕ[Õ[Õ[óÓòÓòÓh0 ¦Á…# GŽPöPö( S¨ H‡úûêïË_èVÉ­RÈ¢»Çhc`cx®alÃXCóøxÍRfÌŒµ­ø¦|SÔìÓ û§Çpø¡«‚ ^'8Á yÈ#Ö$¤±ú¸Š«à` S8âCN±ìälÛÀæaa^nÂg ŠþœÁ™¤*¼z Ç„G.€­ØŠ­¿ó•®á®éw`G1Uz¼:èèizšž–(Ô:P2’Œ$#I"I$¹~\?®t–t–ôxQFQFö‰ô&éM¾Òutz5à6>àBJð(,i………EO‹ž=5:ltØè°‘ÔHj$ÍfÙ,›a4Fc4.à.ˆ˜È¿…+F¸Ç²ƒ,RðdAښ̶ªoi< ˱0L4¸Éx—6UËÓ…Kvªøôȳ=¯Ö§ÛÅ=K\’œØ9uEÞå5t*\‡Ó7Uò˜ô@$Yq¤ëŽùì2f³ÝxÄ6ã ¢øüNöáhˆá¿“ÄùgPÙ‹#Ä¢ÖÙ˸ŒË:N§Ó‘ä9‘Q+£VF­Ùíf·›ÝnDíµGÔîeÝ˺—õ˜1!cBÜ2Ý2Ý2×ô\ÓsMÏìÙ5²kÐÏô3ýÌ×áëðuðŸñYLNð_@PÙ½árAÞÈ“äIt &ÁüNmmmm„h´F Oxb38p ÐA'þF¿Ç÷ŸǢŽi ü•ø¯l9óbkؼ‘N¦ÉIÓ)òXi¡9™‰Æ¨à0¢DQþ]äHF2rÉ:²Ž0|À²¦0Űܧ(D .\™üîùÝU~¯-^»x×1ªc42ðþÂû —júNé;¥ßžVÀ²0žñ(#L—|Y¾,_–Oæ“ùdØÁvüAþ ?ßáÏ^Å:‡Îó1óÙUv•]ÕõÔõÔõ$‘$’DêÚéÚéÚñ&¼‰vºäŽäŽé°W/_½œe_:­tڀײ/²/N‹Ó§?#†O Ÿ\·ê1­Ç´ÞFYÓ²¦}è˜_7¿nQÝ«««Ü#¹Grä}Èû÷!w~îüÜùªçªçªç…Ç WSSSîWîWî/r.r.rœ+”éÊt¥Bk¢5ÑZ10à`Á7Á000˜ÃüÛ’NÒIºttt´­´­´­ÄOâ'ñ“͔͔ͤ>Ô‡út5èjЕ"‡È!ƒÓ§ NÓÝt7Ý-¯-¯-¯-‰–DK¢å“å“å“iÍ  …ÂG$ ’Ÿ5>k|Vê/õ—ú^7¼nx]¾D¾D¾D¾Z¾Z¾ÚHg¤3Ò Ž@B®n%·’[itÍèšÑ5¹ŸÜOîGoÐt§é#ÓGæÍ`Íàü·Ïß>¿ ºk×6•‡VØXac¶ÇKï—Þ;ÅN1¸ÂSKâ°e›Ø&¶IÈSWWW\\lxÂð„á £›F7n U0É2†ŒŸï"‚Êh#0˜À„w7xaø†žUx<™Ÿ›7ìÿj(çÉ¥ä+åù+ì>ÿê9à¢þ ç0ç$Õ¹ $/€Ïº÷ü(fÅz³;hÆ¡Sã(Z€‡Züö(!ùXjZÁ©õd=YO2ƒÌ 3Š–-+Z¶!xCð†à>OàÇÆŽÛ>¸}pû`çgÎÏœŸ­±bÄŠ¯^;½v"íH;ÒN˜Y!+d…z'CÁIä?¼àG8â9MN“Ókw¬mÛ£še5Ëúgã+ÄWx¾oûýí?tåMyS´‚+\Ñ/ñRŒOø=~´¸ïÁs¼Å!Èî¬<ª¾Í¯b„y‹8…»R·™Ú™L”/“ÖÂ"Á˜ _TÅ@TÜÿ@ºÈ*ò†¼A8_…¯¢¥š÷š÷JÁk¶/$@U"{gXŸ(o o@^&·Kn‡&MÖ*^¯y½æÍ¢‰º‰º‰¸Æ\cÎô€é³Ë£K>I>I>ÉHn$7’³PÊB ež2O™'YMV“Õ&SL¦˜L!ÉGòQê#õ‘ú(º*º*ºò}ø>|Ã+†W ¯Ì4˜);!y.yÎÚç·Èo¡‰QÖRÖ2ò•“³x…@Zœ3363¶®Zçh£Mšª—©—¥ß–äKòe׸ýÜ~n?¢Q4ŠÛÉíäv’¹d.™«¥¥•¿?þþ¢]E»ŠvŒ-[0¶ © © ©0¡0¡0¡`QÁ¢üÚÚÄæa͇5woJŠLŠŒî%1—˜Ks|R}RÇì5Ùm²Û–“ÆKã¹xY'Y'Y'Y¨,T*k"k"k"‰‘ÄHb ëÖ3¬GÇÒ±t¬‘‡‘‡‘ÝB·Ð-F·nݦÖÔšZJ %†Iº$]’n´Ùh³ÑfÒœ4'ÍùYü,~ËÆ²±ü$~?‰1#fÄÞ°7ì ß’oÉ·|’ŸØâ¡wyÝl>ŸÃâ]ãzJwr¹4 R4C9Åî3+¶…1KÌ×]{V:h†ÒØþßýùrÅðËØ2¶LPèIÒŸô¦Á4˜~zóéͧ7AAA5GÕUsÔÚ̵™k3×Y?fý˜ë[®o¹®¯‹,Xî…e€¨¾ÿENJã0!0…)äŠ Š f‡:ìè°cUÓ½»÷îî_—?ÍŸþàˆhAÇã>ñ%S/úKøÑâ~Œ½@€J@NMeu]ì$«KÛ‘£äW–®¡MM;ËÓ¤µõ7À\ÒÕEù[Ømv›˜÷¥ÿ—þ¯ºÖÖ&¹#¹c`^Ͷš­üudxd¸Š‘Oäz2WæŠ%¦{#1€éŠ-ÂŽ‘##7é:è:D‚L#ÓÝ$ݤø=ð„çÿyo”A™ÎøÀ>ÂZœøâϵçÚsíq:˜¦ƒ¹Ê\e®2ʆ²¡Üdn27Y2N2ŽŽàóø|.ø¬™¬™¬™\d\d\d¬\¨\¨\¨j¥j¥jU8£pFá !T+O•§ÊS  # # #UUUuv:;—× ¯AþSÌÇ|]׊òŠòœµ‘«#WûŽJ–þ,OõÊb­Ykö÷p¯„Þ–ÏñÏ!œ¶“¶“¶³ff¦’äºä:wHúQúQê  ¨†j¨&Ö‡ù“鉞H!+Èr0Ï$o ÏRŒãï—÷Îïý²Æm,’]”t ){瓪”.÷‹·Áf±QØ…q°Ã'¼G*>»ÿËŒMÁú.xK J¼óa>ô}D½(÷¢Ü‹rkÖ¬ œ8?p~‹û-î·¸?7qnâÜÄrÊU(WaÇÓOw<ÕôÔôÔô$$‚DWЧCÐ@1Yð†x¨‡zxÎ ˜ó¥É—&éNM>5Ù¿šö‹ö‹º´‡´·\  ÐAT€=¾ˆ¿ÈoùÁÇš4ÇQÌb7ÑK*}²ýhQêißvÛ¸¡äi)5—w“›–¹MXý•&G½,#ÙM{“[Úaü1ÖLåï·é€*ì»À)MW™®Ò½Ùî³Ýgi‡Õ«kMœ¼zòê–ž—z^  ÕiuŒà#øì, r䀰±EC€?L£i4m‘‰=¬ «ÂÊ o`sÙ\6½Ñ½a kXã4NKJöÿAÕȪ‘ÒùŽ+ÕÕÝ1OOnlœSœ“¶fBÕ„ªü?瘴Û±]á¢pQ¸Ÿ7>o|Þ˜7æyã0ã0ã0…ŸÂOágÌŒ™Ñ“ç&ÏÍ/KJ†%Õ[w¬_Û¯a_âV'¸$¸˜íä¬9këQë Öç…h6k6kÜÔ1êuŒ*N§ŠÓlÔlÔl,ò)ò)òÑ©t*ªÈ±È±ÈQ÷D÷D÷¤páþÂý|4ÍG6-lZØT“§ÉÓäaVa•xgý[Ä#ñ(‹²(+µ•ÚJ¥Ûúlë³ý`­Žµ:Ö©;¦Ý˜v£Ç>*xTðà2W«ÀÕÖ½Ö½Ö=Å&ò§azŒ2R‰çùÃ,£y¿š]\¾œY³¸C»ÆÍ/–ºróÞšø—íïO|ÁŽÝ‡æ  ¼á†ËÁ{Q„¿õS§Óè4:_Á¯àWpœç0ôøÐãCÜ3pÏÀ=ò\y®<÷¶ä¶ä¶DðXL>–|,ùu§îÔWð ^¡W.Å,4ÿ (((a„ cŒ1µiÓ:Wt<Ðq¿§½“½“£ÿ˜ûcî¬ö\ö\öü1'æÄ•-gËÙ2Qx¿åGW™£xw°€œx•¿º™Å³²ÜMr”ÜB0ÝH3L[ÊÈôÙ?ÈB4C à{Ȥ"& &ï$ïÄéTxPá@«ÏêYÄ[ñVrPPU»Án Ö‚ëI áo–È\˜Á a\AAy†Ïø Ž÷å}ùkP@¡ßŽÌÕ¿w`la [½e8†c¸>ó®°­fØè§Q!­¡ â íûïK¼„>ðmTµ¨jšQóÚ ð=yN†“åøŒÏÐa&¡®é…8'â$ØVÙ#öˆ=bÕYuV=?.?.?îwÊðE#ÑÅþ®=ÅlŠ™ÿÕ*)UR¼ÏÝÛyogìÇ m.´¹õ0 ¿{§þHt@‡ß9_5Qó‡3‚Û†¼àE©#uD=ÔC=Ä!qúJŸð ŸX6ËfÙú”šBM!åe"‘¨Ô j«Û8 IHÒ·QB‰"$ ŸP€–ˆÆhŒùè„NXÂÆ²±h ‚ ú2+%u;^H ý_«©©©©Y’=({PÚíÅP® Wä9…úöB^ßÿû}“½°0˜Š©˜Š\ä"— $É@!–6¦icz“Þ¤7eee—¹`.˜{±zÎê9ë&'oIÞ’q¢ÃÞ{»Î¡þÔŸ¾”«åj+n 7ÁÕãêqõ¨’*©’ž¥géYº.¤ iZV †Ô’Ãä09LÖ5d )CÊ2DADã8ŽãD ÈÈNÄQóÿ…%,aI‘ABàqn±¢Å Sÿe5–Õ蜠 ÐT®fgG6B ±Á!‚«(6‘?™îh‚²ØŒ ðåìhkâùÎðØÎÁS aS|òw^½0¦»…Òd¦kûE\dI8€l¥àé(ЦD"…ôûTr7I/Ú‹öââ9žã$Þâ-Túì颧äφðîþØT0H¯›^W¥X2bÉ?³Ù!³¯Es͹æä? ±ˆ…R›ÈŸŒPö(ñHƒìaòÊê}ߌ `ì=ë)UH¸Ñe{82wÓÛ$E±ýŠç€ß€ ØÀ옳£žÔ“z¦|Jù”ò)pPà ÀAN8uà”$A’ ISoL½1õ–Ÿ]~vùY›4›4›4¾?ߟïOrI.É…#á¨wΡ¢)æß…1Æ£nÔºÝ)ºStç©ëS×§®œgÇÙ5:Ðè@£ô½Gïñ½ø^|/,Á,åVœ³ÊBóÍ£Kw†a¥s®)§¨ is¢&7v„éãdj‰/ÂÑY-8£/²0}1DæßE -r#Ölù/"¤ä;ÊŽâ–p"Ì,̬Ð* aßR÷ÿ¡ýlÌFŽ(6‘?¡ì‘äà=¾"/ÆóãÝŒã¸Àž³ÛH‘^£ +x¹F[öDCT3É'W1„,ólü3÷¸^}—B )ËÇò±BŒ¶¦¶¦¶æ&lÂ&¼/z_ô¾h\Ô¸¨qQ~9~9~9¥ K–2\4|ÑðEÃc c c õµë±z¬žÞYQˆÅ"…DþU„Œ@7ÙMvSˆ8ºmwÛî¶]R=Jõ(åýÈû‘÷#ÿ”²)eSÊ’íd;ÙÎ$LÂĨ=?®Å‚€ð‡Ù æš³HYO]…˜¹ðG˜Ö8Q$õ1ô“´àš@J:ÀS´¸‹ˆˆ” „Ío$$¡*9@ ‡´'í1 åQ^ï/+ZØDþ“п9`¼ xç’±Ù.<…Š[NíKW´g:ñIä,Y‚΢Êþ/ ÈJ°ÁSPPþ ÿ…ÿ‚8´­GëŽ 8òÕâW‹_-öÜê¹Õs몪«ª®ªÚBÛBÛBËš³æ¬¹ ²ë㎕]`ùWU­˜³ÂŒÀˆ·o-ÞZÄÖ‹­[Ïúµõkë×>[|¶ølÁS<ÅS´A´Uö§âŠ;ÆÖ !¦æ8*[¨Ý !jÜÏ‚˜ÆØV¶EÒÈÀ@¢à,¡À£#Ê‹Š»ˆˆH B õwÈΈbÙ@˜±‹ì"Ö"qЀ˜Nä?Êg¤£@PÝR§äï×D«vh•“X2Þµ²Ýy;º‘Öºf|6‹F0–££(¶á>|Ö{¢'zò^ÂK89'çä/ª½¨ö¢Ú„ÞzOè}©ÿ¥þ—ú;D9D9DÍ«2¯Ê¼*£jª5ª–l”l”lËgù,Ÿ6¤ iCÈ…ß ‰ü3 ªÏøŒÏd ™B¦`6fcöÝ»!wC$žO‰gsŸæ>Í}èz^`“Ø$6I_ûE4¤ø­â®†Uà H@A²Ï+m5«Á!çvˆYËd'% L$e¹WúµxÂY¥ˆˆˆˆˆÈ¿ÀnŒ—0†¤ùº¢/êÓïŽIÉy …vï,FY8§ÚTP¸²LƒAt 1*‘µ>~„K‚ ÍC<ÄCÑ!é$¤§/J_”¾hA¹å”; 9 9 ¡ hÚ`蘡c†Ž™SNý9õ-[Z¶´lÉ?äòiÍ¢Yð€<~(%òÏð_ñ•ì&»ÉnÜÇ}Üw w wüâñÅ㋇{s÷æîÍËW,_±|E!Ïý@?Т!EàÇAV ´Ø‹Žh(XÞ³½•óU7Aˆ)yÌ.ò™Ô¸@zL"7HÜ9}NnÒT€‹(J‘¶ÁˆF> ¡É5,œ£ŽM(ý%&{@êâ†E¨¢¿¼¦Ãh«÷ÆŒa)Q’«d¬(·Oèÿ×݈Y3kfM<ˆñP¨ Ô¶mضaÛ⽋÷.Þ›f™f™fÙ!¢CD‡ˆU«W– +V.Œ—ñ2^¦Wß¯à ®èÕJQ}ÿ§á§òSù©ÄžØû)R>¤„œ 9rÒõ³ëg×ÏM4YÐd>!²¢ZåQ^”ÛëhÉ´F5áDö:¥¿:…Ï%k¡À.ð' ®ÈŽsŸ ËË"8cØÂ£4ÄTI""""""ÿÛpQ$Øã„¦Žv??&^—šxZv0!ÆdZ뎦Á†»P%4øˆ“*ŠíOC(`'ö–½eo†0„ ¾ì—u—u—uŠ@E "Z­ŽV×^V{YíekW®]¹ve«Ò­J·*ͧóé|:Z£5Z“ dÙ ªïÿ313©”J©T(ª¦ S†)skäÖÈ­Q'¬NX0Ón¦ÝL»ñÓùéütRÔ#õD±ýÖÇ]G® :$ùwU^ZJMÉE£Ò÷l™Á;{Sé}“B2G³Xr©H…Ñš4CfDDDDDDþã:b9mIºÁ 0‹ÿùxvW”e­Yi¬i_ÃNn5¬M£ÊÃŽ‘E¤Laü½ØÈ¿ø(¨ÚePeXÖ…u!™$“d¾lö²ÙËf7nܸ’x%ñJ¢C˜C˜CØÜ‚¹s üWù¯ò_E,‰%±d,€Ъ´*­ªWßM`1üBAAu[t[t[PuQ÷aÛ‡m¶ýpéÃ¥—ª¬¬²²ÊJÏîžÝ=»£º¡ !!$ä‡è‚_TlÅ)„Zö–´C˜0œ“¶)åF]¡U_O{М=öd·<éªÌœÊgY® ŽKŒb![ Ø‹S‰ˆˆˆˆˆÈ?I&r¡Â#DâÞ#9_Ö¦›³m…eÔ¾¸NV ™G¾s¢ùh„#)º—ün~ Â^¢ðþdŠûOÄAd–Ì’YÒkô½–——7³ì̲3Ëî1ÝcºÇ”ä#ùÈaÑâ‡E/t_è¾ÐÝb­ÅZ‹µ|ÅG‘ ’A2PQQïœ#°þ‘Ì; :GâHózåõÊëõÒç¥ÏKî9÷œ{Þ´ZÓjM«áNá_¯ÎWG)”úµ‹~þ^V™nè‚ñ€ ˆºÊ‘Ÿcß/¦!Ÿ‡È!W¶“$²³œq›%~£¾: Òm± fd (Œ¡9¿öJHDDDDD䟂{Âl0 60‡aR³´Ìü+™esÊõ@Kþ2kZv«ó!‹F2*™G/±­,C1]¾¹³þ„=ú›uÙ6°üà÷;¯þœÏàýx?ÞD‘(¥{«{«{»5fkÌÖ˜Å[oY¼%#'#'#§½W{¯ö^ëÊ­+·®\Íõ5××\/¤;¤.Ô…ºà.á’>€U¬ú[„Äš‚ägc6f_¼tñÒÅKªþªþªþõ.Õ»Tï’éZÓµ¦k…btB'tú•Óqþ¨¸+¡…GPM…!œ÷X}‚oí%Åg¾Ž7{T‘«½€uð¼gÜGÙÀØRnbPŸ^d3Y:»Kî.¸ŽläC¥ôâÖˆˆˆˆˆÈÁ€Ë<Ø|¤!E¥¨s'¦ßË1WÖXÆ”ïëòÂüšYÅfùE(`) @ןPqžú‚ú%ƒ 2ìÁ¤Á N¸Fš&ðNïTûsëÅXøª¬*«*؆©õ W—^]zuét¯é^Ó½^mµýÕöêgªŸ©~f‰Û·%nm®µ¹ÖæŠ?ÅŸB,bK<‰'ñDŠP¤wËõ$-´Ð²mlÛ†ÅXŒÅ¯Û½n÷º]\ã¸ÆqÚ:´uhÛ„4!MˆD’FÐñ+gvÿ½à‰lpúz`©l#Y ¨º“3šš©—º3ªy{Ã't摊s¶\ä|Ýz¦b'+ÇV¡¥¤W|ü>è ˆ¾°³ˆˆˆˆˆˆÈo`·™1È2¯S}²Æù¤ŸËYRø UðÜn®Å£Ty¦´—‡|Aƒæ¤ÖO˜ÉMxî[Âvú²GÐk°{Icv—ÝÅvRT nB  $%b^P¿êµX‹µ|¾߀®¦«éꈥK#–N|1ñÅÄ—C.‡\±©cSǦΌf3šÍh6ríȵ#×JÞKÞKÞ³XËbéGú‘~üa‘#ºÐ^ì÷È=r¯ðYá³Âg÷ªÞ«z¯ªicÓÆ¦}àÍd3ÙÌ*³Ê¬²_\üè!ïÉC}pª‹Û÷Ž’”Cî+w¸ï:â;ßÙ3àˆßü\·Ž]r±t7ÆBÖO´ _´³BŸ¥§Ú=2Y%\&Ð ¤Éå*ò¿7›ÀMŽ—%/K^–üÞô½é{Óg;œípVß&™Kæ’EY‰ˆˆü3HríI¶p|bÞ<¾Í –èÈ?¸Ÿ3Ñ·VRù$;{áUr™´ÁÝŸ®Ö°†5c0@8®Ùáf‡Í*÷ éR*·õ‘ÖGÌ¢ô-ã1)­?6‚ŒJÌ$¨‰Å2Ƈä!y(K'I'I'›2nʸ)!¶!¶!¶áÞáÞáÞË´Ë´Ë´¶¶¶BKDƒhÊ¢,Êþpå_NÃi¸P§Ö ^ð­ӷNß:}éÖ¥[—n•‘–‘–‘ ‹(:œ§ÃQ)ýÎÈì‹XH¤{² ÷4¸“X½l÷5\\íó»kûÕ¨=ê¬ãn¿¦|=Õm~^ÍÙ^#ìg\½nP×üªmÊL¶î×á_³»ô Ñ/ô€/Êê7¤üÏ$H*¾“°ÃàMÚA ¨ØüN‘ßÂe_™æ¡ Üa¿ósÍìP˜iúéZ’†Ü r¦Ê½2/­mõíeþ„OÒú¨úð‚6Ò7ô }ã¾ß}¿Ó—…Ž CÕ\{p]¹©ÒTi|õQŸ} ¯È+r…(Da‰Iž(ØÈ…JcØ5d YCrŽœ#ç4k5k5k7­Þ´zÓêEW]Yt%­kZ×´®­ýZûµöÛä·Éo“ŸW¶W¶W6߃ïÁ÷ VÄŠX;bGìôWþ…ý¶…1ÀÇñq|¡„(þPü¡ØÕ±«cç»å¸å”~P¯W½^u¡‚ *RÔìÂ*ÔÖ_A é/«q‘gHÃYB©]¬ÂÓPí9Æ»“3c‹{ÉdKçÇ .÷ðù¸WíÒ¿¶9Wgx!c6M¼ÀØÃ+“ú¦» ¹¿ÁÛJ/­õ3RÝJ–¢ œ`¦ÿ ¸ª¾ +b ¿åÏ!©d>ýÐæ=© ÚÁô{%¢úþ¿…hqù‹(ö¼ ƒ‰¶Ó…ä qÄÌA«ß¶)¹ÐÎäÑ?Yú´lîSþ .ÿ ØÂRo˜<|­×˜ú>•ôr&­qGï#ý³¡‡„îgºž±™ºT²TÒ%g‚ÏŸ*åÖ¯ ^±ÜªºUu«Ýú^ר `ƒ’ö³ëÀ+¼Â+rˆ"z Tö«ìWÙïКCk­‰\¹,rÙÕÞW{_íÝúVë[­o¿ YB–%ßÇ󯫾 B]O×ÓMÂq?Òôk98rpÌ•½‘{# “|’|2i_¬ù¹_N>¿sn®#EÐB“ë¯\­^‘žWØPÙdé‚’Xb›:<%§`@ûÊÓ.t|;öÓåÌŠIÅ*Û^æÆ†Õƒû®°éÔ~k}âöR·Ífr…´i‡4\ÀHh¡_b¦ÚâXrH!Á ôC:€„fËv•sÅmšîzÏz“yy¸±â€`#}Ð^ÐB+æ¸ù—àÀ蟱]Ù>V~.sd_Ћp•&ÒJ¤%•“åøDf%–ˆÀ Å´FG4D˜Ëuö›P˜ Z³-ÂqláÇò™:m²n7¯-)ON{y»ÅZybÚÀ îp€)øŸ¬zŠ ÂJ!Eò‘|$/Ž»8.-zÏÊ=+fÖM®›<ñA³qÍÆµú:¥û”îSì V¬6X+¯IeR™TÖ—C*Y>ßÅË-yÁ ^l=[ÏÖs”£¾}-úÚDˉ–-¯;_w¾îlãaãaã1+bVĬˆ‘‰‘’’b³Ø,6‹< ÈÁQD¯¾ÿ …œŠkY Ñ Y( e7Èv² ¿½øöâ[_âWǯ¾I­ºYuûR±æìš³åeÊ-*·HÖIÞ_ÞŸëß; þL9ž`$Úá:£¾pâô«^û|2¶ìð8~û‚ ƒšEùYÞQ¿:,ïôÌÜñù ]§û\fìqðämüÝ·< nß¶¿¸Ÿ‹'ô%šÉ℃Ä‘˜®ÿ,CÈÚ•eñ¥Å4ôFmÎö%ý‹7qaŸc^­O“vÇ\}ôŒuZVׯÎ&£òò~äöc:ª¢+º~ßmùŸ@´¸‹ˆü)nKð·œåΑÖ;L–ÕíçimŸn8Cf)­ð÷/Cv‘:8Ï=¥ïÉ CËÆd9ñÄ)ôF³ï…ÓéOãиãÐXø>¦WŒ2¿ô3îøË ³™òöµå¡²>èûUñX˜ÿ¤öébÏt²p­öÛÚoë†\Q]Q]É‹°Ž°Ž0^ºg鞥» ®\1¸¢o;’Œ$#õo,‰!›¿ñS§ýiª×deeG5bÔˆGæÌ™‡ËÂeá²å+—¯\¾Òî–Ý-;½ ž¶¤-iK´A´)ÁÒøûR*¾ 9‡s8GwÑ]tB†!¿}Óü›óoº4<úæè›1dEΊœ.ƒG;Œv0Z™V¦r!FBJ²Hšÿª“æÔ@Y®9CšÃ (ö×î¼£ac+¢GtÐ|™?}`¯&wŸb°K*焌ï°]nžn˜{cöº2]ý ³òR}ôŽ6`¶zòÝÜ e&×èSã þWSà9f#AòÓMÂmg ƒïÎ0‹IY§Þä¼>Ó ˾J¸Ñ‡;»Ui—Üî¼ã¨ðõÏæq•¾&ç\<0XqrÉU}©…¡@*#‰ìÀ \EÿÍÁF¤¤#*î""ÿÉ (x<†?2Œ1îYNœéú¡Ú~¯&Nu¬ôúQCu9|³Üš¾]ËNŽï¹ºF׺ã=¿Ú/´»e‘f4N:KR†üáåmiwÒK iä­FŽ¡·±]PŽ0ƒ=,a9¤±ªÔ>ðé-êHÚ=;±kpŸŒ… ¬”xò䛡Ÿ¬\LûLb€Lùé~;á*…RTGu€Ö¥uI–ðbƒüù r®Û^·½nééé97wnîÜ\î*w•» ;ØÁYÈ‚¾}‰t!ú|zßUmÒ•t%]á—o¹€Z7mÝ´uÓk#®¸6"ê^Ô½¨{GN9qäDI5&Õ˜¤›è&º Û° ÛôW¤Zr2óX–¸†k¸FÒ‡ô¡þw/†ñLã™Æc½•Þʆç6ŸÛ<0pGÕU;ö‹™3ósÚŽ¶;ÚžîÕ¼aó†–Ý«\¯r]²_/ç'ä ÿÒ3§t}A!²æd«öµ1åÊÛ#eªøy£¬ÍËŸ=¶_Ó¹ò6Ò Ô–œAªð.ó@…›Üè”ÝÂQm70Ö+°’öÍíÓãÃ{d;iéݰËõÏÜE+²€ÔÆ%ÚŸ„Å÷[”û¯xíÑïë?ý'“úHÇrò™ŒÃ«â [8Ö²t­zoÇñÞÝ{h3±cOkOÏ_öxz­ תoqó›²(=ðr¹É»¶K÷øÖ¯„ žøß Ïý…w‘ÿÅl–ôõ&õ„ãÙM5¯™´gã²I5_0ö¬ñ¬Âµóæ´ôJc,d×ä,Æ„L eìþî‰öÙ»/]uâê©U£:»/?8²VÃ2ϵò¬¨¨Ö¶ì`›öæÑòAÿà;¤ãüiS žÎ'‰Ä‘!p{0 -~x>ý¹Ïªf¨ W˜Ârx£"lƒjÏÑfca'kf]j8j@½UÛëMH´yL ê\$‚¢Y•Q™óå|9_át£4pÇøŽñãgãŸ6~¦ÙL³™f$…¤bF̈™>hU äÚ›‹«Úˆ@™Ef‘Y‰êÕ«îsßç¾Ï=Ò7Ò7Ò÷ÊÉ+'¯œl}¶õÙÖúçj£6j“éd:™^bz]ü÷j‚&hBüˆñÓ;  üp’:¤©S%ºJt•è!‡‡røØÅc- w wpŒ‰yÐ|õ©Õ§š¿9ãæŒ0·«‘W#Ÿ”Y8fá˜öŸ<ŽzÕ_Å’¼$/áû+L“’ß:°68È®at¨œå]4D½ rÝÝ|’¹@ÓÉL²Äj¨‘Nþ:w¡ª‹Æ†«NË“žÙ«òãT'ú[\îjÕ¯73§ÆiÞkHÍÚ²…—ÕƒgÆN¬§±p2 7¸6öÃzËÛ½ùC¬.Ë'…d˜[‚2zå]÷—xï}û, N°‚wFúJ¼5ë'L¯ÐÓµ¿Å´9G¦ÖÛÝ­WãÞeË| ¯J]fÀÌåu¡Ã9Ù1û]!ªuyß‹žFåû®^OmÛ dfÔòôÞoª'zg=%:²ïÇæÁýWX""""ÿ2 Œ\$­q‡·å§² [7ó÷†—;7èå±èÜú˜ä°ëÏœ•OJ¿™·ªHhš±û½AÒ©Ýa6Ôêœq´|´eSüÐ8¸ì€OdR÷m‘ñ¹sZ¯|凲_W嶉ڞð)íLز˜J_>û×=uIÚ«Ë¢°FlçÁ€í¸o¢Vd1IÆ1É`΂:òù«¬ _Àf0v‰I0‡pq?à+rÈhbŽ=l=‹Ç ¨§ ›Ò%݇˜icÔYv»tVŒì«„Ì&Î8ŠãŒ¡óOúk Уh¡l(É!9$çÙ³f«G¯½zô´Üi¹Ór;ßè|£ó³³³ 9r6ä`;¶c;nán¡š¡™Þ¹Bð)/)h ¦ØþCu6Œ cÃhYZ––X±*bÕäÑ“GO=Íwšï4ßf›ulÖq–f–f–Æ}’û$÷I;wíܵs—æ©æ©æ)}KßÒ·¼ïÁ{è¯)ˆõg‰ð}„þ¶B+´¢†ÔÂö°ç7ó›ùÍ‚•]hn»Ôv©íR_âK|I½võÚÕkWsRÍI5'YÖµ¬kY· º ºà@Ìþ˜ý¯&ܯx¿âu™Íëc‘šHÍŒåŠÁŠÁæÍ™9ûh¡ªJs€G&2øKÏŸ'ê@ÖÇþ;jO,?‹YtnðIÍ»ùöP~œ›< NÝÊÎ2k5ž8Œùä©+ů³ìüH“†`ìÑšI¯Ô»oëÆ3ÆBfMÖžH^Ø©íl³åÆ—dIBKJÈ|пíoUÅþlk‚p]ÁºßMàAöz¸DmÉVä MÌ ƒd{föÍ«í“^éÂÀ‘» ¹6ű‡«&Õaì±ã䚯ÖpìÙõ™ÏÁ²£Ì|šÊuÇoÎÖ¶›ËXdÞìÓŒ…¶ÚÞmR‡¦µI ÀWn=NÖ`º£º˜¯µ¤#ZÜEDþ#ÃR.„& áDßC-êV¨Ç؃ä‰É¹†w´åΔéFYD›U”FwhÛà¸û›%·†ÅÔo}ëùºv]kÇì?è8 tæ¦`sÿ Œ=Ì›4±ð²S¯2¦ìÍX˜Ç”dÆÂ6:3öŸ4]ÅÝÐŽ«›µ 8n”ý#ƒÍ»{TY6Χñì.¯|n”]erë•ví-¶5ø£¯Lj"èTO¬I$ˆp2ØâŠpc± ð…/ªÃùÌû†CBu´)é$œèÚÔ'ªìpÆžxNfì‰Sà„­FîmTEi˜IKshSÈÊÔ?Dï&ÑÐAïh×­]·vÝ8>p|à>1|bøÄ1écÒǤ ¯Òƒô =ˆGx„Gú«•\ëûo|»iÚ„6Ñw«9לkîÏûóþü#úˆ>¢Ïv>Ûùlçš­k¶®Ùj•e•e¥w¢ehZF°Äë¯üß `êãÇp G bC¶-d nâ&nohÑÛ¢·Eïz{êí©·g^çyçu<$xHäþÈý‘û£ËG—.áø…ãŽÏª=«ö¬Ú cÆ4Œ6J0J0ŠÕßó ç ,XVt¹úñêÇ㇣Gmó³-m[ÚJ Cä9@ÿÒó'7ƒ„ŽÂqO«J+J?ÕÌ=°®öÖüOj¶Ïo3зm…rÕœ÷9D†úñ9›”Â⊷РqÊùžj„éúÜ:¡µv×måø|ÆBS§$„vÞÖ¼—‰£Öê‹q°þsgÑýß“"ým¸ÿ{Ë€bn*Ô˜¬@iŠ,¬.Þ°óÃF˼ »º#©woÆBl&cìþ퉕{¼ò”Ä°Ó ‡MÚcxÖ¦]ŒNÉoù…®-hÊú‹ŸF¾åÞŸ9áSîØë_ÆÔZQ>È®2ê¢"lè.RDÊCNTÝKôÝ!*î""ÿ .a:â,–¢#—D¿’˧V,”¶]Â^‡fNyʂ͛¼t°¬•¯×z²¿3´ºÔ_UÉÅaùÐ[mËy]ÿ~܆ƷïÚø¹{ãÌÙyÿ£Œ…T˜üбÇÝ&7f,¤Åä(ÆB®O±`,$JmÆBNLfŒ…ÄLi®¶¹7Ž1tox?߃sf^ò6÷úÀíuot ðq*[ÊåœíA“zÿL·hKrP‰„3$èa“ò¤‘cìa ÃæmMº ǵ·WXi·\™uóñ¸ ~`jö‰¥ó­ÛŒ^%»H=\ÇÌ€_ øe‹›á:¡:‘¥d)Y*œèéÖÓ­§[ˆgˆgˆçÓ‘OG>9øÂà ƒ/èßÚ—ô%}ѽÑû›@Kl®AÅ_’xOâ‹7iö¼Ùófϯž»zî깈+W"®ì?½ÿôþÓBrIý»Z¤!„oR5Ô×ÿÅ¥m c“î¤;éNÓi:Mÿ£7Uó©æSÍg´f´f´æß!¿C~111Q4ŠFÑûíî·»ßnÕÞU{WííÒ¸Kã.]n¸Üp¹ñ;›Gæ‘i€Xi²4ÙÈëHÅ#O ‰xñ2ºOþ û6LÇ$LÂL*¥Rj¢ÏÉókBcÉ$¢/$ÔbE™^Žõæ÷û Ûµ ×@%ßkÁ¹Amö¬6·l3}û‰Ä™?dby€Mè&©Äy}¦óð«áÙHõòæ½qoÙˆ»Ñ  Y79ÿ©ÁΈÞÚÒžv LÖ믖G½I”ƒ , <íÿíÉÂrH¸.t™Z¼Ií” ì¶ÍXœÓÞ]«½s%`c&WcìñÊÉÕ­o¸¥åÄ MÝœÕ6§ã~R$-MqjŽ}<ø|‡AMê90ö¸æäzŒ…¬œ¬9²hf»oŸ˜‡k 8Á²¿<øIäOBTÜEDþd¤€’太íÌ&3›Ì,§sC4DxÀã[÷/õ"Žx)×ÈtH°š–9qƺ>ùµ ^ êÉØ¢2ƒÛLmPÞk¿¾}:™KõoæŠ)ÚCО4™Ö ]„¬ëßp¯’î¼Æ?UWé¾Õ„PÆB<&¿jw¸ÕÀV^¹n-­ôS]EÒ‰ JÃ&߯üóÏ_<¢jÒ$”b(:£ªpÚÕܶ‹"kýàquWÓ¸ßÚ>Þ“±GA“>1öÀib?ƆLx+`mj]Ó‡5º¹Œ*~yî8½Mv‘ÆÈ‚Þ•ˆt#Û ÃmL²]iÑÚ¨îÇkAK†ºñÝôš¸ˆM¾ßmBf›…õ Këƒ(h]„‚ï·‡è8Sâw‘ÿä ÿ-%À²q#V5ÍØãA“[0ö¸ÒäZŽÏj®¿¿¦ÐÝdÁo6…¤Ä ñ˜K5´1i'9ÀÍ¥ršLëvÿs%ÜÚ¶ÊÀ2rë%#º¶¯R™ÛÕ6°As÷[×9vµÿpôÖ ¯Œ=Ø;1š±§nS] Í™rŸ±ÐúS0ZÊ0Æ/œÜŸ±ž‡2vïí„ð÷þǧ!AçŸksÉà‹õÎuxÔ`¢û:¯ƒ¥­`üÌÐ\Úàï+³ÆQ²¯öoÙÚc?öé¨À9ñmv$uÿì]e@VËÖ~Öì—A¤Pl±E,ÄÀnEB0hìÆîîÀÂn±‘î²»»›˜ïÇÞx_¿sνçž{ÂxÿŒÃìy÷ž½föš5k=«¦‰¾v$U%{TgÖ´Ï¡•ïè;"¯\nÂ&l"ÉHªXw`Ýu³²²R¦¦LM™ÚíL·3ÝΈeæÌœ™Ž"Åhˆ¼­„V‚”\L?\?\?|’Ù$³IfÙí³Ûg·O«V;­v Q Q ‘Òm¥ÛJ·¥ahÉZ²–0 L~¥çù1œ‹¹˜KqGqÔ‘:Ò¯DP”[UnU¹U®•\+¹V;&vLì±ÀcÇóZäµÈkq6õlêÙÔÝ3vÏØ=cxÍá5‡×tÝàºÁuƒJ¡J¡Ê¯|Ùköš½¦ãtœŽÃ(Ë,ºE)CÊäFnä†`#¸ ª  Ò&§MN›¼?aÂþGGG˜Â¦â†ð‡"Ðü/Ð9ÈÄ2¨C 2™®‹æ«‡*Q-»]æÃ&¹÷ßÉ?E÷i3MÇC©–t4#ô¤8jþÕÒ!¯d·EX±CL“jˆJ«î7™}×l·‘_sÎSÒÃ:qžR?´¤°ö/¿x·IÕ#Ì*J²§#èÓiÔ@eèË Ù¯-RZP‡²tÿ È{™þº¡_DÛÇN®¥n0 ˜óôþái¼\ÂÙÎÓ’Ãg†ï.ò»<ä¡wG竲æ‚“z»A!8O+©.ÁæÐ‘ºOÄ›2¢%x"–‡|ôžêü‚óÔ·a/¸oª6!õùÍ®cÕCUI¶‘>Ó8\¦6(Æ‚ŸN°~(wøÓ šZF£7j!«ÐSõ–òa÷Õr›.ô;ÆÇ¤5wý{Î;ÖÏY¿ÅÈëv[^÷S4ôäåaùƒÄÚ!m8OkîÊyƾˆÎ3.Dìã<ÊÝ"€IDAT3*RŸóì¥Q­9Onr/gçNß&ÙW\ê1$¦ãȸ™¡%]òk¼nú±ÆCs[͵ÑJ“äïaÇî ëÛzq~úò¸%¥KãcÃxõ¦Ö÷$ « ÄZ–ž3È+‹OðOh3m¦ÍbEðëà×Á¯³§dOÉž’2!eBÊ„‹;,î°Xº´ˆ±"1YÏ2 ~qz@©”J’g¿!D~cýÆúM=–z,õXNåœÊ9•§šzhê!CCC‰ô‚cãØ8ÃƿճT#ÏxsgqV°¬k),X¾ùzZOëæ8Ìq˜3´pháР]6tÙÐ%?-?-?í ¡3”09arÂäù[ço¿µí½¶÷ÚÞ39`rÀäÀ¯<¨*©’*EPE ‰HXónE¤#ébQù‚òå Ëh-£ìÓÙ§³O{Þö¼íy[TÖ™=³gö?ëbzÃÐI,jV¾«Tû¶GØ­.m9Ÿ”8@ó)Ň®Nnÿ¢¡‹¨Ü ÏÊHŽ~!"ÜBš£,džBc’RëTt¬°á✇úÕä<áÉœ' u{±'®aàýŽï7¯(ùÍ Ø{:„L,ûâå&O­XÚPÅ D 9kK ôÕ.Ó壺QÁ)×M:»sž²%¬ çÉÝCçrž6+<ìîønÃÖ/ó ëÚlŽÉ½_y½³õô™ì¿úÅ_nÔ¡ %pœB0Í¡jØ£qLõœ’EÖÚ击ïçÅi Ãkpž2'Ì¥×a`ûîÒ™°nÔKÊê÷ýZÝå§™´¡ŠÉðE}ÒE6Fá#rГìPŠ8ݨ kXCYÃïÖN¢PÜPàOžSéìJY@j·‰M?Ú¶*r;õ1xïÖ=¼é±¥³ï{WÃ,Á@ØÁ:hŠ0ÿƒë¦xÎ)¦ÿS‡ d膦°£µT‡…©lÍ‘™f”ûï»Ñ¨¥!»o¾Ï`’æµîÝ[Ø5\šº¼™vüüyw;»Ñ+öö€ùï­æ.â<ýeÄ@γ'Eµå<óBdKÎ3¯Gvâ<Ó8â%çI¡ÊŸO̺öË®~”¬´¨~—ðQñ}vÖËßýÌãÜÅVºD_*9¨ÙµqO§vY& ’ b„ 6“ž’fb&ô¾K×y«ðNìÄNœÂ)œ¢:T‡êDÔ¨Q7{{ööìí§ªœªrªJK¯–^-¥t÷ì»Ä.Á ^ð’¾Ì?FžQ9oujL©1â‡8±¦fÍ6šqãÇ=>ctÆèŒÑæ¸Íq›ãœ§;Owž.L/Ö‹õÂU\ÅU©OQ6,a KQ5'eR&eJ¤DJüå-˜_7¿n~½SÍN5;Õ\öxÙãe–',OX~Qù¢òEå¬Y²¬-Y[²¶$ s@ç€Î6£lFÙŒæ ó…ù_Mµ9l›Ãš°&¬‰Û mþ[—žJ¨„J,˜—ågè~³ûÍî7/M¹4åÒ”i=¦õ˜Ö‹±‹YGÖ‘uÏ.¾{gªÿ `<Âptg„—8r)kØ|ïr¼t²Ë_ΧÕñí¾Ï®g»d—i2=šm¨üj‚€_ ž ÃÚS7±l}Íxj9­´ÕK »á<½wxZ‰M¢YˆëÛîÇ ‡lôKi›ê$Y È…˜„bœDYrÅF3¡*ûWÆ5€±£ž–†úÂàasÜÚØ}ìÅYœ§. Ëæ<¹mè,ÎSRÃêi9{QÇîÛk©˜ïÿJÔfÒS² ud~Ioñ{ø×E>„±lcY\s·‹ÍjÚŽ(æ)Ê¡ç¹JJxX­3»Ö~èÝEë–úpeF呃Qä„{ˆþ¦3È~õÚä6-á†Jt‘üP ld ´R(Jø+uà+*Ìïx:)wøÓ°ÑðbF´Ïeš‚%ÝØ9x’†ç<Î3U#.sž¡Qµ÷…í÷¡êÁ‚EÑUª=”ûÓó†Ê¯oUa =RB˜Å «ØZÁ’™!5ü=™<©ÐWãv+“ºƒ,·tTíÜê=Q š?˸²lQ÷/ªœ1èçéFá;9OÛÌyz—ðóœ§çGXqžV=4ó¼wã*xººZ’4rœrÜkÃ÷­‹_FGÚÛ÷oÑÿæJ£‹t˜Mc¿Jhø½)¯"? €&Ñ$š$:Ï(P> |`Âû ï'¼Ï˜;0wàqÿãþÇý›¼hò¢IËJWÖ•uýª·C]“WmãxjE­Hr¡q°t°t°\/¬Ö k Ö¬=:ÿèü£3Z©µRkå(ß [Ä!š± xRŸ¯s¿—Aó˜æ1ÍcÞÞÞã6ŒÛ0nÑG^yqzêé©§§æ{æ{æ{8zà裛#6Glvá:Âu„ò åÊ3~Ù«À*° ”I™”‰ú¨ú_æ×ÿè¾Â¢Y4‹ŠìkØ×°¯qÜú¸õq½}‹÷-Þ[ËbšÅ4sµ¦ÖÐ 7Ò•ná-‰å¤³›·^Êùävr>uÉÀÛÉÝnnC‚ú¨J“‘„9XöøíE­ŒJ ‚8±XgJ"ñ:74‡ªØž3»UÇcœg(G´(u**¸ïœâVuxNÏ£µgIÝTÄ=Le³é™Ód²Ç&±^#Hµ‹ìnÀÉöjUOÞ^´=h Œóôiáï9OúÚóôJá»/o²ìW¥gÇæ†vË•£dÛØ.I 2˜5ÄkÄ!ÚPÿbþo—€ ˆA?DçH]él$[x¼îìgpž67¼çé}ŸEÖïžPk°ô,ë©AÙNú+ïüobY+A5a šNöØ!lcÉ´J°b=¾Þ,ÉC/Pk¾ªƒ³Ez¹©]·x¤X/0[g¼T5U¦#ÌÁmRЕP©l±þ¾ PÜPàÏÛÏTIŠ>ª²Í²gùÊO?Ø9ÈŸLË Ÿt­ï–™ý?˜:UÕ¸]hC9Ò†/1Bë‚` #h¡?ZÁ[0­QŠÓsŠÂ¡kGÝX>³¦Æ¿ÕNeMGGë»Æ‹µï´«ÚPݦǤ¥>ëê«6£yû |wq¿V/mã4 ç<#rÔ‰£:ë*ÕòöJ¼µ;Îs]F¹˜·#6ĺ[v÷-)E‘°IXB…’=õû…|¶QeR&éë ’¦’¦’}4úhôÑÜm¹Ûr·3>f|̸Á…\.­#ÔêÀ®pý.ó­þ;©+û×-Ñ’Š¨ˆŠÄ?jïÔÞ©½3zgôÎè9»rvåœO1N1Nž0=`z`®ªƒªƒ^}`ùÀ–€P¢â¢â¢d÷Öî­ÝíaºÃt‡éoY½eõ–Õ9•r*åTºðî» ïŽçÏ;ž·°taéÂRO#O#O#CCC“_¹Áú¬>«[¸…[ð|¾Ê„úgm¢Ä~|àÚE»h/‹bQlì\µ¹js]nm¿µ½P¥G=,”î*Ÿå³|˜ÃŽ?Ój*€@´W±–(Í]²îšúp>9c@>/šbã“™k2h®×n5®¤&\‘ƶÖã÷å÷’s8a³éY‰eÕ ÊšBpLÀ¨Z-žržÑ,«hýÉgÃzsž¾$Bu׮]Øh¦+òu,jSñDö½U>=ý9OÝö”ódÚ‰óôváWŸ‡ÄÕ¼1ùâÀ¨ú›t¬4µÊ˜ã¥ e«(:Ђ´…øƒùM唎’Är½ £ö^9äBÉýdýÐÞOt÷æûß¶N6Õ>ƒÅE3¦JÓpÿû‰ðA8ÒÒÃzMÈ„5§8”b#Fÿ6ݘñ,½ ÍÖ:ja`å•SµÃÚÀÍóìØ3/pèZß)sê¦Í7Û­êû……“œºTxn¨" :T@=¨Û÷™çL¡¸+ ÀŸ+¡ͧje¼(à {d׺ÁyF÷ˆ¾œg®´]æßL²§ z¬+õA ÔÅ7gQ•7»Tƒ *PuBš0í¥y²óB,³§ž,ù÷ÝhC}Ÿ²KmÇ.†©áË»udÓƒF=ªxû°ß|ÿÖ‰ÏÌŽ˜xøÚîLËmicOŽw©ÕË®Èns5Iy¥J¡D"òKšïQ…U‡:Ô¥'Ê¥Ü2‡%Í®š]5»Î,œY8³0wEîŠÜºèz kuVU/#zþ¥óá<ó õ—b‡˜dT¥çôœžûŒô9 19595Í#cFÆŒ“oý¹?¯µÏ©–S-Àa¾Ã|  5!½YK –,¶N K KI;“{&÷ÌѼԼԼԕW~\ùÑ÷¸ïqßã¶%¶%¶%¿r#å©<•LSÁTÞïüï”4Ö”5eµÅrgÎzn^°yÁ´=AùAùîWÍߘ¿‘•ÑbF#ͺu•Žà$.”hW¾~,ç“K|à|òËw/®ú¢c¼Ñ$Íáj‘P†FYx„=¿[¿NpíJûðÙØ† %7á9k²Ô,T¥é~ÎÓ:…÷øœvrÕ°Êœg׊*·Ö*J»¥®ûÖ!–™̦*µÏä<É!$žó”YaÕ8ON -à<Å&ônl¯ñÉm:T»Rѡ ¯^¼+íGnc;ÊMï?ãS ž'”‡T©^•1ÏlÒ]ÒòçioÃwqžaá¾²Iø w‰¯†õ¢,RÁTø¢á_ù:å&¿t¡JqÔI²@¡3½lX_êû›—ÖÀD×¾m÷ØÐ`\ß~®õ‚öyO¹ïu÷ü­˜¥}>|êw¢ÇÐYœgÏêÎy:ïÃù…öb–¿›ô¶f΃‰{Îú˜gælèëÕPI¯Œ ˆôÉ…š¡Ú÷8/Š» üoS „h;±Bù¼’3˽²uSa¿ >7µJت÷8v|ÈT·ÌÖf3ÑMPQ0d]©×wû¼À< Ej÷˜O·(géÂ5êMÊX†×8Œ _^ê–ç>_éèèâáF ç™ö¼Ö¼Á *6Ö[·¢CÐÑG'æ×8VãXõþb{¦Ä”˜‚ô¥·ïQy• ¤ô‚$Ç­­­ˆ%c—Œ]26/6/6/v¯û^÷½îNZNZNÒÇERjEŽ‘ ¿ `Oói>º£;¤Ø9-Úe¬z½êuØÙ•ñ+ã›]?QýDõ¥5N|8ñaá Õ!«Cº¥y¦yž¸rèí¡·G Ÿ9|æð®õ×[\o±¦¹¦¹¦ùW¿8 £0Š:Q'êDÞäMÞ_ÉÕßï’$žÉLÄDô†ܨg¹Áå«gûnöÝ\éÒvÇ펋Æö5èk`ÑA¼72"#<ýéVWyÅ}R@³©5jq]ÇÇŠß›4¯ÿ­»UÂÏu-gïTad¹Ò„JÿÀ0ÉÙ*ˆ! a¨;TkÆÆô}VÏ’—¤Ü [’˜\tyëv»ƒüWÔñ\ð`ÕÍ~ïx`ÒÐÐÎÓ{„¿0aƒCß½*{Ô·ÿŠLèÏfФc º~YdÑr¦ÈØpºNú8ˆhSµ¼uáµÚáРƒ¥«“—‡®uûHÊàiÕý+ÍÕ÷Ek¸À„¦ëdð?Ý•ü$j†š0G<æ¡ÕÁ#L£ ÔG˜­ÀsV‘VãÓ/;ÐÑÓ´U)_užÍ@½7=í›ÙÅ.â®w¡ULVŸ÷–gC¶sžâ&pžù,r0ç™c"õ9ÏÚ™ÊyÖéÈËï¯;6øbîã§þuV/0­þ›qw"VÙ›o;áAUϪ‚m¾öP¨Aåh,õÇ ï óß/W…⮀ÿ3˜3mÁ[$`:·yì²Õê~©]¢àB–ú*\5sçrÕîž°€ô0ýPU`ò¿‹Iæ»°/a²ªP†€XŒGkV‘¶ãŽL}¦«*PîMÇ´ÚiûQS¥Ê[ÓxÓn;½]ô|nÈ™:gꟹwÄàˆÁáÓÍ­›[7·;¦#t„ŽiÑ[ÉwÈ}.Ÿ¨¨7õ¦ÞbY/K/K/kYeu–ÕÉÏÈÏÈÏØ™»3wg®íÛ¶W]¤‹tQÊØÊä\_ È[¸}àAEP) 3­Ò¦Jß{sïÍñÇÓû¥÷»:ò¤öI휕3ÌÐtZë.­»4>¨»Wwoë_v,ôú}h8 §áІ6´%uùÛ=;ØA€#)^¬×w\_·N;Šw¯iÒõn×»†—¥–ïð®Œ^ö'‚¼âÜË%Áa$çÑþ>ÍJNMØ_ïéñgzŒ«3´m…2JÄ4™ÌÿðU.D %Cl mä‰1¬W—Ù5#_:î03Ì1ð…yËísçD»M¾aè,«z¯gu2zlR?ýz–å×i;©JVDÀuY<Ó£:¨ŽJ_%•þoòh;¶ŒÞ”9wèà®® 9O¿áÄyÚ®ð ]O&7m+Q/Ñ*ª‹¨”û]᪂ÜS4G-XPõA¶LSТ 6žn“ñ¿ïÀú£qr¹r‘íôªF¬h~ÈÝ#mÞ’ÝlÞ5>j3x:癎÷8OÐã<=;œóôná78OK ŸÄyÊž°Ö·‚·ùúôÛÙr’©çŽQV½kÕYÙnEæ6Ršªà­êÕ8Ëyö´£9ÏKµ`ŠéÀÏ Âa 3hÑ@RÁT%Ê_óB¡¸+ À„¨@i@»ËœÉS¬Þ¶vüéÖïøšô€ð[œ§µ o<¸w‡ûÕv¡*£ݤ@œùéÇŽ€E}ª`[Á^ÿÐäÇ“M>–½){Sö¡ÄÙ‰³g÷{Ûïm¿·_]VH…Tø¥ïOy•cYaÛÙv&±­6Zm´zCÝ u7Ô-Ð+Ð+ÐÛ6lÛ°mÃ,t-t-t¥öX'Öé;~ö¹s fËl1šFÒH™©iÓþÀž){¦DžÏµÏµ¿x³çÅžûŸë¼´óRÙ9•Ñ*ÿbô‡?ª³MlÛD5©&Õ”ß,}£#fƒ2Çf6ž'3»¾v}…®¶slç•kW®­´SjÙü't”ùZqï^Î)Ï:œóèŸaŸ_ß·ôS«qOú{œ¬¸Á¤½ØFXGW~ÛÝâwAÞeå5#ˆbeYÁ<+44·˜²ìm´gõ:œŸqxôâàU6yNjVÊüª›ITHfh'˜È™þ"Ȉ&âé" £,ëöÑ xp~w_?óÒVIÛB­J³g„Ìk©_烥zË h1žÉM›2”ƒ”a 3èÂ^¨JÛ©NlMz°ô+ÑÊ•ûdQ~ ú¤Víë>³ü0³Ê šV¦U_2£{ðhw _(çI…¡m9ÏÞÕšó,‡ÈÑœgùGnä&nNÜœ¸9ß ß ß`Aà‚À†Û ·JVjV™Uf_'„ÿ¾Ôw¹`i,¥‰eë-Ö[¬·l‹Ü¹-2?7?7?wåÄ•WNÔ]§»NwÔ^›i3m©9ʬkÄ$û²mcÛÆ¶¹IîIî‰/vïÛ½oG¢akÃÖ†NÀ~·pßgnQyyÕƒzFÏЃ™13øÐ1:†Ò_eýŒŠûQÜ.SÜ«V0t-9Ÿâáóø]ÜØv}ˆœiã?q`xͽ•—I£t›¡KÚÏË«ïÐ Nd…4,ü•ûpûÀíóïäßÉ¿³ûØîc»Õ\wp])‹[ÅV±UX‹µX+õóݺ‘°¬k!–«6ªÚ¨j£½÷>Üû0^þ¼üyÑ*Ñ*Ñ*ªµUk«ÖÆ@ Ä@šA3¨,yÐ÷®¾‹üý×qס h Ü?pÿÀ}gŸ|fиá㆓RIÒð½}mø¯A8I¸—j©ªm|td¸A÷ÖŸÆ/ï{„ó»ý«L9Þܵf’˜3•-¦öø€v°‡…bô~e<ÍpcYÝ!e-R»¦´$>f¾©w\ò½ÍõÜê»±®_›þ•ûìÖµn}ʳªÅ¯y§<'¾~qÄyÈKÎ3.EDrž^áÌyzxø]ÎÓ»„_æ<­mx]ÎS'…}¾#Û>~ öÚFÃ7{ œÓ~gµv cœŠMÌÔ/©Ö•]øÍ»2ÄiŒF²µ4“­¥OdK•p¡¯‚T~çC‚$&{)½c~ãìŠYœ§Ú‡-á<Ó&âѾœ©-ÚI;~a6ÛCóah}/ïQ¡¸+ð߈‹œgvv@žíJ4p 8±Ì•\`„ _ ?œW7¦¾ÈË+ÚD˜¸ûóÏ©•8OYV¬Cߤº\zôl ù¯×ŸŸ òÞÉ-Ñ-™'ódRȯùvóíæÛ—ù-ó[æ—w/ï^Þ½c.Ç\޹´vkíÖÚí«÷AT–)\ŽIý›†ü6æ0ecØ6F¬¨1¬Æ°Ã:tèСü¨ü¨ü¨±æcÍÇšËvËvËv# ò!Ÿ/sQåO48þ¨Ú_,èÐ&¯š¼jòª¼£yGóŽv›×m^·y¨ŒÊ¨L^äE^? —¿_MæúX(±¬g®–£â|iò°9Ï”¬žØ¦?8Ÿ.ó}¼ôjÛóõ¥@Cb˜Šþ7TWŒÞ×Cù¯ÓHI%®­¶»ÂÐù«æ:U›¿×sÕUÅ;OmXbs¬ý†­u¯§ˆô^Íù™5ã#9O?®õ)øD»¡áU÷&ø??©?wº÷£1¬OJÝ5;T 6¹k¦W¨1÷·nAXÊÓbBI—àfbÑ®p†éŸ@˨öC ÊY{i‡|°;®9d!/ÊhX0}Ml¯­šãÕÖ)í½öÉï0ï[~_¤BqWà÷Íúa¦”©ìêñªo„ÅíÖ6É4?i«k­­ñøWJ9!Œ-¤EDHD´ e(ÿ£±:ÿ;” #u¤#³WçºÔÜ´cþÀùülšNxÅ7¯O šfh¸Uk\àc¼ÀA~sù¤¿UI#¼BöU~ÍêÚÕµ«O98åà”ƒ9sç4N‰I‰I‰ñâ;Åw ™‘™IWù’/ùJ}~/^àòÎ3õPõ˜3sfR.Þ†6jØèxÉñ’ã%9rå4š¸vâÚ‰ëeÎ2g™­tÕ=Ü+ÛL~‡”™Ò†M¼k!Nˆâb¦ÄL‰™’“ž“ž“îRÏ¥žK=éáäƒtøañãÐ200õéJÝ…w‰}F·.Çùä’ù‡)«šížÜýQ³ÂÚGý¥«’àƒ6ŠÁûhB J(3—°‘m«-(ïq5ã}–ïUÙ^9kRT3Oo¹Ù*-Î~qiÓØÃ–sšwÛ?½R€UÃ~‡5_ñ‘Iÿ 2£¿ù+ïq!²ýÂVN°d½¨/Yã*&ȱëüåI¤‡ü²ºš/Õâ•¶eõX>£û"^”±$bùã){'ùO«yζ«´ °‹¬¹~/Ë¥BqWà?@ž+ËуàæhžVY¦*ÎêÙ¯b³Å|RãjçÛ[á´:j¯“ýì†Ã«Ô0öÕ<š@•±öRKœ‚LÎ5⻊ !,t¥çbÙϨmG§ ¿ä¶¡Ñ|Kz•ð#±åÇÕoÝOj: à‚¨ …(ýWu h@òùf“Ùd6YZ‘ž Ï„gÁ®Á®Á®™2;dvÈöÌöÌöÓeL—1]´|µ|µ$•ue]Y×_Èó·½}ú¥õ=Œ…1)šÂ5Þ5Þ5þØÓcO=Íí™Û3×{Ô¸QãFmQ=¯z^½M¤‰¬c1IR_ßò‡<ñ훼5ykòöÄÃO<<©yR󤦑‘‘x2CU©*UUL”'Ñ­¤y‘N¾d»óf÷ M÷ñSÒ6ä|òô›“Î ìÐ:FÃ\)Væ ‘ôaú)ï7—ªp”þë„4LfŒšá[;$}rÆ“Ô[s‹Ç= \6b×à-Æãš½mÂÊõLüegT×0Æ6Ókk´ˆªc– M¿²Òýýù)ðGC²ÇUŒ's\Ãø•S#¸æ;³ü#WqÝ”Yaíº½oÖÍv#\àcÙLa(ñïà –C90¡·Ð[èM ¨œ¦kOמÒáÚÃk¯Œlÿºýk¯l›€Âiá´pJPRòÿ”3@І:”[ֿ̨1m÷@ÆáûÂîwKÎåT;93ysX—¨=JóO6™õ:"A=üÂükC¯6±1×Ö¿®y@¾KY3Á….c7¦ T%—ûâ›Æ{ÃPZG pPù®RkÁ&.eƉNœgdE¬á<µEØU/ݬÐÍ`Ë2™15’Ì üQ ü—õ½u¢NØ‚-Ø"¦dêbßž‹}üºøuñëò¶æmÍÛ:ßs¾ç|O“&/L¤¥‚¡`(BºÐýeŸßþSc0c0kÆš±fb…{c÷ÆîµììÊçäåäåœ\upU?i3É4™&5AuT‡!Ô¡þ]¨ï"ÁÃDšH’†à2Ôe¨ËдÎiÓ:¯}¿öýÚ÷áááRûk¸†kŠÉñ½ã?-úçð/à‹z¨\ZŸ¯æW^uÿ¨óù bÙ*ªÍ_Ïátj«æ*¿PÚ)¼bVh[ÄqaïA ûÛQŠR”’‘9à­KýÖ:ܲ»©î¯>¨Üœ —´£úem¿Ú)oœ’¥ró™—ÇÔ…бE¹¡ÒÖµd]I^\j\º;òÛ°Ã$Ìâ „)˜Rppp Œxò ÄÚ¿3±9Bkáí.ÞZr„4ºûÄq‰è¤ÒMfí0Ù²eùêÈ@5–âhƒC¨3$¢÷¾¡·&ZOKQ ŽWxUZI-éWç}pŽ?àÓ´mµzi^6Î*:ýùšÊáÒ§¥ ,K“¥ÑS¡Š©ð3AôJ/A)8s£8â%ûKÝøú&Õk˜Î‹Òí[ZG-ê­ò7ÍöµÉ>}íyÞkÏ63=îÕﯢ^GÉ,Ýk×*êÜ£ʌå¦û»œy´Èz—]ÁÇ-ŸG¿·C<2zK£qŸäêAoDãÞàŠ$›+ÿfü¯CŒÝbCèl©_éu¾¤Fp¥{úCÜxÍëæ¹ØÅwðƧ/Ýyt4Ýô< û Úœ¿äê|Þâ +ꢥ(ý¶ù.¾‹ïBô@tB'tÚ±~Çúë_f¼Ìx™Z)´Rh%×Í®›]7¾5|kø6Ú%Ú%Úå|ÆùŒótŽÎÑ9Ëcy,¦` ¦HA±%(ùmÞ³ø©ÅY°K°¤´AiƒÒbØîÉà“Á'ƒMºštµžãÂ]¸N¼0[˜U/ª^½Ø]lËÓ»n~ݼè%R"®ñº¼.ö|C³é—àààtšNÓinÈ ¹¡Õ3«gVÏÔÜÕÜÕÜïm¸·áÞ†ã>Œû0'q'qp@19~ttƒ¬Y[rÄU”ƒ ”¦ô8Vëç3ºø=øœ=þqßwöEÎìfe´Vs–š‡xõÇALQ ÞW—‘¶É†Ù0É».¼_x¿ðuWæ^™s»$*'êâØîÀÄãò;€-x‚Øÿǫ𽸔¬`‡i ô  •fñ5û›{½ozÔzðZ~=ó}¤÷îÂh;/ ÙZ!Š•‘s¥`1º}3ïë« »¬6íÀ'Y‚ðŠ6‰5ÆuMz1ƒé+fx´Þd½%&Ð$¨ÁX‡3©v¢ãt’â1c ©ÿŸr¤ô‰Æá:¢1*š>Ô¯­YåÖŠm3}v½I* ­ÄyöõáÉ+^…÷¨Uw®ÝãµKãC«ºR9Þ`Hçiá•9O]Èyz@ø™ ¹Ÿôë;¤fÇÇÎÇ•ýeœ}•ìLèÆ¦ÒpÌF IUòDºÿ,ìa]Ò@6¤ÀÇi†~zsžQ7Â󌊣‡ <]_Êô)pAF âI…B þ4ȳ¦ŒÀŒ`ŽÌ‘Iç¾NmœÚ8µÙœ°9asBA—‚.]öoÙ¿eÿ–Úk¬ýQ’çæÔœšã ®|‰ÅøöC9åŸz†`q⤲ºšu5uÝö;Ø/æÑ±sÇÎmj¦f¦ #:2;&0}¾ƒ7«5¨ ª‚ª ÑHLdÙDv5ñjâÕÄžk{®í)ñ±xÏâaØ(&Ä÷Žÿ´¸ç£Ïi5ÎÑz¼Æg½|ùñÀçTpfÏÖ–ñJ|µnµ«Ê”²„‰ì–tUMCO1¸_AܦÃt¸´}iûÒ6 *Tv‰s‰sñäûÈï¶û‰N'Z¨Cz¤UºPöXöPpÆ,A ôѳ  Õ/êú·k(à9ÜŸQv­õ½®//ÜßöL÷ÝcØ` œúZ9•ߨå¤þDé¾è¿KcÑuÿá;W2XÃåp»1PVN(O™¥9¼ TŠÝJÊñÞÆË×ÖlÆÃÑP£Eë^º¶.Ÿÿ2¦Ó+Ônëæ4Ki9õG*WASX Ô¡ò°+ðïQ‚RpL’5ŒPŽnâ†-*VÁ­ÄÒß"U×P¦É^PÇ´ 9ö·²Â*.U>’v¹Z¡OP³ygOÖòð¡øàÒs•ß·ï^4 J®RÓ:^ïá¢Üµæ^™KV°U{ s_b×MuœÒ]¡wɶÒQ|YÐ5Ì¢óäƒ<èB *Pƒ dÿØ&_ *­'˜òw¨ƒÙjSTšËºôìÜœÙõELiò"÷ɹ·Þ±ñÎW`;&¢ 7)]È«á5Þã³B þ4£Å’É<ÌüÒ÷¥ïKß³…l![x.î\ܹ¸¨ÃQ‡£§nHݺÁ¼¼yyóòÓ·Nß:}kûôöéíÓù ~‚Ÿ@Ò†×x×ø„OøôM³¿‹O-šÌc1ã-Þò^؃=Å • •_ŽMRNR^ò(Ù#Ùc‰¾±š±šQ.ö`g\›kcÌ`³oúÍÎÃ<Ì+YU²ªdÕ T£Â„ *Lø¸öãÚk   PPâ)žâq7pC1!~ È>³™tW,ûí¬Uh;‘?ž¥Pý]û±½/r>¥‹Ï»*ôÝÊIqÙt·«·¯PåQžå±<–'V´kÚ®i»¦ç=Ï{ž÷\¢²De‰Š²•²•²õ¡>Ô[±[¿»èöÿF¨ #±VÔK¬8š:»UÇNüm–y䨒« ×BtkäT§BtG¡ÝÔ'ÿ^á–㬎¨Íè4iáŽâ«0AëiÆýµOGÍïÙ¡V¥» vÄÞK^¸Ñ»ÙòÓë¶võÖá<³á„<Î?EFÞîd*qû°ñt“L~å·ø‘ ÎRu¨@ÆÓ{ª(V‡¯èæU3‡ót§ð´âå§ö~õ1îEPÛê–s+œ’„¢P8ÈliY—¥ºÑ0¡ªšIë=•£Úžã<Ñ!Äžó´ ðNœ§T -å<åS؈Sžî¢ß6ºþ6ëž_ÝÏ^ÌFgÖ™’I½àñ%ÉÎßn‰g;˜@¨ª0í¡ìÞÚöméáÄs!+ùú´Îáî;c& ó”öѲýòÕ`? æ7 ñ8“e²L±BW¦+Ó•MŽ˜19"‹gñ,žÚ7µoj_///v”e)³d–Ìò³à[}krÖw–ÇòØMlÇvjÖÓ²§e³9ssææ4[{bí‰uSÔ»©wS÷‚=ìQp¾åÍ EQI¼„ B!öEì‹Ø µj'Ô®v ÚjÄ ›Æ¦±iß½F¡€(ÿ«Õì–¢­ñfágã¢3Ðÿ¼­˜³©Ô–>áƒ5,Õ{¨&Kí¿eŸ° 1ˆALiTiTi”²¡²¡²a³Òf¥ÍJ?7üÜðsÃä#ÉG’|¾õùÖç[dGvd‡îèŽîßýH¦à,â>¶¡:¡ *_¹w/B£8ªô«¤4‹m¯uÖvœá8è@ªP‚ ô—sW39~b” ”yS")3=ZD…¥+¸3=´ÄB«GFµ+Ïœ;(³±V|ÐüiÕfëÖÐl˜õÉ öÊO•æRsÙ·O›K;eñ¦Ëçm¯Zè§—?­¼Üq†Õ-½Š¥¹5@)ÅßR,œ?DYåà»ÆìÈ­tWç×kØTÊП>þnG—GÅNŸÜ‹Õ…UK¥¸ N뤷*¸}½ÖÓ¦TLp³Ø¸¤méþž×Ç\ÚL®8”i:ýðàpÇ«cÎtò,^soTJXžÍݪŒH @n¸U©ýÖ"p¯îÁ«÷þÛÓ*´›Vÿ ãQã!è€ì,ÝÉóOl{At<"£T:Sú«Çd(:¢?ÈÕøHÜÃ%Üï¿´U´C19(£ßÍknl},á¢r±=ÐÕa%m-Äxþ:D#Q„¢Òz¥õJëÑÚC{^¿(~QþpßΣwøDy¿w¨n9N¦#¸õµõ视HÃäNîäŽ^è…^jjjâ©ãAãƒÆõzêõÔë‰:¨ƒ:bHÍWi5¾cÑ1Úˆ×bE—+nï*û•?µ*Ø›ßHÛ>bý摵[¬@=8BŸîÑPœû“ïá_ô—e¼Úë1-hÕÂLIW¾¹“¥uo½Žó— -i²èùăVƒNržÖ6¼ç©ËÃ28ϤˆroÊ]½âî¸îußô ï7F}øTÕQ¥V‹b/M¬zé˜Öº—~ÉÆ kw5P™§”,ôbÖƒ÷NFˆ‘~æ;¤óSà+ÈY…©9Þa.5Æ+,Öz§~P¹qÖ¼Çzøqž\úˆóôõáï¶~©ÍP–ÃìÈM0`©;ò°½ 5(IŠ”\.Lç©?³?ppP0Ÿ˜î~óB㘤>oÊ5ÐU^-ÝB <ÀTÅœø ÷­! ² †bMW¿®~]ýN '…“ByyùÂ] w-Ü¥ûP÷¡îCéªô€À Npú%£ü7s˜Ã\rž„\ ¹rõLâ™Ä3‰s[Îm9·%š¡š‘>链äÍÿ­=‘‚°LX&,ƒ>ô¡ß:µujëÔË—=.{Ì~;ûíl)n„ÞÐzƒ¦hЦ aÿ‰ ØÓª.–8›§êßyÙyÔ†ž×‹ßLøÐ/‘óè>íƒý]V:Ha… Åý— ~Ô$ËDT@T@TÀéèÓѧ£G:t)¥Š@¢…ЍˆŠ?Ô³‹IË• €Ulg’Z.äýöc‡˜rž~)ÂöB•˜S}ËØšS°]ákTø~Xž³«ÑS8Ìr)æ— ku·M78°¦rÔ^ª¯„8 ÜÊyzQD#ÎS4BŸsžö(|Ù›àç‚^. oä^»‘àôÚx·|ÖÙ†u^>º'!ð0çiÉí8OW>í¦¿]Ã2·™½Lœàkè}Cრü/h…º°`j4 ·ÅŠ•,ÂÚ=†óŒÈˆÀ’mI/Bû\þ´©}¿YÆ!å‹5*à) ”9Ó&¼,›¿Pš•!û"·G0íÙI¦Kµä›h To¨l2tŠ÷­êý¯ÎÙÞ1çiÃ=8O^ËyÚÖð¨WÍâÎÕœ›;DÅ5Ö¦«‰µö'ù„H¶–&ÓH2ÅF©JÊ¡ïÿ†¦¨ s6‘n“4¯Ç5í7¾ÞHÎ3nElá<ãPDÒD6`¬‹ä,ÄBé2¡êÁR!PÿäÕwFŒ˜è3-Ö4¾ÕøVã[qIqIqI 4Ž)ˆ)ˆ)pXå°Êa•ô{±^¬£ñ. oS}W†2”™13fÆbþÔ*gªœ©r&¡{B÷„îÇgŸu|–ã]Ç»Ž’{0ÓeºL÷›{Š:¨ƒ:òK>1>1>1—]>vùX¤w¤w¤·ØFp…€ÿt` ©]Y¨c¬“NÌý}‘zÝd¼Å¤æýc9næãíᄂ†ÄÿªPÜ%ˆ¾q—q—á _ø–W~\ùq;ãvÆíŒËz—õ.ë]W5^Õx8ÀÕbµX­ï&_ÝïGW¸AbÑ|ØT~¶úº‰½§qž16"úaôžõþæ÷ ´%ùJúØø_«¢Â!Z²õ  UØÁº¬%G7´D©á"ÜÂÂÆ­«YšLÝ4þ|›A/;Ç= ÌyÆíˆãœ§Ü Äy†~D“çwúº¶êt䳿™U—ÚtÑûðÕ¼¨I…Ø);,3¤Ab÷×:­K†'®ÞXlt*(¸yI­„>Á—Ú¯idjóFúõ74ê “®Âëý{„¨jkB JB6“FŠÕ}oµxW¥çi^ὋVÇ?öªÈ÷T§àŠ®9ÎLI—Þ£\’[èßüÊ¿~KPF}8˜mb {ù†ú}ttÕÚŒ=Óoh½»ï}áÿšóô9å8Oív„óô.áéöï=à¿dTAŸáu¡ûJ+P%ÿ+IÞÍT¨¬`í/Ó?¢À –x_–¹|®¶¡jÍëѱ†ÊóAiOÃ>rPgÐuçæ—V¸ ¨€„f,’ÂbõM@^ÕžŒÉ˜ÌbY,“bª/¯¾¼úòØF±bÞ|zóéÍû‡îºhà 4\ u°™mf›1 ³0KNο=ñUX…UäAäA/轘tzÒéI§/¾|øòáÐÏ¡ŸC?#È`cØ6о!ñ5Xƒ5bìœÌ]æ.sŸÆ§ñi<'>'>'¾më¶­Û¶Ï è=½§÷ß¿.è3E‹©¹©v¢†Ã•âàUÞ%œOž=`çÑš>ÂÊâö †J튻OÁSðËm?´ýÐöCÁ¦‚M›nZ¸iá&ÕDÕDÕD‰fëGõ?kŠ0‡ ªÀÕ`½ÍYc-[mç§ÒwD( <¹aX“nÚž¶íÚ°‡‘0›í¤y¿O4åÜ`ÄŠ^¤‚ÌŠVàéW- 0-ÛÔ9dÙbGì¤ žE|D™à7œ§æ‡½á<%.¬çã"–>˜¿»‹ß¨ù·‡Žl2©ÊG˃å—õƒó©5Ù òG-ØÂµ` }6’®‘t¸¼pé°zn¾œg8FŒ+™™äòövòö·CÌè×Ó4Sæ°1tëKЪ"ï{¼+KJ ‰Ïz¿ñíí·ïîÒòÝR\#1*¤/çé7"šL»ê¯ßP:‡dç˜ ¹ÂzÐøƒ©…ÔþÅMDíQŠ%Â<¶‡æË71[©?YséÜ·ƒ¸Þ{8hoOÿIœ§w ÏyRvhmÎÓ_DT½Òpï÷rˆKÇÎ^å 4Î)ÇÉ÷Àö35ª†;Ø )æW'Wÿa±Q2uF*¢Ð 5Û—6`óšóT¯°y|JÚ•ð¹q/gvh@™ä«´Œjã ‚Ñ 5þòÈ~?äUm‘VaÛÄ$\‹Zµ,j-5\j¸Ô0Ï!Ï!Ïá¸Îqã:íF·Ýn´$Ÿ"zPê!·Ê}sŠ#»Ì.³ËbÙí–Û-·[©7Ro¤ÞØg»ÏvŸ­±†±†±Ú¡ÚÑsz^–÷÷›À|€dHÒ¾§}OûÞ¶òÛÊo+Ÿô4éiÒÓ*U«”ªPª¢êŸ䉭ü×56)]‘EåMôhçÂ?Oa>û9Ÿœ3àÌî…= ›¾‡t I»q 1€Ò#=ÒSê¢ÔE©Ë ¯^3¼ÎÝ;wïܽ÷îÞ[løƒf¡<4˜3mÁGXÂÚAU;ØWëÄyV‡ÈXÎ3&GDL~:pRýD±¹ìˆ0ŸiC*ÿF¹‘'X<ˆð–E}è…|6– È }J#›÷‰ê VvStääƒaaœ§?Œ0å<•…Esžº1ìÁ¿Ýj¾ESZû5lpß6¼¼îWüÄtŽüO³È»1½PGúƒœ½œœqÑ4‘*b›–ƒÚK¥óÙW¼ëÊ?¥Ì«ÃyZËpÛ½•§8xõ>ÚtUÐf¨nc;Ê+dßäÔSlÅ8x²æŽ™@C©^ù'sõ‘·³Å`$<ðq$û$¼fGÌî×чó´:áΜ§‰H[ßû®êjå…Â6žREò#m¬ù•Þþ[ȯ«•` ª†ûˆ¦ÇñÅ–°‡y©nèúâQ;ZÎ+ºÇsžêv€ó”GaaœgÔp9cµviïŠ}Z¶8WÅ‘õ¢Ý(–.Ö‡TY!«E­~ó׿šlÿz&ÚEî8!–÷øDï÷rãÓ,Â+ò{I#CÍzUò(gïƒ Ðƒ2ËaæÔè'ü2|WßU &c2&­Tš5?j~œTiR¥I•²×d¯É^“º-u[ê6ÿ&þMü›|5uÖÐ*“|Mh~#y-ħk…Vh…c8†c²Á²Á²ÁkBÖ„¬ 93þÌø3ã{¼ëñ®Ç;é)ÚPj#R+~ RjBMħ0-0-0-H¾—|/ùÞá&‡›n¢5DkˆÖ‰Kg Æ`ŒBœ>L‚;jRî–…I%$ùtk­ÂùÔ?ðÒÉËìH…¯O›!’HÝÆ;ÄýÔ#&@€À*²Š¬¢ÈkWÉ®’]¥D¯D¯D¯ý}÷÷Ýß×8×8×8ë±ë©)5¥7p„Є…ÓQ)l’\]Û̼¤yÊΰ¼ 3%²ÙþúS—µ«Î´h>£à‹«ØŒ2¾y›´Ì¡ŽD„Ò òu0«æµJ[{ø»/´óϺ´âpU%g®…èržÞ‘óÔ¥a™œ§÷ Ï»2hó„þ-&6[ßÄp‡î3uǯ^àvŠ–S*uE†T¥,¥cúÿJ—\ ËefTO,×uµO7œöÖêÈóÁáE~ Uƒ“9O?á\»Ó™êw¤öª4w¿ÈÌ?¿Ñ•W¿Ê#cõežA?ØÁú_ª~–@Û.hŠÊìs%/hÂV3¢ü÷6\Ìyúш %ÏÞ‡˜Ý­°s‘o«Š¯MÛ—“Ò$Q,5-Sdÿä‘ûR‡êïäÎ,&°­´@¾a“îÕ[š¾<5ím‹ƒNÍ nÈyÊþ°œ§¬ëÌyòÛÐü¤ö‹ªt™ÚܳÖ ¨C 2Y+VÖÃ:Ð<”ÝûhóΧ­öÝÌùdíͯ×÷žËbÈ ïp Ð ­P ¦?éˆYÀHA RÄŠ€ë×®Ÿµ?kÖ~‚0A˜ M{jFͨÙWËÙ V‘VC²ˆ[µ3j¥­výà– ýS9ÏÚ™šÿnul¯ªú/uæ«’#‘:!í+«ö~jxÁŸ- hùžÕΩŒ‘¼ªc€s‡Ô¬¥‘ÝfqžärŽóÔÙaœ§L «ÏyÚð±çcâû6:gÔj©ÛAÝê«¥° )aëDI¤‚†pB™+ËïW©0€gºevÄÁï:Nwöç<­Ox­â.§ú×ýhprÊ0íF‰U-MjJ©°–Ô®l˜þ!Ðø—òÇv0%’¶1*Ÿ”ŽÕñ²W2LT PR$oWv“¹’3BÐ e¡ÕßÚ¹ÁŸ¹óaË")”³µ]½ –7?ÕOryöùRü©aùœ§‡mîÔÛuV%é$e3S*;£ø«Ã‘奴ªÂ˜õ£LR'5œÅHù†mšºXYMKv_\·«=ç©%aï8OæÌyªEØ\ÎCºìÕ˜RÎkPÓí52Ì¿ºgV¶á-ëC¤.U‰j·:T $k.Ô')~cÊ|ßì»8ÏX1—óŒ•+g¸„6”¶¬d‰Ë[˜ãÛ ûSà·  UH:)Ò(MžJ¡ý¶öÛÚo;>éø¤ã“ò·äoÉß²`æ‚™ f28d ­ê‚¡`(~ýaøG]hdA&}x;¢#:ê´Õi«Óvûýí÷·ßÏ1 c@‹ A-$V=*¢"*ú‡ß‚µ¦ÖÔ•Q•ûNé;¥ï”ü¢ü¢ü¢Èã‘Ç#K-;¢#:Jl? üœ©2mš XL©÷ÔÆœOí=ðç“–÷rûH¸i—ÚoU6+¥J<@$ºÿ|Ãdèƒ>e “Õ—¨/Q_²»Êî*»«d¦f¦f¦Ö|\óqÍÇ8Š£8*훼€Ô_@úTw†ìT,•FíŽÏñónÎ_g‰¬ÿ©ñÉqCy½qUžy‹¶mÁ‚õ¤>øŒ*ÓÊQš|oågh+©: ÛÝÙ¸úáóÑ1]úâ<5*,Žó´áU8OŸÁ8O1ίˆÑí3!À½ÝܪÊ{j婚µöd3i4öa*¼$¾Ùÿ`ûÕîAhªŒh2nA ¦b£Çlõ’ó´”ðÙœ§Ô Óɳ\“ÙkzyG­•4MØL»Èã+»ìߥ¾Ëù[³>”AÒ‡Ù¦ŠÁ9zAu{µ ‹˜4Ô2ßÿQÿl£·•L­«KI³™'=Anc|¾Èÿn+Oø8€Ô± QÖ/týÔë_½Ñ­ïΓG†.䯶.Œš¶æî¨ ;²“Lê*Ü)¿KÈÛ›G`F0#fČĊ†– -Zî_¾ùþå~~~«õWë¯Ö¯èTÑ©¢¤> Ž‚£àˆj¨†jrsíŸ[7š¢)šR>åS>Üáw?W?W?× ×.\»pm®É\“¹&t‘.ÒEr$GrŸúŸ5´ÑPJRTá¤ÈI‘“"Ï­8·âÜ ï¡ÞC½‡BºÐ¥Ù4›f;î= üÍ2ÂXÊ o±böÖ¯ê4âÅÑ…>k¹Ú$½þÓ‰Z×Ý´bnyS­uPƒZ‹Ó_|:207æÆÜ 5¨µyØæa›‡Ùg²ÏdŸY–³,gYŽŠ®Š®J™)éHÿ)¥ ,¡+k(Ô&‰8o~ƒ!]?sž™YŸól§(½Þ×<>Ø'°Yô„Ì…+ì”ï@¸Ž†Z‹ac:ͬ>ðrú¦uýŽsžV5¼&ç)ËÃêqžò&,‚ó´ áJÉ1K‚ºî °õÚ]µ™ª±2zÈ÷#lfñ´ˆ‘'$¯ú?Í*§ˆÐ)ê€$GØ¥ÿ@g¶Úá³1ëöô^X:$¥X%Î3nGœZÛh¸µ‡•$3ît5P_æÝ_õYøE¿BmTÆc>ß P3=7zmJÏuIÓõê~[ñèÃÀàä kì=«íŸ}Ó]+t±÷ÕZ›¿êA“µ§.p€ôþäQý‡V< £Ñuéá ³§ëdºc×ÄŠžZœ§- Êyʦ°F9ÂJ¥ËÊÇk»«ve†´÷h35Á±oâYä· Ó1 …lvƒ¶Ë7QÚ,«ÅBC{vWcÍ%ڜؿ/çéÉÄyRfh}ÎÓÂO¼ÝtdÖàÞsW Žvlkf6Bç+úYº°’™03Z‰gW6N¯ø†óÔþa{yn&"Î2+«£L¥œ’¯`AÃÈ[PŠ„¯3+ðAÞØ40@PÔ5±Âqšã4ÇiÛ¶mÛ¶m[Þ§¼OyŸöOÝ?uÿÔz•ëU®'¹ZQoêM½ñPæÔ!2¦ÿC`CÙP&©Â•c+ÇVŽ=\|¸øpqÂÔ„© S«ï¯¾¿ú~‘ž¥±4–ö¼ì`‡T¤"•ªRUªºQØ(lÎ):STÓ¢¦EM é‰f³Ùl¶"[êO A›æ‘Dê7rœ+U=ÆùäyV–Ö¸¹çÅ#¯÷œV{ˆÉö e‰…ë“5.ÿD$Ú üáÜÅ]ÜÅ+¼Â«9qsâæÄ]vqØÅaÝ'vŸØ}¢Ô¼%kÉZþx¬íÿ²š‚EUØ ‚_hÛINMJÓ‡ŒáG3ÆG,˜})¨Cã¯RÆTªmZ«Ü‹Eƒ›¸¿˜´¹a¿gœ§õ ÀyêÁ°Çœ§ ŸWêœh”´xaj—^û4™_é³ú•²ŽòýÐ @dõ¯ ³/ô£‹œúÎ0­2n ‡ñF_M?š58§dΩÔàᜧÎ{èÓ¯µ•C§õæLn’{Æ_a,£T‡2Ô AvH˜Ãʉ´›kÞS§$¯Êê螦œ“¶aÁ´—õ#§Üʶ·*Xï8“¶¥u—œçtÙeåªÈþîƒÊwÓê¨"½5a;NK0 ~¨_öÊ¿C¼(Ђ[H’=âX·5‹9ÏPŠð(ÉO˜|ó¹Ç¡MG«kW2®%]*£hÜø¥$|ÿ€?Á~0uš…òML¦èÐ0Öµo׺ûŸúìï0óôÎáç8OšªÊyæíH÷{-w·ñ0îe­z[õÊk‡¨†É÷°[;Zæ9¨83µVh«ÒÕÉE!ÙQígT“Ô5á{KǞ¥\$|HIJÌd¡g¡g¡·jÚªi«¦åëäëä뜨w¢Þ‰Úr:ät¸öU7ƒØ 2·Ò_‘Õ¿c^DÊ,~—ŸážMx=áõ„×Ü/¸_pʈʈÊÀ&lÂ&¼Å[¼ÅP ÅÐ`7¢Fe®˜Æ‘ƑƑW\ypåᛇo¾iÙײ¯e_hA Z_yº+ð“ÎÐ9ä…÷byàÇZ¨|WœdÐZñ“ Ÿú%|2®jŸ9žö¶¾fRòAƒæRåŸn”âY<‹‡ l`ã`ï`ï`?+~Vü¬š4hZØ[Ø[ØÃÎpSIÿLC1cZRFÔX³EåwFÏx1hï–n¾ì´íšc½"œ^X?Ö[8G;èk¥×ºqƒT8O7ßÇyêãpÎ37EVÿþظ!î‡Ì<ÖaZ[õúQÖ½ÙFTUþeZ‚¥#]Q]ªRùÝÄvÿ;ä©“˜ÕËaã»,¬1ŠótÍð˜’f •‚cŸ¬ˆ«˜ï|¾R¥ W¤öy̚ʉþ,åïÞól/S!ÉϾ–jåÎ7R¶åù¬ã<Å'ÌóÔraûž·9xqP=ÏA £,bæóà×pžv.|DIóÄ!ë8O»>óœÞ†Š}u›¤´ƒ«Œ·¬X¼zÂÙ~[‹6OèܯIé©Iý§÷®Ñ¨RW±P@¯)ø' w¸Ã"(‚"Ä ¿§~Oýž^t¿è~Ñ}‚Ò¥ eÌ7é&Ý”<Ï~¶Ø< †+<á;•òJM‹Ûý¶+ $Î3\"]ŠOÆ_ V{kuxÉàÝœgØDØqžR+̈óÔag‹ÆO³aå˜Ñ­:6Ó«ñÞìʯHi«@µÉŸÊRÀH Êß?Êò¬ §0Ù#V“<„LÑâ]n“¦µ•qžnÏk¦Õ¯–±{YT·8­Sêó•J™ -ÁSRG&$YúŸÔw%9›· ªÀH8ÂΔ}œšZÕ¨fõ`óÞ"ÿ[¥3’¶†Vå<åiX१±~ººlsØn,ª²jT›íP­Úúg­ÆÚqžÒ=Ìšó”ea Þu8>aÈõzî¨}“ΠþÒeËh*zÃv_½‘o ò#|³ÑЕ4©]Tš™»lmwK®œü.ôçéG"¬våNÚÐVSEUÉKÐ"ØšNq 㿳ù§V†:CýKwhÎË7¬›TÅÛ°(æè¨š-+ð gCt8OYº–ótŠŠ*Ü7½·÷Ö:‹U«WÞ_…YÝðà 1gë¿›í7ª–ÃLiB8’Ò—¨'…âþ€é1=&9Î)ÏVž­<;¸zpõa72fdÌÈòZ–¶,-´u«­­¶ê·­åYËS%Mh%´¢QÒÅF0ú¹þˆ*x]ÔE]‘ Nè%ôz- Y²,$/9/9/Ùç•Ï+Ÿ2¶¨4€üýò,l¶[à Oxvm×µ]×vö]Øwaßø¡ã‡Ž/Ë¥S‡êP¤ (€”ܸau }ƒÉŸfoÒwx‘êY?çS*ø q­ïîÐWš}XÚòS,Îâ¤-A JÄŠr-ʵ(×bÇÃwXwJ#UT€tmú™h•kugÛ®¡¾KcÇ„ ã<ãpĦù¹Cê»J*5;Át¨ª¡ââÅÿòjYÚ¡ªp½¤£b…g±ËM«/oƵ Ìå<©4Ô‹óT¯°UÊmTí›h;Ì¬ŽŽä…ÌÞ²ÖäJ¡dùbMÕu6úT’ƒ7éRÄyfßHÕ’´D¥:œ§w q`á åö¬_÷Õž+õ°™©PuÂt´—îçÛTßOc-zØ\Š&m$"|Ù€ÐÑM÷qžááÇyrrè©+*[Lúg>-_Q}†ô’§’-¶ÿò‡ëXí©>ÊA¤ TXÇNÐ"ù†Ubª—>skûœg„ŒJKٷٻéÖƒWöqytgS\uýÚ{õºFE {¤gŠ}˜ŽNI1WAþøS@ž>R—tI‰H,‹)ò)çSÎ'(|~øü:§’'Žo3b׈]UQõ¸À…•GUT…Ú?pçÚІ¶¬F©ØF©*ÛHï~¢ñ÷ß>ðO Û¶-lsòsòsòצ¬MY›¢¤¤$QJI¼ªßf"è¿¢÷ðfÄ Ãу¶´Ukboš¿Ãî¹FÉœgiŽP¾vðh›æË|CÖ5¯îØÖZ§ü‘¯zh8#ÙzІ?¼Ê6ß´¥SîÞkQÆ¿ëÝ8±’fÉΤf!ŸŠgÆOv hoR|hÓÎgܨò©=X+ò†´¡*ù½ÿ¨B¹LºHI9Ô£, ºÇT÷*¶™ï¼Žïò¤T+¡Bð&ÎÓk†ŸÎm¹ªnÏޖꆖZ’J*[+L`eKÿ D ¹0ŽÅ’¤Žk¼U“)M;á¿¥áüÏùñÇ-å¾IËBu9OwO½ÛtWmßå]'»½¨ò•1¤Ôº>R‘ŠÔ‚4ýÏ *ð·B J_«š±f¬j ê›W1¯báçÓß§¿MÅ¥³—ÎŽ, êÔßþ4ÅP ú™Â NeÔ“?¤¤Q:ÐNùàòÁ僷ôÙÒgKŸì^Ù½²{µmÚ¶i[)ïŠPN('”û›në!BŠPª§TO©Þ¼'óžÌ{’ãŸãŸãßüXóc͉Kì:»Î®+P`¼á*uSÔô”Sßî“Õ{ý§Yã›ö ã|–R@ÕÅC<¸Ô@u¡¼’[M/`núýå÷Ù¢ ~ —Ê2ÎW™¯2_åìü³óÏÎïü¡ó‡ÎRjbêD¨ô¡ÿ‡m¨?Öa-DZÆîå]uçÉÏyÆÔˆAÅÓ“j†²ì#Öc=ÖµÚÙjgë#{<÷x®®5!`BÀ€ÖöÖöêWɈŒ Œ§xŠcЀÆ?¸™7…)LÙt6M+üMüMüM.Ü»pï½–3,gXÊRd)²)P5yÈû«oŠVÒJZ)êF0‚v²l';nÜþ¸½í<Ûy¶’ƒ(í¥½´WᦀÚe^ª*áBË}˜µ¯»VÑš û5å|ú3¿U±õº´mâ+‰Î ÜÁF¬@û/iÒPÐeºL—á/xU®\9øXб cA‡;v4_`¾À|H ɈSL$ñ õÿò«Ä<ÐBèÊ6Ro¦E«¾$r/óVÿÞŸ] ‚˜‡’M ;T¾\S¥ÊùÉQ‹ëwíÁyJIX8ç©gžñ¹ªÃ2ášP޲hY#SáÿÅÞùËEY^ ]Fµ°Ÿ¢ÈÛàG8D¥õèU»3ç©óÂUЇZìÍyz^„Õ¦¦c¶ Uï¦ ‹”Æß€K}þ2œWž^° &ôesh²XaÝÇ(K{éŽ^¯zÎâ<µ|Xhi“Ä•!“9OQ?uÜÒ–Ýzתl«§/me1CМ2¨Ç— µÒMüÅoZ®oRE"ÙzJæjãUjÈ[;ëIljœ§ú…%pžÖ)¼åÉ7óëuJW[ 2RVò¨?r¨31,ùéf®ÄEÆEÆE¦|Lù˜ò±ª[U·ªn¢O<³d–ÌRþ„á¯ëÇú±~âÊ_eN•9Uædºeºeºí°Üa¹ÃRµ¹jsÕæOèÀ£€莪°…F(fê46çÞ q^ƒyÅI:ýçð’© ?9ß׃˦±F$¹7!æ 臘À„%²D&yïùó;æwìâÛ‹o/¾¨2Qe¢ŠpP8(¤Ctˆa:¦cºB”ä „Nh,¹»ô'U4$qsÈÐõ¿Øbe~Ëœÿ= ¤ÒË•e¦Kt:<š³¯k@çRßÄ€œ§G„ç<Ü+¾Ž”ÞHpdþ4ÍP_õ©Í2÷Ö‡2è+¿ÆéKº7|ÈyÚùðCÅâ;[ÆyFˆ.ËÇ„6Ûªl c’*¨°Ö$—K–ûß²ØÈ;&µB]XZ¬-u‘oV¹k•š¶oøÑ9ƒrž|;´€óÇ0•WGŸ ~5­Ç¬Úöh*×% ŒÑÕ¾d\þëèEOîÙ WVÌ‘§X=å˜oiƒýœgtˆèÏÕŠCì Mw{úµªh`Ò®ÜpiM‹£6_2üœ)„ä¥B@pQœªëÊ-Zã·FmÓЋ½/ö¾‘=´dhÉÐÃ’|ª15¦_øÂ÷N»£ÀßÑ€Èbe±²Ø™ófΛ¹âìÖ³[Ïïþ¤û“n™¸û€°XX,Ìüûû!/™pÄâD݉ºuOß<}óôÍ‘GG)Å a.æb®”1ý¯°skBšÒÜÑ„&4›oh¾¡ù†swÏÝ=ww~àüÀùÒ°™“9™ÿ¤Ž¸ ü ZÃfR9}àz¸^Ÿíõ9Ÿì3`6/žbç“’:ßww›OÚ³Tz+ÅB à ÌùQ‡„‚(ˆ‚à W¸jÐþ ýaýËõ/׿ÌÒÈÒÈÒhbßľ‰½´È)÷ |ÑúîG¨J~–°üRó£õÉ“EªÓLÜË].¹]¯üª´]ÒŠP¥b„¶Áù;¸8ôP³Ìššæ’{Ëe¦Ô@Ú(ÿ«:Bm‘ –•Z E¬ÉÊØÈAÍësžî~ø³ù©èজ§/?íÿᆅ(ÂH ÜäŒ{ØÊÿ —ñíÈ[úÃÉ›h0”²×-©bc¸,×uUËž&œg ‰YZ#qkÈlÎÓö†/Üž=i£çS£´ò5Ô¥ -[AET9X‰ÿõýüÈõÆêÓž²€rÏ—õ»Z·.~“˜’ò¹qBëà%·’ìBÑaP£¥[Lo¿Pܪü+Šà'…&4¿¼—븒͕Í`RT­öµ¼j J•8êTF¼A¼A¼}eûÊöeÉwD[濤HqùÂfÑ,š%– ¦L7˜¾µxkñÖâS'N8u¢¦vMíšÚ’bjÁ,˜Å7tëäK¾ä‹«¸Š«Îsç:ÏMóMóMó=úüèó£Ï³³³ÅTÈ@2þ»» l`ƒ$”­ð§Ïž>{úìÐÆCmŒÆhŒÆÔ“zRO…Ô)PWXÁ QfÛÛ|°ó×Mü}ôZŸ`Î'7às>cÈ«LZhuW{%.Åtpä h@ƒ1Æw×A®ƒ\å¿Ë—ÿnmÓµM×6U¾®|]ù:ò‘|ôAôQìƒø ZP‡bš WØ#Ú%V/î|©©ç­"Z—ŒKZj|iì¦ýN$èÖT·'Àš¢È›ÄöÂ(¶ž¦‰åò#µ«dìíýÎˈóôe៊3dÁ«‹&> 91ôE'µê’3la=ZFµp@ªÑþØÇÅOÛ1m…uì(-+t-5¯©ÌYU)r`ójœ'ݵ-=—¨âÈy†FD›+Ûb× ˜ÚN·ÁFù.Ù:KZ_ýÊÿÂ$Ÿ×Öï1]Ðv¯t#Ô\[²Å´ÿ^®‘x#d;ç–m—U Óhf.]êÇæÓhœÄ}x- $+‘•ÈJððЊû 6ˆ bƒPåPÎ~“ý&ûMŽŽŽ{Tö¨ìQÑY©³Rg¥Ôô&nâæ7$âìÅ^ìEuTGueeeƒn ܸ<,xXð0À;À;@Ê(ÏV³ÕlõW×þY¨/1îÀE\ÄÅ™ÕfV›Y-Ï9Ï9ϹuRë¤ÖIÒ϶¥¶ÔV1§(ƒ3ŒP ˆ"3ôÜó­êöâ|ªúÀRç‰cûW¹ó8¼´ËõJåÇiÍ—DÙªàê8UQU%ÎWÀ”óSÎO9_p¡àBÁ¿M~›ü$¥ŠÂ)œÂâ£À¯@nq¥ë4DX¯ù@-_iWÞ¤ÕÎ=/ñœ”’°Éœg¬Ž˜¶ýá„‘mÊ(cÈÇ7ARà©ñ;=- £Äí Ó»4ä<½oø-Η„LùwbïÐuýÃ[U«"eôdö´/Ié_xâÿ,Ny×%È 0ešŽ»òMº¨»¡Ò•û w…ûærž®¾‹ßLÖ íT|616dãÜ[CF¹k˜©ʤCsYÁ–.£*¡‚Ô…òÿ`ƒÿ€c¢‡…[bEì¹qCZûsž~:†ó“Ð×ùçV{÷Ò(Gõ•£q sÑ…æ’ã¿[Å'ñ×%¹lSdAd!2`+++ï ß¾/<÷NîÜ;;9v*Ë àÊ\YYºÂmæÇƒ.t¡K;hí+ÚÅ´‹isî̹3çÎ,m¿´ýÒ2rØ÷x÷R §o :Ћe±L ^os½Íõ6×O·?Ýþtû˜Ä˜Ä˜DÝzºõtë‘d¡ÿsá OxІ?Y¡¬PV¸ëÙ®g»žeoÈÞ½¡òˆÊ#*fŸ7y“·Bô(CeèA›†à$Õaì€&''s>ÍË×ÿÓâñ^}'~¨6vzŸ 5-ç–—r(²,RæÅûƒ@´š_Á\A ´@ ³`³`³àNt8Ñ!>,>,>ÌÊÆÊÆÊF¤}$'r"§¿:lEïò®& Ô ib¹ÎAû•†ßN?ê9øpqýSã‚[sžÖ>¼êÐyÞœ[Êw`ÞË ¢æÐ¬Y«&õ¬ÆyÚºð‘%•Cj½èyİI'×u•üÄ–2´(áè†ZÒÅÊ™ý¸4¾p9;á¦0{Z…bu‰ñîrú—O/h¿”ó´ÕáƒKŽ%Ä¿å<#&bbzÈò&ÝGW[i\ÁYêá ùã"ó²s ¿Ç/ÚÈ«Â6F‹Õ~“ÚF:ã<µ(Üôsñ©SÁƒßw<ѨOÁ^ßPJD{¨%N~Õ¿Q}·‚¬XÖu«;ºwtïèž«›«›«»GsæM³f ̈tôÒCÅàý€¨…Z¨%1MÂ$Lš 6Am‚Z¾r¾r¾rá!ÍÑÍÿe÷Ïí@ ¤@ÑaFç’Î%Kªo¨¾¡z~~~ë.­»´–"|Ø<6ÍÕý?íçoà$³‹y}óúæõ,,,Þ8xãàò]Ëw-ßUg2$C2TˆžeЇÔX3²ƒ”±Ò¿FmÛsœOßîô.blÕÞ9Ÿº|à5×É–— ׈m„v´‡Ü~³*±‰l"›(–}ý|ý|ýÎ<=óôÌÓq]ÇuוE²H)y¤MÄDLTˆÿrl-,›™“Ä3D«cgOÎSW…=* Mȱ}›bMÈźFv×Ì‚«»Û<5Úu;h»µßÎS߇7-]x7d]añ>}ÿB·ýÕÇ™IÔ™,Œ®‘ú¢¤¸‹¿‰ù^ÞC}‚àÊ2™YÙÓ —Xm~£çÜÚ—ßgײ‰ó”¶aúœ'Ÿ=ÿpÚßAMüN´åN£ä»^°b:GXCï?<‹<Ÿ}.õA–XvJ²QÓ;ýÔö Ã Ø¢S ½‚Ó9OÝö*âD·¤ZR ªÐES$:Á•¿rRà÷à^á³a6ÌFí†Ú µ‹"E.Š<r.ä\ÈØJc+­ÄdLÆdôŽÞÑ; Çp ‡*T`úàŸ ð€‡4›…@!p³ãfÇÍŽ9åsÊç”o5­Õ´VÓ¤„Gß²ƒ‡üwß›y3Éž=èà ƒƒ´+hWÐnñ©Å§ŸR1R1R1‚#áˆã8ŽãÂ100ÚI;i§Xáèè˜QœQœQ¼H‘þ"}•í*ÛUÊÀ‰¿«€Ô ƒŒqšNÅŠNG–Zîàé3Ûùo~Ó|ŒvïòC)üíÃĸ}1ÜàÓzGFÛ5åZ?z:ë舦œ§\ ]\˜¿ÇÓïu_Ç@£BI?²RŠG%˜@û˯üÝ2)þžÇ<-¤ê؇ xÃI¬i¤ZUÍøÕéÊk#{½åj‰<Ö”‘2™áF)Dò½ë2·™u´ŽÖ‰åZ#j¨5â;ÅN±4µ4µ45—F.\¤-EQEý²‡b>ËŸá ö$Nâ¤ø6ví4Úy¼åñ–Ç[¦_H¿~Áú¸õqëã’XTÜ¿eˆ®\×q×áø›l0Ù`²áˆöí#ÚÏ2že<«±¸Æâ‹E«< ¤4ðÏÊWÀv³Ýl7œá gŸ>-|Zœk{®í¹¶a‰a‰a‰h‹¶h‹»¸‹»R˜¬ ÈCL§Ê&XSeëšFë8Ÿ¾ÖoÀÛ)cööžÍùŒr~q|j¯,‘³0rÅ”‡Ú-Oäb/`¬@ÌÿçvÓí¦Ûͧ§§M‰›7%êvÕíªÛÛ±Û©;u§î ™Qà¿€¼ÒB†Ø€e˜J¦Ñêh½Lê³,ÖÓn®÷ìš•‡ÄÌZw¦ÏÖ]Å댗}¢ü•…ÊBeÅ’£À¯MÅrűl¿¸Â±r-y×è^»xÏ„œ~8Ÿ8ðÈŒ¤õjGHÊÇŒG/8Áºßû³SSjJR¼¥£¥cåé‡ÒåïKx—ð.ýykóÖæs€$â>¡XÁ“ Àÿ‘œñ&nšú I*ÛTã˜|}BN7>ÓéþÆ9wÇyží»¬×í·ú¯ŒÖ³N¬'%áàl¤ÄLßþ¶Qj_Èq“…¶l8ˆ5• M t<ãýç—ï”Äyæ¦ÈªÅOOu ¶ã<Ý5üæq‡ùâí–›¯×­*õàM³+Ì–¤ôN†ÕuCÔ=o×Þ®é“Áy’FÈ)Î3FFÌ›Ó/¨‹k=ieËe©Ž`&:Êoœø ƒ 2¶“íd’Ÿn;“v&íL²Ã²Ã²Ãö¿Ûÿnÿ;+5+5+5ÌÄL̤=´‡öH&ï×ð!ºI8êÈA¢Ùp6‚å ËJÓ:uôë-¼Ñ ÑÃ1å~7>1–ÐZB娕›û|îó¹Ï¯$_I¾’ÜiN§9¤ì.Bu¡ºPzÐû¯òí£…(Ä<Áååå’ÙI³“f']м yA3àdÀÉ)œcãØ8)›é è1=¦Çb…¥—¥—¥×þÍû7ïß|`É%–X-°Z`%QîÒ+zE¯†B~M–ŠIÀ)±l¶Y;F}ï¥Òaq_ò“’ò·SL}2×u°l(|£Ì ˜Cÿ»øBb>Œ`£¶m#*­œyoæ½®!#gœÕv)m£m(³kZÁ šŠ)¤ÀŸ€›¸)ÎrЋÕk/l·pÞ‡ë®{ÐûeÀ ÿú6fƒuU_l’cRYö €ðaý=©¼ î=Ñ=á O,–U’U’UªT!ˆÇUë_­_‹§}Ÿö½QC1]àGz hà³x4¬2þ ÄEߟüÉQˆâZÕ2ªY5SózͳÑÓ^E½v3{¶ì¦7[îÔØ^óó”ÂàB»â¦à8j£¾·Ïág¡DR™·á$.•V/½ÉSh9ÕÆ¡w‡>,z;)-§å´œžÆ={ç~ÇýŽûî ܸsWîÊ]©õ Rª¦ïëô²¥(Å ÌÀ TGuìU©§ROö‡GîU‘‡<µ¢ãcýÐâ×ů‹¥dU(BѰaäààÔŽÚQ;‘Ñ<É<É<Él±Ùb³Åw¯Ü½r÷Ê­g·žÝz†[¸…[|)_Ê—~gF.JÖ—¬/YP„"ôä瓟O~¾ªtU骒½—½—½W½õ:Ôë€b£XºJºÿ•ßH(Ù ­Ð v°ƒ‰`"˜:ž:ž:ž…*…*…*Ÿ+|®ð¹ëËú²¾¨†j¨¦Xl~ü÷Ká¤ã"Þ£Åo3?'ù¼ ø¨òÙŸØk ƒ#àŒ+hMU.[Ær©›4u¡ö‡32~ ؃=؃c8†Å)Å)Å)TŸê—L½x70u3QÐçD:NÇ¡‹s8ÇŸC€  SàÄ¿}KÌÄLdº™º™ºéé U“Oûv¹¢0½p*×yÔèÑüâ"žÊ~±¸ÜÅÝ/Œï ¢ÊüQ$²ÐðA<žT1¹Ò~”îm“bx}F£cCŽlWÙ¾áhå‹{ÑBæD.¨YrrÝ<é`Ì“°@³”:£îâÍŽ‡Ægä—¿ï}eoäñ¥–)±ç×ݪú,SØÀ’h9_ÅßÀ_"|,F J¢÷§¿S.úówüÇ옳;?úüèó£wDíˆÚ¥ÝZ»µv뀼€¼€<ÝÛº·uo‹Š-£e´LR…¿}ˆ 1 ð{Å^ÁÆpö²ö²nãÜeB— ýsŸ›?7ç9;pv ¯ëí·gW‚/|áËËñrØðÝ¿kMhB“úR_ê‹—x‰—ÆmŒÛ·ÑSÖSÖS~ÒâI‹'-žë>×}®Kµ©6Õæ*\…«|—F®®èŠ®ôš^ÓëwªïTß©ž¸uâÖ‰[ÅÅÅí£ÚGµ¢[t‹nñÀ$‡™ßÏ3ÓíѾ$´$´$çp笖Y-³Zö¹ÿçþŸûßlw³ÝÍvðƒü$¾üû¸ûŠÅægÀ­¸óHE-F.–|z[\Zï©ù»{ý Â²]%ÍKwsA/C}§Š+í¥{´CšŽÊ߹Ϩhõ©Úè$N¼}»÷í¾e5"jĴܽÅ{‹¯æx#œXá:®ã£B¼øƒYNáNñwü®sWç®Î]'o'oÇMoýßú½¸•›u:Y HÀZ¡¹Ðœ„ÌðHêáÇpöøˆÏ(†ŒçÁ#KÕødX³…ôŠ*Þ{øäÖÛµÝõ'jÆõ?çQ¼QñÚOÛ“}ÿÜå$Ãjåç«¿5ª¨m§Ovj–ºÂR­ÃÁ'no±9ÕãrG¶‹uÃÞ”&ðݸ‹Çxƒ÷øønu¾|Â'|ÂÀ¾œ/ç˱û±«óVç­Îç Ïž/¬1°ÆÀ»Íè6£Û ¾†¯ákDEPLu÷?±sü=(E)Ji$¤‘¥SK§–N5k:×tnO‹ž=ú+/P^ Uûžú=u“¹¥¹¥xxåΕ;Ÿ p7qåQ—¿û·ìø”x•x•x‰ª§Ãg‡ÏŸK”,(Yp-ûZöµìÒ+¥WJ¯Ð1:FÇ00á;{Fq›!ªàÉHF²HÔçççòÄã‰Çûöì?4ß`|ƒñb€)M£i4í+ü¿GwtGw¸Â®ÊEÊEÊEV­¬ZYµzçúÎõë ×®7\± «°Š—ãåx9…k®¿ú0‡¾ÌƒÕ ubʘ•Ùí®5XÀùÌcþï>Ý?¤ï¢7æ£Kz«h QNWÒ®š/™¿oüâ³Á6ý¢Í÷æ‘©À·)jµ„ZB-TGuT÷¨èQÑ£bÖÔ¬©YSWW[]mu5í"í"í"ÔAÔ¡†Ôþƒ"—»”6Sc¥*x€™bMÃzU’Íìg;ÊvBñ±”±ƒÞrž¿9úêm~>Ègc¯ö=>kK\OlšÐ¡uÀPIà‘ù‹Åú_Ê7=¥§ôT,·ŠnÝ*:C+C+CëøÊã+¯¬¢_E¿Š>,a KêFݨ›Ô÷é6#ÞU=ÔC=H 91'æ==zzôôÓ7Nß8ý|á…FHÍ'° ØÍT™*Ò¥Ô¡þ„DŸÅYÉ€uSuSuÓU^«¼Vy¥/L_˜¾Ðí€Û·¢w»‚ü½S8"xƒ7x#ºµD>‰|ùä¢ì¢ì¢lšÍ4›i64œ†ÓpzFÏè™´ýOMz¤GzbŒ‡n®n®nîÖZh°9asÂf‹;w,îHMÅ`Y~ü÷&wñ„ªb)…‚£üù™÷?9á1wAÒpÙ FúzÍÔoª”…¨†£aYš•ïz´J¤I¥Iš¨N­¨Ué2r$GÔ…&4¥ñü Øù*ð?ÁîpçœsÎQ€8¿u~ëüV·¢nEÝŠy1y1y1¯•^+½Vb{ض‡ßáwøŸbd>¡%¢É€÷âÉhÉ!é² ²²KÍ¼ØøÞ¥Ã–Y67®.9šWphó‚í#3í»>]é¼/¶X¥võâ·XÛÆ í±­$7¡Â÷B@©P É Íðï?ëÄ·Š” D ¶ã-yKÞ’ È€ Žn=ºõèÖSýNõ;ÕÏ`–Á,ƒY>j>j>jð„'®ú¸êcóåÞ˽—K <—çÒºÒ¥Q_êá=ÞÿnZRd‚*T¡ªÕA«ƒVëWÖ¯¬_}hþ¡ù‡æ7¼nxÝð:¸3wæÎßÔoa–aËfÙ,[LÏtrÝÉu'×=ªô¨Ò£J5§ÕœVsš]W»®v]¹×ãz¬kÅZý®§n‚&h"žöë Ö¬7ØHÓHÓHóÅÄ_L,ô-ô-ô•¶Á¢ÃŒ? ظ‚@Ü øN|D1J^~¨ûy J"KºÓkŒE_¡€†Ryý»‹TŸK“y,š úw?ZrS¿åoQÀð#Håçùydá-Þ~ù»"¸MÿÔšZSëÒ¼Ò¼Ò<ÝÝÝ’‹j,ª±èqÆãŒÇgûíw¶º¡ºá ÎàŒ”3ïçÁ|B±´=n‡Q8PSJ¼í£z((íû©™ÒѬú…ÂÙš‡Òo›œÒªRïѬ3?º·¤òðq«ˆ}üÄ<+¼Å'ç”%[€æ¨’/ªbþç£E(7¥H@ø9~ŽŸ[«¼Vy­òã…>^ØH»‘v#íæBs¡¹Àçò¹|.»Ì.³2g’oÇ1@tÉ¢,Ê*õ.õ.õ6õ5õ5õõyçóÎçR¤R¤RäF“&M.](ºPÄô™>ÓçÏø3þLR¼¾wåUv°ƒ¸=³õ±õ±õÑÙ£³GgÏÃ÷ß?|_X½°zauéí‡! aßýóTšVšVš†K¸„KùŸó?çÎwÌwÌw´Ì²Ì²ÌrmèÚе!F`F`*¦bª¤”ÿ{ˆ[\VI«’V%-á¤pR8ymüµñׯm-ÚZ´UjóÏñ\±¨(ð dÐs’Ò%ô[R=«•ΙXÒß¿ˆO˜Ôo`Ñ´ ný´Ñª¼ÚLÊ GoP‚xŸ) À€˜à£"«È*жÆzƒë ®78×"×"×"özìõØëjÕªÄ0 Ã0ŒÁŒQd ø X})yÀÿë?µ+u`Äa0qûÿ—31—c \Õž¤þï…¨|·Fk´fJL‰I£;ðêÀ«¯æ—Ë/—_n{Àö€íúÍô›é7“ßÑÚ@¾ ™©*Ç` ư@ÈÅtB#FŒ 8§tNéœÒ’%!KBÔ“Õ“Õ“Å[yÍÀ·)fKíL©³xf8°óÀÎ;ç¯Î_¿zxÅᇗq™{Á ^p„#¨ÐgúL¢½nãÚÆµkúôéöÙ{dï½gzÏôž¡:¡i“6i‹çN¿5/¨ u¡.¢óÕàyƒç žwzÒéI§' z<èñ ‰Ù±ˆEìä‰Wàgƒ CóÉN,{ÆÚ®2 ü°`\“>«KL&êõË/­>qUÿF}÷V”r7²AT㦀ÿâ¼k±V¬:n踡ãÎøŸñ?ã?öæØ›coŠõÒ²®€¹DS{°øŒhŽKè‚•Øœ%g˜ô¢N€à}oÀjð³5çuÍ&“û5EËŸÑêüð@}šú4õiëö¬Û³nÏ™þgúŸé¦¦V–¢K“4IStÆÉ%ÿ»•S¹äýïËËËR‘ŠTÄÅÅU-¬ZXUò?¦´‘6–‰Õ¹Ù&Wr%W±<«Â¬ ³*œ;qîĹÞ^Þ^Þ^¢=žæÑ<š‡ ¨€ ?Èc‹ªÑE~•ƒ*UЦ–\–ËrYÇŒŽ3¤Qò%_òýý#9ÏežË<—óuÎ×9_Çã¼Çyó’‰GÆdL&p+ À¿Gx#–¾²˜aðìUÂèÖ½V”¤L ê¯ÆùdÓaq ;ºHíïÓh2TŒ› ü&Dëct@±By®ò\å¹Ûõ·ëo×Ï6È6È6hTÔ¨¨Q¢hjOí©ýoÚløÿ£ @ž†½ùÿMt7À¤§°:Zÿ"—#r¨þ¢þäÃU=ȃ<Ärã“O6>™Ú>µ}jûSO <5°Æá‡k–Zn§í´½ìeþ3J0õ¢^ÔK´.ëééʼn;$ï}Þû¼÷›l>°¹Ôr2M–b(ð]¦”ú=H@D…R+C+C+cç‚ v.È É É ©Q§FuÄõŠ `Ø€pëRPA¢ÂôÕcTQg#ÎFœX1xÅàƒ•­”­”­ððmÑm…+i ¦`Š8’*L…©°íÊÛ•·+g¾É|“ùÆá¨ÃQ‡£R6b‘Á]Ÿ pÚð–<Ç %Èžj¿/øÔÿÓºb—GªNËŠ"jIïôN©oV‘Ò‰ÓÔƒƒâ㦀¿ ñxÔ…\ÈE$ùªž[=·z®ñã Æ¹?rä~~íùµç×Jî1™ÈD¦ä-ªÀ‚s"Ò°©@© ¨^ô€q`9x¿ 0SIDATÀJ' à€_™¸aÚ/׿ªb ÿD?]‘åÝ»q7¦Í´™vʸ”q)㎮8ºâèŠ Ê”+(÷oÚ¿iÿ¦*^*^*^b{¼À ¼ø[}ÄEuStÚ‰§xŠG?ôC?ÿ¶þmýÛ:Öu¬ëX7§ONŸœ>[nY¸e¡d7g«x­H.ü#At’1!2I?-}-}-}uêÕ=z=æzÌõ˜û÷ îˆë¯Ãëð:?”g¿1wé,ÌÂ,xÃÞ‰²DY¢ì¦ñMã›Æµj9Ôª•R+¥V aCæÅ¼˜—$ÿr +²"+q$-¼,¼,¼tè,ÐYp¯ó½Î÷:?O|žø Å/~øü©á§•%GKgÒ*ôEK(Ñ\r0°Ò0Qí %`X€Ö¨«ØT@ß„âÆˆY¬n°ºÁjÝkº×t¯euÈêÕá•ç+ÏWž˜Žé˜ÎƒxR ÛÀ'¹²p‘¶¶;'àl8„€mÛ ¼Œ› ¦^P,ÚìÛ­PæS¯iýcoå>a4Fc4¿Ëïò»"7KÌݘ»1wo.º¹èæ¢#Œh0¢ÅðÃ[ çíy{ÞžMgÓÙtXÃÖ¹WŽ=†ªQ5ªVZXZXZèâæâæâÖ®g»žíz¾6}múÚt“ß&¿M~>8|p -Ò"-~äØ\Ú"£Î2¶Œ-CUTEÕŠ£*Žª8JßIßIßé¦÷Mï›ÞOv?Ùýd·è±Ím¹-·ýǃƒó¼ïÀœ™3s~°ûÁî»ã_Æ¿ŒipÍàšÁµfg›mv–NÓi:Í=¸÷‚Vå@dA¢˜Å#‹GtÓuÓuÓïñ{üîûÜ÷¹¯È³Ä½¸÷R, ü>4ƒ5Œ ´e¶$CƵÊ! ;µç|r­ý9ŸfçëµgqµÍF‹ÍefÌ”æAJŠ|¢ (ðÿ :Ɉ‰9üáõMê›Ô7­z¹ê媗g›Ÿm~¶yK§–N-%BUÁKð¼þ‹ | ü>È;Òt‘{I7 p-l® g@ÖêÿwÃD¦ yBIEàðïû×?‘]¬î×¶_Û~msæ,ÌY¸?wîþ\³f;Ìv *¡Y’%Y~5›þŠ*b¦aš8®ÞA½ƒz‡µ×^\{1ÿSþ§üO#sGæŽÌ•. §p GMÔDÍ<|\ /îÅz±ÿkï¾ã¢¸ÖÿÎY–Þ;H•. н`¯¨±&kì-ÁÞ»ÆÞ5öÞ vE ˆRD•¦"(i»{~Ìæ^¼I¾77Wï/‘óöõò5޳Ãî™ÙáÌ™ç<Ï׊Yþ³ügùg¤e¤e¤MÔ˜¨1QCyí2™ˆLÐ Ñð ?‘Í©95‡´ åþ³ûÏî?ß|róÉÍ'·»Þîz»«S{§öNí1³1›Pj  z$ ¢QŽ(æ0‡yP¯ ^A½243434gŠfŠf*ƒjèizšžÊ3ñË÷Ÿ\ͲPËÂr¬æ˜ã=²™|É– Œ-¿üáÞšà–]/ÁFÐ#Wñ±]Є·Çýͤ™4S(áá{Ç÷Žï{®÷\ï¹^8záè…£¶Õ¶Õ¶ÕB %U¥ªT•·Øg"übºiÝ€Ï5úþsËð]Z]wþënTÚvÕYŧ´þg„tIHB’Ú0µajÃv¦íLÛ™öxÂã 'Ì[9o引†d+ÙJ¶BzÐûŒÕUÝáwÚŠ¶¢­„!çBÎ…œ‹?2þäÑУ¡GC ì ì ì”4u³Ç|ÙU-‹QŒbaQµ«jWÕ®6:mtz¸àႇ :úvôíè +XÁJ$IEÒ/ü¼nÒt¡ ]bBLˆ éKú’¾kÍÖš­5K|—ø.ñÝDƒ‰™A†0„ Ýt|‡ïðéGú‘~ÂÎï2¿Ëü.Oòžä=É:0t`¨À@´M´M´_$¸ÿ„„œÅ3„-t¡yåÔЇ1¶$2(ŽÉ–5™úpÎØÖ=§«»©ì­R^»|°3xãqÜGüáGâˆr¬.Ø5Ø5Ø5½Ez‹ô+ÍWš¯4Ö+‡íš£9šófû|t”¨xýë&.+`Kl﾿*…B¶Òë¬F_y8Ío«ÓÍ%©$•¤ ˾]}»úv½»õîÖ»[ïM¾7ùÞäV­Z(›t<OÇÿzŸêдUN6mÔ¶QÛFmoùÜò¹åõuÔ×Q_·ÛÔnS»MÊ-Òƒô 2 ÿóÝHüuW6É&ÙÂçµr±r±r ;v:ìtس°gaÏ,¯[^·¼®Ü²+éJºÖŸôµu³Ç4×|\óq151515çÎ9œsÐ:¬uXë0¼á oaæ’‚%l/=-=-=½Ëo—ß.¿ÈÌÈÌÈÌfWš]ivEù0ø€F;víØr¶œ-'nĸ}²î²Ðùþ?ãgvˆb‡T[¨¶Pm´/h_Ð>ccc›ëÙ׳¯gß«½W{¯–úSê/ľ+£ö5õð‹¢¨Åd1Y,$è4O6O6O¶êiÕÓªgQHQHQÈëM¯7½Þ„ ˜€ LÆdLöNKý5D±)l ›OxÂóQþ£üGùÉúÉúÉúÖÄšX“î:Ýuºë ñˆ§Y4‹fá0ã°Ð’ÅÅÅ–Û-·[n/\<¸xpvïìÞÙ½…Öc™,“e~±³&¸Ï‡\E&Ž Ëkgu>ÔXÁØRŸ‘Ö¬tñÁï³×L_Òÿ©sC åc}Büñ–·Ç) Ù„xŽp„£}ª}ª}êýö÷ÛßoCzCzCjqÕâªÅUè@:Ê.;/·ôÿ[@%¢ ôý?×ht€aipÆ&¬Í:ÐÈ; –áo!G =ûMd.™Kæ ËfÅfÅfÅgjÏÔž©{÷,îÙGC y¤Ür%YI”!4ÿÕ<:¯%ƒÉ`2XXÚdh“¡Mx8àá€óÎ8Àâ…Å ‹Ê-MˆÉ?ׇÑP˜À¤nhÇ€ÇxœTžTžT¾àõ‚× ^+£'éIêß4Js˜Ãœ£Çè1aE¿ð~áýÂS¬S¬S¬w­Ýµv×Zõ õ õ ü€ðƒhhhp…÷VõVõVMìŸØ?±ÿa£ÃF‡È÷ä{ò=nâ&n 7üÊÀýÇêvܧüÐl°kcKGŽl#/[4w„cAù÷ã{7n~Ó@çI ÈúÕÉû;b눭#¶ÆyÅyÅym[³mͶ5B¥=å¦Ñy‹ýEÔgà¢áÿº‰1€yßÀ¡èãó«ã? ÈÍ:«êÆÙ×wuKÝ 7È a¹Ïü>óûÌ;0vàÕŒ«W3”a3¤=iOÚ+÷ðŸÞèÖ Ôù@>²½ª½ª½jXlXlXlÌ«˜W1¯zæöÌ홫Üò¹D.)÷ ŒÓ×MÐM  h 5¨Y¦¾L}™ú£ÐG¡B{éôÒé¥#lCú>¤Oýt ÈrAˆz7|oøÞðý‰N':èÓ-¦[L·´m¡l•*+TVËïß¾KÞ•¼+y×’Ú%µK”iÉP2” å†úì“}…Þf—»Wh …[ÏÞjmTuS9ª;K}²ªr¦99…AhÇã”l`åãÔ¯ð¾jJ›Ò¦ÂìSzOïžÞ==D! Q¤ iCÚu%y³ýEÔÔYN¹Ps#tÈ'°d¬ÙÝr`ÿfðŒ¶X y¸„[áøýo • T¡ UVËj™ðïÚ0•0•0•èŠèŠè 3#3#3£‘#Fà[|‹o•…Ì®à ®üÇBçR(‘S€ˆ‚DA¢ ””›J›J›Êðêðêðê0µ0µ05CbH ëÌ:³ÎÊ=A2õ L`‚ø€âæâæâænjnjnjòxy¼<þÙÐgCŸ Å<Àåöõ!H¦.¢L]*£2*{gðÎàAä÷‘ßG~/M‘¦HSº‰»‰»‰UD*"‘l€l€l:£3:;4whîÐ\¶Y¶Y¶ùyÃç Ÿ7&ø*§óç®ÜŸ<'댸wJsp2¯f/—^¹¨êÝüÒa-Yø’>AÁ}ž¹\·Î¶Q1¥&d o7ŽSÉ„“p.d«piäÒȥѕ¤+IW’î¥ÞK½—Úðnû ïÂF0¢igÚ™7ÛßB)­B0ŒJÿݤc_8¸ <‹_MÛ'y€uuVñhxt,KÇ Ës<æx̹5øÖà[ƒ£G ŽÜþ‡ö?´ÿA¹eSÚ”6Ròý¡À•º£ûWÉU¢LÚË«—W/¯EŒ"Fqyäå‘—G:wî¨|¾B®“ëäú/­žMÌE.r…Om½Ùz³õæ;–w,ïX^Ú~iû¥íúOõŸê?UÆÁbPŸÏ[åì‹(D!Ên”Ý(»Q7moÚÞ´ˆŠˆŠˆrnáܹ…UŒ^¥WéÕí±Ûc·ÇÆeÆeÆe¶¨iQÓB9P ä¨á×îÏžˆ×õKÇÝs‘ɽӌ-k;òuEö¼QCõ™lÕÝÑþ#gøx8ú Û¨<¡ß‘dÞn'–î¸oྤiIÓ’¦mÚµiצ]’6’6’6ÊnŸ„ô·;¸u–µ€ ãcuB(h(Œ&¶€Q‰@wÔyí) !uÖ]Ëú8Ú&t‹á gòš¼&ʧO“‚&M Šÿ9þçøŸY²>d­•£•£•CÄDLÄÂxð¿ _©Û᪱LKMKMKχž=·Þ>Þ>Þ*MUšª4M4I4I4©º[u·ê®H[¤-ÒVæ¨æþ>êf)…Ðá®ªŠ°»F;€y[8à]…¹Aý@±h&`6€_"àëþýån_Ó†4Æc WqW?<þðøŒY³2f¹Ív›í6{ðÁ7ßBkH "AÊð•:c꿱çP„"”Σóè<Ú‡ö¡}‚*ƒ*ƒ*í·Ùo³ß!ŠEˆÎœ)8S@HI`,€a<Êjõéü–CN¨u@"‘è\ì\ì\¬½X{±öâg/ž½xöB+•Ç ™v°;°£ž^ „¡ T ‚>¢è#ŒÁŒ¹àzÁõ‚kmNmNmNÛÉm'·l˜g˜g˜g²Ôd©ÉRPPÐÜþ¹ýsû—Ô–Ô–Ô ÙfØev™]®××Vî¿A&â:V Ëæ:ZÕ˜|>(º:wÁ¬aû[õxtÀÒ‰Û|:@jÓŸÈp"B78ÁŠ·WŸQkjM­…eÛ+¶Wl¯\Ÿr}Êõ)7jnÔܨñêáÕë&c2&Ó´mÀ[ì‹QwÐâ!ˆþuwOØ3ö©€÷©ÝF$dèHÿ=Éêæ{ÙIvå8n§¢NEŠ¢k£k£k¯=¾öøÚc‡cÇ”Ù<(¡„þrƒSw|]H):šŽ¦£…ÕmDmDmD÷ß?|ÿðõ·×ß^ëâëâëâ«Ü›õ¢^¿±·úC(4‰L"“èWô+úÕF—.]’ç$ÏIžÓáA‡ )š¢©hŒhŒhL}ÈgÿGSbJLDH¥R©TºÅb‹Å‹'jOÔž¨ ž=xöàÙmŠÚµ)Šÿ þÁòšå5ËkDN"'‘“r»°ë£Ân\½ó߸Ç#…Âbõ*y¤b]áéªi5+TÐK¤+Àú±p=Wõ]ªSP‚jÔ²1¬1 o˜BŸ7=WOé@:,šE³ht@tp v v 6kdÖȬQŽ4Gš#M9•r*åJP‚…¿Â_áÏ m|1„g”•×äB*ɧ@õ 9BÀ¹Nðý}XÞô€\È`â´M= õY¿äs¥ÎØ6̳ÁdÙEvÝÜ}s÷ÍÝ·#oGÞŽ466Y²6d­(X, fsØ6å(GùGg (  *D…¨(V+V+Vë¥ë¥ë¥­[;¶V]K]K]ë誣«Ž®JKK£b*¦bE¶"[‘­üVÖ·06Bz¤ÛÄ6±Mf&f&f&6° ²æeÍËš÷"êEÔ‹(Ä 1ì ;ÃÎ|áùìÿ0–ÇòXu¤ŽÔ±¢¢¢¢¢âvðíàÛÁ²XY¬ì´´ÿÝV7ZÝhuY|I|I|æÕ7¯¾yÕ_x6KÖ“õd=Îâ,Îð–äþ¬Z,Äp¡ŠªÔF|LÅí^jpﮇ[²2è«Zv?¸Åé—ƒŒÚ]¤ùd&QŽUàF  o<®žjˆ†h(TKV,8¶àØ‚cñKâ—Ä/ùÖ÷[ßo•ß”ºÙ‘¹/˜ÐÉV¯³B(ü”ýÏ5*ë`l=Aá@Û×ÙÏC ç(o ”¾ÌqκIcH ‰–ܜܜܮ­¿¶þÚú˜ä˜ä˜äN=;õì¤Ì N“Ãä°ru§¢Ž&£‰r¬}jã©§6NHKHKHÛ;yï体Õ"Õ"Õ"QˆBb5Vÿòœ¹>i‰´DZp€Ç6Žmccc²W¾W¾W®*S•©Ê`3˜!ùÈç-öÑyûïñU¨B•¾ƒ¾ƒ¾ÛéÙ§gŸžpÏùžó½i×L®™\×}´íѶøzEõŠê­vhGÑDÑDÑD¨C½îÕ‚«þ»÷ûÈF¾PEµÊPV&·çZ1¨z.ä´]5ÅKÅ|£Ç%k$?«TŠâ•§l XØ7=W¿m£1£hDë=Ö{¬÷¸IN“œ&9Õ³ªgUϺcuÇêŽ&a&)áñGÌ_:a´¶€2o òÒ\:dÓ`Gw˜ý \·ÀþÞÐÁ „ ÿ,D@šø%Ú^òŵÂfXSÖ”5²m¤§¤§¤§œœsrÎÉ9â â â ÁµÁµÁµZ¡Z¡Z¡ì5{Í^ãŽá˜ðýÂ<Ø.¶‹íòéáÓçGï¸Þq½ãJ'•N*´#tGèŽÐêÕ-ª[$’D’0 ³0«^+í`;¶ícû d8T;T;TëNÓ¦;í•Î+W:5*5*5*´ íB» š¡ÿš+ ^0€m@P‡Â.…] }îÝ)ºÓNüFüFÅTÜYÜ#Þ¯{¿.ïHΚœ5Y7Žp7úÜc»Çvíö§íOÛŸ¦o¡o¡o!d­ù(9ŸmR']¦Ö-­[Z·Ž¤I9’±4biÄR[[[eS’@X/JÕýŒ:ÐÑ#zDn èe;üŠÊU•«¢"Ÿ¶>m›ä °`צåÞ{ l‘<3yæ‹GkÌÖ˜mÖÿFÿ:ý­^Z½¤w•/ËG>xº‚zí¿œú…äG©|ÂA9ŠZÔ~·ÛÜŸöߌHEЉÙ‰P0†ï}*WUå! “Qì9sÒÈ‘ŒP])§:^e&–¸WA‡7=Wã1“1™QXÁ ÇõVè­([‘³9gó…‚œ™93Ù’wï2â­Q€,bOØŸzš³‚û}u»?QÀäÀ/}{Q0”ÀvÀ‰!0ŶùÀqk¸Q'ä†lœösý £Ê§3Oø¾œÄIœdÚL›i³l#ÛxpçÁ7·0naܦõÒÖK[Ïê\Ô¹¨Ë˰ÆaÃÆ8v⸾FÆ>”}(ûPfTFTFTu§îÔ]Q®(W”+§òØb¡……Ö0€ \L]L]L%n7‰[ŒsŒsŒsIRIRIîáîá4N gÖßšpõn?Ú  Ú’BR0ó0313YK` ì+öûJHŸ#É”dJ2MMM}Úù´ói׺¤uIëÇ,Ç,Ç,­¾Z}µúÒ¶´-ñJwNwÎtÞãyiÅÆŠñÕO÷>Ý»gŸn®n®n®ÑwFßUØUÕVÕ²ë0‚½†R”²Wü·C}ö)*½MÀO¸/,–ÙT¿ª=…šÚë2M:´#Å(b[ðÜh|P»ôÉ~"Çý©BùCLÛÔvªíT#ó_ã¿&hHžsžsÞ¨@%|9 P@ŒI#Òˆud`¯Ž÷¿$L9º×"ïb8…V0дF†@?Ø)“ÿ¹Káâ,k @™£FYk´ú/øùëv§Z¡Z‘t’NÒñ/ñ’”‘2R¦â©â©â™3&gLÎÄ}¹ûr÷Ý ‡Šgººw÷3:gtNwFSIS‰Oà“¢'EOZ4;hvp1™AfÁ¬ëÃz*§Ö‡`?Bè&ê@:BI¸†ï¾køNe¶Êl•ÙÏ«ŸW?¯Æe\Æe¬À ¬Àø?þ-?©pÜ…Ä£7p7¨>Õ§úXõX¯¸«¸«¸+ÔÙ69ˆDî–î–î–Í£šG5ò¼áyÃó†gÏþžýuWê®Ô]ù¡Û‡nºå{å{å{]uþÕùQ_G}eê‘êñôë7Ò7ÒWÓ½xPq–¨KÔ7Ž"£HÈsÓ‘¦#»~ocóºgyßò¾¯Þ‘ad&3Á¸Þ•ýâ”§çÿ]ÉÎ#» Ÿªj]ã-û¶F&Û$zFš“žè‡Gxf\(m¥È››«§„îÅ1ƒ:jQ« ŠE¸Û¾ëû®ÏZk^k^c.÷—û‹“ ö"[ËÖâ}Ý©K÷›„»:¿ºÙ@ ÀLâ¸c4 ¦#ôË€%VðóU8fy~@€0ý žÒ”gñ?ÿþ\4¡ M8ÃÎp‚œàG8 Ëd™F¦a*¦b*Æc<Æ“9d™Ã옳cÓØ46 Ѐ†Ðì£q£úFud´šÚÄ÷6¡6¡ O O íøÄŸšï¾*|Õ£³yò&¼?‰þè“T•ªRU!ƹ0悽؋½CÂðð¨ÞwÃÆl.›Ëæ ÇÈÝÛÝÛÝ[ä(r9¦–¦–¦– ™òéVº•nU* …ƒÏ%Œ^7ES4EôA²l'Û‰6Ñ&ÚŠE€" î¹¤Å´˜³žk=×znóƒÍ6?ØR­¥ZK5k-k-k-SSS‡š5;jv<Ÿñ|Æó·ßn|»ñÝÚ»µwkã|ã|ã|‹îÝ/ºåXŽ,À#H !ß<Úðhƒì0~]Cº†ØÿjÞWóúIû¶ëÛîCŸu-×µ\k Ox’pÈ c2e¸Ï‘_Ï|‚I6¢Fäñ•'°á,®y•u#c¯ËÕßÜéøZ3CµBåG‘Ê6ÑÞ±ÓÏÛFŠv®8*í4¹ŠLe]`‹!üpÜï|+ùX;÷ Ï!zu¯¹N0!ZHàÊ@8x´Î6B¶øé xTg½0þ¬øÃïæŸõ…å5Xƒ5ä ¹B®HI"‘Œd$ ™a„VÈ ÙÐíÓî¤ÝI»“Ñ£ FLƒMƒMƒÍΚ5;këiëiµÎª‡U·A•´’ùÉw»ïö Q:!:!¾ë+ÞT¼yùþzåõÊ™ÝããíÇÿÿsL“·Þ>(8ò¥!iH’Cä9$”QcwÙ]vWò¥v¤„¢KDƒh° VÁ*ŒZµ6j½·ÁÞ{hjkjkj‡T‡T‡T¿8þâø‹ãÔ€PÅKÅKÅ˿Ч¨û”FúÐ'^Ä‹x‘ïÈwä;E{E{E{eÌzj³Ôf©Íò9èsÐç ×N¯^;ýŒüŒüŒ\-]-]-Õ{¨÷Pï£8Š£¹7soæÞ| ÿ@ÿ~|e|e|åƒãŽ?8þ6ümøÛðßx;oèšË^²—¬‚½b¯Ø*•H•HZ*O”'*N»t=èòr{ðöàí=>è}ЫÊ''×éeôËè—äGò#9Ä:²ŽŒ'0¨w>ňûD\b±@K«6Ô¦}¸V»AÖEç€ä”8 Ï` £gÒ( ¯–ÊÕoªPA j@0Ó¡I ˆn!©xÊ̘¾Åj¬FY-y÷û3êž7C_ÆÔÙØ"€Ÿö@È$Ø{èÀ½vÀ/ýs-5 E8=[ÿÙ1—(§ìÂ(„d’L’I"I$‰$Ÿä“|<Á<‘ÛÊmå¶l›Áf(‡­à‡>ÃìÁÕ6ªmTÛ¨MS›¦6Í2Þ2Þ2Þòå!ËCV•V•V•V¬6Xm09nrÜ丮LW¦+Ók¢×D¯‰Þ ½z+tGëŽÖ­x£x#›![#[£qáAЃ ›'²OfŸ,Xl0Î`\á;¶m«.±ogßι|ÐôAÓWõJë–Ö-¾×‹s/Îe®~0ðÁÀ–<,yX’]#­‘ÖH™ócÊ"WÔ˜ScÀPÖ9öƒü”uªP…ª¿ýØ<#A$ˆ±l'ÛépÂá„à ý¡úCõ‡>—?—?—N/œ^8»° »X/Ö‹õ–þ?¿s!èEHÚЈœ 'È ÚŸö§ýåáòpy8 gáLÙ±–È$2‰¬a~Ãü†ùm3Úf´Íð2ó2ó2s8âpÄሉµ‰µ‰uqËâ–Å-óå/Ê_ôøÈã#ÜytçÑG)v)v)v¯{½îõºWÝ·@ÑF´ófÞÌ›…°"œÛ {…½Â ð„-e[e[[É2€LKÝ–º-m÷-É-I¸Ã ½AzƒZ÷©èSѧb½d½d½&N†“álÀó:øE¯þø#îTDT©19ZYéxJçß>6âV—›Á†k´{d;™³©Õ}‹äðÉ—S´ä#îÇqÿ_ÔYÑ{ÿsoKdü*°"0˜î¯€)†>ièâ ¾‚ ñC{x vâ Ó bÒ†JÜÅÝ—Ië'­Ÿ´~2\g¸ÎpÁ>ƒ}û ‡3fõÀêÕ‹,>XæXæXæX%Y%Y%i•i•i•‰ŸŠŸŠŸªº¨º¨º¨¥ª¥ª¥*:):):í,ÚY´³àZÁµ‚kïæ¾›ûnîÛ¾oû¾í›{<÷x–ÅË™/g¾]êÔÒ©eŠWqTqTy§²¯Ë¾ÖìÿÌÿ™£Dõ°êá{} }©Zn6n66“¥ ¥ µ(ó-ó-ó­ô©ô©ôy6ïÙ¼gó¢h<Þõx×ã]™a™a™a] º|\ ÜþðnZpqPÈáͲ†¬!Îã<Î4úû×'†bÑ2Ñ2Ñ2ù ù ù‰!Ò!Ò!Òyóçkz¬é±¦‹[,n±¸…Pï™91'椌tÿߨ۞ÍÑÍ•Ù÷CŠPÖŽµcíÐ >N¤¨µNkÖ:§FNœù]÷»îw½e»–íZ¶k0¥Á”S4+5+5+E¢ QEÚÙ´³igSTSTSTccc£&EMŠšôîлCï}ôNæ`æˆJD%¢!XˆeGÙщþŸ7r´m@Ï+ňûv·q } (Ö®\=§|eMZ­jÉ·„B̆°$“ ÍîêYˆÔB…òæ3¢9ŽãþW„.»è²‘Ÿ#ëÀ°fXM â‡òtÔ×ä)1êw‚A6ûäŠõ©ßÊCØšõ` Tö°`»°¯ÎÞƽ_5¶hlÑØnÖĬ‰™¯ù$óIæ“,v[ì¶ØmÑÊ¢•E+£mFÛŒ¶‰ŒDF"Óæ¦ÍM››3g6N:M:M:­¦mMÛš¶µWj¯Ô^©Í¨Í¨Í¨W;¯v^®^®^®^î¸Üq¹ãrUsUsUsOåžÊ=•'Êå‰J.•\*¹ô~ÿûýï÷YYYVXVXVXÖýøn?º¦îîª j²j² T2#2#Rc‹7oP1*:\tx\Pà _8ú¸Ä¸Ä¸,õ¿àÁÿ‚Sc§ÆN=§xNñœÒ,­YZ³´Ê•;*w¤g¥g¥g¥ÞK½—z/azÂô„é±§cOǞγɳɳQöÍú¢/ú ?]¨½J‡Óát¸BG¡£ÐaÇÙqv\™ý¯œ'df`†â”â”ââ‡8ÇÙŽ³g]¢KtŸy=ózæ%LW¥3éL:Sî/÷—ûöwU70i7vc7%”P‚,d!K±H±H±#1#…ÍU*U*U*}Ý|Ý|ÝšD6‰léUíUíUí>Õ}ªûT­6Zm´ÚT˜W˜W˜Ühy£å–QjQjQjO‚ž= Êyžó<çùGïAÈ3@H aCVͪYµ|¥|¥|¥ò½ýñ#+‚"E¶"[‘M숱KÒNÒNÒ¾wðÞÁ{ûxôñèãØ6°m`ÛõG×]”5bX#ex°ï^|ŠŽ»váñE6–ͨi&—VT_­ „˜&“-€¼œÝµ4Ò6‘…7ja#h@»ìÇqŸ…÷à ^ð‚+\á 7¸ÁM*L‚I°Ð#ãÈ82ß¡ß)+†(³r€•3Ñ6gÀÀèt~Øò^õþ˜ôgëtoj”Œ5}$Ö —$£ª»ÕT¿+Û!›ÞFÍîµÝ«Î1ÆÓŒ§iéK¿“~§¥)—ÆKã5·kn×Ü®¹Hs‘æ¢*¿*¿*¿âââÂÓ…§ O§œJ9•rê}Êû”÷)Ù³f?ÌÖËÖËÖËÝ—»/w_ö€ìÙJªKªKª«5ª5ª5dýdýdý”Ÿw@YJ TV‰…PE•N èæÇüXç|q¾X1-ù¨Òa¤v-ÈfÀûÕÑÑïhD÷=Ú÷hߣ}-6Zì§ã§ã§ÓèZ£k®9':':'Úl°Ù`³¡Éµ&ך\ëÕ¿Wÿ^ý r r r²¥ÙÒliT¯¨^Q½¢ý£ý£ýóÜóÜóÜKÄ%âqÝžõ¥¾ÔWH[ÉÜ™;sBMpgpFè"ÿFRÉò„Ëó¡ûëø`aYN–“多T“jE°"X\÷ê|¯ó½Î÷¶Cm‡ÚmÛ:·u®[ÿ¶þm-Ò-Ò-ÒM&šL4™X£Q£Q£‘™˜™˜™xÏëž×=¯ÈŠÈŠÈŠè³Ñg£Ï¾mý¶õÛÖÝz=!OÈr„!Gî w…;&b"&²ì{ð» CÿøÍXÝ“£9š£¹vóøÖã[omÕ6ªmT—í]¶wÙ~fá™…gfågågå ]|–Ì’Y2¿øÕŸ¢œ6Ô Vq¦¶d³,GñŠM¹¼s¨]GÛ®½\ÇØ|…ìgù³Ôêü^ů\569·Ÿ! ËÙiôÁ”¡FY„ã8Žû}uÇ턼+;°;H‰ ä:¹N®ã.îâ.~ÂOøI¡¥ÐRh¡Ú¡ÝÚ½/iF|Oÿh|Ò¸‹ñ)ã.ær+…¹Üx‘Ž›qO {ƒ=ÖýŒ¿s®R‹T–Œùy¶÷DŸÃ+žë=S[d\‘ò¤Ñ†6Ò™RWÓsv ì Ô/s-sÍùîñ»Çï¿Í‘;#wÆ›Ü7¹oró¬ò¬ò¬Þ˜½1{cöÖì­Ù[³¼‚¼‚¼‚W+^­xµ¢¦sMçšÎ¨5b ÒšCsˆŒÈˆŒM`ØÖ’µd-…Ü ¬)kÊšâ0c—GL‘AhD¼ˆ\q7Q w¸£†Mf“a‰X@,ɲ gض“-aKØoÔùÖýN÷;Ýï܈q#n7ÝnºÝô²÷²÷²÷ŒòŒòŒÒ Ó Ó ¢Þ+++ÓµÒµÒµâÇ=Ž{ütËÓ-O·$ÞI¼“x'oeÞʼ•¿q,¤ù‘üH~dØ#öˆ%²D–ˆýØýÿû0Hi â–â–â–S±S±Sñ¾Š}û*Þ]xwáÝ…¾!}Cú¾“¾“¾“u¢NÔY%«d6ç}ÝO§ ]èM¢I4ÉZ²–¬eÙAv]f—ÙGµƒU^ª¼Tyémïmïmï£æ£æ£æŸíŸíŸí¶Ým»Ûvñ3ñ3ñ3Òt#ÝÞ„¿ ———?:~tüèlY¶,û7nè z‚žŠI±9l›ƒÃ8ŒÃŸñ(O„[ë—ä%yI†‘adØÜ¹sçÎ;0`þÀüýUû«öW­)\S¸¦Ü%wÉ]6” eC‘‹\ä~±E¯8寂ODň’5²2E1ûþÐæ~ý[E~âkæ¤d³A™â¢§e=\Žmþù\eÕtÙ:ùA,A|0gþùp•ã8Žû h€â>@d$ɬ!kΰÿî¥t]GשժժÕjÜи¡qü•y+óV¶ílÛÙ¶³žl=Ùz²õ8ëqÖãŒòòòuÃuÃuÃuïëFéÞ7¸kipW#]:Yã¤l´ì ;ð.¿`ö ÿØÖ1!ëÞ[kXËfÈ{–¿«àÅûYïœÜÿºëë…£Ÿ~>X»EÎO9?¥,Û[¶·Ü¡4µ4µ4µ\T.*áŽáØï¾[wêNÝ?ê¤ •³Ãì0nán!©ÎŸ$ AÈEóÉ‚LêŽì~ýÏ?B]La”WñJñJñê£Cd¥a¥aejajajá^ä^ä^ÔôiÓ§MŸzÞö¼íyÛàŽÁƒ;† >,ÿ¡ü‡ò^vÙýe÷Ìî™Ý3»Ç®ˆ]»"zFôŒèyòå=ªŠ©Š©ŠùèME’HIÞ7ä ÃÆ°1LÁLjT£Z9Öû9Âl¤B*$ÇTˆb…8@5@5@u£ûF÷îk#ÖF¬ë>Ö}¬»2çŒð®„)¹\Ý*¤îp‡;™Afô{ú=ý^þRþRþÑ$WÉÉɇB‡B‡Â¶{Úîi»Ç{÷ï=víÛ5¶Øo±ßbqPqPqPÁö‚íÛSæ¤ÌI™s§óÎw:'~Hüø!·Un«ÜV؇}¿{)ë\Æe\f­X+ÖJ¸1Æ)œÂ)£Åÿûp&º”.¥Ksss=u=u=u7EmŠÚUEªHùvÝ·ë¾]÷|÷óÝÏwÓ@„›+~Éü²‘OµÑbK¾’Ïc~ìôz­.KüNL-j9ÉC†Å…ãëš²+7 ß‘ðÓ¢W‹Ë´>,"ýp‹ÙôSÖá8Žã~Ÿ¬`Šä ÈV©Ô@ï‰f¸f¸¤¿ö5ík>— .NÖÔÔ÷hp°ÁÁ-ƒ-ƒ-ƒmŠlŠlŠŒÇ1#m-m-m-^#^#^£š©š©š©æ¦æ¦æVõ¨êQÕ£‚U« V½kù®å»–olÞØ¼±yööjÞ‚×µ¯ß¿5Ì?Pàðr±Ï]ïmiÞ1v1öНJÕKOk{Ûzû¨õˆ00©p{bþÄ\1í÷>„H,‹Ä88Á$LÂ$Ì€0VÌŠY±0R®Ì³ñ׉ù®ûNDAD¤DJ¤$ŠD‘(Ò‘t$å¯å¯å¯ýRƒµk Özž÷<ïyÞ7Ð7Ð7Ð)Ó)Ó)Ó5Ö5Ö5Öè•Ñ+£Weee•—+/W^~>ÿùüçóïÝ/º_”¸*qU⪌!C2†¼£ï軋@ÙÀ6BM!o–` –0cfÌŒ•“bÿûQa!›~?ôC?a²éDÑDÑDQH‡!ŽjÕ<ª¹ªhUѪ"bClˆ û‘ýÈ~üC-é8#ʸ€ ¸ |NRËjÙGÏáÕߨ¿Qãâïâïâï=È{÷ V=ZõhÕÃá©ÃS‡§šK5—j.—‹ËÅåB~›$i’4IúHÿ‘þ#ýˆ%K"–¼ |ø6ð7ÎÆÕ¢Õ¢Õ 3…™ÂLY (øK¤õÚ*$MHÒ„…²Pº(pQà¢Àþ)ýSú§ìf»Ùn¶!cCƆ á9›òWÈ3ÃÇÝ¿PŸ¢Ž©pQÝ‚<V¼W|èZ}"v}ŬØœVó•ŠéMR¿¨¶ÿ-#ö¢7Z(ƒ'9Žã¸ßAš“æðc9,…æ=Í{ªd¹÷wï/õ§!4D1ªý°öþjòU“¯z¯Ò™¥3K£—F•F•T^ãQãQãQSSSSSS[[[•R•R•’}&ûLö™,Ã,Ã,ÃÜ˹—s/ç8ç8ç8¿iý¦õ›Ö…c ÇŽ)¶)¶)¶Éo–ß,¿2†_’ù¶Å;Ì}u27CÜP£™†¶R:˜ê<~ûømY¶s¶3–’½d/ÙAòH‚˜ÓÂNÌÅ\ÌeÛØ6¶M¾F¾F¾F7üwÍÿ:Ó4ë¾9ä³2VÆÊ˜scnp \ƒähM¢…úšŒ1ÆØûïg¼ŸŽp„#<"<"Šw'+È ²‚^ èÜÃ=ÜÊ-)Ëß‹0öoC a…Õ 5j,ÔH:št4éèÌQ3GÍ¥üìnĸ}ôZŽû=´!1C’°Ü·Êµ³ÍeÙñ…O‡Ÿ’Û,2þ¸ºÙÑ0—Þ‘ ¯Z½SžQMÈ!Ò˜·ÇqÜÿJ0ärÑíµk¿Þ²,tYho½¶¡mCÍÏØö¶ííÐJœ'ÎSéôìz#6b#B§Ð)"‰H"’ÐN´íDv“Ýd7®à ®À6°Vno¨ÐÆ´1zÑ@ˆ¾´5mÞô{ú=b?öÃX¹¥ð¡|4Ž+‡XkbM÷Óýt?u¢NÔé÷^ªÙP³¡fÃæ]šwiÞ%(.(.(n³ãfÇÍŽ·NÞ:yëdÂÍ„› 7ÜÜÜbGÅŽŠuÌõ˜ë1×iYÓ²¦euÏêžÕ=˲ȲȲèwß› L`B£i4¦8c&`‚òÅCLf’™d¦°Â?Î?Î?.¢ID“ˆ&§ÂN… ÓUÑUÑUn/©'õ¤ž4Œ†Ñ0eõ_“A™ÏŸ>#‚:uê¼=s{æǫ̈´¨´¨´„Ý »v'X'X'X_Ò½¤{Iw æ.èv®Û¹nçLLL~÷;²†®¡k¨U£ju;¸_HçU jP£b*¦baZ¶»Ä]â.¹'¾'¾'¾šz5õjª]»v=”a…£Éqÿæê´É¿Lòh9Îúб¼z÷‚.Ãæ×V.œ7|8Û½Ä0¨Ù¨Y¾ÑN”ß&U'‹x»qÇýÁ†ž°()•”Ò†ZŽZŽ€Î#€(W”ûñæ4ˆÑ ªI5©&9H’ƒ¤iGÚ!™ÈTNúœŠ©˜ŠŽèˆŽÊpî϶°H‹XÄ’‘d$I[ÑV´Õ¯7—DJ"%‘6 mÚ4ìy¯ç½ž÷½\ôrÑËóçΟ;î碟‹~.JïšÞ5½kâŠÄ‰+η=ßö|ÛMS7MÝ4589898Ùc¥ÇJ•ÒåÒåÒå¿Þ¿Ç†–ÒRZJº‘n¤;Í¢Yô%faÆŒÜ?rÿÈM<>ðxóüKó/Í?LÑGô¡È^d/²ÿõÞTUUíììB>„|ù°+jWÔ®¨ð‡áæïOߟ¾ÿAõƒêÕ—4.i\ÒXriÉ¥%—‚‚‚Me¦2ÓßÈñ"äÂ'[ÉV²U9š>c1VH›øËFun–¾$?àü@“Çä1íF»Ñnó»Ìï2¿KêÂÔ…© §Ÿ>~úxtAt¡Ô€`†ð2—Üÿ4Á>Ì–]×ÝÐm_©5O>tyÍæÑÃR[Ñ-$h.iÓÑS97\å!Fx»qÇýauôS ÇÈCòTc–açG£Œ_j'æKU÷Øå!yô1}LÓZBK~ïEÚǵko~ªù©æ§¦8Lq˜â°uÞÖy[çÝùñÎw~LÓOÓOÓïß-¾Û}Íûš÷5Oã4Nã»îßuÿ®{ˇ-¶|h®m®m®ýë=“’@Â…åe_-ûjù“ç’ç’«¿éøMÇ¡͑Ӛ®5]k†÷@ïÞœpnÀ¹mg¶Ùvæ®û]÷»îñqñqñqI/’^$½83öÌØ3c®X¸báŠîÓºOë>M?F?F?æ7>ØvlÇvÑÑÑ2…L!S` XüF[ÕÔœšSsaÙýû÷7áÃ'†O¼~ëú­ë·ìíí± ˰ŒT‘*R¥œcÀ}A>Ùád3p±oW”«UªÊ/±TÖ€Rl&çP!êF¿Ók >]m^9ޤ€õ¼ÇqÜÿA 1jQ‹Jat‘ š€ýl8ŽÖ˜5fƒ•[Ê!ÿÇÔÀ¿f%Nî÷Ôi3˜)˜‚)˜r l! QHÂH ÃiœÆiæÂ\˜Ké ÒA¥ƒîãŸTÍUÍUÍ{:ötìéÈ™#k´«Ñ®F»66llhqÎâœÅ9§T§T§ÔÁŒÁÈpÌpÌpLß¾!}Cò½ä{É÷ÊÊRžÌy2牶t­t­zK³.f]ôËßY½³zõüÕœWs²w¸d¹d¹^ìð}‡ïžzæ{æ{º¸¸è:è:è:Tίœ_9¿pYá²ÂeW;^íxµãíäÛÉ·“…*F¯B_…¾ U~ÒõXõ˜‚)˜"d‚º›¬ˆ±"ù!ù!ù¡ªþº­ê¡®êkÅkÅkbOì‰}²Y²Y²Ù½%÷–Ü[Òר¯Q_£@Ç@Ç@ÇusÖÍY7G9yZ jPãuU¿$Ÿn$f,üàŒˆEšÚÑ[ú:gûŒ­îêžQ_¢6D¬¢á¦¶êÇ÷CS†Ì8?9ÒY4< }åçYŽÓx‚L~08Žã8î‘@‰rjé|ÌÇ|2‘L$iÚƒößßßøhû«¸Š«Z¥Z¥Z¥.W]®º\meÓʦ•›ª›ª›ªõLë™Ö3­c¬c¬c*s*s>x½xQúcÖܬ¹q×_6}ÙtýCc™±Ìå'v‘]ÄÙ‚… S6]ÙtåÊr§ñNã›;U>¨|Pšù¢ðEáËËOß<}óôÍý;úwô¨>P} Z„"i0 ¦!¼RFÊHÙH6’ […­Âã1ã•™é…?Üï CÈ2„å°–ã¢æ¢æ¢¶Óc§ÇNê˜ê˜ê˜QÙ£²Geg.Î\œ¹˜l![È¡Œo7îcƒá ;á^X¥ u#Û]7º—©bÊ¢°][é2JýdÖÀ†m£”§6V#aŠNõ»á8Žã8î¿PwZÈfS‚”ÐytGGÐtÄtΡsè;;»Ás϶zlõÜîðüÃó‡UïÎÚµhaè’Ð% §öšÓkN¯Vƒ¬Y úÝŸµŽ®£ë„(mCýÊÿå‡ñ„fb&f Ué º‚®˜'''MižÒ<¥ù,×Y®³\•§Æ-r‹ÜB4@ÞÎÜǺÁ –ÊåxLEÏ«#‡t<ÃØÇ á¬r¹ipè-éˆf÷«­Ý¢yÊSÊ{0“7ÇqÇ}Âä㡊¡Bi¡ Ïïå´}+ú–ž¶lnÙܦ_‡¯:|åºjMÄšˆ›»w½~{aÁ‚M¯ÇEŽ‹tÝêÜݹ»¶á¯÷@RI*I%kȲFY\iFat ~@>º€.  „essó;>w|îø\ÛvmÛµm]º:tUnÙ•v¥]y‹qk[˜Bˆ…ÇÌú;·q`²¥ãFvalIqÐÛxýq[zM4Z¡ñAÒC…„á%ŽòÆã8Žã¸ÿ‘ºÓ:…” }hÚG´F´F´MÑô— ·n&ý4é'íþþêÏü~ ñ×ÖMX§9È$ß$“‰ñÃ{•S*§DQä9BŽ(«ºþúgqŸŠðŒ¥z YGÖ‘uÂê…]v]Øõ‰É“'&Ó¦L *Ú’Óä49¯ñ5¾æãîÜ/Áúø ß T!ÝàÑur“çL¾,5¸›B¶ØcÄ™ŒÊ)÷úMµÙªÛ@ú@x5%úˆáÇqÇqÿÔ ³Ñ….t p›ì$;ÉAÕŪ‹©ŽOwŸîª²¦¤)QÓnº¡éµ"ŸDŸDµ%ªVªVä¦b*¢ºAã7öÉ}î8‰L"“0Ã1\(­{ÇëŽ×¯›Ën.»¹Ì6×6×6W(†EH àyf¸_8ÂÚd°LX1ÿtÛÑ(c+4B|kï,0¼Ë»¿ß38Ø5×è­®²²]Fº¢Œ7ÇqÇqÜ@xš!Ô…*3æ?ÿtþÓ¤KI—’.ÍÚ:k묭ÂzâJ\‰ëG¯åþ†>Ýã’T¡–$“o(¬x‹ò9•AéO2…‰b“vc‰DU¤é¨zE¥³òUÓÑ‚xðÃÀqÇq *PùÇxy !¥Ýh7ô¡ÞÔ½”w£ÝÐGøßßx÷¿!¤w¬@*躅nf2œéy¦ç™ž…§ Ož xð&à}GûŽöYËcy$ŽÄ‘8ž’ƒ³NËÈ"¢,ŽÝ_Ï­‹m#övu³ÑÛʦ̵ÿÆŽ±Õ¦£çu´°onî(l#šBî’^üËÎqÇq÷'­Æj¬¦SmªMµçµŸ×~^ûÔ•©+SWΘ5cÖŒY˜ˆ‰˜H¨5B‚Ä›ƒh<¹Mº Ëí4XhšÎØÊˆQóË=æ.þf»µêÊèÆƒŒÜÓ ¶¡Èd¢ M¨þ2¥•ã8Žã8ŽûOQ}ªOõ…e·n/Ü^„KÃ¥áÒ‹o,¾±Ø¾Æ¾Æ¾#1#I))%¥<Þýoy”?ñþvàž ‹\k+äþŠ—Õµ›E3è}ÒíÙZöÖàš†…Úåöí°]ÔxÇã8Žã8îOêª* …ÄŽØ»»»»ðgáÏŸ™t1ébÒeð´ÁÓOÃ>ìÃ>Í¢Y´²®ªbÞûûøÄw¶ 1,UX®ØXÓ¬ötÉ™ªF5Ž*‡h(.0‘ñi¼z#ˆ@@˜?ÛƒKÐæwŽã8Žã¸?¥nÌz34C3tDGtõˆûnÄ!MX¬XV{FV[º½újÍ"Ñ5ò3é‹Zv˜‰Ò¥ïÕ"!c^ØŒ‹Ð‚*XÃqÇq÷§‰ ‚ˆY1+f%dpÏèÑ;£÷–7ZÞhidkdkd;Àa€ÃÜÆm܆%,a‰¾è‹¾<‰çßŧq_Æî bPÐò Õ³dã #*IÍEBEÈjˆ=ÑÚ75ÞÀÐÂjD úЀ?ÇqÇq’0î.Œ¦Ûb#?'?'?w.ý\ú¹ôüEù‹òµ¾Ûúnë»î'ÜO¸Ÿ`Á,˜SsjNÍÁÀÀxþõ}ê÷y¸xÔBEiëjQMzáîÊÕV¨¤nt7î³£Lf0\£R²žÎ']Q(ŸœÊqÇq÷ PPPE–"K‘Eº“î¤{ryryrùýÄû‰÷¿5þÖøÛA‚Ñö´=mÏö±}l–a–ñºª‡ÃûI±CH@¢=<ª÷Èýúe÷«[ÖæBBv?E,û™é¾Õ¨T›)2$k© äP€ñwŽã8Žã¸O@؃=؃îèŽî8‚#8r2îdÜɸi´@Ú®G»ízx¸{¸{¸³1l CI"Iä÷×÷©ï«Öã>RD7ÉH"A> ¤xD•}%•Óùr_Å6Vl|Dj¯>D´€¶#¥ÊWi@ÌcÜ9Žã8Žã> ¨@……²PŠoð ¾I,O,O,¿½øöâÛ‹u.ë\Ö¹<°çÀž{âü€xÄ+;ý¼®ê_اî¸Ác<§ ˆ9I‚"¨” ¨ ­+’¶¢¦«ù©œ¤wôú¨ç¨žP¾j4Ù Žã8Žã¸O@d¨Bªèº‡îêª^8sáÌ…3¥J/”^ð½æ{Í÷šãLÇ™Ž3™˜‰™˜¼ /È ^Wõ¯ìSwÜ«!‡œíD KEj!+ ª,ªiŒ¹BŽè€Æ¢^ämk¹C»Bú½ð"r_¡ ?ÇqÇqŸL5ªQ­Ø­Ø­Ø-ÔUMYž²uÇ›ÈÂ%¬(>Sy°æœb‘¼L~‰D’Q¤‡è,ù†¨†jÔH~qŸNZ Žã8Žã¸OL¨«úRñRñRSOòKòKò»ëz×õî-óÆæ-FêŒÔ§…­Ø*vSœTœdZh‹¶è†Ôð4‘%Ÿ%éóÀ\–ßÚTŒ¬ú¾ê¢ì†<ƒôÆq,"it>Q5š¡i¥vAù‚E žü`pÇqÇ}bucÖÝà7LÇtL>KÏÒsa¹á¹á.FíŒÚUÜo˜Ô0IÃKÃYÙvÁ Ì@LÇtñ&üëø<Ù:Ûb/».,t¨h\õmÕ ™ª¼ mIŽ)“Ö¤P¿¥ú$5e&2~hÈÅpÇqÇ}B]ÕF¬k„]Ø…ëé­Ó[gYï·cÜ÷‰ÙîÙîQ&˜| ßaóæ H+ô@ §?ÐЙ7Þ_ÇçqÿšÆ]¨C¢Â!•ºÕ­jfÉÎ*æá!‡@P²‘x˜,–vTÿ?  šðG1ÇqÇqŸ…0î> ³0‹œ#çà\Ù±²c‰qâÅÄ‹Oš4mÛ´m ·HO¤gIñäÖA)Ô ÆK2ý•|–ìé¬Nà66Bùûþ¤ÕkªjäSåËÁR˜´+ùÖð°ÆqµíЀ H_âŽPe"PÔ@?0ÇqÇqŸÅr,G> (ÿ úAU¼4miÚ·hŒÆlLEIE‰Š9˜L‹904A’x£}É -âݘNt1ÃÒ×NžÒ÷*“/4›±åI!:w/ŒŒë:\Øœ¡—±íáÍã8Žã8î³ ÿMVƒŒÿÏ­y¦¿œÏóø#E(ÃQôGVŒå8øöByÛJ/P„blª"YÃKì¨òLòŠŸ¨9Óƒ*º‘è¶üpÇqÇ} RHAQjä#hH½©7ÆÑF´Æ krå–Ü_Æg •QF®§ãJ`)$¯7—¡²{D€°—°Ð°TuTÑÕÎSk.žS¥"‹“Gc5:Á=ùAá8Žã8Žûl*Pñ°d8à© ài5¿µ%÷ðyî¢``Pƒ Dx‹ T½›ôaf• ­ˆ Ø¤(Ñ,P5UYªë+é¬j9Pãdqç8Žã8Žã¸ß¢ò¿ù1O+üªÚPAkÈ^¢…†¶8YtQËBm—¸§2ŸÌ2t$ž8‚8ž^†ã8Žã8Žã>ö?Š[Ê›_~­²€Vð›±µ,Os¹jSñ)Ým’yª#…mÈi B?$ÇqÇq÷kÿ£Žû«Í¥-?ì@)ì`¡xÂ^3IšÊM•uZ5jëÅÂ6d1áYe8Žã8Žã8î7}ÎŽ{J¨ï:}x_5Úd"úÈ™b6{† j!*±zk$£U{(7º…áè ÇqÇqÇýÚçì¸×BñK5Ôwq—«»Â›õ@(«e³ØÔˆ’E6ÚÔÜTƒ”]üL£ÚPƒ˜Žã8Žã8Ž«ësvÜ“ðEÂbå\ÙuÙÃòëUy5E¢~ô íUÅ;ÅÃ0 µÍBg]áÊtÐþ°ú7å8Žã8Žã8®Þùœ÷Ÿ‘…·ÂbõY/E‹‚«~U*Í©Y(üÙ)½žê'Ôæ¢Õ¨eÙ 7Ì Ï ÇqÇqÇÕõ9;îáx‰×B1¦Êá²Ý²³oåå+ˆ‚EijgmLÒ5Ϫ§ÐÙ¤‘°D„à´G˜ñÃqÇqÇqu}ÆŽ;{Œ< ŘjnÈ£·ŠgU-­Ñ€ŒD‘vP•ç+– •æªý,¹©RLP9h ˜ðÃqÇqÇqu}Î÷‡x…w0ƒÔkÄòbÅÝ÷G>ì©îM&½1‰ fI:M$šªaâ3"P[aŠ*qƒ1tùá8Žã8Žã¸º>gÇ=oðž4ÃÌ@.áf¡]ezµ¡CdR¶ÜÐRCE²MrXôX”«Ì@Ó V0â†ã8Žã8Žãêú¼“S3ñ–ê- ˆ¡òÎçÃ*U€†ÐYs…¡âýVꕪaâ1¢8jª|•Ì`È ÇqÇqÇÕ¥ò÷ý¯P@“H*È+Y-LÞ•o©š‚|rýÙAV­q^í½jº4@,S©T¾Ê&F?÷`£p? Ë¥ªíkÒa\û³Ì€ö#>ä5œC=iGÉOÊ~P8Žã8Žã8î_}þŽûhv÷…å’¢ê!µäú5“dÉ¢­¤7©… áˆ7š+Í•¸ñƒÁqÇqÇq¿ç³wÜ‚‹ˆK²«†Õ4¯XT;IC7“žD1!Íx½´@âËÇqÇqÇýžÏ?â>?!VX.u©¾V[òánÍYYO:¶%/<ÄsÃá%øÁà8Žã8Žã¸ßóùGÜGâ<»Uˆ@KžWu« ©È­í+{AùŠTˆÁSão¥¶’Óü`pÇqÇqÜïùü#îCÙiܪ¢ï­ú±ælùÀÚE¨%#ˆ:À"Y’ñZÍ-’#ÊÈ €‚OQå8Žã8Žã¸ºT>÷`>؉‹d Nc^éîê¯j”©nXk1½Nzrg5Z»™ô!\P]èCjÊbLÇqÇqÇøtÜŠëx(’Ò‡ä+™†BÌDy5²[Ñ!Õ¢‘eÐT£P²w‘bœ@ 2!…*¨@-dü qÇqÇqÜçqJTCbPˆ V¾­ö˜:ë°¸$ñTqÙ¨9‹nÐdŽo°ËÐ<Ï ÇqÇqÇ)ý?¦õnKt}—IEND®B`‚routino-3.0/doc/html/usage.html 644 233 144 66476 12574075650 12004 0 Routino : Usage

Routino : Usage

Program Usage

There are five programs that make up this software. The first one takes the planet.osm datafile from OpenStreetMap (or other source of data using the same formats) and converts it into a local database. The second program uses the database to determine an optimum route between two points. The third program allows visualisation of the data and statistics to be extracted. The fourth program allows dumping the raw parsed data for test purposes and the fifth is a test program for the tag transformations.

planetsplitter

This program reads in the OSM format XML file and splits it up to create the database that is used for routing.
Usage: planetsplitter [--version]
                      [--help]
                      [--dir=<dirname>] [--prefix=<name>]
                      [--sort-ram-size=<size>] [--sort-threads=<number>]
                      [--tmpdir=<dirname>]
                      [--tagging=<filename>]
                      [--loggable] [--logtime] [--logmemory]
                      [--errorlog[=<name>]]
                      [--parse-only | --process-only]
                      [--append] [--keep] [--changes]
                      [--max-iterations=<number>]
                      [--prune-none]
                      [--prune-isolated=<len>]
                      [--prune-short=<len>]
                      [--prune-straight=<len>]
                      [<filename.osm> ... | <filename.osc> ...
                       | <filename.pbf> ...
                       | <filename.o5m> ... | <filename.o5c> ...
                       | <filename.(osm|osc|o5m|o5c).bz2> ...
                       | <filename.(osm|osc|o5m|o5c).gz> ...
                       | <filename.(osm|osc|o5m|o5c).xz> ...]
--version
Print the version of Routino.
--help
Prints out the help information.
--dir=<dirname>
Sets the directory name in which to save the results. Defaults to the current directory.
--prefix=<name>
Sets the filename prefix for the files that are created. Defaults to no prefix.
--sort-ram-size=<size>
Specifies the amount of RAM (in MB) to use for sorting the data. If not specified then 64 MB will be used in slim mode or 256 MB otherwise.
--sort-threads=<number>
The number of threads to use for data sorting (the sorting memory is shared between the threads - too many threads and not enough memory will reduce the performance).
--tmpdir=<dirname>
Specifies the name of the directory to store the temporary disk files. If not specified then it defaults to either the value of the --dir option or the current directory.
--tagging=<filename>
Sets the filename containing the list of tagging rules in XML format for the parsing the input files. If the file doesn't exist then dirname, prefix and "profiles.xml" will be combined and used, if that doesn't exist then the file '/usr/local/share/routino/profiles.xml' (or custom installation location) will be used.
--loggable
Print progress messages that are suitable for logging to a file; normally an incrementing counter is printed which is more suitable for real-time display than logging.
--logtime
Print the elapsed time for each processing step (minutes, seconds and milliseconds).
--logmemory
Print the maximum allocated and mapped memory for each processing step (MBytes).
--errorlog[=<name>]
Log OSM parsing and processing errors to 'error.log' or the specified file name (the '--dir' and '--prefix' options are applied). If the --append option is used then the existing log file will be appended, otherwise a new one will be created. If the --keep option is also used a geographically searchable database of error logs is created for use in the visualiser.
--parse-only
Parse the input files and store the data in intermediate files but don't process the data into a routing database. This option must be used with the --append option for all except the first file.
--process-only
Don't read in any files but process the existing intermediate files created by using the --parse-only option.
--append
Parse the input file and append the result to the existing intermediate files; the appended file can be either an OSM file or an OSC change file.
--keep
Store a set of intermediate files after parsing the OSM files, sorting and removing duplicates; this allows appending an OSC file and re-processing later.
--changes
This option indicates that the data being processed contains one or more OSC (OSM changes) files, they must be applied in time sequence if more than one is used. This option implies --append when parsing data files and --keep when processing data.
--max-iterations=<number>
The maximum number of iterations to use when generating super-nodes and super-segments. Defaults to 5 which is normally enough.
--prune-none
Disable the prune options below, they can be re-enabled by adding them to the command line after this option.
--prune-isolated=<length>
Remove the access permissions for a transport type from small disconnected groups of segments and remove the segments if they end up with no access permission (defaults to removing groups under 500m).
--prune-short=<length>
Remove short segments (defaults to removing segments up to a maximum length of 5m).
--prune-straight=<length>
Remove nodes in almost straight highways (defaults to removing nodes up to 3m offset from a straight line).
<filename.osm>, <filename.osc>, <filename.pbf>, <filename.o5m>, <filename.o5c>
Specifies the filename(s) to read data from. Filenames ending '.pbf' will be read as PBF, filenames ending in '.o5m' or '.o5c' will be read as O5M/O5C, otherwise as XML. Filenames ending '.bz2' will be bzip2 uncompressed (if bzip2 support compiled in). Filenames ending '.gz' will be gzip uncompressed (if gzip support compiled in). Filenames ending '.xz' will be xz uncompressed (if xz support compiled in).

Note: In version 2.5 of Routino the ability to read data from the standard input has been removed. This is because there is now the ability to read compressed files (bzip2, gzip, xz) and PBF files directly. Also using standard input the file type cannot be auto-detected from the filename.

Example usage 1:

planetsplitter --dir=data --prefix=gb great_britain.osm
This will generate the output files 'data/gb-nodes.mem', 'data/gb-segments.mem' and 'data/gb-ways.mem'. Multiple filenames can be specified on the command line and they will all be read in, combined and processed together.

Example usage 2:

planetsplitter --dir=data --prefix=gb --parse-only          great_britain_part1.osm
planetsplitter --dir=data --prefix=gb --parse-only --append great_britain_part2.osm
planetsplitter --dir=data --prefix=gb --parse-only --append ...
planetsplitter --dir=data --prefix=gb --process-only
This will generate the same output files as the first example but parsing the input files is performed separately from the data processing. The first file read in must not use the --append option but the later ones must.

Example usage 3:

planetsplitter --dir=data --prefix=gb --keep    great_britain.osm

planetsplitter --dir=data --prefix=gb --changes great_britain.osc
This will generate the same output files as the first example. The first command will process the complete file and keep some intermediate data for later. The second command will apply a set of changes to the stored intermediate data and keep the updated intermediate files for repeating this step later with more change data.

The parsing and processing can be split into multiple commands as it was in example 2 with the --keep option used with --process-only for the initial OSM file(s) and the --changes option used with --parse-only or --process-only for every OSC file.

router

This program performs the calculation of the optimum routes using the database generated by the planetsplitter program.
Usage: router [--version]
              [--help | --help-profile | --help-profile-xml |
                        --help-profile-json | --help-profile-perl ]
              [--dir=<dirname>] [--prefix=<name>]
              [--profiles=<filename>] [--translations=<filename>]
              [--exact-nodes-only]
              [--quiet | [--loggable] [--logtime] [--logmemory]]
              [--output-html]
              [--output-gpx-track] [--output-gpx-route]
              [--output-text] [--output-text-all]
              [--output-none] [--output-stdout]
              [--profile=<name>]
              [--transport=<transport>]
              [--shortest | --quickest]
              --lon1=<longitude> --lat1=<latitude>
              --lon2=<longitude> --lon2=<latitude>
              [ ... --lon99=<longitude> --lon99=<latitude>]
              [--reverse] [--loop]
              [--heading=<bearing>]
              [--highway-<highway>=<preference> ...]
              [--speed-<highway>=<speed> ...]
              [--property-<property>=<preference> ...]
              [--oneway=(0|1)] [--turns=(0|1)]
              [--weight=<weight>]
              [--height=<height>] [--width=<width>] [--length=<length>]
--version
Print the version of Routino.
--help
Prints out the help information.
--help-profile
Prints out the selected transport profile (type, speed limits, highway preferences etc.)
--help-profile-xml
Prints out all the loaded profiles as an XML file in the same format that can be loaded in.
--help-profile-json
Prints out all the loaded profiles in JavaScript Object Notation (JSON) format for use in the interactive webpage.
--help-profile-perl
Prints out all the loaded profiles as a Perl object for use in the router CGI.
--dir=<dirname>
Sets the directory name in which to read the local database. Defaults to the current directory.
--prefix=<name>
Sets the filename prefix for the files in the local database. Defaults to no prefix.
--profiles=<filename>
Sets the filename containing the list of routing profiles in XML format. If the file doesn't exist then dirname, prefix and "profiles.xml" will be combined and used, if that doesn't exist then the file '/usr/local/share/routino/profiles.xml' (or custom installation location) will be used.
--translations=<filename>
Sets the filename containing the list of translations in XML format for the output files. If the file doesn't exist then dirname, prefix and "translations.xml" will be combined and used, if that doesn't exist then the file '/usr/local/share/routino/translations.xml' (or custom installation location) will be used.
--exact-nodes-only
When processing the specified latitude and longitude points only select the nearest node instead of finding the nearest point within a segment (quicker but less accurate unless the points are already near nodes).
--quiet
Don't generate any screen output while running (useful for running in a script).
--loggable
Print progress messages that are suitable for logging to a file; normally an incrementing counter is printed which is more suitable for real-time display than logging.
--logtime
Print the elapsed time for each processing step (minutes, seconds and milliseconds).
--logmemory
Print the maximum allocated and mapped memory for each processing step (MBytes).
--language=<lang>
Select the language specified from the file of translations. If this option is not given and the file exists then the first language in the file will be used. If this option is not given and no file exists the compiled-in default language (English) will be used.
--output-html
--output-gpx-track
--output-gpx-route
--output-text
--output-text-all
Generate the selected output file formats (HTML, GPX track file, GPX route file, plain text route and/or plain text with all nodes). If no output is specified then all are generated, specifying any automatically disables those not specified.
--output-none
Do not generate any output or read in any translations files.
--output-stdout
Write to stdout instead of a file (requires exactly one output format option, implies '--quiet').
--profile=<name>
Specifies the name of the profile to use.
--transport=<transport>
Select the type of transport to use, <transport> can be set to:
  • foot = Foot
  • horse = Horse
  • wheelchair = Wheelchair
  • bicycle = Bicycle
  • moped = Moped (Small motorcycle, limited speed)
  • motorcycle = Motorcycle
  • motorcar = Motorcar
  • goods = Goods (Small lorry, van)
  • hgv = HGV (Heavy Goods Vehicle - large lorry)
  • psv = PSV (Public Service Vehicle - bus, coach)
Defaults to 'motorcar', this option also selects the default profile information if the '--profile' option is not given and a profile matching the transport name is found.
--shortest
Find the shortest route between the waypoints.
--quickest
Find the quickest route between the waypoints.
--lon1=<longitude>, --lat1=<latitude>
--lon2=<longitude>, --lat2=<latitude>
... --lon99=<longitude>, --lat99=<latitude>
The location of the waypoints that make up the start, middle and end points of the route. Up to 99 waypoints can be specified and the route will pass through each of the specified ones in sequence. The algorithm will use the closest node or point within a segment that allows the specified traffic type.
--reverse
Find a route between the waypoints in reverse order.
--loop
Find a route that returns to the first waypoint after the last one.
--heading=<bearing>
Specifies the initial direction of travel at the start of the route (from the lowest numbered waypoint) as a compass bearing from 0 to 360 degrees.
--highway-<highway>=<preference>
Selects the percentage preference for using each particular type of highway. The value of <highway> can be selected from:
  • motorway = Motorway
  • trunk = Trunk
  • primary = Primary
  • secondary = Secondary
  • tertiary = Tertiary
  • unclassified = Unclassified
  • residential = Residential
  • service = Service
  • track = Track
  • cycleway = Cycleway
  • path = Path
  • steps = Steps
  • ferry = Ferry
Default value depends on the profile selected by the --transport option.
--speed-<highway>=<speed>
Selects the speed limit in km/hour for each type of highway. Default value depends on the profile selected by the --transport option.
--property-<property>=<preference>
Selects the percentage preference for using each particular highway property The value of <property> can be selected from:
  • paved = Paved (suitable for normal wheels)
  • multilane = Multiple lanes
  • bridge = Bridge
  • tunnel = Tunnel
  • footroute = A route marked for foot travel
  • bicycleroute = A route marked for bicycle travel
Default value depends on the profile selected by the --transport option.
--oneway=[0|1]
Selects if the direction of oneway streets are to be obeyed (useful to not obey them when walking). Default value depends on the profile selected by the --transport option.
--turns=[0|1]
Selects if turn restrictions are to be obeyed (useful to not obey them when walking). Default value depends on the profile selected by the --transport option.
--weight=<weight>
Specifies the weight of the mode of transport in tonnes; ensures that the weight limit on the highway is not exceeded. Default value depends on the profile selected by the --transport option.
--height=<height>
Specifies the height of the mode of transport in metres; ensures that the height limit on the highway is not exceeded. Default value depends on the profile selected by the --transport option.
--width=<width>
Specifies the width of the mode of transport in metres; ensures that the width limit on the highway is not exceeded. Default value depends on the profile selected by the --transport option.
--length=<length>
Specifies the length of the mode of transport in metres; ensures that the length limit on the highway is not exceeded. Default value depends on the profile selected by the --transport option.

The meaning of the <preference> parameter in the command line options is slightly different for the highway preferences and the property preferences. For the highway preference consider the choice between two possible highways between the start and finish when looking for the shortest route. If highway A has a preference of 100% and highway B has a preference of 90% then highway A will be chosen even if it is up to 11% longer (100/90 = 111%). For the highway properties each highway either has a particular property or not. If the preference for the property is 60% then a highway with the property has a preference of 77% (sqrt(60%)) and one without has a preference of 63% (sqrt(100-60%)). A highway with the property will be chosen even if it is up to 22% longer than one without the property (77/63 = 122%). The overall preference for each highway segment is the product of the preference for the highway type and all of the preferences for the highway properties.

Example usage (motorcycle journey, scenic route, not very fast):

router --dir=data --prefix=gb --transport=motorcycle --highway-motorway=0 \
       --highway-trunk=0 --speed-primary=80 --speed-secondary=80 --quickest
This will use the files 'data/gb-nodes.mem', 'data/gb-segments.mem' and 'data/gb-ways.mem' to find the quickest route by motorcycle not using motorways or trunk roads and not exceeding 80 km/hr.

filedumper

This program is used to extract statistics from the database, extract particular information for visualisation purposes or for dumping the database contents.
Usage: filedumper [--version]
                  [--help]
                  [--dir=<dirname>] [--prefix=<name>]
                  [--statistics]
                  [--visualiser --latmin=<latmin> --latmax=<latmax>
                                --lonmin=<lonmin> --lonmax=<lonmax>
                                --data=<data-type>]
                  [--dump [--node=<node> ...]
                          [--segment=<segment> ...]
                          [--way=<way> ...]
                          [--turn-relation=<relation> ...]
                          [--errorlog=<number> ...]]
                  [--dump-osm [--no-super]
                              [--latmin=<latmin> --latmax=<latmax>
                               --lonmin=<lonmin> --lonmax=<lonmax>]]
                  [--dump-visualiser [--data=node<node>]
                                     [--data=segment<segment>]
                                     [--data=turn-relation<rel>]
                                     [--data=errorlog<number>]]
--version
Print the version of Routino.
--help
Prints out the help information.
--dir=<dirname>
Sets the directory name in which to read the local database. Defaults to the current directory.
--prefix=<name>
Sets the filename prefix for the files in the local database.
--statistics
Prints out statistics about the database files.
--visualiser
Selects a data visualiser mode which will output a set of data according to the other parameters below.
--latmin=<latmin> --latmax=<latmax>
The range of latitudes to print the data for.
--lonmin=<lonmin> --lonmax=<lonmax>
The range of longitudes to print the data for.
--data=<data-type>
The type of data to output, <data-type> can be selected from:
  • junctions = segment count at each junction.
  • super = super-node and super-segments.
  • waytype-* = segments of oneway, cyclebothways or roundabout type.
  • highway-* = segments of the specified highway type (e.g. highway-primary to display segments ofprimary roads).
  • transport-* = segments allowing the specified transport type (e.g. transport-foot to display segments accessible on foot).
  • turns = turn restrictions.
  • speed = speed limits.
  • weight = weight limits.
  • height = height limits.
  • width = width limits.
  • length = length limits.
  • property-* = segments having the specified property (e.g. property-paved to display segments of paved highway).
  • errorlogs = errors logged during parsing.
--dump
Selects a data dumping mode which allows looking at individual items in the databases (specifying 'all' instead of a number dumps all of them). More than one of the following parameters can be specified on the command line.
--node=<node>
Prints the information about the selected node number (internal number, not the node id number in the original source file).
--segment=<segment>
Prints the information about the selected segment number.
--way=<way>
Prints the information about the selected way number (internal number, not the way id number in the original source file).
--turn-relation=<relation>
Prints the information about the selected turn relation number (internal number, not the relation id number in the original source file).
--errorlog=<number>
Prints the information about the selected error log that was stored when the data was parsed.
--osm-dump
Dumps the contents of the database as an OSM format XML file, the whole database will be dumped unless the latitude and longitude ranges are specified.
--no-super
The super segments will not be output.
--latmin=<latmin> --latmax=<latmax>
The range of latitudes to dump the data for.
--lonmin=<lonmin> --lonmax=<lonmax>
The range of longitudes to dump the data for.
--dump-visualiser
Dumps the contents of the database as HTML formatted items for display in the visualiser web page.
--data=node<node>
Prints the information about the selected node number (internal node number, not from the original source file).
--data=segment<segment>
Prints the information about the selected segment number as if it was a way (internal segment number, unrelated to original source file).
--data=turn-relation<relation>
Prints the information about the selected turn relation number (internal turn relation number, not from the original source file).
--data=errorlog<number>
Prints the information about the selected error log that was stored when the data was parsed.

filedumperx

This program is a modified version of filedumper that will dump out the contents of the intermediate data that is saved by planetsplitter after processing using the --keep or --changes option. This is intended for test purposes only and gives no useful information about the routing database.
Usage: filedumperx [--version]
                   [--help]
                   [--dir=<dirname>] [--prefix=<name>]
                   [--dump [--nodes]
                           [--ways]
                           [--route-relations]
                           [--turn-relations]]
--version
Print the version of Routino.
--help
Prints out the help information.
--dir=<dirname>
Sets the directory name in which to read the local database. Defaults to the current directory.
--prefix=<name>
Sets the filename prefix for the files in the local database.
--dump
Dumps the complete set of data in the intermediate files that are written by planetsplitter using the --keep or --changes options.
--nodes
Dumps the node data.
--ways
Dumps the way data.
--route-relations
Dumps the route relation data.
--turn-relations
Dumps the turn relation data.
routino-3.0/doc/html/example3.png 644 233 144 241144 11541143732 12227 0‰PNG  IHDRôA^#X oFFs6È *8 pHYs  ÒÝ~ü vpAgŽÌdKž€IDATxÚìÝu|KÖ7ð_uÅ•¸'ÁÝÝÝ‚»»»»»^ÜÝÝ!X€B—±®÷ž»ÞÝ}vŸg¯Àå|ù|vûöÔôÌœ™žœ©>UÅ@!„ò³Ú(M¸…'j/Å2…¶×²ÎA—l,¥ ìQ¤¿k–Ýäi=t®º¾RO>’ÃtU4» côéçs¦l½TìqÍÃ'#Ǫrêiké*²[¸†‰0G TæWÑó1q"0!SàɃQ!„ò“r… ,Q Y84Àù¶õRËâ}7”i^¤|¿­¥'z9­r4j¾M_×8I{Æ8ŸP½B)ôfŽŠ‚Š”«I±ÞIÅyÜ za\©ˆ‰6y/ì¡›ËjHxo~É´Ÿ’xò_ ÄB!?Ÿÿ?…3l –êñIü±Üij€“Õµak*5 ¾ÝÃ7¤…Ÿ³M Ë󚣆²¹Mµu ÷$w~UÃÍz«œ ¯õÓ³¯ÌŽ_ü%yú¢Ë“#v]/S*Á˜,~›,ùI빑«0KŽ\h¡ƒFJàÉŽwB!„ü¬4P@D.ô0°ýÈÄuö„DŽ4“B]¹a©d¯Ž.ël*Ó¡p`‡îÅøÖVPø°[y’6^o>±›¬ŸÊM©7t5&ð »ï¿÷z¥Õ£‘oîß‹Ç'飉UpcUQ“»s-J!È‚Œ ÑÛBþõ–B!„``ÀÁQÅP¥c:±šì6]šÉs£Ü°rC¿Rîvã:W­r¢^¬oCçlŒøY8«­¨Ý¢ëË"1 ½U©æ5MÒFfí˳ÛQîéÅwáKn-zî–<:­¨|ñ ûÀŸó±<±Ç „z)}'ÿ %î„B!ÿŒÜŸŒB ÖŒY!—¯ãÓ¥ÓpÆ0Ø`'Þ4Ù[´®ßª1®•Ò‹•¨ìÕ®Àg@Z"is*èjéi+¬Ä‹B9åDEçÔÍ9ãuukn‡GžØ>øQ­èañ)©3öÉ%X0DH¯ø@¬‚'f`# Ü”©Q9 @‰;!„BÈÿD Dha€3Ñ 5„÷ì+H‡ù5Ø# ŠPÑÐÁ1dcÁE£ûTî]|}ÑaNõ¬Ïà¼á°qgî[}3ÃX•‡XTì%6ÒÌV¥ÆtM>™±²Ô]Õ+ËÕÁw>¾¨§­¦/­_.? ÈW¶É8M*Ë÷`*ŽàÌ „B.æ¡7„B!„G®‰·†*øÃ6B8kìò7±­b¶[;Ô®rÃ×ñëGåµKå|Ά^’ä2MÙupÖ›‰Yîp>c~÷ºœÏÙsâ‹è!é­Žwr(ñ¬Ð³ªñʳ¦‡šŽ¹¨ÂnÀˆ;p€9ÔPB„HoÂÏý$„B!ÿ[*ˆ¡ƒFh±ãÄNÌ™]6îç-ù¹‰ÛÛñV(Ë Ò XS¦~¡«67Ì%Õ}Õ¼ººFOi8?§Ù©Ú¬(\(y­lÜÐ/æKöÞªùüÂßçwcÖÈÇaA˜€ælËc÷¤‹<’ûb!Nã À@CZ”¸B!„ü_åÒê;Øà ©P…íÀé C!¹aÐ]çûô+ø«ÚÓ3¤›_ªê*^Ü _ª5Ó¯1ÄJ y’ÙR“ò€s6úDèæ 9‹ÛÜùâÈåúÑsß›r6a48öðþÌe¹O‚Ÿ©_kšÜ’SEü_%î„B!¿ ¨¡D6´Ð³x‚}‚5‹f³ŒKy+þDnR¶ª·ÑuøÈJ•4ÅÐrJᕞJ¦°³y–¹7tµ„6,ƒU›Õ!ªi†m†ãÆÙÛŸ<+ç²r×í3ÏŸã̷ЄïÅ þ á˜h|B2-óôWE‰;!„BÈo-ê\ðбB,ž?ç•y[~£±[nXïRábÞM†¾©0¼XѺáþc]>Ü MË+§½jè!x eT{5‚êUöè<­¾ûžÏ´±V˺Þ~ñ¢ùs]bp²Ü£Ÿ+2ÅPŶ—}`·ŒVÆwÆ8^_z(݇<à$|Àz[~t”¸B!„üžälKž£] "Û„¯¸€ ¸‡“Ü50_U@1HáÑ*"¸l@úȹv¹„-wK°H¶Æ 9¡ÚH½·ÆWœ-6«[¨â¾–ÍÚûvÃü3#Š­ ¾áû<õƒ½1òÿ{Üù¨ˆ ŒÆMDšJzäþw*§!„B!äßPå›f$꣒x‰éØäüMÄ7âq ÎkÏ}Y|Ø©6å8Ÿ3º×!ãªiŽ]eßž´µsiÈÿÎA9¥O/ÙæsïÙ!lÕ„Ï=r¤Ô3~˜Ë0ßöÅ]‹”¦('Ž=Y2³ÇKÓ°|ÿK!„Bù—ò'ÍØŽŽ¨ËâÁq=C—cÖÇ,kLhRãFÉÉ'&8tÚÃùœéáœOšÒ¡ÐƒŒœ›Ù%ïåqÎyÔ;Î9O àœóE†eþ "͇+˜h#M±Q˜ÄRð ÓÑßôæPAIoÈBD¼à‚OHG–ivRB!„òÇ WÎàâ°“± ‹Ñ é‚È&f,È[ª[rýõ»Í‰—÷Z¾8gPX*Å|«Y šYºec«gëë«ÇiÊäÍ»Ÿ×"ÑKÒó¼óÒïÄF‡ï°x™[‡[YXXß¿JÍæé5rjûc .ã>;‹·ØÎÞ¢B¡ÀU !„BÈŸF Dèa€$¸°UH•>ñ°:¬G¯J•¦,Ð×°/ódfÑÏš”W¹¯ËD…ÏݽÌi«xS“<`Så6Åïu,Z4ÐÓÌF%ûô\[D_ØXUzÌËi6(7‰+QHQY¬³åë‘,«7ï4|ùfÏô§Cb.|vÏÐd™jâ |Å6þŽù£ wâ©(bznòuJáÿx¡ë=V:÷5½ .Ø…9B!„ïkÊDlÃ6ô‡›w—;¶E²?œ‹ìlx1f–ó]ǤMï™^9Ð$ÿ}ƒ[¸–wx·rv³Â•¯d՜ܾË.Îg/î©“zO+ÙuuvãI9Ÿ¾´ÛÎçv¿UzØ–ÖÓÆçÔÈ+™n•¦™©vÉ4ÅJ¡/‹B&Vb‚i—”PÐ{ôGƒÔ.MË¿‹L9‘~ ÇB ÇU,ûuQB!„ò‡’‡‡ZÁ 6Âq¡8c¼*?ŠÛ«&{\sYÉòÅ/ºä°ÇÜ+V'žÉ¬Þ{ú‚šdWÊ»¯SˆÍ„06˜½æ'PèÓÕ¬Q¹MN]|•¿õd6hÍ Äd9œ·9d½Èr´Y¼Á\WÔ¬MÑ}ÔWr>`ùÅlM¥ÿ.×íõ!»ü‹Å6âθfisn¥‡çµÔŽÇœÂuv1ØÆ¾ Êá #YÈ¡­¿»Y!;ÇÊÛ,†9 †bB!„òçW Ø~XÃÊûÅýSFÇ‹g†LÔ]»ÔepUÎïŒåÛ3®ÑŹ=Kccgºó44E5a$k#«%è’ÿÈ%"ëbÏâRái»¾É¹0i}g')fÚÞnvœÏíÞóUÏaªÖ}ÇÙUïT¢E1VS,fó²õ¬:k‹ø&‰/üÄe–cùùõT*_=éÅø‡Nq>§Z¯††Sçwm;mÒ«Î%¥'Ó®v+Éùì¸^novXÑvú¨#UCw»Ù6µ:•ÿh‚€¬ìXa$}ûò(…ÿ/LkU׺¬«)ÄŸÙ:V™bB!„ò‡²‚9Tò¦0–%°@æÌJ²²—6-¹Ð¦&7Üø0¼4ïxkõˆ–7¯Ôµ›h>J³Bi5B=Vϰ#þ£Gòõ÷@y³jØÂ,Öžiò7,èQÀÏöæÜ°úŸÊå¦ ™`Ý©ç³5=r>}~·-Ùí&¹wzÎùô݆s>ר;ô­Í§6w¦¸×®[ÆÖÞѯ\ƒ>å¾o6:¹ýiÎçÎ Ÿgì3õF×Î9Å'5íôœó»á|Ö´žUß/Í;xªjÃxµ²÷²Öó°ñëXO\ÆJ„À ¦îcÓÀVò?Ût²åÀªL›ÃÞ²þT‡D!„òa`[Á*à¦&”c í3mBÌï]_µãît3uøÎo 8pÖŒf“MwŰÔTÑnõ9-£"_™M”@ÈŠ"‘ÍÀaŒÏß°`]§êöÅg4¬³¿L•Äsãzu<Íù¬á=+ò;ÓƒºÎùeÒ‚Î*ã¡iv]—s>w]øö7G¬h;abVÍþ¥|=,™oË4q;˪±ÌoL»T¦žrÑnïÃv®5` +X‹±‚’Í¢˜B!„üîäÔTÂuÁ™••w·XëqPCβ1_µÎç— ¡­s-p¸mé:E¼]oã"Ö¡Ÿ%fµ`ͯ6¿1¹2^ â1 Å™ìk“¿‰‹™u5‹MÓ+ÕÉ+£ÿpvô‘öµ8ŸkÞ“óé§»Î::ñZ§ÙœÏ(Û݆ó9z=›9ªS»ÙãÏÔô+ÕÓõ¶õC cþ£‰cY †˜ŠpT„Ü)…ÿ'NÕì”SÛTc$>dïYWØÀ Š !„BÈïÈfPb. 6«…<,2»­±Q>x·jïÖðã”Ë/9¿7zTúöm­¤³šl&Û%l¬"Vc,šÿîÏ0O¼Ìa.tfm˜ ËÆ#ÌÌßÐ#ÕÞÌ:~¶m=ϲ³ßž9©/çs&÷ºo<:­H×ó¹Á“Žwv’vM;ØÍŸóÙozyÇ ]­ý•±›ª= {ïžc×Ñúhþ£±0 E9a%ëÇÜQžp3Ý üôiü•v=«5¨ÏÔìà„ƒ¨‹PlG?à£@!„òsóU–s¡ë)oO¼ÞuW…Kœß~=²³|uðÐò)GNîêÿÉã˜Ó:ëµh €Il²ÿ„çœ`kCG`€0œ5cß$Ó•lYmZ²rhÈž÷ £#Úâ|ö^•9Ÿþ±[ZVìÄ·¶ñ¨iñÝTœÏÝßlÖ¶ËŠ„¦=+—÷…CE›³ß„ê1{ËZ²Qxc¦]æ?ñ<ñ÷|úF7yj~LýXí)ïaqKèœ"„BùýuÙ æÅúˆ NÇí†ZL|[nï©^ {®/6ƒóÛFœ[9mX¥Z3äöì ‡÷¦;«¡ÄŸ½öŽŠ_Ÿ[‹4\;³u¬`þ&Îݬ'XÄÍô¬;¤¬æÝ´‘ÚvnœÏ[Þ»“ôbÚè®Ñ9e&µîô–óéún:Îgi{ÎKÛ51µsêÂZ 'Vè\t¡Ë-‡OùÆá±½ˆÃtCy„šnøy¶>÷<­e/—6c­jÁ ˆì ôx@§!„BÈï¢9ª¡˜Ð‡]@мcÞ ~Êj39xuLœ~ãÅÆƒº%{žì3€;åÚ×°ˆc¡øˆ¹l4óÆ!XÀ컚H19Mu{Ì€;,éØŸ¿¡/"lÇ&W÷+Q>¦þȨvÓ8Ÿõ¨çdΧí–stҼ΂~ÙTÏ.çsöÒ})0~Z§aË®7¾[ñDA'µý7S– 3XF³žÌôK^ìé¯]NóÖ|Ĥ¶üßH°ob D!V• tNB!„üÆ,a›ÈüpÙ8¡~çÜ횥ï93e6öˆIœ?*6vô¨í÷—™Ë&³ÊÈPøˆÞì!  ~€×¨4•10ÜÅxôP@pd+ò7±hþ^óedfµÚ%ÊG?>³ÍXÎç< ¯Èùô}Ýve5œx¬Ó6^mÚ’®w9Ÿó*Ü!%tüÙNêeYM2+W âxÐveþ£‰ƒÙ ÖK05PžØúW“ðz¬m‡ÈÖî¯LëZ [Ø$V‚Î,B!„ßL¾I…©ìó¯%%;KO m¸—óÛö#V]o1¬ê;½ó{5ö\á¼Ê¦5»Ãš`§¶ì‡ËAÿ!uJ²*Ð GX)<ÉßÐaºåHóm“ž×L,_lôúöÓ8Ÿë®’´Ób»5Ïõt¬³‡aîÔm]»s>»_Ïe©O&±.-õi8ª|ZQîz¦€ó7›ŠðâØ2VÃQ•LûÿbeÙËצtN©ÐÕ÷ [ª)ÎìëLç!„BÈoKØ*X³òv©3AJ÷V9æ: ÞÀ¯ÔÎù-i$뺨þ¦àѦö—WVë×;ÿ°}ÈÖ ”†Üñ £ÐAhÍj|»Ø“WˆÝT+CŸØrÓ‹9½4buÛ¦œÏV÷¼Ìù̲ݿd§NjÐ)ÉÐcj½.ÙœÏ+žðùö¸›¬jÜ̳ò-¿Úom‹íÁÐb+; þ·"p ¨ øûâsÊNíÚmy­M{½ºË{ÄÉ,•M£S‹B!ä7 §¬7± }ÅuÂ)6ßl©ú¥²ëáÓ³ 4ýÀùÝ£Úw_«=tê}ïõêŽÁ’`]Ù5ÖwPÅà[XBý—Љ”¿^`ÕqëÅìk–¿‰u†Y3uܘºÕU%–=¿<¤B+Îçv ?ÎùôòݺeßšT©Ógî=íL7‘óY{vÊ85ٲ˩•6M/T*‘â±ÕiÜ7oÂXœÇ\v)8Ž…hê¦~¬­Æ±3{Z5Q´†ïFÓóO¼Øv:Ë!„B~j¨ „pÖ£Ñ!•¶§x–”„ÛúQ'´[ÎE 0r~·Ü¨ó ¤òÆ€þò„K‚ 4ØüU[æOš‹Ã ®,žið@pb 'ó7,PÆj©Åœ¡9•}C*DW1²íÎg íéÏùŒîMsŒ“6vVêFLY×e'çs²zíÏh4Ù¶Ë©µÛ¼¨Ñ'Xåö¥À¾üGc}1 å…Ol«°‡é¹:ÿ{ÆùœáõÚuY0[Þ£h$4dWè,#„Bù¯È“6zÃv¸Œeh ð¼â²Ü§íg¾êúåaµ9¿9rÕÅ£K—´m¯ÊV~Q|d˜v±rÈÆ®Ÿ.br%º\4PM<'hØ7CQm&›Y¨ ˜_±dðÒ—k†niõžó9iá8ŸY£ûͬßu:gœ8uK×âœÏYØëfÆÝI}:?ÛîÚ&ºÆœàGn æ?š°UG"«€˜:„×w=°•¿™Õ;®{õ’>GLÛ% b/è\#„Bù?þÞ—,l”¬ª¼Ý¶LÍáA~œß,5¢„qöå¥C,s–]¼4¤u• ÐE^rÑZèÂ~-óø9W •ç|ýñì8»YUÄåohs×|’&ihŸJ¿ç=‰\½åÎçÜï•ÁùôÝöçÖÕ¹²þÈÔ°®¶œÏ:Þ30S{v[·ÁµE­*Ëî÷)çúMm(¥hÃ~au1 MÿVNóý lå|á´¾Ýúµ+ýµ°»¼Gé$lb™tÆB!„ü7Xo抓ì$kŽ;fCÔG•}¾Ûø±ó`iÇ­–#jr~óÄðE§Þ,¨ÝRkjˆÕÁ5ÓU_Þèçâ߆µ!ð€3n ?š >̱ù:–·ìbþ±ìÉ¢«^M6±uç³¼{æ|æus MêÚ)G÷jÊ’.S8Ÿ^&íÖ¤Å]üw¨Ú†Ô84Ó¥£ÃD@ùhBA<ÁÁ‰•ùÛðÙïažxÎdõ¹2æX‹àMòóT`zÖ¾p„-}Z!„Bþל᱋0ƒ –wô;ÙÜ=ì4ç÷÷Œ¾­;wþåÀÚWÚ ëê\ðˆs³À-ôegX3ÜÉ?q$ù'òlõÇA,T¬º±;ß4骪©\<¤]¥!›#® òo1›ó¹{ÃS9Ÿ~£Û¹ìÏ“ÚuVL½ßµ ç³ö4Ë;3u|·r›w´Š¬–Y¶½×EÿüGc°ã ³Æ}¬CÔ7Ýð‡leœÏwè]m®þ⽈áã œ-u¯¥0Šé±MzÈ0 ‡×ô !„BùØÂæƒÌE0󄹕¼”zÅÃÓ6tÚâ³Äm³åtE[Ë«ê+Cvš?ô|pÙ¤Kk„6ìR¥¥Oü6â@‚Náü—ä~x”P²éx†Ýo(¸34—Ú-²hÆ[¿(Æ}1¤Oyÿ¢k‚ʲ¾ H)RüaºR†ÕB˜Ð•Tuшª“¹´É†ÊoGî‰×®î~ßåµî¶Õ;ׄc¦‡ FØ*6•µ3FñÚüd 馭z!ýޝšó¹Ë•k2›EWÖ™v¥¡l0 P™>„B!ÿ‘|ý¯‚=[Ž/òöä ݇T|Âù]qäGc“+k‡,LypêË€wÁ¯.:Â^ €¿è.ôaã)„¿AüåzôZ(†Bâb–ÎfåobÕ]ý^5®p…UÁ.ÏÛ ~Õòç³ÓzÝä|æ„î Yº‰ºN†Sº<æ|ŽS¯Þ9½¦tìÚu÷ðö…k-(UÝ3Ô) 2½Ë§Y=$³Ñx„­hŒ øþm`ëïÕÏùÿžïwo\k óa½Y¼{ÑMé3@!„òŸcm™Ná F¢„Û…IÖï?Ÿ=Ó7LÚvµùPsÎ﬙¸`bÿÏÕ›Éí^bð߯*¡ø ¬îù'¿``PCüu„[ƒÏ¸(b ˜kþ†æÔÕbÿÛåßKЏ7(½åBÎç| ·å|FµîòöMžÛù¼®Ü”Þ]†s>k_\Ãõé{»?ÜÚ¦u—êÁUÏ4õˆúæqà «³«¬&£)j˜ö+~Ë)&€tŠKÖP?WE‰×Ä]b]ƒ— £ìéÝ'„Bù7ä^ÖøÀUü 8±BR OÅ”îm^–\èdçÞѺ¹±gæ…<–>ñK³ìGóÄÝçïþ‚(ìF?Ãmcï†þˆ†ÙÈ…žÂù_‘‹g´0Â('ñ¼?œQÓèɸ-Ž +ê £Ù]lÌñжԺ¯Æm{M¯wœÏìÓ=!§Ù¤Eý …¦úw‰â|Vµ† Ó{u?¸Åغ_õæ•Júú¹^ÿæƒQ«1€i™ ·°½ÐÌtÃÿi`«ÆãQÝê“j†²µò–0”m“KêYAØÃŠÞ_B!„I%D9 ã£ø#^Aè‰#ãó:}-bµÇ✬ j˜âÕëQO’Ûn½}ÚõEfƒ˜Ë,àŪ!:(<èa0•Ó¨03 ۥ˼›ŠØ+X‚ã$Náfì~÷èäë"µºmézf[Ëî{†].x£úû¯]Ì«-”gÅWŠ‘ŠÙ:mý5C?ƒ“Á§›P"Î?û’}·½õvý²¶}õš™ýü‚܃ømôÇ*®æ:T@(ŽãˆÆn±ž°† lLÏê?^±U@Wò&–ª +ÅDÁWøµ„ßv° ÷—B!äŸ{KuÐÃÈÞ²¡øÀÕ¼$ú”´-¬t]ÚeoÝj…m‘9uõõ„áÊbß5£ŽÌyr)U“±3Ç(¼‹±z’–âÜTÚAþHùc®ƒ:> ÅÐNÒA‰&h€3¸'d°¬‘!Ô0×°çÐÖgyo µ:o}²x«vû¬®™ß,þ~I2S}RUuQGin¨æÄæäå­fO¥óFeÛ>Á¾¾[/;7®Ul߆ŽMj,ÛÂÛÊ¥;ñsy¾IXÊá Š»ØˆÖAAˆù–yú}ñŒ×˜6§ë«Oûòšk„ ZùéÐÙO{2kæg½p+øFTà z !„B¾!ÏÒ­PQb»™VÄ•ÜìÄØyæ-Ê5ô©²ßïÒ»""'Æ„¤U*¡ /¿ã¤¾—Ïðw< {0kq–&}üîÈóÄçBsÄvÌú²@öÜ8“—ã¿ü­•ÄÚ·K ½^0±÷ÝRî;«7õâ207ÕöÕ6¸ GY*»¨LT¹)¦’Œ_yú^õ‹òq_6:<<õéŠñÍñ-LÇ*¢;Íšñ-<c°çL[ ù¦˜4–˜z¾k»Ì[“GtUxܶYjaúð°YxˆôÞB!„ü+âAá>3%s š”ïè__[åF‘áÏu.,T‰ó»Gé[ØU]Th‰Ü†å±)ˆ7Ý™ý©kp’ÿYþwÆfPc <‹€W¡G8Ë7šUS­Wæ6y\t¡_›§û.mÉKÌ0ï~óÙ%zÎÌÝ;Iê\//cò™Îɜϭî–=xJh×úü;.«ý©L‚÷(—Ï.1µéa3p }…^¬+s"¦ .00…TMø³ŠÑbŽxÙ°q¦§èË_g©$„B!&j¨ ÀKìB?©‡äÄo Ù $Ø®téRJ'a$«‡ëf9ÊÙW²î”‰·;ýìŽ"F#4`»‘#}ä*Œ„J( …žªÛ¿[ù¯ƒd ZLÃyÜçã DU B]TTª³ý¹Wt½õfÇÂ^ Çð¢PÌ¢vÂúÒ§@ÉÈ‚_«}ñá²`TæÈî•ç¨Þ'Žc+Z~ Šõ l8Þ£Ü>å«êï‹­z{gv¤çMëwM>®5ÕòlGUø =ØMlâ¾硳˜2·Ë>Îg ê‘W¸cŠÍMù²óˆÃz×!„BLòõ³hÖOåíÎoêÏ ®Ìù>£Üu·/th0 ¹yldãº6emüZËmÅ*,Bø!þý³À|±37f…[H@7Ô3½ãÕ —f/‹Uôë{Í¢š¼ä|fïç9Ÿy¦Ç8mÉk;ŸÈó˜<©óÎgçöbÚÓªt·øe`û5/Ö^]Xô1ûLJP0Ç[¬ÄuǃV[,†™n1ÐP B!„|äšã¶hˆò,pU?TÝQÚŽܾC‰ü’þ€A©,g™§s.ôF‘ÕÅaNÅ6÷ 7Ùrƒ¹ÑÀ+ÑKÆ¿çÉ<1Yú̳Q îØŠ3B6ÛÍš®¢ ŸŽy~3fm­›öžjаwÁµ×Ç_úÒG•¤Z§l ~¯y¢Z™k•Û-ï‹`. 1Žo»"8ÏwóÉ­í"«Ù_± i¼º~­Â[¼34~*kå\²a€8ÃÊ¡–yÍ`#щj®ùXÀÌŒ™13¸Á nü.¿Ëï f03U¥Iþ6¬„BÈH®G×ÃI‘ f±S½q4·ëɹ¿_hyÁÍŽVÒôœ½Ú‡ð0¬æ®o9zû„ÁÉ8RªÃÖ±j¸‹ó¸…ÁÈ¿ ¹®ENåÍ „B²àø1fƒ­˜.ta¾ì‰ÎÎPÕpð0žáÍ»Ãxvðíù¶CBf,êm(]«uL¿$—Q€Ô×8J7-7]·Õ`„¢ê]ïA&V…ϱZwϵxk“Ø÷›ß|öC-†š ¤øò¿ldódžÌ“ùSþ”?5¥ì2JÙ !䯃ƒ UØEæ`¬/Åòý.§ZæŒÐ~c©ÆЗ3p±šemõêýþW»Ä´}äôjdb$ašóÁü&*˜zëÉ_[®ižx<Ý0Ù¸•×ã'0 µPš=ט3¶rÍÞeOTÑí†n—Ζk³½ÿù2çëÇÄ&E 'D¡²jžæ“JÒmÒÕ¿Î[¦uÐÕ¬s(à£kkEþDz;nVY]Àzœ£Èò/™ÃæÈArðÏñ¼ÀÆ l¬+ÁÊpÖpÖp6å^ʽ”{(„B(„×x×6Bù!)Lk\ `ðƒ-Œ|Cï.¡uwû<ö±´í¡–a‘û59QÆ„i‘›Ío¶cµ˜ ÙM6„­–DIä´ÐCOáü)ä/6ÏD.´X€«xÌg@*¦­‡…Jlc^¸î†¾Æi¼º‡ÓxÕ% J¹çëׯsé•¿4J,8ÃÝ „(«Uç½×]ýæ—ŸÝs³ÓªCmBþ(€ò¦pM¸&\+>­ø´âÓJ¼)ñ¦Ä›B7 Ý,dä–h‰–0Bù`„Äna¢TޝâÜé…}9K‹Igº,/;Áø*csÞ:Õk'³{»œO xþ*9Þ=¥¡PšídéÒTÉ‹¿Gò(eÿÉåå›Ah5Îá–áƒtƒ×`nØŠ©‚Óà&«ŽmuêÑË2ïbïÜ~ê¬sí˜ísÎw=e½/ñŒjƒb "ù›w›-š0ÕlÂnŠ/!ÿ ;ý.â".êVèVèVðkü¿†R(…R¦[³…, !„üäžv#$,FÂÞqéOŸú®»Y…–Î6£U{ùÝyû¯ª¤^Ù'VXêýd/sÆlÔà+ùC C&^!‡I¾‘`k"ºa*Wqfà2ºÂ(Ìc™TžïäªDOyKßNª^ñ{é6è›w›Ójg%ý"$äßÉ¿d†¬`Å겺¬®Ð[è-ôN˜œ09a²éV!ßòÅ„B~,FHàbWa=[/-’üøûÖ…œ\âÚ/ªË ­0ÌÍ+oP±†ªåðEï÷.yäôæÍ‡V)óñ€Ä/R&ïÃs „"’üKr¯…FÓÀÖ1|%…½ÑMÀRIi¹´çòˆ75>ßô¸[÷SUÆPŠ"!ÿw 6 6 6BùáÍF_Ô–¼ùBþ…˃,[8‡³]aßÈ,Ñp;óQÞöDÏOÕ³¬Ö®>²!" 9pB?tFœ†ÔP"Z*’!ÿ¡|[Qó±Õ¨â‹¹sЙcÐßwnã­Ò*òLÿm„nº3ÍçNÈLYYYYY95 !„Œ"Vˆ½ÅD¾›£Q‰>…ʸ†uM¯Ÿ[d‚nYªEÎÕ[½¹qqáuîw²¾>ÍX•{\!¤1f4“¼ø1ä"šRvò?ëÖÁÆá$nrà$n~Óãn9K™+¦âÊ V0ƒš¢GÈÿúŒ“¸Äi HBù1YÃjd Z¦g×Ù8~ŒçñÌ™=bËOcïÅCÐ*}Ì.+ƒ¢Ÿ½Þð%zSíSnÏ¡ fb­Ôœ¿ç'QѰ¦@’ßÃßw¢ÕrÅfa)žÀᨆÄS_;!„B~"ȆVüExÍnÛI…x…Ú—ËÄû}ªý²üŸ逶¨¡—kö\5gQëkŸ¼L“‘››+$²,@ZÊ}¹500H´=ùí ( w8<ÍÕQŠ—¢½ê„b®˜ÉO¡&bZ¢…‰B!q `­˜vc~ÁIÛÍV%5g&uì<§ô=Åye2{ÁN*Š ¬z®þ\uÓ¹ã"4,¯1RÊäC¸54PAA);ùý( 8CÇýy#åÅ ñ‰ÍG³ë/g3Çfç°—h‡z8ˆ ,B!„üeYÁ*6¹²ÍÆ¢Ò~¡î—2¥}ÞUN¨á»PÛ(yHæeE›Êæw&ÔßðìæuÃ@£¥”+,.±«¼®”ËŸÀ F $ùýœ âEy+•¥ØW¼j7Ø,TÓ `XV¨Ma"„BÈ_–*ˆh‰ê(*¤1Ü^¹]qUÜ:·xoC¥÷’UÆŽÜcêv)æÁçl¯oŒ9yù壸xsá´`Ï*óúÒuÞ óÏÎMÈïCbÌ•9 9wUŽx_˜o}جŽJB%HhÍæ²Æ¬§O"!„BþzDŒÂR!—•”l¤p¾qðØVJÚú¬÷¬kc&ùió ¡Ùs3éºLQmîv+QßÚPÄ"脺¬0×! ch>òÇXœ`Çï¢%§,'^­]ÕCUL·OGm”¡0B!ä/È ’МÝg¼–´¹ZFˆn±"äž´]:, cÕŇB/¹GO¹7âe‘Dö•G¢¤’Îò ¦ºvJÙÉB@œ`+ä-1KYX¼"äZ[kú*Ê7³é¨…0 !„Bþ‚* ¾˜Æj@ÏïÃÃûŒhr!ä¨ïÿ4ûK†¹“ôò¼rûoM¬·iÿ͵Ì7ÐGq/` ÈƒŽ–í  ÂV<’à+”Þ¢J\o•¤2*˜` «ˆÂ¸B?$ !„òb+hX(ûˆ9| Ïä™n‡÷ZÅ *ßò|èq½{Ú„œ/ªûn–Ïç>^ä–êÇ$ûŒÑÂ8!–åKà - E%,þ°…ÿ„‰ØÁ* ®l’¥¨Ú§PÉ7³¡(…‚&B!„üE¨ „ˆTd"Åã ëÉs |œk'ór›œ1Ó‰!ʳ"K</µõæI§2_\‘Ü¥p~Œëx#À1\ÇkÐ@ò‡;Xòh>»‘)8 ƒ¬V*׉¯M·D)øS˜!„ò¡ƒFa"Kc¥¼*Ï.1¥PŒkD© ĤW¹Ÿô á”2Ra¹æÉQŸç_¢×¼_™’%¾²:Ò4nËoC„`ŽJÈJDˆXϯÂJˆf‹,Z*¹ø +=P.è ÐïJB!„üðú¢5*’0–=d;P‰­Ô¡EÁkæ‚}ó9Æ_2Ÿæ&Ç‹N¤OX¸cËÝɬ²amäROþ ¬aµ¼º*’üñìj!€E?ÜØ–j^Ha+dÈ7³(ÇÀÁ)g'„BÈÍ æP „[Lell<$õ/·¬X)ñmw×Ûä¥OuÎ^¤Ìµ=b¾jVŸ%›®Eæ¾Ò2ˆB.«€Wü>?†aÈB. E%AC åv†'\(aUY™®ìŒ('†1|> ÃŽ,B!„üÔPA!Ïÿ"ÙI³¸OGY,žªî¾©ü4³NŠ ¨©X`^L±ìù×ϯ~I¸¸ôÕK†$,æñNÈDôT×Nþ\BFývã{!}`ë)Nje5ج‡ø‚/H’ºI=ù/苪(IÁ"„BÈFƒ:„æì6sBqtÃæºÇÊNñW«héÏ–Rívƒ¹±/ˆÇsCw&Ý«q2{M^œ°TÈcex_ {00ªk'úÇ9sµ~¥a±p÷°à½ùi+_uUŽÐZØ,Ü’:¡?Ž¡#J!ˆ‚E!„ŒΊ"뉷ÿS”7Y…S¢«.­ç…y4 TC¾wBJÇœ¹øÈòX¤d…PL@Œ˜È6h†‹6B¶©UQXAI+†B!ä»#@C+ÔFiÈâØl Ãc¶zvP¯âÕj{a™ (Š+â4ïJ¥V^»éؤ§ l/+¥Rã'þÀtêk'ßÿ‡]o|Á?ÀÝxU*)4d¹Ø?~˜kíßXN4Ÿnú$7Âr¾ –PCE!#„BÈwD‚.öV°™R)?¨™]j¸·YƒQU‡ø—Ö§æøë>°âjs¥~rÑͽîŒú²&õTÖF´D3´áw`¦ÔŸïž …ä%Ê;JgÅ:Œ³ýãökÍÃ4uM­:ð­8 ¨(q'„BÈwB.c%ºIó%? ÉÃÞ·~Z²¿¦·ê¥PU< œ.ÚDÚEN¾}¸âµ·¯ß²9¬0ŽÁ‡·Çv˜C%Í!C~‚ö¸ÑRòËyk("-ú0+v^ÁÅ>ļަ…܆·Æ6ƒ%ÔPRÈ!„ò'“Ëw 0BbÖìñKðÃúæbÕu…K5VÅxϼú±á)Š\㊇æDôÂ,ÅR¾ƒwƒ?¦Á·)äG'à87“ædši{êîÂQÖ‰—áe0Ú²¡ò³¨òØ36ÛÔVC‰;!€d"SÞ”Â%½¤—êIo¥·|™¤’TÆ_Œ Œ ð÷pÏta—RvBùo!A¦²tVÞ%5àÜ/Ød]¥cdí„B»Œtk ñl­ºrÿª‡½ž^y¦}»òóHæÈ¾à4Ûò«PAIUäÇ'@5Ô™ãsOk]Á ¬‘Êð’|¬eSårqnÁœ¿þ[[ÆA~v"Dˆ(/xÉ;T‘êÚêÚ*­f’f’R­þªþjVÖ|šù4q ¢ž¢ 0À?!ˆ‚G!ÿG}ÑåøHŒäSàÞ8;:¯Ct™ŠžE½»Û]â} IR“¤_¼³ã–­Þ“˜€kŒ1X‹K0ƒ 訮üȃÚì›úlÀ_‚_€Ã8¡¶w±‡V×Õ+ÕMm¢8 RÈÈO‡™&W¸ÂU¡P¾Q¾A?tG÷9'÷ßW|™î„ó ç±×öÌÙ3çæü{?ì|užÿ<|À¼QÔQ¶R¶ú'G#„ò?3‡ V„Åb2¿Â}°Ìo¡{€Ý…Þ[š,(š­;šž=CáeSܼò ÷­eï.ü¼èë´ìËbSq&Çq } - Hò×`*}É^o°’îó`žÀ&Áì«Ï 9v²Ü`6KnÃF¢6ÊSÈÈOGž2ìNáüáÃsý ý ¬Ál±ÖØV´­¨1h^j^j^šß0¿akQÁ¢‚ò˜z˜zã4N³óì{€fh†f¦£É=÷„Bþsh Dò``÷±™õ@#LÀé)»êË/Ðì3+¥Øªl` 5¥ìä¯Ç”¬dŽÓ½Óoâm¤3¼+V  ÅYûj«5[¯>%·aÝP’¡‘¿”ü³¾lÃ6lC4¢èBŒ#Äøºøºøº„Ö ­ZÇ“y2O¦¬;®;þÞìãˆ#¦Ôî1¹ÇäÏú‡o¾ÆF%G%÷Kê´¦Óšá Î/8oktdŽÌo²ÏjŸÕ!;Bv„ì°··GGtDG\À\ÀvlÇvÓ˜ü?!!äçdk˜ ¥…Ýì«LJs¯ S‹}qû¥é’šMkéf¥ÉýÌDåEÛ‰¶›¦ÞÒøŠW,”½gS‡D|E:² ¥@’¿ž_KeêévRôÎÆÒ$ÑÀJA/„°~ì­BÓMUÀT\BW”@öâ"(p䇧†jSŸw8ÂŽæhŽæX…UXåôÉé“Ó'ïýÞû½÷Û–±-c[F –‚¥àÄÞ‰½{ÇvŽ;.3%S©Î­˜s2çdÞ±/U¿TU¯Ö:i.=9ÒåH—Œ¥Ù–Ù–ž‹½šx5ñjîYÒ³¤£Ñ±¦cM«JV•¬*ň={àý‹÷/Þ¿à]xÞÅ”¾ÏÃ<Ìà ¼À ºÈKù騡‚#$@º'µàJ¬Á4™mî]éƒâ“‘·ÀÒæ…Yɳ‹®™½ûrÜæÆþ7…Ù[6¯yynÍÏ" YL$U¦Ä=ÃV¯ß¢ÿ$µ—(®=ÑÎL€™Í&Í(åI¹ k‡â¦)ð"(pä#5Â#j¡ja36c3¼à/yà©ÕW«¯V_½[{·öníœëœëœ+4š ÍÒ&§MN›———’‘‘ù_QxÀÃi‚Û8·qŠ$u%u%©³ X—´_i¿2óPκœuï…ø>ñ}R£¿fÍö+áçççW`[m¶äyAn›i›i›ù®Í»6ïÚdvÉì’ÙÅôl÷c?ö£5Z£µ©žçûG!=0h¡ƒQÎb™T—»ñmö׸^¤DùŒà².3¤9úÖÆ$m®~ŽnÁ<³Ýíî;ó²º6•À=ã9i"mZb‰¾+É_šDµòrµûõ£zãÅfb0{…•Öê>Ša¦¶­w ù®ýãÏ阎éèƒ>è#¢°'ì {âZ̵˜k±’SKN-9Õ·Šoß*ŠMŠMŠM ‹%,ŠØ±1bclhlhl¨¡¡¡ r‘‹\Ä#ññä Qa3˜!yÈ3U̧! i܇ûpÜÄMÜä#ø>â½ð^x/÷ÒXi¬4V…†RhH±‘ÅFi¾Ï|Ÿù>”A”AB‚5Xƒ5ÿæ•BÈÈŽp„Ì Q|/‰é¼‰O’›Ø„للù4öiìÓ¸@ë­ ´FTA•´[i·Òn½kú®é»¦É·“o'ß–ZÂlÁìÃ>샬`eZ Õ¶°5¥òÿ39¡—“ûb(†bò‰Ì™-2[<«ó¬Î³:ž×<¯y^óêëÕ׫¯ke×Ê®•­ó¬ó¬ób>Å|Šù”è’è’èbê}—ݰ€Zh©žòÃKC2’Y¦Âfý>C cëÖÊóÀø>­cŠ„s÷ŒŽ_[+¬Zš_Ëöu|¾ñµu|ᔂ$\dŸ¥KR  (äg À$TCHæ…ÜYZ®kh`jàû`±Îr©r­8ZÆÇº£<Áñ‰RòÈŸ¶ú¾è€è€˜ònu²:YìýÈû‘÷#×h×h×hu¼:^Ÿ=6{löØ„Þ ½zÇÏŸ?_RKjI øÀ+°+ÐÝÑýŸ$Çù{»ƒŒ`¹ÙÈF¶©,G–ÿ^‘ˆD$Z Z`+¶b«TB*!•ˆCâ>2}dúH¿5~küÖ8Œví0ºÈ¢"‹Š,²ãvÜŽÇ”)S6O‘§ÈS`F`’‘ŒdìÁì:èèã@ù±*l1[ -³}ZUxR·{-FVõuj^rU‰‹Yo´‚!)Å.U‘¾cu§#åw¯6Þ•Ìy–+X²(,Ál¥’Ÿé„I†çåíÈ€AË›Oàú£º¯ä|Ί^«Ï¡Ëû:c% 0cœ ‡laEq#ÞGöJDvb'vÊkšÊ; ÁB°poêÞÔ½i¹­å¶–ÛZû`탵VŸW}^õyEöÙ[d¯Ån‹Ý»¿9ÎìÀ”EY”5íù“32sfÎÌåí‚õ Ö/Xÿ‚î‚î‚îvÈíÛ!nÜ:¹u2µlıFßÜ9ÿ1ë¡êa–a™¼C¬"V«ø)ý”~ʪ¨Šª¨#Ôêå+•¯T¾’ó5çkÎ×¾9Ú]ÜÅ]8ÃÎÿós&„ïŽLñZU@å*ï˜*ny»åæ§Oœs~ÅVׂóȃœs¾øþy\‰—ÛˆgW7MG!Ò7ù¹NšçHB*‚à×ÌšúšÆP 8>”Ÿ3›§²Vº! élŽá<æ°шGþù{¾ÝáwÄ 1è„Nè$÷@Ûž·=o{>¤tHéÒE6ÙPdƒe¶e¶evêÂÔ…© Ÿ> |ø²í˶/ÛfwÈîÝ_ð_L½õ]Ñ]ME)2¹ðæµC;´“7­OXŸ°>!n7‰› ‡ ‡ ‡¹ÈE.šZÊUïùå?æyœÇy Á ÁR,ÅRã5ã5ãµ}Œ>Fÿ´øÓâO‹§lNÙœ²Ùò‘å#ËGE}TôQ‘±EÆ«j¨j¨jhú™±K°Ä´t”||ª€'„|ÿ$Hà¸Ç×ñùh 7Xf®M’.fµ1Î2¤ªîÞd¯QÌãýYš:ÒÚ¼Þ¬)Sb7r›°€Jå©# ùYÐ@‘ø€ÄÌkúåÆ…Ê¢8ôÒu.™¯R Qt7Û î©l†Jx†x6P™Gþ°Oèßûå$õ2.ã2€øÁ~æÌ/˜_(²¯È¾"ûÂÆ† ëXϱžc½œàœàœà¨SQ§¢N=Â#K}‘‘‘3/f^Ìâ#>¢š¡Ùÿ±gZ ^H/¤ü¿ÇïÉ“E~S¸òŸ?¹<ƒ»¼®êB,ÄBãã〷ƒÞz;èi‰§%ž–H÷N÷N÷¶ŽµŽµŽ-6½ØôbÓ;vì ¸¨¸¨¸húy#/)%ÏX/ŸÒwBÈw†%á&éãÍv³Óã¿Áu¡µ¯¾‘t@_Li÷éžäÎ;˜{3/7''' p‡-žánÒ |ò³ž6wðåí-9m×xÅù̺=*ócÓ}º•Žë5ê`»ä‚ל¸CE¹Ðеe(nä·þ æKpP@¨X‹µXkÚ_eQÖþ¶ýmûÛ%”xPâA­[µnÕºU«f­šµj–ØYbg‰õê;ÔÿæÈŸð ŸL“*š>Äÿm ËŽ²£ì¨¼]ݾº}uûk¸†k¸ÒçJŸ+}\»4viljY‘Udÿ× ÿh‘É¥î·q·Máy x xP°HÁ"‹ToT½QõFµ+Õ®T»RéK¥/•¾äðÖá­ÃÛo޶+±Np‚Ó?‰6!„üI„A,ž•· †zL³¿úñÁÑÎ÷Kµo¥úðqÈq6xL±=–î¯'•\U@hÅ1_x£ QôÈÏI‘ÿ?Ò?iÇé%ø"|½t‚gš-T®Qܰz¡>ª”O’›˜Ú(Ø‹S>òÈ_¹€˜ªÌía{\Â%\²ð¶ð¶ðö)çSΧœóQç£ÎGÅGâ#ñQVtVtVt¼.^¯Kä‰<‘K§¥ÓÒiTFeTF}ÔG}Ó Uy¾ù±þUåú÷C.¡‘ŸíU\ÅUÓõƒ8ˆƒ†R†R†RшF4¾nüºñëFÿTÿTÿT[[[ÿà.Á]‚»¼ÿåý/ï‰]»2v¥a a a <‡=â!š&¸Ì¿š,!„ü‘TPBd›X_øÂ›û"&ð³gmŒkI§µêR8‡ëÆž'D6ˆ_øjÿ›í÷IŒAna04xIBòsú¦ß1}b^eýp‘|áÅkf*nˆÌ›+Å&r6e~»ƒÿòÓ'@0­ *O¼(µ‡=ìmmm½_z¿ô~á^ƽŒ{ãEãEãÅ÷!ïCÞ‡<ê÷¨ß£~ Rg©³ÔÙ´P‘\í=1Ñ”²Ë~«K«ùûì›  šÀv°3 –ÍÿˆÿüÏVDÛ-ÑÒô³daQJÅ”Š)Ï{<ïñ¼ø=ñ{â÷ȃt}Oùžò=Ú?´hÛŶ‹m›V•Sö9˜ƒ9ßü< „?’Ü`/Õ•¶qwÄáÒJÕ*áf(‹ù€r¢Ò*²lܳ¯†C’Ÿ¬ì¤($Ì‚0 Œ ÿÈÏë›~ªMn¼ö%€‚p•ªp_ôМQœvXtWº(6˜ `¥QGþ×X¾2y6•A„A¦¥ŽÎã<Î;µtjéÔ2¬~Xý°ú/¼Pð‚f¸f¸føg»ÏvŸíž>{úìé³W ^-xµ@;Z;Z;oðoL}ÒýÐýL)éï׳žoÈ©ÔBj!µà;ùN¾“]`ØyQ§¿a¿Í˜üuð×q×1ó1_^J]]ýõØ×c_}Þîy»çí2eÊ8dgcgcgr6älÈY;;;q–8Kœ…q‡qXõXæhŽæ¿ñ³%„ÿ™œaÅ£–ã,ö`EV\åÑ ý$i¥±\V]૘âiŽè‚&(/õ’nò¶¦¿ü»¿jJÈïæ›R™Ô{9òưÂ'Þ‰WãUy¢™PÆ,GÙMTa°^(o)xä?”¿FTLÇtLÇ—ð%|‰ÜÄBi¡´PúÔó©çSϹ¼syçòâ`q°88«UV«¬VqÇâŽÅK\•¸*qÏãy<°pgqÖ´"©<ñâS ÓmÐmÑm­«YW³®&>ˆrîçÜϹ/í”vJ;M-å…™~+ùûà?ã3>›Vfm…Vh%ø2ê˨/£ÒcÓcÓcbbb]Â]Â]Âý²ü²ü²l&ÛL¶™“““œæ˜æ˜æh:šOyH+­ÆJù½µAMÁeÎv€YR÷âÏ(l„|38µ±_ÐgßHÎgêzœÍ­9éfçPž:·AøóŽãB—˜ÖeTL:±{7òï>XùzÖ=á OSáJmÔFmy·ÊMå¦róíìÛÙ·så©•§VžZ;¶vlíØª}ªö©Ú'`IÀ’€%Ê(e”2ê›#ßÀ Üø—õ‡ª U…ªòv»Éí&·›|[s[s[s2õdêÉTÇÇÇÓSóa>Ìçг¼C`û¦×Üy¤óHç‘å:”ëP®CºuêÖ©[uBÕ U'øúú O…§ÂSSSùºGþ%¨¨†òÛ!@ÀV0þð„Scmå‘…Î\Þ6$’ó[É#&<¼±±R§‘rsvˆÕ !²ozÜSJg?Ì}†¬3<%-ÿÈgÃ\"˜YD(¢År¦Sh *¡€<òOåò81_ñ_131Snâ²Ûe·Ën¯#^G¼ŽØô±écÓǨ5jÚÏ.Ÿ]>»Ä5ˆk× ½izÓô¦†afJ(åúìJ¨„Jßô ÿñ}Ã:è`ú)ËÓxOã·ùm~›d#ÙH¬À ¬0µü½ßü¯q‰K\2ýLºû¸ÿyáç…Ÿf8g8g8ûŽóç;ÎÅÏÅÏÅ/àUÀ«€W¶ãlÇÙŽ{;öíØ·c3»gvÏìn:Ú\ÀÓ„’ù_ õÄBþFHØ`fØÌߣS©ˆBñÎ\©«h„A¼¯z7ýUåä €–([¡–Ó}S $!?1Eþ¤"9=++Ç¥PùR|Æ}¨P –;Õ³•…áà1ïŠUØC°†>#ã7„G~tòr?*¨ B2­ØŠ­¨‡z¨'7±c9ÆrŒïA߃¾ øð-à+ŠÓ¯§_O¿———Ç{ð¼ÖaÖa6a“ièjþ$øÏMó?“¢(Š¢¦’ù'J¾´þ%ÇD~nòÏ$ù¹€ ¸[+·Vn­ÈÓ‘§#O§¾L}™úR.žqšà4Ái‚Õ«=V{âÒãÒãÒß?~ÿøýc^WãÕXiVš•ÆK¼ÄK¸Á n¼ /È â$Nâ¤iâN ´ !ä?TåÈa 6`7arÉIo8LÄ6ÅA¶+Œ•øûcu®ŒZÐÀ-Q ”™‰È…^þÝYc)ÕXÈɈQ,‹ù‚K9ü¾]ªyOÍsXâ!Hí¸Èƒ /¸â4žã ‘ ±ˆýfO=ÔC=åRåRåR/£—ÑËèÁ<˜SmUmUmÕî×î×µˆµ's4¬5¬5¬5ÍÚ.Ït(lÈ©°[°[X:KgéòŽÜC¹‡ri;i;i;I¹R®”«{§{§{§sÒ9霴SµSµS¥ŽRG©£éIHB „ÿÈ6LA C7cEÞNqU&¶«âÖÛ»ס™!x~ñWÊBƒ¬„Ö|¬ùXëÖ%¬KÀþðG]ÔE]„"¡¦ éqÂAyæÙLÁ¹"Ÿûsî#8‚#¦[¿·º|ù]k€hØÀ†_â—ø%«,«,«¬°›a7ÃnzõóêçÕO¥T)UJƒÆAã ¹¦¹¦¹f6ÅlŠÙ1P MÇÌwåBþglºè†Õxc{Ð2^]¢\^‘S.}QBJ—¶~9ûeD6^nŽ;––‚çˆG¦Toå5iRZBò¸œ¸‹`¨cÜÌGdÚjç" gíY,D>†ëm®ir”mUwÅ A''!¬8œ`Cáû©™Ãæò¦RTŠJQe®2W™«z©z©z‰-Äb ‡¥K––èT¢S‰N…S §NÕ|Ñ|Ñ|AT@$#É8Žã88üí§àõ5-¥•çÒ)ƒ2(G8Âñ»xnù#)?+yøì)œÂ)¸Â®…< y 9r,ä˜Ã ‡72ögìÏØ#[³8fqŒwŒwŒwôùèóÑçsVæ¬ÌYi:æ,ÌÂ,:!ÿ‘ö¨ OX@ Ñ©·íeóYOœ,ÍÆ#I¬%ž|Y5¾YŠñyÕ˜I/ØiV§¥D© ×Ò´„ä§@$’#¦k+…J‰éõµÅu ¡ ÌI:¦¿#eXSÍUWÙ-/q~°ƒ%¢(€?±ØùëlþO‡?þt¸øIü$~âá<œ‡3+fŬ_9¾r|å~ÇýŽû¯™^3½fÚ-³[f·,~UüªøU A A A¨Žê¨Ž;¸ƒ;‚!‚»¸‹»ßÌÿ½É—³¦¬)kjêeߎíØþÍ;ÖŸœüs®Ë+ËÎÃ<ÌC!B!åTåTåÔ‚u Ö-X×u™ë2×eÂ4aš0íóñÏÇ?=ýõô×Óó–æ-Í[j:š<Û¬Ú¡i{:¦c: „C D¨ ‚£*#¤ú¨’}ß §j¡€Š˜õ¦a¢̊ÆSÆþÆhEÌ‚ ‘ÆIœªÛ ù†‘ø„”ƒn(mlb\q9/V7åØdÖDšÇßsgËVJkÑBÑ[x-Ô€/l`Fáû©}À˜ª·3Ûf¶ÍlkÚ/'߀´‚iÓ ¦ø¥ø¥øy›y›y›9v<ìx¸ðŒÂ3 Ïpttttt|·åÝ–w[2Êe”Ë0-ò%OYˆÍØŒÍx…WxõÝ-ý£…ZySz =`&`›È&²‰(Ò(p„#<ÿH€?”ü³G.ã‘N4DC4´Ï¶Ï¶Ï.\0¸`°µƒµƒµƒ\Åþþæû›ïoÆŽ={XZ*-•–²…l![ˆOø„O¦ë D Å_ñW؈Ø%”Pš&$„EŒEœp+ñ¨v™R‰žñ’Ug7ÐTÛÀØøÆçºOj´E—B¥ch‰hx@4Ý—Pà)>!…P6¼1ßÀ[§7ʵ+AbÅŒ«xne9N¹[¼®˜É>3oÌoà +JÜrù“éc8†c@Ló¨È=åÇp ÇRg¦ÎL™¶1mcÚF÷ëî×ݯ{/ò^ä½Èé‰Ó§'¶glÏØžùÐøCãc—Ç.]nô5ú}á Oxb/öb/Ú¢-Ú~G¯=Á–75]5]5]…­ÂVak^á¼Ây…ÌÌÃL-åÄ÷÷–ž{¹$æîáüà?ÖŠµb­|júÔô©é¥öR{©UUTUTU2×e®Ë\%EIQÒWǯŽ_-ïY‹µXËûò¾¼ï¿y\JÙ !ÿ‰1èŠêüwÆXu••bNñŸÉ¶SQ„™ãEÆšì]±³uïlxS¯CÒ ~÷ÂRp‡‚GH~ ŸˆO²Ó²Ó²Ó I†$Cæb.æ" Hø=ŸJ¾Ùxä ûq‡qrÊn>Ñ|¢ùÄ€ 68q:ãtFZ/­—ÖLø˜ð1!zSô¦èMº²º²º²xŽçxnšç§/ú¢ïww•ƒò# € 'X{ö^šÇëñ7Åæù—q>à ±63[ -Äß¾ž|>§ÿ'¤tÌúˆ\Ì€±)x„ü³Sêâ‘(,`)ì´ÈFVêðœW¹+!’•ñ¶|!S ;ñʾ¼ù³_ë\­  QÞä '|rÁÆp ÇpÔFmÔÆœÁ™ÜÀÜÀÜÀÈr‘å"Ë=ôüÑóGiMÓš¦5µ±±±±± š4'hNÑ5E×]cÑÇ¢EÓê¤rÊ.WÃ{ÃÞûÿÁ‹q7pÓŠ¡¼ïÇû!ˆ`;ÙN¶“U`XSÓßc mþcª¡†ÚôÃFîeoŽæhîìì69lrØdçêÎÕ«çIyRžôz×ë]¯w½8÷âÜ‹s¦”= iH3%ýñ)e'„üf$HàÂpá³DUu¥ÑÅsÜ|lÞÙ^23à›ßkûžLüEªÍWðâØ‚(Ž$¤ÿZŽHÉO¤!“åa†è‰ ™mµ·ô=LÍ*#ëð·ï`°¬nöëÊeôü'ò-•—[º‰›¸‰®èŠ®òL2I‹“'-N M M õZéµÒk¥ÇC‡Ý=Ý=Ý=m›Ú6µmú!àCÀ‡€øàøàø`^Ž—ãå°˱·p ·ð ~Á/ß”‹üÎcŒýš:;Á N¦udåyÍó÷ëjÄ¿õçK©å’yÉ*'8ÁI\$.ùÏòŸå?˽œ{9÷rb„!F$OKž–<íMÍ75ßÔÌüù!óƒé ‰ l`[ØÂö›G¡”ò[©r(ăy5ÞW13Š·ö9bçƒý*gA»°Vç&ÜÕ¼uGwTÄá£PˆÕúIQœæn'äŸäT€Ã¼wåu5ö“îã«ä&5`GØ~ÖÖHEŽÃgó½f4¾›üwä øm؆mX‡uXÇLÁúnúnúno¼}ðöÁ“ãOŽ?9ž””dhhXðBÁ /”8RâH‰#vÍìšÙ5Ã` Æ`Sʾû°%Q%MòGN(i kX›z¾ßã=Þ#9Èù]KN©'c2&›êìà'OOϰÓa§ÃN{5ñjâÕ„Y3kf×*®U\«ˆW¯"^™Rvù§Å#<Â#ìÀìøã¯WB~¬9Ó`Ÿ±´T’ϰoe3Îbmp¿‚Ówà¾1ÜX0míW}^‹7U|Ò]‘„Tˆ88X#Z?CÈ?#˜R_ð_ä]9Þ†ÏRØËI•„lú<©öMÌ/kNPÈÈ%on6²‘m*;éþè/Ï'“Ö(­QZ£§ê§ê§ê—[_n}¹5§}Nûœöö•í+ÛW   Ö¸iÜ4n¦uLïã>îã®ášéQ~·””K\â¿öëŸÁœ‘gs—KePQñogØÿý9äÿù!÷‹Á|1MÂx —pÉ3À3À3 ø—à_‚±[i·ÒneŽeŽeŽå‹/¼Ï›ò¦¼©i–/xÁË4#еZ-!äÄú1K¶B¾ªçSÃé„ùð•oUÛ«(m¸l¸÷nB`êŒOÝ¿¶Ë.0ò^”O¢¸òoˆÏg¶IÞn˜äãóÎxÆþµñ“_w~ÇùÌÇ=6O˜P«EiSrÏÎ »)nä7“?I]ˆ…X˜ÿF³gfÏÌž5 jÔ´Ú­j·ªÝª}°öÁÚË/+¿¬ü2×E®‹\±¾¬/ûu”wx‡wòMSêü›öÁ‹!bˆ"oOÑLÑLÑ<Ë}–û,wžç<ÏyžŠEŒ"ÆÔtva× yrIùÚ@µBµBµ¢è颧‹ž®9®æ¸šãj©k©k©ƒcƒcƒcÍëš×5¯kºï4LôüsàЄ„ßüÛ ½Žéè…ŠêÏfõ4O‹±‘1ƒ#5ºZiçé³ò¾ìx}8ó^J™ª†UUB Â^±¦XBHÈ¿>½dýù<”73êhsõéÙ{õÑÆFâ ¡4{ à1¢mÇk¨«RÈÈï"ÿ`Ö‘‰‘h„Fh$/Æ”[<·xnñÈ£‘G#>w~îüÜ9-/-/-Ï¢‘E#‹FAfAfAfÅ“‹'O¶fÖÌšÁ¾ðE bƒË¸ŒËòÂCûÔÿ·=ñö°‡½é`W„+Âa…°BX¡ýªýªý* ‘†H¦™ìM«Ãþ'ò§Ôò3<‡s8gº’ÐíÐÎ~‘ý"ûEa×®…]ssssss3\2\2\Š^½$zɳ³ÏÎ>;›s6çlÎYÓ0Ó­ØŠ­xЧxJCN !¿;ÁtƒCKØ¢9ÊÀÅPÊX„«íê{Tñ*ÛQyÞ¦¶¶ f¥cEcËÒöwUÕÍÕÓ1‹°ˆ­ÀÜ0Mþ‹@ÉÇ´4 _‰»ˆ–{å²ûè6ç5Ä{Y†«’ÅM&Am[H³XiO!#¿£üƒYOâ$Nâ.ມºÉEÉþÉþÉþéËÓ—§/÷°ô°ô°ôŒ÷Œ÷Œwѹè\t6Î6Î6Î #F$Œˆs‹s‹s3V5V5VÅP ÅPÓì4[°[þ«Á¬ùï%— ¤#é¦yoäg~Çqü?ú‘?¥–k呈Dùç'ä y~3ýfúÍôØá±Ãc‡’)™’¥mHÛ¶áM‡7ÞtHíŸÚ?µ¿éhã1ãMÿòó¤”òÇSö¯h+t`ÃÅ¥RÜuˆW«ç¥VZZᢔž›)Å E0ŰH»XwTÚ+¼WR•R½EQLÆFîÇËñ²¨‹º¨‹³8‹³ô FH~¿¦sqOäͬºDýؼцÆ#ìª`ÁnxŽXk3õvÅ ùƒÈ_Óò¥rÏñÁy~°~°~ð;çwÎ<{òìɳ¤âIœЫޫޫŽû]ô»èw1,3,3,Óq‹ãÇ-XŠ¥XjJÙåU?+£2*ÿÏÓ®p5Õ ŸÀ œ@ Rò¿è×—_©üÓB®×·‡=ì-oXÞ°¼ÂCx÷¹àsÁç‚°YØ,l~¿÷ýÞ÷{#¼#¼#¼S‡¤I‚¯øŠ¯((Ù˜Ùÿäø„òûQA Q^MYØ(蘟q­TŠ»VYrÏsÍä[½îV(lh.>Q¼ÙK‹³êš¡¢òžÊ³hëb¬˜Êq‡Ÿ…‘eJÙ÷`ö|ó(TìG~z¿ö¸ÏÅeþ‡ Â3»Ÿî¸Þ.w˜¾‹¡ÌØfusÏ`}ZµK9¨Da#9锿¬3 SŸtOôDOøÃþéãÓǧð4ài€Ë—).S|Þú¼õyk§±ÓØi¬×X¯±^ó±âÇŠ+ÆÎ;7¯r^å¼_Sv¹E®#—ý'½;ùo}€x ÷¸3sfÎÌQ •PÉÔÛýŸ¤ïòêª.p‹¼Ãµ›k7×nþJ¥¿Òl‰Ù³%9µrjåÔzûèí£·>õúÔëS/Ó}â(ŽšfµÏD&2iÈ)!䥀:èadeðK¥Ò’=dÿÜÆÆìåÚŽ#üjM²éoÖTjªÜò¢ÑÅÐÜ}f›,SïfÒÍë× ×vçK=zºØà:Áu’F~ÁD•ŒÊ‰Ê1´7´7´7}³É]$YÈBõÁ“Ÿû„“Íåqy( žõFÛYÿ8¯‡†JøÈ|ÙG€㯭««BÅ·°€ó`€‘.Á“?Ì?~Æä¾s9=]€X ’FI£>â#>"E›¢MÑú ñâ7Ä9Æ9Æ9ÆËàeð2Øs{nÏãîÅÝ‹»—˜œ˜œ˜,•–JK¥ñ/ñÐLÕáÿ3%”PÊ›,‚E°ù^Æcˆ1{±{á g835dþ󥊡˜6>6>6vkíÖÚ­-\ªp©Â¥ Ô*P«@­˜O1Ÿb>e¸d¸d˜z»M‹:…#áxxñOþ<È“*ʧPKEKEKE”"J•|9ùròe©°TX*Ì\™+så÷ù}~ßt/ùrZßmÑVž8ÒfŠÍ›)Xp Ýz»õvëõõõßµ}×ö]Û¸kq×â®I¥‹ÒEÓõyù*yé¥?pÙ)Bù†Ü×^ Að ñL4ÆI‰üÒÀÝ­P2®cÍbárR…ì«Zí<©£pÿ¾Ã‡1ÆÖ…·…V)sÎëêýÄÉŠjŠÏ_*$wHî k÷¤Þ“z…Ux”£«cÇfÞfÞfÞ¯3_g¾ÎL¶J¶J¶‚ì`g꼘€ ˜@é;ùY¹ÃVbË`áò޳§»Ü«Óó9ë{máé3ìºW¾0Ô¹e%¤a;áz¡ÊÂî<ò'Ë_õ(¯`Ú-Ñk°käÝ /…—ÂË·§oOßž•ÛVn[¹m›:6ulª´ªÒªJ«€ºuê*Ê(Ê(ʘŽÓ=ÐÃ0 ÃL{òÍo ö{‰¦b•Ùïg¿Ÿý>ªATƒ¨ý½ú{õ÷’‹yXÖ‡õ1Í#÷ÐËõúòS>ÅN±S>Ö>Ö>ÖU4U4U4µ µ µ e^–yYæ¥Ã`‡Áƒ¿y1MϪ< !.ñïWù„úì*³‘·Ã®^q—åöõ [ºaWFéÂùíù#1éf÷Z•öÌ+·`Çâ]ý{TªÆýkô”°˜ÀÓwšÊCå¡òîÜ%¸K­uµÖÕZWmOµ=Õöx÷òîåÝ뛫‹«° «LÛ (þVA@ÈÏC1JhÁ.à Îp>ìÐaHÍÜÏÙØë*?:ݻ۰ؔ+ÛTµžc¶QÓÔt‡ÌÆ`ŠùŽäOjå4W^+4«fVͬšO-žZ<µÆ¥—j\ªU+ªVTç2Îeœ ذ/ðíìI ° P`š]ø›ÄýÁì³D…F…F…ößÙgÿ¦'ÒŒ5cÍLýërÏÀü¢ùEó‹¡½C{‡ö®Õ³VÏZ=k.«¹¬æ² CA‡‚©æªæªæšW˜UUPÅ´‡V9%„ü¹äu1d§±}Y)|ÁÕ}¥QñþÁ‚ oº8r~£Ð°mœßZ9bñíÌÄfmÕíÕfª);œwì¨÷ ïÁÙ}Jù”ò)å#†ÕcõX=Ä#ñ¦=,úùùÕ(R£H"5u5u5uEûíS´ªªê×é}啳ÍasÓêÚ ñSð×ÿg`|n"IøŒÏ™›õÆ"¯¥\Á{ò1jg±·pÎÖѬ z€Üž-E Ô¤ ’ïHþ ¦r‰œàdꃅQ•y$óHæ‘g‡žzv(²{d÷ÈîÙc³Çfµ)lSئp±ýÅöÛT7¨nP]ó2æeÌ˘Jqä¹@%ÿ´•š|ÿÞà ÞÈ»gœqSIÌ,ÌÂ,ç·Îo߆õ ëÖ¯@vìÙy5ójæÕ|µøÕâW‹#¯F^¼ª««‹+¸‚+ŽánZ –†œB¾$pŒ@GTû gÙcþ0jú‹ž«+ªKŽ,Ö²Àv@šÍÊ&>ÊZ5À¸øØ…Û† CGã ‡KAöm¥©Ò]©HÊ•”+)WLÇ4ƒÌL%ˆ»° »xâQ1‘1‘1‘/о(ú¢¨ÖLk¦5s?æ~ÌýXððàáÁÃ-ßZ¾µ|kš‰ë=Þã½ib€ü«‚ò—#üíTäà8Ç?"MÞ‘yO̸@G¾‰Ûòž§<¢(/®µ 7;©–Lí—²æ¨NA$ß©üI¼<•¤Üw.¯':0àSܧ¸OqS¦n½TQª(Uôôô :/tž§ÊSå©f 3…™B‚Øcö˜=6ý™‘/ÑÊxäé »£;ºKG¥£ÒQñ”xJ<8&pLà˜ /A_‚¾˜ûšûšû¦(R)Šÿÿÿ„¸„¸„8SoS4@TC5T3Í6ó¯…BþxrE»%,`&žœX}c¬tœßmº°òêÀëcœ:F•jc˜’7^oÔ¹\1§ß¼%.ÿlþµOV¼½»ý#»žÊ"ª›ê%9or"r®dÍþšýÕtä$ ÁÔ=ÑÑ@€¼&ÆçŸ|>ð´ðÓÂO § ©Bª`÷Ñî£ÝÇ÷÷wyú8ÀHE*RÑ ÍÐÌÔ½B½ïä/çÛËî‡Dy3c´îƒáry Œæa˜Î×*+‹qBëJšÇ*g¹ ›z¬<‘üò‰OÁLA)”B)<Á<Ñ]Õ]Õ]*U(ªÐ³»Ïî>»›²'eOÊ‹¾}-ú*U¨T¡RÁyÁyÁy¶*[s[sC„!Â5,“e2oáªp•/D7t;*|>0²3ìŒuë6ÖmB³BsBs¼*xUðª€9˜ƒ9qRœ'=õêÿÔ?«lVÙ¬²ˆF4¢MºNáN™úŠ(Y'„|ÔPB!Ïö³Zxh|--áã|Ǹ²K]¶ep‹j ®®˜fq_3viïý^O²ŽW¿Q#ª'ÛÏ"ª°Õdëe…—‚§õL Oëcègègèg:¾|%SþÆ“ å«—áG8˜À„Œ/2^<™üdò“ÉIK’–$-1{cöÆìMÐÆ A}û<öyÌZ°¬…©›FNâó‹ROþ¾ÌqÑø(ofÙiÏê—ÁÈOñxóŽØ¥ru­{«?©VâÎlj£€%xA¡$?€ü³ÂßÀ Ü0-ZTuP½Ð ½¾VýZõkÕ E†"CáâçâçâçõÑë£×G§"NEœŠX²îbÝåËÅ/þ_ü_6|9êå(ýð\Û\[eC6˜ þ0êÝÔwSÕfÂTaj‰ˆ’ÅJS•UžRžÊ*U9«ò›eo–½Y–˜˜ˆó8óƒ1ƒ‚(ˆ‚ß<Ïü¥8„òg‘]-ô0àv¢:swôfj¦dc×­9½ÖrïLU1€gðZ·µO˜9½ÙÖæ7m…’‚'ë*5‘NòPËú–̲¹xD<&žÊ~šý,û™á«á«ÁÔãÎãx3õšç/LD"9çœs,Æb,ÖõÑõÑõyîúÜõ¹«_¿>~}<;yvòìp*àTÀ)‹¶m-ÚFeGeGeëíôvz;ä"¹ò’v¦mB~pßô¸óÙ¸ök þeuÎígôà˸‚ÏÇU¼R~§ ¬‚Õ¯”KMwª¢ ’Ì?ÖÁŸÃ9œ3ÕJ~À|0 ƒáý÷>Ü{ó(æQL¼w¼w¼·òˆÒMéæþÖÕÅÕ¥Zɺ ê6(˜TÊ·”oN+³úfõ+ôiìר¯]Ûþ†þeqq°8øÓ”O>ˆ¸q3â¦)e—+æåÚ÷y˜‡yT‹IùN‰!`ÂQWLª±pêø4ÍØ£r¥µ3+8ø,5dä Ñ{'HÙš‡ÞýæO:¿>;,÷¾î ›ƒûÌ[>Œ ³1Úä*;+»(»dŽÈ‘9B_S_S_Óôí'_uüGòwµ\Ž(ù™„I˜dL4&£oFߌ¾ùÒá¥ÃK­R«Ô*ÝÖ¸­q[º"tEè «±Vc­ÆšŠ{£7z£=Ú£½éÈÔûNþ„²¬Ú¯ Mëþ¡¿27Ö™–Öí½>pÊ„.Í9Ÿ9»§O¯Úe—­g:£3…bìÅüEäÿ*oÖh-“ÊßÄÕÖ-Ì-¬ÈÜ€£Gg §oœÆ9ç·=ŌŢÛsÎùumæÌ;îÃ]û»öv÷„{¦;À0Õnþã#BÈ÷èäMaÓ³’òvýsåÊ}9o˜½®×¥3ƒ‹s~«ÉÈÊžÔ^Ì4Y…)³æ‚F°lå=ÍŠ7+Þ¬øÃ¬‡Y³f ³…Ù‚-D ¿&ëù¦îý—þñûy$Fb¤¼Ãf³Íf›Íe•TfPÂu ×)\éA¥•8sç<î›ã,Æb,þ'Ç$äGÄ^1 DÊÛµŠõ ÖÛN=Û5U·nJÝ.¥yÚìͽV ÝS¹nH-¹¢·ÐQ‘ ù+Ê?ñ¢ÜO3ƒ0ö¬+ LŠ E»O½~ôúh£±¾±þíky ó>Yhèlè|Pó2ûe¶é¾˜‚ýÚWôG&„ïM¾ Ùh懓ò¶‡S{ë#qm„öÞÈùµiCçs~·ïÈäõÊQ×ë>’ÛˆÕ…!¬ ¾âÆÃ…aÂPy— ]*t©ð´ÊÓ*O«Œ-8¶àØ_‹åøù¿!ÿgùSí(€HF2’åªUˆ*¤¸¢¸¢¸¢VíZµkÕ®¾¬ú²êËÂÂÂØ=výÚ²°ÁÔ—OßÉä;Aó[Ão BÞüÚ,ǘ÷Õ8…/篱 _X Y1K£’‰ Líû£<è÷*ù Ê¿2«<ŸúYœÅYe®RP Òdé…ô"»}N‹œjá”pŠÏc7ÙMÕ\q»¸]5Ȭ¯Y_´Aô`ÌŸù›úxh•SBÈ÷Ož7.—0M8Ʋ»ŠeŠÁ ¶bÓP󚟽~q;`•°ìÀ½ÓO¶|.=*}íºk‰¬7³Æ&)NÇ›Âu0Ð]äCÚºÛºÛºË+Ñ}½ñõÆ×¦…ꦲ©l*"ñkîñoä/tü‚/øG8ÂÏð ÏtOtOtOž+ž+ž+bô1ú=Ê£<Êû$ù$ù$oQ¼Eñššš¦µ±áŽÁ V°2“úàÉwïÿKÜqåÍÔ™9fy)Ò!i3æ{ ‡=D¶€%ZŒT8 MŸð~(ÊÜhÞ ò—•?ÉŽB¢¤GÒ é£úéÊä9å9åÚä^ν, 3.6.ÎxžÙ&³Mꇤ¥IK¡Bò0ä#ivBÈÀ j(Qað» 7Y®ñ•´‚Oôªå•°Ô¦Æêþ7ŒmuM ˳ûå67‡÷œoy®fºyæÎ܆˜‰¾¨Ícà‚žr=›Çæ±yð„'<í[Ø·°o¡z§z§z—Þ$½Iz衇^-ŒFã9žãùõÌ‹£8ŠcÆa¯Ê«òª1Wb®Ä\‰*U&ªŒN¯ÓëôÎ÷ï;ßÉÉɶ‰µ‰µ‰5M¿+÷ÙûÃþßL`@È`!À4½£µJ½^ù9#sbNÅ´G§4é2–ó5ú´_®j0«l;˜ÃÊ)ÂCÁÁt¡‰Ÿ¢8X,FÔC½¹~sËÎ-#½ó~çÝTÓ´`Ó‚…åX.~?ˆè!ä ‚â×!òBIv„iäíJ·CúzÏ™u!oH¼áñå僷ŸßÒŒøÒw_³ó%L½ébsa6›„( X *”EY”ê u…ºr›…O>Yø$Ú1Ú1Ú±A»í´3Ý÷²xY¼ü<ÿüå.eQeM«vìfÙͲ›U6¬lXÙ°ÚfµÍj›UZyhå¡.Ÿ\>¹üºVFtALÄDL¤ùž}›p¿BLÓ3åå ó²Îé«k ¯X4[H¤¥V35ÅÔW‘ƒldK‡ù2麢B)”ä§ OÔ(_ñ½…38çóV¼óãoø^‹\Ä Æ`¨ ‚Šæb'„|×äÎ 0²ÒÈÁV)œ_ä>ö“lz™Y«ѯf®Ùxµ=ÅP›jõ®B§Æ¿nºáÑñ}OnŠ …l•q†Tkñ¯ðYÈ…s1s¥x)^ŠˈeÄ2–-ZÌ Ì Ì Ìh˜Ñ0£¡éÑå’•ÿ^þâÆ»¸‹»XõXØ©R'¤Nˆ˜13bfÒ­¤[I·Ô‘êHud‘E9àÓ˧—O/lÇvlÇLÌÄLÄ!q¦£Q<ùÎ|ûqÌ7s4£HÈl¤d<+œÁC,¤V|¯ÕsÍx•#¶ànIÙ<ÅÑ¥Q”BI~ ò9 0À ¶°E3 Æ`$1gæŒñ؆mpƒ|Lm!äû$_ ”;Œ¸ÉÂ$á9ËFOôÄÆ+úέZ¦hX`}‡¥ØÄŸàÄë¢1]¾º=¿îÃ5 ã\ãã[I' ç(†Ö˜ÿÍÖÉl2›Œ—x‰—],ºXt±xfñÌâYNíœÚ9µsnæÜ̹)·ä«ùj¾ú7{EùËå)&;£3:Ë#”´ µ µ ŸÞzÿéýØò±åc˳¬kp1àbÀÅâK‹/-¾TÝDÝDÝÞð†·iV1yBÉ_#FWPÉŸîÛ˜ò`øõCÏKðX’ÝA_Ú8ž]d—Øx€â­Ê©Ç©,•W••õoõZ}&ë‚N(JŠä§¿2iHC&¾â+0À€d|ÄG|D,bé+žò]3‡”ÐÁo„îìµ±‰ôŠOïs¸YÕóz¤65mkTæXjÛ*‹í”úk¹Ì>6ø2'#GˆJ²–’Ÿ$òn0‡Jä zÓ‘Gc4Fã6nã¶EU‹ªUÍCÍCÍC³c³c³c³¬³¬³¬M-§c:¦ÿޝQî/¯‹º¨‹ã8Žã¼1oÌË ³fÉ.’]$à`ÀÁ€ƒ.}\ú¸ô1¿m~ÛüöËÀ—/3Úg´Ïh•X‰•¸ˆ‹¸ˆÃ8ŒÃ¦¹çi™<ò'ù¶Ç=†_?ˆÆ—ÜŠ·Ê(¡›eg‘ì#öÒXþØòµz·²¢™ZñU| ­òÿ­ûH!„ï“ ˆÈF.ôl/k€'R!éß[jW‘ån¯ í{¾âƒNë¦+(êÍGhϵغåÞKã6}'Þ>±Ò&)”gB„öMÊ`3ÙL6S¾êhUÖª¬UYËÕ–«-Wg½ÏzŸõ>óFæÌrJÍGð|ÄïøJå>x¹¥1£1Ê¡Êɉxb»Äv‰íž>|úðéÃôééÓÓ§[ϱžc='8<8<8ܹ•s+çVˆhJÙ; :˜Rvêš!’ÿ?q×ÿzqŸ¯æFÞ$ãŠ6M_EYûàK¥O–çT>Ê š ÊŠ‘ÐAG+V ~JB!ä»&§šz`ÜØV¦à•yÔ´ ´\® Ûì0&º¶»U/ËÁŠ •Æ]™t¢çÕø·;§Ù:çæ{ÂMÔ3¾’Vó…˜…M8gš8òÀ˜ÒqóÏæŸÍ?›[š[š[æ 9È®•]+»–)¥^‚%Xò»¿jùJ©Üû~wpG^»š L`Bzxzxzx„g„g„g¢w¢w¢·¦¶¦¶¦vMM¿¿¿à/ø þØÿÇÞy‡E‘l}øWÝ3ä,Y@rFAÌ"‚bÀ0'Ì PÌ9ç0çœsŽHPA$((9g˜éúþèq/~»{ïî½›Üí×çá)kjª»OWõœ>u꜓~€€IDAT8‰Gx„Gßd¼”x?o]e*!ùáÝt)<Ѻ$º:¶ö.8r’4A­ô>=¬$‡‹ª|E;ØrÙˆí +4¤À{AœY4¡ E„`.z{ÒË™}d-³{köô®^[:Ûèæn×Õ™¦¥éX>p²Öfㇱ´ ÝOOÂ!Ž g`/³Ù×ýk•¾>d%YIVòeÕ­ª[U·ªW9®r¼üEù‹òåƒË—†-laKçÒ¹t.žâ)žþî×^ß>ùȧ,e)‹ã8ŽãµŽµŽµŽ âq‚¸Æ¤Æ¤ÆÄ˜Scjfifif©p^á¼Âùd÷d÷d÷Úµj;ÈzSƒÔPŽr”Ët'! ÀïÌ·÷JÔA‚u0…rx[º¼fn­ RŽ{Ü*zê(½—›Î>V(Õ0eßò…-i(ˆR@@@@@à/ ð±e¨bæ•:rÊÔzhaç«^ÃKºÙÚºÔnªlY3ˆ(±œèjÀ“­™?|ÚTÜ“µa–’=´ ½ˆ&ós*»ŒýØý|Q­™Z3µfªcTǨŽ)‹/‹/‹ç^s¯¹×L„`<ÆcüŸ,™¡Š¡…QÅ1Ã1É)É)É) kÖ&¬­‘«‘«‘3,2,2,j¼ ñ‚Æ T U U eö{~k[´E[!¼ÀÃÿWÜkPGB0^¨C-ꊬªFÖnÄ@¶±hƒ4ˆ™\% ¹wr:ŠÇä›É†9ìa0€–2I@@@@@à/ó¯€ÌRRFZr©täíl}Ñ^²nÖ„Ëm䥳jÞÖEË)©ÉïØ¦v6îõ“ë#Ãî%wbæ‘\â mÈ…ÓS N¦°ÿ|"9À½Ñ½ù Õ Õ Õ >P#GçÑy ·¾ª}7qáG8ïBSª[ª[ª»=v{ìö¬#YG²Ž(x)x)xÙKí¥öRó$ó$ó$ Á Á<ÌÃ<ÜÃ=Ü“õ)‚èÿ9$ üÏü”Å}1&mùŠ 1§œPv¯YfÇ‹¹+šîUšØâ²×D½ÃgŒ|ÆÙÑP— 欹*  öalH:'Œ¹OTÈjÒaXÉèüÃ1áMT@@@@@àw¢¾:\)8’‰ýèÀùS}¾xÞˆ¤–ŸÛ.húÐð¸Ä¹ÎU*)Ð)Y-+]änUõ²šuHI&ס¬ƒÄ`‘÷¶9ÌaNÓi:MGò§²Te©ÊR©“ÔIêTVVVVV&ky7pã/ä^ÿLøL¼ MrS{°ö`íÁ¸Qq£âF¥‰ÒDi"ºî£ûÌ;™w2ïä0Êa”Ã(ñ{ñ{ñ{xÃÞ¼Ò/ó€ÿ×4ß%ÈAÌ´bG± ùŠN¤s黎r”R6ˆRJ#(¥ôÝpJ)é6\·½®c±«û|ÔH„-¢ÝìJÆ’ÙÆÈ“Þøˆk˜#û˜•-å |°lÀ—Wg­ÎZ•¦–¦–¦ÖãRK=.ÉÚd±Yl– +?ö_2&™q#£ù²_Œ—³}·-´p†äËÖS+%U¡s‚îúå{Û:„ËÚ§3Τ ô¡M™Gû/g'vb§¬Ÿ &ˆ ZÙee—•]^e¾Ê|•Ù#¹GrdÙ§Œ£ñÝÈsöaT ¾BßVßVß¶mXÛ°¶aÞÁÞÁÞÁÍ·5ßÖ|›¦³¦³¦³ì[ˆ@Ú  Úüp_þ‹F@à¿âÿ[ÜkQ‡°‚_Qò®t[Yq„´Lª'V¬q®n-ž$-•T\«y_¹|ýŠñî-–FîÞñ¨ß¾x×£ G¾;6~‘mÑ»»nwJ±Ú(¿ÁísÉÊyT‘žB€d¢t>÷›ÆÕÐKh_¬a"Ò‰¤d ¤b9qã0½Ðü—A±ø÷ðf0)8Pf©!îÜH®ˆ²w5Û¡ÛfËéO:´Â&i”Ä‘5P¼-¿t—êyƒ7’ÓÚ÷ã[±Ì2››ÂiÒd#EÿÁ£ýǸ®C ±ü'ùOòŸ´.h]кPgVgVgV°¨`QÁ"¾!]C×Ð5ߌd#vÓŠÝE°,›#Ý͸°j('j(•ÛΪ)›9ÊÞj×äGÚÏQ_¡ l S­Š¡è¢f•_y ls]Rrå熥Z/'ÎÍòˆ'nÎÑŠéžÜ;¿öÍú¾9n5-k×-° F6°ì/Àîa%ä1FÑ}HåÒ-Ôš†ÐLtF!JP!s¹ù¹8²ÿx•E"NcN!šÎ`F3nDq½ãÄílõÜT*tçL¥Þ\òÛÛI¢¼óò÷ õGA›ÀQ-\‡9¢Á‚é¯TÜ­`+Ô¡uâ‹â‹â‹j Ô¨5¨ ¯ ¯ /]Qº¢t…¬åœÁ™ï@ªõcÀ¿Ç{¼ÇDLÄD$! IÅ6Å6Å6±{b÷Äî±ö´ö´öÔÛ©·So§Ý»)vS”V*­TZ™VžVžVNWÓÕt5øPöÊP†²¬!ˆ¤À¯ä§÷2<ÄM¾È¹Ôí¨•#ËJÅr¯$Ûë^ˆO‹Ä'Š—U¨¼t>öqƒ´åÍ Íß©˜èŸhÐBe£üÅQâx€õg•^¨º‰†6uŽæì&p(ÑɃº³T\X4¨Ò;WZ8·Âñu@jÿ"ýÛ]¢ö||ùhû«Ñi[Š_–¿®yW:¾âZÍ éx)¨€±?œî4v0)¡å´3ns K5éÊ` JPZ”¡µ¨BÍ·YÜþæð‘݈¡ÂD1CI,·”“P‹1õº×Õ¹†i?êZs¢v@ÅlÉJ¸MÞ´yñ£äò{•Kj¾0“Hqà¾Pº@fûµ*;€8âÀk¡âhq´8Z£ŸF?~uÎuÎuÎEŠ6mÀ\Áº—î¥{eŠþ_Ÿú1àyxØÀ»±»kÆ×Œ¯÷:îuÜëªsUçªÎ™(š(š(šo6ßl¾YÙCÙCÙãýÞ÷{ßï­QªQªQB&2‘ÉG²—Å€øÅü”⾃+å.òÅ’¤øäØ£JïWzN47M”ßÊ–1ëÅ "f§Ò‹&fO©º2"TUÎUÉú´[Òtœ©[¼m/½Ve KÔ]|¬,toÛU5ŠÖ,W#¾Œ,€¹BƒèjõPÐn€óì6[ÎÓðƒ',–IŸH¶q)©sºW4»/ÿÊ0ã]ØØ×£>uü4"oe…Ö›')Šyþ%ÛÊNV©8ùÿÎù‚áÈ #ª8‰±èKºP]ô£'h)mŒùØŽ3,ôCxOt ¤à˜ Æ‹ 改;t¯7Ó<ÃÜyþª‘'›Gs…ÕUµÉÌ+¹+ó˜í¢GcžÑן>³S™#d³ô׃®ç-åÿÓ™ðŠx6²‘-Z&Z&Z¦zXõ°êáš·5okÞ–¾-}[úVÖò{±¸ÿ˜úcxëûlÁÚ„6¡M>à> ¼¨¼¨¼ÈÊÃÊÃÊC______9T9T94ádÂÉ„“¥F¥F¥F˜€ ˜€ T Çp Çë»À/›î?æ4ég€~U©ä™Ô²|t©4TßG1Hn84ÅKí±*.ŠKÑ —°·ÖOÒB:î¾oRnßG”nŠ,}±¶XãªÊ»iZj¾pà̲Œh¶Ýv”¡gKG‡×ú‹¬[7´V±)ˆß²‰€HÑfWŠËm+˜4S²‚™‚£ÑÄ»ý'7Wå]Z^ò.ûã­‚¢×‰îç}Œ.üYxýñŠ˜ Ÿ ân¦Dåœ@_¬G 4Æ>,’yæyŠÏŒãÎxstmA¸êNSa(Kú@¾™Šß ¼AJ)8RKV¡œ âP#m]Kµ¥{»éh.×™]{ÆO¬"plùeïŽï ϾúÌhÅx.}Ê­¤}‘ˆøò(Ž:Ð_TqWqWqWÌUÌUÌ-hWЮ ]¥E¥E¥…¬%rñûE $2‰ èŒÎèÌG•ÉÖÌÖÌÖ¬Ò¯Ò¯Ò·Ñ·Ñ·ÑW×S×S×kòªÉ«&¯’w&ïLÞ™=9{rödYo˰ ˰‹°HPßþ=?¡¸Óeô!b±f•™Ö “J«’kʰ@³“Ò}H¹Ý”ÓÓRñUŒ'mÉ8ÒŸö§ÞÔiO.Sfc‡£!/óK‹{”wÝXŒr6tãkdÀþØ`¥T…ëbõFõUÔŸty×2Úò‹ËK‘v¾ãjÓ‰hä¥ßM½­¦¶Ö¥õÛ%Š÷”#Ø¢¦pÖ;ÓN‰}G¡¦Rz¼â}åôšóïò×WV=ßÿ.,oò=ßÒÊ^oþÐ=GïË‘‚€ª¶…%: ¹­ø%0ÀA&±!>A7à í€Éô]J!‡qÉØŒSˆÀ{|B¾0…þrðÛù5ä¹ð‡® IÌlæ2sb·óŒ¡Þµ¦cŒtÕBn07å­ÂûÝ…7f^ßÕéÉ~ò””Á…fá9Xø!™²Þþ÷_:~ó%@§ŸN?~ä¹Cîä™å™å™ÑF´m$ûU­E-j¿û»P?üÜÁD! Q„BHIvIvIvìÐØ¡±CmÚ´¨ë£ë£ëcWdWdW¤4@i€Ò€´õiëÓÖË$³ »° Ó1Óe/õ" à§-îÛð ¯Q:HÊÏ×t«-,N¬×.F5ãËDÑùÒ[’+:Šåº‰Ú13HM]ª4šÆsJ´=•r•ÒOh€Æ°‚YL#•¹H:’»8…c8$5æ"èúJóêîuëß!ùàÿÊžB¹Ìf²ûû% §º$X¶×vp3-׊mbÝ^ÿk¬•£¶£¢‡ 5ØÁðQNVﯰßjq ¯l7˜ëjîomÔ<®x$)ˆ›”~¶èÔKûw_²|_«¥HòŦl)H‰šVšw³T¿|Õm¾^è‡uèøU¬Óƒxà&îaBŸ£/×—^¢VØKˆª¿() ?^•3…!°w5éjîu3g¨‰ûÆî«Ûw1³•VN¯m[5Iš€Hÿäµ»ï¬Ê5)<_®Àj1ÃÉ i!w”nüHëÅKQ?¦~Lýs‡¹ÃÜád¤‡¥‡¥‡Ñ]ÐEæ"ò÷¹_¥W„"É*¢…¨ZÓZÓZÓ8Ó8Ó8S³cfÇÌŽ™l6Ùl²Ù|‘ù"óEÊNÊNÊNïsßç¾Ï­Ñ­Ñ­ÑÅS<ÅS Ä@ D²%êóS÷Q8ŽkÌ¢ˆkuÇ%ޝÜëeï*¦`2›Æ˜I{ÖÆÁ]³\î’HÊ|Á¼… 9à‡!õÉÈ¢ýh2Ì¥”^ €1ô /ô„+|Ñfd5Æ£‰ H9„¡Ò‹Üengä“8½Œ‘ˆã-ôTƒ•×)l5ÜÑ࢒¹ë ÛFŒwëæWÍ<Ý÷ØÓ7ú¬³HÙRõ¾ò\ùH@a3M~±òAQgW8,Õ6rEãzÃIJŠžùUY~(«2ü0÷ó´ÒÌðU rgß=µ,uy’áÇéù·KoT¬[/]%Ý'½‹®¸ŠÇü90+]ò‘l&JH§¦Ü^4åÑ+Ô׊÷²M±E(Cµ0µ~GêEa¶0ÒVÚ‹ÛO϶êëtÖ¸ïÂ{#fº•nªê[»™­Q¼/'¿úæî¸pß(“„ó_L˜Æä<IßpýèF>£*ê ù}ŒPš 4h6 ÇÉqr¼èaÑâ‡2•]ªPý[)î?†WµÝà7"\Â…¤T¥T¥TUÜ­¸[q×ê…Õ «ú&ú&ú&J¾J¾J¾I±I±I±ÅÎÅÎÅÎàå` ш–E¶©¿MVàÉOYÜWã6ÂÙ)ä>3˜kB;reEÛ+?U‡c2cÔr„jÒaj{ålØ•¢Õ,aÖÔHÁúP…â7ýÔW_3ƒÀ¼âÿR`ÎS1QuT‚]ÀF gŽ1·HCæ&iOŽq ¸1ÜÓ²f†ÕæI¨@5’.|Š,ÄIÜE<¬;Z,Ö‹l¯ê|Å8ÍEÅb„Ö§r‹e:³l"LÆh%«;j¥²M'i¶Ó-ÏjBËMa¤EkS­ÃÑb—IÄÒ~#:4}ôåeNõñ¨YIó ž´Œi”þ¾ðmâ™ ÍbÝOúYL °@! @¢uD¹ä0íå4ŒfQ{,†;Fb'jQ'‹Û A©ø/©·ÞK† \âܸô²ú(ME×]ÆAc=ûÊ/”7 ½˜&¢¢ð›7Ÿ…§«lX{Ê>ÊõgÖ“ÙÒ%œ˜Và ؉ TÿàŒñ; qXã°Æa&Љb¢JRJRJR E(b%Vb%¶a¶ýmïTý ’›±›eU[¢%Zf/Ë^–½¬Z³Z³ZÓj³Õf«Í#5FjŒtšè4Ñibò–ä-É[²-³-³-¡-ha!b!–c9– “@à§÷HÀá!*Áá-XÈ—wô–ÎD)EŸ¡)Æâ³‡\'3u½U•¥¡àE °=ÐËñ±¿âøu|õ‡CÌÄQŽr”‚“ÃÊbb0˜´A5“äÓH¼@4Õ§=°Æðù¸)KsZÄ!9@9^ª[•#?Û5y¦9Ïb‡!£v°ý—×.¶.wmØÉÔL/Qi¤j ÒDq2úŠú°7ù7¢K†Íô›+õìý‰âzuïØÇ\Ÿó¯ì#1K úÒ«ôò»fé5ùã^NU,ºªõöÒ›gޱ·>V9ÖhÖ=§ i.fQ@ãh¢%ˆ96šéÌ- ¹4˜‹¢=h½KkÑ[¶4É+ñ‚…^@@@@à—À»hŽBw4!ÇÑ”GÙ¬:¥Öcp“RÛë:Û©C]œiJ™·KÛŒŸ³~Ô½ÕµOëÚI2˜*rlƒ|QõÇä*×i¯Ó^§=SΔ3åyzyzyz¨BªÈsòœ<§e´Œ–ýÍïoçÕ÷{¸‡{2;ú-Ü­â.Å]Š»¼¶xmñÚÂf®Í\›¹zÓõ¦ëM·Ó³Ó³ÓS~­üZùujjjjj*íM{ÓÞ²DNüzß'­÷Oàƒèç> Ýq‹Æ!µ0+èR}Uòj\:›l„5,ÄWÙEL[“£š£Õ&¥¹¼( &·0)ˆ­ÿå¹Ôz¼•z."’ ˆ¤ ÀH˜Br8 P…ÙHÚ œQ'[I)yO6µlzE‹*Åx‡ª§/ھÜÆ$.S ’ß&n¥¬ð\´Ó]Ëá‚ѯAÍZ4ªj:ÝÒO«Òb—aªÆ$Ã!Ú_”S˜Î╤-“­ð–I´‚éqõV°PÔúÒíë¸'µC«:Ô-T*­îðZ!­Wñõ‡JÑ#2î=}ùñýgi~›Š° «œË¥¹u6åZa€;üe1÷-Ò èVúŒÆ\ÁzQt/n! kq¡HD:òŸ6¼ªÝî°e˘.$HZÇM¦}¦ìï;±™ö¨1=íI¬ªúÖ¶€<á˜ÆÅ$ã3ûå¶+yÀ¨‘D™{A}iXYŒöß>,2¯Jò[*µ¡ mrrr2’Œ$#‹ŠŠp —p [±[a3˜ý#î]}ç–t¤#]æ2ôñ¸Ö£Ö£Ö#Î5Î5ε"»"»"»Ñ…F]0»evËì–ÊY•³*gßxwâ݉ZÕZÕZUÜÄMÜÄ ÁÞŸ^Ðþiü¼â>wñŠ_–)jUݸ¶쥶Ò,¢…6Çô`–“‘z&ªZJ øöd=éNZÿî#‡·Ðó+P::“棉”RWJa=¨“©Ä™ÒŒÜÄ.Œ@Ci·N¯ÚP3­.¼jS êÂo"üFòª›G2pÇóÇFÑ N¹´ÖÑ=à lúRÓÒ=Ó>¢a§¦5Ö=uêŽhp]1 ô¡Üq¥%âeúÇ•ÄTúi*JÑJlÜ*´RMÛÿefYXôª¤øœ;¯:%õÍö“>±hs„mÜðÏÅm‹—Wæ‡%¯–FëÀô!žC–Ó~4½8_z–šc/.â¹°)V@@@à‡<ä B j!a,È1"‘îå¬èˆf'íÆ>Z2N­¥f݈jßÚËâdE©Üú%Æ{GGF݉nŸ2šÉgšoÎŽ›Aà +K«ôûüHóê©.t¡‹|ä#_½T½T½”1d Ãûû{øÃþd;ÙN¶ÓJZI+ÿqw“W’X°`áxàáEGÑQ©$•¤’ò½å{Ë÷Ú(Ø(Ø(è*ë*ë*ËåÊåÊå¾×¯ÿ^¿¤kI×’®˜‚)˜‚\ä"gqge}Ö‹ê#ðwågwxÐCx ïU¹®æ]ÍN‰-·\tŽ,Ç`¦9Ë´Ó{¯’ ØÀykÐnhxþ'LžLä „n§€‡4•¸9tG4ÆQ,D#¸Ãº$†ÃDâ@>“uØKÒé™Í ”R‘‰œ; òÝå^ˆÏêÒz¨äj± ¡§FšWUóÎæÏÛÝpò7pµnn£ê¤ùXUWÁV”¡ä&÷?¥úfþFËU‚ÍÐh„šq_t>o£Sm_êW³9ûAEy›÷Å™kK®F¬L˜˜7ëΚ¨±)I Û)u©hW;P/u’NGk\ÄCþ‚˜éŒ©!˃djÇBsn$½Eme›b‹QŽ •ÂÛ¶€€€Àß Þ’ZƒZH‚ ˜Ji8½¡´N!Rnâ~ÃY½¼‡häqÀï»Ëªú ý@?ÐL“Ƥ)×(×(×TVVV˜W˜W˜ËZŠ!†ø­bò×ÎßßQ…Qp‚œp'q2×)×)ש¦CM‡šÖ·­o[ßÖiˆ4Dõë5ÖûÐäC“M²²²d½ÁŒÁÀÁúþ†YD¦k¾ÜºÔ¢Ñ¨’ÐtØ ië%ëFPº¢jŒêÒ–$îr|¶ #ÿ›Ëã­×Aí(è4c(¥ûfjPúlWP_JŸjÔ|év©Å„­—“Ötèû$¨éÀaÍæu>áÞÚ¼_£µšüûs ‹ˆV19Ò”T’U¨D<Î"rƒýÚè÷÷düçÁ°l_^µ:kuVšZšZšZK=.õ6‹Íb³Y üjT¡ M¾HbmRËJDì) Å›ƒ¦7õŽ£4rHðYéÔǺÓÕ ì¯¿™|Úq·Eg½Æü·;r•èËzûc~’‘Œd¾¨¾K}—ú®‹[/n½¸õɤ'“žL²º`uÁê‚ìÜ, ÆB¸ÉõîÎ×û£u¨}¢ÿõÞÉ[Ë[Ë[; wî0¼cXǰŽažšžšžš   ¤’T’¯«|I~ûï{øñó®2ãpŽ>ˆѨxIer\­“t7žT‰w2K !#Ñ\ý¶Âtñ]¨X‰°…1¾“·½ú'¡ˆEU ”H8)58ÁúÈÁ ¬ ‰äOØA‘6§#°›ÃZ<Éë\´¤üÉy“Ø‘Ü^î"-Âs(ã)JPš?æ"È2²Œ,£R*¥Rµ…j Õ*è+è+èç?Íšÿ´zbõÄê‰20¿EUàçà½Õ'þë£q4.Í!Í!Í¡êRÕ¥ªK–ù–ù–ù†ê†ê†êÊÍ”›)7KLLLLL,±-±-±Ås<Çs,Á,á#Ø.4'~Þǽ=6âr0~%F•ÕoªÇ×5–ÞB7òˆHL@õ\¹­¬òQŒT ÑЀPŒÊ¿Ù{?Ü+Q:Y)z` Çp %‡”"g1ƒ "GI8ñ$¹˜Å™Ò`úYâ(•—N)šQ©¿ö&‘¼ÊÐÔôUŒ]š;Û>0ð·?Ùh«ºv3»G©nwlK ²lUŒWª=ƒ¿œ³B®¥bžX^Ê£ä´õSô«té„VŒw’”V=Òž|)/[sâ}¯œùÑo’êrº¿Y–îR4=âT\Ýçëù#‹Äå7J˜/»‚&z‰"­±ŠÍf܉?·“Ö`!gÍm£FPA[,ü£ü3ù—åÍFŒ?I%N8ˆ-t1÷€›Lµ€zN9·Âgékƒ!zÃ'+pY@Ù\fú¤¸¼qŽ9»däþk³=˜ 泃FÑíœ"–Â#Á|ŒvOOOù òä/”/._\¾¸fEÍŠš²È3|\Ÿ£¾ünìÆn´G{´ÇTLÅÔìÞÙ½³{W*U*U*Ùô°éaÓCÃUÃUõ±¨±¨±è½ô½ô½4‡Íasd iCÚÈÒ]U¢•4“fÒLY Ðÿ Ÿ-é(¯ð!"u‚¸Ç@*]~wÔKJWfŒi¶`lRw7²“1a& íဧÆHAn2šÃFX´G$B0”Ü#~xǼdlI?v)sŽ„üÌ7ûê¾Ñj¡2¢ñ1‹ë:‹''õC³¸‹/V é³$5ëô»1½ËÃ﬘RFé³}3¦Sú¢xÖJŸ_™‘LiÔÚ™§(}þ$¸¶jÍ}¹éÓǵñW½7zÓ±þ–ÆûKÛ‡µÓx¼q‹;Ôí÷ˆß‹ÛˆüîôECØ~ aî3–d*ð‹á +èÂЀÄÿæÅïoàã. ð_"1X¨@r˜x±¬I­ßÄz»éV½ÙG>«·ïò.øÃŒÃc$v½(‡ÊÈä@ŽJö>¾róßžý Jåɾ̛ZþpXEV‘•yWwíݵw×Þ1Sb¦ÄLYw`ÝuH9)'岦ˆ@„0~¤Þ?}èCgpgøE™¢LQ¦c+ÇVŽ­¼\½\½\;Ìî0»Ãls}s}s}aeãïÊÏ+^üäA `è¥Ô —¸À Ía Ž6çN¨´•O3ê}ÞÈï.ž\©QOæâVS`= ÂÅ $ Söw ö”P‚”PBýqž´‡3ŒsœˆÉb¢AÖHR¥'¹ ¹ O—#…ÝËñ)È[ºçO¼{-f‚[mpZ`2µå'‡}› £ µ ×ö¶· n9,3å´LDÇ”•Eçf«¶k•>ê:`Ü]£³ÜG/Ú?ü|S‹,§‚«UŸbO¤8^z“ÿ¡$gÉËÔÄÏÙÇ“k>k”*½]•ò>·¹ä„ÔCz'Ðþ‡ëŠÅ:¸0—H?òi¨€­DKº•r´9à"!N¶øË vz0|üuî_M@áúÀêN÷£»t¥ÔÜ*Ÿ¼Áù±­|›;õ¢gµódµ)òÞÏ>ÏPn+ŸP²ƒÝÀá5ÀÞâr˜.rfrçåÚ“Öx‰!ˆÅE„*” ‡2T¢ö½F^­œŒÉ˜Œ Ø€ *7Tn¨Ü{-÷ZîuEXEXEU¡*T…cbLïÒ»ô®04~õmáÙÈF6b " YÈ’H $q'âNÄ(ïYÞ³¼§i¼i¼i¼ùBó…æ ß)¾S|WТ EA lÄFl¤‡éaz8gIÎ’œ%hˆ†he(CYf}øNøyÅwP„"¤ ¹…_ªÕZä:i †;ÏíSö“{&NPÛ¬è+¬xj¥¨Š%[Hox k.ÿaÖ ƒÒg(p"Êàc YF1ŽìÂ$¸Òµ8€ÛE×ážÔ[Ú‘[ŠØéE,Òc,žºÕZT7ØF˜LÔo™Ú0[Ý©UEã8ã6™ixÏô‘ÞIe1+jÅÎÄÍØ ƒ·†Á*Ôú#•‹» ­’I34à†‘•9ù¹ý+´“3Ê ãDig ="5ß)åy¸à•4-*cmNDÉS8c¦q ³d—Ág¿ëÅÎcº“!Ä…Ô‘8Žá–Q.€†ÒƆÅ8+Ä¡ø¡yˆP…HpÛá/ e“˜“’ÕÒœÖâ :QY,ÿhz¯þ^ÍºŽ¿Ûã­£ªQ¶á Õû€$ƒNêF’ýuÙuŸ$j´íE‡“4QxEoR®öt­Eí(ÚͰ0&‚ÊÎCAAÉqrœç+Ô-Ô-Ô-¿(~QüRšXšXš h@ƒéÍôfzKII äÂ0À*¬Â*ÌÅ\ÌM’>$}HÅÒŠ¥K­/Y_²¾¤ßI¿“~'Æ' Ou¢NÔ¥6R©MÞµ¼ky×dY¡´¡ mAqÿ¾ø®9 Ë?Uט‰æô2íOoª6•¿+wX«Dñ‚üÜO5è„@<ÃXÒm0MPÝ!õU 8 ÅBœ¡ À L0b°£ €®è{æ $eL3ÉXoÔæ*v(SËE!ÊðÔ"vrâÞöUÚ¥°[¬iÓ½Qö›Žþ®ÛMã›õ²Ž×.´7mä§9Úܼa£ÊJê-FŒ6g£§­ÓYAQo•þ,ã•mÐì£ñ±ñsª;IZ•I+;µ*I¹œu­œ ÝñöBvó ^^JÝ—œ˜YX¼?Ó7o|ù¶²f=«™.ʉ ‘éG‰: Àvú+èDÐkˆD&Öá^b5ã)ÊQ…™×§ðæ' ð}QßWXJPÀL„éCì¥t*Lx«EƒSêw”’†wï2ßqwPvçr#KýÙªþ7M*h*¾Rv²†=¯û8ôSå*§“ý­5 &™«îŽÜi¸cdÆîòve]·9¸,æÎM—î–îúÓ®Ý&0¡Á4˜c–a™òåÊ#È:²Ž¬«H­H­HE1ŠQL®‘käÒ†4aÈüãmæa¡âC|òç-Î[Œ-Ø‚-M†7ÞdxµWµWµ“Éd2™Ò i…´zЃž¬>Ó­ÀwůPÜ ’+ëjäÐN0á®ÐƒÔKÑ[|‚½£zM~«¨l,­€'àk !߀ZÔý¨â!céSÊpR© X…h‘pâfiJ.à$NâŒÔ€{FïVNª¾Y‡$! 1Hr˲ÂPê§!—Ûj–Ó5c+›‹FUªE-ä‡6¼Òô±µ¿^+WÃÛªEâŠóØZ²FÜy§Í;ŠV.ùCgºÀî‘ö©i8¬ñØâÆE‹«×ǹ¥é®zýèƒvŽý«Ïï§çç¾jö^-wKÂøÔö¹×%ç¥ÎÒÓ8 )€SÄu鲦$šªÒ.¸Í ¥h;z™V ’‘Ba대€À_1D`eù¼w`ú°…Œ+i+Ì ¤t2LäBÄ1¢w#.tiëxt’EŸiM>8«ØtÑy KÉÉ4€ZÓ!4…Ÿs›îÞLž°QçLÊ«»QKú}–ýFÙ—6¬åÝÎ~ž=Qc®ÆJµæ«LŠM¼RÚ¿Wy¯‚•XŠ¥hŽèø'$6‚!ÂÝänr7‘‡<ä©…ª…ª…VùUùUù•ĔĔÄðQÞéH:’Ž”E;žê¿ŠP„"µ¢VÔŠ"‡È!Ý:Ý:Ý:ÎóãüD{D{D{Èj²š¬Æ ¼À <Æc<–}—ß.,ð]ñ+÷,Q™eoÁ8(Æ=£&Ê¥âQ”úGù(1ÁS\°ŸtCs ³ñwFZÏá$_PH[ÓýГòÑ8u¡´†Ñ ®0"wÈv #*ˆ&ˈ!‰A`åÊê–µº÷Ï¿@ îãÀìÄ%ÄžÒFŒrHƒ¶êN +=‡»^6Óõéí>¼Ñr[=£ joôÏiWz£ºYmœâ@LW7Z%òm yJQ¸6Œª|¤qù[ŠÅUoòû—L­œ뙲µhÈ]·——>½8ìÅ•ÔVÅ*ºÔn(9W^}BR"M§ vXl&SHna2Žá §BS]ú‘š`JP:d ¥(F™¡V@@àO7(ÈÉÖBY0Œ*ÙO”©–Sén ”[$n%êä{¬µ·åàÙ-§7Km>Þ±¹þa@zSz %ÔLZ+u€4¼8.+kï2ŸÃ·#çßÿðòJúXCédö3«Á(p&ÒtîjåËê¦ÕS3’ô’½ßyõ>jWn_f_v/õ~æýLbC‰#ŠñOÆ$LÂ$jL©±(E”"JÑÐÑÐÑЩ̬̬Ì,Ô.Ô.ÔÆ6lÃ6:”¥C±‹±XDÿük¯ý(Žâ(àóBóBóBgg纕u+ëVÖd×d×d“§ä)y*õ–zK½ùû%ëG°¸‡ü Å=/¶Ü¤râ  Î˜Ãèˆ:²EÊvâJ‘»€LGc˜€à# ¼KÿÁÓø_ä¢å8‹ûˆãÿRPà6U@c*B5­ÅÒiØÁ aÞ âO¤dä¤t17(oI±KòV£‰øØ¢ o×±‹xÙ€Ý;t4zêÜt»ñ›æ /©2ŽR _½¸ÆGÍÕ|–»¥jÁnDJÚÚS3´¡“¨”a ‹ÙÚüà¥bq¿2¢rUÛÜgs *›Eqï ³õŸ\‹þð1 ¡É§%ÅŸí>®)ØUbTÎTéü¿ë+þZ`Dd."qƒ„Ù´’¶§!T‰vÀZtÃtþ&Sœ`Ïø­àÕt~ýsF“ùL¦“·\wzŠqèHÁ¶ôúÔn£MóÉN}ÊœÛx»Nix Óéz@Z' ØR‘ᓦ¯gØoŸ|!þuéÿÇ:‰~²£´…“™KLg m/ÍæBf³µV©&µ&)nmܦ¸-=Rz<éñÄ|¯ù^ó½l›Ä&qg¸ÓÜiÌÁÌÁ¬Áš?R0¤éFºQB % ;v*ìTñQñQñ©1­1­1-ŸY>³|¦¬é~nCø—Æh€¸ˆ‹¸È»Ê¾3|gø®QÛFmµ•>—>—>OòMòMòÍVÈVÈVøÙÞ²!úÙwÆRÜ녕ʽ.͆# DGne¨V‰4˜ZÕ¢ÛLkš8Îh 1® ¢ý RÚ¯ïÖô3Ì0EºŽ6¥ Žc9‘©¤C°þpÆ%ÜÃsL§Ûñ”jÂ[£FÆ?ÈÔŠB<2ÀÐÚ¯¾Jy¡­µÉQÍývGµÓ*ò¬pÕ6+o¹Øþ½®–ñ Vñ®h¶¸5;dz”,UÝ™Z»yJcDì`1V={zÚ:xEç=¯ôù¸5ûFÉ•÷ã2NuQýþeþÅ;3£.§±ñE©Ú¹+¸öÜsº˜“ÐÕhn2­ü2ìˆ>zA…-dÙÎ\ ¦Ž\97ŽÖ¢9F`»,ªƒ-V@@à¿CrñÏO¦‰!¶¢®áŽRgÚGäzkZn¦¤6à€‹¡¯q«I¦PÌ>¥öçG;$‚”'¬Ls/ž¹~ù)ó—%'Âî)¼ÛW׬NG2‹œ MqÎpESšL­°†ÓæfÑ-|l7bL HgØÂ¶i¾i¾i¾%—J.•\2ô4ô4ôÔo¥ßJ¿ÕgÏÏžŸ=Écò˜<¦kéZºö}Ú Æ` æ·H*ª(ª(ª¨5¢Fª/T_¨¾P¢S¢S¢ƒ$$!‰Ò@ˆ}؇}°úÕðn-ü®Ò؉¼Ê®‘¯‘¯‘o™b™b™B¶‘md[ŠmŠmŠmvÓì¦ÙMqp@;ÿÞᑈDY?ß!ÿIqÏGÍWo¹’Uçkp!ÒºyA& ô… ¸jöÔ‡…s_ë!Š“†öê×øÃ^E6Ï”ª”CE_éx. Ñ˜üÉ#7¤jÛN÷KsŸG/¸Ûø]£/‡ò4K²p˜Ë !¦t:—Nƒ¤Ï¸Ftª,%S êdK¿Qª¸Ü îñ'þÄÿóëϯ?¿þþ%üK¸ýûöLUMUMUÃ*Ã*Ã*é:ºŽ®ÃLÌÄL¤ )ðdoâWl¦ØL±™Úµ7jo ,.X\RZRZRÊ+‹tAg`ö`0è~õUmÞÑè)žâ©è°è°è°Ýy»óvçUUU‹Æ+—t#éFÒ Ä 1èŽîè.¨ì?þ“âƒ\”ðÅšáR5®¼hhÍÀºÛÚ¹r÷šrN´‹î)ª8—¸Ì{ºƒZr/pþè­Bd™¿õT’ñ ytÍ@c)¥(ÐZPÁø  Üa rk1t# Gˆ ‰Å´ò• ªCL1]vÜšzqÃ~Œ¼àE>’äczzú‡ 6|ØÐŽ´#툚š[ÉV²•Ò@i 4õþý1ð)Vb%VÊŸ—?/^¥»Jw•îYáYáYáå­Ë[—·† l`÷ݯ€WµáGœÆiœæ×^¬|¬|¬|´|´|´|ÊO”Ÿ(?ñnÁ»ïÔJk¥µRÌÇ|ÌçCs~ÓÀßä¡õïy‡|”‚€º³Òœsɽš¥u¦ÄE}™b!j9îŒf¤¢Š|™\­h>û¥†«q,œamA¸ÿê[¤sPˆrœÀm¼Æ Ü(ÁV< OùL±”Ã3Òµ8Å4d¥D‹¬“dI/q1…ÍKNUö)D‰†,”à Bñ^Ö±ÅI£ zµÛÑ$ÒxŸ3,ä5‡4±¶ÔÑ5sØdf©}_û²Îq¥ ½Ç¥ªNWm'« õþò‹ÌGšJ4U»ŽlÑÇX oË[ŸIž^UÛg;Þ–e=}1÷Æç}Iw>%W¿–l“;%+0/§”  4~êBÉvÒk˜©Ä…D1˜ÇÄ@ê!]ŽÎü‡²½ ä›Í±-H½9Ê‚’aD—ˆn’ž\u£¡ÒîõÖ Òz§º`ÜÕÓ§뻳Iûñ –+®ê:KméPéÛBŸÒ¢:¿£îž~[¸cÙÅG±÷Sò2 âБaC˜sd6çBÑÙ\snÕ‚"ÞC„jÔ@ò+VòDADÒ†´!¦` ¦|˜ýaö‡ÙeÓʦ•MsüäøÉñ“š¹š¹šyQzQzQ:™Oæ“ù‹; ,Ô 5¾B¹»rwåîŠ†Š†Š†FFFÒÒÒÄø?z„¡G„aø+°‚¬d4û¡ú™ 7n6Üp›á6Ãmu±u±u±Il›ÄVH+¤R¼Á¼Ac4Fc!˜òß•ÿ ¸Óp|Bl!‚¨º½Ô\Ú+SÅ–ìg“y.‘û¬ÝIiœÂyù¢ÁÌášquø‘–0¶0R~"Sl$ä0ˆOË‹+`)ƒ=˜‡¾¤7‘C,ÂP8Ae؈Sˆ¢;éUÄ¥Ègv*NA& €pŒ‚“üt¹¹V ‚5ÓÍÛ(¨vlË9{™lôÜÑTÙø­¶ÑÕŠ>r»EÇ/¯.²ˆ:6ì¥÷Z±ËÀJƒ7m¢±¹ÕJOÉêDO¶E—Þ§}Z]ð,iifbÙþ;r/N |³,£k•]ͤº©t*Çl)èG iO’‹ˆ “ f*{Ž=A·â±¥¢lQ›/ú"ú‚Ï4—æBJPB5*Q) ?ú™›­`ŽFì&–Ü”ºpjÔn*k”ºËožÜ¿oÓË#UºÚ•Øêš_вC|í§ºýBp³¸)?ç{Ÿ¤,\Uttxd§7Nžåøó!÷H/<Á!ÜC¦t7—#°,0²,ª¿)¤Ò×ô5}„ $útôéèÓåÊ/”_0Üe¸Ëp—f•f•fU‘¨HT$BGtDG\ÅU\ýÝ¥ÊG 4³1³ÕO«ŸV?Í…p!\HIjIjIª,þIªP%¨’¿p¬Š ‚ä G*H© ýh?ÚOO]O]OÝ´“i'ÓN”RJiŠ~Š~Š~á´Âi…Ó‹\äÂö°—õ#Èùo;@þ=¯‘…|è@Ií!É©vÑ—ªÊšBÈ3÷H.[²‘Vªµ’—ˆ¢Åí˜f%8t`m¨!W¯À¿…ÿƒå¸@A ¸„ƒøº9Œ·ŠGw°d 1Ä}Æœ%"bE^>Õ¾5µ«ßHÙšƒ·HA®à>“;!nÏÞÒú¨ÚTA¾ýÞ¦Uf¯¼k›õ4žl—f¼^}“ÕTãšótî6¸¢|à^SÌe—Ò‰¶0?¨io ëHm=’$q!kû¶qºSÂTD×NóN)¹rkäs¹t»çLüìŒíÙŠÔ½IÒOo”TWz¹Ô)—”^(žŸ˜M:\2F2JÜR$]“ÖWÙùëâø·ß¦Þ Ø:L7ñ eØ‚'¸Š}¼Ê®î®â«¨Ð}Më'~sw yÑü¹ÃlË@­7—›pm¹€U»ñ9L=Ýv 9Ñ÷…øY»×>•üÙÇLYÍ…ÑI´õ¦—á %(@Œ*¤ Nvtéÿà¨À«_D u;ksÖæ¬Í9å9å9åZ·´niÝrmäÚȵQªAªAªA½§ÍïïÓ¬%(a&`_¡á£á£áC—Óåtyñ¹âsÅçP€*û/‚—[}6aF§Ñi-5Zj´´Þi½Óz§h–h–hÖ§ÈO‘Ÿ"3Ë3Ë3ËeqÜ}àä#ù‚ ÿÙL@;4%—± ÝùŠMŸºå´R¥tÍα65Òņ;ä¿™~Xà µOÊûec/aØõÏšÀoS/0i¨C™4EŽ0W]Ò“ά'sQ‰°û÷ݸô¶ieØqhNçWV7¯×vN„bȱ¡wKân‹§úQÖ+h ¥a$¨=¥á/fô¦4,%è*¥aJ_(žáOidé¬;9_.JüwïOßx`Òüsã¢L£ÚÅe-)œòðòÊËóFܘã>g@A´˜}Êl!§HO|ïQËN5¿|èFžÁ莖ìdæ9úã†;™¹Ï`˜'¥£gî¤ôé½€õ”>³ Ü@ièÜ ÷ûom=ðsãö¶Žþ5eo`Ü™5¤˜4†+`úOªß–¦hЦð„'<hD/軠1b&ÄLX½gõžÕ²íždF†ýAÒ6ƒÌð¯ñ P€Âؼ±ycó^×¾®}];mÿ´ýÓ¾j½H/ÒKž?K}7ËC8ÄodN*œT8éîëîëîë=É{’÷$§§§Vž•gåùœµð€<~¢¿)ÿ9ªL >3í‰ K¨U.SaUÙwÙRæ©ô w—6W•“›Ãöµ!ÇÐàh@I®ÀoF}+uJPA  Š´' Ècn Ž0Â< G+ A'Ø1MH!ö‘YDæÒ)ôMÌä¤ð/[b.%…yÀw¦¯ûâCƒ!ªäõ› ´;gxÁsªëÖFk\/XÝmpÒjxÃÑjí5T>)l&[”º3Û® ­Ñ5ÐhA϶¢ßƒ&jë¥5RÉb·µ“ZÏy=§;úzvï0ã‚ÆÖn Ë—Vµ«ãçB{”‰%¥uÜyº ³±·QŒrTËVþøIÕ¨…„ø1Î=L„t3×6!Ƥ‰éâÛò³åŒYMYºöh§Ö8Ç@4u!éH逞}Óé}`þ§eŽG×GÕÞÈ KüP^Q«^‡0LH"IÂK:•®GG.“Φ岔L?~Rý¶$! IŒ˜3b®)×”kq+âVÄ­A}ôÁ Ô Ô ”4%MISêFݨ›,b÷K¼ÄËßQæŠP„¢l#l5ªQ­~Nýœú9ZI+ie‰]‰]‰00ÿõ×"üá>êŽÈJd%²² ¶ ¶ V›©6SmfqâÅ=’Ò“Ò“Ò¥5Òi La SœÀ œÖ4¾A,fv‘"¾<. Ùyošµþêø„ §eC¯SºÒcôGUÝYš²÷Û{ùŠžû) Õ Z@iØè Ñ”>]Л҈3ý^î6¢oï¥M×ÈŸ­ýæA¢Â6$©Ø‡Å$«âaþø‹žÄLb&A ZÐâ™ÃLJKÿ–þ-}ûTûTûTÙ&Œ„‘0™ÃÌï‡;Üá.+oÇvl_“»&wMnôÖè­Ñ[»©vSí¦*;Áâþcê[Ç`#¬ÅZ¬åÓ*Ùζm;Û+Ò+Ò+²ÕÌV3[ÍTUPUPýš•ß„úã~þˆ~I#ºÏ‘‚ÅPyRâÀ}Áfé)ÎŒ¡DôA.½Žú¦jRåÂø·¹ëŠ4…÷=¿õ-Ù‹‚;ÃJ8[(E7´-ID&¶a @k((ÇäÞ«ÊßÐÿŒÒ«^Gƒo;Ä»–¬jÏ„¤’Iˆ£bêƒCcij±X *S*QýƒÿúoÉF! Q˜õ ëAÖƒ¤§IO“ž6~Ùøeã—vÖvÖvÖ ‹%,b¢˜(&JÊI9é﹚§ e(óŠ#cËØ2¶šyšyšyœ7çÍyv-ìZØUEà'n'((L`¼Ç{¼çÝ97rnäÜк¡uCkÉqÉqÉñ¤¨¤¨¤¨²ê²ê²jY|>nLý~þ1ü2Å}þ¿÷Òuã$þt¤=À´#EØ]dà£a¼z´Jª P¿4õ•àx†D a¼(ðÕÚÍ·P‚7Äd'é€×LYA ɃÊêJÛªsq'ÓÃ+"”?ßÞ¹Ùj°SÕ£M{$Á5æ‘h™(¿9«\lªÆ Ë]²¿dî¢é²¥-&N>Ðk¯“æŽu—RÞÚéð`æ»^eN.\ÍŸÓ™< JÔ~ôÕ§½±‹±@!!”À?ú[º`¼À^ f\HÖs[è0RP “8íFSÍûïlzkä«NM­u•7¨‰åËZoÉ@´õø2:'¡Â%DáJt܈§D¿(Š-ͨê…XŒDÚ¬ )“ôÚÓÎÔœî‚#ÄØË‡CþaÞý©óšPjB܈q+êXÔ±¨cÚî´Ýi»Û¤·Io“n°Í`›Á6ÞÝ‚¾¢¯è+X–ø€?ì±ùmá]e(((cÁX0 5j4¤›éfº¹¸¸¸¸¸XÂ?o#W€ðð€/ë¼Òy¥óÊì’Ù%³KÔúQ¿‹‹ £Ų¸1|ä~«À?Œ_¤¸c}Šxº@W[!¹_5E²C*•»GŽ’{â¡ « ¢¡tAy'ð#­çŸZŽJÔÒiô œ¥RÚšRØ¢t0ŽÔŽ1$¹Dãù°[º×CüžÜšz=ä‡>vBƒ¹ §«<úÚ²c’º¿tœÜÕÙ]j’Hª¬?¦ÁKEå˜hÙ²bò¨^süÏÑÇÕÉØ¿ö†Rüó·ª:fó‰Ëb3²v/AîJ‹¸3tfa3.Ë–éÿ$›Ÿ€ÀD½qNv¼f¶“$XªÀu 9P`£áFj›3Üp½2²Ög¾“öNí5Š¡@Ýi@;Ó•¥¦•w¥}Ž4¼Ô?æåކLc¤ïeX4Än`“ýH£°™’ÒªŠ#Hþ!Þ{ýìÑ–a–1™‡ÌC©ŸÔOê÷!íCÚ‡´*ƒ*ƒ*‡‡‡ågÊÏ”ŸU¸V¸V¸[bKlGƒ,êÀçòT›¬6Ym²´´´AéÒ;¥wd-“§~´Ÿã8ŽãüŠ„º¢º¢º¢ÍT›©6SEA¢ QPÆÄŒ‰3j3j3jq ·p ]Ð]ð_ðE¤ÀiádñäËÎ÷Œ®ë­Ê3÷ýP nÇRës)]0zÈFE߃múòmÈmÁÇ]àoŠt¡+ç3H,‰eŸˆºŠº²"C‘)»T4BäÒ—‘ù¿Š§‹.‰Œ=´\ m¸µ6©ïùŠë÷šO-¡4rÈÌm”†~8AéóNÁ[ ÝnLv>²pÛ-«©ºšAK~ÂÉŽBT0œq ×H4„T  EÈ Þ+xûº M¨A™©cú’àúMôX¨D¯t¿Í£cf× “ÇM¥ôyÿà[”>Y;}=¥Y3}*ŽÜ»7q7ù¢nœnœnÜ›6lîÞ-¼[¨3Wg®Î\Ù̆Øa€Ë‹±ËåÆÈ‘ãâââ}Àû€÷&êMÔ›¨3ÑL4 cØϞ+û®ðÌøEÏ BìQ EÈAdœ¥õX½\¢4üØŒ`éÇ'-BmvÎܺÏðö96ùj½•Ÿ)<øæ€ed 2‰Ò°ÍaÙBÊ'?—úáY§a Zä‘]¤–ðÕJF óä¶÷,jc½'ìånÍ!)}¶>è6¥¡Õ;) Ó |FéÓñAB³wŽ´»ëãV½¬úb–}Úä±ÂTf)%dUbˆþf£Ÿ – &ƒÉ`œÂ)œ3wÌÜ1s_^|yñåÅÝSvOÙ=…qa\Yûú z~ÛÇÛGò‘|äËwnܹñ‹/v¼Ø±á؆cމÅŽbGYÓ38ƒ3ÿБϻ»<ÅS<å+LLL<ó<ó<ó<==”6(mP*k·qû«ˆ…ç¶À‡2ä µa,Èf¾âfð°iÞ«)]}Ìÿ¥Ë;ŽŸ0íL™qÂzŒ€.T¡,O@@¿4ϳSЕ¹Åè“Îx…5°¯ßÐÌÈp‘V¯yQÃÛµ<êpfþØk”†+Îp¥ôÙ• –Òg½‡R¶yFeDÜžü¡Ž¦ô:ãR&ç$^-z\¿V‹é@œ˜~$ž8`~8º-^àáGjóŠiLFWD¡kýú^»Ú­±yöT´c¶Ÿ„Òpß™ƒ(}fØ‚ÒÐ3c(P›QÆ„è×ggûb[GxEF回o0ªÄ‡°dUõ³¨þí¤Jz’ž¤'_ѬºYu³ê¨Œ¨Œ¨Œ­n´ºÑJ>J>J>Jæ$3ƒ~ˆ@ÿ›Âtgº3²¬ê~üøˆ}û6öíü²ùeóËx?{Yì”X€ÿ ‘ÏK^ JPBŠ Ë„£3Tg¨ÎÐöÒöÒöÒŽÞ½;z›Œ3g2Nö­\ä"0€ÁÏÍ _¶\XZÔ!JÐ…<”¡Rܦö¥d€éxŒ,ªLí6‹EéªqŠòÑ4Á8‚G˜‚ˆdÔÔ˰8;p“ëÉÐûðÇA‚(,gw2OÉÙ´Ì/Ë /¯r;ú4bŒûš »Ofóõ§s’¥Û{äc“tm Çgº¥»·Ï¬öœÓö@ñк™óŸk¯3N£Vyª´{Dßrç©e2ÈaPDaLa¿­Z#ðç«üèj}¨# ’cÕÈsΕ{CÒWpÃM·&ö3n¼á·.´oÜùYË»j[çòÙp )—<ØÏ¬qœyŠfÑAÿÌUé};m Ä9Ë‹“Ÿh$ÆÁœ6äÊ ²ˆá{rƒ8޾Ãh,ýa-«µËH&¼¿x2Áû²gvÌì˜Ù±Ü½Ü½Ü]¹L¹L¹Ìf‚Í› ¼W4ùD>‘O¿‹ 8C0„/ª'ª'ª'Šgˆgˆg”F•F•F¡ e(#FĈñ™_ÿãŸ÷Dç£èLÅTL…&4¡©¢¢b-²Y‹äÖÈ­‘[ó9ùsòçäOŽŸ?9âîà†c8†# YÈúæ^ üj{‘T“e|ÅN—^­Ú®¤Ü*ë1iÜÝ¥G<Ï.c:(ßÒH§Zk(ÿ rx.O@à?ÀüÿˆŒ)9GtY}Æ›4®ßPQNþŽœýƒ¾›\†mÚ}zðJÃOÏșҧ~”F^Ÿù9ååÙÂq mvpSS¼«ÐTnEýØ\¦ŽD!‡0UV%þGîèˆF4¢eO†¾Š}û†¼yòþå™—g^ži2Òd¤ \àf³Ùð× äYyVž 9ëÓ¬O³>%½OzŸô~xÕðªáUƒä˜9Ìfœà§¿ù©ÿ߈ØÈ¯9ÈyÊyÊy6Ëh–Ñ,Ãûˆ÷ï#.^.^.^ìzv=»žWëÑ­Ñú'úø_`»’d _^¾ÇÇÐ=ŽV¯Ôc%½°$b„gщù†f¸™™Â°?èÒ—h røÔ÷Åm&0#P…ò’ CTý†ÊT©¡üÃ>'ÛÚ<f·«ûEÎèqBÀSJÃ÷ÌXEihmÀKJ#½gæe,½¸züÉ­´¼–š^6l¦¹÷›*±ØÌ,$å_C¾Ö{‘~<~}Ø/’8¦3XT-¾(¾Èfˆ•ĦõÚÍ0¸¥½K5l£Æ”+žóoXNžCiDÑLeJC[\§4bÌÌFY.;Mx|xðG÷R“}w Ïú‡"ud%>ã ®bÚ71RþÉ£Ô>ð!‡È!r:ÐÎDµ‰jÕø,›+,WX®°”Mè=Ìf¢!þ¶§ÀN`'°²³oV¼Yñ&uiêÒÔ¥½Ïõ>×ûœ¬ÍEö"{ò‡ü?â¾tFgtÆ\ÌÅ\²Š¬"«Î8œq8ã=ß{¾÷üî-Ü[¸+±&'‰'ávb¤ìƒGËø'ðãû½càIš¡;I[Y75ŠÒð~3ÆÖ¤?ØÐt[EÀc¯—v“L_è¼ûf˜g’á¸NêÈÔ ?¨éŒ°ú'Ÿ „q`¾Âê•Õ+«W×Ú^k{­íÓ-O·<ÝâÖÔ­©[S~‹$“Τ3é¿ÙÁEDDdwG!D!D!äàȃ#ŽŒ94r¨[°[°›,Žþo{Ü¿(ŠP„¢l×ÀðŠáÃ+ž¦ž¦ž¦žÆžÆžÆ; v|µ¬ŸÅÙo£Š ü>O‰·Dq|Ù+Éf{£ÒÚ’%F|®]¾Øc¸3¥«"ý/æ·}Ôd+ßFÀø“w‚Ü~ë©XO…Ñ„á KèJ²uŒY†Kõ7lÚÅÆDÿËQ¯÷»w.öº5pò9J#낃(}ºxz¥‘z3g•ÅÞ5ŸÚáÎê_ú¯éðÁuŒés6šÉv®Xf6É%nð@S˜ÁÚPýnòM üúhUx¢Ì‚`t!ɤ±k˜[ä¹OܰúÇ_Ò QKQRo¢c½ÔP!è@ŸNŽKCÇ„ö<ÑðÓeJ)ýC)¥/¦PJi4­Íª4«(¼3iÂÒCÖó2ºÅ8êšÏ×Z¿7‘«G2ð»àèC]öò Œ«_z¡z)-RZ¤´hß›}oö½I8˜p0á`—;]ît¹Ã7d÷±ûØ}¿Õ|%³È,2‹£­¢­¢­rzñéŧ?œõpÖÃYÛ¶;l—=7‚˜ &èo(ù…úe†0„ñÕW5®j\m›Û6·m®×v¯í^ÛÍŸ›?7ÿºß/9È5¬a-8Æüþ£´na_v²5ÈÔþ\õ`ѳákÊ; oEËÖ³\ºÖ«±ë0P€’HÊ&RáÑ+ ð»Sß…`$z£5{€‰"waøÿ:÷°v2è´íJ€[ÇÜ\_4y0¥‘»fö¡4ta ¥a}ƒ¦SúôaP÷«ÌZÓ¾zý›tXdÛU¼T¬+ЬߣKVâ%yH†!õ›Ñâÿj°õ¶6 ÈaÒo™¦5Æt'‘ùï;h²ßªÀ`æà³Þãí쎟¹¿ÓÛ„ÈãóÆìäôŸúÌØGéããôòŽ'7;×àѶ*×*×·ŠCe›_]—ô«v;×ÿSaûáMîÖï“\&ŽXÂÌ#Ť­¬J$¨êÿêP‡:óšyͼæ+–8-qZâ”Ø%±Kb—éÓ ¦àáq!.ă1ƒÿ÷Ã’R@ ør#ÛF¶l¯]-ºZt]îºÜu9S?S?S?YØÊZRKjÿV2¯¯p¯Çz¬ç‹ é é é-Þ¶xÛâ­W•W•W•ãÇ+ŽW{Æž±Ç¬ÁøÂ¾Â°ø£X/¸òE•Ýr§Å†¥I󋆊kò¾†ÒõJã=7ÍëºõçÕq“Ä bøC©¯:Äô"!ÄwI-YŠOõÚ70}­Ã¬ ›à±$˵«“†RÞeÆvJC?úP¾:è0¥a£göŽÜrepåPù·Ä¢wì›úýˆž²‡2˜hCfÛƒ2!'ÜŠ?ú9ABêä2ˆL¶ŠÕ"…" Ö„ýÌ7ƒÕǩȗu–w/·´Û4%·c³ž›÷ËÍireþÄS”†åͼBiÔЙO)h´‰Ò¨^³ÏQúÐs쌂%qÍ&á2¥”Æß¥”Ò¸"J)=ß5ù퇗²SÌödž‘Áb¦Ám¾ z¯ÿݤÁŒ`Fð1d÷Üop¿¨—Q/£^L8˜p0A©B©BIæqŽT¤þ¿—íÿ˜AŒ,6¼]s»ævÍïw¼ßñ~dzWÏ^={Uw”î(ÝQ²`”›Éæ¯`þVxžü¦[v0;˜ì2Þe¼ËxïæÞͽ›7ŸÛ|nó¹rqrqr2?LÇtL—•…uJÿ_³Ñ' E_¶×BZ(=UšQ·]¢¥'çË@Žãúë6Q t_À`“4”¶äl±¾X‹¸†'‚¸~w¸zqý±W(C\Á<e È ¢E‚H5F&§7ÉÛ4¯u/Ùfq®Í˘éýƒ›]𪃩¥¾ùèFšÙ@m—Ú ÷iK ,ܧÙ7Ôk>oÑÐâævÚ^Ê~½ä|Æã3IãrÚŽ*çmûI F2&`SEêƒ8‰Ûˆ•)gHÁ ·è‚ÿÉç£;‹ ‹ãXŠ~$ŠìÆ@t€#4d.Lóè.Ü¢½¨)Œ¤þ0(Tj)1KÒﯶÅ%ÆzžîˆNVn­ÌI›ëƒust55ö*Lf6Ê5Q@t’|8SN `g£¨c°þKŸœ%•YéE9ÛJݶ¸¥ F/.Þ>/ä^ˆ?*ïRÒq¹ÚxN“Õ÷RMIŠÁ½ Ý3Ys.ä! É>2ãèiúLvB¨øŸÇ½J¯Ò«(F1Š_‰^‰^‰*ü*ü*ü,Ì,Ì,Ì4?k~Öü\©R©R©B†‘adØo|+¶b+Ÿ·U­N­N­Nõ£êGÕÙìG¶ôtééÒÓ¼B§Ð)D ÿ&ó®z ¶a¶á žà‰Õ«+VW´kµkµk+++ßå¼Ëy—SëXëXëˆÓ8Óðƒüø¬·BúCNß‘áp…lœØ—mÍœ+pêO¸þKƒFTSºªÃ˜>·#FuëR#Rõɶ²=Ç*Ax2õ³¥z£¬™@ò‰Ø“¨ÅÌú ÖéÙhh-ð3vS}ŸzÊÇÿ8¥a£ƒ¾Púì@CéÓê€U”FÚÍŒ}+=ª;2iÎÉa.-7…éuÕp®ßÓ@(ó™é@¦AòPªw&‚…õ—Qß2Ç‚C|‰"®²ý™r\t‘ÝÈü‡»¶ïLŸèvÛ¿Ç1—«[Œ§†uXíàòðUãî›Nϧ42cæJÃ×-¥4ÂoÆ2JÃ_ÏX@iØË “u—M?S}hŨ{ÚÏRèÜiÐY¯L»/öŸÌ7èñOø~?1ÐÖÀÞÐÝλc+^-|µ0828;8› "~ÄÑcô=ìÃ>ì||3º  ºð£E4[4[4û̬3³ÎÌz©óR祎OœOœÌîKz¤Çÿnñe° XY&ÔŽ:>êø(¾M|›ø6Ûô¶émÓûfð!w¨@ñ²`ަò¦ò¦òž™ž™ž™666Úô‡i“µA bd¡0+»Àoᱏ—¢u|¼É)n3•æÇV­¨ùHŽj5WNG ÷ž›£ñLá€üK•Wò}Å£Š[Iä% €¶pÆ\AÔ*Rp?Ùî!ï¹GÔŒ20²p ›0„U`ú’)™Þ9Š[nÂiDáHÆ­~q—ûßòÜo7zŠg¯¹NýNYD7È8[®Ü‘1¿§é¹zÐä÷mZN[ßG¾ñ¨£WïV¾× }Ù=fNú¬1ÅmÑ‚‚=ÊÜ%k¸D:•6§w(Á¼E òP[/›¬-L¡wØA“Ñ͘¥¤ '“ˆ26K»qv´«tÎh É2دm­\j~ÆÑ¸Úy¾{˜åuŸóÍ}n±ð6ÐQ;¯•¡¾]ñ ßÕ¤®Òg³†dì F;P-–¦±ÍïX–w/}YÑ­ÇbO™Ý7¬üý¤Ïvù=*TŠÓʪ«îâ Œ~Ø9AqN¬sšt¤]Ш‹BEEGkg׎¨r"ôŒÇ/û„Ƥ1ñMö½æ{íÑØGã{yêåé—§‰%±$–”£å¾±e üwä!y¼ %5’IM’Q’Q’‘Õi«ÓV§›Nl:±éÄÛ;n︽/ð/þ'™óá ½à/¬À ¬PéªÒU¥«Â}…û ÷+NWœ®8(D!ŠQ`iˆ4DòÝK˜—ØnìÆnÞIFç¬ÎY³¦M;›Ê6ñ§T¦T¦TæË?– ÷p÷ÐíÐ5¨A0Hþ ¼aÙvÇZ¼º<±ËXJ—GŒ:Hé²É#'¿KRÖ0LSC­•l´—‘†ø(O@à/ ï_ÏϘT“M„a'0«¿ú,·Vœ)z<ö\|—ÆOîïØå—Gé³Û3¶QúÌ2ÐÒP“@]JÕ‚2‹>ÞÜ8åêÇÉ+:hº†ÛÞ1ü6ðY8Ì;ÆžtÅ}ì„,­Û?È×¹~pÃKØ€aŒ9O´XofYH¶#,ÿ¹¯ª.S^¯¨Õî™KßFt¬¼¯zc‹“.‹'úzd÷¾Òp’!¥¡¹Av”†9 4¢ëŒ«”†ß ª£4|ZÐbJ£:®Z|ß)€<^°­ÊÏmãÉÛï:ÓGÉ)Yû¼¦’rüÏž³û¡+òcû1,³aHO\ÂF|µ,*Aò°‚¬ÈH2’Œä«‹‹‹bÆŒ9¸÷öÞÛ{o˽—{/÷Ó0 Ó01Q˜‚¿ Ñ ‰ ±!6P…*T‡Æ óvùÛåo—ï<³óÌÎ3²Ù͆üo³Ì6°a.2™‹PƒÔ†J†J†JÞ¿zÿêý«9’9’9¾!kÊš²¦ß±Ty·žXÄ"–/ªø¨ø¨ø´~ÖúYëg^!^!^!Ök‰µçpçp7pã›L±‚­]àOà `€áP•ý_eÏì¾£<$Tº²ÝèÓÒ©K–Ž0ÌÚ9·t¨½ÍÝ$-G¾3–ô% ‚ð¾ê»Ó8ÀD1XL¢Ép¼ªßPñœ‚‘ÜÂ^ží”¬£ŸŒØ^6¨£tÔã«( /Ÿq„Þ}¼zZ¥Q¦ÁÛ ƒo6žüáØ†…mº£ùû¡ ¿Éí@šâlY{f¦lûÚןÉzëÿRýz-]Ð6LrŸX‰:³ÝE2ihñã/‰\ØÅÌ!ƒv 2TN¾ÞyPcûý“fWùHÞì=ì<|oé¼Û¦¾¦ôùåY ”FfÌx@iø¹ Q”>w˜™@iØ¡sk’îgNsKÝp¦¹ÿ³£7nô½<ìuç‡+®‹lë¿Wj¨*ïóãã’Wd(^sÄwÈ^Ò·‰>b–`:~³õ¹¾2RO5!nĸ!!1Ê2Ê2ʺs5æjÌËO/?½ü4üÐðCÃñ-™¦LS¦éRb…üÿ5 0Ì$f3‰3ÓÔ¶©mSÛWñ¯â_Å_|~ñùÅç:q:q:qü§DžÈ“ÿÖy£?ú£?1&ÆDÑê©7¦Þˆoß*¾ÕøãŒ—¹Ð0'˜̉ïRm­ïÄ5 £ 3aÈ;!w­‰[·&Þ©Þ©Þ©ÎãœÇ9c^2/™—è†nèÆ§¦úñ¼ø3°‡´‰FÀ,ä€Ué]Ú´d)]µ~Ì©ÏEg‡½¬é»ǫ̂-ÍtvêÊÇL YK Âø.Q‚IJòŒG‘ÛšùF¥&{É2¾Ëà–VìÝ>›ŒúërñOziP‘8ã ¥OÉôrJ#ÔgdÖ9?ì5}Á ÇŇ}ï´ÔtlÕð›trŒ8c/ %ý <Â\ÈCÿ•럛+ì`„lÜÂlBZày@zà1 !MqÍ óS˜~1ì§ù®mT_£ ó7Œpnµðž}_†//r[yò#*ÿøsÀ)J#üg 4"fF ¥á#‚T(J îDihÎŒS©gvûswælxÜk '¾î0»ùmûå ˆO‰¦2_~îÄE¥ì¦ {ƒùDÞ%Äc£ìƒÿ.’:¯î˜ÃæL_¦/Ó—¯îÿ¸ÿãþ£Õ¢Õ¢Õ®7¿Þüzs³]f»Ìvñvb¦5Óši-Lµß`¾ /È ¾l(1”J.1—˜K̳uÏÖ=[×±Çþûó«"L8΄ÿ—‡YÕ?D÷OA Rs‹¹Å\̦˜M1›úù÷óïç/õ_̾Gaa†`³YÈ,tZç´Îi÷ ïÞ3Ü·ºouߪ ® ® KL‰áŽáßÁóJà„!Ô¡Â°ÈÆ^~`NeZ•; t²\åÈ…c‡–Sºª£ÿ¨Ö7­×Ëç¿Ä6#‰— <ïžzöxâ:e–’DëGíBº¤·4·xtDwG·Yu+~8DiØÔ E”>MÈ 4üNPh혇 Z_J_Õ§W·‡ÚÛ¨ÿø€"MÖ€$e¼ûšAŠÿ‹$½¯ŸÅÖ›0¸Èæ°ò$ÝÌ$£ÿÍ÷&àž»£ŠñŠõãšï<·cÙ)ßk)»Îô›Iièö)|2SÒpàÁ”F,™q›Òð~3¬) ë´¬òÄ=L›ÙeÏÝa7žžêÖ!§ß*›Ofꆵ ~ö¨ZÀì 9D…yÇ4&ý‰'(NC jP”µùM³“ ¢A4ø *)*)*);ôvèíÐ{“÷&ïMÞ„… H© L¦Ó‹±‹e(þ;®ã:®#™È---\•¾*}UzÒº¤uIëüÏúŸõ—9­±Ø ìÈAî¿ÛÊ;„0`Àˆg‹g‹gotÜè¸ÑñÅÄ_Lìt¨Ó¡N²’BRHÊw&C^ávƒÜŽpÈ^o¬T­T­T½z{õöêÝÖ®­][;u]u]u]Ù·êmW¶\ üÞüšŸÀT£id™  JsΗm¬(D yËŒšÓ ˆU2c”o‰ˆ¾Ú•œ¡ ¢A@¾ T' ð}Áoo%@Ÿ@#h U¦òh è0ïÉ RDGÐôì-Óˆ)o!"5eØÖ#ç†ÄͶRìVìõÅÕ£a3­Àœòñ~v¸Ô£<çZí~«•ºéó'=cÞ4ñØœ{nM4ûØ3Æ £iÅʪ5öìæcFrG9[š€‡ˆÆ'd"¥²sûý¶6Š!‹Æ°‚>šÂ :Ø„éèÄL!FäYH °[jÉ©Ñ6R=i €Ñ€|œÜñiÝTŠÛÃòîÞ}=ÛØNoÙÏŽèœÖû ™¥ä©¥vWAˆYBé(® Àž":µ%;*”Ê4ëNe+8—³ñŸÖ”œ¼18âKºßí HËäW…ïÊ>Õ>*תŒªÑþ¥ê2I6ªI‰&×¹ÔŸÊÓ ê€ÙHCʹÔ’æb -Ã9ç¾¹R®Þöåÿ>@a1-¦ÅŠ¡ZnQnQnq8äpÈá§ýNûöû˜ù˜ù˜=Î~œý8;ôjèÕЫD›hmZE«h•Lõás‚ ür|á _ö0{˜=,Y.Y.Yž¼2yeòJn·‹ÛeóÈæ‘Í#ñ>ñ>ñ¾ºðºðºp™ß¶=ìaÿ+Žb [ØòwGÜBÜBÜBm‘Ú"µEuÑuÑuÑ%K&–|Ý·pGp仑^ýQÇ»l‰–hÙк¡uCkãÆ;ŒwHs¤9Òœäˆäˆäˆ’]%»Jv¡E(’eBý×<Æ­À_ 6€„‘>|¹ƒ«Ù&J×çPî¹`éÐ1”®m3öþ0o—ÍV%²¹p€x"P„¼ =¿!¼j˳ÁèËÆ2E$þ?lÎ’aomvUwã³i—:z:ݘ59›ÒÈ.3í(}z+à¥Ï*‚ô)}¶d†\˜âî§Câíòžb_&÷InŒøbý~5²Ñä#™ƒ"䇣ÿ/y[ëû÷C¸3êd?‘g=™Y$ˆèãÚÿÜWUƒ”'+jøm3ݪnÁ©-jn—lb¼*ª½¹iÊbJæm¦4,&è¥kf¼¡4Ü;襃g4 4,n†$#øÂõ Ko´^oÒ·Ý➣LZÍóã*g–(W!¦¢·?w\RBü°EäÁzÆœ\"FŽn_ÓäAô§îP†2”ù$$‚D¾:èsÐç Ï±Å±Å±ÅÇŽ;~ì¸ÚaµÃj‡‰˜ˆ‰ŸñŸ…)õ¿À¼eÞ2oÑÑÙËßËßË?L>L>Lþ» ï.¼kعa熲((äy@üêÔ‹‘¢««{Vî¬ÜY¹§öOíŸÚÛγg;OÖ¿± ß™ø¢…(¾¨5HkÖ vsÛÍm7×ËÝËÝËÝ|ùsY¨k¬Â*¬â· £Nà/ «M™?bË"©Þš°"uÌúª¡ ã‡yPºz¤·¹z"]`@ÈœÀ˜A‚ôþæÔw·ØˆéèBfœa&’wİ~C»Õ¦kµ/Ú:zh›ÝÒ CÆëS~tÆJŸÉަôÙ–Àþ”†aÆ«ç%{ÅC$“ÆôIm6\ÅB1VîPý~D[ÙÙŒ Lü·•÷Ïþ%çÉ«ù-ш„l#Ê"¶£Âj0͈ٿ$ZÉF01ºëïS0VÜ£ºé– ™v‹yÓæÐÞá“$  \KiTaðJ#¼‚¶RÑ+(ŸÒ磃{SúÔ?ðfyÝvStß*±y—Æ IçÚÎ9î–f7-ý"h’f-û¯$—ÌÀ{r•øàYL,p<ÇŒ€ïjú_Ó£–ÏFÂH QˆBýTýTýÔ åÊ/”GwîÝuÜÀqÇ ”5_È,d¢/ú¢¯0™~5„,"‹È"¾Â¼ƒyó×Ï_?ý|ÄÀˆíûÚ÷µïË«›Ìxf<3þWÄŽØ;¾¬c¦c¦cvoì½±÷Æ>Xú`郥ºCu‡ê•5½†k¸ö×—˜¬ÌGƒ¨ˆUÄ*âV†­ [zŸ÷>ï}Þ1Ô1Ô1”wÃ&lÂ&øÀ>?Ñ€À_ æ $|PH4V2È×W\½Èz„{]§Å;‡O§tåÑ…;=z÷l$ó[#¸Âú‚ôþAð?fõÔhRDV°ã˜…¤[ý†Úƒ”»/Y0ư­Íû1§Ž9Li„ÇÌhJŸ™äQ6,h3¥¡»‚ÓgžÓ×išsífC Vj/VûFA'Ñd$^‘9Ä—0ýÑRö´ ‚;ØŽQäi‡Çä 釧d11ÁQ †T~|úÆñz]ºiyμjuîI‡Ï%{_ {Q¾åŽöd ¥OÕ{S©;ó0¥‘½g\¡4ü~PJ_ œÕ¨®ë#íÀ »Žõ%¾øxÅ“™“õ=Þ¼£i…¡žfv6“ĨüœØDoÙóŒ;ó€±%° Ð_öÁ÷i§žBÃj°¬_ö ò ò Š*‹*‹*»y/ò^¤£¯£¯£/Üáwr‹Ü"·dqf•è×b cãî|}•ÝŸ²?eJœOœOœO¯„^ ½ -h‘Íd3Ù mhCûWÜÒÞ¤7éÍ—M4L4L4¢.D]ˆºp£Ùf7šÉµ•k+×VÖ´z¡×_db<Æc¼Ìkß[ì-öv½àzÁõ‚wï6Þmšé5Ók¦'¿I~“ü&YûX€?Ñ€À_Æ•´F_6ï¥=T# ýƬõƒ^P»¥þ#îÐê~£åNÛiÝiS|}ónK Òø‡R_éì‚6pdüH 1"K‰î·™• úiŸWKWÛÓÞ9úu×Ã~#;S®=ÉÒ0½ 1”>å6Rá8sÜ;ÑñW£»,±=·Í4“ëúW4=¿9bs™Ý*òw·bŠžŠÊL Ë~æüÔš~°ÝÝpBPK¿.nyGªæ{úD'…œÔs‚Òˆ…Á®”F6˜1ŸÒð#A($3Í) イ”>;äP<úæá)ïlÚtd ÑÜŒa¬{`—-›XÝÓZñªQ?+“æ=cEÚ1ÈcÒexŠ¥‡Ü+'¥` ¦` o¯•¯¯¯Ø¬°Ya³Ḃ˜16¥oJß”ŽP„"”Ì!sÈYò(@(ü«!£È(2 :ÐÎì³wÎÞ=/z^ô¼•ýWö_Ù;±;ùÐhŽæhþ+zîEz‘^|ÙIËIËIëÅž{^ì99ùää““EgDgD²˜ñ芮èú—ïßÏGƒÉF6²ÜÜܼ]¼]¼]ܓܓܓ===díy[û¿æ¦ ² |ƒ$¢ŠD~À©ŸWíç`Ú6¥ËÊGFRºÜlT“û–c|û’©d*™&[8ï{˜ Ò!1D0‚.ÔpËàÇîa"ÈúMÔv+¯•ÏmÔ}©³ßó”=CiÃ'ƒC( Ïœ¡Eé3ý@BiDf°bnä•/N.çïܦƒ´Õå—þø€¢á`»<ã,¥Q9ÁÇ)\=£9¥Q~3«(LJöß:EçmÅá³ÃÏrÑíJ¿ubìn7ŒÖ™¦ºDž‘³ýÄæN6žI%—˜¦™ˆj„b|Ñ–h+èC®Þ¿+õ£¼&£¿FݱoißÒ¾åãi§=ž¾.|]øºngºéö5UÐKò’¼ü*D!Êû¯“6éIz’žüNƒŽK:.é¸ä¥ÒK¥—Jçžxþ¡ø¼ø¼ø¼¬ý¯´‹×WÜÛ¸¶qmãúÊô•é+ÓÝkv¯Ù½†iÉ´d¾®tyÀQ)¹Â®ü–h¾Â´Ì´Ì´ÌËÞËÞ˾ݑvGÚÑØ¢±Ec‹¬ý<ÁYYˆ#ð§òë«­¢ñ €;ز)5>u©…Á•-jLP¦c¬º‹$É\#-c…=rŠì'âGˆ„£Û) ùâ1 Ô |FJ1KpF*åÑÓ$…ÌC s“4%+K'Vô«1>ˆëˆÅA‹ë‹cù%z+9¤ú—tr´ì¨Þô½Ñ@z_Btܵº+}^ì>òMã)#îŒlÙ{õ>ˆ5¥Ÿ>^ÿì›OÅÖr·å*[~0}¥xª¿œÑÓœDÍã:qjmî—?Æ”ôðór%@Ý2®iÊ„Œ¬Rë¨ï|9Û$y{¾ú³7qM³ë•ßXüê¾òêÿ]Õ¶Dú`–`)—A'P-i7® uD:¾ íþëTóß/üõÊCò´ˆÑ"Æ›ñf¼’’’ϧO;Ÿ6¶|lùØòÁÝwÜ-Â/Â/¯h`ÑÀ¢ä yBžÐö´=m/Lš_!íLd"RH!ÿÿ1þc©g©g©§ö2íeÚËlÙ²9ÇÄ1q ùL>“Ï”PBõÈÔy¥óJçcÁX0ù«óWç¯æt9]NWö¢U†2”ýE¥´k±–zQ/ê¥?A‚þ³>f}Ìúp‹¹ÅÜâä^ɽ’{ËËËó¹fi_Ú—öâ üøÕŠ;Ýp¼ÁpV¨Ö>©«.µ®.­™…ät0ýHïi'(¨ˆ/’md$,qå‡ã ¾…W¤  üvQjAWA^jLõ¨&êðsÈrþC§bÞiÛ{æñg/–?©}ïÛÊËáƒáÙ€Õì]'t=ÖÒÏ,\¼$W—ËmqÈnsjðâÖ­\Õ®¡¨‰e)älÓÌàߘg¬:P«$Ý_ÞªR¹æn|ৃ¥¦÷z¿Ôûtð‘Ë«#i "¿t,mûI%{[ñ~€Ìø8&À–ô'ú¸‡kx†d\ÇsdÒ@º‘Ò‘ÜrzÎØ'™¥¹¾2ôOSÙëÃG#¹„K¸DKh -á•§S–§,OY¶voíÞÚÝÞÐÞÐÞp¤ÒH¥‘J›R6¥lJ!ÉF²#0#p'qu¨C0uþÃĺMoÓÛ¼«LEMEMEÍçÇŸ~líeíeíe÷ÚîµÝë¸Þq½ãz“T’JR)CÊðŠþ/?ŠFFF‰'ñ$¾èDщ¢؃=؃žè‰žHB’þâ¨?y7!/xÁKý úAõƒV%V%V%l[ÇÖ¥ßM¿›~7k`ÖÀ¬|Äz:N§Óñ_ðEWß'Óá wæ3iH¾âÈÀ¾×ÛeQºvÊØ7µ‹RöiÁð¡=Ն˟çɾµ]*­·€€€ÀÏ‚ýaIÚ60eC™\òæGílÛ=j*±ð:·yn¼§Ilæ;Í;ŸÃgÖt¨.—”se¢gEÕóªÇÇ.M{ø:o¥”Òè”RšZD)¥gªV¿R[7 O4ègeèËä2ÍIF‘ì"{1ÿ‡Ð„¿inÑ4bˆ!† \àBX™ª·füšñkÆÇ\¹s}·înÝݺr·änÉÝ"¦Ä”˜Êl¥¿U¨B•ucÝX7¾¢çžwzÞIÔLÔLÔÜÝjw«Ý­äÊ?” $à1ãñè“îÙ…t!]øX4K7-Ý´tÓÛmo·½ÝÖ·cߎ};Êæ’R:ÐùÓ$P_eï†nèS˜Â”½È^d/º4qiâÒÄû®÷]ï»Íû4ïÓ¼ø¾ø¾ø¾¬ý œÀ‰ož?~½Ý¢RHqù"µ–-­½'ÍA7‰Ú“æÈ ¯Dó9愾·Z™²¯ì[[Ñ^‚¸~5üw$_ýJi2 0‘ʾÃc¤‚Wˇ²ÇÙäiŠEÒëd›ø®ï޽;öNýõ…ØQ‰ãß]yw"®ßíNoKgµ<-9¥5ûòGX¹­.ñbK’LŽ’)èÓp¥ò8€çœ÷ŠÞáªè$J1+qAv&¿UnQÞÝå5^ã5>á>ñÛ(÷®Þ»zïê<…<…<…fƒš j6ȷзз¦ÓtšÎè2ºŒ®,å Ný{ÊP†2z‚ž '`CföÏìŸÙ?Û&Û&Û¦QûFíµ7«2«2«â×@˜-ÌfËè“÷í¶‚¬|äk<Òx¤ñˆ]Ë®e×o.Þ\¼™oH’ƒä *Q‰Ê?MüÙ¶ø¿öî;>ŠjýøçÌlOï$!’B€PB“¡Jï"Mz) BD¥÷@@0T)†H€T„aÉgñAÔIDAT@zÛ:ç÷Ç,¿^îï^¯Êóޯװ™™Ýœ³»yöÌsžƒÆhŒ¾è‹¾8Žã8^=¸zpõ`×®7\o”•”•”•$×L®™\ÓaŠ0E` ¦` "‰È‘êFÈßÅëBvI¾cbßfáµçs¾¨Á[Œçy¾é`iø~êø>¾a1ÖmBk#5!䫸në°p»°×ÔïD9«§iöÏߢÙ/Ì® ÖkP'P…õO"FýÑýÙ.¶‹í’ïY<²xdñ•1WÆ\Ó1¦cLG¯N^¼:ÉùÓ,–Ų؊)7äym˰ÌZêÑ~¶ýlûÙ뷬߲~Kb\b\b\;C;C;ƒuz±¸X\üÿ9gB"Wˆ—Ëzn,ßX¾±<ñDâ‰Äõ‚êÕ ²¾Ë ‹„Eÿ³/WòãÊõì¯ã:¬kû†ø†ø†´ÝvtÛÑ-g´œÑr†«ÆUãú¬Øh’d=–ª‘q¯`þ”·ÅÖüÔja½aa¦ªó¦½Ù¯^9´|ô…×vÕÞf}ïd³YMj7BÈKaóËÂãÌ d­Ð_èÏ® …¶Ì$ôú±qBMö#ÀZ?;ˆu”ÿ=ûo…-ןÿ×Pì†h)èÐò5J دö's`ÌÈ@†®£®£®ã†È ‘"¯Å^‹½;ë³îZ÷ìÌ:³ÎÖDØÀ†Zï¹áGaº0]˜.ßñ~—÷»¼ß%µ^j½Ôzœ'8Op¶¶j]V—Õýÿ¬Y»›±YÞÔÎÓÎÓÎÛ•¼+yWòùŒóç3‚÷ï–‹Q@è,tþÜ+~‹G<âåM—~.ý\úµ\ÞryËåmë¶­Û¶®Ïk>¯ù¼fÝ3ùȇ?üáO/ò%ªÙa6XÞî¼·F¬ßÜòy×?2ÛÍ{òæ—œGvκˆŒ·î_•a}¨Ý!ÿ¿ÙjjG°>­ÿdÓÿ-«[¸²p… Jëêп>?ùoUœ®Ú•ueÖËæËš/k¾ì§ðŸÂ ?=õôÔÓSÙ6²md]q–•²RVúsŸÑtÕCH’„$ùzÅèî~µçÕžW{.Ï^ž½<[õDõDõ¬ŒÄaÆá羉BY( •ËzVšZij¥©ßÿnüwã®8ºâ芪㫎¯jý‹ÏŠX+ú“ßῌî¯Çz¬·¾e§ÚNµÚt_Ó}M÷Eܸq?0)0)0ɺ§¼ê_a-!ÿù;ú÷Æûa+~€ ,¦úÙ†–QRSß~yr¤\å½oÄ ­„VB«ssÎÍ97çð¶ÃÛosÚî´Ýiûˆ#ZŒhápÌá˜Ã1a„‘µd-YKª«ý\<–ÇòXŒÆhŒ¾ùàæƒ›JZ•´*im›g›g›'¯PËF°lÄsÏ6³1[.ëiwÎîœÝ9uwuwu÷’Ì’Ì’L½›ÞMÿl*êAÄÁ?éw¬˜‰¾k°FÎSWwUwUw îÜ3¸§®‹®‹®KÎÔœ©9So]ºuéÖ%LÆdL¶¦Çȳ,(>!›·õïÂ{ñ ü0Ìàà¹Æ²Cúbƒ`®kQ0=ûïC-ôai•*kWªjC رoX;Ô¡I„ÿ¡_>}Lxž`ž€ÃRá'€ ÿ6pÀ 8°®÷ÝXW呹”G´½–új{ }¼ }PjÞ‹RÜÁAÜzÂåàýþ.r•wyôîàŽä!yH[zoé½¥÷Ýð»áwÃëw¯ß½~÷×=_÷|Ý“;q'îÄ^g¯³×QµQ›ÆÝÿ $žÍ³y¶\ÉçêW¼úcQtQtQ´[¹[¹[yÕ²ªeUŸM!m€h𼓱Ùl6›-oÛ%Ø%Ø%¨ÕêÀC‰¡Ä ïªïªïj½~rpà¥ÿvCöÎèŒÎ8„C8$x Þ‚wàòÀåËlll 'N(œZ)µRj%i°4X tÐa/öb/MB%/¿7p/ÃH,@+¸B“Õ¹`Eñè² FÉä(lfQ,ÀøÛÏTmÛ£¥(†ˆ\Ü…-Ô..BÈ_Qoˆ¸°¯àb˜~L4L/í¬(•Z´”Zë¶­;®Û¦ÆïU ÂD!LD1bP odà±ß?@„Qº+Ý•î ­…ÖBëÛ‰·o'nÿtû§Û?5Ï3Ï3Ï‹\¹ rAÕ¡U‡V*½/½/½ÏÌÌÌÌÖqw7ý-¹Ô£FK=J=J=n×¼]óvMñ©øT|ÚÐÔÐÔÐoxÃÛZ¦óyv`¬WÑv8ípÚ¡KÓ¥éÒòÇåËWª.U—ªåë'|5_ÍW¿ôßKµ=à´Fk´Æ>ìÃ>ÿîþÝý»{lðØà±¡,©,©,)¹erËä–†•†•†•ˆE,b±‹°ˆBvòwô{Ç'"ñ-bXgìÁ‚ò>Æs¦Ý¥ûLçÌ•0޵`Z€âkíªªÇªr1žE±s–é5~0=¨Ñ !i j0Üæ…¸ _ö|¥e¦li™a› Ê™^>Xœ:Pœ©ÉßzV“ÏÂ4 Cv¡ : ‡Žšðw’Wîd``’JRI*¹däîÜݹ»s¯º>êú(ï+ÞW¼¯Œ>bøˆáÖ…~>ÆÇøØ:¹ÆÝK^õ³(àż˜Ç;Ç;Ç;+k)k)k…®]º^žŒGx„GÏkCÍ¢Y´¼mß̾™}3Mš&M“V¼±xcñFS¨)Ô*/ù$¯9ú#ù ÌȌ̈阎é>N>N>N>!>!>!ò׿tÏtÏtÏâÅŠX¿À´C;´£¼zäRSgð{0ÑüÌä‘“ºNàÆ…yC˸)ºÉÐ[ êñ»z¦Ø_× Õö·4)ØOGù`Ðý~åø•ãWfÍ<šytlÛ±mǶ•ÓlŠ@EàK©ƒ^1dÿ Ÿá3yÓ¶ªmUÛªMÕMÕMÕc#ÆFŒ ½z%ôŠÐNh'´ÃGø!´$ùǼ—çqòÅ%ñ—o®ÃJ6è=´A=žÀ§òk¶CÔ›•ŽNg´’úô0ÁŒ}x³BÕdBùëûåRº€÷¸/îAÄnˆ¨Š‡¨ %*C ¸uœžC g08 Û|$aûV÷#ûq–ˆC™Øe¨ÂTOˆ?ý4Jü 9g}"&b"¿Ê¯ò«æs‰¹dcÌÆ˜1éÝÓ»§w¯Y;²v䀸qâ$½¤—ô¸‚+¸"çsÓ"M¿zÛq;n{ØÃ>{~öüìùé³Òg¥ÏòèèÑÑ£c@h@h@(r‘‹\¶ƒí`;¬iK²ÁŒÁ–U–U–UÈD&2:.t\¨¯¯Ÿ¿4iþRy5\þ.—¿û«cÿ¸Ši-ïâ]¼+¿*õõõ‚Þ z7è]ÝÝÝ}¾@Ÿ–˜–˜–(ÅJ±R,.ã2.ãŽá]‡!ÿ /l¬çQiI?}sµQE:ÉïóÖÚ~Êb=»›ª9 kÅw¶¨ENùã0ƒÃ‚{° ^È„ Y0Y*ÀÕa혵ÉÚ1Šýsû­Eh @…ºP£”‹ŸÉe"UPAųxÏb ¦`ŠƒÙ³fÇõŽë×»’]%»Jv£ÂG… g3ÙL6~ðƒR‚ªòn•€$°oØ7ì´E[´½ãyÇóŽgþ‚üù ‚7oÞà<ßy¾ó|îÃ}¸sfÎìÙºªíY{Ö^¾‚¡î¡î¡îaãiãiãiœcœcœSR§¤NIë£THbyäPÛ ^ðÂûxïc<Æc|µ«Õ®V»êiçiçigœdœdœ”´(iQÒ¢Ò/J¿(ý303¬¯gïÊy€¿/v™Ø*o÷Q;«ºÈG?¶Go7×)jçjFx÷×Ô¾`Í5T¼.tf'i,‰òöË'œ D€5ûùž}HÀ>Íܨ՚¹¶M~aÛD1óm„°Îé¡°U‹*ðe ZÇñù„­ÂVÁúw'l@Ø€°'Ÿl|²ñ…¥–^XÚqBÇ 'X÷”§«:ÂŽ4î.·[ıEòŠE€âà™ƒgž9v>ì|X¨&Tª‘'° }…¾B_ëKz4ÍFËãßÎ:ÜtoÓ½M÷N95æÔ˜°‘a#ìcóòLƒöœ]á W\ÅU\•ïðÜé¹Ósg륭—¶^Ú¦W›^mzy{{[÷¿‹»¸ ;ØÁŽcÈ?÷­üGTxSdŸ.Š+ wÖ¡–¹šÁ…›0Ó6S™.œ·î´íQ‹Æ’!ÿ`rº‹ èagp@%¡*¡ÂÐC¿`Óý‚ò摵˛óDãBž(Þpj%ÞÀ]¸à.ªàªà×_œ ‚AõŠ"r™Èh)ZŠ–«Í$lOØž°ý€p@8 (•ÎJçÁ6ƒmÛ8Îpœá8Cª&U“ª±bVÌŠ)Œ³.Æ´‰oâ›äÑ÷ŒS§2NåÏÊŸ•?ËÁÁÁÁÁÁËÝËÝË].i]ýÔ¶°EWtEWyü[³_³_³ß¶È¶È¶ÈðÐðÐðÐZlQ|_Äý¡çYqb«œ›^uQ×±©cSǦMš4·‰ÛÄm÷¯Ü¿rÿʃ¥–>Xj½2…(D¡Å(¦"Bþ¶ ·°EÞö_å<ß.Ÿ‡/Ü2Ì¡tÛ{aƒîp¾4vÔæ©™MûÔœ t°QD !l*Á¶Ôz„W„\R€€fÂD4ûûÉõãŸÑþ¼e =lQ_˜‚úpÄ98B§Ÿ‹N¾šSZó‘|ÌÃ<Ìsupupuصc׎];â#â#â#¦äLÉ™’cmÔ‰l"›h=êß/0ôʰÖÞ,Þ²xËâ-×v_Û}m÷—).S\0µÂ-¡µÖ™xxxžlu²ÕÉVûtûtûtN&'“Ó³9…(Dáï}Z¾\ÆhŒ¶¾öi÷i÷5~§ñ;ßiw´ÝÑvGk•Õ*«Uf},8ÀÁº!¯€?6➈Ügåõ̲D:T8ܸÁÜJqœÅ~€%CZà“⤱/ƒe(µ´•ñïÑ uDMOyEHx6¥•C޳Òg8‹Úl jCžB Àadz*ïå?_ JpEZŽ+(@SÀ,܆þÌþx6Ư~Ex¹VŒœàÄü™?óZø´ðiáúðõáëÃÍMÌMÌMºLí2µËÔ°]a»ÂvñÏøgü3a‚0A˜ W>y¥Gßåñì;¸ƒ;x ¯áµ„N :™Ì æ„Úŵ‹k³Ãì0;ŒeX†erš_…Ñ_i¿Ò~å°Üa¹ÃòòúåõËë999ãu¼Ž×1 Ã0ì¿~V'¡.Çr,—¯(¶*¶*¶†L ™2ÅNi§´S\,¸Xp1µrjåÔÊÖ}FaNâ$NRByü±—x2 ž’ ¿R´ÎèiÛ£a¤ËR{Ѷ‘ºDp¶åòi˜X´‚?*SÓB^9e?' &òH„(…C„Î JZ wÐJþ¯êx—kªã¶kVŒµ]#tðúNèHN2x2Ð\XŠæ?ýr}ørð"׊‘ÄHŒdŸ²OÙ§GöÙwdßé}§÷Þç~Èýû¡¡[†nºEÍÔLÍxwÞwg®Ì•¹¾Ò¯ÀŠÓ4/à.\nv¹Ùåf¦Ã¦Ã¦Ã•;UîT¹Så•wTÞa ñ·b+¶Ê_“䃴´´4ç5ç5çËg”Ï(Ÿa)¶[Š­KeíÁìùï Žh€Ö{²‘ì€à€à€`çýÎû÷—¶-m[Ú6ùLò™ä3ÆB>ÔéG§~”úJ}¥¾ùú|}¾5P5ä)­¿óùè ƒoá-¼…)˜‚)¾|øð>ì}Øû°é†é†éFª_ª_ª_É%?”ü`„:1ñç÷ •z$¯ˆ?¸ó‚à3äµ!¯ y͵ƒk×¼9oΛ#ÉH¶ŽÜ¿’i3üCþ!ÿPN•)~¯ø½â÷®ï½¾÷ú^»L»L»Ìê«w®ÞYgN̉9YÓQ§N9œâ+ø ¾¢P, E$! IÖE¯þsrZ‹ \à´LË´ò£TšZij¥©þ›ü7ùoâ:®ãº § § §\Ÿ\Ÿ\ÁATAkâ!¯˜?6â~·-̰èÍuÍuÇ•D–¿³Ø[øICx†}?uUe’²­¸^¸h½@7ØSÓBÈ¿!0 Ø@€ ê‹#Pß<7ó¬ynù£™åŒÞÖ0z+,ÃÊeVó7•YÐph `Úߌ%Ë벊ÿ° U¾UPA…õXõlÛÄ6mí·µßÖ~IO’ž$=©\5¸jð°ÁÃ̾cß±ï„ËÂeá2"ˆWt¤v Ö`0I˜$L’êKõ¥ú·Jn•Ü*QµWµWµ¯â_Å¿Š¿pO¸'Ü“ì%{ÉÞš6#@€àXîXîX.Í‘æHs â â â~~½þ§ùåòžrZËB,ÄBžËsy®}ª}ª}juKuKu‹ÂFa£°Éú6ëÛ¬o³:euÊê„k¸†kòþT#ˆ¼ÊþXàþÒp}€9hÅ;K¤ÝÙ#‹>*m …0YÈ5;òæü¸s æŽr„Z)ú ¡Ö£êÃŽÔô„òoÈé.€R(E¼e âÑ£!V Z¬4¦ÇåÓË?ê[þ‘郳×L@ÐÃÀ/Ãy«Ì™°EMÑ5ጰ.¬ó)1i‚ &®åZ®e'Ø v¢è\ѹ¢s뎮;ºîh™±ÌXf|}ÙëË^_Ö0¬aXÃ0)JŠ’¢„ !HzE§3ÞÆmÜfûØ>¶OÎ,ÏB²PPPPPPP¹Få•kø&ú&ú&òDžÈY"Kd‰ò¡_9|åðŸÍgóÙAAÿM©‰Š™èoãm¼±‹±ê«ê«ê«Ákƒ×¯ÕlÒlÒlÊqÎqÎq¾uñÖÅ[11ï༃s8‡s”CÈïU¾ð£ÙN;ØÀfÎöVÙuÌœ/¹6ò~¹÷{×£ºBçßò†¯£Ãuë4V¶ 7°ŽBþ+r€)×  ‡ ^¬#¼ôúÍ>ý¦ü¡Ø @sBˆõŽREš¥XŠ¥Â a…°Bñ±âcÅÇÑ£G?N|=±sb篲¾zøÕCm’6U›Ê’YKCîàÜþ@~ößci,¥ÉwøøøÈ3K/nº¸éâ¦=[ôlÑÑ…r¡\°V9Švvv½ª½ª½ªí^Þ½¼»õ~Öƒõ`=þ£GïÞèžè‰žì}ö>{¿ö'µ?©ýI»‚ví Îo8¿á|Z£Ö‹Ï¶[„-®¥®¥®¥r%™§Gžyzä?êY(Bj-øƒÄø5ðkà×À]pÜ…²è²è²èäFÉ’é zƒÞ _ÀJ¬ÄJkºµ“WÞ ¸DÈ— Yòv©§9CÚgË^WÈa'ØDò$dWzÍaŽíjnBy8,?‡/yØŽ<”âÒ³â¼ëÒØ¢llX.ã,WsmèÍ5m£¯Çh)bV)bðˆ{ã²ùdC'$A‡gUáÝþâ¡{Åõ5gb&f²l[!l6 …öB{¡½òmåÛÊ·3g~—ùÝÆ;ó6æ±{ìcöñÎo¬c½ÿ&ÿJþ•ø7|5_r,Ã2±¯ØRlÉv°­l+j£6j[ÏÿOM§‘3ÝåŒÿª¨Šªã3ÆgŒ/ßU¾«|Wh¿Ð~¡ý”’RRJüSþ)ÿTŒcħûN÷îóXËcóRòRòR¬g{ÞX¸j«¡†_á+|_øÂ×ÛÖÛÖÛ¶J¿*ýªô³<µ<µ›}6[÷OG:Ò­"iA%B~ãT±å³øiÜÀ8Å—yæ#úLsŒå±²%kÃÀpî‹l{kO¡+=[R„BÈK$A„à€G(Â#´´Ø£¥ß@±þ¶ŸÄúÊØY—•±vK7åÛ--sYæSæbÎÕšs,ìA0R¤ÞHyϤb7¸Á qÙö€=`1,†Å°­l+ÛÊÛñv¼$J¢$âK|‰/+žÆš%ÑÐÁº=c1Vþ©×W^_y}åèèèrÈåË!777ϯ ¯ QNÚ·wÎqα´P6R6²ïä:Àu€Ý6LÅÔ:‡7 oÒ^Œ°‹°K3g<¾ÓòŽîŽÎú(å(G9fafá4Nã´ T‚ mÐm¤eÒ2iÆ` ÆXkÃW\"ê¯Ì ,¼:¯Î«Ë½“ªKÕ¥êÊÃÊÃÊÃÜ›¹7soæ¥óÒyéò7åoÊßäéé©R¨*EѺ¢uE댟?1~‚+¸‚+¸…[¸e=³|=D#ßÝØvh‡vví6Úm ŽŽŽVRRzü øApÖŽ¬Y;¬ÕååŒö2”Y×$ „üÊ‹Üûa~Â(X­?o_ÒÉh6qÔ£E#€ HñzÓ>WG‹.BÈŸGN,`8C€ C Bû A–+¥jËKÛ÷`ikžR{¡y räØ@âÓ!áY¦; Â"ð…:<†µÀ$ÀÞ6à Ì0£3:£3 gá,Ü ?dÙCTFeT¶4²4²4âøåfµ[°EÞ[‹­ÅÖª•ª•ª•:/—Î«Š±Š±Š±Ú§Õ>­ö©ä#ùH^]¼ºxu‘S³ç:ÏužëâââàêàêàjßÒ¾¥}KÉžñ bMî‰Ü¦;v‘v‘z'S/S/´“ʤ²Ü–Ër½ÍžÎžÎ,_¶0,ë‹Ç.]2×Ý9{çlêØÔ±©cÏß9çü´Ei‹Òé[ê[ê[þjNøÀGtÝD7ÉIr’œx1/æÅ(@ ¬ÕÍÿÊiS0SäÊ<Â…? Ïþ:ûëì¯Cf†Ì ™Y·¨nQÝ¢›š›š›‹ƒÅÁ¢è®è®èž¿5kþVS S S ëyR‘ŠTkÂŒüûvDGt”Cvå0å0å°àÍÁ›ƒ7kjjÊuÙÓN¦L;É—óå|9ŠP„"k¥vBÈs¼ˆuãc5ß5°}šUV¢W©ÿÖ8Úm·fŒî€±˜áùµÝ.mô¥'„? Á ì„ |=„ëÂq1ÇÍHlYa€X ×µÞ”`A!,°à:,0Ðÿ‹GjަhŠÇx‚'ØŽíØÎåÛoæ !BˆâÞѽ£{G§ANƒœ9Ts¨æPͽĽĽÄÏÆÏÆÏÆ{‹÷ï-¾÷|ïùÞsÞë¼×y¯V«ÕjµÊ!Ê!Ê!ªƒªƒªƒêBu¡ºecÙØ¢ø¢ø¢ø'•ŸT~RùnöÝì»Ù93sfæÌÌíŸ7:oôí{i ÒtùrRФ Î[¼özí-Z{xÐÐà`pH)I J ªY»n§º‚|}}›}Ñì‹f_ <1ðÄÀw•w•w•q>q>q>‰$ȺŸu?ëþ.wºÜébÌŸà žÍæJD"Ù%v‰]ÂE\ÄEnÃm¸ –a–ýê*ÄÿVò'§'Ië¤uÒº·nܺq«–w-ïZÞµ–ïÆq,A,…‡Ê:”¶4Šæ0 o± ây‚“QýTYÀS­£ò÷rš!N!Ž2pë2L©¨…TØZjÀ^¬^¸‹Æ¸ ¿ *øB#’aÄ Ñ “á%~L6¾…iÿâügpçäMuGuu‡ê£«©>ÆçkŸ¯}¾öòöòöòv9írÚå´Ç '¼B½B½Bݲܲܲ\Ç»Žw¯ ÐhLsLsLsLî&w“»±™±™±™åcËÇ–K——./]ž}"ûDö‰GxtàvüíøÛñ÷ªß«~¯úÓ[Oo=½•¿={þö¼&yMòšäíÈÛ‘·ò píøív·ÛÅx…. ]ZÖΜ`NP«aаì÷²}³}oÛ\íyµg`lðÜà¹Aû[¶n¹¥å––[üŽúõ;hhhW·[Ýnu»™;˜;˜;d^ϼžy=%9%9%ùzâõÄë‰qåqåqåC2†d ‘§·VüÇTLÅTÂNa§°“ä#ùH©žTOª'gðÿÏÖ d Cx,<K\â¿y)òRä èAу¢+'WN®œŒp„#Ü®«]W»®ŠSŠSŠSÅAÅAÅA¦‰¦‰¦‰8ƒ38cÍMD ñÞÀhЦhZ­Iµ&ÕšTò¨äQÉCoÒ›ô¦¤ÍI›“6—5(kPÖÀ:N‚„PÈNÈâEÔ ø‰ÖHÁ \cC„ô³KÞÚØé\Ó=UTš.í—Þ¹ÐãÁöÜ K¿L9ð [‚ñ1¯t§ „ÿ¹Š%  š³½hŒÇü:òD;ŸbáÇ^ J]f¬×wθ¤Õ.å'4Ì¥s’Qy]8)¨ÒNÛ|l³²{éžÒ=.¡g=ÎÚž³©bSÅÖhk´5Ú²d;H»[»[»ÛÒÃÒÃÒ£pEáŠÂáááyòå5Êÿ<ÿóüÏsûäöÉíó ïƒ¾úÞ7Ý7Ý7¥ìLÙ™²óÉÉ''Ÿœ4ƒÁƉƉƉ–S–S–SÏý­r‘‹\qŽ8BÁ{ðn¼›ÔA" ùÏ›EóPóPó°’W%¯J^94rca,Œù%ø%ø%T›RmJµ)Î:,>X|°øà“½Oö>Ùû¨Ú£jª] ¼x5ð‚ß¿ ~·kÝ®u»VŽ#äüjª%뺰.ì8;ÎŽs×q_—ð%8€8€C8„CNƼPG¨#Ô‘R¤)Åÿ¤ÿIÿ“kš¬i²¦‰tYº,]usÔÍQ7CòCòCò?8ûÁÙÎÆøÆøÆøÎÿhþGó?‚J(± °ð€FaFy®ò\å¹*¸_p¿à~òߤ÷’ÞKz/{nöÜì¹xˆ‡xˆ €2Ú ùs9B ¢ªàÄÞ—ïø¾uÔ•v8ÿðë·¶p¾°ëÐÉÉqßìådý¨ŠÀ—Gè ¡Æ#„¿´¹¬VÉ›¶í;]LåÜ2ø†7çœ'ÌâœóDGÎ9¿Zr»íí¶Wo^y|üÀ«nWÝNhOhOh7ïÚ¼kó®ßûø½ß›TcRI5úÏë?¯ÿ¼ö÷Úßk¯ÎÊ:+ë¬tÎwÎwÎÿoŸscnÌM8-œN YB–% ÁB0›Æ¦±iøŸà8À®òþBea“°I,W¬P¬—(Æ+Æ‹7++„Ûâbq1›ÉÞbo‰¶¢£èÈÞeï²wŸ÷¸n5ÝjºÕì˜×1¯cÞè;£ïŒ¾³Ú~µýjûm~´ùÑæê㫯>Žˆˆˆçñ<žÇLŽ™3yÆ’Kf,éß-¾[|HëÖ!­Ÿû‹yÃÞ¢(Š¢(¸ n‚>ÀøÀúÓŠ¥0_Ö—õeÖdV'''‡µí×¶_ÛþÚäk“¯MîаCà {‡ôé’”“”“”3mÁ´ÓXþ_à‹Š 09Þp¼áx£EÍ5[ÔŒhÑ6¢­ÿ2ÿeþˬûïÂ.ì‚-laKo/Bþ[/"ǽåÐÃ5Œ<¤Á¾àˆ1Ç` z¡˜·àuµë”§Å‘¶4ª*%õ£6ø31 MñÖR7BÈ_ƒ 7¸‰Ða ´ÆF·MÆ*e] æ_Ãc‡öKS€¥ÌR®½,ÚŠÚÃ!ßÍúnÖù¤Ã-·ÈŒÊ²dYJ>*~·øÝ’Ó%§KN—d•d•d“ŒIÆ$¼_á&›€ ˜Àn±[ìÀ°|3ßÌ7[k’,Æb,æGø~iHC’„$ÇãxïÆ»ñn(D! ­gKAÊ¿ª‡#eIQR´r1füê÷e`nán­#.×B¢ØZ¶–­•«ß<9ÿäü“óGœ8q–µùÞæ{›ï=Â=Â=·iܦq›†® ]ºVíVµ[Õn®\;¸vÞ|xóáÍ — — —²…,Ü ¿~+<íQÚ£´G'“N&LÊìŸÙ?³é‘Ò#¥G*æÍ³¯Ù×ìk¡ÐFh#Õ’jIµøI~’Ÿ”]`€†?26ÏkñZ¼ e¡,´À¡À¡À!Ó=Ó=Ó½U¿VýZõ«U%ªJò‘|e]e]eÝ‚õë ÖC 4B¸.„Kã¤qÒ8íXíXíØ`e°2X©®¯®¯®Ÿ½;{wök3ÖZŸíAÄA” %”4KÈÿæÃ‰ß1#[(ß±ªN­Í¯piQýá¤Ä÷§¾‘ýÎÌŒ7¾÷»êátU>†­B>ÎRãBÈ_Ú[Xø¬Jºæm›½ºè¤\Î9¿{„sÎÓöqÎyaUÎ9oҸ㤎“þýÉ_ÁWðKÅR±Tl.6› QB”Å겺¬®¼4u׿Îâöò3‘K=Êw4aMX±ŸØOì' ‡žw¨]k»Öv­[¥¶Jm•:=ezÊô”5±kb×Äž>púÀéI’$ˆ¯_/¾Þ™“gNž9¹Ç}û÷é1Óc¦Ç´ kÖ*̯½_{¿öÏ}n§p §Øì ö…õ:ÃflÆæß׆âYñ¬hý»y;òväí¤ýIû“öXôaчE;|ì𱃼LRÿ«ý¯ö¿jíÓÏ…Ï…Ï…“ÂIádØÁ°ƒaÛjwªÝ©Ÿ6ø´Á§Ê»Ê»Ê»ÖŒÁü—ë_BþV^Ĉ»ü]y=nâ¾|G~ŠÞÏ #7ã¿ÃÀIýH‘ ÎpùD×JSù¶€ãàl̺Ð×lBùK;†ÍØ%oëê×.N¼ß¿_¥b…ØMì&]’ÚIíÔ%B¬›^~móµÍl$30‹N §y¼´\Z.§¬ð/øü iº4]š./èc Ýä©¿õ×ùó ?“ ãÙü¿À/X~²üdù wqw™Žé˜ÎZ‰| b \C¦ødñÉâ“§‚N :…S8»$»$»$¿î~Ýýº‡†††††6¨× ^ƒz¡¾¡¾¡¾Þ ½z/ŒjÕ:ªõþCú韑‘‘t9érÒåtKº%Ýráý ï_xÿfäÍÈ›‘Ü»q·ß6•x\<.çÑ<šGKjI-©­e+VX¯H€Ïåsù\ØÃöé,¥³'Ÿ>ùôɧçÎœÖ ë„uz½^¯×RüIñ'ø?àìÄNì¬~¹úåê—ÝSÜSÜSJÒKÒKÒ“—'/O^nªbªbª‚åXŽåÖÒ“4ÊNÈ_Ä>gMåíÉ­ZüP·ç “‡µ71?äÍseó~|­ÓÝ ýÚY÷çì ‹¢v#„”ƪ¢„œ½í¸È…ÁGðƒÅ`1ø·»+>P| øÀýk÷¯Ý¿îø¨ã£Žæ=œ÷pÞÃM­6µÚÔêtêéÔÓ©·:Þêx«c®„] »Ž½yìÍcon|gã;ß™*N§ŠMÖ4YÓdÇ={÷XÖ†µ©x~æÏü™¿`'Ø vÌù1?ìÁìA$" -´ÐZw•Sƒ"Ý Ý Ý]É»’w%ŸrfÈ™!Ç=Ž{÷8óù™ÏÏ|ÞÌÐÌÐÌ T­[µnÕºµÓvNÛ9- [¶,tä2ÈeõœÙÈF¶õz­„JȦxagúçŸåæŽ)ï`hÈGó…<‹æëqZUM¼+´s<§áÊ·±l%:£`u!„üEU,Ò燨!öV+‚Q5PYÈAÂî–Ê–ã–ãPòŸøO°ƒ#!/Côª)©p[‚%X"I’$Ið‚¼XcÖ˜5f#Ø6‚ó`lnjnjnšƒäX‡Åå›nnnAÛun×¹¨ÔêÃê…Õ «WoL½1õÆÔÚVk[­m5GÕUsTd“È&‘Mîuº×é^§Ä}‰û÷]›zm굩·”·”·”×W__}}µu€»Å(FoôFok÷& IB&c2&Kž’§äɼ™7ó.«YV³¬æ‚;w *¬|°òAK´%ÚmH0$Š‹‹í ì ì üzøõðë!Ï ÈPf(3”¹›s7çnÆ ÜÀ kݘ¿Ëj²„üå½° 3–ÎìÌ«ób„´¯Ü¡êüC¥f·œÁóý| RPMR]šPó𘠙Ÿß8~²Eü Å9á#–gn*ÍäÎÔ „Bȯ®o$#É‚^Ð zÃbXŒeeeÁo²ígÛ϶_cŸÆ>}Bî…Ü ¹WÓ¹¦sMçêÕ#ªGxõê9TßWßW߷̳̳Ìói·§Ýžv»˜|1ùbr\Y\Y\YÖ;Yïd½“®Mצk¥ÇÒcé±|æÆÿÔø§åë–/Z¾È¼À¼Ð¼ðñ®Ç»ïZkY‹µ(ßR~´üháÕÂë…×ÝÝÝÌ­ÍmÌm¬‰1k±k)£ë…¥Êð&X‚uØwŽ<íSb®$u•Ž #ÅB7¸ŠqÂz—)šÑŠ.¸NM;5íÔ4¹<¥.]—®K¯{¿îýº÷«7®Þ¸zãúËë/­¿´F—à‚à‚*#«^ªzIj¥ñÑøp-VcµÂFlnh}´>¦“—É £`€eàà²ò÷Ñ5á'/Ã,ø³;ìÐéìQÉÝÛñìï ùŽ—D†õû1äþnµlÕšu€±7qñç¥"!„òÇU\ÞH^Öj4Fc´\yõgýY!Bˆ"~{¨n«Î¢³øú¬òY5 ËàÈÁ‘ñUïßýi®ÁÇàóS5ý)ý©«ƒŒžFÏÊïú/ö_,׆gƒØAvž¿öBëF;¬EÆþ+ƒÓ:¥p¾ðã¡38_1TymòDmï<÷yöµlC …ÆN‚ã 5!„ò'©° ¬\õEHR…T±½Ø^üÕ*­žÊª÷«ÞÔŽsÎ3:rÎyFÎ9˜Ã9çUf½ô†¼'‹fÙCjZB^þÛ÷E)„Fô†{0 Yê«á ³ãÇÍõ,+œ¾Ñ¼§²ØÎP]WDå”ã:Þe3XS„ÒÌB!äOR±ªz5TC5kš/|áËF³ElšÁž…sgæÎâÖod¿‘?LÀyÕU1«°*ç›gX Vò¾ï£¦%äï#žpe ôC D¨€Å:£ÉZε>ÕtcÞ¥7?ºnN¯¨ôPïJ_»Œ—³áÌ•B!„äã#L€vbÒÉ…OJãö€µ²Låƒø[To+¿Ô5Qƈs àsŒD-øb€§Ô„BÈÿ˜ h`„z¼‡oñ­è¥ø^ñ=Ò`€ÁºO ÔP[š;™;a!†cø¯Ž"„ü ØB •ȆÂ"ß1 EíéþQÜòÑþ‘.% æ¼=¨/繎thíPíKÏyqû‘õ Æ#„B!äß^Ø™J`€‘­Å[¬|GÎÃ’¥e" ù\G.°\ttœ©­¡na=jNã4P¾À±B!„Bþq„|¾]¸ý,éEßÙRCš 'ó&ËLчõch$Aš^9Îi²Ý{Æ‹ùp>ÎÐACA!„BÈó¼àÀ†Ü—·KÞ5U·d¿f˜e¾®Ø,|Ã\)†]ÛÚôÑÚC„àíð¶À¨©3!„Byž=âþ .òTy³ÄÃø–YÌmègúXá.d±7aâ“ø¥JírlªÁ38wÁ—øÐ@EA!„BÈó¼è÷­¸Ž»òvùsOKrÉ4צ=lÛÂ|¡”&ðÇ^«í¦kÇ`*’m(ƒî„B!„ü;/zÄ}1?‰«P@„Xò½a’IÌ÷)/6ø¢Xp>Å ~…8ÏÓ.U ¯ ]™"8l¡¦É©„B!„<ß‹qÿç3,°”.3®2Ý+| ßhŒ‚ÃæKjžÄk¹æi¢U‡Å2Ö”]†€U•!„B!äßyÑ#îsð~61OÄHK¹e{îúÒ7Ê»â![ÚÊ èâÐWí$®ÂY[h=J Å &„B!„üƒ¼èpyŽã‚x˜}+ôD%(Ÿ2?½ò„R ¿ÏCí:)ç)>p©¡Û¡Ùm=jZ >u!„B!Ïó¢÷r˜`Â9 ÆcHŠö›YæÁ,áÁç·pFL²ÙNﱎ6öUäƒØf Awê B!„BžçEî ø`ã7À!A*cŒ7×BÚ(-bß³ZЉO… Âë®…¶¾štëQ3X[„SgB!„òÀèÙèÙÄÖ¤.ïÃV£MN%„B!äù^NànÏçò¯ …â#碼ÒGå“LçÌ™Â&²dh˜ž­qᕲ3†²@T‚AΑ'„B!„üÚË Ü#°ÛQ3,9»K~,óÒÏ5m7¿ÃÞaI,`wñ}Õ8Q…úð„ ‹A4ƒ’œ#O!„Bùµ—“ãÞc«‹5˜VäWîmihlf®,œ)Þ¦¨O*Wâ2â©”À÷ñG†&¨C]B!„BÈo)^ÊYoâž }Ñ’ðü“‚Ú†R³rð>,’älûHÓ]]C­QPŽ3|mêfêÎ|1K9ð®QÇB!„RÑËq—³ÕÓð…ð‡Ü {Ì- °ö¬ ”R¦ôºã,m;õx£]€Í¨ „’e±E]B!„BÈo½œÀ]ÎVWCxŒ'OÒË7h‹ú¼€¿ÇSlÕÓ•Žƒµ?¨¶ÁLØHÖº„B!„ßþœ‡ÉCÔ4 @mT‘âù]ÞB7@qQln—ª^ªœ OIe µ©K!„Bù­?)pôFñàr@JoH±¼’ÍZÕ8E¦Ã<õeëNëYW4¢.!„B!ä·þ¤Àý~õ‚ÁÅ'Tƒ‡äŽ˜"W oÙÎRªÅaò>l2ê  Ur'„B!ä·þ¤À=' 8°l®18Z¾å|<+œÅYvze®˜jÝi3"P“*¹B!„ò[Öˆûö‚ÊEUQáÇ]ù<„;³C¤}mu™Ò ØÀ«ñ¾‡+l¡£Ž!„B!¤¢—¸?y³tá„É]ªgéÃ?Û1'vÌb/­¯<Ýéºý%èQŠKwiÿ=PAÔ1„B!„Tô2÷x¹X¾Î𞢊ÎzÁ Õãß8}¤Uª=”þb¤˜{¡@¼àJC!„BHE/3p¿Ç(„˜i°%TªT0[ßÌÏì„­¬*Ô¤U®Ótó4ó5WYâaˆ°ÀÌ^ƒܨc!„B©è%îü²ðH€¾¦ÙËÒ&7ªì®a/ôì©0˜åSy¾Ã'ê¶Ê‡ªÞânáš5>n°§Ž!„B!¤¢—9â~÷qp7²œ°hž~S:¬|4‚À–›ÛJ}ùUçBÍmåDÕÑU¨n=ªÜáHC!„BHE/3pßë¸%4fÀŒã7ùš,§Â±%Ñ€xJ¬aÙÇçs³½BuL1[!±ál¯õ¨8AKC!„BHE/3pÿé¸'رÌØÂ>§AqNiXÄ~,ËÒ\:ÏkªßV~.¬×1åqµõ(ØACC!„BHE/3p/‚ø!AУEŹÆBóEÜ’ ©àˆ¢¡Ò³‘Ã8Û4ëQŒ:…B!„ÿë寜:?"EÞ,écªa CÙϲSèÆ²Ù'`ü&yV±Ÿc{œ:ƒB!„çyé;g‘,oM2f˜›¦™W[ò„öLþ‡ɸïál·V§ Î „B!äy^~àÞŠoÀ)y;oIYŽ1¹¨¦!ÒÚT`}1à¶ Routino : Library

Routino : Library

Library Usage

This page describes the libroutino shared library that can be compiled from the Routino source code and used in other programs.

Compilation

The libroutino shared library is compiled by default when the Routino source code is compiled. There are two versions; a normal version and a 'slim' version that uses less memory but is slower. The names of the libraries are libroutino.so and libroutino-slim.so

Including

To use the Routino library in another program the source code for that program should include the routino.h file. The functions that are available in the library (both versions) are listed in this file along with all of the constants and data types that are required.

Linking

After compiling the program that uses the library it needs to be linked to the library. For gcc this requires adding -lroutino or -lroutino-slim to the linker command line, possibly with a -L... parameter to specify the location of the library.

Example Library Interface Code

An example of a program that can link to the libroutino library is provided in the Routino source code called router+lib.c. This is an almost exact re-implementation of the standard Routino router program using the libroutino library.

Library License

The source code for the libroutino and libroutino-slim libraries is the GNU Affero General Public License v3 the same as for the rest of the Routino software.

Linking with AGPLv3 Source Code

If libroutino is linked with other APGLv3 code then the same license applies to the combination as to the two parts.

Linking with GPLv3 Source Code

The AGPLv3 license is almost identical to the GNU General Public License v3 except that network interaction with an AGPLv3 program requires the same source code access as distributing compiled GPLv3 programs. This means that libroutino can be linked or combined with code that is released under the GPLv3 without changing the license of that code.

If there is no network interaction with the resulting program then the Routino source code can be treated as if it was GPLv3 code for the purposes of distribution and use.

If there is network interaction with the resulting program then the AGPLv3 license will apply since this is required by section 13 of the GPLv3.
The Software Freedom Law Center description of the GPLv3 and AGPLv3 licenses describes combining GPLv3 and APGLv3.
My understanding is that only when modified Routino code is linked with GPLv3 code does network interaction require the modified Routino code to be released.

Linking with Other Source Code

Linking libroutino with code released under any other license must preserve the terms of the Routino license on the combination if the software is distributed or interacted with over a network.

Routino Library API

Preprocessor Definitions

A version number for the Routino API.
#define ROUTINO_API_VERSION 7

Error Definitions

No error.
#define ROUTINO_ERROR_NONE 0

A function was called without the database variable set.
#define ROUTINO_ERROR_NO_DATABASE 1

A function was called without the profile variable set.
#define ROUTINO_ERROR_NO_PROFILE 2

A function was called without the translation variable set.
#define ROUTINO_ERROR_NO_TRANSLATION 3

The specified database to load did not exist.
#define ROUTINO_ERROR_NO_DATABASE_FILES 11

The specified database could not be loaded.
#define ROUTINO_ERROR_BAD_DATABASE_FILES 12

The specified profiles XML file did not exist.
#define ROUTINO_ERROR_NO_PROFILES_XML 13

The specified profiles XML file could not be loaded.
#define ROUTINO_ERROR_BAD_PROFILES_XML 14

The specified translations XML file did not exist.
#define ROUTINO_ERROR_NO_TRANSLATIONS_XML 15

The specified translations XML file could not be loaded.
#define ROUTINO_ERROR_BAD_TRANSLATIONS_XML 16

The requested profile name does not exist in the loaded XML file.
#define ROUTINO_ERROR_NO_SUCH_PROFILE 21

The requested translation language does not exist in the loaded XML file.
#define ROUTINO_ERROR_NO_SUCH_TRANSLATION 22

There is no highway near the coordinates to place a waypoint.
#define ROUTINO_ERROR_NO_NEARBY_HIGHWAY 31

The profile and database do not work together.
#define ROUTINO_ERROR_PROFILE_DATABASE_ERR 41

The profile being used has not been validated.
#define ROUTINO_ERROR_NOTVALID_PROFILE 42

The user specified profile contained invalid data.
#define ROUTINO_ERROR_BAD_USER_PROFILE 43

The routing options specified are not consistent with each other.
#define ROUTINO_ERROR_BAD_OPTIONS 51

There is a mismatch between the library and caller API version.
#define ROUTINO_ERROR_WRONG_API_VERSION 61

The progress function returned false.
#define ROUTINO_ERROR_PROGRESS_ABORTED 71

A route could not be found to waypoint 1.
#define ROUTINO_ERROR_NO_ROUTE_1 1001

A route could not be found to waypoint 2.
#define ROUTINO_ERROR_NO_ROUTE_2 1002

A route could not be found to waypoint 3.
#define ROUTINO_ERROR_NO_ROUTE_3 1003

Routino Option Definitions

Calculate the shortest route.
#define ROUTINO_ROUTE_SHORTEST 0

Calculate the quickest route.
#define ROUTINO_ROUTE_QUICKEST 1

Output an HTML route file.
#define ROUTINO_ROUTE_FILE_HTML 2

Output a GPX track file.
#define ROUTINO_ROUTE_FILE_GPX_TRACK 4

Output a GPX route file.
#define ROUTINO_ROUTE_FILE_GPX_ROUTE 8

Output a text file with important junctions.
#define ROUTINO_ROUTE_FILE_TEXT 16

Output a text file with all nodes and segments.
#define ROUTINO_ROUTE_FILE_TEXT_ALL 32

Output a single file type to stdout.
#define ROUTINO_ROUTE_FILE_STDOUT 64

Output a linked list of points containing the HTML file information but as plain text.
#define ROUTINO_ROUTE_LIST_HTML 128

Output a linked list of points containing the HTML file information as plain text and with all points.
#define ROUTINO_ROUTE_LIST_HTML_ALL 256

Output a linked list of points containing the text file information.
#define ROUTINO_ROUTE_LIST_TEXT 512

Output a linked list of points containing the text all file information.
#define ROUTINO_ROUTE_LIST_TEXT_ALL 1024

Linked List Output Point Definitions

An unimportant, intermediate, node.
#define ROUTINO_POINT_UNIMPORTANT 0

A roundabout exit that is not taken.
#define ROUTINO_POINT_RB_NOT_EXIT 1

An un-interesting junction where the route continues without comment.
#define ROUTINO_POINT_JUNCT_CONT 2

The highway changes type but nothing else happens.
#define ROUTINO_POINT_CHANGE 3

An interesting junction to be described.
#define ROUTINO_POINT_JUNCT_IMPORT 4

The entrance to a roundabout.
#define ROUTINO_POINT_RB_ENTRY 5

The exit from a roundabout.
#define ROUTINO_POINT_RB_EXIT 6

The location of a mini-roundabout.
#define ROUTINO_POINT_MINI_RB 7

The location of a U-turn.
#define ROUTINO_POINT_UTURN 8

A waypoint.
#define ROUTINO_POINT_WAYPOINT 9

Profile Definitions

A Motorway highway.
#define ROUTINO_HIGHWAY_MOTORWAY 1

A Trunk highway.
#define ROUTINO_HIGHWAY_TRUNK 2

A Primary highway.
#define ROUTINO_HIGHWAY_PRIMARY 3

A Secondary highway.
#define ROUTINO_HIGHWAY_SECONDARY 4

A Tertiary highway.
#define ROUTINO_HIGHWAY_TERTIARY 5

A Unclassified highway.
#define ROUTINO_HIGHWAY_UNCLASSIFIED 6

A Residential highway.
#define ROUTINO_HIGHWAY_RESIDENTIAL 7

A Service highway.
#define ROUTINO_HIGHWAY_SERVICE 8

A Track highway.
#define ROUTINO_HIGHWAY_TRACK 9

A Cycleway highway.
#define ROUTINO_HIGHWAY_CYCLEWAY 10

A Path highway.
#define ROUTINO_HIGHWAY_PATH 11

A Steps highway.
#define ROUTINO_HIGHWAY_STEPS 12

A Ferry highway.
#define ROUTINO_HIGHWAY_FERRY 13

A Paved highway.
#define ROUTINO_PROPERTY_PAVED 1

A Multilane highway.
#define ROUTINO_PROPERTY_MULTILANE 2

A Bridge highway.
#define ROUTINO_PROPERTY_BRIDGE 3

A Tunnel highway.
#define ROUTINO_PROPERTY_TUNNEL 4

A Footroute highway.
#define ROUTINO_PROPERTY_FOOTROUTE 5

A Bicycleroute highway.
#define ROUTINO_PROPERTY_BICYCLEROUTE 6

Type Definitions

Typedef Routino_Database

A data structure to hold a Routino database loaded from a file (the contents are private).
typedef struct _Routino_Database Routino_Database

Typedef Routino_Waypoint

A data structure to hold a Routino waypoint found within the database (the contents are private).
typedef struct _Routino_Waypoint Routino_Waypoint

Typedef Routino_Profile

A data structure to hold a Routino routing profile (the contents are private).
typedef struct _Routino_Profile Routino_Profile

Typedef Routino_Translation

A data structure to hold a Routino translation (the contents are private).
typedef struct _Routino_Translation Routino_Translation

Typedef Routino_UserProfile

A data structure to hold a routing profile that can be defined by the user.
typedef struct _Routino_UserProfile Routino_UserProfile
struct _Routino_UserProfile  
   {  
      int transport; The type of transport.
      float highway[14]; A floating point preference for travel on the highway (range 0 to 1).
      float speed[14]; The maximum speed on each type of highway (km/hour).
      float props[7]; A floating point preference for ways with this attribute (range 0 to 1).
      int oneway; A flag to indicate if one-way restrictions apply.
      int turns; A flag to indicate if turn restrictions apply.
      float weight; The weight of the vehicle (in tonnes).
      float height; The height of the vehicle (in metres).
      float width; The width of vehicle (in metres).
      float length; The length of vehicle (in metres).
   }  

Typedef Routino_Output

Forward declaration of the Routino_Output data type.
typedef struct _Routino_Output Routino_Output

Type struct _Routino_Output

A linked list output of the calculated route whose contents depend on the ROUTINO_ROUTE_LIST_* options selected.
struct _Routino_Output
struct _Routino_Output  
   {  
      Routino_Output* next; A pointer to the next route section.
      float lon; The longitude of the point (radians).
      float lat; The latitude of the point (radians).
      float dist; The total distance travelled (kilometres) up to the point.
      float time; The total journey time (seconds) up to the point.
      float speed; The speed (km/hr) for this section of the route (ROUTINO_ROUTE_LIST_TEXT_ALL format only).
      int type; The type of point (one of the ROUTINO_POINT_* values).
      int turn; The amount to turn (degrees) for the next section of the route (ROUTINO_ROUTE_LIST_TEXT or ROUTINO_ROUTE_LIST_HTML or ROUTINO_ROUTE_LIST_HTML_ALL format).
      int bearing; The compass direction (degrees) for the next section of the route.
      char* name; The name of the next section of the route (ROUTINO_ROUTE_LIST_TEXT or ROUTINO_ROUTE_LIST_HTML or ROUTINO_ROUTE_LIST_HTML_ALL format) or previous section of the route (ROUTINO_ROUTE_LIST_TEXT_ALL format).
      char* desc1; The first part of the description of the next section of route (ROUTINO_ROUTE_LIST_HTML or ROUTINO_ROUTE_LIST_HTML format).
      char* desc2; The second part of the description of the next section of route (ROUTINO_ROUTE_LIST_HTML or ROUTINO_ROUTE_LIST_HTML format).
      char* desc3; The third part of the description, the total distance and time at the end of the next section of route (ROUTINO_ROUTE_LIST_HTML or ROUTINO_ROUTE_LIST_HTML format).
   }  

Typedef Routino_ProgressFunc

A type of function that can be used as a callback to indicate routing progress, if it returns false the router stops.
typedef int (*Routino_ProgressFunc)(double complete)

Variable Definitions

Global Variable Routino_APIVersion

Contains the libroutino API version number.
int Routino_APIVersion

Global Variable Routino_errno

Contains the error number of the most recent Routino function (one of the ROUTINO_ERROR_* values).
int Routino_errno

Function Definitions

Global Function Routino_CalculateRoute()

Calculate a route using a loaded database, chosen profile, chosen translation and set of waypoints.
Routino_Output* Routino_CalculateRoute ( Routino_Database* database, Routino_Profile* profile, Routino_Translation* translation, Routino_Waypoint** waypoints, int nwaypoints, int options, Routino_ProgressFunc progress )

Routino_Output* Routino_CalculateRoute
Returns the head of a linked list of route data (if requested) or NULL.
Routino_Database* database
The loaded database to use.
Routino_Profile* profile
The chosen routing profile to use.
Routino_Translation* translation
The chosen translation information to use.
Routino_Waypoint** waypoints
The set of waypoints.
int nwaypoints
The number of waypoints.
int options
The set of routing options (ROUTINO_ROUTE_*) ORed together.
Routino_ProgressFunc progress
A function to be called occasionally to report progress or NULL.

Global Function Routino_Check_API_Version()

Check the version of the library used by the caller against the library version
int Routino_Check_API_Version ( int caller_version )

int Routino_Check_API_Version
Returns ROUTINO_ERROR_NONE if OK or ROUTINO_ERROR_WRONG_VERSION if there is an error.
int caller_version
The version of the API used in the caller.

This function should not be called directly, use the macro Routino_CheckAPIVersion() which takes no arguments.

A wrapper function to simplify the API version check.
#define Routino_CheckAPIVersion()

Global Function Routino_CreateProfileFromUserProfile()

Create a fully formed Routino Profile from a Routino User Profile.
Routino_Profile* Routino_CreateProfileFromUserProfile ( Routino_UserProfile* profile )

Routino_Profile* Routino_CreateProfileFromUserProfile
Returns an allocated Routino Profile.
Routino_UserProfile* profile
The user specified profile to convert (not modified by this).

Global Function Routino_CreateUserProfileFromProfile()

Create a Routino User Profile from a Routino Profile loaded from an XML file.
Routino_UserProfile* Routino_CreateUserProfileFromProfile ( Routino_Profile* profile )

Routino_UserProfile* Routino_CreateUserProfileFromProfile
Returns an allocated Routino User Profile.
Routino_Profile* profile
The Routino Profile to convert (not modified by this).

Global Function Routino_DeleteRoute()

Delete the linked list created by Routino_CalculateRoute.
void Routino_DeleteRoute ( Routino_Output* output )

Routino_Output* output
The output to be deleted.

Global Function Routino_FindWaypoint()

Finds the nearest point in the database to the specified latitude and longitude.
Routino_Waypoint* Routino_FindWaypoint ( Routino_Database* database, Routino_Profile* profile, double latitude, double longitude )

Routino_Waypoint* Routino_FindWaypoint
Returns a pointer to a newly allocated Routino waypoint or NULL if none could be found.
Routino_Database* database
The Routino database to use.
Routino_Profile* profile
The Routino profile to use.
double latitude
The latitude in degrees of the point.
double longitude
The longitude in degrees of the point.

Global Function Routino_FreeXMLProfiles()

Free the internal memory that was allocated for the Routino profiles loaded from the XML file.
void Routino_FreeXMLProfiles ( void )

Global Function Routino_FreeXMLTranslations()

Free the internal memory that was allocated for the Routino translations loaded from the XML file.
void Routino_FreeXMLTranslations ( void )

Global Function Routino_GetProfile()

Select a specific routing profile from the set of Routino profiles that have been loaded from the XML file or NULL in case of an error.
Routino_Profile* Routino_GetProfile ( const char* name )

Routino_Profile* Routino_GetProfile
Returns a pointer to an internal data structure - do not free.
const char* name
The name of the profile to select.

Global Function Routino_GetProfileNames()

Return a list of the profile names that have been loaded from the XML file.
char** Routino_GetProfileNames ( void )

char** Routino_GetProfileNames
Returns a NULL terminated list of strings - all allocated.

Global Function Routino_GetTranslation()

Select a specific translation from the set of Routino translations that have been loaded from the XML file or NULL in case of an error.
Routino_Translation* Routino_GetTranslation ( const char* language )

Routino_Translation* Routino_GetTranslation
Returns a pointer to an internal data structure - do not free.
const char* language
The language to select (as a country code, e.g. 'en', 'de') or an empty string for the first in the file or NULL for the built-in English version.

Global Function Routino_GetTranslationLanguageFullNames()

Return a list of the full names of the translation languages that have been loaded from the XML file.
char** Routino_GetTranslationLanguageFullNames ( void )

char** Routino_GetTranslationLanguageFullNames
Returns a NULL terminated list of strings - all allocated.

Global Function Routino_GetTranslationLanguages()

Return a list of the translation languages that have been loaded from the XML file.
char** Routino_GetTranslationLanguages ( void )

char** Routino_GetTranslationLanguages
Returns a NULL terminated list of strings - all allocated.

Global Function Routino_LoadDatabase()

Load a database of files for Routino to use for routing.
Routino_Database* Routino_LoadDatabase ( const char* dirname, const char* prefix )

Routino_Database* Routino_LoadDatabase
Returns a pointer to the database.
const char* dirname
The pathname of the directory containing the database files.
const char* prefix
The prefix of the database files.

Global Function Routino_ParseXMLProfiles()

Parse a Routino XML file containing profiles, must be called before selecting a profile.
int Routino_ParseXMLProfiles ( const char* filename )

int Routino_ParseXMLProfiles
Returns non-zero in case of an error or zero if there was no error.
const char* filename
The full pathname of the file to read.

Global Function Routino_ParseXMLTranslations()

Parse a Routino XML file containing translations, must be called before selecting a translation.
int Routino_ParseXMLTranslations ( const char* filename )

int Routino_ParseXMLTranslations
Returns non-zero in case of an error or zero if there was no error.
const char* filename
The full pathname of the file to read.

Global Function Routino_UnloadDatabase()

Close the database files that were opened by a call to Routino_LoadDatabase().
void Routino_UnloadDatabase ( Routino_Database* database )

Routino_Database* database
The database to close.

Global Function Routino_ValidateProfile()

Validates that a selected routing profile is valid for use with the selected routing database.
int Routino_ValidateProfile ( Routino_Database* database, Routino_Profile* profile )

int Routino_ValidateProfile
Returns zero if OK or something else in case of an error.
Routino_Database* database
The Routino database to use.
Routino_Profile* profile
The Routino profile to validate.
routino-3.0/doc/html/installation-ms-windows.html 644 233 144 16500 12563643607 15466 0 Routino : Installation on MS Windows

Routino : Installation on MS Windows

Using Cygwin

Cygwin is a large collection of GNU and Open Source tools which provide functionality similar to a Linux distribution on Windows. A Cygwin DLL provides substantial POSIX API functionality therefore providing direct compatibility for most UNIX source code.

Since Cygwin aims to replicate a Linux-like system on Windows it is the simplest method of compiling Routino. The disadvantage is that all programs compiled with Cygwin require a number of runtime Cygwin libraries which may introduce a runtime speed penalty.

The installer for Cygwin can be downloaded from http://cygwin.org/; there are 32-bit and 64-bit versions available. For compiling Routino the Cygwin installer should be run and the following packages selected (any dependencies will be automatically be selected at the next step):

  • base packages
  • gcc-core (in 'Devel' menu)
  • make (in 'Devel' menu)
  • libbz2-devel (in 'Libs' menu)
  • zlib-devel (in 'Libs' menu)
  • perl (in 'Perl' menu)

To compile Routino open the "Cygwin Terminal" change to the Routino source directory and compile using the make command.

The programs that are compiled planetsplitter, router will require the Cygwin runtime to be able to run them. The library libroutino.so should be usable with other Cygwin compiled programs.

Native Compilation

Routino has limited support in the source code for compiling on Microsoft Windows. This includes a set of functions that can replace the mmap() and munmap() UNIX functions which are not available on Microsoft Windows.

The source code should be downloaded, either as a release version file or from subversion - no instructions are provided for this step. The release versions include some files (mainly the web icons) which are not included in the subversion source (and which may be difficult to create on Windows).

Using Microsoft Visual C

The Routino source code (for the router at least) has been modified so that it will compile with the Microsoft Visual C compiler.

Compiling Routino with MSVC is not supported directly since there is only support for using Makefiles in Routino. The files that need to be compiled for the Routino router can be found from the Makefile in the src directory listed in the ROUTER_OBJ variable.

To compile the router in slim mode the pre-processor definition SLIM=0 must be set and for non-slim mode SLIM=1 must be set.

The default directory for the Routino data files must be set in the ROUTINO_DATADIR pre-processor variable. If the router command line --data option is going to be used then this variable can be set to any value.

Since Microsoft Visual C does not fully support the C99 standard it is necessary to tell the compiler how to handle the inline functions. This can be done by passing in the command line option -Dinline=__inline to the C compiler.

Using MinGW

MinGW is the "Minimalist GNU for Windows" which includes some of the common GNU programs; principally gcc and related programs for software development.

The installer for MinGW can be downloaded from http://mingw.org/. For compiling Routino the MinGW installer should be run and the following packages selected:

  • mingw-base
  • msys-base
  • mingw32-pthreads-w32
  • mingw32-libz (dev package)
  • msys-perl

To compile Routino open a DOS command window and set the path to the installed MinGW and MSYS software. For example if MinGW was installed in the C:/MinGW directory then the path needs to be set to C:\MinGW\bin;C:\MinGW\MSYS\1.0\bin.

From within this DOS command window change to the Routino source directory and compile using the MinGW version of make with this command mingw32-make.

After compiling Routino a set of library files are created (routino.dll, routino.def and routino.lib). These should be usable for linking with programs compiled with MSVC.

Using MinGW-W64

MinGW-w64 is an alernative implementation of the same concept as MinGW but allows for compilation to 32-bit or 64-bit executables.

The website for MinGW-w64 is http://mingw-w64.org/ but the downloads are available from http://win-builds.org/. Installation of MinGW-w64 is slightly different from that for MinGW but a similar set of packages will be required.

The compilation method for MinGW-w64 is the same as for MinGW and the same files will be compiled, the only difference is that by default a 64-bit version will be created.

Limitations

A native Microsoft Windows compilation of Routino is more complicated than compiling on Linux, other UNIX system or Cygwin. This is probably not an option if you are unfamiliar with software development on Microsoft Windows.

The size of files that can be accessed with an MSVC or MinGW (32-bit) compiled version of Routino is limited to 32-bits (less than 4 GB). The MinGW-w64 compiler on 64-bit is able to handle larger files (bigger than 4 GB).

The Windows operating system does not have a function equivalent to the fork() function on UNIX. This means that it is not possible to use the planetsplitter program's built-in file decompression with an MSVC or MinGW compiled version of Routino.

Example Web Pages

No instructions are available for using the Routino example web pages with the Microsoft Web server (IIS).

For information on setting up Apache see the "Example Web Pages" section of the main installation instructions.

routino-3.0/doc/html/example1.png 644 233 144 413161 11541143712 12223 0‰PNG  IHDRôA^#X oFFs6È *8 pHYs  ÒÝ~ü vpAgŽÌdKž€IDATxÚì½u`ÕØöþýì$GëNÝ X¡)§ÅÝ¥¸»»»»0¸»»;-îÅ+´Ô&ûý#™ûë¼ß;÷ÎF`úO8g““³’³³²öZÏ"`0 ƒÁøÞ…Ú¨€q ·5#„d¡iW¯2= ;õV•ìr½@ã<Ç xjzm~nž!M¥ËÉ AK¡?šÛúÒš¶)ÇvüŒ³®wB÷ö8óõ9ÃóË XЏ!^B'ÌEìÆiðà@ Be†gü3ƒÁ`0Œï_8ú"DPüˆñ|¢'Ä4†Þ–‡xQÇ'ö>½w•v+¸¡WéR‰ù;8úÚ4W‹–c”y€h/u¢Û´§Ô»„È5?ßáÍø$Ï.|´ïúÃÁ¯«Èû!艊d Q“§Òiú„aŽã*pàX$þû9î ƒÁ`0¿¹¤U…œáˆ胆\y²#¥ô òË -öØë|²OŲþ¡‘û…m *¥>§~Æ/´Ì6q–…ÖRc𡛝P_èdj>TúÙ¤ùçθ²éaü¹¨ßiÜX¢ÇÚfxÑâÔŠ’ÐB&E\’eÆ3 ƒÁ`0¿h –7I7<Ä~ÙGJäRzB@EÏ»Z¯¨®–Œ“—wBé4—ÎþõØwm˜FKjk¥tªµs'ËΉ':d®1757ÜÇ;Õ=(÷~%z\!µ±Ó‘pUÞÅ%ßì¤2 ƒÁ`üÑäÖe/‡r…H>òšÞ§åi z #±]X‹à¿°¿¥ìÌÐè|°}ž1€”-22_³öäJr ˆ—zƒæºjmöTSQëò- ï{¿.:ßëò’N«¥VbÇóÂ`~ ÙJÞ‹¢øZ|KkI7¥8¸Ã>HÂ{¼g§åŸsÜ ƒÁ`0¾&²·¥NnöDÖ" gQ'°™BCü Ž •›n/j—÷êIJ|¡‘᥽.;Ÿ¤£b—œJ&ÞRWëÏOçër4ùUGR–fº›¯jz©Åmº´å%íóïÏIgÿŸ; åP£p””9‰†¥ÓüÃ/%ƒÁ`0 Æ×G <̰BÄpÔE%¾ÙE*ˆU©–N‘‡G…qBóž‘¥[*ÕëLj€©»O´/M‹›ËZWG‰÷¥4m1ÓºÆ.e¼ªn|Ð*Ç[Z¸êzì̇6ÒLËs±ñ™5§‚N}=íþ•ûáB#~6_\œ'WÐ@jA)%FvÞ™Ï`0 ƒÁ`ü"¹§8ð؈֨IÞ‚âbîžZØ~ë\uF©IÍGl)Oéäá#)ó¢Õ”›69†ìšq"¥”>{J)¥)½)¥tNýùCfÐíæßpÉ€ròÞ„Ù\ògÑ-”ÐC ;!ÿÂá‡<ÿºŒ‹Á3 ƒÁ`üiÈÞ—¬ ãƒà:N §¸ƒ\¾Ü Ööùì9vëòÎwæ|Þ:4¥E±û’v~ðŒK²:šßƶɾ’µå|Š1Áø8±Éá|ëg¾,Þ=¨æÕ>Þå„-ôœdÁ&þg{ ñØLÊb+Æ#.pPÞ`…­ ƒÁ`0 †BîP)<â‡8D¢ Êä¨ß£KÔÉ· -ʼ/[!rrá}*´ÜÕkÄ’Fâ«K≌ÄKó(¥ônMJ)}B)¥ï¼tÚÔÒaW‰”ÎÐ3èqñþIMËñ­¶ÄÁ¨ëªšûSø›$…ô%kñ‡”—ä^­Œ¿¼®…j“°ÏúPÚ#mCáHC&3 ƒÁ`0 Æ ìa{4DC4ÄvlÇvC1Ã{¼Ç{[­­ÖVëÿÁÿƒÿ‡¼kóŽÏ»ÂÕÑm¦k6.¡ Ÿé]Âqº_瘺[<’ò>žE|²^rH-•¸&y¹t.KÈÞ›_øtüi9>âíÊ˳›IwH¯+v»µ « yæÓ«YZᦄ»B¶`ûÒ”Ú,ãyÖsK3ìÇ\lá}ÈRƒ¶Á;¨‘ˆl˜‘#ÌËËøë!~yœ}íSÞ&¤¾ËpÁô@s4ÆØÁLÃ`0 ƒñ»Ýt $øÃþX…UX…nè†nˆG<âåö—í/Û_öªîUÝ«ºûq÷ãîÇ…ÃÂ!á DÓ!üi>ŠÛšÖ/ó™!´ãÝÊ3ÝõÊÓ°yÐ É&Gg,¢Mßh²ïµüÇ=/êrmÒt9¶U׸ªZ´íÞ)K­AÁ½°|4ÆZ®‰%ŽöÒþ¨ZÃ/…0Fñ²Ìç´Œú‹&]S?^¾Õýžúe“äð,ßœ9Êáç#œ¤×ሠêH¬|/’«¼•ñ'"8OÒ×~Û-µOH/T@8sÜ ƒÁ`0~Dé¨*AÂlÌÆl8À¨Žê¨.±ímÛÛ¶·oß¾\oºÞt½©öP{¨=$^â%¾ðƒ¿uµµ‘%ãmËwªž‹ý²Îµ:U>»ÈºÇÔT2rÙz;íµýyÎnúÜ7þÑ—z¤™$‰Ñìh{Hs}åâ7±ÙOC»ýXºeÁ쎛Âf=·9§k¦I -ç-× w ëŒóƒo8>л,Dý eÄÞ¥#¦æ·®}rçÙËûK‹\=ó°UæsSs58"sÝÉSk[© ]G ÀLè †̰²þç 8ŸÐ«´?UwC$Šb3 ƒÁ`0 Æo¢8Š£8*¢"*ÂŽpÄP …’Sn×Í®›]7ïFÞ¼¹óî¼;/<ž Ïè ú‚¾@S4ESSiS„©TÒõ¤I7>¶øhø0*' g°aû*nÈè¨-N¢{ {V4½·Ôx}âMÇ´Z뜬÷"Í®¬Ms§…Ò1‹·&ÖÑÖ¦Šnê}ÿ÷”n}±—ì\sSõ,¡gŸˆSG6/Y(Ûo­ÓjÛ3:w«`xbR[†d·3 ‰u µ»0Õú/Û=_I.dÑBzuõ£Ó;¹‡¯âÛè›653?ú9ŽX‡exŠÏôºbã#’~ÖvŠñ×éôìt ¥P“˜­ ƒÁ`0þ#DiiDAá Oxâ9žã9la [ÜÂ-Ü’Ú«íÕöj¯4¯4¯4÷²îeÝË µ„ZB-ÅY@,--?.ü¸ðãÂ„Ú õšäË9œ³ý ÔÎ<ž5·ÔH+<Øê—³ÍüFx«k¢rò£ï¥½/§¾6.Zx©Ëss–ä—NªmÕÜzÒžØáš`ÈÝNïë'åé÷_’°òÎuà6¯ÂzßéÚ¶¸6o ÛÚµšêÔÖÚÃ:ÒxÚÜËêîÛÎW7g¾ºÞÍ2½zzET)ØiÝŽ;£_$ÿØò†×ÓÐä™y³;Èߎ?Fn‘ú’"é4IMU [°ÀÊø?Áé¨îz`éˆâ$N2+3þÃôÄ`0 Æ÷Œ¬ã'8¡: ƒòŠì²—A”±­j[Õ¶ªßL¿™~3]m\m\m„l![ÈFy”Gyr’œ$'M¦@S`âÔÄ©‰Sß¿~l,c,cTTeøC¼WJt—Hå;ç¯-îiïæ”©;Že†–m·½d~ª½ëóÙgÃ]÷æ9êsˆž¥¡x*d —;õFõ#uU©?ÝH³IYò”!½p;9 yGæÝ*ö®Nâ¥[x—’xiù´ØÏ컾\Ã"Ï[,xÂ÷²ki{è½QÈ<Þ<3ûhÖ`CBÈGç»6u§¡ZZñ½ö–BÈÍÅ$.þÙçõ¾7o>­ŸX3³xöÀ>/9Bš‹Ýérú«‡'x‰$¤BÀ:¶þ ʪV¼¤¼Í-#ƒH³ j¨¡V¶`Qq$ŽÄ1w~L.Šño¯œ¥XХą¸vå0Œ0r©L"+¸‚+ÿw ‹ÞEï¢Õ†jCµßW|_ñ}Ôè¨ÑQ£«dVɬ’XºKé.¥»èÂuáºðŸíb:¦c׈|"íåÏ,^5ß7ƒeØÙ£ý‹[>œ.ÑO°6¸Òn°w³ˆÊÃò5ÁTôG+ï^^­=ITͨšQ5«ö¨Ú£j     Ÿ<º]Øíp…+\á7¸rÈJR…ôÅLÔÍýáËæùâºqV•Ú%#Ë$ Õ·MsJ§ûw©e->aPûò†~c¯´ žM¼Ñ¡"¥Ó^vq¹rÈŒ–Ç9Vš®ñ*äXßîÈÏÌÆá~àœH$ýì;2mšß™Ø´†}iÏñ»ŽgÄ~âÉ RAò ÝéEfƒÁ`0 …؉‡q‡ÇxŒÇŒÁì¤vR;©}ûúöõíë”î”î”.D ‘B$-OËÓò¸‹»¸k7„ÂßÛ¾·}o›8#qFâ ³ŸÙÏì§ìya.ãÎ`;va?ךÄ­´™–¦–c#g•lx¤Æ´ru‚<°—4$»ÎÇÆµoPóÖ°2ûìQæ§bu§7N§ÌСSBkkkÐ~Ð~Ð>~ùøåã—HE*Rá oxã)žà‰õn&o1 ­H5²‡L“FÒÍ4[>¨¼o\?:ÎêšSzk!—.^ÅHPˆ³½Í`­)ÌigÙf­¯ß  Fêmê믓CÓvn°¹W,¾úbóåý÷^§~ÎÑå½ ë¸þä½µžL—Àý06PC…l˜aa×ÿÀüWõŽ•;!oóÉ9Ò’Ù„A„Aò¦M¼M¼M¼{¤{¤{¤kªkªkªª‹ª‹ª‹22w •Á€ \9½lzÙôrórórórMtMtMTuVuVufWƒÁø›’»)R$"‰1ƒ1èŒÎèœ{ Ó9§sNçŠúõ)êSyaå…•FMš5µÊœ*sªÌ‰‰‰)=±ôÄÒýûø÷ñï#T* •~öQ…H!RÃ1Ãs¿Î_å^EÙ¯–¡4 Xm)vaò@OÉ÷l÷þ%)½p}`­JŸŠð9¬üˆÞMï«/Y)²Rd¥ªšªšªšðÆáÃs¹ÇÜcedTA•ÿß÷Õÿë“ÊéH1xÒÙ¹úv~ã`i­S¨ìÀwó‡ëZ= tƸ®“ÄÈ ËÚ‡å”Û¼ÍsJ'çëXˆÒ©;Wz·pñF*ÃgùÅ8çuøY„ìÄ],#ÝpË|ðÿéË³Ž­ÿÁþ±ú°_ùW-øÂY6ów?w“`LuTGu¾…} ûjÔ,¨™t_º/Ý«W%®JêúÔõ©ë±»±v°ƒ³ƒxoâ-O¾'|OøžêÔ7¨/­J«Òª±Cc‡ÆU®œ=؃=J>(ƒÁ`üUä®à D q÷pO™®â*®Ê®:]uºê#ø>‚ËY—³.g¹¥ÜRn)­KëÒºhŒÆhlhehehõ!âCćˆDc¢1Ñh^b^b^¢|ÖŒÀˆ!Òt]€™˜‰™ò1Äh>4ÃZGÞ¶’&hLãvšƒ°EèΕBAa2×t›ùX‰G—Ï{Þy÷¾¹D:á5-O× Ð8ÊØÅØÜ²À²È²”>£Ïè3­·Ö[ë-x‚‡™˜‰™(å³¹‘½< $PàÀIz:”œšäÇ;ÚœŽÅìwuRýÓ…á8Œ+øqáõùOôíë†{ç»Øåx‰Œ|g=ìl )Ž«"'65¼0 æ¹^!6Þª•3¥ZÓK:t;[²ZHƒõõïš_Nù¡GìŒÇç’›e†e÷’ïJf'i?–ÓêI_Ãjðà”£b¾èÿA°Í£ÚÍoƒ-ì`V¤¼1’23}¿xÁ ^4”†ÒP`€AŽŒòòòñ'ù“üI²l `–Ÿeþ1¯ñ¯åMëëë£h"¿•ßÊo••`…V63Œ¿¹ÒFÎüˆ¨¸é¶°…-)KÊ’²N;v:íô»äwÉï’Ã6‡mÛøž|O¾§|¤ŽÔ‘:fÞ˼—yïÃÓO?:ÈÄRŒáW’(òîyÿ¤‚©SÇà8b±lRìŽÇ^½êF†Ö!½H“€3Þm§ØNÌ- Ùç²Â ¦à*Žsô‡'!ºYøÉ.yÂ3òYyñÖ«—k¯Þô¸ÃÇUéòÆc~0yBúˆ}隉VØ‚ˆÃ[$0þg—­Ý0á%Ÿ,èaA }‡gp@´H‡Ff ïŽ„ UQU130CÕGÕGÕ‡wâx§ÏC>ù<$§zNõœêp‡;Ü1 Ó0™¡ gR¤¶R[©­PT(*MÓÅtѰɰɰ -Ð-äÒUf0ƒñÐÐHI ­€ ¨;eÅÅÓÅÓÅÓÛ×Û×Û×e•Ë*—Ud-YKÖ npCGtDÇô–é-Ó[~Œýû16 H}BŸÐ'ò»8“ëÏ6°ùEe6[è BWÔAQ:TZB›©ßªJòÂÔ¤ÎWÊV¦å²]-Ô—íDíàÕív^½=íŽó‹âÉ&n"yCJs¤WÔ™,#UHêD¨“I4‰&aC'r"'jÏhÏhÏÈQ8E÷æ×cQŽÄý1EÔSÕsíIKâD§Ñ®´ËGï´èŒÙcæÅÕI+ZÄ|T§ÇÞR•ó7jU­èËàˆÀçË6 ¥Mæ/–æq9%1¾ãl¡m3eLôÙ¢—º-iÍ—üCÑ뻟–ßXønó—«ßµM)¶s€ÔÂt4 óÈk+-¥©„gø„$pJ[«ï×?ײsåÚµˆ†¼àܱ5P Ð Øïú;%W&ŸÆ§ñi%BJ„”‰:u"ê„c-ÇZ޵”‘éHG:3#7rŒJÞöâ7ÄoH-R‹Ô"ùÎå;—ïœ2ènà†r3c0Œ¯Gîœug8Ãð~6& YÈroëÞÖ½mñáŇ^©j¥ª•ªF{D{D{DµŽjպʮ*»ªì*y±äÅ’=›x6ñl"Ôê ?ÓcQŠVåÌø_“˜+Ÿ›ûÌ•&ʽuhPË–%ŽRzõÈ(©ÄùW|v?è×czžCÎñ6Î8ˆùhCÎ?)Ä+«Ä¿ÿU6WÙ\esTDTDT„Wi¯Ò^¥•‘¹j~#œbQ‚z(Š¢Á" Ⓠägkï>×ÚÚ‡Vypñ¤÷=†7Ž §tÚÁ.ù)”Ò!'+eLZ›CtÛÄ}íïS:£o× ñLJÎk¹jÑêúÞå2üû8m±Ïû3S½!_HWÒ÷°SyI„ï3^Ð_S­fêvª3Uurꛎ›î|؃öXƒ½ìWÿÝá _øÊ?KÙq– K…¥âñøðÐ]Ðû°û ‚ *%m†ÁÐB ­¼I>’ä#ÝL7ÓͼšWójåÊÉ@2”›\©5 ƒñ»ÈÕ–ïMÕP ÕP ¥P 1ee. äö8íqÚã[Ü·¸oq§BN…œ OâI<Žp„Óôý®O×§ëÖ'¬OXÿ)íSÚ§4é¢tQR”÷ˆñ#~Ô:PLÂ$LRÒG¥\i'¿„ ”Ó“H ïèsúÂm‹c^]ínkêg$³–Wò7Ô/„Ý|î~T:¡nj@v*y@Ú£ ¥ëQjà”P5HÉ Ñ-t ÝBÚ“ö¤½.C—¡ËÀmÜÆí? Ù$wœû îáÕbÒ¹ÔJ%ò#²q…{HŽ‘!ïK}i’qe.Îá–û¦w·¤gû†FN(|¨u‹"QcÝÆÙç§žÆ/¦™ÆrÙVC^ÿËv¥´´/J?.° wÑAA•W¿™þ|Ïúq·'œ†3Ú’VÒº‘&)î»üxñ­¦Ó¼ÔÛ¢nðK·ÎõCä'•»¡~¯\Ã5\“7ívÛí¶Ûµ+jWÔ®Èî‘Ý#»óýùþ|e¤¼ È`䂸Wâ*o{ óæ5¬º[u·ên¡kC׆®UÉ ÖePe˜Å Æïâÿ¶FÊß–oË·urr*©/©/©¯2¨Ê *ƒ¢vFíŒÚõ0êaÔÃ*¤ ©BJ®+¹®ä:{{{.•KåRö)Ïð Ï”2VùÉïh"dT¤qÅ:ˆ¸€þ~‡=JÙ5Iq9øªÇpó™Ó/ûu¢ôÆýa7œmú,¼( ÅsL|x/r~ð€ýÏö–ùOù¾ù‹üÅ öì+ØG—.]>bDĈˆJ ­j¡tÐA÷ÕÏ‹ <8Ù¡ÇMŒEWpndIî!.klÝõ¾ÃNDq% /Î×"¥Óã»Ö§tÒÆë²êŽ9Ðfm;qgû”NÓÕç³iÔ¤Öw¤ÔK/_>oc×…Ž#~v®{“{¤,˜~¨‚|ðUœøo.†ÓÞV-ægÙŽPg ?*¯@Ec³Áw‡< åÊÌSµPµPµ‚…`!Øa°Fˆ'Äâ eÙQN›a0r#B„¨lŸÁœ¡/è úQ¡a„‘EÜ Æ€á.€(€8Ä!Nv^=÷yîóܶ*lUتP)T •ìMö&{¹An´2­L+§îKÝ—ºïцGm¸|3øfpbFbFb†ä,9KÎx‡wx§Ó˲ )HAʿфùõh¡l`!"ΑàQ ÇÕn×­ô%çÏ®ÃmÚ§Õj~ÄóOÜ“jnÿpöÚ³(\&kÐDÜ/U¥¼E"2~¶Ï\õfR}©¾Tß8Ä8Ä8D.Qå+òùŠÂGá£ðGqGQåQþ«Ÿ Deå¢$&c••JÉ´W‚T„™Û@Bp)¥SVRλYÕÏH7ueF¯å»ÛÀ!A?Kýý9âF˜!r]È=b/-¥¡4­hhð0× -®W /PµÌÃĶ䳠ånŒ]³¦Ü•ŸÚ¤<ˮ­"Fr@êJµôÕ¿ÑT‘våt§îÔÝ8Ç8Ç8Ç~˜ý0ûaüj~5¿Z£‹ÑÅd’L’I”¸ûIœÄɯ~Žrgœé½ – Þx…QèÀ&×±ê³sf@–jNáFßuê›ÏPOSèTà¥Áó#U+&;°éHiRfÎ'C¤)Äî©pŸû<¸o¥äPKÛ­a¡A;= xóyîÈK•ï|­M›^TÝEÁ&5JkÐtܦÍá€h衆,Š0ñ? A› <à7ëë«ü„ÛXèRÈ‹IlVøÎ³ßNáNÉ?0m6HD#i$4Î4Î4ÎTâ¦YÈBÖ/Š[1¾cè'ú‰~’¯%q´8Z-EHRW«ÎU'‹È"²ˆ> è8ÀÌb ã7BAAI‰#q4›fÓl7ƒ›ÁÍà\ع°saë0ë0ë0¹p3#<#<#üý­÷·ÞßJ®“\'¹NîÝ{bOì_Î_ÿõ¦¿ù޹ ãQ‡I2jh…|ܘ¬6y"¬¶¥?è*KÏÌáÖ|×Þzñ¾ÄŽø3;žU#gÈ\”úÓ‚´`5Ò‘ óÏöl†fB!Â#<Â#Ã'Ã'Ã'Ym†óçü9uuu¥T÷ω¸ÿÂùR¶ãð ïQ³°Q2R+Ö‘†¸Ží\g²åm½/¥2ö/Åeܽ´ùåíÛÏòõèVƾi[®H| w¡öžsœLXb¾héŸs6Ëhâ~^;V%ö¾ñ%¿v­‹f‘õï©_ YãúÓR·¢?„%;pÈPÃT4@Âè%´Ç ŒÀA\úg¶rš*ü ~´þ‘j_Ny­; C ›¾;äVrŽ;UŪbU±tEG™ç™ç™ç)Oöò¤Æ\vÆÿå#>⣼)•‘ÊHeè :ˆ’£>d/ÙK~Òª’s. ã·QµQ›¶¤-iKîwŽ;çêêJ³hÍ"„BhDß›{oî½¹Éc“Ç&UŠãçb.æ¢.ê¢.Í 4÷q÷•=õ@ Tàù^Ü=¢S¥£t{x©|%Üw4ìPm]þ¢–]™“Œ%9gáç>áÑúž×:Ò{(‰yÄ™Ü"Ãñ ïñå߸ì2²ãÞÐA¾;¢ Q†(9©•×òZ^«Û«Û«Û+¯ˆ’¤iñ·8ƒÿ¯°•Ð}(…âhÚ”^'oˆ×9-2±5m^N¸aíŒUg^Ü,SeÞÚåÇö xzhblôóGéq†Sú*Úzš&¸Íõ#ÑF­1Ù|DÀ¥¢AŸó‘¾zœÖiy­®ëŽ6­YéYh3Ïò.f:51š–‡3êê!ˆ{D’ÒJF¾Ìß>†ã¦ u¸rúT¡Ÿ$¿Dº£üØœðÝ!;îña{Ø«ƒÔAê tGwt7W2W2WbFbüª«HFnîhDc>æc¾’a)“;žÁ`0~=rôºú¡Ÿ¬ckkë¤vR;©å¿Ì´Ì´Ì´¸ qâ6ˆuźb]%\vЇb(†â0ãðW?Z5Tàá[hÄ R)šƒ˜ƒKGtl_ÆM‚Ñd¢ª©íM‰c½/L~yìÌÁ[+ß•!5‘ù4RÚDËÃ˘-ådžh€ò#‡¡­¡­¡-¾à ¾ðKø%ü­½Ö^k¯<”@ ”øŸ›1}=rǹïá >Ò`jAiÉ {Ä`Ú¡s$Ë’îe λ°À%ñÞûRs—ÆïÓô™äèõOê¦xfVÔõ¡Úºª©ªí¼öŬÆ[¶yøa¤]ûš%ÚçS_1t¾X{àºÚÍl++²×³Ë\:ݰA*DûÓXî)E‚H¶a¢ÿî…­^rÛÈ ]¼P»­¼Ö ApÃ!67|gäv¹ö`öhâ5ñšxZV£ÕLLL˜‘ÿ…\Ù–˜…Y˜¥´ûîþ蚨‰šÊ»ŸÛƒÁøg!—¹Ë 2‘‰Ì<çòœËsŽ¿Æ_ã¯IÅ¥âRñ„؄؄Xƒ` É $ƒºRWꪄ þœcÙõ3Ñ‹!W‰^ªCóÓC ]ËžVýfä½À;ÒIk11Ò4Ò°ÔrfÂìõ×®m H#iî.H*KaÒkzNqéxåïò ŸðI~Áâbq±¸XŠXŠXЍÃÕáêpÍ#Í#Í#ØÁvTEUT¥¤Öä^gøû`…I±Þ lÄ^Q’(ÝK®‘LÔ‚_z £“Év).ã^ŸMEn½}V¿cSCzu¦ )šhM´&Ú­©[S·¦´mF›™šš&š͉fÄ 14ˆÑŸÊLÿÌ$O ”A<&ÐPt¤Ô „…\‘1­Ç•zE/r¥‰WM]GØr|uìÙø¬Ø¨GûòM¤Ž).» ¸_u¼7q7åû¸…Xˆ…˜K™K™KÁ.pQçUçUçå]yWÞ[±[QEÿ¥µò÷D.À•£ñ„–£’†ÐkÄEôDC.€ãMú}ƒŸñÀ‚§—VÜ«ÝzÝÑ©Ý>íK¾ºùéä/þÙ-µ'´ÕÔIBiaïgð37­:á˜4 +-=¶€û‰Çí"«Ç¬ïÙlq¿‚Û<Æ;¯E+ÜE¦h¢è9Î|ÁNb%>x¥¸ìB.9п ƒiû¯Z.Gå(¥í0p…#›%¾#rµ —7YB–E—Ñet™ù…ù…ùÅ¿~NL„ñï‘u‡òÍR~ðÃÜÁ¥ðKæk´a0ß6²Û=30/ñ/½¢½¢½¢Õ Õ Õ å‚Ÿ}nô¹‘UoÕ[õJ€ w’ÞŸ‰l á:sˆ íD¯ VÛ95ö\±°D_Gq²a¹y¡¡hÎ~söèô¯^YEJà ¦B ¥Å’Ö_y·•áDˆ-)–KŠé˜é˜é˜LÑähr49ªõªõªõÊ꺜0óÏ:ïòÌ}|D2ªãG’âéKø_lÅ4a)׎\þ|5ksÎêU^±uö ¹ôʾ´:zõƈ»;¦UÖ½µ‰ÑéU|Q®TΓìU†áöT­¹Ví–CÓí;=OÖkµº@“á•–DÌõM÷h!£÷‘— ô=‚HKlÅ0Ž-.a šã§ ”œTó'ÂÔŸNp¬©»§uƒœÀKýáDË£|àÁf‰ïˆP„"TÞÔxi¼4^Ü3î÷Ìn 7…K÷¥ûÒO j©HE*3ãß;áJÖ?.†b(&'_)­¹eØãƒÁø_éŽîè.×ÌÓ…éÂtWÑUtÑ]ÑÕ:Æ:Æ:æÃÌ3?Ì„/|á«HÐ’?=>j=ÔÄ70LJ£C©íÝÕÚ›…Ÿ&3´³äN8øé&.ï»gÑÝË|⇤tã$nyNwRŠÞ0Àô¯´Ã_ƒqo…Vh%ŽGŠ#ÍEÌEÌEd5wu]u]u]Õ,Õ,Õ,%¡Q.Òýç"‹9Ê‘øwh…QÖþÒVZ™LÃì$" ØkXo>m´pÛ%Ÿ»ª\_SëèÈî÷.¿üñQ—Ô˜ì>úÚ™šá\+n9ã`cM³Ž„SÞéqI‡|ÏöîÔ¹f±õ÷š9V^‘è÷:O5º ­0KiÊ’ý°Å>Œ\&a ûµÄÊ]äúÕài½ìhÒIššHÇX¤>4=Q^l!û»BÎxh.k.k.s6œ gc~`~`~ ÝnH?¹\ÌqgüoðoäMñ–xK¼%kËð”§<ýY?B¸À…ŒÁ`ü*ädÎy˜‡y؉Øé:Ãu†ë »3vgìÎÉd2™üåÀ—_ä´Èi‘ÓBéЇ8Äý©é1rEr`&éä0zÒ ô1Zõj× LÑ«…ë(àáÎ5Â[¤'—øx9½í‡_>ˆ€I°Òƒ¸†·Ø†Óxú3¥ö_à ¼À ò‘|$åõsó"ó"ó"\À\P¨Tj/µ—ÚK/ÏÀäÞY”þLÏÞ ‹BhN5°ATE(òósI:™òepöYy1öÄ£|eÞ,_³?´wïúëéÛ%WÊðÔÎÕ™5ƒÔÍU¥ùÙ_²;›i¶Ƶ+R¼UÞ|g7u¸U½÷¦«-EåÏëíâúÇj<ïÒrt5·•”Æ 2qXZ(€€¯]ØÊt‘ôÊᜮ‰f5 ÝHŠâÒQyàÌæŠï¹ó@=V=V=–£å¨yŽyŽyŽxD<"Q~ä_ð_˜Áÿ†\u’d'ÙÑ$šD“¸‡ÜCî! #a$L™«G/ƒÁ`üŠ£8ŠÃ~ð#}I_Ò×}¨ûP÷¡ä"¹H.ЧÅÓâéûû{z‡Þ¡wpçq·q·ÿÔã” ’¼xÉÒmꎑnGßèXÝlyøDúÀ<ÚÚˆŒW—¬,¾Ê=ûÇÕÞtK½Ä[¹Z¤‰ä#Ý¥g ü¦¨­¼¶ˆD$ÊÝ©ÃÃÃÅõâzQîÑÍ(Í(Í(åèNàÄ7˜²(kÔÈåÇñ/ÄÁÔŽ!Ë‘ˆÓ|2‡xgž2•5oZ¶ìJ¡{[#¬X~УwƒÝ¯­½ç˜t;ƒØ8Ùdéjðíù«\ˆi¡A0}R}$™°¶.S´y`å¸×Ý׋\[¥i­Ê^•Zñ%Õ¦ÇáFç!Ž÷xÅW$gI ŒGcTUŽJø##ñ ¡’=4ÔÏø üf¾†ÕÏJ¬àÆ÷ï ya ÚªÚªÚÊ]à.p,•-•-•iÚvPžn3‘‰Lf0Æ¿!Wª éD:‘N$“d’LE[Fnÿ!ÃRe ƯA.,‡r('ç¬Û¶-l[Ø©½S{§ö´-D e7ÈnÝ uHêÔ!È‹¼È‹ÞèÞê<#¶<àÞ†¯Kê‹>RGê<¸^óÂÅßyöòupÚ*¦eŸ4[Sò¦¬IŸSm{ß[Ó1EÐ^Ü.¢3”¼ölÿÕ«õ„¦‡éa#ÁÆÕÆÕÆÕÒi€4€ ₸ }}}EWg Ö` ÔPC­(ÁKÈ¾Š "D9öM{ÁÑ¢/u¡ŽØ‹v¨Å #±X•ÓÔ4Ëì³ WñÛÇÞ3½ª\;¦À¿½½ó—®Ppgi³ç9Ǫ˜ÃµáÊdzÍÎG$âÔáLÉð|ù›蟱¿Ò3›CN¼ròáÑØÊoj~j'‚V¢Ã¹¸Žp#ñØ+%Ó[°ƒ<8X )E·¿qH¥§©‹½^;HÕE=—×rW­œ•‚¢ÜY_Ã(ˆ‚ò¦Æ 1h Çqg>i>i>‰ä }Ð}°{±—Œño0£¼I+ÓÊ´2­EkÑZʲµ|“ØÝØý³lxƒÁø¿È®°ì|'! I²òºwqïâÞÅùÅüb~1-GËÑrIç“Î'}E_ÑWÉöþkŠ/)w‚s$aÖ`q]ÜÀËÞ¡D׸ƥšˆ÷³–›Šó‘¶jÍ­ ) æÖ"KmšÍ…“íÈ‘žÓÕpø=.»‚G˜j™j™j‰[Ä-âa¿°_د»¬»¬»ŒJ¨„JÊŠ„œ0#wCÿVÉí ¿E ÒÐ [qR2R |`ÄbŒ†qgHµ”ÉÙšœ*qOêntº•ÿiõÖÚâ>ù“»Õ*±!$¹âÄ€(÷G˜(ÍÏjf×3vÕ¸òwɆVçBkùû5^°…oÇMâƒÖob,}ýøã‹—n¼.õ©@$ËÐçÈ´¦ûiGÌBsüˆ}¿­c+BߢŠ]‚z²ª™ê 7€¬—ŸNI>8ÃŽÍßÑ Y‚” %dKs\s\sœ ã¸0“ƒÉÁä »Yd#ÙH6Ê"\ÌbŒÃ+¼Â+yÓ:Ð:Ð:P$A„–BK¡%W€+À)éXL’Á`üä¸ép Çp¼Å[¼ÕnÑnÑnqç:Ïu­CëÐ:V“Õd5%ÔL¨™PS™Uú¢/úþ©ÙÛ²h#:YzI›Â5°tx‹˜´’áζŽz}=RSm:>ìõðÀ§Ò›‡Ÿ¼õÄŒLœ@_º Gñ9ÿc)ê/!Ë ƒÅ`ó‰ùÄ|x×x­?¯?¯?OÒHISìó}PŒÿ¯°ZôÅ4ëré ­F&âvp6pÃi½¸ùÓÍÓO«Í_;ïè¦õ¶V?k¾Ì½üÒ@wL㡺ÈÇ …ÎfÞn^a³Ž±NiÏ…Ÿ º{Æ©Ãöš›·­nU#ÚX.0¨w!z½°”j¨eQ °/A®‘®p‚ó¿r[T¿¶· ‡ ª¢õm3Ô»;a ÈMUÞ †ÓO‌o/xÁ‹Ž¢£è(9GYÕRÕRÕ’n§Ûévóóó¥=ò!_î¨*ƒñ3äš´!mHa—°KØeii)v»‰Ý”‘OñO™Á¿Hî(WB¢ÄÀ^â%^" HPÞý3o« 㟈œœéw¸ ¼À ¼Ûe·Ën—åjñ˜xL<öiò§ÉŸ&+A%9L«›ÄWGÖ©…Rð%‡1‹4D(Z`ÑÄ»&—yÍ÷ÔöPíà>«ò—îyðéÓæU§F?¨Cn‘ö¸&î–ÆÐÙJÙâ5ÊÕD%Q%e/ãJãJãJzžž§ç¹n\7®›>]Ÿ®OWÆË• ù®d… Zp’š6¥»Höc1?„œ# M…,§¬-w¼üôMù–+qÐ?fÀŸ¯öfÐçöz{ÝSmᣗw652d™xH¦ÞͺÊï+\ZÙ¹E­±›Þ·˜V¹tÞÉ>冷ô6 Óy(‰N¸[xÊW!§H3,AG4R®‰ÿ#1ÉIi´$&Ø>S­á“„~Ü}¢(y#vбóø]P ¥PJ¾dUÞ*o•·°VX+¬µ6¶6¶6¶¤YÒ,ʲ£q4ŽŒñ‹<Çs<—7­:«Îª“â¤8)N8&ŽÉ· e¤g¦_-ö±Í—[š’*•j²*^³[•fÜaœii'ÚXc¬®­½Ãw·=Ü´õÑ軎¶ ©>¶ôÒ€|ž+ðY¤‚xŠV¡ÛI|ð†ë@ZWX þ¼c« E¢>]¥ë- ãsø‹ÄŒTݶP³3ø]†â(®8î—U¢JT‹j«Ú*Öo‰·¬³Å brˆŒ!cH[Òt Ýh7ÚM‰¡¾Á¼¡·émz[qÚnán!±ˆU¤¸äR!aýÈ¥N@ch ¡ÞÔ›z“dY@ ’‚¤ FaF)7fY˜LV9`0 yÕN.dè(ë˜yõõêëÕ]Ð]ä¾"III4Ò@eám–ð€*ð¸„Åh!=£Ói 7‹<$ƒ‹4ÿX⣺­ª_÷3Ÿ÷äéË#^–9½ûfù·§¹2¤WT…aPCó¯îú¿ÚÐ +¬919191ÐB -9EN‘S:•N¥Sɯ(±yÆ/‘ÛgÉ@Œˆ£Ã©%1ÍPS(Ä¥“ñ9L“Í!û‡<À+ìÇÃ*¯ÇÄø?•\×ná{óž­¼2hjž‘€ôBL5ôÍîiôÔlàIMÒ 6õ oØ(d‡w÷ç?|·xyLì¹Ç'.VUùÃ0Åi:ƒÖ¨ÈÕ&»1…‚ÎÅa˜mÆÏh·ƒÒ©}; ÔvMq¸¬œ÷“xƒ­ì¬}ÜÇ\AOôDOÛ;»2"æFÌ-ö°hí¢µQë7ÍÃÈ02Œ»ÃÝáîå„rB9A#h ‡¿Ãßágñ³øY|y¾<_ž3rFÎÈíävr;¹\®§æÔœšì&»ÉnR™T&•qWqÓ1ÓÿÔ©ù{@~Š—‘»çnÂ&lB2’‘Lj“Ú¤6IF’‘ä5yM^Ëg‡ëÏõçúsó¸yÜ<.KãÒx5¯æÕ|¾?ߟŸÊOç§óùíüö²ÉåÞ–{[ý‡ûjì³ë°ÀaòY÷p÷˜ù Æ¿AN’©Šª¨jWÜ®¸]ñŠï+¾¯ø>Ê>Ê>Ê>rxäðÈáB^!¯WIÆ“có¹2ÉcÒù'øfWªô ¢ôŠeðËëÓÓú…š^X<@Œ² §¾ŠÔ‡àÌ»’+_ý`È›NÙNÙNÙUrªäTɉnÝ"ºE¡‹….º¨¿q#ßkŽûï'W )€˜Åå!6¸ˆ£(¥Ñ•pQØ.¬j¤í´òBÿtJ§NG)rºÓ8“Û¸Ú2úŒÛö.¥Ó.v¾i›äÓ1aGþ˜›Õ†VÓåé?öß\€æŠãWµ;¤Z£î&h*xÿ8ûØèKº×C>Æ‘£ˆÇZ ˆag盥º¡n€§®¤Ö©uU=kŽ«9ÎíˆgÏÖJÒ:i©yV›¬6·Äöˆía°ÝŒnÖbV‹Õb]c]c]cÝbÝbÝbéoéoéo}g}g}g9f9f9öUŽ–žÁàF(ZòÉHF²¬6 ´þy†gxFŸÑgô>â#>*yùr¹’<òá½AoÐx€x ˆ]Ê™‘²0V:Ò‘®lg ÊþåæS)HE*Þã5^c6b#"H9RiÔDMp%¢Ánº™nÆjŒÂ(ø"Áp„”8‡,¨‡z8ÀÐ@ ìa{¥ÄJtÊùÝp„#œ¸wâ®4Ìòƒüˆ@*Yžù‘ù•ý„ !ÄžØ{eŒœà$/=+B`òžƒŒ`Z„¡EÇ?ˆ¢7 ](tAs[SKSëɶÇG±^@ä1¬1^7^Ç",ÀÄán°Ÿ#ƒÁP8Ó8hD#:¿o~ßü¾Þ‹½{/–×oãÄ7ˆoðªä«’¯J¢z ‡’$óç kÈ”Dx’3¤!.^ünØ­*+Õ­f‡ÞÉ·Ôý^ª–ð3Œ=5ýÉÔÆ7ÆÝ<| P.âT©-Gxƒ$¹¤õ«¡¬a¿K±TwNwNw.¢bDňŠrõZêëÔש¯oï¾½ûönùÑÛ±Û•UtÆoƒSÖ9DP€'d?i)RZŸn‘‡htÂ%¡\½…ß ð,s³Àµ Eý¹å¸ÒÓànð4-Wi8WKx§Y VYœÍO¬q—»|èûùÃŒNÒïÍ9gx5ãÓÙ°BB0<`çRUßKÛÀ´ùG7ÁeüZd±)ÉOò›G™»™»•^V{_í}íwÕýUÆy0=xk}k͘ðèÆ£7r‘\4Däæfff˜žšžšžf{f{f{oood}Êú”õ)kkÖÖ¬­Ùo²ßd¿É6f³–U–U–UÞÂ[xS˜)ÌfìoìoìožižižiÜaÜaÜaÚjÚjÚjhahahalmlmlÝ=»{v÷¬ÒY¥³J›÷š÷š÷JS¤)Ò”ÿò½‚Œàÿ2Fv—0£‰éOúÓÖ4‚FüK*–÷¯íæhN“{ä}DÒƒŠÑýûOš²|v#×߯ŸK¨QI^ú„ÖBk¡µ&U“ªIÕÕÖÕÖÕVÍPÍPÍKšøsü9þœ¾ˆ¾ˆ¾ˆ t‚N×N×N׎óçü9ÝÝݾ>?šíãéM½i€Oi»ÒvRYOÖ«çªÞªÞnÏ·¨í¢¶7Ú\{ý-iN:’Ž4ŽÞ Ìqg0À4LÃ44DC4TwUwUwu:ætÌéæc>æ[W[W[WZöiÙ§eJùû¿2A¾zB¦ü)X! /ùT²Ûª§Ðàöuk¬.Ô¼`«ümóTšXÖJU͉Ö£g¯Ysõ„8EZG'“‚$Öãn®ý¯‡,ÙL@@¬öV{«½¹·¹·¹· ô‚^µGµGµGÕHÕHÕÈ2Í2Í2M–¦PJ{¿Ÿ*QPè ‚ h}º…¸b¦s-‰¹nZb-oݳ§æ=<ÇÜÛý¢T‹~aãóÎë&–ª–ß>*)èMž6€ôQ\hnoh Á0AŠWá?ѽbe´íXÍrüÐËÅŸ ?Óït`3@×§Ùøn3’à Wùúž6¥Myàû€©ŸÉÍäf6Xâ-ñš)¶}lûèítº áœpN8'ŒF £…YÂ,a?ŸÇÏS5Q5Q5Ö ë„uÂáŠpEx&<žYÆZÆZÆZ—Z—Z—š{™{™{™ š š ZzZzZzšýÌ~f?KKKósósósó*ó*ó*Ó'Ó'Ó'c¨1Ôj ¶[ƒ Œ Œ ŒÎFg£³¥»¥»¥»AmPÔæCæCæCÙ¯²_e¿ÊNÌNÌN4u2u2uÊZœµ8kq†O†O†±°±°±pfÌ™=Ò—§/O_žq=ãzÆuÚ“ö¤=¥‰ÒDi¢ä.¹KîÒfi³´YÖ —ŽHG¤#bE±¢XQúAúAú0Så{„>;°}a]­V«çSŽr¼@$"e•Ëœ‘9ÃTÇPÔPôg6ohÁßæoó·Ét2LçÇòcù±Ä‘8G®)×”kÊé9=§çúr}¹¾ä 9HÑÇ;wÔ1êuŒí Û¶/t6:~¥~¥~¥MšMšMší~Ûý¶ûÁGð±I·I·Ij µ…Úº~º~º~*•ÊF;V;V;VÕ[Õ[Õ[ÝSÝSÝS}H}H}ˆïÂwá»hzhzhz¨æ©æ©æ©ï«ï«ïó ù†|CM¬&V+§6iŒ£ÆÈ{óÞ¼·æ°æ°æ0YN–“åêüêüêü‚¨*©*‰žb>1w"ìIØ¡ò!ŸulsXd¿È1hŒÆp€7¼Ù‘Á`(yíÑåJ×'®O\ŸèèèȳåçgŸŸ}~fˆ4D"q ÇpLi$ôçÔPQPP.Y†dqº´ŽÆ¹s,¤7ìmk”ìÇ5¦Z‰'f›#šÚëS÷V½ûüË«R>“0Äc]Aó£³¢!#ë–|=>ã3>ËG+u—ºKÝM¦@S >R©^ ¯„WêÂêÂêÂÎÂY8%ш9îE'ýŒ6)®§:ªÁ8TC)Ò Ç±UÑ€¶Ý¾èn“ç­öÿø¸Bü®¨IÁÞó^/úªrg¿•®Th¨ZÁï50zš¥’h c¦ù{Žþ™ãîtPWA`åO·ß8rÄ}­D+ñ&ÞÄ›RF¿Ÿû~îYÓëN¯#…H+Òêވ˵/×Þ“õþÕûõ/íœíœmblÎڜխխխՕӕӕӟ՟՟U«ƒÕÁúp}¸>\÷E÷E÷EŽÚªó©ó©óé ´+µ+µ+u—t—t—´µµuuuµiÚ4mš:V«ŽÕlÔlÔlt´:Z­ÚóÚóÚóÚþÚþÚþ|,ËÇjGhGhGH¯¤WÒ+©©ÔTj*ívH;¤GÒ#é‘4Iš$M’NK§¥ÓÒXi¬4Vº.]—®K}¥¾R_é”tJ:%…H!RˆTZ*-•¦÷é}zßTÝTÝTÝìcö1ûŒNF'Ã^Ã^Ã^Ã]Ã]Ã]ƒ“ÁÉà”½'{Oöž¬©YS³¦fUÌ.˜]0µeb¯Ä^ÏI“œ¯U¡ÄB‰ÙvÖÖöQB[¡íµÌÓO?<µjå“•O\'yõôê©ÒùéüTÍTÍTÍl?Ù~²ý¤¾¥¾¥¾¥Ÿ¯Ÿ¯Ÿ¯j¯j¯j¯+ + + ë¥ë¥ë¥vP;¨d×Y¯ŠWÅ+çïÈ;òŽ»À]à.Ƥ1iÌ œÀ \<ÏÅsµ¸Z\-r•\%W¹Â\a®0yH’‡²¢‹\3À¥p)\ ñ!>ćKä¹D¹K®8Yœ,N633³Œ°Œ°Œ022o‰·Ä[ƥƥƥ¢‡è!zdgg‹•ÄJb¥œ9=rzH—¥ËÒeC C C ÓSS’) ¤ )¨ü’"ÑE¢U/¹ÓÜi<’L‘CJ1ëŸÊ`0äHvi”Fi9ýL&“Éd÷ŽîÝ;b=Öc½xP<(Lšœ49i2–a–QµP µ|õ#”;\òàÀ¡"B‰íHã¨Ô:±ZûËò¹ç-çvÈ|4k¯©@zzúdãìiW6V›MqùIâDÖÓ¡”R|u—]FNµ…-lEI”DÉf3„9Å8Å8ÅÈ“®º™º™ºYvçìÎÙeÝwvþÁä~Ì„&ÌÂ9ܦ“À¡ú¢Ê {¹òäGcóEKÔ%iHV†ù–yÕDb j£ÙXß¼üçŽûÝQµÜsË–Ùü»`va†@ -ÒÑ=ö•_Wv]Ù«WûöÏykð0x$ÔJ,X:õyÚ‰´*o¥„17òr›ÌR,ÅÒ_úX•YeV™µÕµÕµÕ5šM„Æ 1h ªëªëªëênênênª•ª•ª•ê–ê–ê–êPu¨:”ŸÆOã§©¶ª¶ª¶:Tu¨êPU¦ Ó…Ù¯·_o¿^3V3V3ÖnŠÝ»)¶õlëÙÖÓÆiã´qz¢'zb³Ìf™Í2ÍDÍDÍD­N«Óê´{´{´{´ÍµÍµÍ544tsususҜҜҸ)Ün 7ƒ›ÁÍàtœŽÓq¸ Ü~0?˜ÌUà ð¸ò"D˜MþÏýŸÏ€°ƒ¯ÄWÊ ¸µøûâï#Œš5j–t\8&“nˆÛÅí4ƒfÐ I”DI¤ èº@¬-ÖkÓsô='‹'Jë¥õÒze GÊ‘r¨;u§îÆSÆSÆS²KmJ0%˜ÌïÌïÌïäu Ã!Ã!áœ}9ûröYÛYÛYÛeÌþ˜ýÑòÒòÒòRN:2™Mf“9§^N½œz†^†^†^ƑƑƑ™ã3ÇgŽçŠsŹVUcÕXí¬vV;kkkqª8Uœj¾a¾a¾!í“öIûLZ“Ö¤•_7f3ŒRO©§ÔÓ<Ï<Ï<Ï8ÖÔÁÔÁ'ÌÛÆÛæEÛ”Ç)¹#|'¾×Ųö·Ü´ÜT¸ïá.°"ƒÁP÷/ø‚/öÍì›Ù7sªíTÛ©6Fb$Ff É’5$u~êüÔùòú…~¡_”¸û×Fv°Ý% M§p^cßH[jüÍö3Êœ•ze}2ÍUï²Û§-¾níö3·:¿XüA“¶ŸoÁiÈ0q¦4&ÁóÒõ׈D$*÷è†hˆ†ÆÆÆ¤©@*¨º«º«ºkÐþ ý%P%HÒ„4¡„J˜þÛWDîØ*³ 'pÅ*J”FO¬Åx’Iú & §‹°ãо‡y^Î?´ïÑ€×þÕn†œò>0­Ü—Ðn5ŸÞt÷‡¹ÄøåíP:5O§k‹ž6œ]q”¼Or ñØÂìü=@TDOôò¶ç0Ôahµ¡ÕVoX& R©F"iCÚ žð$É$¤‘»ä.¹Ë…r¡\(7”Ê å®pW¸+œ…³p¾6_›¯Í/ã—ñËø»ü]þ®@"Εså\å)ø«£äyÁïå÷ò{ÕjµZ­Ön×n×nׇêCõ¡¶:[­Î¾©}Sû¦W®8\ñ^ç½Î{]HÅŠ!‹.~¸øá*õªÔ«R¯Î…:ê\h¾«ù®æ»:¹vríäÚoV¿Yýfvmmssäê‘«¶xáñÂãÎ#I”ĸ(‹£ÅñNo"v͈ÍSbDÏ=G½ƒ1èß¾ûþí{è} ÷öíÛ·oß>fjÌÔ˜©õ.Ô»PïBͤšI5“ÊÝ/w¿ÜýðÐðÐðÐ|7òÝÈwÃ{¦÷Lï™r’Œ};ûvöíìüíüíüm:Út´é¨wÐ;è´Í´Í´ÍÔÔÔxoà ¼-oËÛbaÐ_u] >B%¡’ï0¯¯²úˆ%K¼oåñÎãÍàëðu2?øÀ‡ý Ú  ÚÈ›…ã ÇŽ‹ŠŽŠŽŠŽªU=ªº¬¬¬2RÖûscíî$çDJÉÛóý{ÿP1žÒ«uçH‡ÏŸ06ñõ~×î~ÝoÙ­ ?Hì%wI[Üú«ÌIÊ“ò¤¼"ñ\î¹ÜsyôÅè‹Ñ«î¨º£ê¿v~íüÚ)CåZ)Yñœ*ê\WÚ*2ŽG.E¾:—Ä=Œ~–߯¿ÎÏ÷õ ZlˆV:§2Çý»@Žz^Çu\—UJ¢¢¢+Õ©T§R2Ël,³Që¡õÐz(&ã1ã& øk/J‚–h‰–Ø€ Ø k¶ÈOÿd™Af(„#ᢹh.šÇãÆq§¸SÜ)9¯š÷à=x¾>_Ÿ¯ÏâFq£HI rÊö`öüù&\YîüÖó[_L¤”ÒËEM3M3“ÞPJ鈕ËS–§üεÜ6ü-Þâ-MF“Ñœ-gËÙrã¹ñÜx¾ߌoÆWà+ðx=¯çõÜGî#÷‘;Ìæs+¹•ÜJ.†‹áb¸(.Š‹"b Y ’Ì&³Él2œ 'ÃåsAZ‘Ö¤µü±þík 5ïÕ¼WhMáa…‡)Ç#«ëÈš9 ã{f&`áG}Q}Q}ÑòƒË.?¸Ê—*_ª|)7´ÜÐrC555•>ßPþç;Ñï€äÚvh„ )TÐåPÊž#?ô*cÙy®zÿs”^Ó 4øh ÷žòxò‘ôÅ#å? ÿÿΗÄŽØ;Y7ÌÍÓÍÓͳJµ*ÕªT«²ºÊê*«K¾-ù¶ä[a¥°RX©´Ã«Ú¨Í.Æ¿TÿJ}€ÉèËw"çI“ÜC~–*cßS³_µ÷'õOÆw€ÜaNU|‚'x">Ÿ‹Ï%ÉCòàzr=¹ž¤iAZ(e+Þð†÷ÿÜ—N^zÛ–ë/×˸ˆ‹¸ˆÊ+§sýý_àà ®àŠ²7OxÂS9Â&h‚&Šè¡ l`£#ʯÈùu9¿_v £0 “ü$?É"(‚"J7YYZQ~h)„B(DŠ’¢¤(ñ!µImêE_Ò—3‡õØk`^aÕõU×mÛNµÚ¢ý0·an½ù<òá›ñUùª8 t”§q4N—”së‰IYªRÞ¾ƒ;¸£HX>ÆcaŠDè~Ô(27ð•ËúÎ+ëm*ÒÜÒ0í¦a¦ê•]/íˆ9ñÛ6ÞX˜¾0«ƒiÿ»I´b¼Ô‘NüË\ö<ȃ<´:­N«#ñˆ×WÒWÒW¢É4™&“"¤)"„!Bˆ@‘a³ñ߇Ü^· X0 ppágË7¶SUþ !a°ƒf½ïÙñ•5_ïYïYï‰FÑ(ù2|¾ ?›ŸÍÏVFʺ¹ŒpTB%yS­ý¨ýÈe©Š¨ŠÐ‹ü&~“MûVö­Ha2Œ Sôtå¸ÿw‰eœeœeÝC÷Ð=ª,U–* S1S•·‰’ÝÇ`0¾/TPA¥4† B‚œœœl;Øv°í 'Ý¥¶OmŸÚ>kNÖœ¬9hЦhЉ˜ˆ‰_=Ön=Ô0à ‘|ÄÒ ³±·'Íéh¹R¨¬n)h„ÂÚyª¸G›MHÜXÿxøc¹„Eh"•¡ÛhE¼À¤ýV•gTYÞq(†b¨ª°ª°ª°»«»«»«´BZ!­°ÆXc¬1xøÃÃÌ1æs º¢+ºþU馌ÿ•ÿç¸óàí k¸Ø‹8ÜÅm¼Â[kÿ.xŒÇx,ÇJ­­­­+¬+¬+xwÞwŠ Å…âÊÈ !ˆ Fd#[Þ¤+h9Z;iZz:—ΕœÄSâ)ú΢³”F62ñÙG–zXj[j[jÓj´­&ìö ûå²fe¤œ°Ä`0¾7äžÍ}Ð}äAOµ§ÚS7xƒ7â@q 809;9;9›Î¢³è,¥ÂêÖBÿ`2‘3ß‘[@ÆIC¨+}[1=ì½wbí×C‚{ÒQæ3Öúd*÷ˆ„Îü¼uËÈôûÙ͉‰%#i?zõþ²„¼”™+Äæ¶Ãm‡ÛÝbÝbÝb¹Cj†&C“¡yßõ}×÷]•©ZÖ†g²d/ãï ‡Âð†;@‹¢‘æ™ð˜wVfð™ôc f¢ ª23}ã$  Êâšµ£vÒSé©ô”¯Ã×áëpÓ¹éÜty ñ"^Ä‹Œñ_Èø*R€ XL“ÅÄçÎsçÕ·Õ·Õ·•‘¿>eˆÁ`|KtB't’µÆí·Ùo³ßæææFçÐ9tŽq¾q¾q~r…ä É”Ük9Šü§8Ä$ɘ׈Çû|úêrãç·ŸSú¡z‘f»ª/Z 5¸—çÜ:óδ©ÃÉþ—“†°`¡d¢Ã¨?´PCø DeËÈU[±ˆE,æ`æx=žF<Çs<—J¥ƒ‡þq8.á.)’вËþ'û2~ŠÁ0Ó`ZWuLèËßuÈÔUÖ^Ãq$"‡,EKÔdfúÆ‘5_+¢"*ÒšCs¤gÒ3éWƒ«ÁÕàWð+øÊÈÿ\°È`Èd"™ò&íM{ÓÞ–A–A–A¤éAz¨.«.«.+#ÿYü ãBÎVO@¼:yuòêÄ¿æ_ó¯É|2ŸÌO•0*a”ØDl"6A9”C9Ä!q_Ý!¶‡j²‘+ON‹ç¤tqÕ¼%wûÎŒ_!oÞ¦ã™yŒã¤ý\&WjÜÖÕ³¯þ 9JwáDFrÞd3â âÿT½öÜÈ–¹‡{¸‡“8‰“Î Î Î ¶ílÛÙ¶“3ݳÏfŸÍ>›r å@ÊTB%TB{´G{ÅéÿsŠ}¿að‚;Ô´0mª¶å{ðçúéŠi»A‚ehŠjÌLß8ïðï°k±VN]J¥‡\{®=מ 悹`edÀ Æø/ÈÊ6Dú$}’>™Ìfî÷ˆ{¤þ¬þ¬þIÁF.8c0ßrAd ”@ ]]]§·NoÞÒÆ´1mlIµ¤ZRlllåUÅ­üÚ±v4P¥à/©¥‰Ô¯Ë "ë§—è:°üféDvóM §Îºþ‡]Îy6úÜæ;éク‰øK.Òã>ã>E–W–þzÎ¥ÜbÉ¬Ü îqC ZbuÏôæ¢N!“ƒ›¸æà*ÆÓÓY\Zªaû„žë®^Û!•¡!ô5Š’¸ /Ú`Ý_lÛ¹˜‹¹ˆB¢t‘ºH]¤Ë,—Y.³è!zˆ2f3™É§“O'ŸVD„K J(Ž;ãG ÁN4MèHUþ<bï© ¾¡¼? ÕÁÌô]xÄË›ÖÎÖÎÖÎô½D/ñcù±¼Ò¿KÖaýÕÿÙq·‡=ìé z‚ž°Ü±Ü±Ü!›Éf²Y=^=^=^ÉÊŒï9^‰HD¢ª¡w•»Ê]u{êöÔí)õ¤žÔÓ:Ð:Ð:0icÒÆ¤JÃ>¹Ë„0úzˆ@9 ™Ž4F:O«¹®uX¤ûÍoÖ%¼’´^êMrãÕû„ëÛKþäÁmò|òr‘ÔÅ)BJ¤· ê/R”›ÙÉÝd­°ÂêZݵºkuí5í5í5B!$5>5>5ÞXÌXÌXLQæ‘‹}ÿ@8‚;¥Ã´ ¦ª ðç8ƒ½½¶‡ªŽò[›„ªgfú Ÿégª$0ˆ=ÅžbOšI3i&ßïÇ÷S¦Ýƒ8ˆƒ¬Û%ã¿ ;î}Ñ}aËgËgËg¹ÐYUKUKUKé?ø1QHãGŽ—‡! aòüàœêœêœjÝþºýu´C;´K÷H÷H÷øÒàKƒ/ —]vô¿6E7LÞÑô5B0±kÇ:=Š´ÍW"ÿqÒlc€ehfræ cØxa}ðÕñ¤8’0 çp` T0Áò“ŽÖŸŠ\N*7\‹µXKî;äŽgÏž è^º—îµ,¶,¶,–›Œã!â¡Òwö5^ã5»0ÿ‰pÈØÑG´7]¥òå:p+í’Ô=U•÷‡“r(ÀÌô]« “u±u±u15P5u…ºB] àŽá‹¸3þ rqê@ Ä@Ù)·tµtµtåNs§¹Óª'ª'ª'ò-GIÐb– Æ·ŠüX. ãÊëºÅP ż‹xñ.B–’¥d)=@ЉíÛ%¶£ýiÚ_4¼û¸ÿÍ6Тä¦HÅéZÊã–“E?«?šõ c9œîe8ÍÓÇ-ع}ýM¿Oe>ïÏ àzq÷IºŸôF6Œ°üe¶•ËIgc6fËC.C]†º µ¹ks׿®Üó;kHÖ¬!i®i®i®Jv{¢ÅÂ%ÿ\8Ã64c°‘”ç<ÉX[^½CP+¿¸(ÉJǾ’„$yS,ÓtšNÓù| ¾…7Å9œÃ9æ¸3þ YÈBiMZ“Ö²Snigigi'ÇàÕÕÕå×é;ú޾ck8 Æ7‹üX.7÷9‰“8i¯µ×Úkísìsìsèºn066NjžÔ<©9œá gtC7tûŠ…jà‘Žl˜È[ìDgº‰æ ÷/-–XìA=/Ø» m„ÆüÜwâë×)'×ö?šðȆž§ž´+ÝC ºâ4náý_r Rma [âK|‰¯çÏ1žcÈD2‘LD(Bú±ëÇ®»¢2*£²ìÊËUm,\òÏ…Cœ`KŸÓqØ‚LΕëk·Dµ‚ª¼?%ÌÌô]🡤ÊX÷[÷[÷Ó/ô ý",– ËIR€ü´öÂÜ,Ư!W´ÌZßZßZßÚÖÚÖÚ–ïÈwä;ÂîpWâjòí„Á`|{¸À.J¸'éH÷HðHðHPy©¼T^Ü`n078auÂê„ÕŠøc Ô@ |Â'|úŠ…fX!rQäDÉ‘Îoè½ H—£Ý$ÙH·§Z/ª‰Üº%%v—¾=éµõÓ¾ 7.[EÒ¤#4Šš”’Ö¿–S8…Sh‚&hb»Þv½ízÇ…Ž âü€r–å,ËY–b—b—b§´º“ÓcX¬ý¿°Sº’É(Cò²“ü]+â.>Š© µ¡6¼oÇÛâB\”‘r ;ƒñŸ¹…[¸%oZº[º[º[6[6[6«~Pý úAUPUPUPY @S¯b0¾1dá`9vž‚¤8wrîäÜI{U{U{•;ÅâN}^öyÙçeY-³ZfµÄ,Á Ã0 ûŠGe T\wî&±oˆóéÊâ6!aî¤Å”Z% w±´OO3ãÌúêw“£6ZbŸ™&Xºˆˆ¹A†`7.à92‘ó_fU9^.÷‘m‡vh'L¦ Ó<y4òhD·Ò­t«©³©³©sÒ¨¤QI£”@[MÔDÍÜá9Æ?ÎrI*FP¾È@…;vT骶pƒÜi8†ÓY(¸2c}ãäN•9n=n=N9ÊQŽ/Âá‹?âGü”‘,âÎø5<Çs<—o3b/±—ØKÜ#î÷ðõøz|=a¾0_˜¯Œdm˜Œo7¸Á £1£É²†¬ñŠðŠðŠ@AëMëMëÍļ‰yó¢ ª Šâ\>Æc<þ*Ç£† Ö:š²qÁC¤IFu¨8ÐúDì=]»ÉîzëWc‚µ ׎‹#:C/¡æ_ìöÊ–± lððð|6ølðÙ€<ȃ<´;íN»'nHܸAI:’KQåX;K’ù&2—Y–Xç9Tßâïc íJ›ÚjFªs¸f\uGê%UDkôG_ Àg&ûf‘ÛÔĽâ^q/M¡)4…çãùxéôNz§Œd©2Œ_ÃÜÁYñÀ2Ë2Ë2ËzËzËzKh.4š«««Ë7FÂH˜¼ÂóËÑ ÆŸ‰œ*C@@È[ò–¼¥14†ÆÈwi²4YšLý¨õÃHŒÄH\Â%\ú*G"‚" GÑyñ ÙB1>ŒÜšr©Ó첓y{Íz ²*/¼yþm}ù.m|y›ì"Ñ8%¶—:ÑšPA ¬áì$»ÝržzI”DI§t§t§tÛxÛxÛx¹CjÎîœÝ9»Sò¥äKɇ»¸‹»˜‚)˜¢8ýÌqÿ&à2º˜ó‹ÉYò€,¤nÒ)» Õn^µWðÁb|€•´BqdÆúÆÉ]œÚZl-¶¦ 4&ð£ùÑüh‡6*#™ª ã×ðOð;±;Ñ ½ÐK¬/ÖëÓ~´íWhQ¡E…ióióióQ‘ŠTTà Æ·Á.ìÂ.y3ãsÆçŒÏ´ mB›À ^ðâæps¸9d@`aÑW죬ÂÏç2Hˆ”@{Ã¥™¥R\¾‘ƒKÄùÖ·$d¯45BEbOî(u¹aA\‘ ¬±Ë.ãG8žðD0‚ìÚÚµµkk¡ˆPD(Â%r‰\âÇäÉ“¥R©` ‰Hd.û·—^ÏôÜü˜‹'‰d7²èTúÜf¦•*CgTÖC MP”‰B~óÈ%Dk¨5Ô*ý ý ýÀy#oÌoÌoÌÿS?Ëqgü>ã3>“Id™$/ïÊÍ·¥cÒ1éÙF¶‘mœçÀ9(õ²`ƒÁø6ø€ø tr(m)m)mŒ‚QµPäž~6emÊÚ”E6²‘îèŽîð1ØA5qÂ-Œ’è`¨ßªunŽzÝæmÄm©ºe˜´DÕЮŠfÉ^Û3‰ÏFßÜú,2q8W’ìÃzú`Œkÿ;° °D 6@  p[í¶Úm5Í¢Y4ËxÐxÐxð³÷gïÏފ挬Öe†ù/,¥e|¸ôãXk>¢%éØ[i!ýb{Xí¦úA;\èÃÇÀ MHa2c}ãÈ-–tÝEwi h h `#6b£¬é®Œ4À3ãW‹XÄÊ7fS)Èd 4yyy%ÉArP–qS‘ŠTf0ãÁLJdžò(òé“Ò'¥O"SÉT2•ÿÀà?èÖëÖëÖ+}U›¢)šþaŸ.g£gÂ3Þ‘]èJÓ÷hÔaÍŠ…f…f‡Vðl‹)bIisæåŒ¥Æ»³¼·N¾¹Ãâg"u$Ùä‚fC‹X»h”5L3Ì0»r=äzH§Ö©ujÒô#ýR¢S¢S¢ g g g° Û° ƒ1ƒÙeøíÁ¥©Œ)f79wº“zÙUÍà÷j ¶üåú¯‹üðbÆúÆ‘cÚ™v¦ß¶}ÛömÛO¾Ÿ|?ù&Ož8\ù ¯ðŠŒñk •¨rÛ{\ðqÁǯ8^q¼âxmëµ­×¶———*˸«±«™ÅŒo9Ä31Q?È•9*svc7v )BŠb[ж mAy IGÒñë–*'†Äa%Ú æà¤S¤]YMöˆM1åJí¡‘†c–L¾š>]»ÃÙYÏ»^{ö¨Ü§×‚ïHΊW¥Ùtðy¬]jÈ«‘‹±‹‰žè‰>ORž¤½Oï[ZZ&e'e'e+ðòÃ’¼âÁøæà¾1œ5ž‚DìÉmq&¥z[Õsa¶§0—ŸªŒª‰`âÉŒõ“+ÞIÇÐ1tÌó€çÏ_||ññÅס¯C_ÿÔ"GîÖÆ`ürkDȲr·Ô €ÕK0ß,VXaE)”B)Ù5ÏiœÓ8§±´IÚ$m"×ÉurÝf¿Í~›ýò<@]©+u•Å"×çæšs„LÞÊ á´ö¨ZßRÔÙ·Ž?ç\DrëJ²¢RÏjO2oH‹½9èòb€ø€ÆþëøÅ¿<Ö.5FaFÉÁ5çQΣœGÙž³=g{NÖãÊzžõ<ëyjXjXj˜Üè ‘ˆD$üVá¾lËišŽ8“ûÒDzôcUÛùJšî|®ƒ2ª&áÁŒõ“ûGn;Ø‘¦¤)iJ†!d)FŠ‘b?]5PD„ñ=»(êE®¿·x‹·ŠTƒÁøVûr ‡€€úúúäXr,9¹Uœ*£î¯î¯î=؃=¨ƒ:¨óû?—›JI€ØH,)µ÷‹ð0Ùë7½ùâ#$³á“y>Ô^¥­¹xáÞ~wf<_÷~Rš#É&GЋ>AFýÞ<ȃ”Œ%Û`²'.êëüŽ±Ù«^MNkš5ÎÔ**jD9Ìþ61j9^.—ò§#éÎÎÎ6?Úühó#º  º¤WJ¯”^)ómæÛÌ·X‡uX÷»RŒÿ(8$?©¨µŒØZ:Î×&*² ·¨Þ¥­AÿS3”&tvÂZæ¸3Œo†\½ d‚®£ëè::N ”ö%rôË#ŒÌ` Æod&fb&|àŸ¬ñYã³Æ›¯š¯š¯ÒdšL“í2ì2ì2„ÍÂfa³2^n!ôkEwb"êJÁt5-ŒÊð€Susø]]q}˜úš0Kõ”opGû þ§M‡ _½úº#™Lòb;òÐFX -Ô ý ¢í¹Åïáîá:®ãºw˜w˜wfc6fÓtšNÓ„!A écúX @¼Á¼aÚ÷g:(ÚJA9/­¥E\g¢%ûšˆN“t+4òOˆ£m°Gaõ¿¢S ƒñOGV˜èèè„t éÒ)¤hHÑ¢®C]‡ºUn¥r)ƒñÛx‰—x‰6hƒ6RŽ”#åËËË  HàÇðcø1úúúÊx9Qä?#§³Y!B"¾äÆÐštªÕª^F°£ñå¨÷!c­33Û¯J“‰=Ù:9bC÷Ø×Ùe-787òI &Db.Œ0Ãú·°’kßýØ£8Š£Ž :.´u±u±u‘ËO³Wf¯Ì^ùùåç—Ÿ_Â.pÁŒÀ¦ööýÀûXûHÃrªZZZðóH ¼¤7Ôßéˆ~–vmµ8ÆwƒñM1 Ã0LÞԯЯЯž<5xjpXpXp˜K´K´K´ü.9MN“ÓÌ` ÆoD~–ePœà§ôNéÒ;¡1£1§å´œÖá¸Ãq‡ãŠô¡¬GþŸ«M4Pƒ—ËXI4BQ2œT¾‰ Ûo,3óÐË…á6ñšçl¯~Í|rùý«<üXn#+æH{é>H +m+¹q’ì‚AqoìÞØ½±ê”ê”ê”lŒDÛDÛD[i°4XŒh€HB’˜N×÷gÌcuå¶¼'sA¤&ùÐZÔqœî•† !ý‡4Ø@ýª¼ ãY±;°Cya°GØc¼`¼`¼`.e.e.…8€ÊíP„‘™ÁøÈ±då´ÏiŸÓ^I%ƒ1Ã.«ï Îàc©emÕÒôØZn „†Ú¢‘ýDM¨ÊLŠ“r< T,âþ?‘ûiÞÞðF/ôB/ôFoôFY”EÙŸÎËNc0þDdÇ]vDˆ5Ã5Ã5Ãå|Zù´òiåsÌ|(GÜUTT´>Z­Nã4N£9š£ùÏö ßSÕP''0›Ô•ŽÐšµê”éP¤hd¨Ÿg¨¥ƒ1ËR'£núcÏ Öf_½€—؉d ÉC¶( –þ>.»ì'ØÂ¶ŠûtLÇtO“§ÉÓDm¨ µ‹‹ÅÅÉ­’[%·B)”B)TDETÄs<ÇsvY}op†Ý–çV)»–¹Ÿù!tdŽ.ð¥1ökÔíUc¸’D¶(—·žEÜÿGr/ó}À|À2,Ã2Å ¸‚+¸¢¼Ë²ÓŒ?Ùq‡wx‡fh†fÚFÚFÚFô=}Oß[3¬Ö ÌÃ<ÌSb„¹…# Æoã^ᢅ(©‹ÔEê’µ0kaÖB9åCÓIÓIÓI¿C¿C¿CvdÉP2” ýÙl … ‹ÑQ4ŽzÐq6¯´×U='Mé˜?Ò*-Ͼg¾®úlÿ@›µ±ÑÑÎ?êÿ>Õ‡ÏÇ­"éÒAZ•JÈñoRŠ*#û 0äyƉwâx»vì:À~ðËÌÌü¼ùóæÏ›ÑÐaCë8ñ}"–ÆÖÀÌÍ&Ë.€›K"¤ÑÖ¼´³ýµ$ìát$+Dè þŸð…/|e瀫ÈUä*ª‡«‡«‡ËBWV£Õh5Z+Y+Y+)?»¸‹»ÿà難z¥´èÛÎ –Ϭ œáL¬DOô(ˆ2(ƒ˜aæb¸v\;\ÀMÜÄrÌÆlxÃ>0 9ÿfoR®¿Ü±<¡ÿÒCüú/å€þgûÿçwÿóç~#3²µÉ]r—ÜÕš´&­I–ƒ4æsŒ9rë冚[8’Á`ü6>á>#1#u¦ÎÔ9çrÎåœË´mE[©¶¨¶¨¶Øœ´9is2%+%+%KÎí–‹Ya‚dÁ ß{FD“$Ð>C½Zå+ñ2ð‡À9.*ÚÝ8ÄÚ"õcâ›ÌˆE…öÔ¸S€Ô!À0šE{ÑA8ކCF Èîø8ŒÃ8Ï2že<Ëp¸ \¬À ¬HP'¨Ô´m@(Qù½Ø‹½ì‚ú>pê¤é™}LæúçFÚÓPZ½í êÆüf.‚|"M•±Zqÿ¹Û¸-»éŽqŽqŽq%[•lU²º¡º½®öºÚëjÏÉsòœª¤*©JïÒ»ôŸì¸çäúû¶‘c±s+35SêHWÒ•dbckt1º "J P…ñïñþ7~–üà÷3‡^v»å‡¹D‰æú“Ë¿ò"/ò*Ý s»ér&e0‚¬4ÊýÀ ôÌõ'ïS~]nÁÝ ÑPi¬-Ö?ñ!M¶ ål8ÎF}S}S}ð G G GP…Q˜Å´Œ? 3Ì0Óô½øÃ?{jöÔì©æ’æ’æ’I#i$%«{faÊ¡ÊÉêïrš W‰ì'ÔR-ZÚs¸ËJߎ»k(\V\k©'âWh„6 ï¬]uƳ²ïÞ}q'OHg,’ ІࠂXÿV! ¹Ò¦J¡”“““Ó§)NSè:…N±$[’-ɉ«W%®’{M(ë„rz-[«ÿ.`šÌQ†£&Oœåb¸eR-IGÚrBu~yŒÙ0¸€Ãß§³Ø?ƒ\M[h?Úö­¢U´r'¸Ü î"w‘»¨8Fp€Ã?ò;ÊQvÙYE,b¹J\%®¥±4Vq¾%TPAEL„ŠHêFÝ Ø\Vp™ºŠv¾v¾õ¢ôDzSújé«w|nn>?ŠEÎ+Ä’ÚHM¥¦ÈF6²•iWî¸[°E‘ôú¿¼Å[¼ý7¯¿ÿÿÜu•(€ò½z¯z¯z/ß–oË·µ†YìaâVq«¸Uù=<ˆ2&ë±ëe§Ó0È0È0Èn7‡«Õ‰êD»vvíìÚ …‹ÂEkŠ5Åš‚º¨‹º‡l„xºj Ыé°ð¥~Ë‚:ºt’Úeí2}ú J.œõ|i‹}9wy¢Æ ÄTÄU¥ÅÒßG¯]Æö°WîNp‚“kŠkŠkŠÖ¢µh-òÌŸô0éaÒCó>ó>ó> Ä@ ”cðÌeÿž`„ ¦ìË–lël€žAºqJÎ!l š êÝFµÕÏ0 õP!øqx ÷«È«ËD&2Él2›Ì¶t´t´tÌZŸµ>k=>â#>bæ`Î?ò+– %H z‘^¤=ƒ<ƒ<ƒ Ù²/doŒ‚Q „òS×ÉÜQáÖÌÛ -IKÒRHSÝQÝI«“3üÌpÛ±6161|¾ ßEê-õ–zËÑ\~?‚Áoå·ò[± «°JNƒ!-H ÒBè$t:OâI<嫈.¡Kèùu9NŒÝØÝòR‘ŠTUŒ*F£¸àgqg•µ“8‰“ª(U”*Ф“t’N¯Ð+ô ñ&ÞÄ›n èþ„?Âgò™|¦*B¡Šà§óÓùéÂá‚pA9BùZ•mõOD.hŸkŸkŸsá\8nll,Õ“êIõ”ÅèT¤"•M` Ɔ<Ó®Ã:¬“ËÄ3wgîÎÜ-”NJ'9Îs°miÛÒ¶eòªä Éù(n4&®–êRUéÈBó¬kw´vváN4ÉœfAT~ü‘©ë7ó×wvJ_o\ÉUâv“B´¾”…vʪ÷»Î+Ï{rEHɪ¨Šªr7SÒŒ4#Íh:M§érª²ØÜMÑ”„"t: U^*/•WðƒàÁhZ‡Ö‘3û“Þ&½MzK3i&ÍTæð'xÂòÿ¢{õ2 ¡e):ºó=KñSÛµ±œ˜èÑ¡tí#…ö)Å©$‡øüÛ\[Æ/!K@œÜÜÜkl¬±±ÆÆM„&B£Œ‘5+þ‰Èyùðäüù/òsKÕÜ€IDAT_T3®f\͸ü¡ùCó‡~K'3Ðh4J•6*íòî+;®ì¸ÞôŠáŠáñ(z|Õ‚RJ_ܤ”Ò—#(¥ô®9ýKú—“  j¿¨Ã7ÔõÕõÕõÿYß:dJÈ”)Õ«V¯Z½jÉS%O•<¥¯­¯­¯­tø›†i˜ö<òCŽj¨óÙå³ËgW£vÚ5jçë¯w¾ÞÊ˜š¨‰šr ›ÌŒ?9 €€Èé1ïT¼SñN´*Z­*¦-¦-¦•ò¹Gä´P—ïN®n]6vWÍ8škÚKZ|!g`ÔN+ž¶,$õ`ÆBä‡/œa¨×ʺ5—ÓZäÎGqGñÿ±wžQdÙÛnUwÓÝdEI 0!bÀ¨`ÎcÎ9acs¨ã˜sœsÎYEÁ$‡¦SÕ}?Ürßö?3»3»3»:S?¾EuÑ}úÖ­Sçžóœª¨Šª¿å46UmªÚTuststsôÞç½Ï{_Ù9eç”S5¯j^Õ¼:·ëÜ®s»Nã:ë4®ý²öËÚ/k†× ¯®¨ ¨ ¨ ­W{ÃÞr¿†qÏg|iZKÛ‰'iGÌÆ 4à;Ž$ßñ¦ö¦Zr=I_T'å)°S®P•Ág9BÖ6‚ñ~À¬q)MJ“ÒL¯—Ø;b'¥s|=XÆ×ãx¦."¶Û‹íÑMÐDã¤qÒ8uØÛao‡½-O·<Ýò´g1ÏbžÅ>Ú~lù±åÚ [ ¶<œÿýúï×+—ªÇ«Ç‹cÄ|1Ÿ{ÊepÍ‘Ç#×Þ]ej•©C‹ Y7d]•OÁGƒ.߸|ãòº>êú¨+‹Ðp…¸B\!Ñ,šE³4A3ñAK™È_³ÿ?—ƒdý5‰IË¿²mOx“,&‹ÉbÚ”6¥M9wÎsç/ðø Éí’Û%·ÓÕÕ%ÎÄ™8ÓÍt3Ýü[!cŸÚ#ŒV§¬NYâR¹T.U¿^¿^¿žEÉer™\þêÆ­ŒÌ_ƒxÄ#žÍ<úÆúÆúƦ»¦»¦»Ê:Ê:Ê:šLÍ'ÍÅ…3ßJ/D y5ž—YX$±ÅóúWJÍ7ÙäVÑS¼³rRV˜°®Ù5=¶C %©DÞ“™ôM§yÈî_®`[Î~,Õ}ÑC0CHsÒœ4§„JcñcIS4ES¶&i]ܺ¸uq»’v%íJÚØØh®i®i®©—¨—¨—¨÷©÷©÷qý¸~\?êI=©'ë‡ÊÒeÙ6Wž+Ï•7o6o6oWˆ+ĈCâ$]¹ UÀÿO•ihÜbN7¹ ›Ä ¼T‚‘$’hò£C õ|å<À5t@ ¼°;åŒO|VÂfÙŠ2” %C±K°Dì'öû1Ç T ÂW‘Va9M3!E¦„Sž+Ï•sÄ1‡ô&½Iïzcë­7¶³ogßξåK•/U¾”é•é•éÕ¡3‡Î:³¡ð†«®&~Jì›Ø^¿ü¯®¬=VõXÕV…Z½jõªûØîIÝ“B»…¦‡¦—<\òpÉÛøMü&~GÍ5wÔ4O6O6O&Èò®¡kèV¶õ?ü*†b(F÷Ò½t¯TÒúoð†Î£óèéŠÛbzŸ®ÅèðÓÿË np“Â",†ÍªŒØìÊRUY:ÊÜÿÿcQÞPÞPÞдѴѴQû¨}Ô>¶¥lKÙ–²}hûÐö¡µ›µ›µ›b‚b‚b§ãtœŽËår¹\bE¬ˆCÇÐ1Lš¾¤/éKó1ó1ó1CCC}°>X,¹òû±ûÅâq‡” ÏÄ ˜­ddüÃqÏq0¼1­7}Û‹QŠK\o´‚1Ac7Õª¾rã@Ú¡,ŠîɆ“‘²öY¦>L~ ?…]B—Ð%fYcÖHGZ¤ ýÏÐ@” q ·p‹{Æ=㞉ޢ·èÍfïR·JÝ*u«£ÐQè(DGG[e[e[eߟxâý‰›¯m¾¶ùÚéøÓñ§ãÙ)É82€ QÜkî5J ZH¶p€ƒh+ü$ü´'zׯøèø‘ñ#{UéU¥W•ºo꾩ûf(?”Ê—O*ŸT>i-·–[Ë=)ò¤È“"ìÌáG$mæ³úŸíijrÕ©˜Š©ì!‡¯ÈWä+ŠUŪbUs¼9Þ/)B°›ß·Ø–¨ ª  Ö` Ö(***&+&+&;;;ooo°é)zŠž’{¦~u°5æÊÌÇ|Ì'OÈ"åþÒ@0#1ò‹#e¾6ØlÜýÐK±KsSrSr?ºWt¯éÞÄJe¦ª/Ö&ËTc?¯ZγZèÊçŠ‡Š“Mu„’úz7SÕ9-¶5»å;ŒÂ®6É$³„,ÚœîÁ` Æ`VúI:¤íI{Òž…QeY—õs´´´lÙ²9¤}¨}¨}hÓÕ¦«MWõõõëDëDëD¥µÒZiMŸÐ'ô‰T¼î7¸ÑGô}„ld#[\ .˜¢LQ¦¨‚è‚è‚è\ß\ß\ß<«<«<+ÃjÃjÃê|u¾:_­¯¤¯¤¯$ýû¦hŠÏé”÷VYÛJæ¨(U¸zÆÕïÃ:u^ýð©kw*ÎhٳɬÈÈÄj’^ß$¹4õ÷ð×Îq/Š¢(*M‘€eJ”)Q¦AõÕT÷IõIõIý¹þ«°ø:[`;˜Ø¢v÷íîÛÝrgÈ!wN–:Yêd©øåñËã—~}øõá×=¢{D÷ˆ¶mEÛÏîò+¼Â+HI ´Ç¢çI) Ñ ¹QÜ(Nj٭خخØÞÞÔÞÔÞtäÑ‘GGÅ·ŒoßòpÜá¸Ãq­·~Üú1ÓäaÇs¹Î\gÉ™¶üD¬Ý‰…Æ| c c căˆÜÍîfw)i„Ø{òmv`ªù8pÚÚÚ5JÔ(Q£D­•µVÖZi×É®“]'éÈ;¸ƒ;ò4&#ó§Àf³›¸‰›lÛiÓ:§õa'Â&„•ç‹•\\Ò­Ä¥k±Ëæ·îOK]¯0ò¥W{³µç„ú ·²Ópä<©Ÿ° §ññàWÿ!%”P¥YiVš4‡ÂCá¡(Ý©t§Òª¼®òºÊë j,¨± vLí˜Ú1a%ÃJ†• W†+Õa/Ã^†½ Ë Ë Ë {ö0ìaÝBu Õ-T³vÍÚ5k‡˜BL!¦2æ2æ2f¯ë^×½®;z;z;z[•°*aU‚Ç¿ã½çÆz¬ÇzâE¼ˆ)NŠ“âÄ…¸—¿`™?TàÁå„ë »LFÁ$!“TÓù8x’'p²s¶ê£X ˜Š6ðCQl&೪ K™p \—@·Ò­t+u¥®ÔU:’ þw°L/aòˆ3È 2ƒé®°DåååˆúŽõë;vœÒqJÇ)¥*—ª\ª²þ‘þ‘þÑÞн¡{C·zmõÚê•´8iqÒb,Æb,æÞro¹·âFq£¸‘ÆÓxÿ«ñ÷L=‹³8Ëvð[ø-üú”>¥O͕̕̕pwq)HAÊŸþ~,%5'`&ð‡øCü!aŒ0Fà \¸4pi·kÝ®u»V'¹Nrdr\ âZĵˆk±>}}úúôKn—Ü.¹Ñ(E£È ò‚¼`å‰b€ H}OÙôúkKð–EŸD<(2%n&7“›ù¤ï“¾OúŽ8nà¸m굩צ^'ÛN¶l#F<°1`cÀÆ5ÇÖ[sìPä¡ÈC‘ì”\—Çå‰>¢è#uZýcÝwÝ×A9NŽ“ã¼ïÃûˆÅÄbb1a°NX'}ÄWô}ÅòS¿­aËšU1{*k*k*k*³•ÙÊìüwùïòß1÷]ÒŽ¸‚+¸"_è_Ý7˜HI"+tÚé´ÓigÙ^e{•íÅMæ&s“ï¹?æþ˜üáùÃó‡“BB¤›•ì}ÇqG>²‘m|hXj¨“R<å‡4êZ¤°ÓË.µ«5·Ë õùùä­«Ö{EÞfáþ«ç‰:d{jFi6«ÏÛt²±µI²Uص«¡]«]§]§]©]©]©Z®Z®Z®z z zÀÍàfp3躃îúZ,Æb,‰‡ÄC¢“è$:‰GÅ£âQÝZÝZÝÚ¼y+òVäøæøæøæÇçÇçÇë7ê7ê7JÎÃ<Ì“ö°õgÖýƒ…?²‘lIŠ7 IH¢¯ékúúWðäñ)óP`"ê |îé‚jl$ €z8Kvd VÚ,V®àG³È"鎲(ŠòÀ’ù–½E™ë̦žÿŽ&½¥ÛÚ=Ѓ8â@§Óét:K w»ìvÙírç~ûuîU:ªtTi—x—x—øWý^õ{ÕoÏÖ=[÷lݶ#lG˜¾³¾³¾3º¢+º’ä9A}¨õ‘â¯ìtŒß2½ZvŠeVš†i˜&Dƒh`z½Þ‡¥2Æ/Œ_¿°oǾûv¬Ú«j¯ª½ÆÇŽd2™Wl]±uÅÖ6m>Úö¤=i«¸Š«4‡æÐ)Ïò?wMØÃûbˆqâÖqë¸uTKµT+Öë‹õqGpä›lKÄìÃÚ*]ÄE\TÖUÖUÖUVWVWV7w5w5w¦ Ó…éhŽæh.§Ê|ÕXŒsÒ‡ô!}òKä—È/á4Ôi¨ÓÐ÷Ü{î=GÒƒô Z¢%Zb/öb¯ì¾uœÂ)œ"ç9{ÎÞ\G(+Lw0‰÷XÞòEë³µ®:.3ÀéBžšöàÒ*dTÊ\xªg¼ÞöÀ”ò]‚œWØÙi§ƒ#»¸@ÎÀ½ãrÈ2²Œ,“Ú^Ã5\#EHR„¦ƒé`}”>Jelmlmlmèkèk蛳*gUΪÜ{¹÷rïåË+–W̰ааð‹EËsZh¡•RYR‚º”.¥K±‹°ˆEèå1&óg£ Cq óM…¥a(a^"|!d+šA_mROyWøÁ즧pEà[|@reóý­±tL™SË"”>ðj¢&jJ*ïlf6sÖ-d I:I'ét@'ÐÙt6­òQù¨|Ýlt³ÑÍïr¿Ëý.7 ) ) )÷yîóÜç±?Æþûã6Ý6Ý6Ý ò‚¼ÞùH>’ô =CÏдmð‡©¦°wË"ô*¨ ’ ‘ˆDò”<%OãÇ5Žk<KT@ª§zª'ûÉ~²¿ ¢ ¢ bVaî̺3ëά¾íû¶ïÛ>¸Vp­àZ?,ùaÉK‚}ƒ}ƒ}—[>nù¸ŒâÅ3Š“\’Kréz„‘òzÙ*Á?×zÿ9LɘYæGîGîGn$7’)ŽÇ‹ã¥F2’‘üX&Ú-Ђ© ©ß©ß©ß Ë…åÂr}¾@_ b2½ kÈ|E0ÅØÀ&]þºüu,­ RA¥‚J¥³Kg—ÎöÜè¹Ñs£Þ¨7êïTïTïTl‰– %h <Ã3<“ ù‘DwÐUGô*x›žŸPÐJ¬)UÅÌ· 7ùÚ|«¹V¥Ä&Åèv1IøPпÀGßß0Q?HŸ˜S<Ç;§D^í¼Úyµ³dÈ`p28œÌuÍuÍuŹâ\qîÿ‹Í½p$u¬]Ø…]’kÎÆ ²0M÷oQ;Kæ¯ ¹ŽìaÛ§KõìÛh¥Ó»¿§ÆéW{4½S|@·f¹šÕVíU¥ãƒq Ëe»ý&þÚª2}ãÈr…\)—^.½\zXbXbX¢Û^·½n{¥#YkëË\ÀXÄ"–«ÅÕâjYâUÙ«²Wå‰e'–XöÒÊK+/­Œ[·"nÅÞ¨½Q{£:¼éð¦ÃÕnÕn•TÌÄ U9GΑsüòbø“5[~Ëg¤  œçƹ±Ú3Ú3Ú3N 81àĹá熟W#®F\­Y[³¶fÕÕÕÕÕÕYžŒëÀuà:°Ä¡_8ÿ?gF@êA¨Ü®Ü®Üü)øSð§:‹ê,ª³Èa‘Ã"‡EÒ‘‡q‡¿±[ ÕPMúª’£äh¹ýåö—Û~ ü@øbßû¾Ø÷Ò‘pás¡›ÌW+ gÀ ãÈ82Žíðœé9ÓsfØÍ°›a7k5©Õ¤V—.5\>—t¯Ã:¬û (™ÿp…¿IY\Ù‘í—ñÓäåÙÏ)¥ôJ}}CÃÄ”Rº^{ùäå£v±6ílÚXŸ±Ùe³[RgÿçÁ!Á$˜KkÂ]Ð]¤"Ti:G‚Ì·Ä‹Ý9õß™{¤" €’.¤MÔÏ•¥‹m}«"ªù*oä0 P ßXãv™?¦ÈË–¡à'Gq—þú{§Ev<»=롇žÌ"³È,ÖB¼%Þo)s”9ÊœvëÚ­k·®•m+ÛV¶%J$”HHÛ˜¶1m㮥»–îZº~èú¡ë‡~(þ¡øéÈäz€ ÄL1SÌü¹ ÍÿÀz,¢Ãb䬘Õ_ôýÉ|2ŸÌ×…éÂta˱ËqC{C{C½ zAô‚²Ên(»aZæ´Ìi™ûìöÙí³[]fu™Õer¶ålËÙF–’¥d)½EoÑ[F0‚SÚåjÓTÉB²$%Öºh†aØWÑNë÷ÂÖˆ·›ÛÍíVf(3”âºúè꣫ % % %™ÄI"I$Iì'öû±ÆIÒ{þï(Þü'°²'f™0„!Œ)ºpVœg•³6gmÎÚÄ ·Ü~pûAÿ»ýïö¿[aV…YfÍ.2»Èì";õ;õ;õëϬ?³þL^X^X^YCÖ58ó8OE*Rñ‹n² ‹¬n¶:Á½áÞpoÄ®bW±«$$ Ih‚&h‚øˆo­pÓbqœÿÿÿA]E]E]Eˆâ„8ÖËP:òüz™¯I'8©œú â ¨5¢æq»Çí·SÝUÝUÝuxíðÚáµ_Œ_Œ_Ì£ÌG™2ÅÃâañ0»¾ØãñŸÒAæ×PAŽì"£PžÔ/K´òøÑ¾•{I×T«}8ƒ¡p\çÇŽo·>Ñ=OûpÄœ/ܧ?·P ? ca$ÈÈü à,Éž ¯iZ   ‹Þ(N‡¨§+.óµ-”~¼”C¢ |eÃÉ|Ar#•ô1mïR(…RÒ_ž*Ãö°È·-laK|‰/ñe™ÙÌe·UÚ*m•]§wÞuú’¡K†.Úbk‹­-¶êªéªéªí\¸sáÎ…k¬=°ö¾ýûöïÛop1¸\ÈUr•\E[´E[:‚Ž #XôZú¿ßÖäÎfçp瘔¤ôX²ƒì ;®¼rðÊÁk®¸fkþÖü­ù,úØÓ«§WO¯˜Ð˜Ð˜Ðбc+ÆÒ^´íE)¥”J¢iÌe·HÑù"êGq ° H8 'ád<OÆKýíyó_ï™?ÇŸãÏq¡\(*ŒÆ ã   ¤#ã1Ë—õ7sµÙfMãG`Fb ±†Ø„؄؄X]Q]Q]Q·T·T·Ô’}Jö)Ù‡éj£;º£; 7È.û/…“XG\Eñ/‘]¥Yé§E=0ž(c”> ñ¯†fœ3ÿ ¼§Í”a ;n x„`‚$A,#ó·ä‹ˆ{¦}ÁÃc5%Ö¢Þè¡î¯8Ém¶î®\¡X 4£$Nɶ{X¼ÀJƒƒƒiM£iæAæAæA˜Š©˜úE« “qlL“Æ,—iѰÛg=C=C=C—ä.É]’“““„vB;¡Ýiñ´xZÜ¢Û¢Û¢»“r'åN 6a6q˸eÜ2±£ØQìH©#u”\4æø2g½[–»\EPDêØÇ²·¿þH›e|C4DCA#h÷Ž{ǽËöÈöÈö`mønκ9ëæ¬ÞÖ½­{[W.W¹\åróÌ?2ÿÈî ÝA»ƒ6vÚØic'Ý Ý Ý r—Ü%wi  Rz’E±ÇÅqqÜ]î.wW\'®× g„3Âéý|ã²zÚpm¸6œéH˜\M®&WIùŸ·Ö’ùš±Œ¾/ÄB,doòŠäÉ+òdæ“™Of–YvfÙ™ƒ‡!?6?6?ö]Ëw-ßµÄ ¼À ÔAÔ‘¥þKx£0ìéN8`!â"j.רã2¬Äb˜P?o¼ñ@ÜÑ ™[0-PCì)®§£pøQ6žÌß™/÷›ºú±lñ‘v¢u蕞×pU4:e7^…@z¡,<¹1Éß‹Lqr’œ$'9{Ξ³§uhZGL“Ä$éHVBÄÜbG8‘Ïä3ùLa¯°W”g¼í¼í¼íº%uKê–TWý]õw©g©g©g=7<7<7lrÙä²ÉåXì±Øc±&O“§É“< ÈZŠ–¢¥DÑCôÔšÙmûç%˜,º\%Pâ‹ý–“_?,"ÎÞó)œÂ)é³›a†™l![È–óÝÎw;ßíᆇn´aІA–oX¾aù>{ûìí³7°]`»Àvk.¯¹¼æòÝJw+Ý­$™Ùó$=IOJ{Fd_‹¯Å×2kÍZ³VØ'ìö¡2*£ò©î‚å:Ë~fßò}ÜÇ}U„ª¾ª>YMÖ5¬ {üÂù“ù±¼–CŠP6ÿ¤Y§Y§Y?[ólͳ5~ù~ù~ù%^•xUâ•!À`øäóÉç“á¡ Ê Ì/´]“ùci†Pøà,îà¥ýk«*÷U9VÂâHø´±YÛó?^Ø—ÿö!öã š¨?}!ç²ËÈ|á¸gdêÜô®aCi#ŒAÇU¶ž«¨ÇÅ8ú¢Ü1CvÜÿöXÞ oã6n3Õ¦CBV“ÕäsÆðwøßWâJ\iÚv* …ŠNMš:5my«å­–·Z÷iݧu÷ãîÇݧ/O_ž¾|ÛÔmS·MÝòjË«-¯2GdŽÈOx“kÌ5æ‹åÄrb9éü?‹åKÛL—†e´ÿ€ðƒ“«“«“+ë³hŽ7Ç›ã³C²C²C¤N{,þëÇò¦ÅÜ P°Ý¼šWóê´niÝÒºý€ð®v¾ÚùjçžzvêÙ)ôNèÐ;«V¬Þ4|ÓðMÃw(v(v(ôåôåôå¸ÕÜjnµ¸[Ü-î¦-h Ú‚î§ûé~tDGt$oÈò9É\á?¦ÃÄFýà? ABˆñ ð…/|¥V_l•€Õ°ãéHG:2 ä!y¬a YB–%´<-OË+w)ß)ßñãùiü´ÜÀ\E®‚è.ÉicœÌ·‹£³ñ3³1û]¯w½ÞõÒæjsµ¹ž=;zvôwðwðw0‚ A9erÊä”aéa’4ªì&þðà@H7₃tuC±š/*Ü-¾Ý±±MKÕzsÉú÷oÒüóŸ¼ÿ1%ÓHÖ ì¢½èÔ“'#ó…Ž{õvžG ÇÒ[3œ{\Í`èt”æèû¼OdåeþRdN©åVlÙn¿‰¿¶Ž{'tB'¶©ê©ê©êʇò¡|íKµ/Õ¾¤y¤y¤yDj¤é@:–/ÌÌÌݬجج¸u?ê~Ôõ*׫\¯2?u~êüÔòNåÊ;}1J_ä…”“Êø-r„L¾žÃçð9õÖÔ[SoMÃZ k5¬U}põÁÕKGŽÅØÿSêô]Æ –6añrKYâE#ŠFLÞ7yßä}×]¯»^w½m¼m¼m\üjñ«Å¯úô ègyJû0û0û°:‰uë$V«‰ÕDÅEÅEÅEéϬ¤ïçïÁ“&`&@td:™N¦s¾œ/çË är¹d.™KæÛóíùöü^~/¿—Ïæ³ùl®×놭؊­†©k:6rlT¥G°{°{Í’5vר]1¦‚w.-º%Q%±û°OžÀ¾y,éÛ¢-Ú2 o6Ò*”«P®B¹ˆ#~Œø±j骥«–VWVWVW–Žß‰Øù c[æ‚æ¶“mpLõîµ·¶¥—u#ÊÒþW‡w^Þ{dû†%ÐP†œ'-q8ù[‘–BZv^žN‹Ê¨Ž’t1Rp *„à½Í«™Ê8¸G»âGlÆ^ØÁ)ÈA¾lÄ_…ÅiؤÏòªYÖ5ËÀö†7¼¥ÜbÆ·ݱhƒBjÖ¤5בÉD;tC7âM¼‰7½B¯PÖôâJÉ~%û•ì×CÑCÑCQ·gÝžu{jêhêhê<ˆzõ jó–Í[6o9›y6ól¦9ÜaÎ ·È-r‹&К@}¨õùÂYÿ-KØ¥Q¥‘ˆD$ªýÔ~j?S¢)Ñ”(Рť¬zS+ÿÖG³ ]HÒ…¬õW™«ÌU~êý©÷§¦ÄL‰™s;âvÄíˆ>¡}Bû„† 6Ì¿’жèmC¶ Ùî°½Èö"^ú4}šê’Õz«õFS¸)œ¤s±\,çÀ5æÓMtG"IÒÕPUÐíÑÕQÕ‰±"VB3¡™ÐŒpŠÿÿƒ-~Û±ýÿtbÞ€ Ø@z’ž¤§Ò 4( VqVqVq|o¾7ß[Ñ_Ñ_Ñ_¹P¹P¹ëÍõæz;Ìt˜é0ӯ߯߯ßõ•ë+×W…¶ÚZh«mcÛÆ¶m·Øn±Ýb{ÝÎÅÎÅÑ×ÞÙÞÙ{EÃÍ 7c‚ª™ªW„L%S¿iQ¯E½÷Oß~?˜\&OÈ9ÌúÍcY´Êñññ‚½`/Ø?‰|ù$ÒêºÕu«ëvz;½ÞŸ÷çýù‡îݺ ÷„{Â=©Ôõ â }ÿè‹Êð¦S°û°¾ø®R‹’£>"YaG–b¹Ð€^;TíòЧsq®(ŽŽˆ„ Q¶¼Œ  @2 >gO.b¦à/$Ð(>‰äoPQGo9fj{ªÂw°[üŽò´^¡8Üq åÆÑÿ l`#Mô÷¡‚ŠïÎx¡Üî ²È ²‚{Fj“Ú€!=ò÷E_À¯Òž|G¾£¯iM…EÂ"á®"¤p‰áˆÎV·C·ÃAmÔþh‡÷vlØúTëM­79ouÞã¼'U“ªIÕ¬Z´>h[ü¶ømñ¹×s¯ç^g1r.†‹ábÄAâ qnànü¦æA?§:ª£:kË¢¹¨¹¨¹¨­­m\k\k\ûá퇷Þb=Öc=r‘‹Ü¿È¨³LÊF6²ÅÛâmñ6¹L.“ËÌ¡?²õÈÖ#[=|ôðÑÃÞÍz7ëÝ,|døˆðÑâ§DO)QÖ¹¬slƒ­§¶žÊ^š68mpÁЂ*UL1ÆÕÆÏéOEq‡%æîáVb%V~ñN‚Œ`M &Ph;Ûv¶ílû`û`û`«EV‹¬Ù<²ydóÈú•õ+ëWV÷¬îYÝS™T&•ɹ±scçÆŽ¯_;¾¶q±q±q±½a{Ãö†ãyÇóŽçµAÚ mµ³µ³µ³µ¿µ¿µ¿ú´ú´ú´ê½ê½ê½$¸+±’9ý\ Ȳo™kŽà^˜Ï‡‡+†WWðíIÉ3¿SWó<ó<Œ)HGº<ýE°tµgb&fâ.î⮾’¾’¾Ò›'6Ol'NœìÒÁ¥ƒK‡CK -14qVâ¬ÄYRyý=Üýo½ û«€µ?»KO¢½Øƒîò\ä>Öql™q^ŸœÓà., ´Ó% Ÿâ›>™Ú·!€âÞ OvÚed ¼Dôìóô0mœï`*ÜR? öd=@»ˆñM_uä!F:Žz£B‘ÙqÿUXlæ ®ã: ÐâTqjnç¬Yu|vRvDºž®A×Óõßð'õ„ü¬ïØ ¶‚õ[?[?±ÕQ]ëem_µ}Õ$¼±ucëòåÅ@1?R—ªK=RùHå#•×{­÷Zïõ´ëÓ®O»Jcnåz^£Åh1ú‹ÛíïuÙQˆB‹±Y§Z§Z§*f+f+f'Nœ<øµûk÷ן•æïàÎ_²jƒ­ð°|( ¥¡è†nèÆÙr¶œí«²¯Ê¾*;qÌÄ1ÇÜzxëÍ­7=«öìÞ³{ã§Mú5ébÕ±LÇ2‹¤O-.ÌŽ ÇM5òöäí9ê¶iò¦ÉY+Þœ{sÎ%½†{ mˆfŸfŸc)ÇRŽ¥´Í´Í´Í´iÚ4mš6_›¯Í×(4 º‰uë&Ö‰Ö‰Ö‰V~V~V~ÚkÚkÚkš M&H½]½]½]Õ\Õ\Õœ„’Pj®d®d®dîdîdîdždždždªaªaªazjzjzjÖ™uf9ÙœlNÎÍËÍËÍ3©L*“ª ZAµ‚jú(}”>*kHÖ¬!Y'²NdÐÖÖÎ,”Y4³¨kN2'µõ˜rrÊIë'öZ{-€×x­˜§ðPxH«níÐeþz33Ó’:„C8”Ý$»Iv“¤#IG’Ž”~\úqéÇû=ö{ì/8Zp´à蛨7Qo¢$ª6hƒ6Rýƒ,ùïAAAI7Ï"”AHéV^»œÆzüäšeÛÀV<½7óYjÆÌ¬vù•Œ0C„Ãè ÜPE6 Œ  Àsä|n¿bž-V Oòö›ê ¶Ú0«Bü)@D/;Ô׬¶JÆ#‘ô;ºöCtAcÙ|¿ KŒYƒ—xIÚ‘v¤]ÕF5ÛÕlWrU`©ÀR¦!b::²rdåİ{¥ï•ΠóÓùaB´̿þHDÒ–´߈œÈM½£ÍŽ6Eí‹Y³6TJ ¥5ë­<­<ù€”B)…nxïk¿¯ý†¶¹ls¹\ôÒäK“Ù¸Š\E®¢¸IÜ$n¢4J‘õÿ|1š%Õ0 L0ir49šþ‰¿d¸c¸c¸Clˆ ±¡[éVºõ[±ù¿‰¥“± Û°M4ŠFÑH¶‘md›ØDl"6Ùo»ßv¿mü½<ì÷x j *Âv¸Ûp7—¢E=Æn˜ÊÚPæqÑîE» ·S¤PÌÓLÖLVDñíùöŠñŠñŠñŠÇŠÇŠÇŠ@E "J(Ñóz^Ϭ)XS°F_M_M_-ÿRþ¥üKŸ}zôéQA±‚bÅr/ä^ȽPð}Á÷ßç¿Ì™ÿR÷D÷D÷¤àfÁÍ‚›ºººY‘Y‘Y‘Y§²NeÊ»žw=ïz®_®_®_ÊŠ”)+2‚3‚3‚OÁSð¤èºA̳ÅlÔDMÔ´4†s¬ó3çgIGžÇ?WìV(Š‚ú³ú³ŸBR´)Z6fhWE£0c0FžÌþRXª  "%H R"õ|êùÔóV)V)V)~=ýzúõô=ä{È÷þŒþŒþLj@j@j€Ô¤éçÕ2¿;XCMZ ™¸‹«xåYxªíE¢Íe=¢³h×swG¾ž›wG'r1ä1^Чh4ÂaÙ|22sܳ?ç©›æŠùty1M47sÿIsY‘€%Ô“fØ®´«ŒWôåöq:s¼ À.Ÿ[£Ëü„$sùᴇX Ï-uµÔÕ‘OfV›Y-‡UÆ'åFæFòÓ_”|Q’»¢õÓúa¥ØFlóÍ8‘hˆ†P ~‚_Á›âÍ‹7/ó÷ùûŠ–\#®‘: éHßþfÏê=«c<ÇE‹Î*šó&ç ¾Ç÷øžt%]IWq€8@€@"PRù÷"ë?‡e·G"‘hh¡éªéªéJŸÓçôy¦@S ¡³él:›5¢™4“fþ-F¦E¹}A_Ð|<Ïdz@ó;ß÷µß×N;œÖ$­‰é'£ƒÑ¡`®â*]$†‰a\ ¼ÄËßõx×#½ñÓ6OÛèCÍ/Í/³eoÍÞšÝ>»}vû¬Y²d„g„g„ç…ç…ç…Ü n7ýýý¶ç›ç›çk¸a¸a¸QRR’³3ggÎ΂ׯ ^ÿ›RŒ¬’â×(†b(FPwRwRwò<îyÜó¸ßQ¿£~GíŒíŒí²Â²Â²ÂpWqUJÓù½¬ÇD43!‹vPð±¼¶æíòB±æ¸cn'¬G:‰¬{äôriÚC”EqØp„ÛÎU —Äo­O³ŒÌŸ†IHÿœÝkj*»æU0¾0/ ¤-‰‚ zÐKNm5Ï­¬Ugßó—Í¥AQîp–Í÷/ÐH…§(@IÔC=Ò(P( --«LV™ÄŸ®Å^‹åz«‹¨‹ ƒž¤'éSú”>ýú?iB¶’­tØRlé×Þ½­{[õ»mvÛŒK׌×Ô?Y9Y9Å=»—x/1‹æ¼Éy£r±jnÕܸаа.  èI¨‘aÙ%ô?‡•”ÍÀ ÌPµRµRµR-V-V-61ý.ý.ý.ößéizšž–ä ÿª‹=ôÐK2yñˆG¼P]¨.T/õºT~©üè5Cã‡Æ‡­žY=Óæ½ª¡ª¡Ù Äpo“¬W­º\ñ°ûawô IgÃ÷úd}²ðPx(<”ä›±›áýXt`}^¥íé˜Žé¬Ø”|O¾'ß³œu–@Å\+,Çr,§{èº;°;XGX°îS¬È˜=…°OÊZ)Úœ¶ -¤,gR’”„Žã¸f°f¨f(Þb:¦£Z¢%ë6€Ldâïñ8÷÷„]ÏñÏqGp„5lz~ôùÑçGÕ+Ô+Ô+ÜÛº·uoë·Ío›ß¶û)÷SªªK]#–a–ÉE«¿ÃäÛÉ$4¢»©]úØ.µšZ­z™ÛEv ’¸Ml•¦HO5Œ~,¼Ñf­A&Þ O¬HwÓŽ X)ÛWFæ3a8ÓêÐú«’UåÎ{÷Ù߬05N{Ø}8¥SíºEÞ6tQët‡ÚRêÖÒåç‡M˜,ïW)Žâ(ŽÕ  ¤©Ejµ­ßYßY¿¤SìÙØ³KîÇšcÍ#SfT™Q…·±ûf9™ªJU½ô§”Òx¥”>®E)¥›®Ÿ0ž0ºn+VHZ\&9$‡äH/cQö?ƒk¸†kìü¶:[­®Vt­èZÑÕ+W¯\½²¦¥¦¥¦¥tä ¬ÀŠ¿ì8´Ôá©Ú¨ÍÍãæqó¤=&˜`j=ºõè֣誎ªÔ¸ÿéþ§mc¶OÝ>õûË_,±øÔN_µ¡Þ†zã­X/°ööMöMþ…ÿå _ø’N¤éÄ}à>pøCü!þßïÆwã ñ…øBÜ%îw‰kÂ5áš#1#YGÖ‘uDETD%}L].¨ Ÿ…ôªW ¯^5"†D ‰âÆÿŒÿ现6° ì`;yû[`¹ÂsGq…P…¬[ ¶<%xJð”ˆ-"ZT̪˜U1‹µ$c=%Ð}ÐçÎ#ó+=$ç` 5¥ç{Íu¾&Œ¿à6LIS®Oéz©ö²ß)9E¬b0YM±Çð#Év“‘±D¤" bl'V“³# ÆFPpfâ*4]slʪf+•Ã9?rÀcì†aóMm™ÿ ë+™‡É˜Lch ¹xõdÓ“MßL~üðñÜÓ9Ž9ޝ>¾vxí X«î¨î(ú..¢ ª¢ª¤£òÕCv’óäzüÿLŒP›j㫯p0ðZàµÒEü’ü’öZᄎûêýÊ÷Ý_4ÀüèùÑZ•V¥U! H`ùåÒ‹îÆý{¨¡†šXkbÍ„5‹E‹(¹7roäÞ2¦2¦2R=QQü¦FNß –ñikXÚÌ%sÉ\ Á a»«¾ªúªê«­ý·ößÚ?îD܉¸g¶žÙzfk¿ýnö»©UWUWeG¹[4¹hrT¹F-µÊ vvV¤+(ÝÄL>'59  }3ö±ˆ¸»Þp½áz#|UøªðUªW¨^ásò£Ð7õ¹dþ(,×-Ä;w<^»ríʵ+‡{…{…{yóç=Nºìì‰=±—ë"~Óõ– ÂC¶½7oFj‹"4ájèGyáæ°ÈžÍ›TúPU¹‰$D@ …¼Ž!#ó%à#Ò‰a°Gºš¶É¾ª?kp3HYáGšMÚœTnãs­Èeâ)½Î¶ÐÈæû¤à=Þ3W’kÇ©9µ¹Š)Â!6Ú mñ ¯ðê­g(è7æD:¢0 ³Mk{ëµÖk5^6µmj;Î)T¨P¡„I~I~“ëL¹5åÖ;ëw›Þm »rìʱ+¹ÍÜfn3  4‹°‹¤|÷ÿ8~püàø:âuÄën7·›Ûíêêêhíhíh-¸ÅXŒý"ýF†Âí#­ÉK´ÂD.{Ï猛ҹ¿] MhÞŒüT^g÷áé'ÿœ(€¢±dãÉÈüÒ%uoÌÍ#éä* ÈG^æpÝ“‚e—@ÆŠ h;:Ÿ¨¸-xâTM»Zó¹ŒÏ yJ’ù?°UT@±®XW¬K‘GäÑõi×§]Ÿ6çÅœs^äÎ;wú»ßÕø®F×n]»uí&‰Ç¸þ\®?&b"&J7Î/úÎnŸm[Ú¶´mÜ=îwOÜ*n·ÒV´mÅNL£h‚œàDŽ’£äÛȱp¤ÌÏÍÏÍÏY^¾ÂKá¥ð"mHÒæçGÊüMaÄÏð Ϥ®ÀÃ1Ã_L|1ñÅÄÔw©ïRßY·o5>`CÀ†€ šbšbšb˜ŒÉ˜,å»[jÆÿ!‚rã¸§Ä ¡ðƒ6ôY¹NEfÚ^h=‡¡°½˜ò -9Y¬MR¬Á”A*²a‡¡ŒÌÏáðYÈ% ˜þ9û3·áª©€d(© iÈÁU¼q6ÛÔÕT–^'Ë2Éüv£bNO,bË´Ò¹¡ÜPnè‰â'ŠŸ(¾‹±ÂkáµðºWá^…{n³»Íî6»Å5âq S#‘Zœü{Ñw¶¦!@€ |ª|ª|ª6©Mj“y¼y¼y|AjAjAªtÎ븎ëßÜõÊ“,ÃRb¶qÛ¸mb¬+Æj·i·i· ¯2¼Êð*“·OÞ>y{ÑáE‡~eÚ•iW¦ Ë–9,s_Ó}M÷5EÒF “¤°XQ¬(V”V2 ö¯kkk±[±ÕÜÚÜÚÜú›Ÿlí‹ ÕTšJS…±ÂXa,™Ef‘YÜ&n·I:R.N•±Œš³Bvg8ÙV¢•h¥Ä•‰+WfuËê–ÕÍ&Õ&Õ&µ´GiÒÊÃÊÃÊè†j¨†–h‰–rô Qeh1Z†â2’  ¼æç8KTÍ87„p«¹’§‡ÞÚ÷ÒÛq “¹FÜIÂá>ž"E†22?‡“އá<±]ú®Bñ2Ä"bÙOv‘>°C&tÎ)ÚXÍVÙd2ÿæ¾ÛÃöLÉ[ÌsÄÒ–´%m÷…ï ß¾þÆúëo(÷)÷)÷ .3¸Ìà2 ß5|×ð¸V\+®å|9_ÎíÑíwÔÊâHí'í'í'î=÷ž{ÏšÞ›ûšûšûJçLG:Ò¿{ZÞòEˆÉ82ŽŒÃÌÁ1L ÃÛ¶ l»Ä‰ÿÿŽ©S;¦òeù²|Ùæææè9Ñs¢ç$îNܸ›;ÇãΡ?ú£?ýH?ÒRY0û/L†r·ˆ[DÏÓóô¼ÐWè+ôýæGfò'²‡ØCìancncnCf’™d¦òòòt$û“‘± F|ïñ=&`&www$ÔM¨›P7ß&ß&߯qãÇþsýçúÏ%åH9RµP µPõQÿo¤òn9_…¢¼¹ŽÜRN4Ò%´“ÓûÖ©åû”X^ø(n™Ì²³²f_>«úÞ-Ë‘O   tÐÿ£Ë‡ŒŒŒœ4¡ìÀK|b»tžæ±œ„ªb(·†lÇ€¾G¦SSí9µÜtXæ·ÁâL,Wx/öb/àpݸn\·ÕuV×Y]gûÖí[·oÕ–Ò–Ò–õrÔËQ/Cφž =+®W‰«¸~\?®Üà·ßµ²•ÔvÑvÑv!»È.²«`_Á¾‚}¬QÒêþc[>ý0ë±+´<Ê£ Ëá{Í)Õ=Ùd2¿Vnk;ØÑ'ô }"FˆbKÇÒ±1ÏbžÅ<;`<`<`t\ç¸ÎqÝ8Ÿq>ã|ÊèÊèÊèÄÚbm±6éEz‘Ï:¾¿%j¥†jV¢jÓ˦—M/âGüˆ_~~~~~>²‘l)–Ïzj~0—Yo6`¹In’›¬rÀù„ó çÓJL+1­Äq„8Bt¾ê|Õùê©Â§ Ÿ*sJÞà ¤¨3ÀðÌÁn 7…›ßüh,@ ¤¡ô–¾¥oY·Wb&fbæ«óÕùÏMìe9H™Ÿcé¾wGwt'vÄŽØ¥M›>ö©óSç§Îô}DyEyEyE¹7soæÞLŠ»¯Çz¬—®¸o×}¯€’pÃxtE(Žc>Z‘ $·yÂ5'ƒ¸d+y+fÓ®4Ó|M8'Bè/ö ë4Ô ªš~¢÷wn™³qk޳ŵ Og_±Ü„UÖÛµZëy®¼så“(²(KDNÏ÷–ëLdd~ÏÓÇzwØfN}C);?ÖôThÌOã‚És÷ðÔa¼z·UmÙd2¿vó‚¬ÐÑ‘é‹Ó$šD“ [0lÁ°S÷OÝ?uߣ‘G#FÓºNë:­«ÞG3è :ƒ»ËÝåîJ¢‡Ö°†õ/üæì&"‰ÌÕÚií´v„BH~p~p~ðçÑŽðÕ9î–J&*¨ â¹@.ÝРݨµ¢V!ÛB¶…l[Ú`iƒ¥ š6kÚ¬i³Üê¹Õs«/Ù»dï’½cK-=¶ô›²oʾ)Ë á†pC$ÉËÑÑÒùm9ïñ亮óŒÆ?cZ+‚»à.¸óã5W" ¬¦ÂLÍÔL¹\ ®…rrrt¤<à!_¸2¿:›½À ¼ „J0ã1þC‹->´x[ð¶àmw•»Ê]-©*©*©rjïÔÞ©½Ô¤é)žâéÛlîƒ9É ðÿð ®aúpÍÈ=À¯âΓíä(©Žõ˜‰¸Œ†‰=´ =‰ Šûé2q õ£FŸ,žÎËÛ½ûTºÒt®—)tð!ó¬±ÍoßtZY´cf‘Å>y½Ë›¢¼oßY?ÌêH¡îÊt›aÎ*®˜"HÑ «°»I5Òƒ •ìÌä5edd,øq_†xʶóû×CôÌvB/.id-€D$;ø«*d“Éü›0GYô6½Mo“<’Gòt?ê~Ôý8uØÔaS‡]lx±áņ¾|7ønø!ꇨ¢ŠÔ)R§H±’XI¬ÄŠ%÷ëçz=ÔC=ÄAT$)’IªwªwªwÆWÆWÆWb †Ïý;YÜýë¹}ZÆ×™JÌyîïíàjÓÚªo„]•¾µvœ^âìÚÅçÛL=¿lñ½–½wxON|ù½Ðwbu„Í­âQdœ}¦RÑY_L?'ÿ;ª5…ãÄfÆáº¹ú ææ&ÁÓdz¥gC„  á°_jÇVÉXÈFFFþq“ž ¸Ï6óZ“McõÍÌó„Åä‚z˜" @}xÙi¬Þ*ŽldÃÉü›°ˆ/<LÓÁd*™J¦æwÎïœßy¦ÛL·™n¶¶¶ÖVX[aíÔSOL=1¢ëˆ®#ºfwÏîžÝ˜ˆ‰˜¨’*©Rr4Ù9»£;ºãNá”uoëÞÖ½•M•M•MuututuLMLMLM¤Ûä9œÃ¹ÿ±ØŸ=H æ¤9iδnÄ1D ñkâ×įÉPq¨8T ©R5¤ªù¬ù¬ùì.ß]¾»|—w]Þuy׬¦YM³šr7¸Ü ñ®xW¼KûÓþ´ÿ-™~{aœ…î Fb$FJ+ó0ó¾ù±—‹\ä²²išA3h†é‚é‚éQQ)ë+ë+ëKGA‘/V™_Å2m†u„(…R(Å®¾¤'IO’žhfhfhf888øO÷Ÿî?ýþÊû+ï¯4«Ì*³ #0#° °à‹ÙàϘaÜà ;Üà Ézt$Q …i/LÅ:Œþ„k(„VX!B…L§Àn%z r¾çõÁ­¤!ÄX:ÙýpøÉÊ‚wtàrホ#ô¶›UHGåÞà? LKØ-h*w“€wó2yý¤BÃÔ³¬)©1º)¡ª`êCDˆîaZ¼.^ßôfëO[2™M»M»9'ΉsQé1É2Ì!#ó·DrÜélœ£w±<Šå÷729 3u1÷€†¬³jà!JØSmUÎA „Êf“ùaÓ®J(Y®W‡«“|>ù|òù Á‚'ϯ<¿òüÊAë‚Ö­›Üxrãɧì²wÊÞì™Ù3³g’EdYD‡Ñat˜”×ÞЈݮ¬Î[·:¯ P(²êgÕϪoŒ6F£¥¤‘;¸ó91ìÀÏnÒÜqî8w\l(6²=}û4ö`?À~€}‘=EöÙóæÕ›Wo^ý4à§? 8x,ð˜Ô\]º±u»ˆ]$'›=̰–L¿v;ÌD&2¥©¡°¢°¢0s/L¹¦\Sî7ŸuÊ¢w Ñ YÔSè t:xOâ¥Ô G8J=åâT™…¥ûÎ\ðƒ8ˆƒ¦S€)à‰Í›'6åJ”+Q®„S[§¶Nmúôèÿ(÷Qî£\Z‹Ö¢µŒ`ãnáÖð~xp  ‚’Ú0c ׌»B\IY‹ræ"B$u£ Àl ì00­§$ûʺ¸Ü)Ï:Á—üc\²+–°r^(ú&¸Âóˆ{Š­(+’f€¹£p EI-€4!3ÁƒNLëÅ”¬¹SM¯o§%½þTãB佘7!qÝŸîMÝôâãÇ%ùë¼"v;gº)ÕJW¥“hÓÄ9ï>¶ªQ3¢f¿;ž xâ3­äÈ’#çåÍË›——e“e“eÃRÄ‘âHq¤Ôƒ…`¾Î¤#™?™DÜéÜ„e@óž:›îé{˜`ÅâM>ô M´««ªÀ?‡5¬0fÿPùøû]Éü±0ç’^¼-Þosœçñ®Â» ï*LN˜œ09a®a®a®¡îµº×ê^ÓQÕÑÉÖ“­'[ …‰ÂDÉB‚HGÒ‘t¤¶Ô–Új]µ®ZW¥‹ÒE颢¢BÏÑsô€ÔE]Ôý|^Ë›ÍtLÇt)RÞPl(6´É°É°ÉÜvpÛÁm›Ø4±ibc5Ìj˜Õ°Ë£.ºÉ'ù’qñŸ^¡îµî([´@m >‚P”$sÑŽP\#“‰ ¹…AÂ\‘§…óâ?nΊ Å-Ål÷™Îßi{»„;ÕŽ©çW>w»Tòõ¨øÎ{=-TÛ¾¥6Wõ£6Jyàvã0`¾&„|_È'2N\mª)ë2*æ {Úò}LöÉ«U²½ø4.ùõð»+ž,Iž96Oa\k,aªfîóO°Hxú›åÈ@*Ûyh,ÔP?m}­òµÊs 4¸QÅFsÍuvvžo;ßv¾mBõ„ê Õ‰‘‰‘¡Gè´@ ´=™¿'Ÿ#îݰ ‡áOð9o õaym ÕLÓRœ» Ð[b¬M”b ¿+QF¸Ã6ò#óÀ¢ïyÈCž˜'æ‰yÜhn47:±tbéÄÒ3‹Í,6³Ø”‡SNy™™™Þ6½mzÛ˜21ebÊ0Íi‘:„†ÐÆaÖ\Ò\Ò\¢óé|:¿àZÁµ‚kLÙ†D“hMSh ýoµö°¼µ0v313UPU0¾Ü¤r“ÊMŠ~ý(úQ¥¨JQ•¢²Êg•Ï*¿^µ^µ^µ)~Sü¦xCUCUCU®׃ë!¦‰ibš«c*ì–’Žÿ9, ü=AOH%Å,Jý­Ãä YûI˜„Iæ4sš9´$-IKE¾"_‘™˜‰™¤)FŠÉÓ›ÌïžÇ˜ûÞmІ(‰’(³g Îü¬ü³òÏÊ´ hЮø„âŠOлëÝõîïZ¿ký®5ë«€+¸‚+çau)"ª£¼É8€ ÜRR–Äâ$Žb·°\ÜCo`9öàöS @!ö66³4E«¦–]^ä`ùå>í§†>)?°X\ål¿û®ÛܲÑ츧˜‡K¤7Ză,èuÚÀZ 0¥"øãô´ùúô;öI;R§Ý]ŸØúc»„õ¯çf=»>(¡xò–W×?¤dôÐC²Â5´îGòi¤çGÞÓÅÔ ‹HEn9_ VÐÂÅàOq»¸[ܳò¹æ~(›uuh9Jo^Ý…Òkõ†_§ôÊ›a/(½Y{T¥×+Ô ƒÏ튶ûøzÿľcÎ¥,-Û>vfdß9µŸ†U¶òì绳hŠã …§"Hô —T9²‰\ ÙEx²‘ÔÂR¯0'ƒN¨òð²˜áinœ€ ˜@Ž‘cäÛáVÇ­Ž[%Âa‰pÇæŽÍ›Ë»/ï¾¼»Ï‡>ú|`+«Ò)sI.É•Îc;ØÉƒNæïÀçT™÷ÈB.™Lº¡\©ê:™· õ‘†@8á<µ£”¡ü(þ®ÝO£úbθ‚5úóx™ŒÇÙ”2ÿeš¬U“¸T\*.å‹ðEø"犜+r®ˆ£¿£¿£ÿp«áVíúlé³¥ÏCWCWC×m·mܶ‘8â`µÆjÕõ%õ%õ%ÓÓÓÝlÝlÝllÃ6lÃìÀŽ?ñS0WÏBÅ…ØbÃTYDWÑUtõªêUÕ«ê0Ó0Ó0Sh~h~h¾°FX#¬Ùç¶ÏmŸÛÒEK-]”~,ýXú1iý*½J¯ÒA#¤’Ó?#¶d餆! aLÙñˆG<EGÑQßücv³Xb„!Fx!¼^( …B!©EÓhÄ ÆRÛ^Fæw\M¯ð ¯˜Ú z¢'z¾Ü÷rßË}š·š·š·EÇ_t|€G€W€W\‡ûÝî÷ÎWç5Ì‹ŽÙ"h:VÌ-üá¸x8ηyå[씃siÏiN6õ£ªÜóY^£LÙh·n –«WpÕá\w@™ÉïhCÚ ÝÅ¢@ûˆåšÄ½~Ë%7ÊyŸð*;-ø™ÿû9ó.$ßOýÐ÷ôð[_ôÏÜ“;Mï`Ì?>K[¸aÛT,å’w´ VCoˆ­¨ZìOÇ!JtA8Dx¢Á/ÎðŸaó¼EC+ª¢*ªââ¸8..¥BJ…” #;òî€i¦ ˜ÖnA»íôéÔ§SŸN¾±¾±¾± ·/ܾp{ŠmŠmŠ-§àœBô=D)R.`•ùKóÙqç@@è,\Aæ!)¹L%„RÀ8ª èOVn|ÎÑá'Í5« 9\Ñ$‹Ña²ã.ó‡Âß˸ŒËB9¡œPŽã8Žãö&îMÜ›¨‰ÖDk¢¿übð‹ùòäçÔÍ©›S÷ð¹Ã石ªcUÇªŽ¶³¶³¶s^ï¼Þy½ FŒ(!y+¶bëŸøž™k(@€À-ç–sËÅâqs,o°¼ÁòÏ<ðÌsƒçÏ ï_¾ùþåšÁk¯¼?lØþ0Ú—ö¥}¹º\]®®ØFl#¶‘4+þ½’Ó¦Þ°k°5P5Ð}Ð+±+¿ùÑ•Œd$³M±·Ø[ìMëÑz´™H&’‰˜‚)˜‚UX…Up†3œeÇ]æwcY´Êêp†`†°yàé”§“žNÒLÒLÑLq*å¤sÒùg—4—Œ¿àAäƒK¸.& =«ëxô¬Q¿|ÛbœßÇ¢ì–VÊ÷,\'À¶¸«c5«@Û]ÊÒxg.,è;Êü5® ÞB3ÀxC(¤£Ÿoþéñ‘7Ssvžok_Ö½ž÷è~rxBû7£²ž'–z½îS €Î_¼oI9Šxà::‘Τ09…X\Eº˜@=é$s ¡%-Á0";þO~¹ø;sËØk-ú7‹Ä b·óá|ŒÁÆ`cðb,Æb<}ûjëâ­‹·.Öþ ýAûCߦ}[ôm1jë¨%£–änÈ+“WænüÝõw׫ÆYU²ªd¾œÝ=»;í3̘ˆ»¸‹õØŽíð‡?>÷µüIE*Rwå»=3—½1£1{Ì`.»ö‰ö‰öIÿ…ýö_ØòbË‹-/j'k'k'_Ûum×µ]‹ú/꿨Ò¶¤mIÛ$±ÂOø„O¢è#ú|¡ªþó’S–ÝÎþ;;’ÿ•Ëó°˜=³¹å«Üáw¤#éä¹An(*****bV`…¹±¹±¹ñ_d”Z$°‰µÄZb-aš0M˜Æoâ7ñ›¸¹¹Åâ@q Tw÷ wŒ–ùýXºï]Ñ]ñ¾Ãw¦Á¦s¦s÷nß;uïÔw{ì=ræÜXŸØi~ºït¸Óü[n›SmqEÊQÕ odº¹2 hÄJLX (îxÂ%ä¸åt)p~yêcxöû›=žtO¯sŠ»ð:ðòŽû§ÞÜ͹¬«d,’µ Ψ•ÞÕ6à’U8Âypç¸f¢‹¸ŒVKÑZÓ±i>šàG3h¾$D¡0é>ÝŽåú¡ (Äâ ñë÷LH 8ÔôPÓCMß5×ü]óQ¥G•UºÔ¶RÛJm›7gÞœys–·YÞfy›ƒÜAî ÇDl‰ q!.ôýD?Ióû/rÙÊÿËŠ¯ !Np‚“t¯¿‹»¸+×*ü_ü¶O?Ç¢rFß™¡€F`4­ˆ©t…ÒÄ¿æìBÕ÷TÀe ÓÐT£ÀcùZø›Ã.6&¥w ×pM8'œÎ!øÏO/åÑŽ GÙžÕ?¬þaõv'ívÙíjŸØ>°}à˜1#mGÚ®Þ¿rØÊaîP|P$«ß×}_—^+ŠTB¥/Nʦø§ä)yJÔDMÔĉ8'Ö´\Šs_À\`ot3ÝL7ã<.ã2mECi(±ã&p¸Xî÷ àÁ ˆ ăâÁÒõJ×(]#:<:":¢r‰Ê¾•}uDGtdKç-·t^•¸*qUb®6W›«å½x/ÞKl'¶ÛÑö´=mû¸ûÒ s©ma [R„!’¾8½B¯Ð+ҔǜKK~ŒÇxŒçxŽçR´˜= ýsثؙ‡Ð!téFº‘nL¬S¸(\.âáз>T™NË?’„$!Iðü?n·ÛÆã‡ñä{GqGqùâ–ù&/æ>îÀìà=øÇüc¡²PJ(õÖø¾åû–.]Ï9¦ò%áÞ³q€íUÒi},ªà št¯ö³gi“®Ny8ú}ðãö¯ÛfNz°àÅé´2WË?øø¶/€RìÞ ÀŸ×AJ˜Ç÷äÒÉwbwñÚŠöt]*N¶‹f(°7%ý O0yßÑÑtDñ޼#ïxoÿ½ý÷öpá>Â}Bâ„Ä ‰UGTQuĘmc¶ÙæñÊã•Ç«u3ÖÍX7C¿Z¿Z¿šÓq:N' ‰…¤Ât˾2ÿM,]vrúߊ2ÿ•à “C¤%Ûþž {Sù5¥ÓWô¸k.>9·Ëº‚*“t}µ¦ôIŸqÒñ*r”t•íö«üZqªºŠºŠZšÊÿÅ©Ʀކzêm¨}¸öáÚ‡+¬¬°²ÂÊÒçKŸ/}¾ôöÒÛKo/yïÿÿø–ó-ç[Îó–ç-Ï[^Á^Á^Á“<&yL*2¹Èä"“Ýuî:wËV—­.[]¾sùÎå;çùÎóçÛ³f?ÌÑÖÑÖÑÖ¶ŠmÛ*¶JÛS¶§fŸnœn¼Ÿ’ñ*ãÕE!­pZáXë{3îÍ8\á®î®®kíÑá£Ã•­f…YÕÆªªUUIðO£-iy½åõcùÇ /ü`þƒfì‹Ø±/"Ü!Ü!ÜáðMYFÖ“‘ŒdâGüˆI$‰$‘kÎ5çšsk¹µÜZ¾/ß—ï«´RZ)­ª~¨ú¡ê‡°eaË–9ò޼#ÿóïý›ä Î@*Bµ9nsÜæxÍ‹5/Ö¼X][][]«>¦>¦–Šä°K±TžÆdþX¸8~*?-…ºÁ[Ãj‡ÕNczhÌ»ÑÆ )(};VØlJ¸™¢ï“_y?ó@›ž½6Ž-{´|ãÍ]­©Ýqíà_8éIŒGIn0yJŠ“C¤ n’¼Á,<ÀfôEsÔF©o¬ÔÚR®€í¸CîÉÕ³Ùh³Ñfãè¬ÑY£³®ë®ë®ën_½}õöÕù׿_›ÍÅ×Å×ÅW²öCî!÷PZeµ<³Ì‹ŽÔ B§Ð©­ÕÖjkÅ4Å4Å4„#áŸ/’ÿQGáo„/"ît&.âvú´\·Þ‚tUÓ¹ðÀåH~—k[Ϊ–r±ô‚ñ¨ÒøA6ã¿5%ý•¦&È"»"Dˆ…‚  R|R|R|ÂP ÅPjGí¨TõOÒt Ôý”ÅqË¡ÊÑEt]Ä2A™"»äd³=ÞÔ›zKY×303̽…ŽBdzÎ8; p×w¡ß…zÎöMöMvpq†3Ô] {S§KN—B&ÝRtKAM!FˆÉqÊ^—½.«wVï¬ÞYáYáYáYϳžg=ÏÐeè2t¦Û¦Û¦ÛÁ c¾1ߘ¯Ÿ¡Ÿ¡ŸQ@ H1&š*˜*dÕN>ºÈaßš¾5ËŽ¨P©B¥‚ÝBI¡dÝ”º'ëžlԢẆëŒ9i•Ó*Û|ìÚ±kK«.õYêóîÔ»SïN)++“3ä 9à jñOñ”Àà°¥ü"~¿ˆÌ!sÈ®/×—ëKê“ú¤>?‘ŸÈOÄlÁE!E!E!®W«Æ/æó‹¹;ÜîŸÂ§ð)Ün 7…/Ï—çËó­ùÖ|k–¯X§X§XG¦‘idoÇÛñvü%þ‰œ$'ÉI…›ÂMá†Øˆ Q!*DêNÝ©{Éå%——\~³ï;7û~óãöžáÛÖ k…µB¤)Dò>¼ï£èªèªøŒ((!OW2ðô….肘„IêšQšQÚzŠ2Jë”~h¨|deB'€S[uRÜj?iʎöæ(Cû‚µÿ¸wìÇR¾174%u‰ y,–¥ëieñ´ø–¾—Ò’ô~ª0£8D”ûfÍd)W`;ØÑ DƒØL•W?¯~^ý¹˜‹¹xazazaêW±_Å~ë¬7²ÞH÷ŸÜrÿiNðœà9Á8>p$ÕIuRUQUéuz^—Shþ«0Í?øÁ­u999[ϲže=ËXÍXÍXí*w•»Ê‰§ÅÓâi©wõ;¼Ã;Ùx?çËT™•¸EŸ°é!óA¿±Žø^¼F1 óð”ËUâvÚÖW ŠÚ€ãABàäÿ›§!-´ÐÒ­t+ÝŠ–h‰–ß°dùÎY:GMÔDMÞÌ›ysΊœ9+ÞÌx3ãÍ eaeaeaÅ{Å{Å{©¹çÀ9ðn¼ïƲ¨¼‚Wð\O®'ד9å ?…ŸÂ4"H#ržœ'ç0 £0ŠoÎ7盫.Xm¶ÚüqÞÇ 7|ÚøqüÇñE‹Šò>š~2ý”לïÈw´ R´U´­WyråÉü,M’&‰_ÍÝänr¸ Ü~ ?È_ä/òÉmr›Ü633ÓMÔMÔMÔŸÑŸÑŸÑM×M×MÏ“ÿ&ÿžÚÚ¥Ù¸÷áž—wÍk5¯UI ¡!TwLg g¹QoÔç6mÙ´å€Û¡c‡ŽÙÖ¶¥¶4¨^P½ zdÙEv‘¤©Á_ç¯ó×ÙÒ°â¨â¨â(ú¢/ú*((¤.Œ¼ oÃÛp˸eÜ2¾=ßžob(†b, ‰Þ£÷è=–AK÷Ò½t/“W£…iaZ˜YRR‰& ’:Í,À:˜¦ƒ¡)¤6j£6ÓÀ!óÈ<2õåjr5¹šÒwÍú~»X§ «…ÕÂjq”8J¥¬®¬®¬Î¹p.œ‹d76ªedþPÄLq 8oÏÍ'Ógܹ}çá¥53¢Â'×êÓ—oŠÁ0m,vDLPÑ#æ¶Æñ¼/טì¡?! ôí.<ŸÐhŒÀô)8px›ÿáz~ I/,ÕP´>­O듲¤,)‹J¨„J»•»•»•o›½mö¶Ùð›Ão¿YfV™YefÍ žÓnŸ?m×´]Åžø˜}Ì+µ•ÚÊ®¡]C»†ZƒÖ 5XŸ´>i}Rs[s[s[Í–»¨»¨»¨#Õ‘êHMMM—Ö.­]Z[ÕV×S×+ÛÆo¥ßJúɽ¯{ßצá¦ádº$©N(†+†g]ÿ4üÓð3Ï|wæ;{—.=H#Ò€4ö{„=’¼c- "‰HhWÚ•v•¶ïÒ»ô®¡Œ¡Œ¡ ©HEñ°xX¤…ÝÂna·XX,,¦hÚÁÔÔÔÔÔ”Ëãò¸¼’×J^+yå|h 4é›bYõß.ìý3' šFÓhq®8WœË4¡¹Î\g®³”eë8ÈÓ˜Ì|[( GèÒƒûŽËM‹HÞ‘|ñü¡v×§ôž¾ Ǹ·âz±í£àû? 7…åÂxÜÄø¢á8à%¶HúÇéXÄøï‹Ž³+÷!}H²÷š{ͽ¾áyÃó†çÐjC« ­6*yTò¨äÚûkﯽtÑuF×)¹«ä®’»–` –Ààjp5¸’4’FÒhiZš––t´˜f—\ùgÀ,ÌC}Ð}ò&æMÌ›¨ñÒxi¼¤™v&`6a6É©2¿2÷XÍ9ô¼ØóÂúE“u¹n,=¹R—`jž=°÷… [ê5¬´£ˆãl9[ìWa*%ÇŽ?FtŽèѹÇêó{ã÷ÆO’™#“È$2é/8¢DA8‰“8‰±?MÐM$gý·´gú5–bÃ6‡wÜuptÙi§¦ê½v²ýdûnÓNM;Uíj$"Ç)•!ÊeˆS¢S¢S¢çJÏ•ž+Ë®,»²ìÊ*[«l­²5|DÄÔˆ©‘q æ7˜?+oÕ:«¤Â”Rz½½ÉÓä™àL)¥Ç¼+÷®\‘†î­Ý[­YtEÑ®fW³«Ù¥¸Kq—âNGœŽ8q¬áXñ†]s»ævÍm›Ú6µmª%Z¢%špM¸&\yOyOyOéªtUº’’@¾ÈÑ”ùOˆÄ?9H’ƒAƒ6m   s:étÒé¤ôW[bKleƒÉüÁØÂ޼ ׋Ì!Ö$’4h¶¢Ž™†¯Ï ¶Ž»6c”ý™²KÝ;ùd²‡‘^ÅòÔe¤‹Ób½W 5ÔÜDn"7‘íP…ªBU¡ÑÚhm´öêOWºúÓmÇÛŽ·c´1Ú­g5ÏjžÕØ‘œgÅY¡j¡–t6ËæP2ì÷Õ­ÑZ2s¾_§Ú”jSªM©#Ôê‡9ba;ɉ—ù¾L•ù —? ŸeN×iôéâ+q}A¶sµ‰x2$[Tôç˜öëpÒeHPÈéa¿L RÂ6i8 §á†µ†µ†µb¼/Æ›{š{š{Jš©ˆ|‹—¢E ê¢.êJÏÊŸð Ÿèmz›Þ–dõX<ƒ‰²=ì >ð4i²3³¿Z–(±jtËÊôÁô2½Œ ”Gùç7.ݸ¬¤°§ô"ê@¢IÒp×ñ#öc?ñ'þÄ_êZ¥QšŽ§ãéxSSSƒ ÿ ÿ ÿ d ã—>ûr?8h5ë»sßÃiGñ<® mAÛÔ^œ>8}h“¼;y7€ÝØ ú¡ŸôÚFh„F¿jÕÓ8Ó¨ˆŠ¨(í)Ò(-å².ŒLB‹ÉG²E^¦™À"Fz‹Ölˆý•Y’ q²%K–ôÂŽaçaçdŬL»m³V2íÑí¿øÞ¿E^à^ : mGÛÑvÂUáªp•kÈ5äZ+bEp §pŠ5®g©Dß|‚Ì×C.2‘) y´mFaLBôó³)µr_æ‰wÔo´í­ Ï+4QmË_抒×f^à(*ÙtÿÀRj“iÀO§‰ÓÈJ²’¬4¾0¾0¾X|yñåÅ—?Mù4åÓ”Á=‚{×Pk@­EBŠ„ ™ÿiþ§ùŸn”»QîF9n·‹Û%®׊k1ã1^ºCýwúfü}¾¯›¸‰›l½]¨,T*§M;švÔç‚ÏŸ n…Ü ¹bõfh€hÀzxËß¿b>¢ =‰Ú)¬~R~Èy;AÙÉÃppr³.ã)W·ïwKTQ3B¾ƒÖ°VNæîpÎPÈ‹¿‚eT€5ƒD YgÐ/2hå:÷$È7Vx*<ñÊ]Ê]ŠîÊñÊñŠtå.å.n=߀ÿÜǯ¼þÑ‚›a¹$ç ox³¥:HI ÙKö’½\%®W‰[Å­âVqfNàUœê˜ê× ™u}vÈì—./«¼¬ÒÔܬd³’؈s8§´R ø’¤q&ÎÄYrŽ™ÖëðwÇq{±{1ó1Ÿõ”R‰˜£\UQUЏ[*²Ëü{¨ ‚JZ ”‹)S.&lWØ®°]ucëÆÖU?P?P?®Ê¡Š¡²Ùdþ`z¢‚° Ѩ«XÁ¿áÞ>{¾Ý¦û$J¯åtÈñ>V|`aç<û‘šÏ‰¨û1 ­d³ýóëZÚ¾‡{¸ÇÔÜÙŽÛkl¯±}—ë.×]®wZÝiu§Õ釧ž~Øò~Ëû-?‡Ì¶c;¶“Cb¾8³|wþc±HFrŽvŽvŽ+V*¬THóæ!Í•qÊ8e“?Æ8ŒÃ8Ù`ÿŠ^¨üy9ÞÊ–¿Ïe'{Œ¹Ôþ…iÒž]U”ΙÜûÓú¹-Ô’ÜM¾é‚×è‰Ðÿ£-#ó—†Áà%•äY[fÍ›5ï¥× Ó SÓȦM%Ýz>•OåSe[}BBØc[Åë¯W¼¶$lIØ’:Öu¬ëXkkkK‡ŽÆhŒ–-&ó§ŒÃ7d âÙö¹ÑKÜÛ= ôZ§§MµÏ$ ¹[':ˆx·‘Ž­Å[Œ“ù¶°¬Ž·…ÐC0©Ä¸a<6b£×—Û||ÅÐCô=Äb?yyyL¸"·GnÜ‚I0 ŸgeI2™?æ Æá>¡"J¡ØÓ…ï¹õ ÐS´šb¥²²Ô2O'çDiâÉ$ÇÈP9öû/0Àƒ4KÆ` ¦Õh5ZëÇõãú½_ÿ~ýûõÑk¢×D¯Ùua×…]ø| ¾F¯1½Æô³Èq‘ã"Ç¢AEƒŠ‰!bˆ"iLUFeT¶,•Íü±;±“µ8R…T!5£kF׌®L|¢ÐÜBs Íe©¶’~ZY”EYÙl–|¹ì®‡ù³(õ åð}Þ “^˜Gn[d@'Ór¶U­Æ¨l””M”MLÏMS.é‚N(#g¹ÿ ,s‘e¾],s+s‘…,ä"R?¾4|À|À+¼’X¿j\á W¶ù´îÓºOëþê‘Û°ísɾŒÌ†"4°‚÷ðo-{U/½6nŠGÐÕS¹Õþf>Ùè†a°&fLÄ •q@6Þ¿Àr–V@…¸B\!®`î»>X¬fðÏMÏMÏM 80à@¨c¨c¨c±êŪ«>õÕÔWS_Åuëו“`Ì’i"M¤‰RèM¾›ÿ{°ïe–a‚„ T·T·T·bÚbÚbZgƒ³ÁÙ`uÕêªÕUƒÑ`4Ù1R‚±¬¸àÿFÜ `þœ{$æS:07Îäc&ä%y‚U€ø=½oóÌj‡²–F£ÈâïC@”GIÙ”222ß –Õ+°+ðð·q·™ä¨ôWùLæ¿ÂýÓIK’O¡ÚãÌ|Gn¡×p7XoÀìÇ5òi WÙmù0'¥[pàÀ1÷WpWÈò†¼Ù£Ü£Ü£56jlÔsëçÖÏ­½Ô^j/õœ¡s†ÎÚ¤e“–MZ²þÌe'uHRGrÙ劣ÿä{9€8€;¸ƒ;yûóöçíÏqÎqÎq¶ZgµÎjË3—g.ÏÀÔ!X5 ì²[ðsÇ]Џ‹Ó¨ír̆@óX”&É&€.£é6»TNÊ=êaÊþŠ0BEKRÞ²)edd¾,™ú¡úI=zÙ²øk¼Æké¯ò CæÏãR¡g†/B>Lϲ6äë7 •¡ yôT‘¬B³¬s•Û·ùqæBGÚ¹8‰²Ù~7,Ñ…°Ö@ Ô ãè8:Ž·çíyû[Ú[Ú[Úh·h·h·saçÂÎ…:^èx¡ãcŒ=2öȈ A#‚4³4³4³èyzžžçZq­¸V’"CÎÃþ½0.&ûøðèSú§ôOé¤'éIzºs;çvNZ¿ŽCâ$y9Œàÿ:î:˜þq3 Z"ûƒ¾´Ñ"¡ä,ôâV*j;©v)BÔË%yiÈ’( ¸lJ™ßÁfz¯a-”º†#æÇ¯'¦.Ì_ P'ñ„ko'+›â^ó‹ôtì…pÌÄS®;)LŽÊfû7aÒ·,O}+¶b«@*Pb bøÐîC»í&ÔœPsBÍØŸbŠý‰×òZ^ÛþUûWí_M³Ÿf?ÍÞ-Ê-Ê-JÜ#î÷pW¹«ÜU„ !R*¬œÿÛa‚Å,Pò Ÿð)£KF—Œ.= zô°vµvµvµµ³µ³µ“’d6`6ÈaÆÿ¸›`Æ,¸PASÙþzã>pĈ‹âlz–zY¯VVàP_VÜâI¯jŒ’¤ˆlJ™ßÝŒ“H„:˜rkéjš:½ZýÑ.w@f‘ê…Ùå¨=Š®+4ßæTP€;r£ä¨ã„eoTL0Q+jE­H+ÒŠ´*8Vp¬àØÜs7ÎÝ87enÊÜ”ÌR™¥2K…ÏŸ>~™ùeæ—)ç_οœ¿è#úˆ>\—À%Hò¾rëïe"&b":£3:ë6ë6ë6§¿M›þV[ -и–q-ãZ†uO—JT™Läßž/‡W>Œ0‘Ñ¡0 díÔ¿3:¡菱($[.G£QV™4‹¬¼¬À¥Q!p‡£šmÏJž•<+ù¥ÝK»—vM÷5Ý×tŸtL2ŸÌ'˶’‘‘ùUÀ»rȆ´Õ¾œXÜ;cÖ‘éƒ:Rz}ôˆÒç›.=С…敺‡j±ô*.`Â7ðéXÓÂ(ŒÂߨ÷ò³D—Ÿg¾4OožÞ<ýTî©ÜS¹wwßÝ}w÷övÛÛmoWíSµOÕ>I_/sß™: ÃÖ°–þÏ®‚hD#¥P ¥ôz}XdXdXdò5Ê×(¯HR$)’$—¥Íü×1þ¯ªŒfl…/TlGNrΦÜÞÊëB®à¦ô5Ñ—ã ™‚«9Ò8B—·×yêØÆû"¶m,f¯>«šÈŸ7ßîÓ’¨ˆ^ˆå<È*dà(æ 9*¢$\äH¼ŒŒŒŒŒŒÄg´&ã#2 {ž²4§jš}v‰‚âáì%î`³Ý¶¿¦”R+(@H'ö•÷Na~î<ÌÃ<4Gs4Ç5\Ã5É•ÿú±LýUB ¥´c –` ÙAvû÷;ïwž0j¨ £^||ññÅÇc€1À8Ý}ºût÷–}[ömÙ—¢…h!A!ÍH3Ò ùÈG¾d9…æÿ_ÏñÏññ8wHîÜ!¹çsÏçžWUUumëÚÖµ­T“° «°JV˜ùòŠ{Ưå×³íª¡õõ ÜŸ-¦”Òkùb'j}ó¥”Þ«H©¸ŠÒ^ã@éÅÀ¡WÎô[<²uÙŽ‡#šÔRQ:s›¾8çxòŠæÔdÞI–Á[lËÈ|#Èw™?Œ™Œ&\i²︅Ü|ní…JKf¶DéÙ#ï˜ìÎýíçSÈ=ÑNê²B¶“º8ý•~–Þ–¨ Á7鶪¡–jÿÀi¸ ÜNZ÷ð8æqÌãØ¢‹,Zp{ýíõ·×_ñ¹âsÅ'úVô­è[êåêåêåìH&1ù…¼ÜȉÁlò#~Äl‡waïÂÞ…ªªªË%•K*—„™˜‰™’ú{1C1ùáG‚‹ã;ñmØv•)u7Ô zá’û »È].«xZrœ!otvç[Y>E e/ŽéCé¥ä¡Ý(½î?ò%¥Ë s}ÐjÝ­N ûžlº!ð£]aí*ËóózŽ’³Ä·0Fºx­ ”s¿d¾dÇ]FFæE1˜ïD¤(ïæ ž7ªNu×oŽò¢ôJ½á=ëM ²*žÈþJÎ’æ¸ôÕ}MB¢ÐmѶìݲwËÞ ©èRÑ¥¢‹ÔÚŒe~³´‡o+ó›Xü°)$…¤°mu :P8rËÈ-#·\_}ýõõ·zßê}«wŒsŒsŒsQSQSQ;’[Î-ç–#üâÌ2™ÈD&{˜±kcׯ®Mí굫׮º,tYè2ëÝÖ»­wK~wpwþžFú¥ìóåbž¸Ÿmf+©îßѺÌl1À³BóÅŠáÃË«4rýÕòѧúL™{eìËì‡×‰º<ÀxÙ\ ›éÁÀÝþùn7WDŒù®þ´Û7V/iÿxTïïÆ•òéâ`)¨EBëÑ<ciGTø‰ó%ëEŒ:Ò{P~õ™ñ–—™7¼áÖhÖR/ùR”‘‘‘‘ù-¨ O·S f£JÃïéÇ‹r;Cc¾&¾Áq¨áܳԻ¢ZéxL¾º»‹3œáŒ7xƒ7$ä‘<;G;G;G»1vcìÆ8´uhëÐV=S=S=p°[°Ej]ô­Ü+-Ó3l`êFݨ131ëãõñúøùæwšßinݹuçÖÍ—5.k\ͨšQ5£–6\ÚpiÃJÉ•’+%‹Äâ&=)¥Ð°3³èûßÓs`Ÿº!¢!{ðË É É É©˜S1§¢uyëòÖå‹:u.*‰on![ÈÔB-Ô’Îð·‘àü¥¹ ô-Û,8ažgNÍu20"‘œÈ¥Ü ’À©»Œ6Û¦¿÷¾ãˆ„M7^ü8eal»—{âº=ÿ)7SwÓs€ˆK÷š_(rêògSc’Úœq«×›ê‡Š¯pk`»‚n§ôhgØòãy-ׄ´ƒ ÔŸó쿺t!`—Ù À´C;´ÃnìÆnR˜&…„ IÇÈz®2222ÿ–NL{´G{lÂ&lb7ï_8æ[Ä3Ú•ÎÂ1<@’^WLIÊCß ³D%²ªdŒÇAÇd´F=”…#laõÕeø²Ì&h‚&ô(=Jš™™ ±B¬ -´Ð–r)åRÊEå§òSù¡Z¡vav}cº+ìÝæ!y’ˆ¤‚*¨B Åo"›È¦½^{½öz<~ðøÁO O O Þ7¼oxߘSkN­9µZµoÕ¾U{z‡Þ¡wèz€ ÉErÑR˜òow¥3«ÞÀ ÜÀLÁq¤8R™^:½tziÑ™ö¤=Ý v)ìÂRtRt¢‹è"ºq¥9ào#Jþ ƒƒN¦gp(¡ÈÕª˜ò3>ì0¸¢çO~‚o:Ç’€IDATHK‡;ÊÅ\ô;÷›§¤]ÍtÈ>^çþÃìKÃU:=s5o³áE›Ë¦#R¿×]É[_`œ*¹Ñ«¿SÓñ•{”¬ÖùÞª5¯;n[ôbp³ÚkK7÷rpÚG#éqÔtâ!˵%W‰‚l&¡8޵ƒúp„í?2ÌþW“4»œ<á O¬Æj¬Ær,ÇrÌÆlÌæ›ðMø&ô}FŸI‹8npƒ›¬p/###ó»a~»WC5TÃvlÇv&‡D$"ÇqÇ1Ó1]Ñ]DHn=ËšýFrˆé#¸ÑÁlûî»Dsr+c!“Ƽ m𺴿ç‡سxˆÓ¸ƒ÷PBñU=®°ïkakP·ÊÝ*w«Ü{ïý½÷†Ö†Ö†Ö…  ð/ð/ð/àžpO¸'hƒ6hƒ^è…^ßXôÁîï|øðáãkE׊®¥®§®§®GkÑZ´I$‰$QÒáQB å߉·üÆÙõ[…Q˜Œ$=IÏ´"ii¹¦ì®Ù]‰›ÙÖlk5š[Æ-³ª¨®®ì¢¼ª¼ æöWDETü»Î–nØ€)l[QS¡Px¿Úí|d{j˜Ù«ç÷â€)}º¾zÔ<:µm%b@cðšcšýšvULÁæÊoê «w LQu\õœZ•«Î«¦«qí»á =+-Üþý°úôËN lEéµ #}(½1\Kéµ*#®çÅ¿7påš»£§†k‡–¿UôñÏßß“[DÆgÜÃgJÕŸœo9˜Š£8Šãná–å!Vj+µ•ºdvÉì’ÙoU¼UñV‰‰%&–˜¨Ø Ø Ø ‰±[ŽÌ_9Ç]Fæ¿„…˜ ²™²™²™Í>›}6ûX¸ä_¼¶?ú£¿¤Dq Çp =Ñ=á W¸JÇ|=nâXtFuð €¶¹º¹rBÊ”åúÙSz}ìÈŽ¯FÇöêÑEÙSQŽK@ |á†iè…šßÊ×èèëèëè[³mͶ5ÛFh#´Ú²/˾,û’Kæ’¹äX`,Æ~ußËoÇò=sàÀI͘Z…V¡U =<új端v¾e¼e¼e\T°¨`QA±ÖÅZk-½´ W†+#UÆ_IžYÉòä%^â%÷{È=D2’ñ ÷ÍÊîÁ݃clÏÞž³tûàíƒGøOí>µ»uŠf§f'W¸Jk S&! Õ¹>ÄÇ››·^^»¥s\{o1û!²«ÿûGßh¯°º©˜Áo–¦T“2Ny¾‚_ÛòiÊð¹a)õbêª;<¨^•µ5¬ §!EëVœ[âJ¡‰k‹ŽQE”Ê:xäxÿe”^ÕXLé¿á“(½>~ä輩' RÙ='´Ùýˆ6•;­j¬˜Èí·|ƒ|n1™ŒöG´PCñ;ñ–Iô@&%]T͹æ\ó¢3ŠÎ(:£jNÕœª9a1a1a1õ¦×›^ozC·†n Ý´3µ3µ3ÑÑßã{|/7_ø+!;î22"ìÖÞMÐÕQÕµe´e´eB6†l Ù\%´Jh•ÐróËÍ/7¿Ø°bÊ ³5ÛšmÍ*NÅ©8Ò—ô%}õü×q×a‚ &,À,@T@©\RTÿƒHg;ÔC)6yðÓ¸g\é»ëÖ ]RzmÙˆÁiΓûå—íä“àº@2R&™ ÝWú 2ë±ugx†gl·³à,8 µ¬jYÕ²ŠèÑ3¢g鿥›—nNj’𤦤ÜÂä#-G·8z-îød2™L&[Ò2¦eL˘ÓÞ§½O{ÇyÅyÅyí*»«ì®²Õ Õ Õ ’ {q½¸^8ÓÿPb#óÛ…]_lì#>â#¯âUü/|"Û~¶ýlûÕ}\ou½ÕsZμ0óÂéG·nܺñh¥”¾zD)¥«û*rª_FzI Y}Åßa‚ü¥ÄY8Žkü÷ä6×K ¡µÄ¬ŒÅº—úËÀÙˆTE[Ù½T â+¯p±ÜNàÂt“ÒTÁTç¡æ¡ú‘ʉ¿ƒÿÊÂN…gvrhã©k?  ŽÿÞLJ?Ý3ŽñÔ´ù¶;NÞyÕÿe³ªå‚[M­3»dá"ë‹ì´O´žh=B¥ŒBèd_§¨VÕ.û\8ç}7ïíÙ-ØÞ¿µ·ÅÅϘ; Ñ¢´&@ž“¾¸x¼BF_á;ÜA"R f¿1MÅrY–9ÜePe$ù!€ãHÇ‘Ž#}xÞ‡·³³£;èºCd?ÅâGCˆ!äÿ±÷•áQ%[׫N{:îNÜ=„xw'¸Ëàî0h`ðÁÝ]†ÁÝœÁ! !$„„qïîú~œÃ¼Í73÷½÷½wæ"Yý<<‡Nõ‘:%»v­½vM°©©©©©é›SoN½9ÅñÝ57ëõGëQzÔãÏÀŽs0sX“Úâ•Å+‹W:÷tîéÜS.U.U.ú ý…þÚT›jS£=F{Œö !©{_÷¾î}é«ÒW¥¯Ê­Ë­Ë­+T©ô¡Ïñn/á.!©HýKž:%¨AH¡R­W·SÏxQüîyéÿ~C7ê5“š‰Ú»ß·³1ÒKæ¥3y„MÌÉ!¡„~~s K aë*$¦Ä”˜ò y…¼”ñ)ãSÆ{†z†z†Z&Z&Z&ª©©¥–§–§–s{#ÐpGqô ›7Ùûdg|!„ÒYtÅñ×ëP‡º£’£’£’ìUÙ«²WÜ;rïȽîsÝçºÏm3Ûf¶ÍzóõæëÍn9ºåèlÁl!?‘ŸÈOtDqWùœë„]´°5РЉ4 H¶‡Ò™t&ÉE‰‚DA¢ïß ¾‚öí Úd=ȺŸu?ÑZ~~ƒšÒÆÒÆô!öc?Ù d&a~Â(ŒBOß°æ=dÔ 8Žl|À#TCP1Z¹[êKôüчxI<™i:Hwµ4¾|fÁ´âiä'âJ„ÊAÊçÊÚgkŸ­z¶´¶km—Úïl±Ýn{E=A¥Pz>s uq×m«=Arþ™ìùòMGaõò«XwëXRÒ¾.Wä.ÆCW´Qø8[üb¾MçÀ´$ö²×A²‡d\as-ÞûÑ€¬ì}ÂKc^lïx.#%¿Â±ºY/×ZŽ0·ÈFu)@íh?fC>ªQ å<©fÓgײ%(A ·î?8¡¢¢bw×î®Ý]“““^6/›—MoÓÛô6}M_Ó×¥V¥V¥VÚµ;ks2šVYVYVY¹É¹É¹ÉUáUáUᘩñ©G=êQzüFaFa&`‚ © © ©Q¨Q¨Q¨ºD]¢.¡‹ébºXuGuGu‡ÔRÃÌaæ0sX¯­(R)Š4igÒΤÉ|“ù&óY³»úLõ™ê3565656Õ†Õ†Õ†åíÊÛ•·+Í(Í(Í(“”IÊ$u§êNÕâ°³M Ä@ $H#Òˆ®¦«éjNOú0ã0r‘‹ÜËœzB”-\@kúèòr]Ö᳑O;áïå7´q4‰×΀.ZÀ„’\2;Aéçjβæ{ JPÂUÉ^ìÅÞ‚îÝ º¿p|áøÂÑu¿ë~×ýVŽVŽVŽªAªAªAiGÒŽ¤/|áË G²*4_¢Û«µ¨å¬ Ö¬œƒ9˜Ã˜3æŒùíÑ·Gß><}xúði/§½œö²ñ™ÆgŸo3Þf¼}ûþöý×;®w\ïX5¨jPÕ ^4/š­º®º®ºÎŸ|6A™ì3²Ï;ƒ1˜‰f¢™hÚ”6¥M©>Õ§úšÅmÌlÌlÌÃÃÃ===[¶l­k¥k¥kÅêɼyúæø›ãWc¯|¸ò¡ªr—r—®ÜÊËʋ٦þ^ýý‡Öù“ó'K:K—H—”÷¬˜S1‡»ú7€?]Ðf8E“ðJ¸l®VÕéBW¥§"á„]|^ æµMsý:é³ P èÒxz Ã0ÇÔÔÔÒ¦§ý˜6C5G5G5Çn¹Ýi»ÓʧªyÊ·V»­žX?ža¡/~}®ó<ô­oQ·ÙØ;X_rüÖcù°%mçûÌèù¶I¨ßeµ£¹q<ÀL'¿†= ²ÿ$§‘“;ñ=ºbð¡Æžlr«8½EvǂР?öþ™SŒ”øÒêÛ´U`Ž`/.â9·ñÆv}˜À„‹mgCNÅCÌËçåóò­ž[=·zn#²ÙˆDŽ"G‘#ͧù4ŸÝZ-—–KË¥oâÞĽ‰+˜\0¹`²3ãÌ836+mVÚ¬‰‹ÄE6I6I6I/¾ñý‹ï¹à›Ÿñ3~Æ[¼ÅÛo|j®G=êQÿ¬¯Žå¯kA Z†v†v†vÒ™Ò™Ò™$›d“ìÂ…… ¦Å¦Å¦Åj÷Ðî¡ÝC7I7I7I/P/P/P%ŒF s„9¡@( ˜AÌ føˆøˆøˆøœøœøœž³ž³ž³éÓ)¦S”•ÊJe¥z³z³zsÅòŠåËËž•=+{Vܬ¸Yq³ª‡U«ÖÚÕÚÕÚÕ™×™×™svã.ìGE[´E[´G{´ÇS<ÅS–Ài–³œÝ|ä#Å(FñŸ>û[ä¡„\aÚ“7´‘šRAòàWkrS0€ðÈPd “˜vÌšjgá$ ‘/袶0‡2ñ%Ÿõ›eÉ3ã1ãÙ%VΜ97Ø€c·õnëÝÖ7°i`ÓÀF]£®Q×¼½½á Þà GX½ŒË¸ü›ïìOÇtLg-mf³€Y79orÞäñ)ãSƧŒpá<¹sxçðÎáÝFuÕm”C ‡-æöœÛsnÏœ œ œ &Œ cÂÔ&jµ Žã8Žsuû÷˜ïšõÏR_Øeö` Æ`’D’HOçÓù¬ÈþÈ´“i'ÓN®ž®ž®ž­Ú·jߪ½÷}ïûÞ÷-[¶<ÌßËßËß›1,cXư‹ô"½Hã·Çoß~+ä–Û-·²eeåeåø B¥“DDÊù9ç真UñªxU§ñ4ž]袕ÿñÈMê‹ `@déFº‘nj]µ®Z‹°‹8ì ¦‚©¶¶¶:*t”³µ³µ³5~Äø±²¦²¦²æÆä“oLŽÏÏÏ}°êÁª«^wõ)Ì#Rªy?ºÚÏEË»U¸¹ºß6ÞÒÕ@9ýJõèÕ”&¼ïBéÍKãÚRšpo¼vFÆÁ­\–}Ñ1Òι›µ¿~ïOžëGæ49†æÿóÎNí:?{-ðZà5?ºitÓè¦ò®ò®ò®ò…ò…ò…Që£ÖG­wV9«œU¢(Q”(ê“j:ƒ38CÂ.ŒÉ.Â.Â.B>B>B>Bþ\þ\þÜËÒËÒË’+Ï& `שõúî_nï¨N­G=þ³`çVICºÐ•\\\`åÙòlyvMM ' ™‚¤pæï3<ó?í³ýxýxýħŧŧ fÌ6˜m'°Ø ¼oÆ› „B†††ÑÛ¢·EoSìPìPìPÜRÜRÜRœUœUœ±Ž±Ž±ŽiÓ(¦QTHTHTHãI'5žÔ0¹arÃd7¾ßoîfîf_{¿ö~~8?œÎ1õÿì¡u‰.ÑåÂ7gaf1cò¤Ð‚–ãÐÙÔ¤`÷ÉW#æRšp`ÜÝGs·­è+4ygÈ×NçÎpƒôGÖö–YxÁ ^¿éph0¦Á˜cäÉòdy²|¾|¾|¾­½­½­=÷S ‘ ÷«¯š’Û° Û˜&„á¢/^ox½áõý§÷ŸÞú‘Õ#«GVw\ÜqqGçé§wžþI¥ö!}Hî?ÿ)ž7kŸèBºp \ȲlàéòtyºŸìÀt`:Øm„6¾ïû¾ïû~Ë´-Ó¶L»–t-éZÒó>Ïû<ï“ð<áyÂó}ê}ê}êq‡ÇwØó çAσ#‰‘Äè“gI"I$‰¬&«ÉjÌÃ<ÌãDÙ>pXî°Üaylululµ[¼[¼ÛGJöª™ó[3ƒŒ!®ìq¸®£¯õô’ÓµzW…Ï\ÜÇ’Ò¹y03³Éî fJcrƒôüƒÎÉŠy±a=£_~5ú5|EøŠð2±L,Ë/É/É/ ƒ…ÁBi©”3sI%ÙM‚ùÃy]>5âYtxëdpJ´àV›WuäÒ€Q ¥·wŽÿ‰Ò›=Ç™Qg\AYôÙýÃãWî97êšßX§½&£¸¿ä œ»9Û8Ý‘m”!:JÑL!”—õ”õ’õ‘UÉ*e¾Y¾Y¾Yúïôßé¿ûä¬{G3òý;|‡ï ƒ 2Á5Á5ÁµÆÎ;Ë&È&È&Èle¶2[ÃÃî<»¬®Ç—;ÞÖîõ¨Ç_Vƒ àÐÞ¡½C{ùDùDùDù`ù`ù`g{g{gÎŒãHŸtKðÀCs4Gs–M¼ˆñÂ\Á•|Y–¹.=(=(=hñÞâ½Å{×V®­\[ùfûfûf'''ËÖÈÖÈÖÄèÇèÇè+¾S|§øNaþ?ÖД ” ” Œ...™25dª§ÈSä)²;fwÌî˜Q™Q™Q™T HL-SËü—ˆq2öØp‡Þ!é„»/¶ö~I—Ü.¯Ðétû‘ó|ÄNåæWHãÏx1+I- ƒ:ÐùbÞ²¦…Œ`s¡À{C{C{CÅDÅDÅDÙlÙlÙl›&6MlšpåOáNÁ†0üƒ³}‰ÐÔŠi†fhÆÉÉãý­Î[·:¿(wQî¢Ü{sî͹7çÖž[{ní‰333—ttt`K2]™®LWnÏŠÅ?oÄkºÁ/ø…$“d’L,ˆ±ø}qÓA¦ƒL±Ëéyç]œwñRÂ¥„K ‰ïß%¾KMM=™|2ùdò´–ÓZNkÙ¬¸Yq³béuéuéõ?¸x&“Éd2ºŒ.£ 8Àá“ûgïmF`œá gC:‡tɽä^r¯°õaëÃÖ   r.Qvi÷UgŸýsªL?죿b p(W¬Y^{L™®zMó#”¤Ìõ÷‰Z ûs?è WØà¶Æ[q,Û5máŽÆÆÆ>iû¤í“¶žžž¢ Q(Hë’Ö%­K¾|?ø~H™š2%eJ±VqÏâ;*µ!±&íƒ-XŒþð§¿RL<:â†ÍË‹Gq/£æù¦ZŶj;ÝçYÇêˆJÇ—¢B)_tYûŠ.‘l^‚öö|»Î­Á¥%zf>·í‰eåãt§Âi仪å5YJž$\ôš¨ÊU®³õ2ýþësÙ²›d÷¤Õ´ŠVqÓ k²ÛÀ6܆Û¤â b`A]T]T]TæÎÌ™;]O»žv=ÍÖ@Ïž <‹÷ï/Þ¯NU§ªSÙhk.°©õ¨G=¾M°3;®žÇyœg˜&À¤Ø¤Ø¤5¨Aržržr^ÎΜ9;¹’¬æ·&e‚ÝÊ?û?ŽIÁRYqI6ä‘õÉ=ÆcÓ™þËô_²ŽfÍ:Úýp÷ÃÝwéÓ5Æú¦õMë›ËN,;±ìDVÛ¬¶Ym™nL7¦›šª©šrûQ¿gÀ³×bÍâ:Ô¡Žè¢Ãôbz1½TmTmTm4YH¼¼¼~3üføÍm”m”m hÐ2 ¥gµgµg5ÝQl_l_lÿ ûAöƒìóÖç­Ï[?==½Îÿ:ŸSgb‘ld“•d%YIÇÐ1tŒ:TªE)JQú‰»&Ý…ÝOKCÒ*¶Tl©ØRìQìQìaÐÝ »AwãÓÆ§OçTçTçT³­ˆ]}­CæŸî¶t6¶ C ÌžXúºüaUMRYN~¼^Ÿ‘wÓZ†BWC)diPú?o[óÍ¡Elˆ 1!&ĤäDɉ’Ig“Î&õL÷L÷L×þ ýAûƒh½h½h½÷{ï\ïÜg›žmz¶©`HÁ‚!ä$aÈ šM“h ž!˜J&”´V?W¥ú×ü“ÜÞ…]CÞa‘ÃãócL:·ö?Ù$!ø…íwVN¦ÃtVÍ0<©e÷šíòðïp>ªsÝÒë“s?l>U÷`à‡ÕçßÖz9+%ñÙÅÔ@œÆ6t$OHÜ"«È34¢è*h¡P~²ŽÓÈšÆN9„A”Ó)§SN'óÕæ«ÍWëõ×ë¯×_¿P¿P¿Ðd“É&“M¹Wr¯ä^á,6œâëàc±™ÞØi•MYe kX³mÈB²¸çeCµ~ßNêQz|k`Gvb–B ©±—±—±—ÄTb*1eÍ‹’ö%íKÚ—{—{—{s lÎÔfô`õ^Nj|XhzÙ”L¬á4LÃ4âJ\‰+íL;ÓÎÕøŸæ–=΄3á‚A @ï©ÞS½§úûô÷éïÓrÔrÔrˆ ÄÂa‚0ApGpGp‡WË«åÕjùiùiùi¹h¹h¹è¯×_¯¿^¨¾§¾«V©ÕjuÝ÷u]ê"”¨Ó®™ýÒðµ×»Šw÷T‹ŒÆTÿd`ç^ T¨V«e²Æ-o·˜Qxà₤ož?³L‚tb@VÀÑÏ;Dõ÷ï5"Á/ø…›¢…¨4Ó4Ó4S6Ùf Í@›ÎOŸ:?e?¹$—䔡 ep…+\?IÜó%Î)š÷,…RêC}¨‰#q$®vpíàÚÁkÞ¯y¿æý» ï6¼Û0´ûÐîC»Ë¬eÖ2kV“gÙÉe'—¼ÓúNë;­™¾L_¦¯ú‘ú‘úçÑgë™M 931“Œ #È–ªD=¨õP­U­U­%È#òÈî¸Ýq»ãa†a†a†òžòžòžoÞ:¼5M0M0M¨\W¹®r]Rû¤öIíT>¨|PyÞë¼×y¯— _.|¹°n`ÝÀº\±f¬kLÄDLT§¨SÔ)°ƒì(¥”R,Æb,þ¤þ,Äö.îâ.â!ªýÕþjÿümùÛò·™†›†›†———äøåøåøA:Ðô Çé~Cˆ€  Ñ•éJ È//.ÎìØÒ9Ò~a”.X0pËiß^ b9ò _ÂÉdèC âêü HGÏÏÏ X°4`©ü‘ü‘üQôÉè“Ñ'#EŠýÐý Æ‚áxçFƒŒ Zúa釥[%†&†ÞZqëÉ­'£Fl;²-sóO)¹,Ù Ùà3Üg¢ÏĉeK&–hw Ýv÷U÷U÷UÏ ž<3¸¸ê⪋«6wØÜas‡Ž5k:ÖXšYšYšýÁ f3ƒYJFb$Frûí¿§ÿ>ìa{,Çr,g©n¾Í}›û6oæ×̯™ŸeKË––-¹’¬ôê7“’é#x`ÀcHÃN¸Àg†ôslÑÒ9Åý*©j®e¿GIY#];ˆõ›J½$ÜÖ!™Š×ÿœ7â“×Éšàl#à1<†çVëVëV«°QØ(l¢vDíˆÚ!++ëøÌñ™ã3.º\Æ{Œ÷ïihÒФ¡‰\.—É£e1²–²Ž±Ícv(îF <ñØzµ­Ÿ] R½SÒ,áÃñU]WnMüqó¡n)½%§¤ôÖò¸¡”ÆgŽSSzóɸïîŸûé‡îò¾-”žOÌ×ÕúdeO: 61~d/*±ƒÎý!ã0–=ÔÕÖÕÖÕŽ|ù4ò©¬§¬§¬g˜|:øtôˆèÑ#dQ²(YT“#MŽ49booÏ Clüר9ê ÷zÔãßkÆ` f¿°µµµµµU8(ŠÕŠÕŠÕ.]\º¸pG/4€ >»gù½·~,Æb,;Ê‘0FBÑÐ ÿø¶Ñ¦½µMçF ìæWØøô¢ï‡QzyÈ€±Y½rœnv½}RJﵬ;_+y¶•RJ·ÅLJćˆV …B!´P ÎÆRG~W_ 4µVXe߆o÷ñiíÓÚ§u̘…1 ÃÂÂô‰>ÑÿøŒ,êÏÞË— òÿïí3ÙL6“ÍÕL ?…Ÿ2Ò`äÀ‘o„^«½VûH÷i‡§–Ø9wçÜÖ û:ôuhݹ+úk×lëŠmM¶5‰÷¸Yv³,©URç¤ÎÖ>Zûhíö%Û—l_2^à-r>øU=¬m pâF}D½JÚQЀZw£¸§hYñÕ ~¬$í!ÿ§èeš¯¼z VaV©¨¨<ïò¼Ëó.ª‡ª‡ª‡6Km–Ú,Uå¨rT9öKí—Ú/eV0+˜ï]Þ»¼w±e;Ëv–é2Óe¦ËpWq•&К€°…Í»šlUNqfÛŒ ËrUÅ£Š3DŒe@I« ëZÿ¥ØûØvJ7YÒʳñ}{§áÞí£|K?óºcéŒüÎLÇ€¦ž ¯¶4õ,±xœZY`¹Ëã\—”ºõ¦ÇKO(ö(o[3„Ý1„yCâ 6 ‚Ĩ‡Q)]N舎¥‡K”É?œ8ÿ°E;‹víÄCÄCÄClÙ.²]ôb‹ /&p¡9ìjò5^ãõ_þæYÞÛ0 Ã0rŒ#Çè1zŒcÓSc7vc÷'åÛ¢-ÚêÔéÔéÔn7Ün¸]§R§R§R+H+H+H¢%Ñ’h \®WšM³i6ÙMv“ݪªª*ª¢*Ê_È_È_ˆØˆ­žÝ^z|›` –‡º›±™œ'çÉy‹õë-ÖÓ«ô*½ª¬SÖ)ëòÌòÌòÌ8O*;b°SŸ4G36¾u=Öb5«!FÐA4”ÿ÷žìVTr‚Z«Å¾ü÷#f¶›ç»t˜qûU¾7ì5(7ü¨HPӲƵΤN¤|@QSêDŠpV*sª¦jqªÈNdç^à’ï’ÿ¶2§4§´pXá°ÂaœàKb|…Wxõ…©ž³AƬs‡]ÔíÁìQöPöPöHé“Ò'¥¯5¯5¯µ‘ޑޑŽÇU«W“?$HþPÚ¬´Yi3ŽXâG8jÒK¾`pé`À°õÃæ4 —È%rIé¡ôPz°~¶oRSÇ͘7eÞ”Ãzö l÷¶×Ô^SÉ>PíÇŒ)Š~pèÁ¡ÂWyCò†\̼ôàÒƒ ]/´½ÐöÙ¡g‡žú0áĸë¶@ ´ ¤‚T°ûKÔ†ÚPÕÕÕÎN`[WêP÷70XñÇüù òØ·;ow^7D7D7Äe¬ËX—±\Ä2ëvdã¿"ü ›¹+#«¿0Uô8íK¯éðEÇ„ë K¾MȬÁeœÁ%ô'­ŽQÿÒøÀ¾ŒÑÑ,‰‚^¤éÅ4ã4ã4ãÚ÷µïkß;88(]•®JWë9Ös¬çX\²¸dq‰ššZ}O}O}‘0FR~¡üBù…Œ—/3^æ>È}û€»Ê[d #Ͱ“`Ã_Ã;C6Ç—?®qÙÿ«wê“÷®tzñc3» ÅvOF“Ž&~Nï|í­Ú -ulD†nbû½F5ó¢†&G´õ¸£§¿ñÖçg‡?³}æ™iO¿{±/˲ØÃ0‰‚¹É˜‘ô£ãQ«N§}é”Ìõ™W2?'''ò'ð'ð'˜9™9™9eGeGeG•O*ŸT>‰ÛbÓWýûƒ,ë—b3Âj†Š²ß°CÀLÀîRD _Ÿ¯Ï×MMM—6”6”6Ô/Ö/Ö/Ö_­¿Zµ¸Ÿ¸Ÿ¸/‰—ÄKbŠ™b¦˜Ëš6C1”J©”J•~J?¥_ùôòéåÓ…O…O…OER‘T$¥ëè:ºŽqa\Ž«ÊzÜÿάoõ¨G=>°ƒÎø?°û{aaa’»’»’»¬÷®|Tù¨òQÅ‚bA±€ hã矧ª™“[!ø˜‰~hLš’*,§Át¢”5ªj*Ö[&].<Ú½yì"·Ý?xtmXjG­S ~È%t¨w zÆ—‰÷Ç\LH3^dtàT[;£ «ÎE›ê6.]ÿ.gI© ,a·z¥l¥Ì°‡©™©™nˆa_þ©?¦žI=“×"¯E^ n¿”åïÅ^ìýÂZˆ¦ðëÚñ¯œ«œ«œûÔæ©ÍS¯^¼½4ziôÒ³‹gÏ.OÒž¤=I+·,·,·äò” âZË—î*Òœ%@@TAlT/?‡?çüºKÃ. £Sõ·ëo_s`õÕÙ©5-jZð‡òOñO©VÉT²Õ-–9/sþ5ô¼è¼¨Ð§ðUá+n§ÀÄĤî¡î¡îÁgÓôý€¸0SÿµÊ^‹ÍI\€ÔÒZZKÅOÄOÄOêÂëÂëÂUö*{•=›òì3]äÿÛø ÷Â„ŠœšRàlÕ'èV#i#8Î;¯sV´Šß 0Ì…œKŽpù_~¬Çjî²É5t¡ Ý ó ó se­²VYëäâäâäBý©?õg¥ŽTZ*-•–úŠúŠúÊ›9oæ¼™“u*ëTÖ)eKeKeKnÍÍÄîð„¸ÐKðR©R©¨ YLÜp˜´%”¬¯sUVÏ>‰[‡Óq·~¬ùÁãí¾ë>!¶ÆÍ¸ûE‚«”é)Jç—›ù˜4ÐÖ™Œþ / ZÓÒÀ‹wbtüðW/7ÏÿeÍ“ê»á©¼\/88Yõ¾Š_ñ:G³'gªmm¸í‚ƒ‚ý‚½ Î78ßàÜSñSñS 7ȲÛÇ,c웳šk¦À `“ÐUt]ÅÕä#<£ߟ@¼]¼]¼Ýp£áFÃÚs´çhÏÑž®=]{ºöíÚ éBº.ä¦ÌçxŽç\dwkukuë*—*—*—²e;Êv”u.ë\Ö¹âLÅ™Š3…΅΅Ζk-×Z®u{íöÚí5MGÓÑ:³tféÌ*Š Elæ<îyÿŠ|oõ¨G=>7°£;Ú³âŒqˆCœù{ó÷æï™vL;¦>à>ä:ç:ç:sÑ5ÝÐ ÝXÉÝÏî‰àƒA”PãtECÃ4%íTÕýè4:‘ʸ‹žbžºñFLïxÛowÐ8ï1–TI;dy¬ZUg´·âbFê¶åú?(Mêø*¢À…½HÉár’:?Û1sìÛdcc;c§²SÅï‹ó³wçœÍ9koo¯k¯ë‘ä‘ä‘$QJ”e?ƒŸñq~߉ØÉÍ_Xï;k¾³± oñokmjmjmR¦4Liè“î“î“®g¡g¡gáõÆë×›ÇÂÇÂÇÂÊ•*p´ŠP„"ô«êG¬‡[D˜˜ž° ™FF‘QÅ KâKâ*ÞÞ¾¯èèôWÞ.Þ®ªkj…Z±ßd߃}ZL‹Y8f 3—™KïÓûô¾j»j»j;~ÂOøé3]$³Â‘,b ¦Ú§Ú§ÚóºòºòºÖ¦Õ¦Õ¦qý‡IÙ¾Þ1öÞ|\©÷û)¨‡'(û¨ÿÖš?>º:ç^ÿÚVÃ<ÚØq[$¼,¦ÙõÖYD ¸ŒË—fÚfÚfÚ±±±Mµ›j7ÕŽ’EÉ¢dRc©±Ôø“ó°,mv+ö]ëãMa F |ÉK2 ™Žä:‘jiè1Ó|ïîêi—›]*rÖ~øJž£ôVß8¥·{^¼í¬xxŸ½Ë§×4ï¶×ÛËr±pÿýG.šèŽè™¨8bMøÃ°‡²Y”¬qô›èôè—†C±áÇèì?›œØ0 6üÈ–°äR°‰H^à^üÁ# È¡ÐGècØÑ°£aG‡×¯^888†Ž:Zöì;Ùw1á1á1áŠ+Š+Š+ŠÇŠÇŠÇŠ5Š5Š5QO¢žD= ïÞ-¼›_Ž_Ž_Ž­™­™­™ž©ž©ž©ð„ð„ðg‚k–°ÔÏÖÏÖÏŽ12b¤¢¢¢çõg¡™Jã A=ǽõø·ÀÒ9à6{bã·ß6~+""¶ lAØá]á]áÇðwÖ#øùð•ÙûA¤@@“¾xÀ¸’]åçxO˜±äÇ–­BØÝ½Q»&½ó{Jol;‹Òø¤qjJæÇeÕ¾¼~Tʯ{–è0:â°Ï4ËOBZyÙE¨ÂfœÄºŽªàCcqÚðŽ0 dê‘z]}{NÊÌ÷Ýo‹Spþܧ›ë׳ùUÏ¢Ž’¨yÎñ–?Yÿ¤Ÿ¡×W×\<¸šy,îVÓØÕä¢a¢(³ßú…ÇÏ=æoycýKýÇö)FiO/úóºÎkÌl&íÒíF6xUü 8¤øŠú­ºP]ƒïð:C Z¿I’}À|àÌz–÷Nã(JR·P·P·Pç¥ÎK—ºR]©®Tw¼îxÝñ‰@"(E¢HÉ!9Üòfæaýþ@¨º[u·êneJeJeJEMEMEMéƒÒ¥J¼K¼K¼«-ª-ª?Í£ÖmÑ–=Lˆ 1a™ú¬Jkù°òaåÔ‹”‹”‹„›…›…›µµµ™öL{¦½z­z­z-ÈÅ>]=êQ¯lg£zÒ‘Žt£r£r£rÉ+É+É+Ò„4!MòÃóÃóÃkÕ6ªmÄ™ì7q7ÿËž?MÏz?4‡ó–ŒÄcõzZ†ÁÔ™~‡ lZô Ûº¥]µïÅÖ'C_Ú»Lf.@ÒÑ EP\w+ýõ‹•C_|øþt`›×*À*dã2W˜Nä–ÊG%T—0G˜«L¥ª£ª£*ðùåç—Ÿ_ÖÒÒÊ×Ê÷4ñ¬õ¬%OÉSò4%?%?%¿üTù©òSAAA¶ […­B2V2V2öYÖ³¬gY5Ö5Ö5֜⠛_öK;§³ó`! QXiTiTi”¼;ywònï&ÞM¼›è%è%è%x†{†{†?îû¸ïã¾uvuvuvœ~Q{´Gû¯Š¢Éö‹óÔˆ!yÈ+ÓÎÎ.šñhÈ£!ùyó95¤zHuNÈûÒ÷¥¤Œœ"§€y˜÷E>¯æ>€t CDA¡î.á}BŸÐ'ß(—œGÆG»ï ‹¦F½)×¼VÅÐ颞¿ÒÂ%ß ùeஆ— ¶ ¿–YCþsæ—æÊ˜M¡/¯ 6~ŸMxûûßþßÀï·3ÀL´$ ¤+î£$¿jtyj#Ö/˜Éô3 Ù”1ï çsJã#Ʀ4~ø¸s”Þ’Å5¡ôºÁzý‡Õ»:Ýì±46Ç=«‘KßkCjʢ·¯Œ£(³ØdYcÆ›Ë_ËŸ#°Z ±ûðÝŒ]!L0¤›©›©›i›l›l›ì5Ñk¢×Ä « « «èwÑï¢ßÅtŠéÓI1B1B1BÑYÑYÑY®–«åj™£ÌQæõ>ê}Ôû A3‚f8¼sxçðÎx”ñ(ãQZUZUZUdYAVüA4B#4â†XµÝ¡Š¡\H«æª]ƒ3ç7Úo´ßhyŽ6WŸ,y¢ÝñP”µó¡Úõ>Ýè·¯• žñC|áÔÍ`‘/\¦­¼uTØhà“‘Õ33³–gOcz¨TªýéÝîŒWvÎJÎî­N–>©V;HyBÝ–&PË*ï:_ú +kO+¯ã=îÓU1U'«tжõ)úPfZ¦*+¨hWq²Â¸vIõ÷Ç1€@÷<&D¿BÑ1¶HÅZJ=Ò„ñ%Ë0ȉ9Ž…ØGéz IX‹#xH×ã8cÝŽÛt ~¦ñÀŽÈp€ ½Ë„e-KGAFfÀ0Œ—¾P_ Ï«|«z«† l`Ãy빬âõ¨ÇWM³€ÍzO㣉38ƒ3hÖhÍ…å}MF<;>³=ý^à…ùó æÈh2šŒ¦.Ô…ºŒ*U0Š |G2’‘ÌÕØßóŽà J¨É â…cäNaêxêH—Ñîmt7 Ýn¨OIO·&Üë[¤kéªóêwý^ÜȘUøÓú»Çú?^°§ðW§ÔĂڒ.U)øÀæcCÂÕ>ê­Ô_-RÇÒ5W¾uPýþÖ8Ý6¤ iSp·ànÁÝ÷÷Þß{ÏÏÚÏÚÏڡʡʡêÞó{Ïï=çŒÑ×x×%ö%ö%öIo“Þ&½u÷r÷r÷2œi8Óp¦—•—•—Õ‹/F¼ñÞþ½ý{{î2Ó0 Ó¸Œ",žm_JÏb»“‘Œä¯¯¯”Ù)³Sf{õ÷êïÕßbÅ:‹uªUª&uTê¨ÔQt ]C×pºF‹±‹¿`Zë&ÑM†’¡d¨C”C”C”’Q2JæÕ¡W‡^âÌxƒ7õJn_:þ7Ãý!ò?zÍk¦ª<Õ†EÓk¦×e%¶‰\@ÕÕž¦Ë´“%¶H'‹ÈrêO'Ò@lF_´Á\û*묪ߚûS¼Æu  ñ°C,ÃpD0®ÌvRVÒªbsmÜÖ«gð‡¼ú6íGyQ`g›Ž#¯vXà×1r˜OŒÅ!þ{Ý=ºUÒ_'µs#€Ð¡˜ƒ:s$ƒPm!vûflm{þ8骈š×ʼ2AÕ4UvéÛʜڥ…GJTä6ø°º¼[~ć֪vï¢òÌDfeÅ*¥YImÅs^ë"AÙCqãR¿Êšº}µÝ”ÇU]ê”Pï©ë¬l¯ºR— ÔUo¯¢Zª®­S*›©ÓàŠ¶˜L9§g3HØ \Î~p„Ïo¹Ñð1EìÌØm8®ä¼ò%åƒ+–S õtÕU¾Hp„ßHëÉ8±½ð’à ¿TµPuRµ1+i:‹± i"ŒÍ¸…ƒôRé÷X…«Ø‚ÓxŠjÔBÅ-¢jP j¡„Š;®B-”¨EÔ¿•©ûí¯êzåøzüí`»ë_?‹³8ËïÂïÂïbæoæoæ_y½òzåõânÅÝŠ»Ñ´m\ä"—ÛпŽë¸ÎáËhY‹%ÉÅQe£qŒæÍ3šÇJ(w)w)w½ïû¾ïû¾ìv?GÃû«—.<ÎÏM@Ð Á°çI™–¤£j¬z mOG óM†ë´ë×ÎØwþpQÛ³Þ»›Aw òVÿ4ÊË)̯ˆßàxbóãšukŽÉ“¶å/ÞXµ“½³Š”Gõ#Ú™JÔMÔ7é=”  â9ûŸ˜ìØlwÈr§.¸.¸.ø™Î3g:²S²S²S94Âz¬ÇzÕ^Õ^Õ^NEíà@•M•M•Íã /<¾à¶Ùm³ÛfsÆœ1gÜíÜíÜí$³%³%³_¿zýêõ+ÎdgÕßa}æf«`õÚ£…(\À\(nRܤ¸É³+Ï®<»â9ÇsŽç«>V}¬ú0vŒc—Ò4¥iJSº˜.¦‹¹=‡ƒ8ˆƒ_dÿbãFøàƒÏ+âñŠl¯Ú^µ½J¢?ÑŸ^ľˆ}‹ýØý,áªÞdÿÒñ¿îÉÈEËî«k£ªQ?)¾PTëBtψMQ«ª»VhµCäÀOä;Ö Ž©ã£!l`öMÔåþUƒ"¯Q€)Ø‚[êu-U‘n„õ<¦3éW:»Ò¦Vr|ö ¼º~7n¿ZÓ¡qöÍû´Šón;Æ{YÅÉ*]R$X*g定ä3*h¨P¥–ÔZiKm¾µ4 Jõ#€úг­D]ÐVˆG:š“Õi@æ$ŒLDˆúuCwÊ£1JFSK=+-jF–(ïV[Uú¢²emp±u9­É(ý¹bbMVñäŠiµ}ÊøWjJƒ*gÕf–~_1¶æE™º²EâC§²‹Õ+’ªw×ÙU«.R¶®ØZý¡®EåÙê6Ê9åk«.×®+Uv©íR)­Ù¡|TaQ5µîUUתæÕ#ßåÎ,JÔQë© öÕ®Qöa&׎VnåÙÔ_YÃÕç•J0ÄîHÀ¥ø´ ÓÑ È&ŒC âH;ø’uˆC ¦ iD&’nhHŸ!…8Cïà öâM¥'q ¯p‰x‹«xˆL¬£Çñ˜^D"2ñ+îá öá2Òð ïPüÕéÔ㯦¹ÉF€ôFoô&wÉ]r×]ß]ß]ßÌÍÌÍÌÓbZ\(.Š_F¾Œ|YnVnVþqü€ÀiI­ÅZ¬ý"½ï”¼$/ÉKšA3h†ñ^ã½Æ{Ååârq9S¸¶pmáÚš53jfp4HVÄö?û¼šJbj¨AI0ò±ˆÄ ²\=›ÚÒW*¨ãébƒeÚ•¢ŸZµ:åõÓØþMýÍ-[8ëÅ@­ÔWX÷sóz—ßÚ¡wnnÊûµ¦GÃmϪÊÏ.?ƒÈxñL*Ù­Ž§©T=šjÓöWžu=üóàÍ¥¹4—%¥ÎOŸ:¿¬eY˲–>Ï}žû<×Ý®»]w{éÍÒ›¥7Yú('˜‚¤° zž¶}ÚöiÛRCjˆíJÛ•¶+8p8 .‰‹Ò~Hû!íVH€&nŒÆhüíùsîq…(D!'™„$$úúú¦ä¥ä¥äy„z„z„Z¸[¸[¸«Z©Z©Z½(~Qü¢X½O½O½ó[‰ù¼Wb%V²É†Ìû˜÷1ïÃ*ÈUÍ®š]5û列#^ŽÀ$LÂ$®~êñ…ã3BR1à†EØ!ì PòãKz®h:°ùÏŽŒY*Dêëêïï·Éû¡ì ¼ÝÏ=O-/T•VÓ…ã'L¦yôjîþ}ƒÈGÕø`ˆžãGœ#KÐ÷! >ô;º†‚lâ×_ÞV'¬q”|¤ _¨p¹óòvz½r&Vê{1: ¢üëä")ÀÒ‡±gö¢œ3Ÿ¼"ÇÈϤ`:“‰!»2 Oæò kI1À´'·Èà` $‚¸h or¸h€°Çì¿¶0H9Y¨„êÞ@íh¥·²oÍU¿êìÚ“ÊÕUµjÕŒÊÖ57ëâ+Ó«'(×UÔš¨VUï®­t®Î®MRNä7úKNÐ`²Að¡Ø©rвîuÓ·‚÷Ír–æU(-®Lª]WVñ¡vv‘yYßêÆâqõ´²>•Fµ~ùMŠ®[â]‘S{@£MÕ÷Ô­i9Í„æü%o0›Ð“9Gº’;Ls””ÕdšÐ¾t-îóÞñ®1WU—ÕétÕ<óùXvvêlÛÙ4N'®$®æÅ/Š_xGói¾*XÕXÕÕõ*õß$XÊÁÜÁ4DC4´a3Âf„óBç…Î UkUkUk‰ q!.Ìff3³¹¶Em‹Ú¹L.“ËdÞμy»fOÍžš=Ü bBLˆ 5£fÔŒ£‘|)[Þ,[Ýžð$]HÒÅ»§wOïž&Þ&Þ&Þô}FŸ% H4 pMášÂ5ØŠ­ØÊ™_ÿ)Â<0PB5t¡o*³‹,RMTw¤cØ"â7Â=¼÷C&µ™å5`m«éÞ3¼œÃLöê[ôÀœ'J¥¬Z¦\³‡^2~^³°f÷Ô»ÝSog>)ν£k¤3naÝŠú.˜×ÈA ç×g÷üþoø¿àtB't2­1­1­ÙÕwWß]}õžé=Ó{ÖåH—#]Žd8d8d8¦¤)iJOÓÓô4gj³â ¬¢¹#áh-±–XKÝÝÝ]]] ‚ ‚ ‚S3R3R3ª…ÕÂj!1S5US5jQ‹Ú/Æ|gïÐ NpâÒ0E! Q¦#MGšŽô8âqÄã¿)¿)¿iÆ–Œ-[^ñ^ñ^ñØ4ŽˆE,b9ÿ=›Mås!‰$‘$Ò@HcÇ=>K9K9K™1!cBÆ„!¯†¼òªTP*(pÊ{ÚІvýðüåâó¸'!0ÊÚmÊM*ã¢ìªÊš1Hgõ{å2Z¡&Rò "˜Ì<¨¡àcè"ï®WÍ­J¨i:œ1 ŽT™ØŒ#ô8O›É"' V4Õ-x6ðÞô{Jž’§Ë++zT\Pœ©»›—Â{³xÄTÛ«_¬y wÿºà´` ÀZë‚h3ÇP¬s@<]¯‡¶©h¶Á:&"‰ÁfEâ‡úÖÚ.¢xƒ3ÚýDí é®OÓŸ§&ºk°Jç¹øµþmoáñná`þÑ5„÷JÔN8‹÷JÒPèÉ?(ŠŽá¹Šátþ‘ ÏQd#Îsã7vçÙ‚¼h@ æ$žÂÑüí’PäjƒÞÃ!m ‘fÈÄÃ`лŒƒ|·°PñT€ú´z@3‘ „ø›X#\Ý€vÔ~t§ºTíCmT|u<«šªê¦^ ¢a´Z¡òP7R™«_ÑÊ¢õ¥j®t-y_UW2£âjMvɈŠîµ¾E1eëªß,*9]•Vr¨BQ{½@»duÕ»âóe'kªŠš”O©¹\ޠʤŽWósídåÍJÝšvÊ5ÕOk+ÛU/ª¦zYëV—¥Ê-?T5»ÎPå¥ÓvjÐ!êÿ‰RÞ]èvöç|¢ÕòÒ!¥û˜Iª£ª§%' Öªº( •…üX~,?¶Þdÿæ i:°Ù+¢!ê¯Ð_¡¿ÂÞÂÞÂÞB}V}V}–5 jkkÅgÅgÅgÇÇÇl^Ú¼´yivÑì¢ÙÅwï2Þe¼kõ®Õ»VµOjŸÔ>A>ò‘Ï¥\aõ4R‚”Ï”‘ÌÖÆTLÅTÖ[¬³Ug«ÎVý<ý<ý<ú†¾¡oJß–¾-}[ú}é÷¥ßs‰ä.â".þžH3Øs*z#ˆ„’,F(¼`¬ÒQw¤Z·DYüm-®‡”Ú/œÜ³§g£î7<öšoP‡EãBN«’êòÔNôº¢›öaaÍž°{=ï½xn”ûà&¯ŽÇ'WÕ­Ueô¢„B‚_ÀG5j ä®þï˜ì,Xv-jQ›ß5¿k~×Ì^™½2{ùøøxNñœâ9%Ã:Ã:Ú[ÎÏ ¬À ΃n+Xe-ÉZ’µ¤Î¡Î¡ÎÁ¹sç6ƙƙƙ¾u¾u¾uφ>úlhéÆÒ¥±[°˰ ˸t6Ÿ³ù®yW/ñ/¹ÐÕ4¤!-Ï9Ï9ÏYP'¨Ô9p:átÂò¦åMË›63lfØÌxVø¬ðYaNENENiH’†4&ЄÏz´a÷²RI*I¥nÔºÙ]¶»lwYËRËRËòͨ7£ÞŒª´­´­´åzÓ—Kª‡þ7Ãý ^â-ù ËÑŠêÑ!Ô17³,·R`„Ì}¥)mJù†-ÄË„]DV¼ ¦÷«@˜Bï+e¸ÿ_ÁÜìj ˆª\}Œþl8Ùà;ëycšŽ~þ:*}æë…Y¹ï§½Ÿ¦ñË8tÂr  µP¡@Ü{|èS tÖ(5ä“«5ÚOþßâ·#g4Àv@X"°g2µ%ÁºŒÖ=¡J{«ÄP®c¦• |+-Ž0ÚÛ$G"íV’–séÉQA•¾»¶ƒèƒno-¹¯ó^ËTðTû„V{áuu’aÂz~ÒÂíú¯µÛ‰íÙZ „[t’$Ù›:Wµêgt¥§D³Èw‚…ÄP¤/Œ¦–oo+ÀˆŒ. ‡ tÇ,Á è‘Æ1…+€nаSMÚß;0`müŠòÀ`"|a @=«a„`èÁ@3èâaõunÎUÝêV”¯ø±vkyUÕ»Z¯ŠAÕo•*j×.ºU&¨ÙSQPýCÝúÊ êUuÚeÅ•!uKË+~¨}Wܸ²CíóòêâüÒÅL¨íßÞÓÛ´n3¢L×ðª¡ä;Ãq×Ú6;ìjØÕi §-œ†8‡´ê;ÁWMƒf&fb&+™*²Y‹¬ÝBÜBÜBx7y7y7™3ÌæL†$C’!É9s ç€Åa‹Ã‡-c,c,cø»ù»ù»ýýýí+ì+ì+L~5ùÕä×w‹ß-~·8; ; ;€ö¤=)'·Êå3nhWx…WŸ‘iÅJô²F'5ö0ö0ö8 œNì7… ¨{S÷¦î á>áÓµt-]û¼¢ðP‹:¨_Xñ>0 I3UŽºÞ¡MéID8 ´s ßêøý8YW×ÀuÕþ ­·a" D$€Ýx„_•WÕ“NϾòúê†îÇëœ~’Püúà'”â&1“ŸlP¹¨šÒ6x J9ƒ¹JÃdÿOÍt1 “0‰n¥[é֔ДДÐFûío´¿áˆ/¾<óúÌë3¯†0„}²ö–Ã&?ó8ŸÛ4·inÓª¼ª¼ª<÷!îC܇èèèx;{;{;§ìOÙŸ²¿¨kQ×¢®øßã{ŽÂÄ*Áþ»=šä™æhŽæD‡èw‚w‚wq¸@\`ÇØ1v ¯¯¯s¹Æ\ã„§á g®Æ>g°‚ž ( @ô@k;k;k;­%ZK´–¤õLë™ÖS™¥ÌRf1ÆŒ1c¬Þ¨Þ¨ÞX?TùSÍ?†¬`Æ›Lv;U?Ú’&Oˆæû…ͽв4øzUVé…ÊF¼ þ$^çnËwêù°Ä³ÂˆlÂSl§Cà‰¾õUü X–ê¬ÁQ¨(Tp5àvÀm­³Ò¥?>šühÒ£IE‹Žaæ1í™öªëÊJoÚœªiÌ` + ´IOÄÂmIÑ Ñp"Ý €:"‚8 3‰‚ é…&pG „Á}О¨@5Ôê%Ԗн´ê?÷v_rµÂ%‚7¼¢O)èÏòº ‹Gxïfü$FO;Vë­¸±ïïžW¬Þ˜xè6 “ë* ûç%¾{©=G<š7Â`´Îñí=¢%&ïõ÷J^é´ÑúAèhöÂ0\KW»ô¤è¦ ˜œÉ ä;ófó­x.$™ßšļÜçÿÄØ —ñmyÃùe¼2rñüæ¼Sð†1uq$[Ü¥oXC€ÑPMKXS¦ÐˆŒH`>ÉT÷h ÊCPö¡ ¥¼ç˜Nï^.´xÐìZÝx«{›ŒÃfg†uñÕâ²Äà ú{²Ž.¡îÔ å¨Dm}'øÊá8p¹nâ&nz]óºæuÍô²éeÓËÔ•ºR×’ô’ô’ô¤õIë“Ö«6«6«¸àn©·Ô[êmûÚöµík“““A– K¥¾¤¾¤¾DÆ1dLi«ÒV¥­2y™¼Lëy¥|ʧ|ŒÄHŒä eÖÃÊúØþ[¦k6±‰–Þã=Þ3ÙáÌð •A+ƒVjÖ­5ºöMí›Ú7/=¼ôðR…s…s…3—8åãþ«r ’TPG¼À,rŽiB.ªÔ¯é ¶ˆü@À6³&é¾§áC¹EÀ-ÛSü•b=þvqPnQç%öä}“™’íƒo?9ß÷î÷w•>ª)êL2ˆ°0„.=BÈDÊ8úÍ_ 1Ä3ÁL0¬NQ§¨S¢îFݺ»¡Ë†.º$ôJè•Ðk@Í€š5œÛÒöQ-ž{#¬ÁÍjû°QÎp†³ÄUâ*quKqKqK1Ž6Ž6Ž®ÙU³«f×Ës/Ͻ<—=4{höPNÆÔÖ°æ’}QªG¤%iIZR•Q™é/¦¿˜þâèèÈ„3áLø‹U/V½X•y=ózæuN¤Õ°àh3Ÿ'ؼò[±[ù Ÿá3k³æN”8J%3wÌÜ1s/ ½0ôÂPÞÞÞUwUwU÷úAúKÇÿæqŒwÈez“gHUÕÑJä{–®¢x!д1M>æë2Þ:/E;„ÆPØA a}å~!„²kbÖ{aTdTdT¤ËÓåéòòžæ ó„E>|(POVïWïWßTY©¬p›p—ÿÿ“qcä# ³P`+€d€³( `nà6˜ À:a ˆA7ŒÃdÒÁd1†"Sу4"óÉ@„b2º£!&‘žhD¾G'`6ú‘ÆHCJéšE»«÷Òj:˜î£å A›AXÝä£Ü‹ ¿¥—þˆR(}[ç'zašù¨¨#i¢ÒQÙ*;ßµº;õù•q]Dõÿ (­Ñˆ;Ú€}g‘’þÂJÞ%Óº'Äïu\´ÄÂtÝÇÒΆúûµ/‹>úèü(ž­S¥µ_Øß°½î*q½R?Ñ`½(©p‹ž@;P8_(Ìäëè´—¶KkÅ­)Òïʼn‚i}Ñyþý+Ò\‘…ÄTt˜G2C¤ÇÛÂo+RðÜæ H:ï ºÄܪ¾P¾¨ôVÙ™::Iž«”='ËySòøï²Þ=§¯±'™ ²ˆäÑrZIkÁJüõøšÀ2ÚÙœŽ]Ð]lllL™3=¦£££²RY©¬^œzqêÅ)U¥ªRUI"I$‰¤NÔ‰:Ul­ØZ±•å#dgegegÙxØxØx¿4~iü’8'â¤c©c©céÕÌ«™W³¢uEëŠÖevÉì’Ù…c‡³ðƒü¸œÓ¬ïŸUªù;Í,ö*¬«b b qãÆ Ä•âJq%«ƒQ4£hFÑŒŠ³g+Î"ÁæLöæ>Y:ˆjPøÁ ÆLƒº¿"•ö Îˆ¤NjP4.õœj!®Û~‡oiÏ~1¦®q¨Vòmusu%@õéÜ[¹IYï’·8ùþÉ ÏÏ}ÖL­§Î¦yXŽ)/‰yKލv©  °û DàÿM&; V*W8¦rNeNeNeÁ€‚Ì:˜u0ë`_l_l_üÚùµókgòùü@—Ò¥t)·xcë“]ÎU \BÃB¢°Ê¨Ê¨Ê(ùXò±äc.k]Öº¬5¿k~×ü®k€k€k€ØRl)¶L?™~2ý$Äy§q-Ñ-¿€¾I@@8Þÿj¬Æê¼ñyãóÆ¿,|Yø²ÐåµËk—צ>¦>¦>ï¾kø®¡ÊBe¡²àb3.à.|v‹–ÝîA<ˆÝMwÓÝVc¬ÆX111ÉŸ“?'Nanana. P€jBM¨ÉW›#¢¿Ó‡pŠì=Mýž9{RºðÇAUU^Ó/ôr£¹sËûŸV„:©¬¹üväÞ|Ì·ZáG8ëbÄŒ˜û™ø™ø™ÄzÅzÅzÙ¬³Yg³Ž+É2V?¯â#Œ  1€ Æ ü±‹Û؈®Pá F“FÈÅÒH°™,&n8ÄœaZ+$“ Ç#—×.ýœ/+òäéŠ- Oùf+S˃– È~"Ã%¢$›‰5™Ll°‡ô"bl"-Q‹UÄï0àÁÿÁ÷'Xò*_ÝÖZï…­ÍêkÝh 7;¡kånnÛZÿ°–³» ‰I ÒuP {ÙuµÜufâˆ+íV.ӛгó¹Õ—Fïlj{vë¥æ{×¥¤”ÒGZ”RzWH)¥7Î?øpÇOà(3¾ÈU!%«‰ÖÔg=¾thf^ü¿~Ì©¬ÝM»›v·ˆÙ³#fGO‰ž=E^"/‘—XïµÞkýqlds³°…-l1#0‚æÓ€á[÷†oýø?ð »!»!»!+’ÉŠää䢊¢Š¢Š¼£½£½£u×ê®Õý”drWp…Õxæ¾ÑLT÷×Õ‰¬`Ź*>/}^ú¼”'Êå‰r\ ûûû²1\"¶&“¥´>:†H( °—ȼ!§4‹8UY]Óo¿S<¥]ÓØ2Ãó¡#~¢4áǸJo{†Òøuãr^îÞ;³°ik¾×Xé.ñþGÏ´3l`IRÉ <Ä=lF÷ϧ粡Ìì±4]š.Mßh¾Ñ|£yâÐÄ¡‰C[Ìl1³ÅLV¥‡À àü §f•IØ«´"­H+ÇrÇrÇrù ù ù E´"ZíêêÊÎÎç‚qÿ Áçß[€ÃÆBg¡³Ð9,.,.,ŽÍ/n2ÅdŠÉN`‘ÇüŒÁðô0 S1U£Þ÷/«É  Vc$"ˆr0ì!2\`ÈV3G!ñáµe~$ãy×™d²—ߟ׎ñsx§7Áw|Ó7ÙCVŸI3$ÿé-‡ðŽ X¬Šìò™éŸ`dÖ¬a~ȱˆ%JÙÁØ©^+=/ú »½¡û}]±—«/Wrylr;åÅ…ŠÃéé9¿~ùð̵«¾ïô‹øšÈAhLrHs'Ó‰ÎR3õøÒÛ6 6®=Ú£=oooQà¸ÀqãdGeGeGå¹ò\y®ÇmÛ·9‚†Î ç§×+X°Ê*šéÙó‡<ó±æcÍÇ6Êh”Ñ(CÞAÞAÞA–!ËeÈ·È·È·DmŠÚµÉÃÌÃÌÃL'“Æ}rÏì9eAÆ‘jþ:°Ì{)¤jkkkkk‡{†{†{Ê“äIò¤      ÞcÞcÞc®<›vêÇÏõìKè!¿`0cJ6~*lçpÏÒ\Ïh‰ïðï#^'œ¾0l ¥·Tq‡)½Q0ö%¥wæN°Ïwè†㓻v §k¬µBh­y^"óš‚ø˜IšÕ¢ù|ÐýÑŸ<#ÏÈ3ö‹)7¦Ü˜r#M¦NSMš:4•{cž1Ϙ[>ý33‹>èƒ>‘`hhE¢H‰íÛ'¶_–_–_– ZP-ø˜,o'vb'«ÇÿŒo¬¸*;Ïœ·9osÞÖ$ºIt“hß‘¾#}GrL÷žè‰žŸû~>`UÛðŽðްä¥Ö“ZOj=éEÍ‹š5+Æ­·b÷*ú‘~¤',[o¼H™ÎËö9Ø´¬Èž©×·YÝ®¿ôžFéÜÃýçŽï"#[¸†Ro¸ÿ0ØC×I®“\'Å>‹}ûÌmÛ ·A\vãòë“jŠA bØÕ Ž9(r¼J^%¯ jÔ0¨!W’LYoÇ¿Í )AhDZ†Ä ë1Ÿø¢t/è6×9ëþĽ­ÛÞ¨¥‘ï#Mc?ÄÅ´Š)‹qUØ7i;<&:zoTrä-·–®?¹<08f0_ÿ•æOÎ|vàdÏ“—&^Né¿ ; $wänç%ã@|á G˜BáoæZ=¾\°‹m6c%À%Ë%Ë%Ká£ðQøÈÚÊÚÊÚ  ˆà4:þ š&‚|àÃIj€777ÐêŠÕ«+ÁW‚¯_‘O–O–O–-”-”-”¯•¯•¯GÈ#äN~N~N~âóâóâóŸ\%Èà µß÷—¬2 kÌÔ6¨mP«è¨è¨è¨ˆQÄ(bìvØí°ÛÁ•߆mØ#Áè“ó°t¶Jz16ñú2ËÈ Í"&öz™‡¹>n…òßéY;ð¥w˜ññ”^¯ÛÒ„qgò8=$bñî¡·Â?Ø1ï¦ó I€éNn-Ò™0ø¸SÁÿ-)Óg Þ<Þ<Þ<–ËÞ©S§N:%Õ%Õ%Õ­ ]º*T#ŽÇpciå?­j¥ùöÙ„DlœÀx»ñvãíááá±Ãc‡ÇoTܨ¸Q±nC݆ºGov9j cÿAKþ|À>éIœÄI6"E§D§D§$Ú&Ú&Ú&rnäÜȹº;uwêr­'p'>»§h‡vhGHáæ²7FÜq#uSê¦ÔM“c&ÇLŽaû¯5¯5¯uýPý͹CÖ‘XöØ_jÃ7KÉýyŠIÏê¹³ÌûŒ tî¸þ½–­lãþ‚ë­õ†;W \ÆD{ØÃ^è!ôz4^ÝxuãÕŠ}Š}Š}ú{õ÷êïå2²[í_‡¯]¬÷‚EÒÖhv£Ùf+¼Þ ïДДÐÑFÑFÑÇhwÖÏñï€Ýy½o™p¦‘°«p `;ŽÝøMFøŒ¥4~Ü„;u/ûŒ|¡ò¸6ply»%Qzn»¸Þ$%?íßî“ÿ•½ëo¬§ü^€÷ÌÍÍY:ª2ª2ª2ºAtƒèzÅzÅzÅܯ¦jì)ýóf |ð¹QâáÐ'½¯ ¯ oƒìÙ ²ÃÚ†µ k+ÏgÈ3ä¶r[¹­üüüAXpXpXpƒ. º4èŸßÃÿ4ûÁÁM?ë¿vÿ½ñËüËüË!LÂÈwÉwÉw…÷ ïÞKª”*¥J®Ÿà žp¿e}›Ágcr˜_#ÒHóôÆFzâ›S§÷ª :ôZuÀ¶¿¥ ã»Pz#ol¥ ›âjKï³^¾òƨ¨²ÍJtJ?yuFLGÒcÐ ~0†$Ÿ¥OõÀ2›kH áôÅ}m}m}m/>¿øüâó¿œøåÄ/V[­¶ZmåŠ?!OÈ“õüÜ1äúoñ–ýB?P?P?](ÆfÆfÆf†M ›6Å(Í(Íè#Ñ(™È„/|áû/·ó¿lZ4v'|ö`çOž?yþÔlu³ÕÍV;«ÕÎjN­…Í™ ¹ ùpçpŽ=‰D"‘hUäªÈU‘‰9‰9‰9]c»Æveg@&„ aB>ÙÙ«Ç·F›4‚ŠLmËð^¶ˆkÒ%šÒÙÇûn¢t®_¯=/»m‰á|õ†»&ˆ± ì±Å~‹ýûc—Æ.]ê—á—á—Áä3ùL>«pŒÎèü‰Äã×}èCŸ3;t ÷b÷b÷bù;ù;ù»¨5Qk¢Ö˜:š:š:râVÙÈFöÿñZ,µ€MÙ­ W¸ÂÕPl(6{Þ÷¼ïy?zgôÎèò¦ò¦ò¦²|Y¾,_¨T†öíÚßi¯Ó^§½ZË´–i}ê„A„‡xˆ‡C üá Kf¹‡¶Èª¼1F1‡)½}dü~Õë#ÇtɬËÿÛ$ªyuv¬ÈAr4‹ˆ¢EÑ¢h'''ÿ0‡0‡0ù]ù]ù]YSYSYS¹J®’«‚;w îdÕÓª§UOž’§ä}*\È’y4³fþó®ÖD‡qÇÒ݌݌ݸ%ÄnùnùnŸPŸPŸP.p–ýØ¡l¹˜à&2Û‰’¸  ÁQYti ž_ßn«ÏÖ—V{—ö=Fé­Š¸µ”Þx36…Ò[¹qKëL.-E¶;M¶n"odìf6ö“Ê›@RˆcNÖü–“]|‰¤56}}"¡í®í®í~0ã`ÆÁŒ=ô|Ð3 6 6 &0 Ó‹éÅôú—Û›f°² ¬9Ð2Ð2Ð2ˆÄ1çcÎÇœìÙ#²‡¥»¥»¥;÷+ÖgÏÆ-üþœŸÊP†2öÐd»Év“í²rY¹¬k¦~=þš&2/q†=Ö3Òº,¹”õ}yZ=×­ß]Jç÷«>s­_Ñ$Ð&Ç‘†Ÿ÷fãß‚hD#šõ“’@¼ã½ã½ã›T6©lRi3Þf¼Íx®†u‰.Ñýjëú—c9–³^=Ë»–w-ï*î)î)î)Šû^ö½ì{qµÁnÿýãÉFÓ˜ð†7¼‰=±'öŸ”Ù‚-Øbìjìjìê—è—è—µ/j_Ô>y¼F^ÆÇÉˡvíÚÁþ¥ýKû—’3’3’3Ÿœ‡ QˆÈ²àýÏ=?c ™FqTû¶V‰xéÝ.?mìG—ßô;‡Òø+q¼Ó7–Œë”&¬êòÏò"™ïÉá<ÆC ñÿªïôwB³n=àV‡:äøîÝnpƒ›‹‘t&Ig_=_=_=ùHùHùHyг}ŸxØ>Ë&Bú³«ÿX/&Àkœ×8¯qòòò2™‹ÌÅÌÒÌÒÌRhA‚“8 .¨”çÂô!Ÿpp §1¦‡OìP·>Ä?ìÞÒ½¸Ó”ÞäͦôÖ¸Eu¹—Fß¿xf»·#ü|Â,?¹[¦¹J2™Xa/º!®=÷‹o½l’ öxá“…O>y’ù$óIf/‹^½8Wq$ŽÄñŸbºÿã–ÆŽ ‡q‡Ù/øùù=ûyöóì§x­x­x-{+{+{ë`â`â`òÉyXîgà&cût¬BN$"I&“Édré §6œÚÄ£‰G¥Òæã²vFa·ðþn?–Ä~äAصµkk×6>%>%>åÌŠ3+άÐÒÒâÞÚ?&æÕã«Å> DGâ~ÃØ“Å7ÂnlÙ˜ÒùNFPÕœƒý®ÞY2ôJ›Ëò8óM×;(°>6 $èhëhëhGŽ=:lBØ„° âÍâÍâÍœ2.«&ñuã1ã1;”èÛèÛèÛÈÞËÞËÞ+¶*¶*¶zkykykq\á`f}²` 0l€ÝLÁÍ‹ðüx~>>r¹¾\¿ñ³ÆÏ§ðµøZ|-ôD,\ÈIÒI!™.ÔRpÍtoÞ?Xf'ºtg…wÇÁtïþc—Szs÷8¥ úq×U&WÈhçK¯Wôì¸J~! …Í'ü]FAN¢Žñ%û~ÓÞf i_Ó2“xì¢Ó0 Óºïr¼ËñûSïO½?uÙ¹eç–#ZDë7%«P„"ôߺ¢æèǾeÎp†³ƒ¾ƒ¾ƒ¾|¥|¥|e̦˜M1›ÜŸ»?wΫæUó>Ž«ë°ë>ÓúÔØ°ìdÙɲSL`L`L`ðäàÉÁ“™ÅÌbf1yeØ|n Òt !-æLÌ™˜3‰‰‰Û¥Û¥Û¥Lc¦1ó±ÿ²¢–õøæ …B~8ãH8ƒãÌä^ãb—Pº`ïÀ”α듪ݨC€ö¸Žè‡fp‚,¾ÑÓ4.Û¶9lk2 É€&<{öàüß„ÉÎb –` {(öû‹ýƒsƒsƒsYŠ,EVÃY g5œ%X.X.XΕ‹±ûÉÉú<ØÜ`&1“˜IVr+¹•<`HÀ€!2[™­ÌVî+÷•ûÊÒdi²4V8 „µl=Øz° ^/ˆÿ仡ºqˆU!áþNxæL;ÂßïïÙð¥ =Æ·¨ë|¹á(I•õï1Ï£ßûW7à¶2y#˜]äc Þ‹6£iüic‘d’L’µUÚ*mÕ'n¬fˆæþÃ×›ñûçb³N GŽ0!“ʤ2iT~T~T¾\(Ê…š–-§uýÏ·¢šçg[ïflÆf4A4Ñ,høÐð¡áCÿ­þ[ý·Ê{È{È{È’dI²$¹¶\[®}6úlôY¯U^«¼VéÔ?¨ÿi‚tvßl6aÓ'õÀCLˆ áÞþ¾ý}ûûŠE„"B¬V;¬tØà°ñ'«OJÉ"ò Ÿ¾Ù» §v†¿ö_Ö¬ýJo´Û•Òø’8¥7‡Žs¤ôV縨KÍW>îÔ e|c'û>ŸÜU DÑù…Ñ">˜ƒ¿©"¾^^/iOÚ“öì±ïß!¾Cî ¾7øÞà“sOÎ=9Wä%òyqo¦ º Ëx”؈ب)¥`¹Ür¹åòÈY‘³"gÅÇÇûÍõ›ë7W´Z´Z´š»g1úÞÿËF0{u–xf+X F F F‡T…T…TÉïÉïÉï™M6›l6™+pà¿üâùàƒO𓿤9+3=Âe„Ë–¿9Óe¦ËLŽØÃî'°lþz|›à»2ÞdDB{ï‰.¡²W”.08޾œíÝwTÆüñâïëÒRHœ¹dbÙç­ú Ð ¸±nooA¨n¨n¨®B¦)dúÕúÕúÕÜ:x Æ`ÌWkôh‚åñ›Â¦äyDùv÷íîÛ]±A±A±!jQÔ¢¨EºFºFºF\mÜÅ]Üå B"$Ÿ¤ôâçç·¶µ¶µ¶ ÒÒÒ—{È=äòáòáòáòòò²Ó²Ó²ÓÔÔÔ–m,ÛX¶áïàïàïøä®ØàBoxÛó©ü; ›b© Z"”T“¨ÂTd{¥3ƶù‘Ò„Uqå”Þ83¶ùSÝËúO7»iÔQ§ ùèa9¹Fz"…»öß9™iNÆ¿†_ïñyëóÖçmľˆ}û†‡ nXeXeøÑ—ɲ!AÈ'íÿkêË,X¢‹ L`"x,x,xt%èJÐÙLÙLÙLE#E#E#—B—B—…¬ð¢#áø_ëÝìý³Úì¢WÀc1‡˜C¦6¦6¦6té4Ò‘»ÉÝänòyˆ ›ttt²ª´ª´ª vvv½‘½‘½‘)eJ™R>P>P>0À$À$ÀÄRÏRÏR¨ˆŠ¨>¹“ à“”4ÿ©iCÃ_NÞ“‰È!^8?Óõ¹Ò‹ÏŽïîÓß_5üFôØhJvÇß9{Z£–Å"­È<ÜD Ü?äý­“뮈ÒEé¢tÿþ'üO(F*F*FF¯Œ^½R¾Q¾Q¾1<8<8<Øü¦ùM󛟜ánáÖ'Rž_‡Ï.Â'c2&³ O?O?O?ù"ù"ù"YŽ,G–¸9psàfþyþyþy,ÄB,Äp ÇðÏâþ5— l”Âï$É2‚Œ°>n}ÜúxðªàUÁ«ä¥òRy©,F#‹‘_”_”_Œxñ:ⵓÔIê$•¬•¬•|’扄`„X€EÆ'ŒQìP8ÊgÆ”ÆÌTzNõêäÍžFv³ŒÂ×N$ó­JûÕêûË”Æ_÷žÒcŸPz[g|TJÞîÁ}– Ím+ò~*xÁoÏìÒ¼ïó†ÃLømäü6Õ™4DB;;;VD¬ˆX‘¸>q}âúNuê:Õ! acš1͘fa»²ƒìðçЭ;[wvȲe!ËbÔ1êuØì°Ùa³ ûö7ìÏýj<Æc<«ñõçüû¡1j/Ó^¦½,¢SD§ˆNÑÞÑÞÑÞúaúaúaÜ^:K¤üoÍÿxÄ3[™­ÌÖ]»2ve<)}Rú¤40.0.0ŽQaV1«˜Uõ9C¾iðZ{ƒ‡æljfœL«çY pS­šy¸K±Á´½:7µwµšÎ6¦#éMl¿¡ b»;5²ábíÐí|#|#|#š>lú°éC›Y6³l>æJ¼Žë¸þª¶ÿãJÒ'úDŸ}j‹',NDˆþýAá§ðSø9.r\äø‰ŒÄFb#±qîìÜÙ¹sp‡àÁX¹=9‹òòÑ¢/D_ð÷÷7icÒÆ¤ 7`i‚M¥ÎJsj¦žù+5 Uæ1ãK¸Äh×€ÞvòJ“ËÎc´T].ŸEé­“ãÖ·ÝÁŽPÁ³b“!‚tÿÂá–e¨³ôâO¸D$’,I–$«QËF-µ”—ÉËäeÑnÑnÑnÑw¢ïDß‘---yÈ—‰‚Ä0fŒžï¿_ü"ìd1Á×§ËúúÚ¹W9ZÎ^Ùß3¸*g剿C~¦ôv×ñq”Æ ÇÍ¢ôÖ¸y™Ãi øi”´c ¿“´¤Ÿ8’Jò#Ò‘ŒíèùI~Ë&Ic4Fc’M² §Á5à΀;úbê‹©3GÏ=“sL0G˜#Ì‘?PÊÿOõî2`À`v[hi µ„ZÂÀgÏŸÅ b±‚È+‘W"¯X¾·|oùQÛÇîp'3ÉL2óOÏü÷€Õ=cçå¶h‹¶J¥‡²éˆ¦#šŽpÝèºÑu#‚„ NðÔ Npú/ NóÈ< Ûoµßj¿õŒõë3Ö—6^Úxi£“ÄIâÄÎpÆœ1gÌ¿ÙþQ`’•„ wíéá—Néœ{ý#•^3 z¯­¾?ófß=m½Û9qÓÏ›Ü'c¿¹jÊCòX¿£®Ž®Ž®NÔܨ¹QsÃŽ… ;¦¥«¥«¥Ëmjò_¿,À,`µ÷jïÕÞÞ!¼CxVyºa^ü†yÒ¥Ò¥Ò¥Ž)Ž)Ž)¬Âºüœüœüœ¼£¼£¼£bbb]d\d\dœÏ Ÿ>3ŒZµ6j£8Š£Ÿ p,ÁÆÖ¿ù°ÿNŽð7~-Ÿ¹Ç8’Vì×3öÛ¾šÒ:¾ZÕüJŨŒ‚g÷Ž˜ºî³äô ˜#ŒÁob‘]îFÓ>¯}^û|HyHyH¹ììì¬@V +ˆ7ë`ÖÁ¬ƒ›®›®›®ü†ü†üFtftft¦|¿|¿|P· nAÝô*õ*õ>úq٤⬗úËÒÖ4XÑ=€nsÝæºÍ£ì£ì£ì£%Ñ’h‰ü¾ü¾ü¾Åe‹Ë—¹ò—p —¸ãÏÿ©5ŸÔö°ÿ=!M,ËÅrç5Îkœ×D´ŽhÑZ¨°”×ÈwÊ{ÉùŠ gù®p¯p§°EÆy†+  {ø˜zw™ÞT?ÄigóÉ•-ýr—??Ä›ÒøµãöSzsÝ8?JÊÇÇd>4pú¢%CmÂW›HõÊ$­4¯Î7æé“[˜…~¿…É~Õœõÿx½y½y½ÙxªÈÔÈÔÈÔOàûµà¤à¤à¤×B¯…^ c&ÇLŽ™,çÉyržÝs»çvÏ9y¬?û¿ <ß³ fÌ’5‘5‘5a½ïâtqº8›Áû¡úý­ Âf3‡Ùe†|’|’|Ò-õ-õ-õÎ;ì|`xÒð¤!G[Ò¤ÓÔãk¿¢ ±ñHa ?T¢¦œÆÒ}T›¾Cv‰nó%¼\ãB­BÑGÉ­3¤¢`CßD]²<9V8¯¨0ª1ª1ªßßß~›ÿ6ÿm~eieie)¶c;¶k¦)ù†À2 `ƒ ‹ ‹ eOeOeOá„?°&»¿£¿£¿£¨•¨•¨•z­z­z-›¶FµSµSµ3/9/9/9Ç6Ç6Ƕ¸uqëâš,Ï’Ý>ÞØAÐ#ôÈ' j¨¡þ›ž´JîZT-RϤ–L QáѼµ;sn-h8Àm²©¼•<ü;S#s!Ðm]£±edïFw:x¯æ\ͺºÇD‚,Ì UÄ,Ž„£†ô_¾vj¡  œR>['ºÐ…®þ ýú3<·{n÷Ü.üQø£ðGÜÀ ܨò¨ò¨òHÉIÉIÉ)­(­(­`)Í¥¤””‡sçÎ |>é"é"é"ß§¾O}Ÿ¾øfà›™E™E™EÜ"-éHçTJØShÞÏçÍ»bÓÇ|ïñ=¯ ¯ ¯‰ÓT§©NS™wÌ;æ+Ä–û6÷mîÛ÷úïõßësYH‡a†qçQAÕgÝÙ'eïö5^ã5%”P‚©˜‚IxÕóªçUÏK»œv9ír¡MnÞó•~–g 3ŒüL’èrŠÉ¬6­ª«û¹µcO“ÞFAþ‘ã§ִB9½tÙešþýÆoÔ?êé¾t:“0ë˜Ó•çJM«­¿tü@R‹ ©'DŸ¤›f¿-9@`¬ÉzÒãH@º²¡jm„؆$´Ô}æµú··XõêÔ?°É’^¯~½úõê7Ò7Ò7Ò’’__ßÇ9sçdYAÇÒ±ô¯q¨i¶y6£ð œÀ‰ºÖu­ëZ§ø¦ø¦øÖðkø5|SSSCCCÝûº÷uïW¬¨XQ±"Ý.Ý.ÝŽ¶§íi{.ûG1ŠQü·Žó1óYuñÏÅ?ÿ\Ò«¤WI/ñ†c Çšë™ë™ë½)ySò¦„SXú;Ç1 ÊÉ%»À.–-/Z^4èaÐàGÆžŒ={Š´Š´Š´ðOñ”Þ¡wèúŽòõá_ðäÑñ8I9Vëûƒe-*‰òº±z3퇇xá¼=$Eß_Ô\`Àõ‚5ÁûªË(D!ŠÝz˜ ÌfæÌ;™wª[R·¤nIî›Ü7¹o8…–½]ƒÔ|s-î%^â%$GeTFe夜”vÔբ¸\.0ƒÌêÎÖ­;›Ý0»avÃû{ïソ÷Y—g]žuáLvV!˜%'°‰ÖÙå› Rc°û/<éÿF€za3lB:+ËUãÕÆk­}cÔû…]ª›ÓžÊiª!}|»[ez#ôd}èO0ƒ79É´" h¸ÿLv6;êBºFFFÞ[½·zoÖ ë„uì¶{ÅáŠÃ‡“Z$µHjÁšì\îÀ8Ä!.;<;<;ü᫇¯¾*.).).aÖ2k™µL&“Éd:té4Ò{÷ï5âiâiâim†Õ ð|>1?°wÅòGY½ê Àñ¶ãmÇÛìÔÈr[+NWœ®8žžNh àZàœÁ™ÏnAòa]ˆoXb †"œ˜’3hÌ{ÉH eÆ’|Î8X €IDATü𶨴¤EJÇ”ëÏÚg8¾ºõÌÙZf Åt+ÎÕ+,éÖ+dS̆ŽË:ök¶¢ã¦Nûû½mb\Ó«ŒÝ#²ÊEåw*wlh{_ù‡,ßÓ|ÂÒ ×oœI7Íþµä8ï “EŽc;&£©ZM§Ã–6¦ûüIûø¿µÿ¯”–ÓrZΊ´¾½½åuÎëœ×Ù¬•Y+³Væ±æ±æ±¬´î'‘5ؽͶh‹¶èè¡6P¨ Òî§ÝO»Ÿ>&}Lúu²:Yl²Ðd¡ÉBÛÛÛ’OòI>÷[–¸ò÷¥(E)ëw§™4“ffee1-˜L SjJM)φgóáfØEþß3šµFk´¦½ioÚ‰HD¢¥‰¥‰¥‰à´à´àtæèÌÑ™£é:‡ÎáñŠxEŸQ¤M=þ[ ÍñëÇLÞW-§™L¯zôcjïá5¯g˜öv¦å‹z2['ædCgð¡©@ÌbÄßPMÀL`7Íú›õ7ëÛ° aAÃò€< ¸’ìJýÛ aŸšÕ͵…-lmBlBlB† C…¡l‚l‚lBx—ð.á][:¶tl)í(í(íøÉØyÖÇ©/ÿ9×§†F;Ï—™H²Ç]†)šy Q5½Ñ|ÜM•Íe÷‘/T{nN‰óïñàDBÍ—™/3_&«•ÕÊj£J£J£J£øQü(¾Þ3½gzœî¸fþÔÏTJ3?€3¬¡G†le®1Æ$ˆ™EÞ ¸Àú7}ßÁ5Î&Þ e‘ì‘Ë£•«GnŠz|÷ÃÆí].Ö\î?ú4¥WÎ ›÷úÅ胭¯~¨–U+n7¯ü¥|烉ÊÝugoâý® ¯àt·Æ&£>ižd+J™ rµÜWßf€é¿)¤2Ï™çÌsö‹©ë§®Ÿº>õCê‡ÔC3‡få2ž’±d,Ë©{ý=Ðì¬`ƒt # ”JÃ¥áÒpi¢Q4ªIT“¨&L“Çäqå5¥fÿ~°.!…ÎBg6ï‡âŽâŽâŽÅ‹œˆ3—Áôo±$–Ä’=Ö²Ô²Ô²\ï¾Þ}½û·nÜZm}´õQVå‰Ä âÕwŽzKÑœ÷EW_l/\Sæ0-¤g›šŒ=zO§tqÁç‹[„9☓¤<ð!øjë„h|4D?ÆñcšÌo2¿É|ëÖ¬?RbXmòÏ&ûÚ êõRT DEDEDEÈ:É:É:y˽åÞòOʳۗl‚tÖ|Ô¬ÿ/¡Å"ðÀg‚È.¼eÿ¸ÒnÔE2¥·ûï_Wtõñèùëé=ÜÇ5¹ÁÆ+Ù2ŒYÿ[B™¬õ®9Y²þcÖpXÖYÖYÖEÕEÕEÕEOˆž= =ô5õ5õ5Ä âS”k¦YÑØú»ÔWFÓ¦MoÜ©q§Æä‰òDybtZtZtšì‚ì‚삳®³®³.ãÏø3\ ,G›ùï.½4¯È&ˆˆˆ„E†E†EF'E'E')–*–*–Ú=±{b÷Q)+©HåX?“]ÓL7$d1ÁNÞnæ ù‰Ë '9öShI¹àAD‘O¹•ÛÜaÞ†úœ¿·´yû¸·ž‡& ØMéõ¾c)MÜ>QHéÝMr)½×aÒJ/™lVPüfÌ/RîPJéÓ£”RšœB)¥‡—¼4z¥ÃÝZ^æi†L@o4ƒ×o-ŠWo²ÿ{`Ì3ÆŒ —ls±ÍÅ6ïî½»÷îÞuãÖ[7N4J4Jôqát7pã¿p‹,‘&A2»mvÛì¶|¡|¡|apfpfp¦ñã9Æs0ó0óÓ‹!ÆÏñdžw²}à v;ˆ›îhº£éïÓÞ§½O“ dÙ€öhöšcì_8\=&ÉcÖ~`³ºžœœ\r½äzÉÕoŸß>¿}\{3bF\¯'S`?LÂc¼#Lê»TÝÚÔ½œÙµO¥ Ï ÚëüÝSÙ!ý±Ž±Ä#ŒÇrtE‹¯¼fXÍfKXÂR{Šöí)‘N‘N‘Nººº’4Iš$óêÂ!ªoJ¿Ï»ÉŒfF3£™Ìf9L“ÃDDDD„Ÿð~ú8n}ÃðÈ<âƒËÌSƆø„ê¶Ðjv»ró©^Ã(ïfÛk‡ý+ú•_ËZSÞe^ÜÎvån.Ѷϰ-¿žO<Ÿ¸}ÍÍÖ7î%ýZZTZt> µ4õŒÅ³‹¦eð…üÈ6²•l©ÿ£íp¢ 0vqvqvq—+.W\®¸ÜüróËÍ-Ü-Ü-ÜYò Çþ;!bGìˆ×é—8-qZÒüIó'ÍŸx óæ1Œ+ÉfËf•[>lÁla³|H÷K÷K÷‡?þX¶_¶_¶_ÏDÏDÏ„có³Rñž™ÂLa¦°oÜ3Õ3Õ351"1"1âЕCW]Ñ–hK´%\l€†Th=¾môF 8aAS^#fwrλNê~³~ì˧êùÚlÏ'öo×BÍÏø 8áHÒ‡°ü«­v]ž|ä³_ØçÚçÚç6U6U6Uzò:*tTè(ñ ñ ñG?%›Ìèïi™ÿ³£Çµb†'˜Êc˜XÒž¿ƒ7“a& éŸÀÞ×ÂRwOϱûÝÎ- –±öÖþõº4-™|&p˜šÒ;£'ØPz{Ñø9”Þ?˜Ò[åqÛ(½µ"nhuÚ¯…#Mã·¯óúîâjïÑÓ£/tª‰näì°Ï²ƒ^û?»"ï*üÔvÃÅ “ß¿vÿÚ„»ò&äá QÈØ06Œ G1úÏý=Ððøòññíïïß'÷É}mmmÆ5¨v¤i÷·Ž¨1ˆA ëB–‘ed™§§g“Ò&¥MJmmmmmmYú "Aäó0Ù5ëGc/ÝSè)ôÆVÄVÄV¸­q[ãöqaÌ2Ýÿ:U=èA<#ÏÈ3ÖãÞü\ósÍÏ%/J^”¼hݯë~]÷+wã|Â'|.íZ=¾Rü+ª2¥¨’ãRU¯§ü‚ÇUók‹É&C?¤¡Jm¥NÐ+n!š¤c$´"ݺ6u<|0ø`ÂWZlÞSxÀƒ¯â«ø*ãýÆû÷+O)O)OåIó¤yRz“Þ¤7q Çpì“)¿,ÊP†2ØÀ6ÜpY…*TqË¡ÏSäßbÁWU«ÐUŒ#ÙKø,Óœsùqákö\+ýyÂÔë±yʆ•jL=ÑÛ³ÑÊ[·“GäxžïtgÀ«kLÓžLP Ô|º€š wf[ã ÁÒt'Ý]ô]ô]ô­¬¬Ô£Õ£Õ£y'x'x'^ǾŽ}›~7ýnú]ÎlmÖhÍi{³uþx4ß›?5¡eƒäØßf9d9d9”Ü.¹]rÛ5Ö5Ö5VÏ\Ï\Ïœ^¡Wè§3NgœÎèëë§ÉÒdi²Úµj?p{,‹°‹p÷qÿ?Ü4Ÿn$Fb$+¥gjjÚÀ§OU'U'U'Ò—ô%}_4{ÑìE³êˆêˆêìÃ>ìC7tC7Îèü+tŠ` =Á æè–ð`ÚÖ‘ÅÄ“ST{Ó*6V³~åªä¼™©A-S;˜wÓÕŠîî¿ÛzM›a®ŽÃ›XóõçFëˆDWx»µj„:‰"kÐ…yOìªK×Ö¾+³¬©~¿âƒnÅ÷_LÎw¼Tò`CæÐ‹H¬Í\•U/+¿^þ¤jNÝìß(~÷²’â éMÒHs ÂâÅOãàŸ®®í]Ûc·Å~ïýÞî}zùôj}¼µWk¯ËÅ—«/Wß{ÿíý·löª¦jªþ ûøß÷x÷lcÕ,Õ,Õ¬'FOŒžy®÷\ï¹Þ§È§È§èjÒÕ¤«I\É¿³ÎYÙ†‹¸ˆ‹Â a…°BË]Ë]˽¦ª¦ª¦êÿ±wÞaUíßÿΞơ÷Þ¤ ¢ *¨ ì½GE½÷Þ{ï±Æco±¡±wl"@š4)ÒÛ9pvÞ?vÍCÞ$¿'E󘸯äÚk™-gfvöÞ™ûþÞ¥K7–näŒcz†ž¡gÐíÐî\Ÿuè¹z’¹1scæF“& L%%%¤IÓ¤iÒêåÕË«—óÚY܈úqGs˜Ãœn¡[èNÖÂÅÂÅÂÅ¢V§V§V'ãlÆÙŒ³ü 7™¸û±_x,€P8óÁ"ÞX‰è¦F4h3”ÒÅO¢tQÈÀ×ë'ÝïµÐ²£ÞNm~vŠ(ˆ-²ÿ…µQ×õÅF02Œ6Œ6ŒíÚ5´k“[Mn5¹Å´aÚ0mø¹.ÿ¢às&P.Iû ,EÑqæ 9DÆ}$rÿÙ‡Ûµ¡ôAÙTÚY·:¿‘”v$a¨q¾þ ­~h€¬'>ˆâÏ“Ìóâ=â=â= ö5Ø×`_ÐÛ ·Aozô èÀ°¬Å‹ø£¸ù!Ω¦n¯þ+O‡ÜàVw%J$9‡9‡9‡v ìØ5àDÀ‰€ÁÁÁ>v>v>vÇ ŽûÙ99ñÐEݧS2†1Œ%±’XI¬÷yïóÞçÊÊÊ‚ ‚ ‚ œ|œ|œ|øòœ’<àñæ‰ëF)lÂ82/E ˜¡dÉ&ã?ïþ5]©¶è›f×ê·7©ô¨ÍK×Ü=Ó…öI;ytÆài”Þ9<1›Ò{G'½¦4jûP•1řҭ§ô¦ô‘ršvÉþÈÐQf?f¯Ôeߪ'#žøÞéÖ¤Õ#‡]:ý4.K—þfåí%Á¸&n$r#‰L3rÕØ„ñàÿ,‡¤Ü(G“Á„ÏŽ9/r^ä¼È˜;1wbîìì½³÷ÎÞÒi´€w7ªÛ÷þ Æ0†1™AfœWz=êõ¨¿+~Wü® 7 Ü0oGKbI,ÿÖ{{ЧxÊÍk­ÑZ£µ&èÇ ƒ~lÑ«E¯½$+%+%’îµEÛÏб–›ÎÐ….t#cd£=F{Œ=z ô€ÝD»‰vä5S‘ŠÔOrÜÇׂù$Ÿäoi±¥Å–ѾѾѾÝÇuן$íH;ÒN°4>Ð 60Ãð¡FÐÜ1½Û €ZªZ4ø„ªÏ‚ñj9³Úö[ä¼×ÄL WˆNzÿuJ…O· Ï9 ìn°»ÁîÐÝ¡»Cw×{[ïm=>–s0s„î#ð+Ô^r•è¢\½1Zåò©¯¬ìLµï2ÇQuhrÆéKt¾`<‘’–ˆA{âJŒPÃA:D:D:„Ë ô4èiÐS.<Ô¿•+ÿV¦õMë›Öç¯Ë% B‚~y'ëñÛ‹±‹ë1šm4Ûhv —.-\‚N:øUàW_q9tú8ôqèÃ|Ë|ËðžÐD›híŸåþ+wÛ ­Ð ó1ó¹®Ý]»»v* * * ¼x)ðR“QMF5%z(z(zOxÂC1Cÿä댶@˜’2ñ"•ˆŒ>Yw¿<ˆ¹ÁhwãFºÏåÛ;%ùηïøã„ ?>=ðíɯL :Ÿ<ü0¥Qû'+(}ì?͌҇>S )}2¥ˆÒ»ê3«UW5ÇHÀcÍ·MœÔ6hLŸžÁ_97m´Ó>Ù°ZÒPTÊôû•|Lúâ!9IBp…l!ž8C$¸‡I‹®ðøY½“_owâM¼‰7.â".ZYXYXYœó;çwÎïIÒ“¤'Iý³úgõçó*0¡L(ó!¤Op›ùËÏ3€À àLÌF"E<Žyó8æd‡“NvÐuÖuÖuæåYŸáž}ò»’B )ÖaÝwYófæÍÌ›…‡‡76olÞ˜×Há?¤?Ï´eܯÈ@ƇÉÓrÓrÓòÐ{¡÷Bï5Íošß4_rMrMr ýÑý1 Ó0í#ß· Á€#é"é"éòCæ™?d>}ú8Ôe»Ëv—í|GèJº’//?ŒÀoâ 3}D DËÒÚø6Qºlý×'îó¾é©Ø¾H¢ÉPËLãÜALYC<þUõPWCÆ&0‘Ï’Ï’Ïju¿ÕýV÷ýçøÏñŸ£©©ÉË>Á ^K¿‰â¯+RBV|X`m5ÈcÍÒªŒ«ïÆŸª¹z}â8 J£¾Ÿj=áJ¯IÞ÷€4bî0­‰§Z’ÜInÔ¤g“AM-Z´€›Ïö{æ÷Ìï™a­a­a-~.ä—sLâÑOÖ3ëzÞs/Nd  ¶AmƒÚ÷x÷x÷ø o‚¾ ú&`UÀª€UÁ~Á~Á~K—4.ÑX¡±Bƒ—Îäó°F øN¸ßÈEMpsç³f;ÌvEEEøùùi}­õµ¥Ã»ÓüßuUל­èã1v /YN\p‚Ü!=pŸì&>¸€™è ¿_žÀ<ÆÐOãfK÷gÍJ&_é5®ñÕÛš›zv/+QF¡:{cÃøn”Þï7¹¥ûL©¡ôaø”rJŸL–ÁNºIÆßL0=ð.¢cäž•Yçhí}¯á û†NâÑ)Æù7›¨Jt›i"Š`V“9HÂa ¨Ó'™?üqT'r€ f‚™`nwÏq=Çõ]]]}Þý¼ûyw;;;.¾…iÌ4fþÞpÉ)dÙ@6pÛ† C…¡âpòáäÃÉ·GÜq{„O©O©O)÷Îb†1ØaŸü†¸ø%îé7¸¹žr=åz*” eBÇcŽÇq÷ƒé˜ŽéŸuåÎÀ Ì@´AÉÉÉžfºÍt›é†ö íÚÏt’é$ÓI|I.XŸ3÷?VËÖbì[Ø·°oq#êFÔ¨ó~Ìû1Ï ß ß Ÿo‰q"N³ ðsè@“ávr}i,Ó¢Üý ¥+ô†$VÏmÝï5¥Ë¢‡øšÚ˜òù,EÞä iý/¬—xùa9»ÞôzÓëMëÖ)¬“«¥«¥«%â‡8^sƒsø¿‘CÊ Fæ-ãAÚp»'_ìS¯™ŠÒG¦ŽW^{ ìûËÞ#zÏqžmä $Ï«Æ3ÎÓ:44¸2èH˜VHAp„¿¬•ƒ/kÐT¶ÞZî<ä(N 1}ÑŠ¿âßó1ù³wìaÏ+0p¡EÖ­;[wnu¨Õ¡V‡>|¸'pOà___³{f÷ÌîýÊ)OørÝßXG»F£F>¾]}»úv ˜0%`JPpPpP°Õ`«ÁV¼›€þóû—s’ÿˆ]Dc¦h?sƒl½frȱÿ»JJ톇Wvìà>÷ržvómö3ý·²MnÄC飖SQU>Å‹Ò(Õ”¦”Þ_5¹¥÷¢&3¥Ï/ÖµõZÆúnÝú,ß6|ª¯sg'ßqö}ÌÆh´ÿÍKNC_x1×ÒŒ9è‘FÄÏ0ÚPÿ)ˆù˜ËëÄ„˜.m–Ž–Ž–Î–ò-å[ÊãrãrãrçOž?yþd& dÆŸñÇB,ÄBÞCWàϱ뱞„‘0ÆX3ÖŒõ"ŸE>‹|æ$ÌI˜3pÍÀ5×pE‡E‡E‡?ù 7g”sýÁžØ{oooiˆ4Djênênê·QŽÇxŒÿÔp|»»»œÐ ¡B'x~ãùç7L¦?ÓŸOÅ­ìýu0`øÔT€v™í2Ûe>4{höÐìÛÍßnþv³Æ øò¯ð ¯„GáßÍ N-A5H%‹ÈhXSPš{¢lmE!ä)ÓGD{C„Xq¦Æ(©ø!æTáñ_HØþ¹1ƒ1˜Ëý)Ök‹µ Ïž7ÎÈþ%\ˆ§µ|Çqœ3%]¢]¢]¢¥õ¤õ¤õ¸ähïV½[õnUÆáŒÃ‡±[°…%/@>òá†z0Dc8Á 0ÞL(©ÀF²x‘3ª0ÖƒPEügxk‹ŒÉ[“ezW4Z¸n·§ïÕe²_?ûµ®ž~V•&_éåªßÒ“k7PKä“$G‰ìÈ’ ÔlPù—x ¬ÌÍ{UÔ­²õÓ‰ƒòj/T=ØžÚÿF`L@æÞ÷’Ò‹ÕoªÖ)NÖr¿:ädŠ™¤-éƒ8±åìtjN-лqÑÈd·±U´e¨†@£ÿÏY‚ý˜á¿Üxˆ1ƒ1e‘e‘e‘û_íµÿ•û.÷]î»Âz…õ ëu#ýFúôÛ'nŸ¸}‚Ô'õI}ZE«hÕ' üý¨û1ùqãDLÄDf'³“Ù©¦¦–èèèÀå(uÒtÒtÒ$$ƒd¨"U‘ªH>÷gwtG÷OòK]à.cƒÌXf,3–µ•µ•µe=XÖ£lÙþ²ý|`ýç75°K°„s7ÊVf+³•yyyz+õVê­Ô.Õ.Õ.-.(.(.àä8Õü¿Ì‚Ë­”Òö´=mo{Öö¬íY k k 딇)SVL¨˜P1¿––*ðKDȽT^õÖ™©Qº²÷0·òÎsÖ÷›HéJ ]±Ðë±KC~ŒZAÜ=¨ÿ æQ¸ù .i<ŒÑ^£½F{CtBtBtšå5Ëk–'‰’DI¢¸è~>?¨€Àï§®¯ð&€—ø×qÕò¸a¢f·Ä¡ºÌ~݇RJŸ†RJéó©”Rúü)¥”îõ[·a|ã1]&zF„^m2ÓZ«ÙéúMçZ4^§e*m+>Á<üK·¦(Le‚ɰ¢y̲JÔ›YNf1G7FJ–#ƒ $؉ËXN°‚ñO^éugsë.œÍs<ŸØH¼F¼F¼Æi°Ó`§ÁoÞ¼ Ô Ô Ô ŠŠŠöÑöÑöÑÖ·Ö·ÖÿyVÅC8„C?ÛÃ]¥ŽéÀí¶O·O·O* * * È È Èô>î}Üû¸t·t·ôƒ¾ø~¬ÅDò˜ôÂmQ 3…L$óˆ ¾ÿ­šQÓ”JDÇÂŽ4jCfùÊ¡IÍéþKÆuhž×ñ‡·ÃžSzïö¤,JïwšìOiTÎOJ£NN‘Sú°ÍT†Ò;7'æ&ɆÔ?ÝléÚ'f]ë·¦in³³õ»›ºŠ1ñäÈo]—™AÞs±®H<"ÏÉ D£=š£ÿçÿmb#n=Ddä&¹Inr»'WL®˜\›››p â@ÄíáÚõ‡}¢Oôë:2ýK¨ÛÛ9ÿrî#“ë“œÚØ‡öÿ¡©´ßºà8f3õQõ›W4¯h^q;ávÂí„C+­8´ÂÈÞÈÞÈž¢“Ådñ'Ç8ïv-hAËÈÛÈÛÈ;¨uPë ÖMÇ5×tœ(^/ŠçËJ2¿nEÈ®påvÔoT¿QýF¡‘¡‘¡‘ Œ50âKÖÍóðWbrà¦Ó‡éÃíXºéþ¥û/%^J¼Ô³_Ï~=ùH&ŸÉgò9ý™Õ$ð×’}¤%·Ý¼ÈZer†¾\’òõêªAs“ú‡Rº¼ýf3‹‚ö{U`@ÈìÁW°ƒá¯juÿ³h€h€¦hЦHB’8½põpõpu.³_òGüˆ…Þ"ð'©“þT3Œ ·º)x¿èEºŽÍ~´³öMížÇ÷TU-öe°ó)1YÚÒ;½Ç\®2¹Òeì¥ü™gÎ ÷NºH6pΓ;—öy~3mã7ݯÜ?×¾æêò‘ý<Ç5íæè1¡}u‹vzžŽƒ¾3º£Û]î¨f.um}Ï\#;ÿèí/`‹¸@t‰i(ÑÅ3¾b‰HNî‹Ì˜¤cGö ˆ¸ 0}à dbÖÿ<çƒ5¢F´E`‹Àœ+Kà„À 4h\oY½eõ–ñÜu9 cCÂ?ÅIœÄInÓ@Ë@Ë@+`FÀŒ€S¦L xð"à…þ.ý ú ñ=Zâ=¢ï™Á¢9Ì~ò+Ù'DLÒÃb¤á%ľ!&Î?ìy3=/tÇÓ­»ÊûÞ­Œ¿N«;Žláçâë5ÍZnl µê7ë3‹ŒÃ ò Çu2•˜á{äà†¢3ü`ÿ¡Ðg©"!‚"rƒÜ 78•!.®àdæÉÌ“™OG=õtÔÐNC; íÄgv0;˜ÿ3î<Ñÿ—®öÇrY! |p0À|€ùógkÎÖœ­¹“s'çNŽóçÎ8l&œ gÂ?ᯮ3›î¸Àqã‚ðfáÍ›9·wnïÜžw"å‚¿¹DlŸ?ÜgØyœÇy΃_w»îvÝíA;‚víð½â{Å÷ŠÆ4iÓ¸§_fÕøÃMjLŒ‰1w- 7 7 ·½º{u÷êÆhÆhÆhú¥û¥û¥sÎ9¢á¢á"A£é‹àßÓx† |5Eª %…ÊÖµÏ42™qÄ`{²K-mtfi¶†,(U`Ž@ê0úÇ×§Òº »°K–%Ë’e-4Zh´°²seçÊÎ9r:åtâÅs« O,ðç¨A-Xè@jB'Ñ-d$y„üg ß\È]ÀÚá"qFù†‘IÄßC½PHGKë²iÒ£jïäÖ’J5èêÈe† Oh?›pÀ”a+¥]U(;T­ikv˜ê$ëT;HÕ’-¬µQi°óž'VMÊ\žw­lbZËw¦¥ç³N,®‘ñ ïH™n†"O»Ì§d]ù4ņÂeeû^Eʾ®^U\¿|¼bYyt•a͘ZÃÿϦrø¼ÁÇš½~ ¤/‘bâ1,R0*rˆì![óI>É'•¡1Mãœ_9§Ü4` Šk›Ö.¬fÇÚ}m7G‡èˆu:&”'$¤WiVVÙð _¸¬±áG¸¤LR$ÉušçÔÏ©SĬ%ºÌf32½AZ^z×Âô …׸۩…ê>»‡Û65Õ÷P_í!wð1rmv®þ|ÓÖA©wY-óêêôÌx›ædù]é ØË:ˆ¾ÇHæ<³€+²ršlª¼]8¡bÉ›ò¬Œ’+‰3,Šº\ø.ê}êú«ÚÑ3ÞÞΞ]гâ{–N¦‰î°0 G°íÄ:"m&–=ÆúÑbÖšn¦îÔ‚n‚?ƒÎ¹'­Æÿ¯ñyŽ2*¨ ¢42µL-S›3ÿ/ €,$ ÉBjCm¨ÍógÏŸ=ÖlT³QÍFyLñ˜â1%2;2;2›§Ãép^cêãîÃ0 Ã8%(ÙCÙCÙCùùùEŒ"FSYTYTYÄ9SÑlšM³?aÎÑOÁ9œÃ9n}­ekÙÚR@ ˆÑ£F#ŒõŒõŒõ²äYò,¹Â]á®pÇflÆf.Þã\…‚‚M¢I4¹UD£fFÍŒš=ñ|ÄóîîîÜÊ}KßÒ·‚Õñ%ðÇgÜ!i¨T=ªi¯Š+©œT $h¦ÈúÔœZ®W_+H,²“Χs)  Ù?:/7krqK/¢Ë겺¬r’r’rg¦3*FŨTPAõ!µÍ{¼Ç{¡“ üI¸ ?Oã¹Ù)Åõ²íeúóÜûŸê߸„–t)éò|aüÅøÄ.¤3³ìÓV§Ý©sü-qQòBý°ì¬d‹|¯š™¸Fý‚¬ƒ¸µå÷Fo5¿5«1Ô¬owÔ ÚÏêÉͦi÷6NÒ› >ÚÎǼ½ÎK­ùêÒ]jï¥Ñ♉j>âcòβ41‘4‘u—8²™âž€Æi‰¡§º\ºÄp«E']• Ð •Ri šÀ›ˆ•¯ê.f*"U†ŠûŠþµÖÕ;”—kí*ãýj§Õ<¨…*¡¥¬¢eªaNrÉWi÷ÞM.­—æ”Û­4þ­í»¥=rf½ßS¹ª ¬$»Ê¥¬c©FîµÌái»•Ä´Êb¡u˜"®¦ž$RY«òg<Œõ¬•ÎWhGºSBmsó»¹ÈEnLï˜Þ1½UýUýUýÝç¹ÏsŸ'>">">R;¤vHí´G{´¯gòàTbæaæ©oUߪ¾UÞAÞAÞ¡R¯R¯R¯¢¢¢¢¢‚O¯¶+°âŸØ©iÚ„6A! Q˜{$÷HVc­Æê<×y®ó\‚þý 9Ës–ç,çûç.õû[™Ó³ŠG<â¹1///íkÚ×´¯eŸÏ>Ÿ}¾¼yyóòæL¦Ó};f_ ¯Í/?> ¾œÞ@ X4S6SÙ¿¦¬hi¥R¡ƒ2#=­­Sûˆµ48"Ÿ ó #§É¨Z–Ρ€¤ÿhÃ= YÈâfèVº•n%{É^²W¼L¼L¼ U¨Bÿ=Í- yËþ:Üpÿwq— hÓOÕ» ™ß!Ó&Ó&&xýàõƒ×E­ŠZµ"÷É}rŸ¶ -h‹À/åF~5¨A˜v‡;ÜÍG˜0aâbâbâR¡ªPU¨Þßzëý­ò§åOËŸrŽ%tD'¡ú¡ßG¨í×xלOvRpRpRpa^a^ažY³þfýë5¯×¼^ó$q’8IL®“ëäúG›¨åÔÄm‰-±¥5´†Ö¨U«6Væ-ó–y=+zVôL™¡ÌPfðysÿŠkÐÿ–x€\º%•H%R‰rÏçžÏ=¯ÕN«V;ó@ó@óÀççgŒÆhŒæWì‹P„¢ß5/>ƒ0HU *P º¡›ãÇ)ŽSZ -…Vöœì9Ùsð¾ÂW¼Õ!„¥~1üñ÷u¸ŽGˆ ¶bEu‘Ò¾¸ªjKu´+¦“ª?ÍSM40’Mç‘©¤-j°…¿ùG¿ª¸™žHD"’šãÆ5Œk(™)™)™Éú±~¬ŸŠU±ª ÙuT,þ0ÜëŸKs}‘ˆ”ì—ì—ì×®»Hw‘ÈU|R|²¢²Ê¾Êž´$«È*’N^‘WªD6]Œ$ ¥qè¶ðÂu´ƒioÔCšÁ^Ä Fp5ôaÈa ch Ð &Ѓ:}4äVÛ)—©¼8ÿ'CøÀÈ:wú-:‘`¢‹:4*eu†iÈeot/kÖ—Iµ5zI Ýu:©)¬sM&k}g³Ý¤ƒö^ë6&QZ§mŠM6kß4Þ§7G}ž¯ÖJ™½dµHÊ4•4‡3ïDß‹o1[ñ‘ *'·Äo´§¨5³öJµ.6Aö†Œ¦Úµ+Q+ âAÁ´üÞ¶]ìÞgëzyŠ—Â !Ê•Öéø±™9Æ9¶,n 03Ä^ô몽ÕÑeßVþP÷ôMRÇ<×+£7K7¿gø¼GvûDÛLÿâæ9Ëß?ªà2&î—Ú¼?`“û‰Kx„tœÀ-¼¡_Ó•¸¬šÈ¥3ðoQľ×}EÉËØ ( à 5ZFËh–a–Ž?8¾enËÜ–¹®†®†®†Òi„t}üúøõñd)YJ–ò9)àŽ|´™éOgÍÃ<ÌãLv¹‡ÜCîa“b“b“B½¨õJ{–ö,íYÎ…œ 9²pZ%Ýd¯{#‡è!zˆ ý,3,3,3L5N5N5öHöHöHv˜à0ÁaBRTRTRÿ^ãfþúš÷¢NÕ©:gÄk³Ú¬6K=©'õ,/,/,/äÒA %”7QÑÿ`”.@ ¸lµïF¼ñn„ÕV?Xý ÝU»«vWƒE‹ ½¯x_ñ¾‚_qúý3\Ÿw‡;ÜÕç«ÏWŸoWbWbWR1µbjÅÔôféÍÒ›qW§{é^ºWðnøm†¡‰LÈhTq;öÙuïw–ҕLJé)mæoYöjN÷~!ÚýdG$Œ×µh ¡ò~?Dè=î•`¢a¢a¢¼(xQð¢&:MtšèˆY1+f¡}èc$FþÌœþ«³ÍÅ^Æjt&GI~dÎ2êÄ]´ƒ¹@6Šçˆ¾&Õ’Yb{f„h3Ivÿ¹ 2Žd7Tâ¢iŒ¦ÁÚ·Ôü½4Î{u~æçd?f|ón7=Ê×DŽêã§ú¾`ÎŽÖk~œ¿ZÕ¥ß#«í«{ÏH´ýþAÄþ¼Ógl‡Û)_?n/¥×ÎìNéÀQ³Vd¾=þÖ EEÿ‡«ª—ß¹E«¸c‘27vÐãõ+´Ú/Ùí>Ó;üP¿ÅáM]v›u5pÕè„…ŽÀ_¹Ï•$—X‰×‰&–iH¢!ð‚%ÿgÑŸÈ/úeSGô”’R†¿ þöAà 4¼žt=éz’çpÏáž¼JCÆæÎç™…š3›¸ç‘“ü?âÇ 4lÐ0´0´0´Ð“xOÂe »È.²‹4%MISþ 2È ûh÷3 £0ŠÿÔ±ƒì¦î˜ºcꎗҗҗÒñ>ã}Æóodæ=óžùx.aCÿp   ðºëu×ënв eAËŒ6m4ÚÈK…nÀløÇ¯NsIå¸L¦0…©s'çNÎÂO„Ÿ?á®á®á®¹˜‹¹øßã{>)ÕïøÕ\Ê*ÎÁÆ`²ÁdƒÉ—¢.E]ŠºÙòfË›-G9ŽrÅ—Ô"ZDKZ~ ™ÎÄ1–0…Ô7tjó¬Y¥«†÷®.ž÷|€nåáyŽý_8®5Z®×ƒïX¦Ø9ÿøß^÷aãf)¸„2OðOøåQ¿Ž1ŒaŒ+¸òÁ™Åé¬ÓY§³m|Úø´ñ±ßi¿ÓþƒD#ç¦õw†vÕ}áô€?ìQ„ A;aôÉzä2ßJ\EÌ2œ‰alI+ò„ôÃ$á{ ú+—›JŸ‰n[e¢§åçõÈ©Âø~k³fýln ðh³Ü½×ˆ‰mÇ8·9ÿÕ=ýsI—(¥ô™¥”¦. ”Ò#Ó+º=4PëÙù·G"=2•hà;&‡iLÂÈ 2ј?M:0‚™þ‘àÌwNZ· U¨"ÓÉt2}eÔʨ•Q1ûböÅìÛš¶5mkšD!QHÄ…¸¬ÅZ¬ýì~KÝ÷'0ÝcºÇtO°n°n°n«>­ú´ê£M´‰ö‡’us…~ ãUêPuuuå> ÚOm?µýÔW_m|µqËî-»·ì[‰­ÄV¼à §‡öׂ!ÂÅ$Ȟʞʞ¶ºÑêF«þ»ýwûïæ*îÓ«-Ú¢í¿¤?ç!yœzŒn‚n‚nB€V€V€–_†_†_†ÖN­ZFìD$rÉÒþk·êBº.ܶ³®³®³îcõÇêÕϼ:óêÌ+É9É9É9Þo¾#:¢£0¨ü$Ìa†hÈbƒè&z´dåa½æÝ쟥´Yà1Ý/Î~–åw|<ŠÜêM@àwÁåçãž5*¡êÝÜ»¹wóÀØÀØÀXá†C ‡òKÛ9ÈAÎgý[Ô …&Ѓ:a ]43L/X£=ZÀDZmÈ,bƒƒŒ?9‡Z‘ŒiMzˆ®2qä x¤¨)a(F~—#A„çŒÊYÁW:¼üîåw/ÄnŠéÙäåé—æEþÐso#`ÃYÕ³;ýRgŽômcÉ”Ÿ|ØèCOˆTùäpéÜÓHIãv84rhäÐèŠáÃ+†?6îú´ëÓ®Où♃ÌA~¾öskN"ÐŽp”דד×kÚ<´yhÈÛ·!omÙ ²ùðÉzgq–Ï6ð‰³ˆYÄ,â¶Ý,Ý,Ý,¯ä]É»’wæô™ÓgNÛšÙšÙšq%J¢$Êpɉ˜ˆ‰\Ëî0Üa¸#¤SH§NÞ;¼wxï WÈò!²Æ°ø—ôd.Ç —ƒv!ba£ûî7ºßÚ©µSk';‘ÈNÄ'ƒ;ƒ38ÞþŸN¤éÄ}âv½ÒõJ×+ÑvÑvÑvßÌýfî7s Æ‚ùP{œ¨€Ào÷&·aº> ãXUË7 ](]f2ÄMÙy¾ícUÓ…¯>ínÝè´S?|4"Í¡üR«L@àwég\ÄE\„Ì`¦?S¦þ̈ˆï ï ï ‘¯ÈWäË™|š«‰Yw†»á@¼‘‡eŒÙŒwL ãMÚ‰®0±ä{ñQ{òL%:@òÿïS’€0’-}Õ$ët[®h¤ÛÒfŸM…Í>é~ééÏS…siÔê†| ¦üÇ…«Ï¯ð¾â¾¹ÝÇ'OŒ^½$zÉé°Óa§Ã̃̓̓ñ ¾Á7ä*¹J®~¬<£áiåžÁ§xЧð€<\f¸Ìp™v2ìdØIÏXÏXÏXÑVÑVÑVÇqçtÍÿ¦ºåd4ƒŒ`yžÜsÊ­‰q¦ª l`cw×î®Ý]á:Ãu†M)šR4å­Ç[·ü 4÷´rÇþi¤0`èSú”>åB{_†¾ }Z®_®_®_¿Yýfõ›i-ÔZ¨µ[Á È2áOÖ —#– VÝNÝNÝNºYºYº¹¼Yy³òfU²*Y•Œo©«¸Š«ÿBáBNð”K¼e Xä3ùL>S¡V¡V¡¦­§­§­§¨¨Èå^ÅÜÁŸÕç$Ó™t&¹³9¼vxíðZÿžþ=ý{ï|Þù¼ó)é\Ò¹¤3Ÿžïkú5ýZB~ßsúŠp›Û¶7²Ò‹xÇNÏê³—5ZØ0â¥ËÛ Ù~D­WlP0äЀ–؃ñ$G…zø/$  ܦãÇ#ŽGÂÞ„½ {ãÚܵ¹ks^C†{1¸Áí'ç ?gpp³€œ’Ï/¿«½ S{¡ÞåÇÓê]ä/Vï¿ÁR§Î„© €þØþР "(ÏüUsÆœ1‡-lak/µ—ÚKÏí8·ãÜŽ˜Á1ƒc÷èÑ7‚/¹‰ÙÄl⟈O=ï^w≠EèWêWêW®\¸:ð›Ào¿1|gøÎð_ò.îâîÿ¸BÇb,Ær÷¯££s6êlÔÙ¨Gk­}´Ö}¤ûH÷‘œž:o2þ¹êq"Nĉó\7_k¾Ö|m˜K˜K˜‹û÷'îOxaJN.³Z¡Õ¿¶ûÀx‰—xÉÕ†ã|ÇùŽó[Ïk=¯õ¼ú~õýêûavaöb/öòA«u™‰ÌDfІ6´Û¯h¿¢ýŠèFÑ¢m{´íѶGÇ5ŽkÿY |i#äŸ;Œ–cà+xÀ>+®Ø´¬°òŒ2«¦šl%_“FF žötéw¢0T¡eá=Ò¡ Ù?4Õ‚€À§†S$hƒ6h#Z#Z#Z£ÝM»›v7Níøý‚÷ Þ/àµ÷ä=yÏ¿þ Ü\7 ˜|äóÞ¢ß`¾È^ Úíòåj·êÛí4ªo×.,<_»P-swkµLÙ’±ž²%"OÆ]䉈Àã8бÛ°çgF¤°ÒøûaÀ€a³Ùl6›iÈ4d&+“•ÉÊãÛo?¾½öAíƒÚ_õÿªÿWýmÓmÓmÓÙ ìva KX¾?]ms½…ûHX€X š š š`WkWkW+~ ~ ~#É‘äH L L L1s0‡wŠøßö.Ç'­¼Uy«òÖ+¿W~¯üÄ7Å7Å7o4¾Ñx.q9ðG1…)Léz€@ JP¢•¤•¤•$š&š&šVµ¦jMÕôFoô&•¤’T"±ˆý×öanu%ÉHF*P‘;&wLî˜Ê)•S*§{{{j:j:j:bVaŸ˜‰©óËz[ŠR”šÊLe¦2…: u¦mLÛ˜¶±¢GEŠÜÓA]©+ÂRþä[Äá[n;>c¬a—&”.>5è¥Ë ¾îwgï7í¦a éOî+ô†/Nbz õ& ð+T¢•Ü+P/@/@/ àRÀ¥€K-½[z·ôVgÕYu–Ï2x'qR¨°OÂKÀ€ÖøY`=ÓÂÞ€i!£[Öʨæ£5oèn0í¯»€éO§Ñ'úDNp‡ù0!áÂy?Çs˜RLÄä­ô÷Œ!Ü'—ýt"&bbÃs Ï5<Ö)¬SX'‡~ý>ˆÛú¾|ö\n%‡S(ŠA b \4pÑÀׯ5^kôïÚ¿kÿ®hŒÆh,ŠE‹¢…ABàÀ€€ÈÀ ‡¼î,¶¤Ã"Z³øý  Z³¤ù 7ÏdcŽwy­ý\}¼ߟÇá5Ε' ð3¸¥Õ:aaõ´ëi×Ón}½õõÖ×ݸpÀ—äää¸òŸõŸÌs,†9ìÄaW·ˆtžKštž£¾K’£¾“ÄÑÞI¢Y¨Y¥Yø³ó4#õÑ :Ðøé?!¤õ·kþ'Ñä‘<’ÇWä™fgš¹»ã;î ¼3ðÎÀ€peú1ý˜~¿<ÃGãná·©k¬k¬kì¯ç¯ç¯4%hJУ7FoŒÞð%Ó‘ŽtþâsXoáç0s˜9œ³JcÓÆ¦Mce±²XÙ±ècÑÇ¢5¬5¬5¬ù©Ã8ŒÃàüû°û¸«È/É/É/ù®ó]ç»Îwïß=ò-ò-r^ƒã0ã¾ 5¨:ê13 fÌ îÜ-¸[‹A-µ$^#^#^ïòÕG}Ô'_“¯ ï³®7Jo”Þ¨ýû=ö{D½‰zõ&ø‡à‚à[ós¹&¬æ}™üÙ nѰµPaî ºP½ú«šLˆ‰ñ„˜ý†¦j¨K­$¯uãä×eÙPƒb²‹ôDˆPé?à ^ðÂ0 Ã0æ-ó–y«ßR¿¥~ËÚ®µ]k»–h–h–hòó1œ_;·+𩡨äƒNlÌE6Òj½‘’8㜕‹^Û*%¾vL*,Hxÿ² Árœå ËqõÞÔ˨÷F,~ Æ#ú PBøˆúÂVPÁ BZE«÷5OAùÀÊSô=ÅüÈüÈüøtäÓ‘OG^¸xáâ…‹:‘:‘:‘;ì8°£n ݺ-èvºn'#ÉH2ò£©¼sÆw È™ãŒ!cÈÚ®²]e»J6P6P60wîþÜýÝ ºtÃu\Çu´G{´çƒP?‡L,X:ŽŽ£ãPˆB¾W½W½We{g{g{ë<Ñy¢óĺ§uOëžPB %¿^ô{Öˆ¸2œÎ•"ˆä%òy‰ú=õ{ê÷”vJ;¥]•G•G•¿rGqô_–úK8“šs ÒtŠ:u(êP"-‘–HÕ‰:Q'f3‰™„«Ù‡}ØGŽ“ãä8'(©o¯o¯oo±Ãb‡ÅޢܢܢܴçiÏÓžó­OãiüQ“¿òØýÙ•Ô~úÚ{׫âau€ 4¦Ïè$«9Pö½DW•½A5jP‹0€´*]@àg8ÃΜ‚»\O®'×Ó‰Ö‰Ö‰V¶Q¶Q¶ÉÏÏç•7Æ` Ƴ,3ÿy1²XäQWä!c‘OTÂW«…v…²B»DDßDJEel¥Âù{G8oÔÆc¿QÆLß1Ã=Õ!ÜC†Hp%Úp…¦@a¾.œÏúŒÀšD“hRmvmvmöw®ß¹~çúFçÎÎý —f/Í^šT“jRM>¼»5¨ùKæ{]˜ÆhŒÆœjŠkÅZ±†s çÎ-ŸP>¡|BJÓ”¦)Mé3úŒ>ãà Ÿã9žvÝXNåTŽhïv½ÛõnWÒ£¤GILOšž4=é<Ây„óÎé…‰ab˜˜ß¥ÕÃÍÐÄAäê\=\=\=œ‹Ø)[þ¶ü-ï ÒíйÈEî2jPPÜÆmÜæúÛ‚mÁ¶ÈÙ˜³1g£èˆèˆèˆq™q™q™ÈVd+²Åp Çp¼À ¼àDt^ê¼ÔyirÀä€ÉBƒBƒBƒÔ#©GR`¶a=AOР!ðÇG¶KHÃ!n{Á̰ÝÞ‹(]²sðôÚõ ì<)‰šç: Ô×Ïn‡Å ®ŒÈÄQB½ üŒ:º¿¶mÛ624dhãF5nÄ'õàЃô„ û,¨;É¥ÍâBÊê ½D*¤— ò¨äkdÎÐÈ’{´½.÷ E)úPŠäè‚ltùé@¹P½ÿ©DH?HXKb¹ín#ºè6âѳGÏ=»ÜÿrÿËýŽ G_²;éþSæ¿]PÇiDã¤ÆI“¾Û}·ûnîÜ!¸ƒY•Y•Y_r#6bãG¸â§Ãö°Yˆ,D|¦ˆ1c<Æx¼¹øæâ›‹Ój¦ÕL«áo_›Ñf´Ñ Ð鿜“S‰áÖ%º¡º5èÝ wƒÞ!ÏCž‡<7—˜KÌ%|.ïÄ—9é°°óz—*¥J©ÒgŒÏŸ1Á¦Á¦Á¦Ç Žð*1L[¦-Ó–ÛîÍôfz3Ïo<¿ñüÆê]«w­ÞÅ÷íd _2mp)xXq»Ê@8ª³7¨¹ædI_ñ Þ²®?¾Ð^ÒÍ„Jàáò>Æ 1œ®ßS¿§~O†0„!ù_å•ÿïéAs Ì>êÎG–£圗*aGŒE"Æ*[SMeë÷FßU¾7ªž±ôZõ fÇÀ5Ìõš}™ê52 —t™ÖR¬Åi˜ã4^  / CÕO%…Õ%”Præ;Í¡94‡Hˆ„HÎõ<×ó\ÏGšL0™`2aØìa³‡Í&·Émr›O…“‚¤üa•w®Î;¢#:rZÚ¤©GêÙ}k÷­Ý·êÝÕ»«wÏëš×5¯k“Ãä0|@!7·ú˾ñùÀ霡E\¦ˆ„ ;vn)ÜR¸Åq—ã.Ç]š•š•š•l)[Ê–þ,ÅÕo¡5¨q뜓’voíÞÚ½i1-¦ÅeË–=äœsøò_¦k÷ÑrGqT)UJ•Ò‚yó æ‰v‹v‹v›4;iv’L!SÈ–eY–ÅhŒÆhç!ÎCœ‡ÔN¨P;!}~úüôùüÚ,ׂB°ûÌGkøqé°Š¶Èƒ)ô¨%asO¼DÔ]s¢¤R̵“ñha1X@€7Vc5VsyµöjíÕÚ«q]ãºÆuåZåZåÚbÍbÍbMÞèÞèÍë¸ |žpFI2ÒŒÍpÂft† :c¹qªOªTx÷Ô­ðVÒ+Í•T´jC©h•VÊì;Z)¢cQ Ü ‡Øfc6fÃv?…Ã~ÉF´BÊP& ´¶7Çä¶í›ëÛkm¦^‹Ö®8<·Q¿TJW_~hÒó–á †B9ÔÅW² ¦Ð†¦P{_4AB/v‹Ü"·Ü‹Ý‹Ý‹Ã3Â3Â3êm¬·±ï/KäDNä21ŠÀçg0þ'L²3-êéIâez¶›y¶’úF.ªúFúSôgèOùÙYº1ÇÐ 2Ü‚ ´Áütæ/шçÜ“&a&¾2|eøêÄ‘GNyjÿÔþ©ýÄØ‰±cù'hGÆñGýßÏ—Ã’s]»‡{¸çrÀå€Ë°¾a}Ãúz,öX챘éÉôdzò™/¹§øè´@F“Ñd4·=?~~üüøgûŸí¶ØÄa‡Mä]ø8ùK{ØÃþ7Ï£A4ˆ·íôØé±ÓãÖwZßi}Çv®í\Û¹|¡k¸†kB| ‰HDr+izcôÆè ¾|5øªïTß©¾S™sÌ9æœg3ÏfžÍî<ºóèΣÓe§ËN—éæèæèæpTuë\àËä¯ 7qx n³zšŠ².%Õß׆ˆÏ‘ÃÄ P‰Ù#–Eº6ZÚP  •ª¾ìdz ÑŽBÕ |ÑpÉe^á^ÉåÎrg½fzÍôšUݯº_u¿Ð«Ð«Ð Žp„#=IOÒ“¼J†À?nI»÷Ù-¸²&piÃQQTÓ@Q”V“¾(­æ­4Ãö­Ôè‰Ñ%£'γ9ÏÖš£.Õšƒ“lOœ„þP@]TuØ9lñAVRö…ðœñ­ Mh7âFÜ êÔ/¨¿O±O±OQÛ®¶]m»öÛwlß±aiÃÒ†¥tÝD71ÙáÌpþ9ª;;ÎmsF§Žâ Oxùùùšo1ßb¾¥º¬º¬º,¹yróäæì1ö{ ¶°…-/þøÏrZà~i*R‘Ê0\B«Ú‡µkzLô˜è1‘üᆿrg8Ã™Ž§ãéxÜÇ}ÜWß®¾]};«Çê±z•+'VNä]n†’¡d(/zø%íráÎ6°MiPiPiPáw…ß~§9UsªæTÃ"Ã"Ã"{•½Ê^¥n¢n¢n’®HW¤+*õ+õ+õ¹'AOFà¯î¯PüÁp¯1fËè©ÒuJµZkQ(3œ(6žílì¦i­þ N^d'Œ¯q­` ¡ê¾P8³ƒ 95 L´¦iMÓš¦6Tm¨ÚÐJQ¥¨RTšYšYšÉ#0#„jû—@Qõ“6|.ƒ\$«´‘ /„à K±K+²*2*²n&ä'Ü,œ’ûuáík½Bµ¯i´]wG£-Yh–H¢\EQŽ4Z4ø2«à (uøW‡­Õýˆ„I˜D¦’©dêÅÇ_||kö­Ù·f¥¥¥^1xÅàÒiŽ4‡v¤iGbDŒˆÑÿ×"½Ð ½°‹±XR&)“”Ù±v¬+‹Ä"ñÛ„· oÊBÊBÊBp'p‚7ü'™ÜÇÆ[¼ÅÛøþñýãû+2™ŠL‡®]ºš63mfÚŒ÷¥^Xñ+çñeX†eòþòþòþê=Õ{ª÷¬|Qù¢òEÅöŠíÛ¹°Tºn ÅqÎaæ".⢪«ª«ªkžCžCžVbVé:éÖ×­ï4ÒiŒÓ¹¾ÜPn˜<8yHòeseses^O†[íøs[ìÃî¡S"¿.«ˆÉ7¬[ýf‘ÞÀN´zÉöÁ²È«ƒî´ë.,ÑÇ` FfcˆP{_(ZЂ/‘p]ëºÖumhƒÐ¡ ì¯Ú_µ¿Ê—œˆ‰˜(TØA]w‹y˜‡yhe?¹Ó<“šá™Zܤ µ8Ž—Ökt”­.[ËXJ™R¡ Ñ 1m0ZB‹ßÿo i­›]µ˜“bþiJwMwM¿œp9árÂcÃdž ;ì<°ó@¾ä]r—ÜåÏP×mff€—-v¼êxÕñjèžÐ=¡{šÌj2«É,f³ÙÆË#6DC4üÇ×^=uÍ–š-5[°8`qÀ"Ê/Ê/Ê/Ø+Ø+Ø Np‚¹An¿tâ´}¸u½z;ôv«««59ÖäX“cLw¦;Ó÷çôyêÂõ¥nè†nRs©¹Ô¼E^‹÷-Þ·ÜÕòhË£»òwÕîª}‘ý¢êEU‡ ötØ d‰F‹F‹FÿfÔ€Àï¢Ë1€"ùbérÉëñCtˆ£tqÚ Í”.Ú8pûc·1>]¯i7S+‘-ã2ìø0D |Ap¦†<àÁíKŠ%žK|—ø. bƒØ V{‚öí Üö­|ü%÷g˜Á«ð«êß¶#¾­qcu…Æ MgÆkl’F¶ë&ê¸kÄ¢±è€èÀïù·ŠÇÕI±TW»}ä„‘FNˆŽŽ>]xºðt¡ÁdƒÉ“ù£žážñÛQˆB·©{W÷®îÝ@HÀí€Û·õªõªõ>°nÅVlý•–ú'2ã0ŽSÂ!á$œ„O;mì´±ñëâ×ů3tÌÐ1CùŽ“Æ¤1i?;VÐ@&2‘Éí°ÚfµÍj[ëÅ­·^ìÖ×­¯[_¾äc<Æc>ËGÝÏÅZ(¡$ä-yk/¶ËµËm7´m^Û¼'—/¿›q×õ®k“CM¤Mø<LSŪbq(¿‰Tä@ŽZ¨ªíkªäí/oZݵ"f;ufGÐlí2I¼$P´‡y(€ú0‚¶Põ_Übñ$LÂ$ÎVï†Þ ½Ò@i 4°ìzÙõ²ëo+ÞV¼E’„7xƒ7Âó×C8‹LCSLƒ6DÐF€h$j[¥-©mUa;U£ÂVi¶ÌEi&î:¨¸«Ù¦nÃÍ6i~¯ž­ù=< †ÎáÎñê4ú0€>7yò/‚Ë(Ì%iâÌÐ]dÙuðÚÁk¯½ˆxñ"¢^Ûzmëµ|óÍnÖ¯Ò|ŽöI™\2wš·øÒˆF4¢¹MçíÎÛ··¶imÓÚÆî¦ÝM»›|™Y˜…Yœ¼Pa_8ÿ¿"©€@ò^ÌpŠñaÃ)nߺ–¸}[¯A½¦õˆsÅ…âÿ¤—wà!2‚ à~/ô_`ÊsóßjPƒ§Ííò ò ò»ïzßõ¾ëÍ37ÏÜ<ã­á­áÍ+r0QLÃϵ۵´ki×242424²éž¦{šî‘Ê¥r©~ðƒú¡úýûº–ÈPd(2„¬`ÕÍÑQ[£¶Fm=Úõh×£]M{˜ö0íÁWð²‡ìá뙓ËäºåññïpïpïðÀ… ê^н {¿À—³fXwE‹Ó~éBº.Ìeæ2sùÈGþ¯tÛ ÆŸñorË+Å+eBÀôSÓOů¦”Ò'c)¥ôq ¥”¾~D)¥Vø£Æ“Çä±00 üYÃf¢%äq‚4 1çp@އ’ÒU±Ã2ª,æ>ïßAá¶àÅÀ>Öº:Ï5ø0V²ñØ+TžÀÇJ¬ÄJ˜Ãæj†j†j†>ó|æùÌ ºt!肇‡7SEÔ‰:Q*Làÿƒ3 DÔá uØö°A\F®€h†h‹h†y„ùó×x×K®ñ&=Lf›ô`£øpQO-‰=Zò;Ôþ5¦Õ ¬À f#³‘Ù(ž"ž"ž²$nIÜ’¸¸aqCã†îøfǶÛÔƒÔCÕCI8iKÚê´Õé ÓÁÿ¸ÿ)ÿS>4ð7ð7ðçÏÆÅ|¨¥J@@Èj²š¬æv÷1îcÜçÈÄ#LŒRE©¢T>O}žú<åä Ez"=Ñ1Ç1ƒ1Üäååß¾|ï›î›î›.1’IŒøºúwÄüœÓ —„«=Ú£=yCÞ7¢¯E_‹¾þeqµujëÔÖ¹†»†»†O0š`4Áh{ØöÝÛw_ÿîê¡«‡^5HñIñ‰ê¬¸¡¸ñ`–R¤=è©HQ¤Äö¯‘ÖH-Ù¯µ_Ë­`$’D ƒá—Œø/ýo‘ÃÄwˆSQZ£üüŠ6UGPH’PVBÍéPµx‰7c«1[:JÒËvÐü)¡·€À—÷š¼In’›4›fÓlƒñã Ækºiºiºáᑬž¬ž¬b‹X^š›øÀ¼Ø«ðUH§*¤#HÇK¼T¹ªÆ¨\³‘läuÎÏël¥nám¥n;½¹¦íô·aZí߆Õθ|¤v‚Á€¤Àj 5äÒ›ÈE-jºÎ?É„3g`fP{jOík“k“k“¿÷íÄo'z%x%z%zuõêéÕ³óûÎ¥K=;ôðÐCûÇö±ö±²U²•²•é²tQºè}ÜûçïŸãGüˆy#•sùàôXþPPPz‡Þ¡wÈäòC^ç¼Îy3¼3¼3¼½‚½‚½‚íoÙß²¿õ€> (=JÒ£üJ WRH!Õ>«}Vû¬ÈEä"r)¤…´Öè×è×èósÌÈ@Æ?¾®¸Ùô:ɹH )!%h‹¶hKûÑ~´Ì`3zžž§ç¹n¢sKç–Î-ûKö—ì/5Ðd@“þëü×ù¯³8fqÌâ˜îÝ-º[dcÔ"Õ"SR“'-¾µ÷öôÛÓÛhFD¨6¡µÊg ‡ &Q à?,á ga0ü’ÿõSÐUˆC&¦@…Ym2{úªT:É#¯‰JèKì4m¡£«™ÿ ù_¸«À §'ÀÜaÎ0gˆ)1%¦ÕúÕúÕú¢.¢.¢.8Ó8 X’©ÿ”‚› p¥€+Z£5Zà np«íR³¶¶K*Òž¦BÞ2ycÙ­±ód·¤Ñ=Š¥ÑµÇW·­=®ì‘h§äÝ!"2A2T¹È@4U?™,Ÿué1ƒ1Äœ˜s¢Oô‰>yH’‡L;¦Ó.Í:Í"Íâ»iß-þnñÔsSûMí×#¡û’îKÒZ¥ÎI#>(™,™\º²Ô«Ô+cdÆ•Œ+ä,9MNS9Õ |´É¿5´÷,Îâ,'¦IÑF´Ñ«>¯ú¼ê–––äëë+j&j&j¦ÚªÚªÚÊKÓrŠ4RH!Õê¤ÕI«aC˜r¶œ-g‘Žt¤ÃîpGÒö¬.虋 (BŠD E E ÙìNv'5¦ÆÔ7p70S1Uz^z^z¾Q\£¸FqMãšÆ5kìÒØ¥±‹[µ[µ[µÖn­ÝZ»«nUݪºUô èAуH«H«H«;êw·ÞÝúF3©oR߬uï’Þ%—\}}õ5S_â q°‡ÝK»—ÒHqqƒ —¢Œ¢ 4Gô Ý¨ÕÃr!JàÏöp)ãNøtι©—Âf-‰ùz¯¢Õ¼oúŸ§ì’ÄÁßåÚø;g~®‚\B õ&ð¥AtˆÑá¶jŒjŒj¼õ½õ½õ›Z4µhjaìaìaìÁ—Ô"ZDK¨1? gbrsÏ6І îKÜáÿºA4d¾Ö’uÐýQ¬*ï6û¸¼³ß(‹ÙÿÓ9Rt‡ ºóú!§‹Ô‚„`8†c8Öc=ÖsóßÄ›xor‰\"—KÆ’±d¶2[™­ø?à‡ÿrâbÝou¿=vêÞˆ{#â.)›(›ÜîR¨*T=>þÞî½Ý²–‡“'ÿìi"Q$Š‘0FÂ} ðŠæœ×û¿#“1çz1–Œ%c9SÕ»‹wï.wîÝ5:6ëØ¬c³´{h÷Ðþàé."""â?^“½&{M‹‹‹7v4v4väMÞó8óu5þO ײk±k‰ñ!>LW¦+Óõ—Å Ú´5hë¹Âs…犱‡Ç{øÐ¢C‹-ºÞàzƒë âçÇÏŸÿ\ù\ù\yþÜùsçÏ­?¸þàúƒÝ»'vO4²6²6²æFÿO¬Ï›Ÿ7?ßb¦·Ì[æpß¡‰ï‡Nÿ©AsLàÏ>ûóH!YÀmÍtÜaµ±rÝ‚¯ή™7߀ ”.9=xÙÄþ"Ï'|O wO @ #HŸŸ§ñ"Yê3I–´íÂ+Ò¶Z×"j]“g´Ý*ÏÅd¡q¦Ì_ºº3ÖzЃîáä 9Èôcú1ýD"‘H$bF0#˜ŒÁüG/b6ßl¾Ùü&ý›ôoÒ?ü@øðýbûÅö‹ÞtÆðÃ×[¿2þnj׭^·ŠC)¥³ËØe¯žRJé¯l^Ù„ËBõBõloÔ;]ïôo^æ®áÇÄ1qüÏZ‡uXÇÿõŸbªÖ…SC ±ñ;ãwÆï.×\®¹\åååâTãTãTÃ}¨ýd?á?ðdF2#™QËi-§µœæ?Ë–ÿ,34fðŸ4p>»_Z·šÀ&¤?éOú3·™ÛÌm\Æe\þåAšššcÇŽë=Ö{¬÷aßþ‡}?2~dütÓÓMO7ÅŒŽ3úFĈë'¯Ÿ¼~rŸÐ>¡}BÓÓÓóvò˜|&ŸiÉ4f=âE¼Ä3$$D=Äâ½úSô§? Ù²Å/Ùõc5,5,5,¡ ]èb ¶`‹0Ä}™| W™>8…GXÅYÕ5?–›+›Öö0|&í'º`6ŠÍîjiª¯P"T¹Àü´ýgùµz æ`æ ¥(ÅflÆfÃ1ûYI? P ‚jì¤Ç±j5ؒͰ¥•ZÔB¹oþrå¾Ú×[µÆê–GŒÕm³ÇÚfeGæOÊŽ,i[\¯¤-&c2&Ñ%"ªI¨&(R!†bˆÁ‚‚@À¢5`¡‚ }Ð}ˆq $ƒd ’CrH—Ç@ÕRÕRÕ’â?ÿx¶c;¶s›"‘ƒÈAºSºSºS~P~P~Ð6É6É6©^R½¤zIVVVæ‹Ì™/Ò Ñ Ñ Ñ_¥¿J•AOƒž=uZê´Ôi©3Jg”Î(Ö’Pƒ² ïG½USOk°Öàê´šö5í1е`-Šú»ä®Õ&óvæí–¤.ª¿¨~¦Ó»ÀwiÓ¦ |5çÕœWsîYݳºg•¼7yoòÞêàêàêàŸyõE_ô---g嬜•Ó*ZE«xD%”P~Öþñ«° «¸Ñ&_+_+_ë­ä­ä­Ä#Û#Û#»¾¨¾¨¾(Ñ:Ñ:ÑšÌ'óÉ|*¢"*ÒôÑôÑô‘VJ+¥•åýËû—÷WÆ)ã”q|^[Îäs€ûàFÔæhŽæÌ=æsè]¢«: : :@ÐôW\þPþPþ°ajÃÔ†©ÁEÁEÁE.C]†º µ`ÿÀþáÃ7†oJ»—v/í^p®à\Á¹¤¡IC“†^]yuåÕ•qAqAqA9Osžæ!Þ<}M—#g¯…r3î´5lÑWh¿ uPT‚Â`‰L‘™€ª€Ž:jÓüZ㘥…ù"K‹š»µù5wß%½+|÷¦²cePe‡ÿrþ@øÃYÈA‘ˆÄß¼‘«ä*¹jœfœfœ¦ï¡ï¡ï¡c®c®cnlmlmlm÷½Ý÷vß[ì¶Øm±ÛÚÔÚÔÚTßRßRßRn#·‘ÛHGKGKGK^H^H^¨ùªùªùâk|¯ËV—­.[o‘o‘o‘ÿ,ÿYþ³¼…y ó¾Z¨Q¨‘ü}‚w‚w× ßNø¶]M«³­Îõ¹²Z•µ,kùZrÜú¸uƒãž O…¼Z_µ¾………UWª®T]Iï”Þ)½Óƒüðà‡gMž5yÖ$³0³0³0muÚê´Õ¿ò#Ÿã9ž“çä9yŽ›¸‰›TNåTŽØˆ? yüßâ'8a†`—djLî˜Ü1¹C}‡úõ=Ùúdë“­M^4yÑdf3‡™Ãnd7²­Õ¬Õ¬Õêß«¯þ½Œ#2F¼¼þòúËë¼âûE\ÄE¼Æk¼þ›~EÝú CÂøÒD ‚6¡Mh^O½ºËu—ë.wºët×énÓM;4íà÷ÚïµßkË*Ë*Ë*¶m5ÚJÇHÇHǤJ?”~è¹â¹â¹"þdüÉø“·Ko—Þ.M?˜~0ýà/oG´E´E´…íÉöd{RêB]PˆBþ®@çHD"’ ~Õé¢ÓE§‹çYϳžgY«bUÑ“£'GO®¸\q¹â2.Ü}ÑWðwÿrø3îÃèú#à ¡%ݪlYÕÊ«5fP2ûÔ@Jóètýµj‡¥'œøÙ"„Vüp&;'(™ dBMUjÐ!ÐA †"¥B­|w…Zw'Àh¨Q„ÑP›Î6I6*"«¬¸˜ñ(;.ã] ˜J—üÊùoànq›òzr[¹­ý û™ö3-ƒ,ƒ,ƒ,Â,Â,Âô/ë_Ö¿lºÍt›é6³Ûf·Ínûûû®4\i¸R®%×’k)o(o(oÔ4¨iPÓ@ÙIÙIÙ©¶Um«ÚVÏ+žW)|Rø¤pcáÆÂü½ÙÀ³û©S;žnãfãfS©¨¯—±ââ¹3Þù¾óM©Š wÜìÜÓ¹gý§õÕ_äçåçåçeÕþªýUçkÎל¯y¾ð|áù¢Ö¥Ö¥Ö%Õ6Õ6Õöuòëä×Éñ©ñ©ñ©QÑQÑQÑ)ÓS¦§Lç4ë¾âˆ±"VÌ æs‚íÆvc»Ñæ´9mŽx€ÿ3Sþ-Þâ-óóó[ÉV²•q3âfÄÍ­­­²_f¿Ì~™ÈCä!òPù¨|T>X‚%X¢9Qs¢æDòùŠ|UUUu¨CÄ‘8G_Ó×ôÓ›ìuW&à0žŒ'ãɲl,ËÆâ!â!W\:@:@: éЦ+š®hÊ4eš2 û7ìß°¿›–›–›–£Áh0•¾•¾•¾¥þ¥þ¥þýû?ö¿9àæ€›†& Múúõëׯþ»¸8v¤i‡X€Ô”šRS•£ÊQåÈ«ÕuÑù¿MvÎ.j‡vh‡A„A%{Kö–ìÍ_¿:µ…Ž…Ž…ŽÅh‹Ñ£kkkøl¾u?›ê àc„5\ÀXôE0ð'‰¹twóãmŸ¶ŒªgºTuŒô0"ëÒûŸìíÏ®%«pk¨ ÐIh ç  ]èB»Î?nO=ÔC=8ÃΜJ7êÃõáW¸ýÖ)õ¯ºÐ÷ÝœV+avç¶þîB=6‘¯ÝË®aßI2™»ŒV‚ç›+6Ò«••†·Mû˜öÑðUߦ¾M³D³D³Dsæ:Íuò›ò›ò›*/•—Ê«ähÉÑ’£Å3‹gÏ|ÿôýÓ÷O‹G*õþàûƒïf É’1$#'#'#'áL™„3Ý ºtSj(5” …‡ÂƒíÂva»üf=¢…¢é¢A¢A´#mGÛ±Øaì°ß_‘r‘\$™´4iiÒÒ§›O7ŸnîcÜǸqèèÐÑ¡£í+ÛW¶¯ôÍõÍõÍ˺•u+ë–7!oBÞ„w›ßm~·ùiû§íŸ¶ÐíA·ÝÒN¤H;‘gŸgŸg_÷üd.™Kæ’åd9YN5©&Õ¤kèºgpgøyë¿ÅeŽÿjPgÕYu›M6›l6í°Ùa³Ã•¨Då÷1îcÜߨ½±{c'•ÆJcy7ònä­Y©Y©YùüÂó Ï/t.è\Ð/ð/à W¸~#Ò>ðÁWø _‘dYÀý³)l ›R· Þ!½Cz‡l;Ûv¶íø*ðU૦M›6mÚÔ¬‹Y³.ÆEÆEÆEªTUª*5Ý5Ý5Ý5éXÒ±¤c³g=κ9ëæ¬›³òÚæµÍk[;¸vp퇈‹Ld"“QgÔuVÆÊXÿ4UÔù÷±˜‚)˜‚=؃=ÜãÛø}ã÷ß³ÍÙæló'®O\Ÿ¸VÆWÆWÆózùßâ[|+ ~_Ãp×…:ÔĺŒŒÌ¬Mc‹èü‹aýãBŸ¶þÑ5Êæ%P{^õäõý|í’=õ[n:xª”„`;FÒ'˜„½(F%ª…føpÒ¢^ð‚ˆ@´B+´B€ä ‡_@¿‰›¸ù»Î9#0B¶Z¶Z¶ZÍSÍSÍS>Nþ•|œô¹ìœ4_Òš~/Ù¦÷M#{›í±g¥†É¶dûÈP¦vHí€w… Ñ®ÌtfzqJ±}±}ö¨ìQÙ£r¤9ÒiFuFuFu®*W•«*šP4¡hBîæÜ͹›ß|{ðíÁ¢”¢”¢”ß_ $˜“`>¯'7ï‚„Ðv´mGÍ©95Ç",Çr” Œ%s€9@’˜÷Ì{lÁ¼A[8ÀªSUÐoÙ46ÙÈf³Ù¶l[zˆ¢¿"¥`¤0R)¼œ¼œ¼œl_ؾ°}á¡ï¡ï¡ïzÊõ”ë)---^á{f`FZxZxZxÔƒ¨Qýýý_ïz½ëõ®„ˆ„ˆ„ˆ_ùažð„§(F#Š¡ÚT›j³“ÙÉìdÌÇ|ÌÿºòÄ’XKšI3i¦zŠzŠzÊ«5Vk¬šMj6©Ù¤yæM˜7!rnäÜȹº·uoëÞö\æ¹Ìs™Â_á¯ðbñÄ≅R¬+Å\lã0ÿÉ[©»ò  hðŸûÈ>²v¡]hZJKii݃$·%·%·›²MÙ¦¬GµGµGuó’æ%ÍKœkkkÅïÄïÄïH/Ò‹ô*\8¸pð·'nOÜžÜyrçÉgáÏŸ…'.M\š¸ôWng43šld#›mÁ¶`[pŸPÝŸ›wç>­Û¢-ÚrWt­ïZßµ¾UµUµUu›Æ¦± Êe‚’Ÿwç ý*T¡J˜wø]ˆ½/rÚЂöaE¯‹AN”.w2ƒ–. “…6h½5¬_Ûñ·¿/aK#ú+¶*¶Ý»\y¤òøÓ,Å6ŶÅU·lÜÒ¦*Œ c]Ÿ¹-v[lýÎúõ;ýú+ôWH^K^Kþ‹ûç—Ì4f3I<‰'ñd™Gæ‘îàîð3‹œ/µ7¼á MhBó#×9ç½;°ƒ›u&»Én²›iÁ´`Zü²¸¦Ÿ¦Ÿ¦Ÿ}GûŽöû<ìó°ÏÃõ%ëKÖ—œ±9csÆæ®ÿ]ÿ»þ '<Ž›7?nþ· nÜ6¦lLÙ˜2êÙ¨g£ž¹*\® G G Ç_©OâIïpåeF‹ž{†_2MñÌ¿ZÔ˜lEîÐQЃ¯Ð ÿ9äó3j›±›¥6R©Ô@j 5æKó¥ùRW©«ÔU#M#M#M}ºútõéêÕ;«w–ÍÍÍd˜&©d*™JækækækU¨*Tªx­x­x­¥¥Uu¾ê|ÕyÅ*Å1ÅJ³Š•ßRuÑ=2ïòãÔ6i“Õ»€ÂL†@k£6cÛŒz|i˥ߪcš0M˜&ä¹En!á§&Ô„šÐ'ô }Bkh ­áf7?£8(Rç , $$Ñb´-:„¡CØŽlG¶ã/Õ©;Rw¤—¦—¦—¦WªWªWªSo§ÞN½RRR {ö4ìYeXeXeX]]{5÷jîÕ/¼xðâñŽÇ;ïx{êí©·§R‡¥Ký5'ŸÛ¸Û$™$“dÄ#ñÔ™:Sg Ã0 û£uÈ…TªÆ¨Æ¨Æô¸ÕãV[sé\:—^p}ÀõSý¦úMõ³še5Ëj–C²C²CrºaºaºaBç„Î 11רù¿k’»7¸Áä’\’‹ýØý|'ç¾Uõ,õ,õ,—Ù.³]f7qiâÒÄ%`GÀŽ€Vç¬ÎYÓ,Ò,Ò,’xJ<%žiýÓú§õ“ÄIâ$q§âNź=íö´ÛÓ²—e/Ë^ö+¿÷˜è˜èÛžm϶§õi}ZŸO õùèzqÉø¸œó0óÜ,Ü,Ü,,Ã,Ã,ÃRz¤ôHé‘´7ioÒ^øÂ¾¼x+—³V˜wÿ—ò1g¹Î±/>$7.z]mW³JZ‹,šJ{CO–#~&šf°V=@Í2…Á5PrœDöB¿ø/¼Â+¼âcôÎéÓ;g=Âz„õΈ”uuuP­6Zm´,P( g³Ùl6› ‚dØ6€u`X‡Êù•ó+çWæWæWæWnªÜT¹©jBÕ„ª U}«úVõUÚ)í”v555жжж¼ã °Ð·ÆÞêéßs¤x¸¿¸?{ aCdÌUæjRUìÁ؃d™Ï\c®ÑXv»«±«éFº‘nd§³ÓÙé?Kíô[¯Ïçõð ÝJz‹Þ¢·T¬ŠU±\&Q>½§‰Þ}Ñ—ªSuª^¼­x[ñ¶køÏ?íéÚÓµ§×3¬gXÏÐí™Û3·gÍf4›Ñl†Üà˹–s-çF<ŒxñpàöÛnOVOVOVyé套—’ž%=Kzö0úaôÃèÛ^l{± 0€ÁÏªŠ›J»&º&ºF'Ò‰t"kÌ³Æ¸Š«¸ú›„íÌvf;s!•¯b_žŠå”yì’ì’ì’LmMmMmåååÑѸءءØ%(A P@ñ+µÇE\p2‘+°+Æ…qáÜXkÖšµæÃ1ŒcÅXyÔxÔxÔøøø¸ßu¿ë~×ã¸ÇqãÚ#µGj¬hZÑ´¢iqLqLqÌ}§ûN÷îÝ1ºcôZóµækÍ7ùoòßäóW_†eX¸À…8'ℱ‹±\Dª•ª•ªougÓ?)Þ,d!‹µ„%,3<2<2<ŒŒŒ̲ͲͲ³¾Êú*ë«Ê¹•s+ç¢=Ú£=¶a¶ ç¿•¶èü$[HKÖ•Ž¡÷&´ºìÙjýP+O5ÕVU×ÚùÊÖt#Ñè&>þðδ‹6/ç¦\f(9Oú³„¶ÿ Ÿ* ð3êhVгô,=keeåÞÒ½¥{ËŠŠŠŠŠ ò ù†|£l«l«l[“Y“Y“©LR&)“*]+]+]+Õ*Õ*Õ*µ*µ*µªŽT©:Rc]c]cÍ®dW²+i2M¦É¿yuBD„Bk¨’*a1ÄxûÞ³RHySãKƒ3þ¸ÏÎÁi.æb.³ŸÙÏì'/ÉKòR¥P)T?3pÅ‘âHq¤þý;úw¼ÆzõëÓܧ¹Os{Öžµg­[?¶~l¦c¦c¦SiSiSi“Ïæ³ùlv«ìVÙ­bücücü￾ÿúþë´±icÓÆæ¶Ëm—Û©HE*S>ćøp®GÔ‚ZP ºŒ.£ËøŒ³'p'ø•œi˜†ixЧx*”FJ#÷÷Úßk/—6.m\ÚŒM›>6½jmÕÚªµúúú÷Ø{ì=¶òrååÊËñ Ø€ œZ?'Ó‰ÑÑŒˆ1"–²”ýÙǘ–––åCˇ–ƒ¬ƒ¬ƒ¬½­¼­¼­¬$V+‰ñã Æh M¡)ɧ’O%ŸJz‘ô"éEÔ¤¨IQ“î¶¼ÛònËüfùÍò›±bVÌò‘¤1iL“ä9À2,Ã2h‰–h‰jT£šs|ú‡õ(‚¬ðoð†‹¦°LµLµLMÿ&ý›ôoRRRxYOÎLÐîû×3 féK Øíô}ßÿtS5×Yû/u˜ëª© Q5$ E©¢Àþ×x~?ñpÈÓ¥ D›KÖ©ÆQ†NšA@@@à·àò;rib,û[ö·ìï6Ðm ÛÀÚµ/j_¼-[þ¶Ñ}¢ûÐpNÃKKKkÖÖ¬­YKV’•d% $€ž§çéyº˜.¦‹ë^KÔ@Ô@Ô ÉÒ&K›,mеA×]}}}Ý©;u§2=™žLÐ ò™|&Ÿy$~$~$~Úéi§§¢í£í£íÓI:Iÿ»…™ÀL`&à.áÛíÎvçd+?aéßß‹¸ô|1µ7hoÐÞÀ5¾ªDU¢*y÷4îi\ŶŠmÛøÏ§Q…QÂø)ð›D¢…WÜv˜Ø¥íÐÝ×#J•5ó'èDéÒ‚!cBZmhÄ•û1È#¡Þþ ÁF0·)Y(Y(Y¨-Ñ–hK´µµEq¢8Q_’›“{ŒÇxŒÓ8Óœ› 7ëÉ;$4ES4åCM`¨A jB5ÿMÔuɨú¨Ï§Ñy†gxFfdÀ0¿ÿúüëó¯×Z¯µ^kÝ>«}Vû,ËBËBËBCbHÌÏ*/†Är$ùÏKn¦ßÆ0þ•þ7Ñл° »¸@mWSWSWÓðá/Â_8Ítšé4¦0…)/'j kX œÀoE=q»øÞõÊâ„ñ¤ªÊy•–)‡Ío; ”殈z{ö± ׯ›¹2âÌZR*Ô›€€€ÀG€óåu€þµ†Ë—@Ýd=ïðï˜4&°ó`ªÉIDATIµµµû­ƒ´.i]Òºr9ärÈåq>ã|ÆùìØ´cÓŽM7¾ºñÕ¯^¹¼ryåÂ9ÕÜ[zoé½¥gÞywæÝœsn̹Ü+¸Wp/'O'O'O.Ôµî™k<¸ñàG}µzÔ*R™™Òát‡-¶XXVYVýìÒ´Ò´Ò¼†z õ:Ðm Û@·}¹ûr÷åÞÞs{Ïí=1ëcÖǬ_¿4~鹡熞º8yqòâäîA݃º™ØšØšØþÖ¯==="—Éer™ÿ4åÿð§lþépqíjíjíjÿÿÿ˜Vþ­ü[ùk\Ô¸¨q Ð pGpD þ}ˆ?Ö‰¨?6à Ž@ÚÍÂ~%iµVìh–a†Š$LC2{˜i*™¸1L`SrH#“ç+ÿƒºËýáG8`Çÿu36c3?kË•¼Zÿ¹ÔÍœj3˜ñ~á6° ŠQŒbò„d~Þܼ¹y~ìlØÙж…m Û¿u-f$3’ɘ2¦Œ)†b(†òø2^þJ[syU¹®¯ñ¯ëŸªªþ©pƒpƒp篿vþš/¿[°åg¬<ÑöÜ£Ç8’trñVÞð„NáôÝ¢Ù/Ðò%…ƒÛÝqö®ãPMµWj6\$ñ‡„ÊøhÔ5Ѹ ENcä.áéAzL„üòPu'õ¹ês­eVÇ­Ž÷:7àÖ€[O­•S”S¢f)Ìæ÷Kª7Tox:W‘¥ÈòôõiëÓö—g`3ƒ™ÁdÙGöñ=¹ðhCÂðWîPàÏÁexè¨é¨é¨èèèú½ñ{ã÷FÓTÓTÓ”/ÉeøapoŽ#{|&:"±ÍkJo´ˆÒŲQ϶÷ìalÒSG¢ÈÁ€("ûÐí>9\fPŽ—x‰—L ÃĈº‰º‰ºÕ-hZaoŸN)¥É­)¥4¹¥”æ˜PJ©ys;S;SRH%.’U’Uä¹GîñI—8ê†Û |\Ì`3^øàzÇõŽëðþáýÃû;;;óm×aÖñ‘Â'Ó?þñýX”@%ºA'1Þ¹Û+¬«gBÅ =ZkÅ^ÔÍÝ—„iÌ—œÍÅ1ô€3™o8Rü<Ž]@@@@@@àQ73¨ÜàÆ‡ÀZ–äk²,Dl`Sªz¿êýªWzî9Xe±Ë8ŠJ±[Š/æ‡ä‡à8Z EMr jÀ§:ªkÖ ·ø¸pY¹”R¶°…m†{†{†»ñ9ãsÆçL£L£L£2m3m3m+›T6©lÂçUÝŠ­Ø*Tžà31z "HámÑ|¥ËÚ~=«æàü݆½_3×sÀ·[f†üb³ŽŒ"fBå üêæUå23\[»¶vm¶1lcØFçåÎË—óå¹\¶uøòñ°ŠQаc¡‚Lö¸’üЧYC¼UKédú^g›´\\¥1@܃Iâן4Yþ·Hë$äš‹ÝØ-Ú&î.î.š(î îÀÿ›¸»¸;÷×_9Jàï“wäÖO¸L6°M¦Y¦Y¦™2C™¡Ì0î`ÜÁ¸ƒÆmÛ·qp;°;iÈ.ÓU¦ ’JaÆæ­,[UQ‚ÖŒ3¤VDýd/¤çÅã4H&‰¦`!Ipƒ‰Ð ŸÊ:RŒ‹ñ5¾VÕñ¬ùÿ8¿r”Àß çŒ´‹°ó0óJõKõKõsõsõsõ­ÅÖbk±…®…®…n¢u¢u¢5ïo [Ø" iHªðŸÅÇ›q/‡J²CHwnG^vùêJŠ‘/zÙ¨Ä|‹*ý>šr[® Ý‚Sˆ„ÒŸY~?qˆC¯ÛÓ]Ð%+%+%+¥úUõ«êW¦§MO›žÖHÔHÔHÄxŒÇx~†^p˜ùò±c½#Üfu•;; úµ‡U³Eú¤yŽ&¬»Ï¢¯£©Ë]‚N¤ë ua‰M@@@@@@@àOÀ™àÐ ø¼ªƒJ•Êß“¿'ÚmµÛj·­çXϱžƒT¤"Û±Ûy}AùçÅGn*ºñÈâ¶+îÖŒS¹•}§L®m.Þ¬& @÷Ó£2M±úuˆ! ¬ÂnhA 2¡1þ0u}Ö `˜À&ç2ÎeœS®U®U®5žj<Õxª¶H[¤-âÒ6aæ`Ž üóÏâcc­G4Mæ6ˇ֜Su)~^}§¦J¬"HjèBšbRO³·ú:Ô¢æÔ¨A*4†€€€€€€€ÀŸ„›w?ó8Ï)¸—[”[”[äææÊ4d2 ËHËHËHä!yP‡:Ôa X•÷OácϸïG xý²[Mzíð²$[kHæ2÷H+HØô­ùn­™òqXƒb¢Â”@rÁpøÓpóîÜlz"A³hÍÊ*Ë*Ë*SÌWÌWÌ7Ê7Ê7Ê×ÎÐÎÐÎÀ4LÃ4ÞÐø‡ð±gÜ—Ñkˆ†"ˆÊ)š×D=¯:V ÆžÙ‡KôµÑ_'ß%e˜þLQA MH>¢¾€€€€€€€À— 7ïÞíÐã0ãJ»–v-íúþÛ÷ß¾ÿVæ s9XM³šf5 7q7± «° Ð „pÕÏŸïã~ÏP T;”j KªªÏ*ÇAÉ"³Y%M£>KÕ,%Dy¤îA @ˆ„ÆøKpóî\*'þøoñ6#$#$#D!Rˆ"ã»Æwïêèèèèè шFÂ&TÞçÏÇžqŸƒs¸Í f8ÍV«*T‡ßï®èUÕD4„ÉaOQ:ëzHóÅã5r’ôà’C$D4 |¸¹óy˜‡y°†5¬K—.9œ× ¯A^IŽ$G’ceneneŽD$"Å(F1oô óîŸ1Û\Þ€kx(Š$»™.0…EE¨´«–L³—M¦ùÔKó©D*Ò0ÈÕ!Í5ÁðC@@@@@@@à#À™à*¨ âal`›ìõÙë³××l¬ÙX³QïÞ;½wšs4çhÎÁ œÀ ìÅ^ìòª~Î|lý 5¨Á=( C.X0¥'•¾ªù¨eGÒúhH_Ы¢rFybY ·N{?w9Œ¯ÑUh 'õ¸+°­Ñ­K•.*]”¿1cþFõêÔXì±Øc±¥(E)t¡ ]ØÃöBå}ž|lÃÀU lñPå£Ú³ûØ¥äq#2QsŒt7ôÕ)wæšIBÑLh Ì=ÜÃ=.=­¦Õ´:Ã*Ã*ÃJ1K1K1Ëä‚É“ Zƒµk FÒ†Ä †?V ± ò9ñ± w tná%·£d¡â]vª&ÒXOXˆ»’³¤½i3MW9AV¡ ñC@@@@@@@à#Ãù¬·E[´ÅP ÅÐ’k%×J®å·ÎoßZm¹ÚrµåÖ­/Z_ÄDLÄDhCÚ0†1ŒQ‹ZÔ UøùðiBB{Ñ“¸Ãm¾?]U¢XV³IuBµ—(1 =Ë ¥®ê&²]a2|á*4†€€€€€€€ÀG¦®Ï:g”[À™G3fUnVnVn6´4´4´4e:Êt”´‡´‡´œà'tDGtªðóá“î´vãGnû}¿ŠÖŠVÕójuUŽ$ŸlÅ$T‘iDij¡‘,ëÅ•!ë7¡1> ܼû\Á¸Â®¥¦¥¦¥¦ùSó§æO% ÉB²Ð£›G7nÆ.Æ.Æ.¸‹»¸Kt‰.Ñ*ïóáÓîFt)Ý9Äå$•]ªø¡êJ®ÊÙNŠÈmÈ !‡ djÚÒ®`À@Œa¤¬ÀòCŸnÞ=qˆ#šD“hÒLšI3Kû•ö+í§¬¬\•R•R•B†!doèK D¨¼Ï‡Oc¸a¡ µPå-)ßYYV=¾fGíh²¤ÛyЉ:ßK/ŠºÂ:¨%[Ñö`ù!O ]DÑE\z¦2¦Œ)cÞx;àí€üù3òg”%–%–%r†>EGÑQBýÛqƒŒˆ'va2yCBIýD­ñ½º^¤tq›A)]vé넛΃ŸµyhƸã¦cÂà+Tž€€€€€€€€€À/ù4?/ƒ|¼BøS:”®-vW”×Ê¡Bƒeãh¸¦ŽÚ Ù{µ 2 éõê ŠúJsBq ;)pw…†ø$È ƒ ( ÀVlÅV’CrH?ËnNÍ©9FaFý¬¤ÀgÀ§1ÜE`@ˆ”À&0*6VžW…BDæKˆØkì1.jÖÒïŒ"4öÊ%Ûí•Rò‚LD/ F@@@@@@@à“P×…Qõ›ÉR“ý3ãÓÈAªÀ‚B1DHF.òó¯UíV,‚&´˜N£Ï4Ê6K´õÉ“e1PB %Nbi-4‰€€€€€€€€€À/aþžËÞ©²S>Ð6ìSú–ú«wßykÅÉ–H†qyd)‚ÑPh_ò7î9)eY•+4…Û‡½BM5öHG‹ÓtæËFJÚó…ö‘ðšD@@@@@@@@@à—üM†{Æ7Å1å Ôƒ k WLõma†hN—HEƒ¹2d<`#(¹ ü’¿ÉpÏ—I+Ö –XAWµ›êÐ1È뉦kÕHŠEI|¡ï‚‚’»€€€€€€€€€À/ù› ÷Ì.EwËÀÍ`Cè%dØh£Ÿ¶“¬H"‡rh`;Îá2 ¡ u¡aêò) ÷|( â6+kµ]Ø–ªº_Ô‚ÈÈyÖ‹½g±M·\ë=”¨B…j(;^G'¸ÃQhº|JÃý)òQÆm*ØËôDQ¢bÍ0Ñ-æ0±TÙV&1š3Ô“±˜¸4í°p€¥Ð0uù”†û]d£Û¬6PÍR­Ë/®º§< ¶`ÒHO(XÐQú×5Zªµ— í5ÆkˆÑ–0F@@@@@@@@@ .ŸÒpC.Š!¢ôU©±ÅÖU)Ê Dƒ‰dAÆÖ°ë «¯WÛ¨–*.EA  –´„5Œ„†¨Ë'4Üéd  ° ÕæµrÖ£À©ò¸b:ª™r2’ž£i‘Î Y+Iš´³è(ZPõam¡aêò)gÜá-r1ú`kG×ÞRi¾\¹¡:jL YQÌö¤±ú¥j©’ñÒ,‘!ó! µ1Œ¡+4Œ€€€€€€€€€@]>¥áþžã Ó…˜ã&ÎÂ’¾ÍH*nZÖ`Š×{u9¸S®^¾)î§a4ù›}Í=ÔÎ|;‰Ñh/Õ;³#,‰§ Ùǯ?z¯ò¾#Oï½Õ¤Õ0U1—fWqcà€B(Ë/ =f¢?öà D`P ‚SàɃQ!„òƒò…+œ †œBà}Íe¾SÞ«Š5ÌU²çú¢cƒ³x+Îi:-ß`©®Œ5WÆ+³µ‹Ä!B7–AÊ!Å^ˆy›5&tŽÿ•ÜO<YžJ¯ìGÞ@¨Ä¦³JjFÞŸµï§$žü(q'„BÈçÿO Eá8›Äò©5øX~ÏÖ$sFw/ç‹—•©ïZ§Àü²y»r:¥;`-n¨oªf½©úñ :®ï¦ñ¶¾°LT¦žŸúnî—¯çœwË¥ŒE>ZãÄ8±qj6u%W¸ƒ0‰0À3¬P('¿%î„BùQ100è A„XÙ.$ã{Àr MÌ?£º­a‘¯YZû¬è½¦X«œÁ­:æÝXU“Q `WªéE>³+¬§&“üTêjm¯|ä§·ÞzÒ'òÅbçëž¾¾uó>›í/øO±™XyTæ~Ü„"HDR B€*T:-äç?°„B!Dƒ ŽE–ˆ±hÃ*³íl¢:™ï㊭aÙÚÙŠø¹l[¾bþÃ5ÞÖöÞ͆‹Ñ SiÓ:söa覉w¸£«—0$e§Ñ}S‰‡gÞtŸýêœÇ¾¿KÈc;Žxž}`}”Ç|‡>ØŒƒ!B€ ¥ïä_¡ÄB!ä_±õÄa…"4b ˜3 |Ÿ¨ƒ7›ñºÞŽ<Õ³-î[&1´P©|YZdŒÔyª)­”¹Š¥Žn®ä,žJÈc¤¶ñkÓF™«ÍÕ]ëúôðÆ~w«¼ø.6¾nÒNÛK ŽÌ÷Õç¼– 3&a5Üž©Q9 @‰;!„BÈÿE "L°BÁd4@%á=‹Ãnu¿Ä€ä)­­2ä_cΰîe»å]™g W —ã8eݧl6„[XGhüÅ¢ý×#É÷¹¡yî´4ßõOOj˜*XŠZÚ^Pä‚/[£„©Åù6LÀ~œ†2$[1B!„Bþ[M¼ tÐ žpº²fÌ9}·rú­Ú·ÜËÖÎÿâÝÊ¡ÆñœO[ÕEU}ÂäöýR^IisóI3;Vç|ÊÎcž¼êŸØäPÏBB>èokFÉ'ì/5ÓQŽ]†‚ëð„´!B¤“ðc !„Bȯ¥f(P`ÂRŒÛ0ovNÙÅóë¶&™Ö¹r>Ý[.Þ7·¹÷²b5C.¸^vP5Û,åÕ̓•Ìê ~R·Y³VÊ\(|±xä€/óv\­üøôþÀÇ7"–ÙŽÃrc4²9ÌÈnªgøSˆÙ8†Ë @€•†´þ((q'„BùO¥Òš îpÅmôF}¡Û„Ñêk‰[ÃÜ7¼?z$ö©[*(´|çÌù;d‹×ÜÖ¼WYæ›ô–eÖ·jm£Ÿ¯ó’·œ³a‡;½jø1mn³«Cžì?WóÕô÷öœMŽm¼óFqÀcÍ^‹o²OnÉ©"þï‹wB!„ÿGh!#&XX'<ÀNÁ…½bS”ù¼ `kR¼|VÅwÐ2et¡h<>çâÌ2“ÅYì„ÑÉpÙ\EhÆ¢ÐO³V›_fÝ`=¤LÝøàQñHŸÅ[®üà^ÌÇ_òÙŽÃ8sÀUÔã;p™?GWÌÄ+|ÆWZæéïŠwB!„ÿµô©si#Pe!ìÌËòæü †a«­a³9C³ÖðºÔ Ð<Õ»ðùp«f,aº`í$dŠ1hvèÍóÔaF“¥ã¶BLo´¿öäIÃÇæ¨|_m=ú‘I¤elûÀ®*ÎÊ%’×T嘆àø#ðNË_%î„B!¿%[¶e›£] "[ƒ8œF)ÜÄîJ˜©É(õ•ü›ÜÏW<{âé¥6åö)¸0ÓG׀ꦜN+`zjɪ §Šµ…}ÚFšÈ¸â)« á«f^ž|?tq¾Ëã?x(Oÿ¿×‰ÒÈa¸‚§ö’[ÿ;•ÓB!„òohÒÍ 35QF<ËÌl\ú&âkq“8ºoÛÒ•óžåx´Y Χ ë²WY–¡ýÞÔkc×·m¦öÔ6wZÑcó6Ü|´ëu]g2Díün Ï@ŸÀ–y}óî±M*!3³¯ÌÏì/ÀÒýK!„BùYé“flDkTgïÀq)}CŸƒ.*®WéráI_öl³ói»ús>v|«ÛIiWR ß4rÎùË7œs›sÎçXÍzê0Hb¢#`¸íhÒja,‹Å#LD/û 8@™NÈ_…ˆ‚È|F"R쳓B!„߇­på8ž#³0k0-QKJD6&i–q¾yÞ¥oÖFÛáôäT¤Ur’>J¡œÝó¤âo+¦ZjjGꊥå1Þ26ŠÊ¢Z¸±ÒŒÄëo_uÝäøÌP;;::+ïŸ'¾M剕 L½° çp‹@86²p”BH¸€‡ˆG* öê|*¦!„B!äg¥ïB!Cf'‘Š‹ì¢°#}Ã¥½;U,½á} ®7 ¼”›sξãœó›[8çü݃£>›ý8vµ¡•óYz\y¾k`禇†n,ß¿ ¯ûCÇ úÆé&gÏXsvVÜ´ïÒA†Dݹºˆ¾¹¼YÚoØaicm€b„nâ >Rh!„Bþ0¶¤Y„A¨Çn°L¨‚T˜|dï¼ø|«Å9e-ÕÇŽlmî8Ó³ü‡VNÄ:Ë¥%ºàÒüÑè3^ÒÀó'¬KÝ­¯åÔÒq£4MøˆAbîˆå±ã“‚—å¸ÝîÕÅú»_1¥“_¥õ·½¬˜‡dÍ•| }x‚·ˆD,íK<ÑÀÖ?öC‘ÅÇ#³Kì»Ïqï“<±=Ð °;)4„B!DX`…*ø°%ˆW?óÞp›0°S—2eÆÏíi)Õú3ùHržh]ìsËb/»NߺÀk½xE÷µ÷š²ÍòÞl³@žàÌzW ì´pS.KN¥¼z—Э’׈‹"•KE¬‹ÛŸâ¼èÊõÚÏ^o›ø°Äéh¿$]н&^pD6ð7,ŸG.û{³Ý þ÷W`¥ÿbïö³àƒ-˜F1!„Bù3`õ™ˆ Ø€^È”µ•Ïu·\©N¾êçm}&¢¯‰óÛí‡'LìÚ9±lW@½ôÏÍ×È·¤ç›ÅSä,{>¥ò¸–í¶p>ung³Ú-¬pû¥©uÇ·‰â|âüó8ŸÞ±ë­—E®k6*­’±p¢s‚n²Ö'ýѤÅBöÉXŒÑö]zÈèýžÄÜZŸúJ¾y{8ñ&„Ù„ XðmQB!„ò»² u†3\…CB^Æxy~×–Œx¯ò‚Â%óžñIc÷x}\u<¹b·‰³:®—ZÆxË,‰ „‚¬{Á#äó…”¡†zGÏ<ÿúnýÃëFQ®hÊ ¼ÍžâyÊu¯Ë§aúwVsk>S¬ù“¥Œ÷n§/ú]•å -¾ƒ[Zòo ª+†J®âæÈ ŸÒ®&v566Â4Å%v ØÀ¾ J€á<î!)H£­¿¹F)ù7°m³æ‰Š !„BÈK\*œf»àWx–*ºÝïsRë3Çû1_<Û®_yίØ9²Î™üž¶ö, G¤ýÉa¨ ÂV «Šyh—þÈ…îgvó.5ïKÝÒ¥'%Ÿ7·½Àù”3óª9ÃZ·vzìʶ^jDØŽîœOoßµóóÎ5M{Œt¯Ø¦P£ŒÃÇ;Nýî}^f/Y+viñؾKO[3w•hjn¡<«ÊDŠ !„BÈ@€† èŒòB_vqÐÀÚ#B«ßçüv­a畳s (ñ¨ø†IN9yèÏhv³Ì{™^`ôÐþ4/»$è Ad]q[žì +–þ³Wΰíå×z;ËÌùÒadZëIœOKíZŽg ëÖþxʧ1qmŽp>éiÇiœO=ßeÀûiÃʵôš«üž‚k¼õÎåö§?š˜fM0 uQÁð†'DûL94áøÿÆ ” ù ±Z–²A,Å„B!äÂŽ±º¸bÛ.164Ô¿œºà¢yÐóÙSúlæìFöaY[>¬êÛž‚K:Ñ•=¶/äôÏdˆ?í÷CFd>±•¬"kŽÁø.‰ÏùÀgJ†’3kÖ*S²bÌ“QwÚå|Z….½­µ'ÌlßÔ6öyÛÂꃰ  s>5²K¦×[/j>qèþòÁ¶fÊíVßùhú£ >b¹àÎr"æûoRøÿBX“ê.Å}í!Žf+XYŠ !„BÈïÊÐØ6…ì# fÞ¬0+~vͼÓÍ*së僊òÖW—n|¥îbs‹1Cu‹dEÔ 5Xe<ÂN þE¯"¤ëÿî„’ÈÇ*`& SXK¦Kß0‡ÆlnW¦¬ù¹„!¶ÿh—6•8Ÿªë|€ó‰3;¬Km1Ö¯ÍcÎ'vê0ˆóéJ·ᮃ½š]ïWµz17 F]\ú£I+…ž,0ì»iÅÖÿȼˆºÇKŸ´m‹åØyÖ‚bB!„ò;I×ÿ,¹ˆÁ,Ù¶Ý`k¹/!Ó•Ê—ƒç(ÏÏŽï׌óËs¬^¶„gÐ2[!;ÛÁ´?‡ý¯+ÿ£Ÿ^Y(’Ŭ¬ŒéúÕvá¼pF‰ZÝKîyß`Ø×–Ç8Ÿ>¹ë ¥û„ËíÛ¦å[¿ÍcÎ'å蘋ó)aË¿_0Œ·Ê:L(o*8+K,.–ï^vcëŒsXŒüÈ{÷±}`+ù¿­9Ò¸OùÞöˆMcá¬Õ!B!„üNÀ±R¸"$%Xmd×ünæYY¾õîu%~Ðmίfô~_ð”I ÆÙŸ4”yb¾½¢]í9-£”®Ì¦ !·Ìò ŠMÂ>ŒJß0Gu¯Šy'Õ®¶«X¹¨“#»´>Æù”AKóësw–¶}쬶eo˜{û…œO_ÑuãëOƒ5=&¥r¯"ü:lH4q;Á*°'̯í»4öžrÑmǾ•<ág¸ˆo™M¡˜B!„üæl©©HÂ%Á›·ín٧ʽܵ9¿Ã†Ç™¼O-è3ØTíbð ·¢Õreõ½†3XžÂK!'«è¾ØüÙ*ãµ!ঠ8™ÝeÍÒ7ñÑ»Tp\3±L5c1ˇÃö·¬Âùt§®9Ÿx¬Ã¾”c.¶™Êù¤â]9ŸVªËÃÈÉCÛ´˜:êxålE:û^s¹ã¨¤?š8‚E°ø„ èŠÒÈ?Jáÿ…£•Û¤Uµ×‰wØ{Ö®ÐCG‘!„Bù 9AÓÑUY1GMç*ß~³dÇú®Ù•ñçžõS8¿9lhâÆ c\j%²Êl2Û"¬$VK1 ów˜¾'ÞpÚ²fÌ•¥â.&§oèï¡wy7Õ­FæâSÃOÛ"óiãºÜR„åjÊoì¡¶^ê–°=‚8ŸúºKÖÈþÃ*´ñS‡„”·cÂÛlà/ÃÞuÐp>}W7¼90¤Aóv‹>Öï\¶d ca·6ê“°aí_¥Û´M8ç-ÌœO1už‘°eL|ÛøÙUj)Õ6ÏlŸ«žŸÓÍÁeÌa;‰Ý耒(`àÇØúØ¿_Xã.>\G8WD¶ܦˉB!ä7Ñ*tg§kÛ1£oO¹ÂdÎï\iY}¦nß_3éÞ›{<*9F²ø„élËŠ½p„þO5‘búršŠÈ…lì®3±+}Ã@xÞwóñµb¶B%#jyÙ"Œó)w;ã|âÓŒÑV°,˜¹ÊùôÚ]Ì_2Ž k3pÁ¥º7JÎä¥õønÊraˈ=Â0Ö™ùÛwÙ{ú{—Ó„; Û¼NPxÆõìaå™@×!„BÈÿ˜ acX6ìE*Na@¶“~Áî ·ß7Àôöôà>1œß 1l視»ŠMgãXY$IbVv9ÿߣl/b`¸Qè$AÈÀ¥oâÑÇá½îËä U •|õpÐäf#8Ÿv·kiÎ'îì°%¥ö˜ƒm6ð aóÚßà|Ú󮞱Fh£]R/¹l™ìý3ìq[œþhb?ö„õÇ< B%ä@柶þÝ||1­ÕÓüMý^xÙ×µÖ±±¬]Y„B!ÿ3é&m&°èo%%›‹Ž-P{ç×</R^j4°üÿ3»ÔͼÈ{‰kSvÕÃflÁ_.ý§ÔY(ÌÊÁ,ìgEð }CωNC6Œ}\9ªH×w¡ÃV¶ ã|z`Wj {Û¡¡!pìÁ¶þÖé6´ïÈùÔžÄ?ËÚ5šÓ½öÐ’ y¸ïñŒÞß½n±6Ì[X ¤bË1[%º­(h<ê ‚xRбºŽÓ;jëôžYºp¾ùÏ– X×ä=çÓºŽæ|r¥ŽWRnyÓæ¤2fºöy9Ÿ6»Ë•¤c»·}´Ñ·Ù«JÓòÝÍT+ÞôG6²Šˆb¥°SQ ÁÈò§ØÊ_ÏxÙ-²cÅÂÁûíÛ"ôeOèZ#„Bù ÿèKÖ 2+oÛn^¬ò ÜÙ8¿Rdp!eê¹ùýÒœ9Û¿i¹Üæd¹ok#ºíØ·2s¥P[✮?žÇma++Èô ]o8ŒÕÅ è^f{>ト~?à|Ú­.IœOìÝa—¡úØ—mËZöO(ØÞó)‡:0¡s‡«|U)7¦ø®€¾ß%ñ؀Ȣ+ÛΪc,êÿTNóçØÊùì°z¶(—Ó϶GöÖ°dºâ!„Bþ¬óÅv„5Äu}í¹û7«?µí§nºÚxpeί4çèëYU›ìí÷²j¸h²æËýØAüiX+þðÆeôBC!€ámú†J:µsèÚõSñ#y–<Ÿ8pLÓ4Χd휓óÉ—;UO Û¾MšùùøyíÆs>½k×b WÇÎm´IÓ<¥S¹'û´ö(f;š0^ðbÅ~>ûg˜'žóY)ÝÏ?XÎ1ßÛû”22 ë…@d€}Z!„B~5oxÂUl'Lbýl;zièWðç·¶ »f>yêYŸÃ¦Ûç› l_À;Ç~ï戫èÁ޳¸ž~âHò/¤Ø„=˜--:°ëß5i¯©,Ïíߢ̇ükï_ìÔh*çÓwtç|âå'S£Ç¶h++½'Üjߎó)}:ëÇ'ŒêPbí¦&O+$o™åŒOPú£±6؉‘‚޹àV jÚøÝ¶2Îgzv«0ÝrææýA#3ž(r³±0”Y°A½Ã³# ûp/èB!„ò‹¸Á :€LG>–Î’Cí¢;ÇV­j³.`^¦µN¥æN´}çßìp'[¿= Æž]&4c»¯U?óGXƒ¸ *8…ógÙúá988$ÈÙD<ÂV GVH\„ m Ýç8öÑó¦OBy úw/”gYîbs»œÔXµ¶q ¹ˆu©PPèÀ kÚéDÍÃmÓWkÙ=מn{gZÚñ–Ï ó5ç7¾Ú_6jÁUа ¬…ò’WåÛ‘„D$Ú¶Z @ý ¿kΧ/è*/Knðª¬Ù¾+¡pÅ8ÔBYúTB!„ü"éú_¶_lÛãFwì_úç7Ä!Ÿ”zç—÷Ÿ{ûè—Þoò½È~Æ{(v 7‚D?¡;E!üÄßV^¡ç²D6%}çŽÚ÷š‘½ò•Z’Ïçq³~Ïïå|jB—+œOÝñcŠyŒ¹Í}kï ÙÛÝã|šW—ni]Æ·nß~ë –9«Ì*R1s¯$€Æ~–±øÊ†á.Ö£.r#ð§­¿U?<çÓ‚:¿ßz¨e¾*ËXëÆ°PŸ>„B!¿kÎúÄþˆÕ pàüúâ!Q³ÆôŠ®ØÀÖ^Ê"æûil¡ éo°ºç|ÀÀ …øm„[†hœCØ,曾¡Ãí­ØëZÉðИû7û&6žÍù´O]Ý8ŸT¡cãÎqÓÛž2—ß­Ý Î§ììd°^š¸£ãõÍš¶«˜¯ü‰ìõý_~÷ºs‘+² ¬Æ¡>*Ù÷KÿË)&%@=ÊUhk^ŠÅ-buk+³2äDFxÐÙ'„Bù7l½¬Ù_ñƒàÅBÔ`ñƒýš=+<ÛËݯµKC¥sòi#Kó¥AêÝâÖS7¶ã%¶¢§õšò’w@/¼‚ŒT`¡pþWlÅ3&(PlI<ïoTV2sOî†ýhšÂ0v«ÓüMM~Kq ½v4}ø$ÜR3.ävÏÞõŠçÏõ DD¦UîYpM4 Ì8Å0Å\ƒ5f—p°ýŽÂIÙc›¶ÊÝ*Ë«ý×_Tù ,z{Ýï™×õo}*­€—çÛ…<ÁDx²wاÆò{p…Ö^H£‚Cÿ‹ ¸:yiÇ”‹gzèê?qè¯uÓ”°ÿU`  ³O!„òo10!Q¨ÄÚà)Ö Aðë,<û'µ8Óÿ¾eÇ™1}p~kû°… 6¯\ôŒý)V6àd àïD÷­0c ÆH]„êìèÿ×j1µ ,T;äÙù]}ëç|ê².o8ŸÜ½ãÇ´cç´ ²†Lj÷’ó):%YOOìÒqÏ:¥iÏŠ ËÌæ{é»FI,Eofb\ÅNtAûÿÑÀVŒ¿CEçÏšIrSùª0€m°•Ô³ð€3_B!„Ÿ¥ Ñ–„ñ¡ü.¯ŠÜèŒý£ŒmâŠåwÞæxRË¡(=±è僯Í×_;æû¤sÅLgŽÈÂ*À3¬È߉Xíå4ôÆdëFõoÀ&à vNà8‚£8ŒI[ßÜ=ò"W•ëÚßиã¶çr\®ø>\;ý>­£|B|. ‘¦š}L­,­=­^Ö€B¡È Ô³vÔØ²}yËŠ•“KgË–Û/7¿†^Xµ܌R(€CØ/dWYg¸À®öwõ‹WlÄe^Ï)I³[r–Æ·þ ¸Ã‘Î/!„BÈ¿`ë-5Ã……³øÀµ¼0ºvË)ûÎo·£z…œnÊÓ´ê– y°ØcÙÐýÓœ×%mNS„×b(«¡šx_Îí¥ä÷”>æf˜aæaE Õ õP ÇqSHb›Ykëtë¶½ëíUÚ®v$o“;/:\Éû~ÞW¦ù¬9¡i§}©»¬™ö6Íh\ʪ§¹y÷|ëO+mëV ݹªu½ªŸŠ7ÊêìÓÁˆÆtå/Å×ËX(°¸ÕhŠüÈ1Ý2O?ÓÏx¥°iíŸÞi¬§T*Øwñç½'>oK®œ–—uÁy,â«Q}éüB!„|Ç6sH4Ai!7ÛÊLj_.sýá3•¨PnW¶ƒ<·%“õþÓ1ùÊ’»–ÜtÄÒÅÊ”ãü /ˆmƒå8A“>þ騿‰7À+Ë€˜,ô`Áì±2™—àÛj¥²–-¢ \ÊÕíF¿àÍëgëï3 P)yL=,û¬~ÂÏÎÈQšLÒkŒÇwhŸ”Œü²ÚóΗŸÏ+¯}hd?V!Ù1Ö@©Ã×ñ4 ÇNœ´lµ¦›bR)4áTûÉWÇ n/ù_sïhÿð°)¸ƒÕtî!„B~ޏG¸ÅìÉ\­z%[Õ4•»œkÐcs›Ó û–áüÆ™¡–Fîåç„̳µaF6ïìOfèœäÿ–þ̸@-¦¡J²û°à,(oÛƒú š•²¡Þ½<³³e¼r¬ÇüúOy¡Ior>µPçɆcÕ¶5ŒI㎷ýÊùôr]3¥ö_ }ÍÝA­Tý\ìcÖ¡>ÑÎ2­ýe“p=„.¬=ó’}‚K LRK¢_¥ï- ÓÄKÌ•´¿Å,pú6K%!„B±ÓB ϰ=ÕNª¿*”f“3´O‹¢E‹È^ÂV—ôiòÔó)׋½s?ö躡j±­HS?q †@ L°PuûŸVúû I0À„0œÂ->2Ê£/ª£´”C¨ÈvΛ»Yô >AâIHÄœw Î ùÒ=cá§9â*|É6Øg B‘ ½S»3hwŠ#Ù¢Æ_r¿ÍÜ wð(ÿ;åç߇. ¿>õiæ+.oê}Zn¯åÙˆò:±+XÃu|1NÁì8~z»œOéÛɘ³V†X×+¶wÈN!Ûè¬B!„Ø¥ë!g¯X7<´m·}]sz¾²œ_ï>ÔÏ|ít‡>Vkÿ+‡Ô­îZÜ5[S[©´XŽ%Rÿ&Ä|X 6c’‰9ã*>¢jØÏx)Xòið,´t¶»£Þ3Î'wëtŠóÉÇ;4e·¼ía£ÿ¸±mp>ÕÐ…™…•ë踽OËŒ•ÏT]šS ÐÿóË ( O8 ‹q)ÃçuŽíXi¨!„BH:¶šã樒,7²ÃW{Gs]vu¯e«BƒùYËn«,—p2ꆟ,p9W„æÌÀÛGß6w WØB«ƒbåeh‰¥¿ åy2‹¶§FóT”Öã¸Ê¶²zÖóÖ—ÖÏûs=¾±¼Ê‡5;ŽÖjdÝ1ëâæK÷ÞýÒ]£Y!×Ò¾×=Ð,68:¿jeTóEùŒk¬oñ´‚Çy÷®u—Ö¬’s]Ö$]6‹<]B*¬Po8{Vqè¥ë`ÚPÍ!„Bˆ­Ý+T飘ŽZ-Ê0îÞ™ÕñÉ{+da޵œÕ‰i;Lwào]Ê}ÇÜ[wàÚa«—2D­ÆV° ¸S¸Š~È¿![]‹-•×C†¤:òVü sÅzLÚ±@öÀìn-oݳðúÍ><Ú~ªyÿü“³Ïéf-Z%Ä¥Rr¶Ÿ¡€ÚCj3$š—£Håodí›qLy¬rãd£pרßýÍç1Àq€¾ÅŸB!ä;\(ÇÎ0O¥¦ú–ïò9ê¹Ç)mhï–«‹ÔEvK ++8UÕ.Ýt¡]Dó»^χDUC V¡!ïǯ ”½·žü½ìóÄà‰è€qÊz^ƒÆXTAQöV\dÞXÏu;<мjY»ÀFõD‰Z{*vªfÄÛ˜WÂaÑG(«™¡û¬QÍkÌ#,/Œ LžæÊÕöfÿäÛô»û!}Ym1Š9!„Bˆ-á–!CD6¸Aá£y$ºµU}Kî‡Wvºu²¸Z(q±ˆiúötmÑ+-X&a»pEèÏbí 4¥ŸÔü½¥/6O†&ÌÂÜãù!¡o3|%¡ ;kìj¾liz,èy»ÈžÕޝu_ü~»f›œIvÖõ×ö–‹›´Ææ 0¿¬ÝAΧøtº>©TV%Rl¯ÂŽã-¶Rä !„B˜·0ËÑ ®^Oþ¡oeë³3Ö~žœßz2lÞ¯~Õ*ݱµG ÛÙ äGNRôÈwÒlÍ„õ˜ è™WXElÀПZåÅë*9Â27?âÚ¡RÍꆉQo|—¸/|Ñ`V¹QöQâN!„™Áž`‰Â¡kgÛ½ôÍ`}µFœ_k5Ø¢¾±ÿËØð##{Ï͞ݷç0–·QIpf+˜…ü¶Ï—DÛaëÃpnßšw„~BËŠs²ŸõW¥ôÏu=¦õ–-CB!„(PÁÅöÂJ¶R™£^ä› ¹„¼ö‰l9§zRˆdõ3–´j¤ºYrí9vÝlñúõcì fbaˆQµ|<÷‚ ",°B¡p’ÁVTc‚Š}`ëp¾˜¿Å5 C±7kÂ,Jaµ˜ºå^/ü°í»ÄÝ¥§ö€¼(Š„BùáMETU³òÙ<­ñçú:5ò.xÒm‘G}”õZò]ãÆ¨ÌŸ+¦8/_ºÕý—Hƒz¢-êáôÐB†&P—(ùeÒ lEIÌÄzEÃçr ÓP¥™#æ¢ï?wîšUc’Œö¯¨àö'Ó|î„BùqÈ!°Ž1|w@BÝCŠùlŸXÓk´yA¼cÚpM7‹ƒ27ç ¿ë)q“–‰ƒ…Æ½š…„¯(e'ÿôY·VX1Gp…Gpå»w§)²AŒÇaC~8C-EB!?8B‹$¤ÂÄ,ìÉr#OžìßémÉ0ö^Ü “ ?'ç~õèŪ/¯ÖT=šéQÔÃd,Wò÷üòà\(ä·ðÄ]„è¼PZ+ÌÇdEWT@ÞQ_;!„B~ IH…IÜ.¼`W•j/Uõ\±wÙ>W}Vòt@~u·)µ‹ðVÿX3mNÓÝË<‹žd0„(ÖˆeWçó@î *­@Oþ÷伞 µ/¥g¢‡æ°4]LæGÑc0Q…ÂD!„¿9°&L­Ø‚í8â¶Ö¹°îøØÖm§½)’¿²'숔Gh}{Écmtù5'ݽ¯cðCÔdÞŸ»@ $JÙÉoGBøÃfÄëÈÇ¥¾â×OúM:—/'’G¤¦±gh؃Ó,B!„üm9ÃÆ|ÙZ%:žŸ®þ¥XÑ€7e?–º8ÛTçkÿäÛriײ×G×\õèÊ%kÅI5s„³ì¯®ø(Piöò[™à ÏÛhœÄâ÷~úºn €a)š *…‰B![:h ¢1*"jU‡sy£tA\?=o7k™÷ªsÒ&ÃAía÷X‡|'Ý.­Ž8rîÙÝÈwÂ1Áƒ•å5ÕK¼ ¬P PO;ù­Ie¾Ì ùøiÒÄ[ÂL—}úje ¢)›Îê²2œ>‰„Bùû!@€f(Â|ÁÀ «®jW¾ºßˆ&½ »¬Ì\ÝU¯f3­R§'4·¯YÛáj”¥©5—5V0 ÕYNnFA §YøÈïC`¹áw~ùH¹„xAvñÕÐܶ?>UQŒÂD!„¿!*T¡!»Å²ó*êNžÛÇêÙÇéiïWå¿©nT÷©ÁÂíqõÞgý^¿9øY®(WÇF!JÕ¨'ø*{];¥ìäw! 7¼à¦á1EÎ)ž ..ºrmÛÃl"ª  …‰B!C¥c•`á·à‰AÝ×;ÿ@àî ³ÖF†±–»Æ,†ÊÕ15Ö캲œ9á2ºá.á  ƒ#̰R ÉïCBx™?å½ù"9«¨W:Çhy?€0ÃYiäÄyúC’B!#îp†Ž`Ÿ0çÉ<9Ó¾ ;œ#û–l|ªÀ!‹_Âè´/šœO¿·rÿU͇1IÄ‘Â[–¦ìSÁ{à E%¿/Apƒ#ÿŒ1ØÄʾl¬“¨Ù)il³(‚&B!„üMh CD<’adï°‡uæû8Ðu¤o‡k<½3l×›Åüò ‘Eyw3¾éÚ±G“ŸœWýÔ®ü 7ó:؃¸„ !€äw' îpâ¯ø8lE²Aèë¼X^!¾°?>EDa"„BÈß„(–ÀJ«‡yyžZh|H„ïýNj‰9{«Ï Ÿ-’pT~*9-{p àñ—WËÞ/ŽM q¬šÆÝø5ˆìÃQ ù]I BäÀJ~ÎÂ+6DZ±ÌÅçX è„ø @WB!ä/¯𢔠 #ض eØ¢¾­åÈÑAð¨ç0MÙžüÐðõøápâèÙ›¶ùÜÇ*!. W;óíp#´¶ÕU)ä÷'±Ó¨‚ì<=q`X¼Cˆä&$Ùf“P‚e§œB!iÎp€Fh%\e¥®²WíUbAhÿQÍ·ÖØ’;‹¥k¼wêÙà¶ßaÉ”îóÖ\|jxn ±Š‚•Âs~‹Ä@¤À@CQÉG°\V pwäCføqß¹¬œ(·EFd„/ˆá|&rÂ(X„BùKÒBÉ6ÿ‹ê®NáÙx"ŠcîmÇ5%Ãôm¤R¨,ÍrÕß_ð8.úùögæ?Æ "sù|€’‘ Õµ“?–T˲Qy/Ù¶P#Õ&Îýô´À|AŒÚAíÌ·£Ê£0‹B!1L0Ã*4dטò¢ÖV?X||¶‘UòöwRk™6Z”J<îM/°9æf©¤#©ËŒ‘Â|ÁÈŠñì|.<ÀÀ¨®üáç䥖ÅÖ¹ÂÜÄ€wãÇœµ4iBSa­pUmƒ^8ˆÖ(‚Ü,B!„üŨàà,¾bž"œGhjêI±“ v¾XjŽðH~$äÜä`1ùö“G5?gØùôlíçNl++ƒ#J{µ$o êk'BRsˆ’‹cÙ@í¦žvž õ”÷hä}’?á#¬¬% !‹B!1Žp€N¨!lcÉêCÞ šc*Êy¹ˆœ?Àw«¹BJ”i ¶J¥ûÃN/oz©ïŇðf(‰üÄ[|D4,°B¥@’?)±®é•ù™ð–E;e„?_Ä›9®Õše‹~š%m0hL‚™¡1ò!§)\„Bù‹p#´ÌO¦ÞP®uôÓÝ–[ÌÕúZÑ·Š›éºÅ¬Ñ:O×=8²óÂÛðB7Æ=}óéšpŽ-E„ú†«oŸñÝ -´Dþ„Ä4ãXk¦c‰Ø'uw:¢É(/× —úˆ­`† ŽÆ,)X„Bù °Õ¢Û&m|ÄÖ ¿ŒÌèÛ=Oƒ»Ÿ†löÊP·­ÙÕUijjËÜ™í¶-»lö·ŒTš±¢ÌÌö¢ú`¥ìäÏFJ±æŒ`zv^ê.µcˆ<]ܧË*]WØ?ÿu‚LøB#„BÈŸœ­=—1 -x1ìȸÜ=³“óà"MO矩®4¤ZHÝ3h3íulÈóeM÷Ÿ¿Û,eýÙë.e8/o_bIJuíäÏDˆÏk8g< •¹°{Ê ~ƒ88ɯ¤AºžÒqнU 1_ !„BþÔÒÍý"YDY¸Ìâ62÷,Sÿu>]¦ÂY.¸G«zk²2×àž¤˜bÃ:lhu}&¡=Š(¥ÔXþ˜•Rvòg$ÄoOi ƒÀ<Ø#5Œ?@N‡±ò±¼¶»ØCè`oUð¦`B!äOƒƒ ›=+gÕ+_TŸl~ÏÝ£úžlV§P.e^JˆÑ,µu¥ß¾B{(îI¿§!o~aì(†¡,ßÏÍhjOý)i'JBܼ´CÆ#óF¸²RMäÕtç%U\¡-* ‚ÑÖˆU?Ü)X„Bù“²-±¤‘{óZ|!t¨ƒ Ãf¶ô/z$Ã@@Ý(µ`eEßÖ|×/açŒM[žßÈŪÀŒ,/Ùa{O=MûHþÄ„Ø\)ËÒV³2Ì žåZÞA%ö¬U¨ÅjØ[UD&¸Q°!„ò'e‚V6—Á9^•ïAsÖñªv ªÓ$Ï'åAê:“»è¥³vòÁ­g~®û:¥®pTôdÕ•<'+•Ç?;!¶uZFƒ#>1#{ª:£F#BŒb«tƒDW!ÕÞ*œ!ÓŠa„BùÓ €¡ ª¢( f‘l*â[:5w—¼¥·‹Z­‡°@¤>â¢HÝ›"ñe—¯98öáG¶ƒÂ|µœò™ß¶‡úÚÉŸÿÃn~§<áà§\P µ™«ïã&×Nc&Ú?Éu°o´ÐPÈ!„ò'¢B»‹ØdµššÀoWN-2(«¾ÖÐòýƒŠZâÓ‚ÌX^­ƒl—gm—ëC¿,‹?š²ÑÍøu8¢•=õ'äOO0A͢泖PZ«'ÄjŒ³]äþË êªÛ[µâëqŽÐPâN!„? "œÃbtPgª¾€_¾oú°p/]7Í3¡¼¸[ž(º>uyìëµ}¥/†¿gÓXNDo‰p€2Í!Cþ*Ó!ÅIÍ–nÍ¥.º3gvPŸÃÇ#¿C5]#[ÞpNÐB¦B!äf+ßµBÊ\Øuôåg‘ +ŠåWä,RûhÙ;ƒ,3’?›°Éò'yü¤KÍ7š'/JëivœÙ|öžE(Æ! FX(œä¯B2ö±öQ‡¥¶¸Z:ÍÒ>1‰áÜëè´9PylÂqœ¡wB!„ü h!C‚'2‹AVIè"ÞgkÇ o·±¨²)e”r„S¼®Å…ƒ7EÎÜqÁýEYqˆ°Š1%«úœß‡&˜)ä¯E2úX=•†iG,o•IB]iÀ­¼ŒkŒ¾Žv\ "Cpáp„/2QÈ!„ò‡±õµa†Uú$šÙëG¥ÏÑîKµ~¡…òòœ5¼ÕL¦z–á쾺 9ÇY×—»±Ã<ÐÒAéÉ¢Ù8|…7&"ÃOóµÓ€Tò"íIjÔ^–cÖ¡xÉê²H˜¸•×v›¥+®9'TÀpƒ zH)d„BùÃpp€Å³0$¨eÔ…ÜÉk—s¼=âCë¤"^b%ž‹W.ëÎËþ‡®~Wäbã{"Ï#kÑŒòð…2DJÙÉ_‘`ð·Ô´ÖOiazf̓0Œ@ËÝÐÌ¥¹V”î±B,€]„€C…ŒB![¹ "[„Î,—z‰·„oõ%÷ËU §£W7ó`ãE‹>Å7m µÂØR«J^Ö0W¼Æ|á‚Ð}„ &X P8É_‘dØcyeUSš7˜Ÿ ŠM ¢ ü•V.šóò!–f[…ƒÔãN!„?ˆ´°3Ð’ïG!^ÞUçTB÷æóM¼‚7\£@’¿:‡¸^–¬7u6ß„¬ /Æ‹a˜Sm9Z4 FöˆMµ·ÕQâNÈ?‰G<â…(D!ш¶oÛRvJÙ !ä¿¡@…*L`‰¬¤òR­Å?øÍ¸Æ¥\ë§U?†lQF›—Yß±åÚò®%÷eyxþ‘)|qô–}Ám5Œ»ñ Ð@¦ªò×'À-´É£ ÇL¾€`–©Åxa>©¾¼Pœ‚«pà/~jKÉ!ìýëÖŠµb­˜™™™™Ýf·ÙmAdAfžÌ“yÚÛ;ÂŽ6Bùõ@#”àC0„‡?ºáÄ0c«WÅJgΓµ£ûYÞÝ£Ö‹Ùü%kjä‚¥»p{,pý0Ëqzh!ÁLuíäï@€&˜R¯XR­³~z> ûpXë"nawœ/ikKÛÛÖF^ä Âܘs³mç©§Bž *V¨X¡b©¥”Pai…¥–fk—­]¶vöö YCÖâF!¿štX.öãøy€Ùfûew?Ým]½YyRÍ⻦N’²¸æu(;Éo}ñ³£çÄ…¥žë‹“ÙH¾—«èL°R É߃½ô%u¥ÕY½ Îóñl,\ÄN²š,$C§Uú)¶6lª¢$…Œ{];@¼$^/IzI/éÅ]â.q— HB!¡PÈÞÞ ^ð¢°Bȯàd¤Á+»…µ¬ê`4ŽßÓÞRr–n§¾ˆ´^Þ§¿¥™ô2ö™í²ëöù¤—á(+‚EJ ÕÊcðñH¦@’¿{âžÒÀZ]QaV›ðdt€RŽl‚PÄCuÖ•²·íƒ²(H!#`°mª#Ôê~—ßåw‘YE½­ÞVoó3ü ?c¨š‚¤PØ!äWHƒ1¿0–ÍW7óüsÙð Y{µìU­mÈ >ÓÔϪ°õÂHÖtæõ%îíˆç›2SÙHÖ…wçg‘ß>1!#ßzÜ››( U3ªGØ0dƒ“ÐHhÂÜÝÂõÓtKím»°’ÈK!#™éÛ*Âr_¹¯Üðø*¾Š¯ÒdÕdÕd•NI§¤Söyf²#;²SØ!äW8‰%舖(IóDNêô߸rþ¹Ã<©/Ž µY¡GO^NŒ _SçPÝû™Y9|Á|µ¹šÂoÁNÐÒÄäïÇž¸'4¿±¬áÍÔã¼=¡r yY~çfÒ¯ÔµµaP˜å¢ÂCy(µm¿^ðzÁë–Ñ–Ñ–ÑRE©¢Tñ~§ûîwzWÿ]ýwõÑ Ñ¿æ¯ùkŠ!„ü"îp^(*leqj$ij”šú%Óöúó*× ®bž’8ÜÍDy–Ô|ŒÛš W-âðœ`ïÙD" qHD LHò÷ó­T¦†y³5ÖrCÙ¤ŽeËY „&Ì^»Iºšoå1íQˆz ððȶi*m*m*ÍÏóóü¼ÐLh&4‹‰‰‰O[š¶4m)‚Œ`¬ÄJ¬¤°BÈ¿¡…"¨€zSmÄe¾ŒG¢ÞÔ£]³–I6+LY§íúDoÜÀ Ü o•·Ê[1Ó1ݾ “ 2…B~– &˜¡½ÙK€êŒÝÍvUº”«PÉ…ùŠûLR§Y%5Æ0(ešyÖ ýÖ§·Âxq^@&ôd>ìAvô£ªvòw¿P‰QÆœægæóЧz÷0–ug¯Ù*—=šIòV{ÛF?…Œ˜aþ¶h6Oà <ñmýë<„‡ðŒÀŒ°NµÀ …B~– œUeÀ^mùx¦¿œaôÀ6‹ÞGoa+ó¦hÄAGÛ]Yööì¹OwoF‚Í`…pS9©ŽáÃìK,QU;ù[ !©ŠÑ`Úe¦X”uì%›Œ~`ì9»xj»Kím›"~2B¾ã OxB„ (4ŠB~7d@8B-žyIþ–kSªFÐqùÞçU2M·LO;oYbYhiÁs+½fì•*øŒh€Á4i‰%ò#`†5~†á i¬y¸õ¼úž‰¬óp‘Å:ç–o‰›\ÀDTgþpã ŒRB!„ü$à+¾²fLƒµ–ÖJJ'—¦ò)`T÷¦¹ºr¿¤ÖqMåÎF-g;[?^ýÂå]ÎØ'‚*œaÑêY5?3¬P)äG `,* òiÃ67×Vz+@%œeÛ¶MœæË=ÅaÐB -ëˆPd¦”ï¸Â®öw+¬°Ò5B!¿+Çæ²¹0qRå”sì ›C‡t_ëS8Où´”×™óǼuO•¼6-m³¿äƒ‘Š·êÇ‹À'c¶áš­Ì†"I~ëS˜mÉ ÈJUSvëBe4ú±-¨ A0;ÅH¯D/#LØÍOá2ÁÎø„ZŒü°l³³Û¬Ã:¬ãq<ŽÇ¡;º£»í] !„ü0q•­õ®Íó]¯#?í´Ö¶0óu37òNˆÄ ¼ ’Ó÷‰ûcYË*Ùá£" ï§›,]{;4”ƒÅz¶6¬7Š!ˆG~h,Ý¢Ú¶ò 4Ð )H¡ºvBù7 juu÷C$Þ ¡H•\÷3y`Šc& ‘Ÿ|—ݺWõäãä6Rˆ0:”ÂX0ßg/„ü8¾ûèǻޙžÈ_µD'Ýq餰ɱ£ì#­²7êÍŠ"ŽüÐÒ§æC1C‰HD¢*¡¼à/û£éS|B!6ð†3߇ŒXˆ؆]¥Y^ôT}ÔÅJ‰”jæàÎy2 ꡤÚE½Â›Ûžòtòòƒù>q¿™ÖÛ8@Vxñ6¼# ÅôK墯ֆuA(²RàÈÍþð·mJ ¥…ÒB&2‘‰ê õ†zƒWäyE{K[í;!„ôš¡2rA†Ám•SIÝæBæì7Ü÷Éy1‡¯ñž©MÏW½Û2r$Žâî«syþˆÂFÈw‰{\|š·Ñ €ÜÕ2¼6æ#AÔ o'K•„öFÝ‘ ¾8òCó†7¼m›Òi‡´ƒ]b—Ø%u¼:^Ï'ò‰|¢½%•ÍBHz"B–‰Cø"CÙ-gíí^Ø©¹Æ@?6áã¾ØCi[>(1mǰ•¬(ñƒ< ià?!ß%î±ESïá6ó…³jâEøT8ˆý½ã}IKØÚ°y(ƒ ù¡¥_9u7vc7b‹X„"¡p…+\)H„ò/(P¡²~Ì÷ˆ)r?ä7†Èµ¥:èËsñO7V<÷úº½ÑEà'hmé>!}ýí×Ä””4A)äàó @ƒâøè´Y»KÎ `¼=–`¼áG !p†3œ!B„L0A…C!ÿB5”D0ï‹ñXê`\á±9.{ŽÁgi›‹E(ƒB?_ÚóòÖâ0îÛŸ¥P];! Xl_˜O(Õx%DyÊk‰EX [¨Ÿy{÷x‡ÎºUp‚dµy>B*˜!€'<á 2d$#ÉTC!ÿ±þ,AÍ¡¾æ–eªéágg`Á iðQF)’asZvkåÇ–ˆY_Üa†à)Þ#•‚Gˆ€7H‚Ñö…u?Ìë¤ö¶ôWJ™+; ðÞêY7½^§«‹¤ÀÌGò@tA^ø"#…ü Ò¯œº™oæ›ñŸñåPåXF–‘ÑÕA!ßãààÂa^£(ò"[îSY=<ÞøïÌXÁi)€x}ÿMøÃ¸— S¯™@V ä+p‹‚Gˆ€p$Á`ûÂ:]-ÀŸ§ä´4Rœ…,Nj~Ù­š~½6 O˜À–ódìÃKä/<)|äå8Ø/¡yÂ!ŽWCl¡àb#!‰ßnBYfª©|i ³ŒµÖ÷]¦¿,=ÅBž•Ç9¯ÐŽIÝ…}Bšõ‘â ôB2ÂÂG~P馃”wÊ;åì;Ä)3•™ÊL.q‰Kö–¾ýaL!?´ FÖx%‚·Â$AlQ.¢`·¬-pÇ:Kðhööq…7Yb§£,LpŒÂ:¡ zD¹¢FRð±‘ð±H¶}a©§PÛ§0GXç°8֌Ղ¢úóKÍôáZGÍYi´xÙš[Q©ÇüÀÒ/«”yð€Žâ(ޢРˆýQNÓ—B°MlªóÝÜŒ-nýœ<µÝJäÊõÎ'3 ©KÔ_N|lij'‘Mbñ¹¬æàëyS00¬£Ÿ¥„ØÜ–¸‹`­¦¬åƒ“ÝL3¬÷aa-Ù[ˆ|8·¸^Ô¥ÉÍ57Ä$Ál»íÏò‹&¼#°HµÀ‹=}×@ †B¾Ó呎ÐBôêævÎaŠÿ/'ý(ĈUÄ#ÏÊ¿k«<.±:æ ;Æj☥¶ã&JÙ IOÀSÄ  fn®P£·š›k@ú0/õ zû91Í=9¯äC>{ËôE5„òc²À ^؃Ӹ[5¶ÈêÌÕðŒUd6ÍTê^^÷Øü9P yÕjêI4¶§û„t<ÄgÄ2+*Ãuù*Þ4ñªñ¬i La¡ÊžÈk8”·ŠÉRcv™eµ?/Δ¸“VºµQÅb ±{Êž²§Êå‹ò…âŸø'{K#Œß¦[%„Ôp´GE~“{c„¶žÆYš–×%`œÛnäb½p&iYj}sê‰ê×c_—Æ ÜÇSµ3?ÍóÛÓ}BH:â#bØ8ö û¡…#œŒiWMaÛ&4P'ó/¨­? ­÷H×…8l^68CGá#?&æÎÜ™}V%ñ†xC¼ÁY"KTN+§•Óü)ÊŸÚ›¦! i1BÈJ€&f-Ù{4ÆX-”Ë{ g]½Þ &~—‡¿üuvZ¯Ïˆ­“"Â3ŒÁrœ¡àò¯.©»x‡(a‹eWaB*Râ¥=7,„§l„:‡7ç³™FØŒç%Vé—ÛŸç ‰ È+Ý`)ÎÃy8€TFeT†|àcoI¥2„™ \$É£‰ëHÇåùzæ˜è½ ·”®JŽ„åqc£×å?$ú"ñq ‘p&X(z„ü3Á~Ó;Þà‹mWZVk´Ú J µŒ°šmC/€D¼G=‡sºÃ2B8眻ëhDÛgs/Žâ(Ž È€ öG©T†òc=™[7¨äuØaP~M`y· (j=g½ùf×ÇàøIŸ;ƵHÍ Px,ÏÃÇRÜù9ö…Ùùv¼Âg„€¡¯Ò]Ù¯ÞVf©Z6ù`ð çÜFëOiîa €Œ8ò#³ NµýÍ+ŽÇŠcY}VŸÕ·ÈÙ"«…ÕÂja{Ó$$!‰"FùØîå7BWtQ'©*ª}¡¯¡û4%Ó©¹7¦‡Ë™úyä4&™,ãå$,Î’¶iÇ»_w]Ô_œÂt‚(àToHÈÏ^^6½øqܱm&U3,‰©;,¯”:â$¡( p¯ÜFévkËSÈI¿6*û¾°/l›Æ¦©[Ô-ễy°½¥ &bEùAØRvœà††(k%׺×ô/—¥¨¡µ|ʵª)¯nU†nR§¢7´ôÇôß*ÚK£-zR ùù‹ Àã^Ù¶S»›W+ýŒm¬.Já>¾²5^ Ê-D7Wö òÝÜoðoxÄ£j¡2!2Ù¥RBÈÖ²çG.ŠnB+6yÑ {ú³&‹˜œ‘IMTãÕpž«¬;Œ;-%ÍFó¥€ÒQin?Â;<Á# $!?ç[ût\ÀÛfJ#s”e„q˜u–²Ÿ]Ù5ñÖE¯Ý(§òtÐÙûà?á>Á 3Ì”²B~ Èmƒõ…Õ‚™eS–«E¸o¹%ùof^6îZ—›¥rY›‰äÞð‚Ø+]víe]]ßNÓZÓYç¢ó´†5Aoô¦pòs¾õ¸OÇ9~:ˆ`©=͇,vÖNÐ3/¼ðá.Ç4Kå2B¾c–šˆD$Ú{Üà'{¯<¥ï„¿7 "˜a "sÕ¢j8?ãñØÕUÿlùŠÁUN»fÒUÊ[ŸÎT°ê"4oOÞ޶׸·^'¿Ž³;Î~!Ýs¸ç`;˜š¦Q‡PP ùù Îf:?ƒ›0"xÊkS[Ë=c' ¬eð‰²O?È_¸TÔÃá-fÀ ª=)I_6@È }:^QжÉò‡ü!\á W衇ž¦†$„üÍÙò…f,Ÿ‡í²ìlÍÂè~c+;äzÒ,ƒ¨ôI˜Êf%–z¹U™ãØÝñüã/g®Ÿ^²gÏú¡ë³`Ï?Æcùv¾‚JÈÏùÖãÞqcbR6ƒ»±rÊS-Ë,€Í*¸…ÇNµ¤ÕâL¤Â3|áúSŸ"!?[R`íX;ÖŽÕd5YMóTóTóTÔAÔAs4GsÄ!q0BÈß­¯½ò"«8GxÇDµ‚ÅÏö,Òðu¡©­+ÕÒä4ª.©3MOÌ|™¸ïAæ/q‚\Q×Ds4å­¹±9Z ®K×…¦ÂráÛºì.p‡;…–Ÿó­Æ½!V`—8Š=bøF^•‡¤›žšá!‡$´Àp‡¦r[ñ °s¸7F`>Š#~Dò^7Bºk§!"¡å¥x)^Êþ¨7¼á *T !äoE„ÁÖ×.¸³Å,A‰T·òm/Ÿ÷9}l×%7Y†šžXf Iú.òˆ»¶-¼ÿñËäx-Oàñ9ktë[k k náÇù·tIˆG<˜Ÿó-ùøˆ$³ñ¬ZÁ ÞðNkcÝ¢T Îs^@.(ŽE—ez³î"ü±ç± ]ј‚H~h H@Œ0ˆ`#Øž¬S‘ !äïG€*TÃbôà_xn>FsKV¤÷«n õ¯¶Êñµc=é•é¼´´¶ðÐÆ7êTîý±XÔÍ”y½³Î}}:ÑÚÈ:ÉçZÚu«Ëõ…š‡EGEGEGÙI?- ùÅ„Ÿ.EŽ“ül;’oZ*›´æk¸ò~©¤¸Ü­«þˆVµ·ŸÏ¢"‘üÐl¿rdȉHDÚ÷‹!Rx!¶Šv'8B/¼XMå­zˆß¨?»ìÒàKýZ¿,ÒÌ:Þ8Ê¢˜3Y}1­çæyÃÎ-‰öŠ˜òÕ+*ãÊŒù¥dižÜÌôÈtÍt,ycòÆäMö#ÓX B~1ữöáì' 3°>Â0^ùr¹¬)”s)£»§ñ¶µa“Pƒ•¤ ’ˆ¼à ,°°þì»%&H#¤B²xU¼*]‘ÆKã…/âVq+bƒhÿ1Œ•Bþ’´!Ù*ÚÙFVw”ê<>2px¦½îñ ÖõkTaµ´âkåR˜ã-݈ùÝveyr(ärΗµØ.V ÷ÜóyLöH‘'Ë}äzÉs“ç'/T’•då[©L"Aa&ä—¾ûê^á“m3ÅÝt² ?Êc‘•·ÆÐ[¨îÒMûY³—q `SPEÌà %ù!Ä!1ȉR(Åð¢¼hâ±Ø;±wÜ:Ws®ö¹ÝÇ«¯ª•ƒÊAÈY Ãßð76BÈ_’­€Å ¬x„Í艶Üݘ–ÉlÄŠ%C&VY˜5Ùßì ð$^åZÔÝ–'Ol°¾á7¡­PMW³«GyA—L.™]²‰/ħâvÃTÃTÃTå°rX9l•(D}ë4$„üß¾ëqçSqñ[ þeiÚ:S4:ñ\â3qÏåOâDa·s>ísy¾ý £P¹)ˆäÇÁÚ°CìŸÅgñYþm‚ ®~£é¦¦› Ï©V-¬zí–oZ¾)y Fæ™ù ~ƒßÀ,ÀŠ!ä/I„cÑÕůBÖ•ßGE|S:•-Óªjr)Ï€ùÖ$cKÖ¯»c×Ñ­ç̱§V¦4Ü2gëÙ§o÷äÝJºuË/7–ËS¥J9d9i9i9i+5¤B~¹ï{ÜWà`ñ !æ êGõq˜…Wâ{¡°Ó¹šF‘ÊŽc0+ŽL ©ÜÉB ‘¤kiK]KÝJ¬QX£°é%gŽ›9îÝð<…Þèýê`‚s‚sÅËî^î^l2ûÄ>qðþ¼?Eò—á4H…fÁ‹-e_•ŠªÌ ÕgÆ\Ï/ž_=cå-òyKÜö¸íqÛÍçÌçÌçìc„îã>îSÈ ù%¾ïq߀[xfÛN2”0eWoò܉Æm|@¢àÆ:uÒ—ì“ܱÁ(ŠDò™‰¾èk[€)­[ R;ÚÚÔÚ4ùhª9ÕüeåœåÜ×QK£–ÂpÀ ÜÅ] !ä/Ã6ác*Œ0³a,ލ}¹ÌïøxµtÙ¿|ÍàO•âô3Ä|„¼Êq¿æÜ*;¡lÍrîã3bE¡?«§úª³yº =ZÙéïï/7“›ÉÍããã-×,×,×ì“ç>óo¹!äß] é-ã—¿ýÕ× M1Æ)ãùBþ ð€“p‡…:)2kÙÛ÷B(üi'ò)€Ò(  0Hïå×òkù†´KÚ%DË9ä:W¹¢\Q÷ÙáÃ;¤! ipCFd¤°Bþ2lóÆ}ÅY„ YmvCZ õ“Ø¢5*GgÙži·óG€}`»o{°.ºèÐÄå+.F±nÌkÔHu$¯wTÃtÔE=Ô³õ©;Ïvží<[v‘]d—¯S¾Nù:…/â‹ø"ÛX ÜÄMܤÀòK|_*³ —q϶?9MoŒU_«kù+¶M¨Â< ²Y,ÊqˆÔSh Äz"ËP± ù1ðe|‡0ÁdŸÚ>µ½±™áœáœ0ã0.iar³äfñÝbæÇÌG]ÜÀ ¼Æc<¦¸BþôÐBFäFf±£p…”çê">}àó¦ù &ÔÏU1$¨¯ÒÜTßrÔèažÅv=0sïI$F%o6Ôf1lÞñ•ðA[wΆ³(Žâ(îÒÏ¥ŸK?ù¶|[¾»4viìRÛ}Köœ=gÏyvžg§ðòëÍF-؇’¸h´+åè¤ä1Û„šŒ¯×nç³*uo¹PSkJñp€#åñÂÁÓ¾ø !?"D±ŸØOì‡R¨Ó³M/>½x„ú&뛬õuõsÔÏ¡Xˆ…âñƒø!„üh }[wB(Ìö3m»Ìµü=²œJ›rÚØÿõÞ¹…ýÖ+¯êé±³Á©BílmĆÂT6…þp‚Ô@ Ô`ÙcfﶘspÎÁ9_]yuåÕ•Ú»j諾ËþÜ{â=ñ…Ÿ_îû„û9b¾-‚`4XCcÊIK¥Šðœ½b+µ”:ßy².T{iHEªº/Pï¢=J¡…’ü(PìË-]ÅqçyÞ„eã¯ùk^‘‹\Ä,ôC?h œnHBþ´l fX¡°¢HÃzµ+?Ã<ƺvqø²\;¸geƒ~”Öƒ‰b]&ÍÒ-!GG½¨¿êî¡®ˆµ…Yl‰2IÍÁM¸‹çø€`Æ.ìÂ.ÊCy¨æ‹æ‹æ‹ËF—.Ój¦ÕL«™–+-WZ.û«ÏÀ Ì “@È/÷}â®üc“¿Ç|L®c¹«œŽãæj¾Ãù±n”&Öá$®ª©ü+ò¢5Š"…’ül¿ä¬°Â g¸Á Ðýü™7Fa6 `oC!N¶{¶Î×0N+Öð8ü"OD»8¿§V|¸è¨LWV)áªYÄЦ˜iÒj;ð"¶ˆ-²ø•t+éVÒIpœC€!À`nnnkÉ·ñm| B~¹ïkܰBµ_N…x%ÌKme)ªŒbgØY6 àCyçÚ‘'ù‚\W®k ·˜,ɬÚ u*’‚í—œ-}OFŒ8ÄA‚V|Å'|Â'¼Å[*’!„ü©9@f(€ðZèÈ^(õÔç|b÷} ÊšÑ)¾¾’§¹"§9™š[ËŠ-äR½tsûŸcŸj}™–”&D…Yc5›*òp€2Ò`„Åv`6Žcã¸Â®8îrÜå¸Ë±¹csÇæiÒ>¤}HíŸÚ?µ?ŽàŽ`æa B~¹ï{Ü °~ëuWžqgÞ$©yе+{Ê>a Žà÷œ^h·Ê¥õZ)N¼ MŸ&…$„BþdH‘ ,l«…jˆúœï(²%×ÂLÏg èqªô<«Ù”ÉœC´8 Öõ›î¸~ÝÍþgGÞ©ÿ&R¼!|f—Õ5jž Xú”Ýn*¦bª­›ÃyŒóç1އ;N±¤XR,ɉɉɉö–C0Cè„òËýÿ‰»åÛÍ}¾”+¼^ÒyS‚¥ò°¶àóÕÏN'5òiÝhy°4f¨àhÂB‘BI!„ü©ÙîZ`…"dbë™ÄËòr¨ìì´PWp­çðWUýœ»8õ“NKŸs¸ó…wá›ÃޝŸvå=Bp5”çêR>S°'íGþ³nè†n¶M‡ãÇŽ;tvèìÐ9µmjÛÔ¶)A)A)Aö5S'ò‰|"B~¹ï÷4X¡Úoñ‡¡J'06ï„ʾ²=0ª§‘ÑÁ*×–žêêJoDû²2¬:rÀBI!„ü©¹ÃzìÄT4g'YS<V B‹Ÿû«ò oõœK2®Wc•£ê›ð·ï’š÷ö˜çyö>ÏÏÏò-,šÝÄ&´ÇDì·÷ÙÿL,ëÏú3ûZÑÍš94sèïÐß¡²w²w²wblblb¬­?žwá]x:-„ürÿân3á M>UäCå½1“‹®¯|3éy‰ýUzVXÙnp‡Ëj.î Wk+5X5 fX…aoY'\ª°Ó̉Mc…pÓÐÕzM.TB!ä7’>¶@Ê>`5*ª]¸ÄoŒÕþEÉeÇ:›i³µ€¥°bÍ×Á¨tUfm8i0N4-¶deöŠFFÔÀLh CüEËÉ#Á¶¾vœÁœq©æRÍ¥š’[É­äNõKõKõ³¯qqq‘–¨#ä¿ã d¡”ØQkÛQ5*аÐs çœ_iÉ9çןrÎù³vœs>¤X;¯ò^¡ A¢W÷ó3ÄÀZb¾´Lœ"d ZÖ‘8„ö‡Eû­¶ÊÝ*w«ÜöWi$4щ"ä×ú~¦4˜aÁ䀸,iarS9UIV¼å%Ö²–ìb/频úÀúÙÔkÖŽîÅK„MXÖrhžÞ‘…¿œJ{v·Èë]q•ϸÝûÍ¥Wž´ütùKýÄxc­¯ú„©ӕƽF?Ô„kBVûò&|-ªð>XÇã:Þcvâ6ãîÃ,öÄžþ6'„B~Ž­L .Ìe&V\í †òu¹ .ö*3ÿHÿ¶KaµrÍ:@ì«?® [$o_¿üvë©çOJ‰y„>l¸ÒG}ÂOá3î#þW¿zADA[Œf’f’f’‡¯‡¯‡¯%Ðh üêùÕó«§­!ŸÄ'ñIØ‹½ØK'_NúûøÀß¶Éz¥Ä¥¼™(ŠÑÊ2¡ è‚æ‚$Í"ÑÅa ª »QϱªË!m‡Ü#\'ës#(À#µ jºäøš¶&yžåÅ«´~I·Ï?Uá¦ü|^´Ç½:¯~5?œõºnt1SIs+Ë8sá`.€œ€¨ ˆ+D+;Ž|"T?>Ÿóåüª#‰Hµ—ÜüÜ<²„BÈÖ²«ààxŽíè…m¸Ë „bL?+´g‰r9½‹y¦éê¨JUõÕ£ã/¤/ÍF}]ÕñR\CK¸¨=ÔA܇‘ w!B„åÿŠúOX dœsι\M®&Wspp°\µ\µ\Mx—ð.á¡a#6b#4B~­•¸'ã,ŽÚ6Õ‚–Åf ë™’7IÖܱ.²Ü’·ËOå- SפíÛ}ÿ¼ç›IEã²=sÊâ³Å³„Óí}Gù v®:Ür.&µÉàh÷áù‘'1ctgXvr9öy|Ë´ª1JÜÈÔÐ"šÆû¯ysEäís‹îtz3?ávÊÓ³¤î©‡LG”î x]z»ýÄV,‘§ðê8® |$w縀æHD*ÌHFÌözB!äÇa›ÙM€ 'á¦Ð†ÝWÃT+s¯Ý¹R§j(ãЄ6m17Kn‚b½çÎîUÊ©´ ¦OB/ö”åQ?ñ>ÆÞ)ö+Sv»ìÈŽìxx!½“ÞI:wuîjycycy;(vPì {˘tÒùµþUâ¾XMRí·®_†í/9k K×Åå&ê«Ø“œ ¼#s$û%º ,X#G×ñ\†¬w=ZiLò~DÂ>ÔÓË£ž.ƒ'<+ë¿äš—}T†-P A• Ö…jxÄœè:©ENkïdzÿìJ×ßU~×þË”T‡Âõ_º$.LÞjp°õÿ{Ï{0¡B[æŒ­èŠÆ¬&÷B¾…'ñ|EØ+ÔCO!äoÈV‰n…UHª°Vª£z‚¯¬*}Ÿ­Àè©¶½«Æ æWÂ] ÍQÂ"é\çËüÁ€wžÂ6O9¥Öã³`å¿ìöòƒül‰»pG¸#Üq¨ëPס®aaa]ì¡ØC±‡PP€Ïçóù| À  Hȯ¹ÜÿÙv<ç>†$ëe%{J'K€rɧ†~¦TÂí ] êÃP û°ÒÜÂZBévºîM„?›^áól‡É »tjŸ«_Ö’î·ò¨Ÿ=ÛY”³c¦J%Có<ð\Ú/Ø)HÒÉÄç€ä"d§ÈÉB†ÈRÄùfêBý{žlÚ;_7CÕ¤óògŸ#ÅÆ?xþúô—È»q¯¯Ç>?ùÞìw±†ßŒÞ‚Ƙ…Ç*8«0Ξ™Wް‹ø(Š UU7¾—àÔk¼8@&ØÔ~KcÛ !„üµØ:¤¬P 23›Šuº†;ùgðÊî¶²ÎÐΕ³iª‹ã[h!;ÉÍ6M:2ñÙæÅ|ïÎ;767”‹êÞÏñŸì“3þ7¿ Ýà7Û¦KˆKˆKˆv¢v¢vbÜǸqS ¤H-`oy'p‚N !¿Ö¿HÜùD~÷1’Lm­™âÃ+S2ƸWs8 E]ÆUo§ºú'¬,ëÆšò¦¼*Ï#”gûY€0LÈ…Û_“ê¥T¿4')â¥9ðVßê¡;,»f=ëãäz¡æ³’w³*¸8»”ákè´€žnÈZŧ¶kY÷ ³fb#$êO9^ã !ÏPï…÷¹oãŽ0¥)›S_¦õ7í~ÿìë¬4ÃÕÏ®|é}ªî­×o’Ì{]'Úûӆ؆²qn‰SýÔÜñ{ Àk…§B«ö|6.ðŠèÍ7ñ0¾W±'ñ ó° ×ðïðõðƒŒBùß²MØ`»‡<]Pp /„áÂ~a˲ƒÛT5tö÷rY¨­Ô>t/—Årxiµ «ÙE–Œ‚< 7 ¢^áCºéþ»ßt*Ôo¿ný+úWô¯ˆ¸ Û¶%lãgùY~Gqô[9.!ä×úW=î q ¬)»MµÍq Ï ²y<ŒB]á&­³ȘGŸOS[*' f&K„r—?Qxy®¨iÊ;x"rÀ—gù!ìe•ÙIlÃ&¬S2«×ø¬´lÆ:–YÏð_aû×þS(FØ#ô.>?÷¿¾Ÿf/Ÿ!OM@ŠÇýü˃Ëû<,|?Gh†P}'&ùb+Ôp|åÚT·:'\ëîäœÍË}]{ÔyÒÌt>õœ5öq¯·;ã·ÝÎýìSTÝ.áÖ¯-ïÇ…Ï rñMÒ—£I>)« ÇÔp @ÌDåosõXÅ)Œã­ù 4Vó}<Vcn¦¿)I B![Š€LðO `.Ê4õ/è-¾•úæÇ(Ù')Â'|ÂCp ~ºìâ¢xþ ÙÎ÷p 3¼áŠ*¨Â¨‹’dÓÐåØ56†=eëÐFÙ«îW—\¿ðØûý’ëxlë¡à<Ôq¦nA¦Åž{²¾•3«¯Pµtу•НÙ”áªÿÇŒã³;Ÿv©½èz ý´ã×JÕ #OXÿÂÈ×Ì»-`-ÃYüÅø† ¸×I ™^üØ/éÃÕ©O{Ä ?¹ûæÄˆI/2Eöÿz<éHÚZË,eª²J9‰Z8ˆó¶÷ L¼X$›Çð–¨+QHmÉð Â%¼´ŠG2ŒÔ7O!ä7”nöa¾`ee•êj¾³Tã¼;37{ªýb•¹†Ææy¢IZ£vtÙã«uofyºûS!ÛÍ$å¡Ú„ϱ­¨ ¬¿M'”g˜g˜g ca,,!%!%!Eí¡öP{@…wBþ3ÿªÇ}ŽãªØ‡Z©ùye59~QÚ;ãUôB„$•qwÞÖe¥&Dœ"M™0Ý4@ øÀú>}}h$b àŽí_ŒÀn.s‰‹°p+–bæ °I8Æü„£¬<Û¤zªÕ‹ÉER3³½@*Œx±çÝõ8lÅI<€@hå ñÞ×Ë;8ùMA§ ö=ò¦MÌ8,äZ–ί\C="Äæ»Ë{¹—sï¤ÝáQL×!¨t@ õÕQbi–kaMÚW,tîÓíØŒÆÍ7‡½È÷Å÷BÉ{¥ßÞ}:èí˸GÏw¼wOðzçõ2¾& @‹ÄÁ€ dn˜É¼ÃÖóz˜Ä¯ð(žãQ°fX Ð<ô„Bþ+éî÷²6Ì ûÔbê¾ßµ£“»¾ðÒ̃ºVj¬«õe „üÒéêÑ£—¯¾uš=c[î›-Ä.Â,6\™ Ê܈è°©0ÂúÛ½Y×P×P×Pa–0K˜•°2aeÂJ„#á¶Á©”¸òŸþøg&X¡â,Ò âDhS*Z*C¤Þä—Q]qLXÁ³!^U:nzƒØ[‰@ê¡<&áîÿŠ×·À žÝC°Qå*çP5¸ÀEtÄ=´be`Äzɶ ¿Ž[¸Ë}x=,@f´À®ÇgÂâKèSƒ¤ýÏŠ¼5}íö S„>þô%Gû>…\½,2Îjr·Üàcy †q@ÇnÜQdU¼+TWÇð>T½Éëñd~’›ÑÐ~kÒ–ÄS=!„_ÂV¢ÙuŸmFVp¾M±ažss…Vù“rθˆç±<¶âÇãIeº˜ÕñÔ4óEK9ë{ÁÀ±…ðG]~ŸµÊ=3xfðÌ ”Êe¢££mE2ì{Á^ð <Ï@§”_Kú¹xãqfÆÖ4´ž‹Z“gsŒ ù 8N(›e£{'—^o ÆÞJÊŽ¡šs` ü‡ï%}kë¥^½¸Î®sp  A„ë!À Îб9¬ ® ®lKb/ÙNîŸZ ¿…g0\¼Uö>a;ÎàùDý íB¹”ÃPÝ iIq<{ü§WiY¤DVC¡þÙ[x¤-ÍáÖ+Së ŸÃ…êòVVø¬{$<πͮÍr Hïñ©Ê[Ô æ6†Š–q-“cź7 Ÿu¸Ûþý©‹·ï_|ùQùZ&õÊûÑû“b,P ©¥0ø6v^8%x°RèÁð˼&à¦ó͸ÉWâ^`6âžã-¾Ð XB!v¶T»"Š#§˜,Ôdƒ‹Ú›7곺qÏ":v®Ÿ;Ï8kCcs h™*äë)϶ž}ò¡IL¹Ä3‚ [ÃÕ[¼.O…hŸ£ý?-²¬°ÂŠ¬ÈŠ¬Î›7;o,‚E°Ä­[·Ö^$³û±-Ð-èÄòký|âÞ'q“ ¾”1Ÿ¹r+9•(æ2è&Ô&±ÞYœ=ÆØÚ³Y¬+ý›ç™¶zÛ¿©0‡ð¯È¯p^˜søÃ®¬/ˆóÂrV„ÅR´‡ŸòBËûf›úY®æš`¹zW¼šzWñ ØŽÍ@¶óþw=·^œÑkMÇ€ÛîÙ‹È}ͯZ!SpýŒ~^í=ë¯,?«Ùì0Ažè³Ùq€Ì}àóÆÉ¡:JÉ™ýEWÊùÍêOC’¯ÜúâIô‰;Õ^4þÜåѽ·=ãç]Ëù¸ÝDŽز “R3h Á[%t1ЈUÂ\Á$Þ„_Bµ.ßɳa%öâ Š%„ŽH0Á «Ä61«²RÍÁÛÙš«k¦s“–ws)énio¬kÞ/¿Ò+šY2¯ìtýæ‰'7r‡w¾ EXU5—:˜_Ѿ¬ÒoóKÚ6ŸŒ¼à…HD"ÒáŠÃ‡+ á„p"öhìÑØ£xŒÇxÌŽ±cìOæÉ<™N/!¿ÖÏ&î¨À×á,€RÀ×*i3MÏLK¬9ÕIÒ.6 ­„Úl§PÎû¥ÓS}}»LGMC œÁßõ;Hÿ·ÂD#‘/â@<‚pÔAäÃFŒEVGNx±{lz²<ì#›‰•|-_QáCÑX‡|@,vmmÍ-y§Ï:³…ƒÆøUr{SÅP´z¶åŽäíâ[8¸¨ÿ=ç¼îç½t9¥÷Å4çù"÷ ìâ?Éih ²¶wÉÜÕw‡d4æNjaš÷ùLlPJ™— f$¼6åiÏ/ÃNL¿Ù5|à‹§‘åb7$L-gnn}¢äUú£4öâ¬íú :fb™€W<—ºEÕüÏi›€˜‹D¤Qßá|eäÛ6“›mxe‹Ð™Y‘Ê›«*ߎ¯Ðâ4€ßv”UOôDOþ„?áOäòy€cNÇœŽ9ÍçÍçÍçSN¦œL9io™9ÃÞ7Où•~¾Ç½và4&@ìgÃ&Ó)ÓëW¥±œ(eú"«ÆR2”Ò×ÖÎ0`CP!ð;'îÿ·T`ÆœÂCû¿¶ïNâ"Öq+W¸Š²èŠ[ÌÌ0½è%,D4dDáŒé°¹§¥adÆÏ=‰ÏHÄYÜy ûŒ Ý'8E”Ï[0&ëÇbÞ!^öåC¶}Úçîø6ÖÌÓ};w¤ÞjqÞá©x: ŽãV·—ÈÒÔýpµ™Å7g©<íOì5"6Òh¼ùäÅî/.¶¼×6rÔ“Áo#â^>÷y·5áUdž¨¬qì?ê€væ¸nû.Ø8憩,?“Ùn^“Oà—ùž£Q­±ÅBÈ_’3ÜáŽdÄ#žÝ20³Uè,ìQ ÖuÒ”ÏÝ •ÿ¿|®Ê^Õ~Æ@s—„3‰§ÍþCf-KºdPzªÕyvá;È|ø3Ô㟟ßlÛÅvñ¯ü+ÿê¶Ûm·Ûní@í@íÀTcª1Õh ²Y‚ìMàÐI&ä?óó‰{7ìâç02²&LH{eÒ˜ó*‹ÕîÌ /&ÀÊ: ¨ëq]ù$\LAsäDf\ù‹Tf§/8¹„ûxÃu| gVUQႼÈDc &³çlZ±JÈ=/ÊÛco‹¸ð¥zü„” »qO°g—¢€ö¬epã,_<]—ùtpN-V6·5Óƒ o vÌ"ltßÝßý¸ó4M”‘R„…€¦—tÌ÷°ï§Ùõá{ͱIý;•-Wv¦Œ·¬‹ˆŒŠIÊò|AäôØŠ—G{xñÜ£þŸÄË/î¼–VÞØÖÒ–Oä õS°GÁA C¼/ÔPÇñh>T½Áëò$~‚ÅBÈŸž­$2ñˆG „ŸPs Zô)ïx¯_Dƒ]9Ž«yS\Tx¤»ïx ×øy«Oº=î~"ú¡Pd’z’WãŸ!C„ËïR`yWp¹‘¹½ yò*ä8Ìq˜ã°¤[I·’nÙò|'ß™~UBȯù!ñ3¸7ƒ¥HC/X?ÝLªbˆ·[N°‰zƒ¼’P„Y¼êèC5¯npeËXeçÕt0ýòðŸ! 8Æpp` ·Ý²<ƒ¡ìe,oq#AXÀá>kÂŽX•ýê¶—ÅÞeüºÍ¶èê ÜÄ›+Óæl2]/åœèà)W(Y;ïâÌç+$|›9*øŒß`—ÜÁ3;¸±Ì¼ ¸,ršâ–Ix)6sª+Ë Wn½r ûuû•KV? ½fŒ±¤Æ%%›f=Ìö&{¼ùlÅ»3Þ?»”|ÿsdâ‡E_ÒÖ½óþ\$iJõ8&8nû†„ÕÌÂB1køM> p ³ùvÜå¶•b×ã(`?Îã)%ô„ò»JߥR…( :¶ Ѽ¦÷Í,§Žär ö\09v¸µZDšÑ}“>Rš)Œ±D®2¯®|xÂŽ‰g>ó¢…@ÖL]©îåñ¸G\D"Raú}¾ 6Mgӹ®¸Ôs©çROw\w\w<:6:6:ÖXÕXÕX÷q÷q‡pˆN;!ÿk¥Dc8Z2[É:¼ÜÔÿz㪜OòìX‰óiS»¬:ÒÖ»j7[sI/hØH¸Áº(J¶¸6O°ƒ…A,š• Ø>ö˜ÕÀâÿû.>Nþú‚•k‰Ï6±ï–Æ &mx:ƱVÒ³y›Ó:¿à«.Œ¸†ókºÁ9¿š<¸ç×› ©ÄùµFƒ+s~½×à—œ_®>8kÄù¥»mÞ³eò“ú¯Gok)‘³®©lhȲ ëÝCœjÿßïÝd¥1U*)–`1Â]¡ ëŽ\úið¬˜î{$¶ ˆlÛÓ¢¦EM‹zãòÆåK½}õöÕÛgo%F‰Q+BÈ¿À~úÏNèÂ"X^A`ý°˜}¤ÓÔ]›¯n|s™sίÜV"9¿W•sÎwG=¸qw‡GK‡1bNapYX̱æxýG}CÂ#á‘`ïS¯Ú¶jÛªmo¸ßp¿á¾nìº±ëÆºYÜ,nè ƒŽµ`-Í'CÈèç§^E8>0Æ¢­jáN¼vli“ližCÅ … æâ=Ýšêkóª =¬ÍÔ@õ ž¡Z faý¿ôýôyÐ sT[·É\4DQä†?&  Ê£Š 3Kfç1š¹³ûl,;‚I¨’4>¥©¡Ç™ã·Ý#î9~÷{=ô¨äääóÀ}Œ> ì˂Ƭ‹*'ê‘ewÿl“Üx½qߣßèXÒÑ[;ÐNë–ÏzÁ¹x »ÜjÔªj‰à‡ÆÉ/Íu£#âS¯¾êôaSb³«ƒŸ¶ŠérîÍ^ƒŸŒ¼ôµcRµ4Ë-K°å²u” ø(²7e©µØD`jG~Ÿ·SKªkxJ£ –!)0ã¾"fXh€!„üBZÈ!C‚ˆþhrâ(q'[©8*Ùx6@“àE ¼†®ßt\ΚÅ•Øã×öu+¥³-·Q¢ÌœªÉñÿ½ó‹"ÙÚø[ÕÈ9£HRA$ˆY1æœ0çPÌ9ëšóšsBÅ,FLA•$A@%g˜éúþ˜Ñ‹ßÞ½÷î®nìß<úÝÕÕ=ÕU=§«N½G*ÏxUš{²t…<žKõãme§yÃï(øøQDHU¤5ÇiŽÓ§rYå²ÊåÍÍÍÒ“¥'KO¢å(gÙAv§p §„æ ðKùyÃ]Ñù£‘‰ØÀFy‰Cd.°BC؃g ùã-¤ñbªÝS%Fº+b©NÙK2û±šác¸ÿgž éÊÿ—`À#8Î# àÑgIsð8Mmè1"&‹‰Y#K’ŸàÏ}¨Ÿ{ªÛ¹1HÄÇ¥;pöx$¸[\>õoºÞiÅä&©õ¦™xÛùÕ(Ñ*qkeÝôz½e–¼ž…診º(@e¶fÑÑZÐè©mX 5;ëxµC£Z5£írÖÕ&Ó)çRYê³ã‰õrc>%d/‰LŠÏÈ:ö¶"C§PíŪÄ7ÊŽË=åûqÀa­¾|¯gXHz“$£z¬MØƳ†X€óF¬r.‚ÿ½<þD(ô×ù¹ ’i¤®¢'!cØ>t–¯”ƒY×N¬Y¬vtÓ. z=Þ­¼ÁD­IÒö%2f¨·ÆlçÖs5ðœã®óÙÔGb%9+iEš!¾x†ó8M¨A‚"”¢òwýŽŠ™ƒ~è‡~8‹³8«¶Vm­ÚZ $ xañÂâ…•ó*çUÎÃLÁœÇyœš†€À¯ãç wÅûº*Ä!™øû¾ühe€\!® üY~¯zÉ#qœÖ&Õ.Ò£ù“KEeÙLz à$ý³°/ŸÏB@ÑOþˆN@Ä(b1ú‘eÄcÈNL€[‹ýÂp¶·äíåmùâÙÕ<Ä3¤Âh<ŒÊõ‚5×Û‡YŒ×k›dž¥íÔ´¤~lÍ®­8Ï4»el|B]LŸ‰šr3±;çgúÂÌ_ƒ™Âd˜z¾Z¨Y¸CŸLVfúЧÄàmƒ´¢œé±¢ä3¹žáº¯Ô>޼»à©<9"mmvXÁ4À,LáÁf)¿†B‹·;7v&¾Ä…T‘Xžò˘?=dõ1‹qFСø¡ )D(Cd¸†m%zȽ¦'d«åÛyo¬E 9^], žÚ½O;÷Žcov}á¨Y#Ëì¸æm@–Æ&UÃȾª¬ªT™kͺ³!¤5óGž²kŒ¯:¢5h ™NŠh·X€ö¨ü ’ÛºHërQ„6ÏV û®âE/µ*»ÄºvkåÄ´å¶Íò¥{÷:/ r,kõ×ammî£sD]M»‰Êp€ðvƆ^*ªÆ«LfÕ\Ùîïj;§¼ƒ¬i‘¼´CÓ‚Ä ™—‹ù‡Û_œËjxG?20iïÛøôÜü}é]>Ž-ÞZä^Ò­œ~ùRmÁâioJ´Ù4lcÁXÁ#Œ]F8Ò±'‰Õ8„(F*ñJ¿$Õc]kB *Xƒñð$= ÅfÊ&ÃB1j¡Rû†Úë!}æ;îòËêcÑ ¸†­ÉlÍQ?E.X‹È¿Xt¢‚;ktïajé*§i}ê誘N°ÖܾÃlû°´]Å-‹:nuœæ2Îíp€IDATm±âäüTù.ùÎ?ì»ÛÃöÌ–Ù2[Eˆ%µUj«ÔV¡…(,Q)Q)QQôÄ€<Á<šŒ€À¯ãî9oK«*$h 'XðÙÖNµ½ø8wCó²t‹¨¥òÙµmàŸC |Šì Œ8žcåår9T° 9Ð#¡d²éNâJÎáNà´Ü”Än–N(¿V…h¼F&¢ñÚ#³6ö€Zo•0ɇ¦³œ.׬mw¾F™f^c©ã ó‹®÷êŒ2ö©íf¤™'Þ :«$kÄè+-èÞP­íòIgêLÔ 689ý×_?oqù±Ɇ¹«ž'd;<Íx3õÓ‡§îo´>lŽ›ÔêÃÙYyù)œà à$1@DFœ%‰bšÌAü ÌZ² ¬]ñiÈýêçP@@@àφÂ[]Ï{;f¡'—KÝH ùD¾›Î&2ÀB²[-z5ôœO Ç#lzNqNh açc [ÙiÙ€Õa¾,‘ï€7¯½·ÁðtâÓ›Kãzg(£ó Í+Eƒ²g×™«³Rg­õ*‹|‹v‰­Þh¼ÑÀJ,ÅR´B[´…ò/¿¿303ä2¹L.Ã+¼Â+Ý·ºouß–û”û”û”î+ÝWº¨@[Ê–²¥è„Nè$<Õ~¿ÀpÏ*íÀäSøGÌB½P\!ŠÐ~'<À%ûH'4D ¡7~gäÕNRð¹¬Ûc¹BÓzÐ@3´ƒ#:À 5È ² ƒ‰¢È2bF¢1½tey“J£ÛgŸ ·ñ ;ˆg' ¡­¾[¿…¶“ÊÊ6CÜ.Xy÷h4¤Ör{ãç´bLôŽ©ÅhnÒ£:3ꦣW Öº'M5‡G®y4Pæ-ý´9_\ó©OÁäÒÙÏÚ$nÉó½é˜úæîà'“šæ·.ñ©\_PZ~\V Oa*vø¸tšK®c"Žâ=¯Á3#öŽY` P‚*¤á ‘"” A@@à@1  QÎ…r T“ì#êLË™…|¿ŽM—,7uèr´Y{Û³› LqOj8Ö±¡É!@~M~`ÌJ^)¯yh~lfæžeÞ‡‚ÂçßNˆ¼˜2À 6‘Ëàt¨ o!Oá/•F–»–OŽO{müZµý«öGÚ©[ìPäPt+évúítbG‰£BŠñ¨Œ¹d.™«½¤ºZuµêjý-ú[ô·”©•©•©hhh)³úÃþ‚É. ð[ø†ûÇgÅ¥ó ]hð5`ƒ9ÔPÔ–ËS¯+.ɱ ÈTÔ‡ÞBÇü]©^Û‹bœÁmÄ*þg`@SA}&B9«Ä8bŽdl§¾4†ØQDNÈNÈó>.Éw)ÁÇù(A<Þ5Îù¸óèyDö GCõÚÖxÐÆßu[Íõv Í5©£Ü¦‹qlý#ÖZú’ëš6Ü6@Ä f0Í`’jš ãÕÒìa3Û`´Ó°¹]VºªÅ‡wg>䔺Gð¯Ì²Lî_ŽJx7-Î9uI~F|ÝwkrvÔ(¦e†ÿïûåNP™‹p\%»ÉlVÊZ±ÝLµÆZtÂTª.¯&ü8|3fºbþs†¡ Í SÉ ¾3;Éjð}Ù0…6wOm¹Á®áD§žE š·Ëw›d~ SÙ€¼J6à Ef÷]ŸÖOsØ6ñÜËç…çFÝ3Œÿ,Ø"L¤Ô‹L“·’gñ©7õ¥[*Õ*’*^Ǯݻ¹kb×û]ï[ï±Þc½‡{ͽæ^ó§ùSü)ÌÁÌÁ¬Ášßµfz¢'zâ(Žâ¨j‚j‚j‚ÆF+,+,+,KÚ”´)i£Èȶ²­l+Ú¢-Ú J@à×ñß ÷j Þiò¼ç…Yp$ÓÑ–Ç(ÓÁ*‘­Ô¼* ¢Íèâ¼Pb!¸ÂŸ’rT~–nd°Â$ù: ØŽQÃr “I.|ñF¡q 1•mæ ol‰öòNº^^"¬½}Ú«ÔÚ×±8¢»¯î‘Z-õòÚ”¸X7YìðÆH¯æ CNõ¦h¶¸7¿äö«Ùj6¢•uç©Ý© ›ÑÚYCÑ;^û¼¨K½ßmɺZpñ͘´“yŸ”¿‰ütþÆÌˆ ÉÜ˼$ƒ+øVüc¶˜—±ÕhŒNJ«üêt‡—Ë…R/>›ù3G¾˜Ã*ÑC±M©ê D‹øu¨@‘âùI»’hb9rÙþkÀ„G]‹­Œý´úîw1ëR³éËõÈç0€ïÏÚ$ŒÇ­Ln”?ó‡å'­# އÜRyµ·Ê½ÊP6‹'®8Œpƒ+{Ëjc oÀÏb›Ún¤&1%^ ?òä.É]’»šµ1kcÖÆ¤©IS“¦m2Úd´!÷È=r­ekÙÚßõi×ýÑ{°{T_©¾R}¥å®å®å^~ºütùé¾€/øÑ02áÕèÌÐtÏO/KÚ}Ø—;¬Ø^¦'p@@»’{DmE {Ó¸…ØÏ‚ð†ÍÂÃÁC$ Ÿ„E±JªÇ1õBcÔ&ÑØÁämKòÞ¼ »‰KÖc;ظçâ#Ãù¦]HSŸZœ¸«J)w¨Ú#ÜiÉ–„3©Î¹‘›ƒÎ<¨Ùµ/´J*ÊîVÃ%ל.#Ûä¾ü"6Q(8På•ÈÁƒ±`Ì‚>âiõÓê§ÕOÏIÏIϱèoÑߢ¿åË+–W2jgÔΨMçÑytžœÉ™ü÷}’µFk´V$%ó$ó$óÔlÔlÔl*l*l*lŠJŠJŠJpp€­akØtDGtš€À¯ã¿î¡Èþl|WváW°ý9©å“ª¦é„‰‹iW@.?SÓD·ŽVÊpåò–üv•ˆ…=¶à."„*þ £Xn¥à%’É4ÙlFer¹œ• p »HkÄÐýIJ‹8‡³¼9‡½(3ª¸S…$ {mÌÆd+‹ÑØ¢ÖPÅß½¦}¨iúUO´C®×ÆÌ§± 5îi]Ëôˆ†£f;­@ñ>€îÀAµ­Z¡ÒÁVÐÚ/]n…ÑZWº_oa•%s.m,»öÒä]£üU¯×¥æ~ªxZëõ­M7‹_÷Á6âfÜŽ YÙˆrÏÊs¸ÀæËw²0 ¸½ô4™†>d(&òø©Ìœu`Ga†¼GþOÕ—þ¶(|ÖEà@ê^ä ‡¤,Çg3´bÞ<ôªãkª:aP÷Þõ|·Ë³{¤V¦þPôåý…‰©žv—mÝÑ(pîã°c97뿪õþàGÝ‚Lzbɦò)ÌOþˆ¯Å&+C2U J¹°ô+Á\þ*•¿JF‘QdTÆóŒçÏ߇¾}êÐס¯C_KMKMKÍÒÒR¶Ž­cë031‰HDâïTyÞÄ›x+†øUâTâTâ4;kvÖìœý"ûEö‹Üe¹Ër—aöaa ÍM@à·ðß ÷h|@"Y1D®Åç ªèWdðArKÅŒwb>F'5˜ê\âBè¶ÙòOp £Ð[e™¿ÕTÞ"Ù–†úrÆ‚à =hÀÞpF#ØÃœÇZô#ÈabAžaJq¿Rýò¾÷…dÜC€]¸€g:zO´{«Ð~¦vQܱþ{ÛQÆ—:\ôH³ÞÒØ®®Ô0ÕòœñEzº.ZMTÆ‘Qb'ÒMô\MÊ;Ã~—ž“3ú¬ï ¯su×mÉ?]V÷ã輸R—x’nTètwrÔñô‡÷D{½KJ ËT)˜žUV®-Í·ä7c4€ÍÖ"[Θ„³ç,"ÞmbŽl{æˆD<Þ# PŒ,ä(uëþúˆ”Á F¢šr ©?Y$oÈ{0CÅ[{H£dm³©wûZ»m9ܧqÝEº?¨¹ {Åš*5€“qe¹y!å÷M¼ýªö¦Û§x’™åœ3±ø€Ë}BÈ þ0oÇÞò£ùÛ,9°ÄTåy+ªé†ý”vh‡väyGÞUhWhWh'¬OXŸ°¾%iIZ;-;-;-®”+åJåÓåÓåÓ1­Úç÷Á ^ð ÜÀ ÑÑÑÕæªÍU›W”V”V”¼)xSðv°ƒëÉz²žXÕX-4=_ûÐúϼÂ'‚€ª3ò¾|ƒ‚[K«,‰‹ö2Õ\TòžüiÝpU i‘¤R4Ÿ{_ÁW‰x ` ¡rÿT‘ÎF.ŠqAxŽãÁÜa‘bG¤1*q’šÓd)Ñ#ëd™ò@>:·aÁÉÒž¹(¨$#¸ˆ‡x£,ØæDýúÝ[nw¯¹·l¤º¾Îul ¬êm´²5¸mpÁð˜Ú9€Ýâ“4§j¶”<Ó„vé"ëa–2]ÍŽÃ÷¬)ЫÉõ òѸ¬Å£í/Š2<™ûJ'cï멯óËŸ~k÷aRæôÙ…ÎÐùw_”l#µ°†N&.$‚¶¦÷ˆ©ÜS¾^ŠÊµ ä«Å±.Hµ>ʃ‘ÁDD‚k¤¿›y°‡òÝ|koì§÷JsÁß®åõS¦îµÃ¹•þKýåª?U^r;@>Hþ"×»0¯ªÿ‘õ7O½Èݾì|ð³Û‰ÓãsbáŒpìævÓ2›waÁl6ßßÉô Š7¡ý‚™<D1sfÎÌ1 “0)avÂì„ÙESЦMqLuLuLÕ²Ö²Ö²ÎKÉKÉK!óÉ|2ÿwrqçÀCò§Ø ž¯ž¯ž/—ÆKãKÝKÝKÝ+{UöªìEú“þ¤?[ÍV3ÁdøMüÃ…"aDå­äÖòîŸ6–l®…}”ÐxHùx>àƒÚ•³Ò®¢ôPŘ*ú“&°€àa ðo"ņC‚а¼¸ŽQüˆyèEz ú`Á *`(œDÛÁ.!6QšÞ!Ç?éÈBP'éTÉÜÚ køë¦X·0UÑlÛ‚oÐÎbC›í®ê5_ÙÔ˜¤©¯ê-Ù%:†—Rm‘@ú£­ywãçª>ýJMclš÷C'bwš¥md«ã Síóß$§®Îyôziz|Ѿ’'§Þù…NY–Ö±¬nÅ„ªÉl2{‰Ùr°w òn@jPC9JQ*4?Œê‘›kõ¸Óô¹&wáµX=x0h¬Që,Ý4±OÏ.®†iøäÖ-°7²>§W/+S«žì=ëËÏâ'AÐå6I\¸*ïÈð1N ²G)NBn‘¸…tùv~.óG,°(¨2Šê/E9äì9{Ξc7vcwÔ©¨SQ§ŠÏŸ+>g¶Ól§ÙNÝ2Ý2ݲK¶•j5•ÊDQâ–t7] mÔ…´ðA¨^ÿˆâGt$–ãÎ!ðyq˜bTì:ƒ##‰nÓzä ‘Úä éYÞ¥bzåê}·dã‘‹x„„£’ãâVÜu½wš®*ÒV{\ˬž¶¯tïVsbÝäš?ho¬=¹fcÝy†7õ/ªŸøçÌs¹¥l¼=¬è:Ø£N¸1Ê^ó»§­íÕÜéF-‰ªœÛ>ewÁÅëÃKRê>¦/g§mËj¸*æµIJ­l¿ò… Ñbùù¹‚!Ÿâ?]–‘” 7ÉE—åÕMvÅ÷âo-ßZml&¡=ñ$EØŒû¸„½ “]»‘FU•ÎkšÝ·é?w»ï“†ëͶ®wàçòó¾¿à´Ec®f„h§Ø¯!Ç{=?jùüNj1`wFÕ|›À:°öìÜ ˆQ†DT)Ï.ÿµçú/@aæ*ôXdA–¹)sSæ¦ìâìâìb½ëz×õ®»Õr«åV+É4É4É´ÚÓ†‚ÿ çý_Є&4áø(Œrƒõë Öóóøyü¼¢ëE׋®ã=Þã½`² |+þ›áŒ¤‘½ØˆÎL›e6Ù©EÙ¥š•Ч2#æÅDzU6HúIÍ9ê«<Ê FÐÆ}¡z~ÕM[9*!cYÚËyÖœ1èC›©Wá0YLmÈyrþpïæõØ…Jµª‘rŸ,äÖ,Áé³·‹Ó¸Ø«Ž.=욚ͨ÷Áòžî”zí-÷ê…y¾uÙQË×á‰åÝZõ4;¸ˆyâÙªb=¨è‰†{ÞÔwR쉆Íä'ÿù^-WõrJò~É|íù-¦uW¼H˜^“¾Ký\ýúÖ,kz©©ÉáNk¸5}D‹¹t³ÜžßÀwfØEØ*=j?_ÂâWoK5éFôG'4æti?2^îÇfCPW‘±_Ͷ{&L?ב[|#sÇÞÆ áY5@V ðùÝëAêÜéûô^FøÎðóëŸ{O»ßäõB`ÀUlD#ú‚Œ õå3øfìG<ÅKÌU¾œ—¢ü‹Éþ­(F1ŠÑmІ_ϯç׿^ùzå땎M›:6uuququ 06`,\à—ïn²+PƒÔXwÖuWÌè~Òý¤û‰÷å}yßÂÐÂÐÂPÄ 1BÃøVüwU™DdÐVÄ…ˆå*L©çŒ,©]Ú7¹Bú@þž¿ÉjJ$s¸®¢æä(zFÁ:P*Wà›QÝ”ÏAJX41”uãÁ)æá*’መ‡!h _t@]êLr±—Ì"ÆäoÎ&±˜è‰¯CßoŽ|úþŽ¢0Í—êÏž$èûj&HMÜûÕ 0;×f²Û–ZkÜÎÕ¾©¢öóZ­t¦i¤ªl"›Õ:ÓmïÌ*ŒLu³3ëúšteñÆÉ ï—rXÁoé Õm^·©Ž]Útn=ãœÎ–Nr‹—–µ¬Rô…iÜúŒÜ“WñgÙVÌÆ6!Å(WÎ<ü’ÊQ éBÄ8CŒ1vòM|'æLj’ž$Ú§K“ Û³\غum©U?ÛÔ˜˜‹|È9@>L¾à|¹31ÞLÿ”ºÌñÈ•WÓCâŠËÓ*µ«b‚q‰'¯É&³ЖOg³Y±2$ÓOŸTß–×x×TLÅTÌ»ò®¼kØõ°ëa×$ H`úÐô¡éCâJ\‰+ó`̯𠯉HD~Ç:WƒÔ°{±U¨B•ö íÚ+ØB¶-,D¡ - ðÇ ÓD¹ôdÌ4÷³víYæ—ÆÆ•8-(t…±•ž#ÞÕÓ4š¥«œ”$7‚B½ üÁˆª)"/Ã8xÑÓÔˆ Íç¦Q#Ž£ÎÄò?`ÿÖr¯á…¡+;.röØÖkZÍ6îíÞžçk—SçlÇÁý>¥&Ì9ë÷`b¥Ce½ÈZ•ÃËMCj•—•—EÈoŸ^ÙåÇõÈHÚź³þuÉêÅÕK&'‰;öQr–¨Ã M?*Çãþ3´ZOiÔ¦ÍÈ5¢Jæ+쨞ÑSÛåb­Ùgz,_Ñmcõü02Âoc–MëÁX˜þÌþ‘fûüÏߥÇR×5’Ñâ³¢µ_=H48s’„½XŒÊM g˜ßÿKO èèAzp€BÇ†Ž {ÝäºÉu‡$‡$‡$å&„„¥ÃÌ÷£Z …òŒ»Én²{ëë­¯·¾~úãÓŸþØgoŸ½}ö*÷v'ÝIw¡Ù üNˆ–Ò¡DùÖ>ȨÁ«Úõ[³htY™ã›ƒíYöŠâWÛ:ÙÔP÷$H0Üþ”T÷yí„æ°'6HÇVr›ôÆSBzã>™EŒ°¨"“~Z€ú¦êëZÚè5YžºÅiÅë÷!Œ1§Éc¯¼c,Qƒ±² ÆL™xŸ±°Õþ™/»Y:,pA£aÍ.ê·Ò^®öcõ2¹etA­H1Vn’@ô•§¿€€Àg´ ©"I¦ks«é>2£z–zõ­*ŒÖžž±ôz×€rŸ;ë§æ0úƒ_cO[ÅXˆ|F·Ô·gƒÆ6›Ò OM÷t6iRýʹ“$‘ ˆE.AQòçžø‡öH2Œ #ÃiÝ;ºwtï\|pñÁÅOÓŸ¦?Mï¥ÖK­—aq›¸Mܦï~A !HÂñÏñ‡_~uøU¤a¤a¤a›am†µQ^­`¸ |+DÿK&6‘ˆÅP¸½jŒl[ kÅO£-I~„ÒðÎì¥v”F’P¡jªû”_Å#Ä3 ¦ ð•÷¹ÚCLvÖxN«È ’K.’i0--/µ/ ˆ=‘Z¦ž´-|SíNeÁs~”ùË´h°h™è“¾5§^îo ¦Åí`Ä:Z»èº,‡Maãñ÷wß㤻}]`⋺§[ß™ùª{¢ô‰¹J‰4êEî5fƒþì 3a=°‹±w@! ”À?êKºP¦x‚=H]ÈGüÀof}Aå`£ì¼-b jM¶î³Ãõú°§\멯×K‹Êö²9€h+çù~Dv\‰Ën•‹Q±C·{žŸõ$ïYaZYw<Ã0@dÀÙ‘"YW¹óbÖl'!Æ…ò—~÷‡ö?fÁ,˜ñ Ä#¯m^Û¼¶É»’w%ïjžÒ<¥yŠéVÓ­¦[1 £0Š=eOÙSØÂ¶H@¾ËI D±ä”§ÃépÍ0Í0Í0VÁ*XÅÇ¥—~\ŠC8„CBCøVüO†;æ±x À(â+Kd·Ë&ɶËå’[ä¹à%TŒT4tÔÎ ’waäÕüS‹QŠJ6…ÝG¹œ5c ö¨Cô…#«KÍÈ¢óxðu£+»ûß¿>ùÊî/e쀽§Ê<{Ùs#_wŽtœØ±A#¹E&@™ºÉHýHUõoÛ¤dâðîsF°{åo±oíUµ—_h&´ÍR.ë‡Mȸ=4ŒÜ”çñ§ÙNÌÂ&\PNÓpªµs²xâ9ÝFô‰¿\…oÍ6ð`À³ †]µ6NOë{Õíâ°Jïùu v¬Q}T–GÌ‹­,´,½)ïyØ<°Otävós–Ñò7Ólṟ h}²ɬ/v ]¶@Í4qo¿è½Wýg`–a½KïÒ»òþòþòþ É É Ée¦e¦e¦õ êÔ+P¤þHýQ‰[‰[‰±'öÄþ;J¹ÀàsÌÑ}Ñ}Ñ}5 5 5 >“Ïä3s?ä~Èý¬.÷û,–P@CÉVÒF‘np«ÆãUÙ#群Ão_Zgè\ÆVLá»AµËæ½yW¿-z0‚‘²Ï ÏÈ3£¨#ç)2YrKECEý¡AzQ¥ÿ«xª(PTÓSÏ%§ÖúËk_÷:[råVÃÉŒ…ûÎÜÊØÃŒiÇ{ÜÁs®Çµi^¸€ë”éªm§eÚDÑá”çÚM40„Ö#—‰>Ìa ¨C!ä“Àß ÅøºT .´ N«h/â_=‹‰ª¾FÔÊc·z¶Mïxnâ˜ÉŒ=îã±ûk§þÀXXæLï’÷.LYõã¬Yǽ‡Ù.«®÷¸z \Wº‘ìÀL‚7L jÑSÿüõCiÚŸöW\o“M>6ùìì줤¤kefefemhC›ªRUªú¯§šbŒy€y€yÀÓ;¦wLïæßÍ¿›oTnTnT®|‚¹7â&4pßëYAˆ ¡ D53õîi¿]á·´ï<Æ–% gl…ýˆÚÇåî¶S¾O †»À? DÊ)uà"6b„È’s$Å?ÍØ"¢AT­ÛGç.´íÔ£hÞÞ“3 -aÁØÃÓÓ[0ºb†¸üæí€©}Èç‰:6hwªáP«°Ó+×t¢K&¸þy“Ò¡F0åþJˆÀ}n±¤Êqˆî"Ĭzc½éÚÝÔu¦õ+kX–¦wÎv¬c¡É32öPoº”±þÓ«ø”ûc¦¿=Q¹8·‹a ƒ-k}eî“ 2;h/El”›¤1ØÿZ¼ÄK¼T¸Áè,ÒY¤³è¬çYϳžÑ§£OGŸnÖ0¬aÔ¡uêK}©¯"öê÷¸âM¼‰·"]?·~nýÜû÷î\–^–^–ê;ë;ë;+sê}¢/4vß 2 q¸ HkmPk¬ÚèY⤭=±ò­†¿clyÎðÒkAÃ{vôPæ¿„D ^Wùb:æ 0…<"ýAk’}(ªžÝeQ&-v$Ïxé¥?ðšÏÄSŒ…î›q±G§c,¼ÍŒ•ÓïÖ¶îúˆõ½õ»µ(±[ȹÐ\º¤z9¢î\oª‰õ˜å¬×W/6ÄÕÚ§ô ÏͤgÉ…êYèºîy´KtƒÐ¹‡ëÀXx¨ÿ$ÆîÇM½ÎXè´äy÷šL»~ñÂZÇ^GÛúº¶|ÿU IÑ%?úÂDôEåî;k­ü>+bE¬éMi›Ò6¥Åœ‹9snÌ1CÆ QfRÈAZÃÖßåN’“ä¤"ÝrCË -7„¼ yòêäú“ëO®×Ö×Ö×þl¬+tè~'Na z' GxOrúa¯Qº3¶ªÖÈ1L¾üÄðÛŒ‹ë‡&°‰FîïlY@àÏâõµštõ'¹¤%õ «q¦zFëæõt³6 šØ&â]›€w£“ Ÿï/fì‘hZ c¡GgøËßÝ?0Ýæ¡ÝŽ›õÒ*Ûî“VõG*w¾:aY‚tbƒd¬AC8ÀB¹CШøc©.Ï:ýИ"-Lv’ZX¢Ø¬VCežd[·¼Ñu~ ‰Ü¥ëÛ±G?ø1ö°|úÆBô¦?bìÁX¿õ³v °«ã½¦Ýk÷‚/–}}¹Jjc2G Ikå&1D³ÖÏG’d Nâ$NŽœ;rîȹ‘ç#ÏGžß5iפ]“¨ u¡.Êüžð„ç÷¸jM­©ò• ç²žËz.{²ãÉŽ';vð;ø¼J™J™J™âj‚„@@à÷BˆEÍ© QÊK]ó<¥ýjÆVuޱåm‡Ÿ6åtÏvŠ½Ä ?`(Œ  u¡ò”(¦æ¬Ä$t¤×© ñÂS¬CõŒV5ÌéuŸ1¤e“ýIõNÏ}™±PÕnŒ=ºèÇ1ö¨ûôAŒ…lšQûã§AŽã&u?íR$q¯Ý«^§G['Ú›¼$ Ð/gÔâ~~2ïJŸÒúdqC:VßÞ}gË5vˆ¶Ïî/c,´ËÌŒ=r˜Þ˜±‡§§d,LkFYÝmâ;¦çŽVùöŽhOT©ÆW%_¥šÄ±}•›QTÿ¦µJº‘n¤›bƒ{¹{¹{yDZDZDÚÕ¦W›^m*FH#”N20à‹ý7…®¡kèEz„l„l„ìYì³Øg±+V¬X±b]DÑEʬ;°ãk}}ïŽÈŽ:‘ãB'.ökÚ:‘±Õz£&³÷˺ÛœÂf,ík««ª#R¦x‰%˜ Ô›€ÀÏ¢ˆõè‚:0!XÎí ÈW#ñ†—uõÔ½¦¬îs§a@üÂcoGx3"ž1±Ð†~‹ ¹àgÁØ£Ã3Ƽœpdö°[3ç hüÒpŒN¥úäêåpGh09 †¬€ Ì¡û·5kþX†º¢uYÂ:x‹s˜&’pZä«E¢Î3Ì7\í¿îa¯X™ÆýaÓG22Èo(cZO3a,L{fŸV‡n##Ӻ亴Sߦj"Y§ÙÖ0,פ8‚A  •' ð_ ÿ_Ñ‚Z’bÄ™Ðö¤~õŒªé ‰Ã$Ó^Ýî†lÜujàaÆBOÍ<ÊØ£QÓ;1¢â×™±Ðó3Z$ç96ºpÖ¾¤ÑƒÚõj^5þÕŸcÜéQ*"Ø€éèªÜ^}N@@৺Œô M9²•¤Ò1®zÆuÆšZí-}Õû|Õ“`i ‘ú5`ìAÿižŒ…_™™‘y&wŒþt»~­=´Toª¸JVT/û@«HBqŸ_MÅÿÈQˆB”òÉÐKµ—j¯Ýov¿Ùý&òtäéÈÓÃ,†Y ³€ \àB×Óõtý7>»Â*¨ÃÕáê ê ÎüÔù©óS_'¼Nx0Ò|¤ùHsåÓL‹jQ-4A“/k ~¸Žä ©H/ÿÑÛ¬Q,+_i<²¶üÜ’°¡mòŽÏO”æae ³Þ „z“^Ä@¨7_@u_Üfp†i2ì&‘d0"ªgTgjæÒ»=O´Êµ{ü¨îÎξª|{qÓ0úãŒUŒ=¬œÉXxû™Ó–ž_=öÄ–„izí–Z^0s×ÝóÕ UÈhl¢ IñgÉ×j/‚;ÀÏc‚š¨©H’XÚ›•‹Ï‹Ïsib5±eµ|3L¯ìÔ Ù 3éb›óŸ\µ8‡±°¼™êŒ=l:í ca#gÖÊ\ÁiÜ]ÿCß5*´ØmÒH§MõS‘*²xK˜ò•FÊ?¹•zÃÞä 9H†0¯5^k¼Öëˆ×¯#VØ®°]a«ìÐ?Òé0‡9Ì¿í%pøaÜ0Ezåž•{VîIòOòOòïÙ¾gûžíÞíÜîwªP…ê_ª~þúÐh²™(ߘ§Z·thÄØòðÍežKÈSåS—LÖ³KŽãt›cÊ.]›„ajL@à·Q]f.FÂKÔ‘ëþµw/×’ÆÓno5M©C¯¼Z7º—oų;EÓŒ 7ÉØCÿiÑŒ…M˜Y3§ÿ•æívòõîç`ßÍtîW}|9ùDê¤ ‚Œ¦ÜñSµ?½ß 1mˆ;r±ƒ´@0ZÒñ³æXujß6°ãn­ÿqTtÃÌœ+W’&ve,tÞŒåŒ=85­ cáÖ3g¼Ï¾Øt¼ææÈ©íÚÞ0½kpBó«(A¢z\]’„cXAÊM‚s×Oà–rK¹¥Ð€4ÚvnÛ¹mçgYϲže=yôäÑ“úúúЃôÈp2œ ÿf'Þ…]Ø…d$#™N¥SéÔí“·OÞ>9îxÜñ¸ãÄÄ”±,¸#Üîˆp§þèÒ›h+ÒƒTÝmê>á=—MîUe·xήlñ ­!Ã×z´wP.—áÞP«ÏBQ¿ …ѬÐÇPlF q…Þ¤jÄî§ÙÛÿаÊZï„ÍÕ.óªúÝ]4­+c¡6~w{xhz[ÆBÃüòËE·÷M½}èà|³Ž›Ö«O-Ô~ZŽÈ“kCd¨@”KД~ùW$_-¡ž/zƒZ“ᢙܪMjâìçQöê8hêÑ,l©ÝÖ½[÷Î ÛºjË܇랙Þp/õÁõö-Æî¯›ÁXhï£+RîìœæºµdÚ½v‘u'X>1|õU3O'Cp…T‘õ¨@¾˜éTXNýoŸ „Ö£õh=ņÚOk?­ýôr‹Ë-.·x°ùÁæ›=\=\=\¡5¨ÑšBS¾ÙÉÛ“ö¤½"­ÝZ»µvëÃe‡Ë—=yÿäý“÷Íùæ|se\Î’³ä,…<?â)ñ‚¨"V‘n÷Ún[­ÂÊ‚%ç†fT._ì9¤c«ÂGNÿÔ"Øy‹"hE^ õ& ð­»bµ@]hA ` CRJÖ¢Š:‘e¬–ÙÜÕÇÎÂäý‘v nwöÊow½ßÄÆÂ«üý{°xj&cáÆ3g=»i=¹õÕÞ÷YÓ:Ám¤åc.Š›ÉyU?-M>xÂV0…4ÿ2ñ&~èCmà+ì†?|È=2ÉÜzÛÄ«zÞn­D5mgÃ:KÍTüö÷ìà¸ôáȇݎ›§^`Œ±„lÆ{2‰1Æ¢Xef©UIî ã–¬3/­S´£‘õ|£¯–M‹$œ1IÃìÄ(XÀÚÊ—¡]ý/ðàÁ£;º£»Ú"µEj‹öÆìÙw î@ÜŸ>7|n(2r{¹½ÜÞoÕ_ÉCò-3d c?¨m³qžçÑGa.ˆwÓ×´†Pm¿+ÕMçX€îd7i„›¤’,EjõŒú–Ï éªqqžK>m¾|i ÆB}flcìá»éÞŒ…®ö;ÄXȈ™=·ì¾8°tÔëÓ4q˜èS½Ñî ­G(Çö UH„[ñP=&¨9 ¡M.~HçÊ8=’+²áÌÈÏÁñ×£a*-ò’6*¶­»ÁoÒ‡¶îwÚlº×ûC¶óÅùãO2òqæEÆ"Í|ÀXXK¿ŒEtŸÀØÝ6£gä,y‡ËvqcìåMÆ‹ÍcŒ±³ß¾HˆT^Ú@®}DBŽU˜‚þhþ¹U{µøu~(J‡*4döØ{`ïˆÈˆÈˆÈqâÄ©•¨•¨•(³&!éÿ½lÿº3ž¦§éiEÚÅÙÅÙÅùÞ¾{ûîí TTT·èoÑߢ¿RŒ2…¤á |+~ÉBŸdä}Ø^ y®üdaZÕ6™ž±\üI:ú<Ï÷1rÖè«v ïA±Qþ5áí±]° p÷…êøîð`ø¼ÈoVâ"£Œâ"Æá15%ljñ#åçŸâüqã¼f»qoÉV›€æ‘ÑS=ûø»_êû´µ¥­‰õˆZiºY@¥O¥_£)õ MmMq07n8oÑ ü†ãvØf=_r6íÞé×c²[æ/VŒí{‘lâ·‡õ¸ÇT™7và‚ðLiœÉ /ܢ߄ÂÕA8ÃRô&dú¡5¡£tašÇvâ:ëÎ,QCù—F¡_ªã§þÞêµI­Í.Ñuæ íPÛ£©5i~¥Þ@£l#]=*鉳ˆ¢$à-y5€›R Šâ‡÷=³—”f¦äeo- rx8;~sN…q:L]Ú{?‘<¿Sß©fèr©þç Í7r]Y¢éPc?£Ó™w³Ï}ð% É^2cØ)öHyAB«øÍí]b—Ø%ä#ùOEOEOE%ýKú—ô·±²±²±ÒÍÐÍÐÍ(Õ(Õ(Õ ƒÉ`2˜U{HüÊÓ.&‹ÉbEZÃQÃQÃQ#U#U#õÚ;µwjù™ù™ù™¨D%*¿_ø'ÿƸA¹ NÜ…kFÏÄOsêCø>Ký†–3¶ªõÈžAaÃ;ùTˆTD}DÊ¥lÄǰJ¨<?˜êÑRÛ£1êÐé$•8~¨ÄÌêk¬3¶ÓÑñ[п¦‡æ›¤“Þ£Ž12Âï=cöûQÆ”O[ÅXxÝ™Ï^È {=çÄ`—&j„wÔiP½Ú‰ìÇCšA[“)B µjW"Œ°þoT÷Hæ@AI¢ŠK\º›ç6Ðÿ"¹kÿÊò¾QçÑ}ºu¹´¹æäÖ‹¢Fí¿0d{Ù˜Û–S?1ž6s3c¡kü–2ÖÆ2ÆBŸÏXÀXH¤ß‰ªéw—M ˆ.?¸b¸þ­f©xup¦]zÝ÷©ÖëOøÞÿ¦¡­€=w5ØÕàYÉÓ…Oú‡ûgùg‘¤?éO©15Æ^ìÅ^P¡%|#|àEkÍÍÍ>=ëô¬Ó³" # # ½c½c½•ëÓHWÒ•týížîÜ~n?·_‘îÑ!¢CD\^\^\Þ¶ËÛ.o»Œ±‹±X…UX…-Ø‚-Â-øVü’÷BT J¡7 ;ÉobòOÏÊVT¼#Gôª§ €ÃÏÑy¤²_©ñTÚK<<¿©L*[ˆih˜+Tµ€ÀŠü—A¶[Ç>˜Y1 #—±¾œ íE&¥·Ï®•ßd#N!‡Ó®÷޽Ðçz›}uGLjÓ}®Sïz'm¢ô?¼=_ìH­oé¶Y=`â›æM¦üÐSZø‘K7Kßíq¡Qôœ”«™#ó[Àœ;Bo’5|<›Ì²ŒÀ/ˆ¨DäÂÍù {XÂP&˜ˆÞp§K‰3 %ˆ:6É;ñuYG9Ø8 hÉ4ÝgPG½Ðú´Õ¹ä5¿Qˆíï³ »˜o¶ioj¨uV/M{›j íÄér7ù#€®!™7ƒjóûËÅò”÷öŸÚ%ÇÞJY–wý^­g§ÞÏ¿Ò%¤øÍ„ŒºŸº–hä'•—ÝÄ}Ôø²r‚á0œ¸ºôiË|Лh‹Šú‰ŽTήZé{üáiÏÓíâê“ú¤ËÛ.—»\<&xLäÉÈS‘§ˆ-±%¶Œg<㿚Cøu|ÄG|TÔ¡¬BV!«x]ãu×5jŸª}ªö)×ñ®ã]ÇmÚ´OðO~S+tô-` Å«—êkÕת¯¥ÖRk©uq‡âÅÐ]Ð…«ÇÕãêÉSå©òTá ü´‡,°O/øuôÍØò°á[6qØÄWq~j}CÌCtu´š*"EÄï„Êø“¢ð‰¯ægLÊÉFB¹qtõתϒµâtѽÑ]?¹Ô¿{ûÎþ{4c+cl§×cì¡Åt#ÆBÕüÒóÞ]Û0éÒzlj+Z뺅Úß0;óÕ}Р¯¨éˆÛØeX·¯suqÃ@¬Ç`jCÎ=®=]D’m¤–ÿÜ¡šËÔPÕkùÈ¥W-6ZÚE»¾Í —Åã»xfõ¸h>ÁŒ±‡üê2ÒÀo(cag\b,ôš_c¡Sü3ÑÁ`ÙâÛNÓȽ[Ëú{lØ?ñ@«ƒfz«9½58««¦þòg¯YŽ}0õçzSŽ®§”tC 6`°r¯T!EmÔFm2Œ #Û‹‹‹¢Dˆ>°'hOО ÉÉÉLÁLÁxŒÇx¡ ~ÌasbGìˆ4¡ ÍAу¢E¿Xþbù‹å;Nï8½CéN(¡ä·õ2E4Ö^´í¥ðb¶lزaËÞ„¼ y²°ÓÂN ;AúÐçZq­¸VÂÍøãð@-˜b4•kü8»×pO“¯l9â”|ò’¥CÍ2wÌ-ä`7Ô赞£"Mz¡òþTw§©˜ Dc1‰"Cð´zFÕ•’…ÝÛ´T«uè¶¢måÃï]¶Š±Ðâ‡ÙÍ{«§ä0aé¿5×ÿZý‰ G×/lÞ ™Û¸"öœI6)¯@A5Åú¿E­~þ.>h;êLn“Ú"/®U%#ŒÆ?=HäÂ-¦M[ê§iœxÅk@}‡}f—yËböj0dOá¼ õ“Ÿ3öøÂ,ÆÂÓfÜa,4Ào8cëÍŒc,äàŒ¹¯o§OñHZºá¨GG®.ÜÐåÂàç^qõ.º-²»gòFÍ\%IêýÓó’§džÒ7ÈÒAÄ ï°K0m¿Zú\ÝÙ¢šëñ Ä»±»kdÖȬ‘y)úRô¥èÈÔÈÔÈÔ!‡rP‘“ºRWêú¥–8!>À¯†‚‚Ò t Ð™qµwµwµúòé˧/Ï?>ÿøücÃXÃXÃXÅ^"%R"ý•300s?Ï¤Ï ™23äeË—-_¶œ&™&™¦\˜N_Ò—ô¥ + ðÇáS= …#8H€U)>Í›pŒ­úaäÉŠ6‹Î ެèµôôðÍîF5v)Ç4‘¬%õ…ÊøK¢(# bÆÂGTkF¿2©É²€ŒõØdZmîfÏ5úñ/ïwóÓa,,~Æ}ƩŌ…iÏH¯jp·ûÔÇêr£‰®cSóÝ_•s”4ÀòôAJŒ¹BòåìæŸÿê׿†º¨,\Çl²›4Ær‡tÅ=²›¸âÜaøï °|oÖ[÷U‹ç.5ÖÏ_?´AÓ…Oöî}?dy‘oúÄ`&½—1í$ca£föe,,zÆtÆB‡úi0ïß±‡Ù3N&…Þ5Š¿1gý½^Xk6þyëÙ ƒ–›/ŸM¦ïîÂE…ÜêÌ]¥©$†¨á%6(wü:%u…Ϻ5¬a­‘ô¹×ç^Ÿ{QZQZQZW^ix¥¡ÕN«V;ãÄ´mF› ]í4Ã'ä y¢H›ÉÌdf²@Hé£uÖ=Z×¶OÛ>mû(fEh( ¥¡¿ò4‡q‡•íGW¤+Ò][sm͵5£7EoŠÞ4têЩC§*›ƒõ£~Â}øã0ƒ64(‡,ìQ<%&Ó¦ÅNÇ[£>*¶tØÂуŠ[ÕvÔðf×jý`üIqçNΓvBå üå©6Ocá÷gª0jæ7±°%3‚ í=£c!^~ËJß”Iá>?Þ|wéÉ­³{_ô,³KµÒ6{§—ó³gÕºd úŠÖ'}H0œ‚´ ªÌóM£“¢Ctè:€ÐHÔHÔHÜn¼Ýx»qÌǘ1Æ-Œ[GJH )Qê|/Æb,†*T¿\À/å ®à Ò‘ŽtÑBÑBÑÂU)«RV¥¼^÷zÝëu£ÎŒ:3Jé´ÆãÎqçŽ.¿ø,aCÄC¬ÚLµ™j³;w>™ðd“ =m{Úö´U6(KjI-…Û" ðmù%?(G’É22 ŒeŸ-ÚP’‹ ò‚•[³~ ˆ•Ò‘ê×ŇEŸÇ•@"D€|%T' ð×B±¼•» †²h¦Î¤¨Ò7dÉcCY?væºe˜~âÝëKJ¼åpÀÓØÙ6¾ùùíÞ»yš»ëM×çÕçˆ÷qCäžÝÑf®í Î×›j[>¾ß-:ÆÙsÓ‡€5Qܽ6Ѧi®%+Ë6T8¨ Ð;ÔŠôãðö,w…T¤ã •×öý–6Š!‡ú¨ ¸¢6 ±SÑN"5Èu²˜b—Ü–×bÍåÆò #i¬$A|Ê(IG_uk}ؾ2ÚÓ·W›æöS›ô®K O'èfªµÑŠÐº©"Ä!€|8ï p'‰!ÀìÉöµ"ݪ“Yª9 й—ž©k N\ö>¥_¸íÛ§¹¯ŠR+ƒ‹õJ#*Œ™ºôÉB9É$Qä ÿŽbRVÂêa6’‘b~³e0‰!AÀWß”¯¶|ù· (Ìgù,ƒ0ƒŠmŠmŠmí>´ûÐn§}Nûœöy[y[y[Ý˺—u/ë᥇—^"Ä€°2VÆÊ”#÷Š˜ ÿ;Š%¡‡¸CÜ!ÙrÙrÙò·+ß®|»’ßÉïäwÚÛÛ‹÷Š÷Š÷V…V…V…âžáà‡_p–Ú¨Ú¨BªÄ‰âDq¢–Ž–Ž–NÕÀªUóÆäɃh€l/ÛËö¢=Ú£½psþ0¸i$„ôT¤[»Ym4Ualí€1õŠÛ,X:h$ck›¾=¸½Ë¦ÚŠŒ…`ÆÓÇ{ľ² #{&¹ѰQ}&9X½Ñn6Õ ‰þ—¸­ ÿìÿå:f~ÔG-"#[‰ºÈ›ëJ58êN¬~zh%F£ku6Ù«}g´¸k¹ëæãú‹,;EÇ4?¸gÈ™~ð™ék‹Èõa,¬ßÆÂºû}bìñÿŒ=5ýZqÕ–“Œ^¨¶v{§Î ™W¥Wv#[«k¶£j„éë’ ºöß©pdÞKÄÁd1±Á9BðK0]¾˜éΔ„‚\ä"×$É$É$é\ñ¹âsÅQ£:FuÓoL¿1ý”ÙÒ…t!z¡z éC@@È"²ˆ,Rl°nmÝÚºõ•³WÎ^9Ö/¬_X?‡^½z)”gèX:–ŽýÅ'q#nDÙêŒ|||ƒu‚u‚uîôºÓëN/³`³`³`eÖHD"R¸-0ô8™N¢¨¯fúÉ`L~ù¢:CUuX¼cÈTÆVóG·V~Jß¹å¨7XÀD¨= øšMòÈjn ]H:UÏh`ª3@½ó’#ÍZؽyráÈCŒ…yÎŒbì‘å´Œ… öÛÄØÃ~ª)3 Æt˜Ò û Ó•‹µ¾2ÐI†§d±D &¢š(wC¸mN’–¸Gî“Þx@ Á@x@ã§—_ó¥qŽŽO§‘M¬ËV'k­ÿX¶çÉà'Å›oL”1ö@{zÆÂfb,¼ÇŒ‹Œ…ÞöëÃØ“~³jUu 6˜>.nçÑnÃÅçï­¸ß5}â€^Ƕµ,13ÖmÍͦ¯©ÆÏU›èw–6¢w¨=‡½X€>ÊE¥jËv9N‡ÓQ¤»øuñëâQQQt+üVø­pÇ.Ž]» ¡¹N®“ëJA“ä—R5Q7pãó«ì¾Ä}‰ûc½c½c½»Çuë=èAl"›È&À¿à–ö =HEÚâ½Å{‹÷ #F,¼¦rM嚊¤™¤™äóRãîèŽî ø¶üòe^Á^T‹;TM“©åß)]¹];M=Z’‹ V ý,µOÒ%¨„%a!Rp ­`û'YR& ðû ð;W„XCÊtÙ\ÆË}Xs¼£ýI4©Áê‹Mø´8ÿdɼ%+öã!~ì}Ñùyã.UÍÎY—NìÞ£qƒAõ¯Ö¹®ÿ 7ÙÀZ?PsØ¿úž¯Ç‹»u­ßát»•ojØx­ñËØT׬nyŸG _ÓÍÜQ*WL kÀæ²›r/Ù ùFö€yþ¿+M…–k‚ý.óqžƒ\2_î|צB/­ñázõÌ_ÕÙg5Z¯9@Æñã~#KÅTšCûr9ÿáëŒ,,¯t|ìŸñ1ì^Ÿè³)}žõJpÌÙüTýõªìÇá>ýÒ{j0È`Á ’FÒHZIÛ’¶%m™.ÓeºAB ‡\¯& ð­ùÅÆ4;¼ƒ=PYÕ]WœP9Svq±Òsbu dj™Ò§d2MÌÙ¶šÕdÝþiT7:¯ãby)ó`"<‚.Öà0–¡?WNÛ“á™c?5)´ßsö"žáÔ®ÛC_¥õ®Ùºn]ÿ±÷»Lr|ìÑÒÞ×°!ÒY;k_eé®·£#›Ü›ð¸uÜ¿sÌå¯î*º¾4ÅîS÷Š©2ð—q¢!`*7î¬Ý¢‘žƒYZç¦MÛœix½Nº~ªù;ÃãǵCµÆª’&´cùü€>gyoªV¸¿àV™Aê€ìÓ…;#[¾yœsåj¿0»¤ a“b¦‡r/¸QvªÂ¯R.#žêÁƒ{I“H SÁ ÜäÍùµÌ}0'°‘(æ§óÉ,•ð„šUoåüŠQóíØŽíQ¡^¡^¡¾·ÉÞ&{›¸luÙê²µqÆ5×èT«S­Nµ®®¹ºæêI"I$sgîÌ]9ú.‚ÿ{mç"¹(E)J#?F~ŒüØgsŸÍ}6Û]±»bwEœ+ÎçVTT(D9•U!zõê$þÄŸøûûûòÉ|2ŸŒc8†cÂë–€À÷à—‚¯bwñ@#pE“*¼«’rýKWX È°¦æ^,’½åkéÕTùQ¢Ê¥’þ„Èx¶Z †»€€À*P2ð…%8-—ó‹Ø)’Hæ¡‚^#®deáø’Þ5à žá€Í•ÅÏõo¯V/iTAçGÛ¶Ú®ojŒä·eİ‘^gµŒÅ†ÅÔŸ4ôư&=Vï5 [S˜úîJF—OL\G$)m’`ùTõdIÙñºÇ cµZüe>ý©%é ór @Õ2Þ5q\Zfaˆ¯î¼?ðÌùí¶OÚbb]³ªBÕcê¼ûì¾òôÿ}«%\oêGzb–`)ŸÆÆ1=y'¾9sD Þ#-u¨ù¿.Šï+…R–ÇòXmOÛÓöqoãÞÆ½=›|6ùlòèâÑÅ£‹vØi`§°þaýÃúçõËë—×Ü'÷É}ÖŠµbB Î_RÛéHGºâUçå»—ï^¾+lSئ°Á2ƒeËìÚ´;Kci,%$ƒd0ÂûÅ-Ó¤I“T›jSí\›\›\ù<ù<ùÄGa”¯ëµ®×º^1ÏbžÅ<ó]ç»Îw²¹â3˜ÁL¸ß–_>nQ 9丄Oã*!/ZZyKž"~s ‘ÆžŠæS =nÒ^«H½‹ò¨-èvBu übî%Õ–·²·0Åx~ö ÷N\.9$~ÈãZ“‰6¯Ÿ¿µ{ÙñÕÑWG_i??÷lxüØW_íÔáEƒÂYMNÉNê;ðNç™d‹ËK±-yKŽIèƒSpcRìÇcÞ”Ênðelcƒ•8§¼’o[T@áîòÏñ©HEªb¤vÏê=«÷¬þ¨òQ壊û÷îºävÉí’ËRX K¡FÔˆ)1™ÈÿLŠPÄŽ³ãì¸Â€Nï“Þ'½O–]–]–]­VµZÕjeUfUfU¦˜¡›éfºù¿”©p¤QŒ£¿Å[¼ÕH×H×Hç¸. çiÎÓœÏk>îàî Å(n…€À Q'Ú›(W OéÓܽþÆV5åS齨tˆ¶ÜcéëaQ½-œë´Qä¡Î¤ *…ÊøÆTÛú?n§uÒT:w°žt†ÊÅ%ÇU.ÒÅôU¬A-ÜE-¡R'Æw?ôC?@H€bó˜¢1EcŠžŽ:þéø@ï@ï@o333üˆñ#¹En‘[Õ]n~®nICÒ4TlК¯5_kþ¡ã‡Ž:Þ¾¢}Eû X–Ün ·æ¿”éw¸+âé:…N9q4âhÄ‹m/¶½Øææçæçæ§ìekéZºVpjøÁ§êd·"=è–Û{û˼çr×ÎU–‹g ñb»–û/÷¸i@}¥j1=CæG¡Þ¾ êÿZG É@2ªÒ~´yF½i[RE{Ò¾d"u$ÒúóAÄ[ñïóŸÕR_þòàzÁ­¨ZA1GI òU~ß Ñ&ÚD‰HD¢š·š·š÷aßþ‡}ŸÝzvëÙ­9ïæ¼›óN™³#éH:*B…GµÀÏ¡èPêOý–v^Úyiç×®¯]_»NÖ›¬7YOY« ç–ÿ³V1CàókÀÙgoœ½18bpÄàzëê­«§t•ùu1Y¾#œ”\#CéŽçnY/*«»øÅÐL™æâCv3¶"hDÚ‚ƒín6œ¤ÌoI‚Ho¡ÞþþedKHaKƒ` Þt”ÿT!üÿ#º¤4`@¼` ÄÊèÐ_—/ðK©¾\µ éB”–-6¶ØØbc˜{˜{˜û}¿û~÷ýi4Òh¤Œ8KJH )ùrÏ„‘Ýÿ£q4N1_1®Û¸nãºE÷ˆîÝcSÖ¦¬MY’’’Ï2×p ×~¶ù?â§õ´m9ÚrôUr•\%ÁÖÁÖÁÖµ­k[×¶Vž±­E…™+ïÓ£Ýa¬/Nà&D ¹7K›•ϯ(Ë7ÃG²Ì@iK’ º¨-—žV0î¨-x% ü!(<Ó € xÇÄ;²0D8|•Ó–¶†- i9PPPv‹Ýb·0ã0îeÆËŒ—ŞŞŞuVÔYQg…F®F®F.T 2šŒ&£¶´5Xƒ5 YO---éFéFéÆ’Ô’Ô’ÔŠŒŠŒ ¥FòŒߥ[ÿ*XOv˜]ƒ ,§²ôjyQ•¹ÈE¤œìÀRHioòƤ†ê6I}¨Bšdiÿh c?š=}ª*|Äf|ƒ¼Ú@­…:´1 Ú¤Kš!é"Zä#Ríùƒ…jOÚÛü*íÙy” W Mô€&ÊÀaì÷W¡Py_€X€d$#™7æyã㽎÷:Þëû;÷wînÝܺ¹uëdÚÉ´“)ÓeºL—t"H'ÔG}ÔÆÝÿ ®ä«tè12˜Ô06Z³%G¸(C ŠÀ!ï iµÉe?#Ï™žCŸüý ÿÛ\…Ù­Ž¢²[|ëüV|kµ“﨔ÒI祔N!íè!E0GÌaì÷7ÀÇ¿ãßñïhkÚš¶NŠIŠIŠ9µåÔ–S[d‹e‹e‹}—ù.ó]f9Ür¸åp~)¿”_JdDFdÊqwa^÷§(¤+Q‰Êããã$Ç$Ç$Gî÷‰ûäQåQåQs˜Ã\)Óù3ƒä 9¨HëlÓÙ¦³MíˆÚµ#y§óNç.9Sr¦äŒ2ëflÆf¡â¾¿v|ÂûH:â–•õ® ©:[r¡*Df‚‰¤%QØ v@ÓR:A’ƒId0 ‘à›²K8Œáè.Tº€€ÀŸ)’X’`AšÂ‚ßX•Åo¬˜¼òhÅ䲡ãýˆr³ë äf«äx¤’GœUxâŒR j 5¡ % ÁAÂKx /Q,ˆ<›s6çl΋±/ƾkþÔü©ùÓÑ#G=R¡þŽõXõ° l„q÷Ã{¼Ç{ä#ù¬ˆ±¢(½(½(=±“ØIìTïP½Cõ)–#™Èü7u¨xš‰™˜©Ø é¯é¯é/].].]^0¶`lÁØÒf¥ÍJ›)æÕÙav˜*^@àÏ„Bjê!2qÓá§™Úe2«\ž;¼”U­h2<á¹tR@x­jÃUû)š‚x\*O@@à/Ú—±[K¬…%ÔE×¾Ö0­®“-Z[¢•øìÑ+‚9Dø¬?˜-˜Ã˜¨Àø‹ §<ƒÀ¿¯ù/£æ¤’BEºáކ;îxtæÑ™GgÚ=´{h×*½Uz«tÅ^Ú“ö¤=Z‚€Â§ éBºÆ0†±»¥»¥»åséséséYû³ögíuúêôÕé $ qˆûi1"±H,+¼áGŽ9v䨄~ ýú͉Ÿ?'^y*+jE­00@¨x?ÈU$á˜bÃEùЮÞ/[á0¢cË¢†ÝJÐõ ï{Áâ¸~-P"ªJê£D¨<¿ÿ2U¨ yZü~’Oü%ïÏÉE6æÚ 1Ô€j£òÂøð¿G1î»[±•Þ¦·ém‘†HC¤1§ÇœszÄèÆèÆèZ~hù¡å:Kt–è,¡*T…ª‰d"™¨4@ªW§5£Ê8¦¶b[±­ø6¹Mn“[n}¸õÁm“Û&·MЇ>ô•®8p_"$hA Z\>—Ïå+6Ln:¹éä¦)©)©)©U'ªNTUäÕÕÕTö¾c_þ•Ç)–rqÿšPËv.>\n   \ÙsæÇži “ëè>Tå¥ (Gd¸€!ÕT“þüükáj9€r¤2 ¤‚ÃYp°Ä{XBŒƒ¡ L9NÏ ƒôèÉš<=Iö«= û.¿‹p”rÝQŠZ„¢8˜‚ûbô £ÄÿBá³>S0…E³h-+–ËŠ <ø¶ÛÛno»Õ÷­ï[ß·xÿðþá|9_Ηã)žâ©ÂŸ[0¿jÆšL“i*Ìë¬%YK²–¼óvÎÛ9ÆÞÆÞÆÞ¶õlëÙÖCrCN“Óä´ÒmIÁ\ÌÅ\ÞŠ·â­`˜èÑ£7¦¢UE«ŠVEoŠÞ½A! QÈX P* |¾ÙXOfIqßòê£ÌÒXkվ⻜«æKÉ‘Rñ¬@[8 •. ð†A9R!G Ì‚*¤£J¹—B¦¤LaC•%¼T–¨_;±Eýš¤›÷I7@~À;Æãä4r˜!fø,+©.ð_PÈDú3æO¢H‰R8l[tlѱE2s™¹Ì¼glÏØž±¶1¶1¶1,œ…³pÒ™t&•æ£àõ®h¶*L…©Ðûô>½_<¿x~ñüxq¼8^¬æªæªæjsÀæ€ÍÌÃ<Ìãmy[Þc0c”ÏÄLÌdy,åIR$)’½Íz›õ6—Í,›Y6³È¬È¬H9–¯0ñW%ïÇ7{œ}š_2³,€;jËGðÁÌLc†x è¥viOq e¦ƒ¤3<„JøÛ"ÇÈQÊ£©èŽÔÒÑgo•Ž.·Z9¸ÜJrmÄÉ5Õñ^©Ž]¬³@tQ)B“îÈ€.€¡DÍý‚B&R $,¥³t""""º’u%ëJVx¯ð^á½L4M4M4ǺuëNf“Ùd6¬a kÄ#ñ‚Ê»’çxŽçdÙGö¡-Ú¢m²i²i²iÞ²¼eyËìÛ¶?¬·Do‰ÞV“Õd5‰Ñ#Ÿãª*cI Du¸êpÕáiii•W+¯V^-í[Ú·´¯"';À°‚ô³€À÷ãÛ¸?.¬Wªƒ0.«gÌ¢!¢\oâ2QeçŸ gÔÞÃþÆ؉T"•˜Išc¦lý“î²õÅ}—0Ãà{ÌPeÍöl•5ªífïSmGê¾§aŠÛ0…ÁB¨Æ¯P¸¾tEWt%GÈr¤ªiUÓª¦û5ökì×ÈÑÎÑÎÑn¹²åÊ–+½J½J½JÙV¶•m¥óè<::ÐŽ0Þœ7çÍqwp'nrÜä¸Éىىى¶¶¶¦Z¦Z¦ZЬ$‘$’D届Ŧ•¨D¥jªjªjªæ Íš/ÊõÊõÊõ M M M”9çaæ V@à{våßB5<ë~axñ‘Ψ'_ͤl<>Š élñ[ªÌtà$¼‡ üQ¸»ˆA G9äÐfÚ0¡>0Aw8£{ù²£ãË—•µð­_Ö‚ÅT.g1\¬®'‹wÐÇ;ÔÂmÔBõç+]p üÇ=2‘+øü …ÚÌóSÏO=?u‰^¢—¨XO¬'Öª>T}¨ºÎ,Y:³>Ù¤ˆ‘"ÁyCŒé(;ÊŽ*Fßï%ÞK¼—7'oNÞmmmmmm3#3#3#…p$®à ®@Ѐ¼à¥(Fê!õzhøjøjøVÜ®¸]q»pnáܹŠÅ¬l1[Ì ?)$ 8®HÛìÔ[¢™ÇÜ—¡]rr¡ó dÆ~¸5ö˜_J³ÞŽ3 5¨‹Óºd#L  ¡öþ!(¤!E  (šÓ)hþoò)ôã?£ú%¥rhÀN‡tˆ ûEtòŸ¹¤5yÈÃb,Æbmmí€Ó§NGµ‹jÕnú‡é¦PVê2…LQõ ýsPjïÖ_s|ÍñggŸ}vvºþtýéúð«ö©‡z¨G[Ò–´¥"¿} ûö-Ù<²ydsqÊÅ)§˜š˜š˜*G܉3q&ÎB |?~Ûˆ{ r>Ë;–ù:þjÁÈÊÃ2OÑH­y"¿¬f¼®ŠV)ÊQŠy[~»Žžh;¡êþ!ðø¼¤•A ø­x„úd/ꃣŸÀ`¨Ãg•÷²/ÇCÅxÊoÂSä£ò!£IÁ†hÀŸÇø¥ÿ^¡£ ]èbCl>|*øTpÈýû!wYYY“Î~ý:û988(Ýf&ÓÉt2ªP…ªôè»Bä1ÉHFS4EÓç>Ï}žûȞ˞˞×/ª_T¿ˆ\#×È5lÄFlT¨Ð z@éò*•J¥R©Æ%K—J[•¶*mõÉæ“Í'8Ãά%kÉZ ]^@àûñÛ ÷WÈÿl¸WyðúìiáÁJS™3׆ŽC%ÀGòŒÇiøªÅ€‘S$‡ÍÀ|Ü‚'lPC¨z ¥_œcØhÄ€ãÝÁA½jÂ…<Oš OÅŸ’;ŸIîhìÝüøðãR"%Rº±n¬1 ÄàÝ«‹<>Æc<ŽlÙ<²yÕµªkU×jøÔð©áSãtÓ5N+Mü“8‰“ʵ•y*óTæIÎHÎHΔ·(oQÞ¢*¤*¤*„ð„'<¶a¶ ]@àûñÛïQÈBž¢ŒÊþ²—|Pn³²í•U\"¹B[ ‚oÌéìSU—šJæ‹&q‘Dp†) …ª@%RP ²ªé^3Ïøñ RxBZex«Y•¡|bêbùDU¯&ª^ÒGãIÑ9’étòþxl!P ÿÂÊY9+Ç Â ù ù ùŒƒåË–gÎ<œy¸ÙófÏ›=÷‰ò‰ò‰bíX;ÖD Ró䟬ò~ ×pMaĨó¡Î‡:é¹é¹é¹ZZZ./\^¸¼€;ÜáN]©+ueMYSÖTq¨Q{£öFíùD>‘O,++ShÔ(œj„- ð½ùM†;{Žl䃇\E°¼”¯Ê_~»rÐ[ÄRžñ; §¨ûKǪÜäÞrgÁAi ü³Ç<þ3ùXƒ|™«_QÂê—Un4.«¬(7½¢˜>°jI¨m ˜¥¶U²¤S ÉøÑÛðˆ)< ý›×O5ã›é3}¦O†‘adXÜÛ¸·qoÏ»w;ïFkÒš´æ°¦ÃškjàeàeàÅZ°¬^á^)Gîÿ‘n3l5[ÍV+\eŠ-,Zøâü‹ó/Îk¦h¦h¦ÔîX»c펊ñxåE'tB'űºáºáºá¼ïÅ{7)nRÜD¡QƒR”¢TX, ð½ùm#îw‘€t¨ByyŒÌEÖ ;¼Ø·l!d\/z“ÙñÃX¢V_©¥8NÜ–;D#”tua-¡êþ@^£ê P‡7n²E)d‹Ê2g·+ˬ4_íPi.’(ÉÅé-†ˆÓ¡Âl QýÉX²".+÷73ªÆ·Hp‡pˆ%GÉÑ}Oô=Ñ7îcÜǸ–ö–ö–ö#†Ž:b(¹L.“Ë4’FÒH´C;´û‡*ŽïÅ^ì¥SéT:•wãÝx·„â„â„bIII‡Z6µljÙÐTšJSy-^‹×bE¬ˆ)‚aé]Ô»¨w‘ïÆwã»,BòEu)§…wµ?üáÏ,™%³”¥ÈRd)ûîï¾ë0ס®CÝNºr;Õð‡iÓÃN 81€Œ"ãÉxö‘e³ìPKb``ìöû4#ÍH³444w:ïtÞé8¥9¥9¥YZZ>À<cŒ1F“hMҳѳѳá›ñÍøfÙ%Ù%Ù%BÇø=ùS„lb®H—˜ÊùãГ'3úÜ%SPÀâeÒT{ÆG¡º¾ ò/Fu.N!÷‹Éþy? žÐp 9„‘•gÃ'«×|®0å³geÏÊž¥,MX–* ð»ð-Fóñ‰Šd‘¤òˆl'K—™ÉWQw’íÐB>˜ÍÕÚ­%T·€€€ÀïD>Ô‘`-À?Δó‹ ÚT¼ˆ=Ž ì±ôàŽÙÒƒª›æg«n" *ÉEñ(‚=!Ç?d´ÝF0R.‡q‡Í،͸‹»¸Kš&¤ ¹AnÔ„šPº“î¤;ñPÙT6•Må‡ðCø!ò=ò=ò=Uë«ÖW­W|çAР!Iž]+ºZñZêµtïûðšá5Cneºdº,;sìÚ±kòù}ù}Ö dÉ6²l£ªT•ªcbLŒ±k°ÍÑÍ•ËaÿêpàÀñGù£üQd"™¯Þ¿zÿê}Qã¢ÆEíÚ5´k¨1\c¸Æp¨Bªâ“â“â“êÝÕ»«w—¯¯¯ÈÍÏÍÏÍW–V]__@@à»ñ TlÙv±X= (²2WTž" ”g‹[‘6ä9^ÂØh•F/Õ{è‚AŸCŠ|GxpàÄÈD!2ÑJ®…V娇rpn'Ã87ñ­9‘â[š?ÍÓü¡TcÍR}YÎ-UYìé9Ø#žï…øop%ŠkîS •P Ú  ÚðùüFŒÇxŒWjÃÿULX9ä³Ú¬6«­¸;¯Õ^«½V+s.s.s6jnÔܨ¹™­™­™mÞ¡¼Cy‡ôFëÖ-¾'¾'¾Wú©ôSé§*·*·*7eiÈ@†Ðí¾7ßÂpï‹„aäï*­šTìS)“7 Òq\%€Éˆ7¢•£&]øýPøªz `$°#?ÂNþ´D**o»ò¶²éõ—˦#GTÇð̼òX…ó mpÁb¨!šJI€}IË ƒ2ÈÐÑ‘¸wâ®4Ðß“÷ä=j jÈÉÉ1üë£ä8Žã¸"ɵæZs­%Û$Û$ÛÔÌÔÌÔÌjUÖª¬UiµÅj‹Õ–š|M¾&oÖÙ¬³Yg…k¶Þ"½Ez‹ôëê×Õ¯«m m m ÕJ«•V+^‹Ù1»"•œ»9w«’5}5}Ëu«zVõD{¾”/Í©KrH޹ÌTÏToå¦åÎËÓwdëgë§L~”üèõ„×^OMMM~³êͪ7«Ê[•·*o¥xQR5Q“3ä 9C^—×åu•â‰ùÈG>*Q‰Ê¯â•þÙ˜Žé˜®PæÉtÏtÏtÏÚ“µ'kOÝÙug×íbåbåbõ’{ɽäô·éoÓß&,,\¸»pwány±¼X^¬,'©H:€À÷æ[ÄkŒ]ì¤AãSziqùÄBßòý•ã ϪŒWK0³L÷h¨6@¡Â~W2ð¨ÀTà9;„ç°Ã Øá—‹;2Ä´ª6@,ð†5ÀåßbPÈQ9äx9*”ÿ›3µ@34C6>â#NáN1Åç'ÒÞ´.­KëyyyëÒ¤;HÛJÛJÛʨببØZÝZÝZÝü¸ùqóã©©©zçõÎëWUUUUU“\‘\‘\‘H ¤d™@&FFF}¬ñ±ÆÇï²Þe½Ëú0ûÃì³súåŽË—”úfÙ›ewOµ›j×ñ¸Ùy³óùã@U 2<*´+´ã‹ãìâìë»ø¸øØYÔ±¨cÑ|GóÍw ¼;ðîÀ»ïÄïÄïÄá5Ãk†×ŒéÓ?¦zZzZzZrçäÎÉ•–ùG|ÄçÕ\1ˆA yBž'ˆ@"˜:SgêØˆØøÕ,ÄK.r‘«pOâòùƒ± ± ± NæNæNæNnNnNnŠ™½Ûz·õn‹ʼnâÄ¢§EO‹žV-¬ZXµPùíXK€t¹gïÉ·qŸÀÎâÖÁò‚«eË*¼JZUr²–¨¤£ÈMHX{®[)ý$Î`?åèƒb!‹¬A@@@à÷¡L†é5œðrhÀŒÁ ïÐïPÁ^¢€: , A%^¡³8CLƒ·51­rfü›ò"!ФÔ[ê%õª=®öøÚãk§æ3s3s3sýûú÷õïß5¾k|׬žY=³z†é†é†é“ &LR±U±U±­ZPµ jA•Q•Q•QeóÊæ•ÍåëåëåëK6•l*Ù”u7ënÖÝÌK™—2/%E%E%E¥ÖN­ZûS§„O y§òNåÊm’Û$·IîéÜÓ¹§¡øžÝIjŸÔ>ЬÞõ~(m/{.{.•ˆœEÎY ³,²,’Ô£{D÷¨sË~‘ý"»‹uZ×iÝêx«ã­Ž[ß°¾a}£ŽfÍ:š.]]ººt•yɼd^)/R^¤¼ˆÿ*þÕ‹˜1/bÂËÂË¡%K¦XÞZý'ŽHˆ„Hèz†žacØ6†wå]yW…ÿfÊ'"‰4›fÓlžñŒgO|Ÿø>ñ´bЊA+jšÔ4©i‚"¡Hs„æÍ¢•¢•¢•E“‹&M–í•í•íU.NB’„N& ð½ùkÀ¯c |ÑñˆÅ32Œ¾}´nÔŸfç,/™Ìã/òswÏ8•ó¸qÉîøKûÈ:<Àzæ}tn€€€€À©öÿ¿ÌÆÆä<#›½@.§Y³ˆîÓ鹬DÖ¡òމOTU`wU¼dïù¾Rü‚SÉ›û·Ý>&îVr®äœ~=ãGÆ4BÔk©×Ò¨Ô¨Ô¨Ô¤1HcêYÕ³ªgåÝåÝåÝ 6l.ØœïžïžïžÛ(·Qn£¼íyÛó¶çôÎéÓ;£OFŸŒ>iUiUiUñgâÏÄŸùü1øcp¥}¥}¥}å”Ê)•Sä÷ä÷ä÷~ö[å 9Ün47šug]YWÞ‹Æûß«Eå½Ê{•÷&f&f&f´i7Òv&ÎÄ™X?·~nýÜjºÕt«ézWô®è])ºRt¥èÊÇóÏ<Ÿi•i•i]'ºNtÇÖ­['9%9%9} 臯!HgÒ™t&wÈr‡©15¦ÆÖ±ul.á.á*®âêïã1OдÏÇóñ6Á6Á6Á{›ìm²·‰b–`ôÊÑ+G¯lÖ0¬aØ<ù<ù?}~ºì¡ì¡ì!ŽàŽ`†`ˆÐ¡þÜè@*"KªK–*6\o=øiûÇŒ­Þ3ê8cË» Ÿö*|ÊžºŠ½¤vcØ©Hjô¯££åñš1ùÐXsÆ{>‡1Æbtc,º8©mRÛè—‘“"'E Œ6Œ6¼«zWõ®ê±€cÇÖ/\¿pý©S¦:ô[Üoq¿ÅR;¤vHm°­Á¶Ûôòôòôò~é¥CbH é}zŸÞ§é4¦S{jOíÉ 2ƒÌÀlÀhÊü´=Jre¢Í¢ÍÜ:Ñ$Ñ$î¥h³h3MâÖpkÈl2ŠŒâ48N‡Ì#óȼŸ;¯¡£¡£¡£w®w®wî¸äqÉã’wiíÒÚ¥õ@ýúõèìèìèì(Û(Û(Û(Å¢Xà´ÀiÓf­›µnÖº®Q]£ºFÕm]·uÝÖ?ûÅÌasŽã8Ž£†Ôb%Vb¥rou)ÌoéCú¥3«®¶®¶®ö:èðìijÏNtèÛ¡o‡¾ƒ6 Ú4hSÜǸqç{Í÷šï…]Ø…]p„#1ó1_è.ß›oáãž2”ðG.Þ@+?¨òƒ|0€uè‰"Ö’¹¨ßçÆh4RÑ–Ô*Ž(W©Žë˜h†µ8 Ü?bÄ29b †P­l”TUY«´Kþâ¢gÈV3VÝ]e+/•—©Frœêµº—ç\žw­åµ–)ƒÓåéòâµEóŠæß/¾_|¿8½8½8½2®2®2K«}LÆdL& $$þ¤?éÏŽ±cìÎâ,Î*¤Y bAxƒ7xƒ8Ä!Ž…³pκ²®¬+ P€eiñˆÿwz8|:?˜ ÕjÞ(³¾ú¾DÎäLÎp7p?âGüˆÁŒÁä9@(Ôo>†~ ý¤¤¤§8TýºúuõëÆîÆîÆîÛ4nÓ¸‡‡‡eWË®–] ¼ ¼ ¼F¶Ùbd‹Š'O*ž¤#éHpOpOp“ù&óMfp\p\p\J¿”~)ýJ‚J‚J‚ªûÍ“=dÙCÛÐ6´ ïÄ;ñN,˜³`…£ *PŠß26Ïœ˜s"õH=R/_;_;_;Å(Å(ŨõÜÖs[Ï­u¤Ö‘ZG¤ÑÒhi´¸™¸™¸YNlNlN¬B“,!KÈ…Ö»Ðiþ î2©$Ëv6è~¢ÅSƯr™ÉÇ,õ›5wvâ€ëÖцítá‘ Ù‰<<*O@@@àOÍ(,ÇERe¦úyµq9Œ1ö.ˆ1ÆÞ\`Œ±KÆkÒØ{ª÷Ôÿ\µ Ô‚+áJ¸®ׂkAÓÁt0q!.İ€…2ëŸ' âJRŠ MHÒ„ëËõåúÒ«ô*½ús‡j¶Öl­ÙÚóµçkÏ×þñþñþñ{oí½µ÷ÖýK÷/Ý¿w)îRÜ¥(×(×(ׇÁƒŸ3:gtÎÈ?Ð?Ð?ÐÓÙÓÙÓÙºƒuë?{m÷p÷ȲƒìPÎ3Ã1ûuuÈ=âqÊßeß$ß$ߤ¸»qwã¹úæê›ûl쳱ϛ1oƼ3`Á€(ôݹZ\-®La S¡»üeàz‘h2F‘^©âÞ¸+_é<ÒC~qÉÓ¡^yÃæŸt§á Z+L?‚‚´5éJt„zøSc ;Ø)’ô8וëÚîY_Q_‘·÷€žzvÐï·«ß®.Ò=ô406)5)%cÈ82Ž~àêruI "A¤=iOÚ+GÊ»¡Û—ÕMÝX›Õc©6B#4"jD¨‘{ä¹G̈1CmÔFퟪ§§ç\Û¹¶síÝvØ}Ó¨M£6º™x3ñfbøá?†ÿ“““ÿRòRòRriÆ¥—f¬Ñ[£·Fo¤öHí‘ÚŽ›7;n&ÉGò³ñȹ;ÜîmM[ÓÖð†7¼?ïø7 ªч´ å‘ì‘ì‘|ßó¾ç}Ï€µkÖž³8gqÎâEì‹Ø±ü:ùuòSùŠ{Ž:Š€À_í9G¶“fŠô4Ï–7]Z2¶üÕˆ²Kê )M\|sè3ŸwË­Û+ó3r… êM@@@àoÅß#ªèoAЀ>ô¡¯ÛDkÒš´&gÏÙsö?Í®Ði1Úc´Çhw¦w¦wæâ÷‹ß/~Ôó¨çQÏû¯ï¿¾ÿ:Á;Á;ÁûyÀó€ç·‡Ür{È‘¹Gæ™ëÇùq~\“½Mö6ÙkœjœjœJÚ6¤Mõò‰ ±!6T“jRMbM¬‰5ÎáÎÁ¾ðUŒš+³*\ƒÚ¡کŪŪż xðê᪇«®ºívÛí¶[ؾ°}aûZ¿ký®õ;ÅA\K®%×ò/ü& ð—BôÍJÚ‚ÐÏ>…9ã˼*<Ø8¶œ¥³qìîK¬¸w´½Nˆ Ü"ÛЮ€£Âmø“R]¦Ðpàz‰ìEöp„Žø€0‚‘¼†üŽüÄ,Œ…A:Ð" Ñ?âjŸuX‡u<Ïó<3˜ÁŒ4&Ic2šŒ&£™=³gö²f²f²fðTí£¶Lm™Ú²I ’$Õ)¯S^§ÜÙÕÙÕÙÕu¼ëx×ñN'N:të8Öq¬oß&¾MR}R}R}b.Ä\ˆ¹ðÌï™ß3¿q‚8Aüb׋]/v)…)‹P„"ôB/ôRÞÞ8Gã0 Ó07åMySbN̉y©c©c©cr~r~r~{5îÕ¸'k+k+k[Ѱ¢aEòü²ü2åe,€ÀÆ0º‹€À÷曽“·D¯XmV„ºjÙ{Y.¹ZÒ~«Y,›]dÅT2Uòd²ãµñS¶¿ ¹úB,jN»‘DzGüEÖH¸ ÿªÇ0±‡=ìÑÝÑ0È1rŒ#a$Œ„ñøGüW+ÁT¦ªLU™j¼Æxñ§áNÆ·Ü×r_Ë}6Ûl¶Ùl3V7V7V×sÖsÖs–;ÊåŽÅÅÅIW’®$]I(N(N(V,}»çíž·{Š¥ÅÒbéO/P%ŠEÉuäÚríqGÇw|pÒà´ÁiU%U¥U¥e†eeþ¹þ¹þ¹/ν8õâL'ÑIü&~¿I¸½ßÿò­ ê…`üÈΡ5Æ:ûš70, _7òªÏn™±¿ê;iÇo¬}ºyåà–Q±¢º–äÊšñ³™žp¾šßx…WxEËi9-'$Ê—É—É—ýô ¾}5ú6®Ù¸fãšuSë¦ÖMuÔsÔsÔ«Ý®v»ÚíL‡›7^Þ§¼OyŸRÓRÓRÓO]?uýÔ5âUÄ«ˆWá¥á¥á¥ésÓç¦Ï}«úVõ­*ŸÍgóÙŠ’G4k¶iÓ¦Ù›fW-®Z\µ8Ï'Ï'ÏgzâôwÓß%Ñ$Ó$S…_ÄñE øÞ|3WÖëpç 9èSïüx™ ß…¿CÇp´+ ¸pzHºÊ8QgÄŸÈ#ô îf S€¯"§:ÀŠh¦0 LŽt¤“xOâ±;°ƒqŒc\ñ™â3Ågnã_ O O OË0Ë0Ë0û*û*û*w{w{wû 2d½2zeôªß¢~‹ú-P4 h@QêÙÔ³©g_Oz=éõ¤·åoËß–‡œ  HÙ’²5ekîŒÜ•¹+õ§êÏÕŸ[¢VbZbZÈ 5 5—É&±IlVc5V 7P@à{óí–’ ‡jã žâ­d>÷íÝypTU¾ðï¹··4ÝÙY‚$‘€D ›‚"qMAFV– 0aMÁ0¢ŒŒ2ãÃ2 ‚;£€Š "È$ì„,„@ötßî{ïytû*<*Ö«÷ÒL1õýüuªëœî®ó­îúÕ©sΧl¸Ð}ú¸!£œpöµ…[&†¥Ùίy°Çé»Óßù¨õÞKj’ŽóFwy±ûp„aý¯•Žg"™J¶’­d »° »±ÝØnÜpI¥²DY¢,‰ðGø#üm'¶Øvbª'Õ“êI.L.L.L—8.q\\J\J\жN+×ʯô-è[зr­GÇõî–Ð-A}βŲÅÑŸëÏÕ£«VV­òíèÿ§ —/\÷ŠbüTfÈ †Ct;HGû_® ³.V‡)»sžºcÐÓÆ¹?¶O; åŸÛlëÐÏõŠÏ‹#¢«à^D&'ˆˆèÿ¨æ..¸àÉ"Y$+ó”yÊ<%R‰T"kê<ë<ë<›š”š”š”>+}Vú¬¥«–V-­ú2oWÞ®¼#çlÍÙzh£”R~¿CJ)¿Ÿ$¥”§>•RÊøe͵æZð+LÀDty­¸Vi&.ˆí_Ž;Ù¿§,|qNúDzò%môà½%ÛúµvÙ[ìÕ_ºxÙÿý¨"""úÿ«YÊk5ã1Ÿãs|.†ˆ!bˆÒCé¡ô¸y¨ó=§á4âËâ—Ç/Ú7mxÚðɾ9¾9²´-á@ï.ï®#ÉÚ%íR“Ôf}šõ |–!>Ÿpâ‰n½ŒÄàFO¬Åùm‡ÒÎyXò°@Oñ’ÈùœZ¢Ðÿ|ëJ4øðœØŒÑèxeeU‚w åªpË/õûŒ×£Ö8æÙ ×LÛqËÈ"Žã91S¤"E‚T‰ˆˆn :ô`»)š¢iðl Æ‹…b!º qe}®Íº6+½þàŒÁF&a 0Ô,Çò¢5yûò‚VÊJ¹UnåÔÝ>R‡XaÁ`´€ ðJï>è´VÊ…ÝÆLóÿ˜õÝ3ËŠßœûÛ‘gSîhô˜‰AÊ+bŒˆåäýºº[q/…J°“àÆFLÉŸ\vµê0 òÄoŒir„Üñ®íYëJg'ëu.î° hÌPÌ0ˆˆˆþÍlpÀ¼ðbÞÀjcËNËNœ†àQT´€v#_L 0cnED·ì°)ÇÄ(†vm3£ÙHi,Ú–SyÿÜgG ’rQlFD·ˆ¦+ãšú¨ãÄ^ñ$'ˆˆˆˆè×)uöN•Ðàk1V ¼P”_ùjµ2äâ¹ÇqÅ5<9+¬¥½kpÔûøဵ×þ‰ˆˆˆˆþã(uü~â§_6½xû-Í©ˆÒß6f©ñb°8Ž&ÌMþ5Õ= d…#ç#N8Qmê¸p—Kp—íÊçüw¹µÙúqË;ʘ[¤/¶{½aáPadO,Á»pÃ;à """"ªM]¯¸/F¶<hV6ôÕÕ’ñÚ`ÿk–Êeñ ürŠü®Ñ'î¢zMa@‡”1X‰½ˆ€6†ADDDDT›º^qÇq1Ðö|£0NVN×Vú7‹¡â]‘«9I^i¼Â=#l¦!%x¥ˆbáNDDDDôkêzÅý¹G` µr§6ů–Ä{*´T(±Êßð•<$›Gg…½j«PWžTH¸`çáT""""¢ÚÕõŠûß±G¡Ã€QõßrÿÏeyÞ·|#áVоºR£IDATÄ|Ó.sdëØëŽ—l;Ôj‘*¾‡ ÀÍ[eˆˆˆˆˆ~M]¯¸ÏÅÇØ«¼-â°ÅÔ ñÁµuUÃ<ýõwJ¡ùžÔÐ7b=J]®tgÄ‚à¨0Xêü›ý©ërùu|‰ƒêñ†2`AI ª“¼V@¹®¼ež’—dŠû1k–å嘖ΠŽMÁQ™èŠö ƒˆˆˆˆ¨6u]¸{à‡û¡ÁŽ+0¡”oöu1² ›äÝè Ïáõ¨R(6ÞñûÈzá‰A⤣?à """"ªM]îd¾?B„Y:ÁwXo‹ù–¹Pì­áT‹•õÊã±e®ÇÙਙ¢;:0 """"¢ÚÔuá.@ÎÀ×8x¡l¬ö¿ 32ä½x­Pß2S…»Ug| xýÄC ƒˆˆˆˆ¨6¡9:BnÿÍëí<Ó|Vÿׯ9ã(ÇdôCž2@äÅ|öOûª`ÿ©èŒd†ADDDDT›îò ¼‰]vñšêEÞ,ï ýnóaqF¼ŒtxÅzÑ"®“Ë6#ÐG¬@oN%""""ª]h ÷pù‚\…0X D—_¯*ðLñï×s•ÍB'á^±:F:lÖ>%Z T(=òDDDDDt£Ðî=°ÀFѦʽս/ø?Ðçˆ9"GìÄE¼>Ä–©ÚÐqˆ[0]`À ì‘'""""¢…f{W¼†õâ^¬Æôò$ÏZ†ö >Zo¡¢ƒ°²'úƒ}·u)¾G>ŠÍ£r«,ÀhtB;FBDDDDt3KHÞõ p'1Ëæòwrqi­JwÂDþÃt›Ñ®G{K»ÃúOk¦ö?‘€©xUðƒ!""""ª)4+îÝêgPŒ24CCÔ/ômÖ»B½D'XÍ\óñÈÙa=íúÜÍë­‡ VXÅeñ"Æ1""""¢›…¦pìV·ÃçqW¯žõ|á[ ;ÚËR9OžrEÚgXK#ÓÂ>·½?üðc†‹ÞŒ„ˆˆˆˆèfÊ­ù˜’aÞÏüã´A¢yX^”]C-ÙêCîÓöW­“GRÅËè6Œ„ˆˆˆˆèf·¨p/V‘æQÜæ0s—lTo­-Ó’‘eŸ`íì´N<ŽŒ„ˆˆˆˆèf·¨p¿tWiZÅWš¢¡Ù-ñõiu©2Ö5ÛjWGúˆ©h‡DÞäNDDDDt³[T¸5¯hQý!~ñˆ4Þr"®X¢ÕÙn¯õšz:Øéô@+ÞäNDDDDt³[µâþAi“ò;Ñ"IÆÊO‘ÂáámìÕÖ(8P.¬ÀÇØ‰X¸àd0DDDDD5…²p¿ F Yõ¦ö•¿yŸ1P.S{Š(±Â7×5™u<ü;xQ…J£¿™.wâI´C2ƒ!""""ª)”…ûa£2Ðôõ4‹ä¹’žšK?¦nSV `n2ïmØÊãìŒãb–øLÀhl@w4G<ƒ!""""ª)”…û>äãZ éU æ W³=ojó,‰ÊYñ[hæ}rMÔ¢0«½¡µ™:\-ÁÏPaA[4F,ƒ!""""ª)”…û¸‚2Ø¡@øÓŒ³QéóÞ.þí¼'î„Ý„¹‚W+iò39M–D,¶w·æÛžR7)?÷Ã߃úg0DDDDD5…rÅý ~F!2QÒ?ÎøÊp¯©íY‡¢ˆ¿êÝÍAòHt™ã'ëd[ž«Üu ’ÁÕÊÂ}Žãœò 6 Sž«/G•ý¾ò%@Ý£¶4¶ÊùR·Ø¾° Routino : Algorithm

Routino : Algorithm

Algorithms

This page describes the development of the algorithm that is used in Routino for finding routes.

Simplest Algorithm

The algorithm to find a route is fundamentally simple: Start at the beginning, follow all possible routes and keep going until you reach the end.

While this method does work, it isn't fast. To be able to find a route quickly needs a different algorithm, one that can find the correct answer without wasting time on routes that lead nowhere.

Improved Algorithm

The simplest way to do this is to follow all possible segments from the starting node to the next nearest node (an intermediate node in the complete journey). For each node that is reached store the shortest route from the starting node and the length of that route. The list of intermediate nodes needs to be maintained in order of shortest overall route on the assumption that there is a straight line route from here to the end node.
At each point the intermediate node that has the shortest potential overall journey time is processed before any other node. From the first node in the list follow all possible segments and place the newly discovered nodes into the same list ordered in the same way. This will tend to constrain the list of nodes examined to be the ones that are between the start and end nodes. If at any point you reach a node that has already been reached by a longer route then you can discard that route since the newly discovered route is shorter. Conversely if the previously discovered route is shorter then discard the new route.
At some point the end node will be reached and then any routes with potential lengths longer than this actual route can be immediately discarded. The few remaining potential routes must be continued until they are found to be shorter or have no possibility of being shorter. The shortest possible route is then found.

At all times when looking at a node only those segments that are possible by the chosen means of transport are followed. This allows the type of transport to be handled easily. When finding the quickest route the same rules apply except that the criterion for sorting is the shortest potential route (assuming that from each node to the end is the fastest possible type of highway).

This method also works, but again it isn't very fast. The problem is that the complexity is proportional to the number of nodes or segments in all routes examined between the start and end nodes. Maintaining the list of intermediate nodes in order is the most complex part.

Final Algorithm

The final algorithm that is implemented in the router is basically the one above but with an important difference. Instead of finding a long route among a data set of 8,000,000 nodes (number of highway nodes in UK at beginning of 2010) it finds one long route in a data set of 1,000,000 nodes and a few hundred very short routes in the full data set. Since the time taken to find a route is proportional to the number of nodes that need to be considered the main route takes 1/10th of the time and the very short routes take almost no time at all.

The solution to making the algorithm fast is therefore to discard most of the nodes and only keep the interesting ones. In this case a node is deemed to be interesting if it is the junction of three or more segments or the junction of two segments with different properties or has a routing restriction different from the connecting segments. In the algorithm and following description these are classed as super-nodes. Starting at each super-node a super-segment is generated that finishes on another super-node and contains the shortest path along segments with identical properties (and these properties are inherited by the super-segment). The point of choosing the shortest route is that since all segments considered have identical properties they will be treated identically when properties are taken into account. This decision making process can be repeated until the only the most important and interesting nodes remain.

Original data
Original Highways

Iteration 1
First Iteration

Iteration 2
Second Iteration

Iteration 3
Third Iteration

Iteration 4
Fourth Iteration

To find a route between a start and finish point now comprises the following steps (assuming a shortest route is required):

  1. Find all shortest routes from the start point along normal segments and stopping when super-nodes are reached.
  2. Find all shortest routes from the end point backwards along normal segments and stopping when super-nodes are reached.
  3. Find the shortest route along super-segments from the set of super-nodes in step 1 to the set of super-nodes in step 2 (taking into account the lengths found in steps 1 and 2 between the start/finish super-nodes and the ultimate start/finish point).
  4. For each super-segment in step 3 find the shortest route between the two end-point super-nodes.
This multi-step process is considerably quicker than using all nodes but gives a result that still contains the full list of nodes that are visited. There are some special cases though, for example very short routes that do not pass through any super-nodes, or routes that start or finish on a super-node. In these cases one or more of the steps listed can be removed or simplified.

When the first route reaches the final node the length of that route is retained as a benchmark. Any shorter complete route that is calculated later would replace this benchmark. As routes are tested any partial routes that are longer than the benchmark can be immediately discarded. Other partial routes have the length of a perfect straight highway to the final node added to them and if the total exceeds the benchmark they can also be discarded. Very quickly the number of possible routes is reduced until the absolute shortest is found.

For routes that do not start or finish on a node in the original data set a fake node is added to an existing segment. This requires special handling in the algorithm but it gives mode flexibility for the start, finish and intermediate points in a route.

Algorithm Evolution

In Routino versions 1.0 to 1.4 the algorithm used to select a super-node was the same as above except that node properties were not included. Routino versions 1.4.1 to 1.5.1 used a slightly different algorithm which only chose nodes that were junctions between segments with different properties (or has a routing restriction that is different from connecting segments in versions 1.5 and 1.5.1). The addition of turn restrictions (described in more detail below) requires the original algorithm since the super-segments more accurately reflect the underlying topology.

Algorithm Implementation

The algorithm that is used for finding the route between the super-nodes using super-segments is the A* algorithm (or a slight variation of it). This was not a deliberate design decision, but evolved into it during development. This algorithm relies on calculating the lowest score (shortest distance or quickest time) to each node from the starting node. The remaining score for the path to the destination node is estimated (based on a straight line using the fastest type of highway) and added to the current score and the result recorded. At each step the unvisited node that has the lowest current score is examined and all nodes connected to it have their scores calculated. When the destination node has been reached all remaining unvisited nodes with scores higher than the destination node's score can be discarded and the few remaining nodes examined.

The algorithm used to find the route between super-nodes using normal segments is Dijkstra's algorithm (although it is implemented as the same algorithm as above but with no estimated cost). Since these routes tend to be short and the CPU time for calculating the heuristic cost function is relatively large this tends to give a quicker solution.

Routing Preferences

One of the important features of Routino is the ability to select a route that is optimum for a set of criteria such as preferences for each type of highway, speed limits and other restrictions and highway properties.

All of these features are handled by assigning a score to each segment while calculating the route and trying to minimise the score rather than simply minimising the length.

Segment length
When calculating the shortest route the length of the segment is the starting point for the score.
Speed preference
When calculating the quickest route the time taken calculated from the length of the segment and the lower of the highway's own speed limit and the user's speed preference for the type of highway is the starting point for the score.
One-way restriction
If a highway has the one-way property in the opposite direction to the desired travel and the user's preference is to obey one-way restrictions then the segment is ignored.
Weight, height, width & length limits
If a highway has one of these limits and its value is less than the user's specified requirement then the segment is ignored.
Highway preference
The highway preference specified by the user is a percentage, these are scaled so that the most preferred highway type has a weighted preference of 1.0 (0% always has a weighted preference of 0.0). The calculated score for a segment is divided by this weighted preference.
Highway properties
The other highway properties are specified by the user as a percentage and each highway either has that property or not. The user's property preference is scaled into the range 0.0 (for 0%) to 1.0 (for 100%) to give a weighted preference, a second "non-property" weighted preference is calculated in the same way after subtracting the user's preference from 100%. If a segment has a particular property then the calculated score is divided by the weighted preference for that property, if not then it is divided by the non-property weighted preference. A non-linear transformation is applied so that changing property preferences close to 50% do not cause large variations in routes.

Data Pruning

From version 2.2 there are options to "prune" nodes and segments from the input data which means to remove nodes and/or segments without significantly changing the routing results.

The pruning options must meet a number of conditions to be useful:

  • The topology relevant to routing must remain unchanged. The instructions that are produced from the reduced set of nodes and segments must be sufficiently accurate for anybody trying to follow them on the ground.
  • Any restrictions belonging to nodes or segments that stop certain types of traffic from following a particular highway must be preserved.
  • The total length must be calculated using the original data and not the simplified data which by its nature will typically be shorter.
  • The location of the remaining nodes and segments must be a good representation of the original nodes and segments. Since the calculated route may be displayed on a map the remaining nodes and segments must clearly indicate the route to take.

The prune options all have user-controllable parameters which allow the geographical accuracy to be controlled. This means that although the topology is the same the geographical accuracy can be sacrificed slightly to minimise the number of nodes and segments.

The pruning options that are available are:

  • Removing the access permissions for a transport type from segments if it is not possible to route that transport type from those segments to a significant number of other places. The limit on the pruning is set by the total length of the isolated group of segments. This significantly increases the chance that a route will be found by not putting waypoints in inaccessible places.
  • Removing short segments, the limit is set by the length of the segment. This removes a number of redundant segments (and associated nodes) but rules are applied to ensure that removing the segments does not alter junction topology or remove node access permissions or changes in way properties.
  • Removing nodes from almost straight highways, the limit is set by the distance between the remaining segments and the original nodes. This removes a large number of redundant nodes (and therefore segments) but again care is taken not to remove node access permissions or changes in way properties.

Turn Restrictions

The addition of turn restrictions in version 2.0 adds a set of further complications because it introduces a set of constraints that are far more complex than one-way streets.

A turn restriction in the simplest case is a combination of a segment, node and segment such that routes are not allowed to go from the first segment to the second one through the specified node. Exceptions for certain types of traffic can also be specified. Currently only this simplest type of turn restriction is handled by the algorithm.

The first complication of turn restrictions is that the algorithm above requires that super-segments are composed of segments with identical properties. A turn restriction is not the same in both directions so a super-segment cannot include any route through that turn restriction. The node at the centre of the turn restriction must therefore be a super-node to avoid this. In addition to this all nodes connected to the turn restriction node by a single segment must also be super-nodes to avoid any long-distance super-segments starting at the restricted node.

The second complication of a turn restriction is that the optimum route may require passing through the same node more than once. This can happen where the route needs to work around a turn restriction by driving past it, turning round (on a roundabout perhaps) and coming back along the same highway. Without turn restrictions a route could be defined purely by the set of nodes that were passed; no node would exist more than once along a route between two points. With turn restrictions the route is defined by a node and the segment used to get there; no route between two points will ever need to follow the same segment in the same direction more than once. This means that the optimisation algorithm calculates scores for directed segments (indexed by segment and end node) rather than for nodes.

A side-effect of this is that a route that works around a turn restriction must be calculable using the super-segments that are stored in the database. This puts a limit on the amount of database optimisation that can be performed because if too many super-segments are removed the optimum work-around may also be removed. The solution to this is to ensure that the database preserves all loops that can be used to turn around and reverse direction, previously super-segments that started and finished on the same super-node were disallowed.

Another side-effect of having the route composed of a set of locations (nodes) as well as the direction of travel (segments used to reach them) is that via points in the route can be forced to continue in the original direction. If the chosen method of transport obeys turn restrictions then it will not reverse direction at a via point but will find an optimum route continuing in the same direction. The only exception to this is when the route ahead at a waypoint is into a dead-end and an immediate U-turn is allowed.

A side-effect of having the starting direction at a via point defined by the previous part of the route is that overall non-optimal routes may be found even though each section between via points is optimal. For a route with a start, middle and end point defined it can be the case that the shortest route from the start to the middle arrives in the opposite direction to that required for the optimal route from the middle to the end. The calculation of the route in separate sections therefore may give a non-optimum result even though each section is itself optimum based on the start conditions.

Overall the presence of turn restrictions in the database makes the routing slower even for regions of the map that have no turn restrictions.

Data Implementation

The hardest part of implementing this router is the data organisation. The arrangement of the data to minimise the number of operations required to follow a route from one node to another is much harder than designing the algorithm itself.

The final implementation uses a separate table for nodes, segments and ways. Each table individually is implemented as a C-language data structure that is written to disk by a program which parses the OpenStreetMap XML data file. In the router these data structures are memory mapped so that the operating system handles the problems of loading the needed data blocks from disk.

Each node contains a latitude and longitude and they are sorted geographically so that converting a latitude and longitude coordinate to a node is fast as well as looking up the coordinate of a node. The node also contains the location in the array of segments for the first segment that uses that node.
Each segment contains the location of the two nodes as well as the way that the segment came from. The location of the next segment that uses one of the two nodes is also stored; the next segment for the other node is the following one in the array. The length of the segment is also pre-computed and stored.
Each way has a name, a highway type, a list of allowed types of traffic, a speed limit, any weight, height, width or length restrictions and the highway properties.

The super-nodes are mixed in with the nodes and the super-segments are mixed in with the segments. For the nodes they are the same as the normal nodes, so just a flag is needed to indicate that they are super. The super-segments are in addition to the normal segments so they increase the database size (by about 10%) and are also marked with a flag. Some segments are therefore flagged as both normal segments and super-segments if they both have the same end nodes.

The relations are stored separately from the nodes, segments and ways. For the turn restriction relations the initial and final segments are stored along with the restricted node itself. Each node that has a turn restriction is marked in the main node storage with a flag to indicate this information.

routino-3.0/doc/html/example2.png 644 233 144 272260 11541143722 12230 0‰PNG  IHDRôA^#X oFFs6È *8 pHYs  ÒÝ~ü vpAgŽÌdKž€IDATxÚìÝu|Ëú?ðÏÌn¤nT N)еh§¸·´Š»sÐâîîîîRÜJ[ÚRÜÝ)ÖRI²;¿?6çÜð»÷~¯Aæ×ëÞ=“Élú$žLF8Žã8Žã~6ƒ†¬À\Ѹ‹sļN •½OöX^AU,¦dw×,»xäæйêºÊÙ@rÃ%6¢éôúOÇrŠŒ^}Â'5dשÔÙuòBuUÉœÁ˜ÃÕÙiDa*ú`ŽCŒžû_Žã8Žã~R®°%|@…cø8_´žmYºë²JMJt[]qd1wgÉ*[«akôµ¥‘y‡¥ÑÒtÍÿ-ÐÃd)#×a#YªR¥ £“Õ™~‹ªÕ/s1ÆË·i!g?ËcÚ=†Ê9òjåüì´–™uV;nëÇJOM|2óí»±3NŽJÛpÖñA…çÀ(á=%d”\H^Ê$¦FÌÂ'ä : ñžû÷ñÄã8Žã¸Ÿ"ä@Ù†Lœ%WHQdËãÙ+ÔV*VxçÞÎeI•Ú–(Ö¶Céí^ajGÑ“\È•óžè%úŠœ'ÝÔnªb¬!JzÎâ7&]ïùøö|«„=7î%%>Á+ñ„wp àFj"„ågy¨€OøŒ,   Cæ/ ÷Ïß°ÇqÇq †:ðAQò #ABÈf2VÏv1I©X½~¡ ùí†EÖ òÝ_ç‘W}çídˆðšÉ«š·JוÜ@:«?˜_Ö†˜µ5×núñ‡±³‹\˜qÍõA¹wƒ?–RÚN‘g¤§t eOÐë±* ÐCâé;÷ðÄã8Žã8îQzâsa€D›’ÆÄ 9l +‚3úÁëq/|K©Ú… q­öÉǯJ÷ÖŽ¯y–œ—]Eªo )Z Ç©¿j„ùaeö/ºZ3µcoì_Û;%ôn¿'~ÞªœŠZ¤É·XO,@AŒÃr2˜1SãÃi8h6ºÄü‚*¢¦‘#¹–9çt¡´%y‰Þê•_uœaaŸ4qí•«•»Ìßpñðµ+©ožG¿-£´C1Ç„³-8Çn!Sq¯ðŽoóô£â‰;ÇqÇqÜïÍ4u®Šbð¢>¤8y®±ê¬;ÁبT¬s¢„Gxß{Uúû”ª[x¨Ë €ä¸\ÿ¼Ó†êA+¨·h©úÖ—Á¹yú›ü®æ=²šuñúõ&×t/˼Szôs"ö‘-ä¹ YI¥Ç¬®|YN‚  Þàžñ—å{ÇwŽã8Žã¸?’’m)k´k @ +ðñ¨‚D`Œ©jG±—X yZ™ÊE> œ\e·K¹¹nÏíï²­Ÿ]6ï†ÞCë%LêÓ]š¦êÇï+g-˹¿lê¹ñi>óËœóºöᙽtãÿ;ïTT…7ãéçÒÏÅ«Mi×Ò;”ÖDaP¼#ö¸i<1ù_Žã8Žã8Žãþ)Ó¤™‚‚b-Ú¡6y†³¦]öZïµ |®ü¸wû‡;DlblÒØØŒݶxòçìó_Ê'æ2ÆØ‡Œ1–Q„1Æfæžvü¿H À¥5q9I2pcÑÝxs¨¡â/È÷B@9¸Ã¯ð YÆÕI9Žã8Žã¸?‡2på0ná1¦aV`&Ú žø‰ dÄçi¹³u³ÎÞ~¸òåÉ-–×=6ˆ–âsÑÇ+Њj'èÆU~ôE_W3L[)»TnRnӗåOù”ðènì:‹›9µ˜•……•ôôÖ§G_اàœ=yݱ'‘DŽà>Ö’û¨‚²qéø€/È1ŽÎçƒi8Žã8Žã8îŸ2íB ‚ŠÅœ!/ð[L+.ìTuÍSf–Óï¬7cŒ¥?aŒ±Ä Œ1öäÊA—õù|¡‰±iùºž¿µ­_Çû­­Ù§œ«]ºE Y3ÓÖ„Ãä&iEöÀDc‘*ˆ¼;÷›{ƒ˜µR­wçlÑG£¼‰xˆç<4ÇqÇq%i@Ai8¹DÜŠ/ÈsÝ“o´ÕüSmç—hšO¥¯=rX»œ!Sj>kûìH†•ꚸ@[¬*»:ü¸“ØïÔÑ«¾l7«gÙÆb­8‰>„‚÷ƒÅ£?[T4¹ýÝ3kÍR:Þ¦oªfÞÍV(EŽ’VR6ÝÆ.\Ç#·xâ[ÿÚ7…»‹}AëŒ'¯Þ?ýì€èŠ–hŠÅØÊCÃqÇq÷—QA„= © Y€ò+Ö¶cúÅtªVmôÌnú*] [3d–z­Í¸•s»ÒØÉç8­ÎkßõXQ½eéÄv%Ê–*VÐÌFMéV=Ë+©/!Õ”S™¿v™j…0ÅÅêB•«Þïβšw>¡þÍ{›Æ¦÷yÿ:ÿgm–qL<µÀ{¬aIaTbNìJŸ›ò»Oáÿ|e—˜ïÜÕø*¸`&ñ˜pÇqÇ} H#"` Ö ;Ü<Úº$Ø–üòìèÝÞΆ§ÇôÊc,9jÈDZ±?U„›>¶LSׇ‡ó'6.QýTVȨ6í706qfGÜ9®|ÔÂ/ G‹xÉØØÙѳ›Ü!6éNÅ~«ZÄý’œ[þ“ÕGíx‹ikâ|Ú•ÜA&æc¸±È *ˆü5ú3 Þ—FùÞÈØÿ)‘ôÇtôÇiÌùuSŽã8Žã8îO¥Lµ‚lè>ZšV“íÁÅ#ú¥†Ì)Pú¸K6Iež˜÷|áËÙAÇN‹‰ÿR-7I' i9Ò›ÜfûQüÕé¬A9áßz÷dõœ{M_Ú }T$Ëá˜ÍN떃͞Ìu¥ eò2t/ôÕœ·[¾5Û¢*¼Áu@½ï†Â ÑFXÿ¸ñÇÙ>Åæ6Ëû“pgÉ1<ÀòÁðÁ)¤"YÈæ[ÿpM³|ת“ÄxL8Žã8ŽãþZÂBO¶Á6p¨âï³9ÿ«ÏíŽî3BwæDûÞ5K8È«ããÇ}”úä#‚ÇÆÇ¡é@‰„aÚ›¶ì—VÐֹʬ· «V—ydÔÌ(ÊØ„ãKË%âÚEÝËŽ¹4ÒI~·%ÚŽ±ÉQ±ouì§nÑu˜]P„_SÇ!V£-&~õ<Ï‘;¤-¹H4¸f,2ã[ÿ0·ù·òQ¦€Ö$aDà1á8Žã8Žû PPŒAGÔ¤½HÞà VNêS;±äzƒOI'ÎíëµòšqÑÇ,íÍŽ«·“¾Ä;‰ ncÌ ùm]v-DˆÐB„@bq…^d/©dzÂ"!ù¶Ø¶™c¾µÚŒ·ÑòÛclÒ—ØÌ-®sÔá¬#ÞG`lÜ“›xªSß§“×hã0¨dÍåV8›YÕ4ßmÚšPˆì'Í1 QÅà Æ•rø‚ã¿þY¾~Œï–…¤?)ÄcÂqÇq÷W!‡HCœWŽýGúø¨!Ï9£ë?TwâØ³žë¹Td°G›ô0goc .jr͸‘ÓßSAø­éÎÇ!qÇqÇýI@æ‘*8O?RRß>ÓÆ×<_b©¥5Û]aNç?ôOfìB‘þOw›0®ñ(ãƒÌ6Žh7ƒæ\–Q4f?xÓb¤^’qØ…_L+­íd_z\ýZÛ*ÕxytX§v‡›Ð¿cU–0Ö;zpöæ‘Ó"ÕÒÎ8»¨¹ŒM^»öÞ‹óZ ‘Ò½‚g¾–{Íט¶&Ì#GH ¹NlpÏX¤6&ð<ýǶ\níìKXÁZxDUd ÇqÇqÜNIMµPC¤g©3©¬·éšê]Ÿ±ËdÈû<çcszÈ«u¦XÛŠµJz¸^Äq,A7z‡– ¡0‡ö×6¿3ed¼(ž`z ãI iiZÅÅÌ:ÐbÅØjµr+韼»M(c“-c;26öPô®¬=#ÎDLdl\å6ŒMªÒ)ýñøA­'þr8¤P…Ž®­/[H¦­ CÉÒ/0±¨ŠBÈÏSøà`HDv˜qŒ‘p™<%Q°´<2ÇqÇq K˜A…Éè0Š\Ì0»¨µQ%?\°euliôÉ›½%Æú´vÍëzŸHO6ÐÕT$U±CÑ䆦=ñ0‡9$-‰ ù‚Œ7­Xàƒ½™õ“‰¶u VžxÿèÀ‘­½›4ªS’´'®dÔ±œ2#÷E:ÉâvDflâ½Nû lsjèŠÀôrOógÛµ³ÞcÚ)‡¾ð§óI7’%QnÆ;èOŸÆŸjÝ1°^]¢!÷¨v 6Êb-bþ„·ÇqÇqÜÏI0YÎh=ÒQ9q6jC•Œ]¼=0R.sºw߀ŒÝ6tU`¯ÓëÅhO€Èd¾üÏÙtbk}”FLCÚŸ4&_%ÓªÙ¦X­è[¾zYßMOŸNk³“±‰ ª36öEôǬG#îG¬awâžD«›¼­3îظUûyÏu¬à‡ª6G¾ U*¹Oš‘A¸½Æ"óŸxøDÏ®wÃÓÍ÷jR5•R;1‹_SÇqÇqZ›œ#î¤+$ wÚg××bÄ}ÿ-;E6Ûoc{ 8:?®_µÐqJ}ò– ÃSãƒ5Pá¯Þ{G ñ×ç@ã#N ‘d )jZÅ9Úz¸Åãñk÷©¬}70¯µcSævŽ¯Ç Žº›]id‹ˆûŒÕGë›×qÊÇ #>D~˜ZD•ÈRÓ].8¼2mÌÀ9Ì [ðÛ”5ÞñóLl½V w\³N.16C­BaÙ=’ùåÄqÇq÷‡h‚@øÐ.$JÁ”^ÝTã»|zÈcýòã {E¿+x Kæ”clñ˜”Å L&ƒ‰vÂfßÔBЦÃi‚P…H*H>a›iE/8¤Ù:}TÈ/àAÝwZÇ16!¥ã(ÆÆî‰~ž½gä”HªŸ3¦`{™±Éõ;éÞ:þÑoÎÙ†—ªî/ZØIcÿÕ’åtqÄ:˜t$ŒEÊfO?öpšûæF¶jPø¾ãsûpc Š“š„òkŠã8Žã8îwf s¨ÉR;ñÇзÐÑüÅìÚtxt/ϼGñz¾a,ÅgèàAëÚl«4™Œ"ÕñYô<Èe…;¿ƒ¿Qe D@p ¿ FÍGæ™V±ïiþTûv`f`˜_ÀÝôþã[elRJlUÆÆnÞUÄÞˆ5,0nVÔ%Æ&ÝŠuÈ(ûˑ͜¬ðÌêÕŠôÉ·Ãv¾ikBortÃ,ôG0Š¢ào[4Ïoµm{÷EþÛNÆ}­è*2’øñ+‹ã8Žã8îwc²h#C^ÿ:¤d}Å‘eëoaì¢ý€yÒÞ³MûÕ|X`ËÔN Îs^`Ó‚$p¬§ s¾»ôïRgZžÔ€Žî&pÅ´¢ÃXËækF^ yY!ö‰Ïà¥mâ›ì«–óâE7Éñ¹7²€aò˜5Q›Ø­ãœWF’öMgt©?(àc)æzØÑù«ó~@=xÐÇd©„þ¨‹jÆrñŸì,û}yßhÄ´ÈŒ*Q^;Ü>ãì@Ž’H~}qÇqÇý¾èjjMê)Ç{«ò7Ï6oÛ{s>U«O,cä$jFÝe럤®$ô×·}È›Ö T„'òã¡-mA‚¿ÞìÉÝ×nŒ•¡Ë#ÿ±>N÷GXتc5O26¾r‡·_>Œ¬ñÆ3¦Nû/ŒM)ûüõÅaãÚ…/hظ`õ …ÂîÛ–þ*Ú½‘‡ÕäØoƒÀ- †ø÷ÅgW=7tE±-î”aù@âø¥ÅqÇq÷;PRÖóX®ÂzL5›­¹©ŠÚuh‚c£gŒ]º>¨µ´ñLXß1IK5í Ô’ì'Qä iƒT†LGSïø¾&¶JCǽìh> T°×rãóNÝÉZ~•qÇqÇý4PCŠÐX҃ѾÕV—É(X^¦õƒöç­:z§‡ÄØ%ÿAÇêÉR‘îʃè jCŠØü¨“-M“æÒp‡+yB´H¦N„à€iEÇJV³-&õÍ®îå[ånÕ[ÍblBߎ…çÛ¡Q¶4ry¤J7`ô’öë›”ÕiÛç£lÛ\Öòzp—2j··Ž[M[#]1ôYGêÂö°3Þ¡ŒÎÿ–16É/¶Në¾³ŠLTJÄ´>9ů2Žã8Žã¸ÿ‰²h£\a‡“˜ƒV€‚§\æz¶zÍœ=Ù/Œ±„ß3{V«6ê/ª·â A¬°øã 6ütSF¢+ƒ‚F£…£TK¾šŠj3ÊÌBÓ ÇÔªåË̾¹¨ïªæO›ô1v8cãƒ;œÏJñ0â¨4b̪¨ÒŒMšÞéüçK#»D^]ëÚònð¤2)nõòí0m®%AxIª`;&¢ŠÁý›žØÊîM¹Óùq‡ òžÅv#¶ö"×ùµÆqÇq÷_¢ëK¦+©ŠÔTŽ[U éï]ˆ±óøIOÎîc™=çø‰>-jx—ឦÔ¬i{òë0Ÿs§P%q6é'ñ`H¦IM<6­hsÉ|¤öMß.Õ6—ɽò wP³+ŒMJêô™±±=¢·åÔy'²º~÷˜rQ¶ŒMØ×±XÆtŒ^²Ìµih•·yú»~•Äc ŠC%ØÍ¤6F¢ÑoÃi¾‰­ŒMëÝ­uÅ÷%ò+%*'º‚dò+Žã8Žã8îA:W H$˜õÑìQu¹üpù‹ÈÞòº Í„0v~ÿïM k–g¬¿“ÔÂãƒÕÛÞèçâoÓZ_€3Ρ;šPORL+æ °loû¢òR ní7¢E6c<:–`lü¹˜ÚÙÅGFEdënžÕ~4c“cc+}¼0rfûÂëÔ­|ƒywiç0PIiÅŒ¦N¤ÒoÓg¿…uâ›–ÕåÔ½5,ʬPž§èHô¤;¼¶üÝÂqÇq÷s†l„öté­t;Ð$¹CŒ%m|QwôØÍžûó’OµìUÖ¹ènçÄЕ&‘`ºp$÷˜Nl-Œ˜..¢Ñ$á«*QêÕÌ>­«=ó]™v¦Wᦛ¼%öccÏEýòzdëH•ÔcLRT{Æ&ôìh–{xÌ/Ñþ+×5¿˜Y¹ûq—¦­‘lÅ0ª%ÖH´E]ãúÄVÂØT‡Î“õÇÓúsHåWì*–c/’!Cãáü§”~x*¨ÈX\ÅF D&À M”Šv3,zš±×}˜út (\j‘w%Goë“€œ!×Ïí§«`XHËÑhR^Ý^+¨ä$ç½3TßqñƦ'y ;$¹ÜÖ]´zèú|¯ñ´eP6TMÆÖÒÆ6ã3>á“qb«ä?ð¯flòœXÕ¢ÌÆw«ëŒEáŒB=Tçï Žã8Žã¸‹Iÿ+µ'sñV95¼CŸªW»$ |!…ŸZÜgzFòÁ·=–¹]ä¸ó lAòÓ.äÂß!þÊxôPø ¸0“|"L«XuÐ`ô€ü-o–Ÿîd—¿u©cf|.ù4âmã/)S„Ç.mÆlD7ÃEé‹FwÜ… _=çÿD<“ ’’ijîpFˆT90[ìFêÒÁä–gÈk–—!.âšÓ–é×ïëë¾/žìîÐ#¼²oÉ+þܖٹ㢠£$wBÎ]ÒŒœÅÞ¨-å?ÉhÑÖ»­ûÝÝ ·CŸIó%ä¿é”ÐúQÓU%°šl3ýˆë ò»ä – hŒid0È`ÿõ (&_Ø!ëÌñ®ÚF×ÍûhlÕþÆoy˜¾üÕç8Žã8Žû—ýDƒIn`»çÞסÏçÖñoú¤é·ÑkcI›ÏíW®UHÅãÆ‡È œ†´PñþI´›Ø `„؉Ö&ÿ¿Z󱯭—_ýâ7Oõump˜±‰‹:=dl|—ϳœYØP|Láöw›óÙ?¶S‡«¤Ý‚šT+ïUÈõìWoŒ,D’GÔ¸€­è„ÆÆ;þ«‰­„=AÕ+õ8U ÕÚ—¬Q†Ô“¢°‡}9Žã8Žãþ)5T”$Œ b), ÞèˆÝ¿äF¼¯äkµÉâ¨RTÝO¼u{Þ+ïZ­¾xÈõz-bƒë˜L,àN‘ <’\èa0§Q£ÆÖÊ'Yc2×±…Z‚áb?Æm|˜ràvÉÐèUQ‡×4ë°©ßɢ炞ú¾oo¶Kc¡:"ÜŠu.ymõg Ý NÏhê÷¸ð—öÑ[êlؼ¸MPHfÕB…¼ó{³‹èŽLÃt¨‚²Ø‡ÝB9rt„5l`c|VÿöŽ­Ÿ™Š…[~Vo­ÄÔ‹þ:„¿0ì`Á__Žã8Žã¸@é-ÕA‰Ü'}ñŒiXyt)o[Bå:»ý–Ú%l¥ÙµõuhÕ¡ë¢A»']9ñAûy}¶Dï >¤ŽœÇz1fÚÁý™Lc®ƒ:´–uP!õp‰ô3YOÊ&6í\}5÷¾!4råज़·ÞjuÆü|é§³Þõ+õu{Íí9õôìGÙ¹¹ Iº|LRµêRÆËku¼Ù0Ôgë²váa/*7õ°ré€bxÉR*«ÂVÐEÄWH_\Âr´€/ŠB0ÙæéŸôÅ7)êÖ«­¹áRp¹^ó_í<òjSfHviÒ §0-G zñ×—ã8Žã8î+ÊÊ!]ÑU©7ÙHòä^LÅÌöbÞÔ¿¾gm…ö2o½›!íÆˆ¾«ù©bÖÐw2é0{ÈÊaF`1ŽðE¿9Ê:ñ9ÐÃ@òa-ÆÓ®¤¹&gþlóoµdÒ¦õ˲g‹¾ì|©Bþbëƒêã2úK¥òºêwòÓ=ä9®z©vÇÞHïÙ§-šëß.w¸¼çΫSÒ½}ÏšÛòÁ‚"¥lËÆlÅQãÄVƒÉ“’ߘcQ­3/Œ%¸h3ÛÂøæ!pËùkÇqÇq÷Ï;h1&sõÂÚ®›Wã\Éþ×tñs{UcìÒñAú¦v5gŸ¥Ô!¹d4žLþÒ=8¹ÿ›é+c 3h0 õ@Ò ÇièQÎÊfꥪœðÔRÓ 9ž?Ôuv£Ìoœy‡DÆ&úuŸ³e¤Y'÷ó¨Ã‘ï›\#ÖíKïÑe£ên/ÜnNØ«JÏ=¹¼p‚hŒ§ýŒ½èJ;‘(âDã—D”Ζ™õ ÙÂYbC†Ÿ¢;,]¥’ûÑ?u @€ j£6j£/ú¢/>à> ÙÈÆ ¼À ä 9øŒÏøŒLd"_ð_ðñÑx¬Üû Ÿð髚Çq÷cÐ@ 7±ÝäÙ‰] UÉ8¼Ô³uÅŠTNt ©ƒ³fÙª‰§²*=±;t5A| ¥õÈFdË/˜¡ "ò ç£Û¿Y¦¿ƒ|Fò‡cHbàBMôBmT‹Ò ²-ç”®³Þlo¹ëx€½¸^üÁŒÖ)åfÛűü¢ïßà2!©rz|é”›O³UFæ5{ëýȽXcïb¿ðߪºôÔgÁý„‰7 ž·~þb±q,ÏZÔ„!籂iÙ|#:‹Ñ“ÛoUe©Ÿ‹á%ëϳãò­ƒï>U%Çð›X<І¿vÜ j¡º¡º‘ö¤=iHD"Ò˜ú¿ÄK¼Äc<Æcö”=eOåÏñÏ÷>ÅS<5–<Â#<ÂC<ÄCã‰x€|DàïÆtç9kXÃîp‡;œà'¸Â®ÆrxÀf0ƒ ¡ A -´(ŒÂ( 4ÐOâIY°¼à/ÔDMÔD34Fc´@k´Æ~2›Ì&}ÐíXm„"GÙuvGx¬Â ¬À\Áã/ ÊíÛÔ Ð€zQ/êEGÑQt ¥¡4TÐ ZAK‘Gä‘ÐLh&4#»Én²[è,t:““ä$9)8‚=OÏÓóô½Ao¨««“Ú¤6©-W“«ÉÕžÖ{Zïi=–ÆÒXšñk†ò%Šã8î[¦$gz ‹Ï…,rР—3»Ž¤Ké¤âs‹®Ìg%ÍÞ’w ™ëˆÔU{.î78IåZd Ä%Ãôæü))”¦LlURvbƒÕKÛ/rEgg¨iر Wqïá.\ÝqÿX«>¾ã‹Ìèl¨ZÜ:8³Ð—A€ÜU¤‹Ëù¤[Œ@Hk^òèå8¢&<÷†^:Úô¾ÍË®¢éyíûZô5ë‰ãüøÉh qJ¦c:¦“}dÙGÐôá¦á¦á&ÛÇö±}¢§è)zª'ª'ª'’æ¤9iNf‘YdD'ÑI$™$“d2•L%Sé3úŒ>#×ÉurZQ+j%Èä¶r[¹­üL~&?“óä<9O>&“ÉÝåîrw¹¤\R.)¿‘ßÈo˜sbNJÊ.o—·ËÛY:KgéÒ2i™´Lò•|%_©«ÔUêjð6x¼å{ò=ùž!ÅbH1¸Ü îR¬+ÅJ¥ŽRGýYýYýY¹ÜGîc˜i˜i˜i ’A’¶J[¥­¬*«Êª¢š¡óc~Ì™13fÆBX aeYYVEQE=èÊm36c3½KÒƒrQ¹ž\}Ñ €v¡Óét¹–*‡þƒ˜W@TÀxŒÇxr“Ü$7Ñ ½Ð‹< È¥„,'ËÉrr†œ!g”×E¼(^/’Ùd6™-ú‹þ¢?£q4Nx-¼^ …†BCÑItÈ ò‚¼PUQUQU!HR@¼#ÞïEdY$„ aB˜PS¨)Ô¤éD:Qy,I%©$•ºQ7êF§Óét:mF›Ñf$ä‘<êM½©7ÎáÎ ]„.B\ÄE\ ƒ„AXƒ5X#Tª UIyRž”§ûè>ºOy]”a6Òi‹´åYijˆgÆÄݶ°å‰;ÇqßFkãÄAª-ǰm.¿8ì°ÌÔ£¦B!”ÐûN –š…› Úu§UŠÓ­Æ/ká –¡ +Ⱥ£Ê?X!„ûñä׉À>!£¤ÕÌŒi0¡¨Hšã0f š°è-s®4»Ûfϲ›Õm zP¨»Û»~=ª4ó¹ôÎÃűº˜¤º,žÕ­Èšw[ÎÂyªµ³È ×_%îvû̪k*XŠ£<ò?ÑgÑ6„ ÁJ¬ÄÊ/i_Ò¾¤=éò¤Ë“.ˆE,b_žŠ}ûiò§ÉŸ&k>j>j>Òƒô =(º‰n¢ýL?ÓÏâq‡¸ƒ¶¦­ikq‰¸D\"~?ˆ„‹ÂEá¢!D´ íB»!BˆB—Ñet™0G˜#Ì¡h'ÚIX#¬ÖÐyt§ ‹…ÅÂbÍzÍzÍzAdA&{ȲGtEgÅ¢XëÃú°>ʨz¶ˆ-b‹ØP6” E0‚Ì^³×ì5®ã:®³`Ì‚ÙX6–UÆ^³’¬$+ɲƒì /ÅKñÊ× ÃÃÕÁÊ`eìï_,-–¶¶¶jjjKë¥íÒvÝV]]Ÿæo¼°¶î¡º‡HÌÅ\}‚n†nÆÙûö%¼{öž¾§ê¡ª¶ª¶‚…`!XÐ%t ]"Ìf ³hZ€Wˆ+Ät Cdz…ÙÂl±ØGìCÇÓñt¼ 4Œ†Ñ0²“ì$;q§qš'ÅIqxždÙEv¡+º¢+I $¥Q¥É²…lA%TB%rœ'ÇI8 'áXÕXM^‘Wä’„$²—ì%{åIò$y’ÜHn$7’‰Ldbüb“ÆÒXšTB*!•P†ëèžèžèž Ú¡”&¥IilÇÆ)¿“°“ì$;i8j8j8šoK¾-ù¶¨[«[«[³¥l)[Š]Ø…]üºã8î»!÷¸¤ ([Hl8{ŒÎíËÖÞà]Æ3ÕÓÒ6F×ï³EÎûLdß‘žÇÝXi~¾5 %"ê“ó¤Y( ²À(ò ‡ž‡ó§`:o+9ÈÃ4œF*5Œ[wÑjdyn¬îœ>øn{ŒC¸Õþ1êù•Lô*Ô-²âüb›¼,:.¿âiTÎÓä>Õ&ºò£µß«JVljN㫞 ¾á3òÂá –ä0a#«ÃǸs€(D!Šæ§ùi~Z¤iyZž–§³è,:‹–¥eiYjA-¨ 4B-ŒF“PJB…¹Â\a®pT8*â„8!NŒãÅxšæ£ùDåv^)·’[É­d;ÙN¶c*¦b*y£¼QÞÈš²¦¬©ÔSê)õÄP ÅP)RŠ”"ѽÑ[š+Í•æ25S3µ2wÂ>Ú>Ú>ZuVuVuVº+Ý•î¾K—þ.eQe£ó••‹8Žã¾aD$Œfs±³ªÛß°4Üwظ½ƒ¿Ù• IJXßÖŽ˜ë¼®_r>oæ=Q^F7“%ÒAy ›Œ+¸…‡<†œ‘éÄV7¬ÆòtEógK°›D¦({¡^E›Þï}ÕÓ>UêÎ-´ÁÅÿ«Ä}Þ¤÷öö.¾{Й‰H¤L)SÊ” K…¥Âr7¹›Ü± „!‚!,”…²Pão-Ñ-•¤ŸÙ3{f¯ô£ã6nãö_ö¾Z‰•X‰Ä †_dÇ}—”žv 2(}F«vrù[»ðá³ZM»y6oRz ; ;fxø¡dV'Ãþʵ»”ßüê¾Ù3ÏŒdòˆ\& r&ëÂxÇ÷Ï)sJÕ! Ht éI<å¶ž=B |èeÚ›¶©yªPc· _%îkç¤O}¼#ªï–öǧñÄû9ÃÎJroLýMoʽv°ƒÝWå®»kbM¬•/ ,‘%²Dcbš€$(KLâ Îà náný9VÅæ•B*…Ì.·©Ã¦ª/b¶˜}nÍÏ3žsgÐŽÐ>jñ¸ÆãYÌ•*ãÈ€cœ•Þne¢mAâGüˆŸ²qˆ‘²øæ;¼Ã;ãÚ;¯ð ¯Œ_ð”5s”ÕuL•I·Jú}ÜÇ}ÜÀ Ü åH9RNYî“陞éy/;Çqß !Š.%+${ù [ï·¢øQ—ÕÇÛÏûÜB´Ì¯šF ˆCµMUõ‡Ÿ^Tø|ë‰ks/F<‡7LÃFà *ˆ ‡$÷/˜ìØŠ‹Œha=iNôÒV‰mPª|5ÆÝº›fjúòÈq€×&·¸ÿiÆÅ¾•ÔPI:•…• M—VT~0½×tùEÓÓå•aÊ’‹ÊòˆÊ±²¢²þ‰-laKydΆ³áw[Þö¹í“Yífù›åm‚m:Ûtžõqð¥Á—^»eÌȘAIIb¥™óÁNìÄN㢓ʖUJ¬LÍT_ÓE*MoÊB–Êr“ÊVY†¿»™.^©KiSY söadÈÿ¾f`öë& ¦“•!3˜ñ…Ú9Žû.MDW„Él:{v¸ƒ“½,›:—;j;ϾÙKÃÅ̔ܵ/ ¾ ʲZ¼p÷²´;Ȇº!á83h Bòø¸vîßd2±˜ŠÕ’šÍd"&¡>ª ÌD¯¿%î ÌÆC'þºr³Ìø`þ/.÷­1MR•¤öOÄê°º¬.ê£!fÉÙfÙf¨¦ Q…oµZ­VJ çéyÝB­Î–D“h­Lå/ÇqÜwC”'÷1‚­aæhà×¥x%×rQŸêæ”®›óÁ"{ˆº­Þ\šYbIþ„¬÷éŸäìЄHf²;Û‹Üå);÷_0ͺu0À€a8€ó 8€ó_õ¸[NPå°•à +˜ý޽n÷#±… ŒûÞ óèd:ÅX*Ke=äÎrg"‚ÁWqUÙ+ÔØ÷¯ô‹sÇqß2kX@ƒÏø‚<¢'gÉ0¶—å²ÌñbÄ‘§ÂNä©<ÍNª¼ï^½½ìíÝaÝ®6@8Æc±Ü„=eP waÍÉýèoG«¹âJ:»ˆ+HÅ<á}í÷(ƒL³1³#­`+Ö™ufc”Á9çäˆt iJ^±Rl6¬;hrÜ€¢òà `eÐDsG¼)Ø«÷‹“…LvM1SÐ ¡­‡û£ˆ(‹p†Žf T‡Å^›fë´Öodý’Mn¢5ê0`ây°8Žã8ŽûaYÁjG\ÉJ©”<šÅ×~[©¢çÃêÏ«¤yMÏkð®Of²ªªMuó„áu—]=ÖÐS²”sè z‚œfµåvd¾z ÷G¢ð…œ f¥Xsµ¥ÐU8m×Û¬¬¶3DP,Ds„ñ0qÇq÷ÃÒB Í„R²AÂìUkÅÓÂêÉ¥;ª=•­>¯ËÙ«Ùo—a^æ¨íÙ圼™òø‰9=DíIuVW>ËšÃIÙP‡“û#‰ð!®ÄMØuäWg Itªõ.³ZjÕ £™L’j|)7Žã8Žã~@((r¡ƒDgÓR^¶‘cÙòÞC›÷(oë¹´`m3¹P^®¡ì—É™{uíG«WF_x©oa(iÈ :Z›”`:”þ ÷ç ÄN°c—ÐŒ Sù §i1kWM_u²ñþ±C%&Žã8Žã~@dÈ´ I"EX¨¼•y»zZÞèq·é<ßDy­¼K.F‡jFËw–=‘ÿîèÄ7K¾´!ïÉ/x)«å#l™q\;OÙ¹?…7œ`+`Í0AUB8Es¬­µ]Uõ•»ÉX„¢ÇqÇq? *(/Ä‘`èYпˀðxß=^Û ´?ahš3RŸ’ëžÓUº0¢ÎŠmçKœCgìÁY\‡9´‘ _7Œû³ˆ( X±¬›§òÔÂR«7jIµ@€!¤*Jàÿ"ÉqÇqÜÄVÐ’²ä&±Ñ,“eºíÊ·Åêq¯€fÇÊîÓçÿ8<û­ú¹}´åµÉ©Kw_P?{öÆþó`:Œ>"ÙÒ.¬rǧ¢r.ŠÂ°…{…XGªQW2ÒRPoÕÊݤ/* (ÇqÇq?5Tð™È%O°ƒtd»;Ì5ÂÜ…ƒs¾Íf:ÁWuD /}Ý&—K£H0¾ÀZbrG¶Ö°€FÙ]•’ûó‰$¡(ÂÞ£Îäù`^\´¥Ÿ•»É8ø“"``êbis®½}kóóã³oÝ$åð3Ùq<ƒ2‘ =×ÎýµèçzúµÒSšKž‘¥€üXnnÕÛ,F¼Å[¼‘£åŽl3º¢&Êó`qÇq÷¡ ȃÚ„\$N(h¬¬½·òèBÃBKU|]ÀR®—·Ö`.³¢H\vý›Ä*Ÿ|Y”û˜Î¦¹¤+Âf„kçþò·sæBý|ÃLz‰˜°Îì•—&FM[Еô‚îØ‹v¨o,Žã8Žã¾32)…wX‚¸ÏhªÃÅŒqå:ž©2ƒ^U]¥¾ÔVULÈL¾~µî«|[oœ¨Ë’l$Õp@Š’X3¨ ‚ò¾vî[@?wÒ—J’“äYÈåx«1Õ¹j—XóðÒ~(ɃÅqÇqÜwÆæÐÒ:tÉ”ÓYK¨[yQâ\•¯§ëF]`Ö˼Ø(>ÓÇ/nq6˜ugYKÀ^x„çx = y ¹oø©aÞ]ÝMúˆ¼¶tD6µ´X©Ñ©ôf“T/Å59ê<ª#h†2(Œx.Žã8Žã¾Ö°€†¸ââäK2e‹üÚdU»a%Û]¬øH²ÍKÐëÔ«ÉÚ+¶ž~tßïÒ¨_\¤'ÉB<2£+¾ë ç-qßú);w¤¡(Ñ’OXKyû`y@í¨Z¬"öÚB ÍH)xñ`qÇq÷PÆ¢+‹6^%+Ð’CAôêRªqJ¹Å×sÊWɆ"ò²lùKYýÌ©í7-JÎÔГZ’ŠDGv"=±Ž§ìÜ·Fü¨ÊÍÐ9“˜‘}p’·ÉÅU“…]ZñŒ°Äøþo€âpcÀ[0Žã8Žã¾qÊXô,œÃ8´f•°Åq±]AK«ZÄûN•—æ|Ñ7;[äÓ¸íüåÐÀ[‹Îä¥Ýz²^t ˆmÒVӸŒ™kç¾%ôC霓¹ñ‰5I•¦°KÌÓÜRuWì¯í&Î&kÕAaâʃÅqÇqÜ7ÍdíQ/¨è96É(Ø­Z£{e´nåÝOÛ½–Í ™ÒÌ»ÏR^F\ôš¶ ë0Q¨ U‘3Ø#葇,Ȫû¤÷Ç­SÖm¸u©$ …KHi"ýÆžz¾ì#÷ £%³e/#ÕHŽ|‚iX4ýEèA j™Ö#uŒµ‚à[,Žã8Žã¾QyÐÁ@f’ 8ÉÂØ”-®ó/¬SáÍK½®|Y•g§ò2©™±rüÞצ¾ª•q/«!=(8 y)+ÁîÂÀ‡Çpß:šÑ.Û1Ç/H.¹![¡,†ãð’,Óölèc­R°‚ŠïÆqÇqÜ7‡‚‚ 9ÂP‘#ÉDôC*Y8Ñ»S骛ƞΡTì)Ì{¬}XáCõÅ+öŽLN¶?Ì–kH¯X²±Þ×Î}ûovÝé:{†üÒi¹<­Or° …Ø.–gÏr„ùXã;¹æ² °„j2Žã8Žã¾!2d0¡GÆËµä,9äK…þfõÕìS¸¢þCvaÝ3RZc®Ò*µ²S ·‹>ÌZŽfhŒ–,hkLý9î›Gó »Ëe þR;ùˆP‹0² `YûÅæå´µµÚ²ÕØ ¨yâÎqÇqÜ7B„Š“˜hyª¬f;äà]¿§-ÒËw×vVߤ5…íª±‚Í »;‡Þ]ÜUõÌýÛ÷É$R{áÉÚ`-Ì¡…Н!Ã}/hÞ>ÉR.”}ßPRžK»+roÁÅÞ×¼–¶©R‡µÀì…%4PñqÇq÷S†ï A&Ö$½Ø ÂÒ&BÍ%%*Ô?Xý²Wý”Ìg¹ÍÉxÕ Õèqg×ê.µÊœ—ÝMgG­Èlò”½ƒF!¹Ðóprß 1·§¡§<8{¿Þư×ršæªà…qì-+k×ÀÌSS…Ì:aã8ïqç8Žã8î  "à'2H0í$¤‘•£†´_[Ñ…¤jÒ3ÕËÚÖ§÷&z8|”«És™¥Ó6{b‘<ôY»Ïœ„`V’…ÑsÚSªû=ö?©p¦YjôãSx•hɼظBž²sß#šS@_×Ð(«uÞMCäÐÁÄf‹–Ö­4‚˜Jüˆ'9ƒTyÈ8Žã8Žû (}ä*ˆÈj€ûþQè¡&ó—œCy®5ÐEr%Vž µl¤š+LÀ˜³Û¿ÕåÓ8¸Ÿ9ÌaKØÀ+0Õ¥´KµK©§pF8ƒô<=¯™hvÅìŠÐS¬#ÖA&2‘‰Bð†7ÇqÜ©+šÂŸ Ä@6ÐGç¶½[©jÁRìN°.†7rø›õo=¾<ž³p’GŠ3è!XŒ0ƒ"t|\;÷# ÈEò¾œ×1LØ ˜±iØ…ýka¹luV3_SÕX·>J£(÷^%èÒ-ÐBu]¬NFGü‚_ÆZ[fmÛÁí‚Ûl¼¯{_?p÷ší5ÛÞ>SfN™ ‚äˆ#TSTSŒÓªø°Žã¸Ÿ9´IIò£Ø)æ‰9…¦ç/bßyUø´R_t{>Ä~'ºÛ”6¯>.ÿêÊ—¦¿žñ>îËI¡‘0ž c;™Œ.ÈA <ÜÁ˜@|Yj°’ÁXöœŒ„5>“£¤.)ž/Âr™Ù¥ˆ0ðq?É•ñ·ôš€€ÐCcðñQŸ®»£»c&¨©ìã¾Ö}­\O‚I¸PE¨bÙÖ¼›y7ÁUuKu‹agÙYR–„’PâI<‰§qØŒÒsÏqÇý3æÐB…läÂ@’°’Ä †ãÐèQú€iÚ­fÄÕª]fIêqw2nJ¯­·%Ÿú|GO’ ˜'Õ‘ ì Þâ2y ¹‰15Éjl¨-ÉÐÉÍY&¢aŽ/ÂN2†V°—Í‹i«ëöDu”ã!ã~p*¨ ‚j¨1S1•.¢‹è"y¥¼R^I=¨õ¨¿ö¥Ú—ÚÏ7Ÿoî¾Ó½‡{L­¡Š¡ ¹Ã|˜OF‚þ³þs@qÿâþÅËÅ•_z¼ÞOg¦3cÙCöl#ÛÈ6d#ÙÆðĸÇq÷7ÙÈ…^ð¥#Ély=+Ë^U¿_ö£G÷6ÝkE¿Ä¦æõ6Hd5FZLMØâŸºåõà÷®Y31‘ #Xv¾üÓ•ûau©åÿʧ cFtL×=®}[ý™8èšõÞ{¿(4]©CrHA<å±â~@h 1'#Éä 9CΘVñ¾ë}×ûî÷ îÜ/MôMôMÖ%ìOØˉ1ÆT`Œ±{cì~AÆ»’û)ãSÆÉð#Ÿ|î^ªGL+­•ÖJk¼š’I2IÆ'|Â'ã Dˆ|ŸŽã¸ßÅt&Ód¾úºê£Ø`û©qåÃë0–h1h¤xúcßêé×VŸˆn À%H ¼Ålø¢(Ü`Ëß>Õ9îbL2‡éêW°–òaÖó0 Mhi’D®Úæš-ÕTêh”'%ð”ÏPå~Ää–‡<äÑ´-!W+È” õ,?Z~´üååå>8|pø`×d×d×äw×Þ9¼sØÞ`[ñmÅ/7VdXÑ ÕÆÊ]ä×òkÑ^ü$~já×(ªQTå‰eÞ–yÛqNŒ_Œ_¹Ïe•=¶Èz‘õ"ë” )R*(O„úR_ê+_‘¯ÈWŒ=ýzè¡ç»úq÷“²ƒ5ÌhEº‘¼—w±g̽úŸx·Ít!áÅëÎ}j”sG-XLÓ¶a»âì…ãÞã)Kž’1l-{Érñ YÈãä~<ÆÄ=«Žn½!Cï,­“G RzêKº‘{¶¢6Z] Àœ@üP[°ie¯´Ì“xŽã~TyÐA¢ýÉ#â)×fnl{ËmÁgKú|.SÙeœ=øôàÓñâÄHŸœ>9}òáÙ‡gžÝãB =.Øw³ïfßÍø€@"´%mI[c‰Òþß/õØ ­ÐŠ è¥@ýTýTý´ã´ŽÓ:N;RüHñ#ůœ¼ròÊÉ# 4<Ò0¢mDÛˆ¶êéêéjã¬:›Î¦³QEPä«¿ˆã8îE°…\$!جuQ÷Qå»R`e±ö”i/Ü0бóƒûOÚž:nP£MÆúûH}$Ì·Xâ~ j …ƒ{Ú=]mh6L>×'*•±‰Þ/ˆh\³ú(¥¢p€È0î›fš:[Àä 9HGâH•b³]f»Ìv5š Í„í‰Û·'¦H)RàÒ•KW.]™3%fJL™ee–•YöUÃWèz;°;ŒEZh¡ýÏáïÒkº„.¡_}aðã;ÆwÌ¢ž‹z.꙼(yQò¢Ä1‰cÇÌy6çÙœgE'Pô×k­<Ê£¼ñÏ2DË׃ç8îÇ`‹|È ˜A«*#ž–(Lºtj¾ªÜ\Æ’ ª›¿¨·ƒnΩ”~{¼Í=?ç{‹WØ‚&di€óÐBÍSvî§bŸdénó4xàƒVaìøXûèvŒM¼Ö©ÎÚ‰-V¾SêêBò>?îešÔ®Çz¬J ¥„R¦U*®8¸âàX€¸|ÿòýË÷/»_v¿ì¾Ñ{£÷FïZÛkm¯µ]ÌsÅ\¥>y@ÆÝOía{cCÿÎUð÷}ð˱Ë•)°Je Ë–5b£c£c£ãoÆßŒ¿™v:ítÚéý÷?Üÿ°ÅZ0m’¾¡oèx›ìê ¤á8ŽûΑ–D•ʱu Õ1àAüº%mce·ã£:eìÒ›¾3a@XXCÁšö"é êMª Ú À8̆ã~"F"¾™ñ9ò˜®¾ÔC‚q‚lÈr,±œ­Z, VR"Ò>(†W|ä÷0¾ÙýÐØ[bË"X‹ ABöÚhÝ3ºgtÏÐG¡BÙéìtvº³^Ìz1kOøžð=áë3Ög¬ÏÈjžÕ<«¹±aUQ•\H.$úiú¿³Þ 3¹)-tGwt—u²NÖÑ´-u&ëLÖ™eg–Yvæêƒ«®>èü©ó§ÎŸÊ• *4 m@Ú€´òûËï/¿¾ã|ÇùŽÏœž9=s"®Ä•¸¢ª¡»Çî±{x…WxõÕÔ[Žã¸ï©Af’™Èc}ØϦ%•Øt`M/§&åøϺ—G o2ì>ˆŸÖ-ŒØ°q¡tI6gY4‡Z’;˜…MXÍcÈýLÌ;èqL9¾Q¤×Ü&Ù~Ü ó›4¯Ó£hÿ´ÖPƒ Í#ýá[Xñ¸q™¿"B}¨õ1-1onÞܼy[‡¶mvµÜÕrWËÔe©ËR—]˜taÒ…Iãë¯?¾~Ɇ%–løÕµp‹Ü"·p —pÉX¤lÆôû2ýe@‚‰L&“Éd¥ÀÖ°Fï”Þ)½SNyžò<å™––¶;wwîîÜFà o4ü«¿½­Gë¡3:£ó?hŸã8î[FAAÄÛjGµ«R0FXuÕùW¯cì”­®)c7v0ÆØÌ¤c8õD©#O‰ç-ø Aîçºh®á >Ààš¢‘zBDiX_vÔlŠÚZå†;øD&ޱ2l;¡ðÀq*Óa'JÿzôGšL“i²|M¾&_£7éMz3àiÀÓ€§sìçØÏ±40h`»§»§»çÕä«ÉW“GÞyäý‘±#cGÆÞÜwsßÍ}4¦ÓtŒÇxŒg¾Ì—ù¢*ª¢ªñ¼Êz꿯<ä!ÏøYÁ Vl$ÉF*ËA~Æg|Æ\¿¹~sý†÷Þwxß+¯|¼òѽƒ{÷Ã<‡yó5>j|”K¢K¢K¢|P>($HRIHB’±}¾'+Çqß>2Ù6 áËÌÅŸ®|²ZJ Ô †{_‰SXw)K[K^œÛ™4"*lDÒpÐBIY:’ã~$¯l_²c—úw»Ãs¦!&ü²{÷èF™fË4mÔ7õ+âò¸qeC"E RB+ÓÊ´²i•b Š5(Ö`Bâ„Ä ‰çGœq~DÊç”Ï)Ÿ÷UØWa_…˜Ô˜Ô˜T‹ñã-ÆP…Pˆ6¥MiÓ¯/†¿(Í5é×'eHR†'ÇÉq¥Äú£õGëžx>àùÍÍMJLJLJÌö¦Û›noZ¯t½ÒõJ›6F;ÑN´F`Fü}ûÇqßp‚µ°Vå®2®Ó5,{Ñä…y÷ícì¼6çyî«»cláÓøyñ³•:Âq™¸œwLp?§¯¶Xÿ\K×ÚÐ åH ¨ØLÖP{_e¦r´ª¥qSOÏQç :Š‘¨„óÐqåãXò‘‹\ä’Kä¹Äü˜óS:Üͨ5£íµ;ÔîP#ËF–,Ý˹—s/÷qÈÇ!‡Ì8˜q0cyÑåE—}TîQ¹GåŒ /!KÈv]g×å¹ò\yîW½øÕèp¥__€¥³t–ŽÁŒÁ$‘$’Ä϶Ÿm?ÛÎÀ ÌÀ…ð áÂûêwªß)e•Èᵆ×^ËÏÃÏÃÏcѧEŸ}ÊXž±dVȬY_]ãé$¤£¡Ñ?ˆ6ÇqÜ_„ö"OˆŸr\´l8ûÓ/’÷DöÜ&‡]ø4èÙ‹>ûHï!>›ŠYæ¿%P1µ#mNRˆûA£:Õo06~HL¹Á}Tó7·~™±ÛoGÁÝ.1ÆËìYNêñ¸q¿“ ’0s0‡ž¡gèÓ*% —(\¢ðÔaS‡MvÉâ’Å%‹”Ž)S:î^¹{åî•­Ÿµ~Öú™•ÖJkõëªêРȲ‡ìAY”EYcù÷µx¢é—HD"’æ£ùh>Ó*!ƒB… Ú2qËÄ-Sߦ¾M}{~óùÍç7î<¸óàÎvÛì¶Ùm3^é$âOüVv“å8Žûó©¡‚ ˜Óz¤<àÛú®Û ­bì¢ë€«Œ]Üß¿ö_¦Ôo|UlJ3ÈXã£rqãx𸟚iâ×¶öÿ~Œ_3ÌÐkŒkû3Ÿ#FµŒÊ_M.t#ÿn¥ŽFÒI/7î{Û™ †q€HsÒœ4GTA¥ŠM¦M¦Mf×]]wuÝuH<$Ó§O?~rÈÉ!'‡Œ->¶øØâj¨] ¶iÃTKµT«´iL|Œq¦cýŸâ)ž’CŒ_§óåË—/_¾Ñæ£ÍG›Ÿïq¾Çù©êTuªz}þõù×çèÐ; ÷Wá¿H.’‹ÆÿàÓX9ŽûóƒI¼…ñÓitdÌðj{ØÔ‹D2–\vHói{º»×ÈQîUEˆÅé¯ÛÒþ›!÷3MÜûv«Ñ¥\ÆÆŸŠ™«Û6ºJû"º|cm;œ¨Uü½G}¥Ž°›jÈ\7î?F[dü– ’_È/äRˆ"…Œufc6f×{Xïa½‡›&nš¸ibò›ä7Éo’4Iš$Í‚Ý v/Ø]åU•WU^}ÕpwÚvWFu‹~Ô阦¿(}ð/è ú´Jíûµï×¾¿5akÂÖ„Ôã©ÇSŸZwjÝ©uýökد¡Íl›Ù6³ñßAv_Å_ùõƒ'ñÇýÑj¡~ýä9‚MØv´ý¬¸ÖV,ó|×~Ÿ •O î÷Kĉ:õËX = œ¢ïÈ=þÙÄq_%îQå+¤—<ÅØø‡1›ó4£~‰\ÍØ„ŽY¿ø„j¢ÔóÑòd÷0Qí _ø aB˜fZ¥øâ7Šß˜’9%sJfÂÇ„ /_¿|ýòõ=–{,÷X¶šÙjf«™f™f™f™Æ÷í2²Œ,S¶[‚<àñÎõ3Ä“‚‚GâHI "AJ±Ko—Þ.½'?Ÿü|òó„b ÅŠ¥\L¹˜rqE=Vô¨jSÕ¦ªÍWMæ§ùiþŸ(†Çýµ–cêCÔ¶¹å#m£w­÷Õëvœ± £úë_9îšÒ9µ€à´Þf<òÁf$œ˜cOÜ9î«UeÞÈvÎu`‡<¹«!ø(¤Ñ SÅ`ºÀ^¨Ñ%አ¸ÌƒÇýLWkéŒÎèL<ˆñ`ñ,žÅKǤcÒ1§§§„–Z~hù¡ÑŠF+­p|êøÔñéÇ '|œ°+tWè®ÐÕÚÕÚÕÚ×ý_÷Ý߸vûbº˜.–cåX9Öx®Ld˜ÐÏøc3ý)(({ËÞ²·¸Žë¸.´Z ­^Í}5÷Õܡφ>ú¬‘ª‘ª‘*Jˆ¢„ /*¼¨ð¢°aÿÂþ[“¶&mMZ[gmµu²6fmÌÚ¨LceïØ;öÁFð_°«²• l` XÀ–°„¥qʲ2.ßÚä¦ÔQ~+0Àƒqåe­ƒÉM)Q6ÔÍE.rgTJöb/ö9Žûã  ´q#‡äÂ̕嫾¡Ü|vs-[©]Ô'cžïÊhœ÷¬Ú›sŸ¦“¥$ñ¬)‹G(Ç}Õã^¥•ÇA—-,i‚CÌ…/ÕFäEdyÓŽt¹ß¹n…ùÅó¾Uæt1ùÄãÆý£7´ÐÂ8I”Œ%cÉX,Ã2,3­Ød|“ñMÆoú¸éã¦i÷Òî¥ÝK“0&aÌü¹óçΟ[qHÅ!‡|Õðer™\þjïþûÈ›CZN–“勱0Nêò2ó2ó2›¸sâΉ;/Ù\²¹d“ü:ùuòëE—]ZtÉ÷©ïSß§¦MÒ~´í÷ÕYþý˜+5=á O"èŽî莥XŠ¥ÆYY5ÈŒ˜3âK|‰/ 'á$oðo”/ipƒÜøËËq?¡7Ý@ÖÃâ.ujYãcçÞ (ÄzžwìßaaäÀ¦u ¢š¡9A㬒îó¸qÈ¥¿%îÅê8lµÞÇØ„†1o³’G<‰8ÈØ´]ÎôϨZÓGÙˆÝhi2ΰ†ÞÏýÖ1É£;c Æ`0fc6ê£+ºÒX:–Ž5­^êT©Ó¥NÏÌš™53ëRä¥ÈK‘i]Òº¤uÙô|èù°h¹¢åŠ–óê=Ô{héÌÒ™¥3+I•¤J’ÿ1ÿcþÇ*ž©x¦âjGí¨ñŒ.p +qÜ¢PŒÞ¥EHMäCŒÚ_kŠ[“ŠìeÂ’»;ߤÿ¼:a•Y¡,˜Aј¸sñ9¿nê®;"9ʤâÒ VO¸C²ˆ˜œÍ’ì>˜wÔ^ƒ%.c»Üš ¬ Á®8„k¸ÇƒøO))”òã{B¢¬æÁ^±WìÕWË ~ò‹\dá=Þ£ Š ˆéÊh§!NÅœŠE6ŒÜ¹3übø®ð]Öç¬ÏZŸýPäC‘E6íß´ÓþµákÃ׆¿¿ýþöûÛñOãi<——ÈKä%¨Šª¨Ê7ú˜öxЧx*¯“×Éë¨@*È5äríØŽíHgé,u^ÜyqçÅ5’k$ÕH꺪뮮»|GúÖ÷­¿Ôia̘«ån¶¸ÙÂØÚ*ãÿŸÁ¯‹unÄ~ìÿû§`Y3Ó14"H#ñ¥øR|).Š Á_ð½EoÑ[Y›_˜"L¦Ï„gÂ3•¯ÊW嫚 š š î÷ˆ{Ä 1H R]S]S]Û‹íÅöâZq­¸VÕPÕPÕPØ$l6 qBœg4Õ ÍÐLé³'½IoÒƒ0ƒPõPl![ÈÉYr–œQµQ[z"=‘ž 'z¢'ÆaÆñ½f9îA@@èUÒ‡|”‹Ê­ÙÏmnýì[– óbù²a#ý"‰9ë³c¤kúÓÞÚA À <Å<ŽSˆxˆÏ¿Žõ4ŒaûYƒ/¶ú>R’6ØUk/_µ53ë¢mˆ,dAdž1/tB5dÁ‘'îÿ‚i uÇqܘÐ(cs Ú ó~æýèÚ–¶E* !!¢y6ò Ïk˜Þ0½Dv±Å>dgd7ÍnzòíÉ‹'/®8¹â䊓ד®']OB’Dž’§ä)ÛÏö³ýr-¹–\ë«‘Ü„ ÂaƒqÙûì>»Ïž³çì¹¼F^#¯‘ÏÊgå³,“e²LÙ[ö–½Y VƒÕ0Øl ¶ºµºµºµ†[†[†[†J†J†Jºººú}‚>Áàhp48666ålÏÙž³ÝƒzPªMצkÓ ‘†HC$ò!òýƒ+—ã¸ß £oiÜ“+J¥QÖû˜‡½ýÃ-"þHM{xÿÜ{ÃÇ /溾8¦¡[‚$x9qŸa\'Õ0Y.ËneíÖIVæ!š|Â1@îÉÎÙÖ2[¦y‰ë„’Ŭ5Ûź¢Ú£ß¿‚„()»ª˜ª˜ª˜M%›J6•äªrU¹ªq­ñ8€_õÍ'H52ŸÌ—K}¥¾+K%ŒOï9Ðk­×Ú\+iŸ´Ï¼®Y ³¾×ë_¯OÓ,p°À:qK»-íŽn>b~ÄñˆGpƒä[`=ñ0aã1‡c˜lÇlG«$;½ž9ÈMå¦Ä™8gêA=¨ùH>’Ê+kØcØcØ#—ÆKã¥×ÒkéµÁÍàfpËÝ—»/wŸd.™Kæ­AkÐÊ·ä[ò-i€4@ _¯_¯_o˜i˜i˜ixdxdx¤3è :ƒ¾™¾™¾™!ÛmÈ–öKû¥ýy~y~y~ú}„>EPEØ|6ŸÍG7tC7ã_}×qÝx¬š×ï^¿{ýŽ0ÂC[´E[6McÓŒu^â%^ò7ÇýÎla3”…#îà®àWC?Ë 1Ö²‹jv³pvùÄî˧mÎJÉÎËkL×x/oe-Pxø8P÷O¿þ¥Ÿ*a ³ˆ~¤¡‘ë"³sâ Ìeì½ÕÍPÕU± ÝE³ W%s©;ŠÃv<|ÿÂnìÆnXÁ VV­Z ¬h]Ѻ¢užœ'çÉB%¡’PI#ŒÆ'ä9Á NßËG’ádxÞ9G¶n“e“¥º­îªîj¨#Ý”njK"ñ[:îš¿kþô÷µµ™›¿\ørd ’çxŽçl›Áf×úP'ðžõ?þŠ!*1gçÙyv^%ŒFIÛ¥íÒö§§žÞ{z/ã]Æ©ŒSº+:?ß—Hùº|].nØdؤ¯%®×}Úñ±ÉÇ&|ØòaKN®>KŸ•7&·Wn/ƒh ¢~¾~¾~¾ÞFo£·‘<$ÉÃPØPØPXÊ/å—òKáR¸n j rc¹±ÜX –‚¥`Ã{Ã{Ã{åùŸg ”@‰ë/êjrS˜¦ìŽp„# ¢  ^ð2®–“ùïŸ.–óg®¢Ãq?5¦†ÒÖZŒ©ÐºÆƒr=Zã²aš4f¯É£kÝ3&£:ò`Esé*ZN> —óàqœBÄdüº”ž>\Þ#Ge•Õ=0Ì ïIKR’\€µoiv_c¡>!μ%I’Q®pàáûLWá(Š¢(ª¤ ÔžÚSû\ë\ë\ëœÑ9£sF“v¤iǰlÁ÷òÇJÛÒ¶ú«¹9¹9yës{äöз18œ + Û Ûò£:ªpÍ?)ÿ¤Â½ í(´#­Ý5ÇkŽÌ90Ú„6¡MŒË*QâƒþÀ—Ê䖃䑈DTú˜¥T)UJ-»¶ìÁ²ûÝíëÝ×»tzÙø²ñ6_Ô)êò ŽàT MÑôéÊg‡Ÿ¾uwÜÝqB%UŒ*ÆPZ_Z_Úø š&ÍŠÿ{¢çe\þmiٮ芮d%YIV*¿G±§ì){ª|ÍÃMÜÄMãØxÆ~ñk¸†kx‚'xbü¨ü <Ÿld#·p ·p7p{°{Œ‹K*_c”úÈ@OÙ9îü(ZG~Am¶é°Á¶·¥ƒ¦³É’O\ ÂO^ û¿=òn@.n^Üâc®¡$2å¢l5k‚UüÚä8…È”Ä] †ZÒJ6 Ó6ï’á ô¤ñ†ŠUaz›3Ú8U+õyá3=‘-) 'Øðkè_˜‚)˜¢æ¼ÎyóúÞ¶{Ûîm#ÉF²1£TF©ŒRç3ÎgüÚËØ ­Ðê»û+ÕPk›Y޳çXK!ŽÈ™ ŽÇË®Pa@%©’´à¼7óÞìŸvôÖÑ[kÒVÏX=ãEÙe_”UN д€ì%{É^8‹³8û=úV¯o“ÕÍ›¡šÑj´­&÷•ûÊ}…ƒÂAá`Ûm7¶Ý±1buÄj§•N5j>8ü ߃|FŸ¨r¢ŠÔ•%²D9OZ&-³X(ôz= ¸¹óæN– 7¸I×  ð‡qµP µÐmІt#ÝH7”C9”Ã]ÜÅ]ö€=`ðñؘ@+É·’p+CYNâ$N2 L0&åÜî÷x÷ü Âqª6¨‰‚8„3œ:Ûž4ŸP`¾“¥Ù#¼. nÖ|Ò8£úµ|ʼ¹N‘º8$¿”«°õ`ÉSvŽû•ˆxƒ]+¹¬üòSݼҺú©8É{õ ògKõdUiUZŒ\pÛQv°ÄÀÿ“É*Ú9­sZç´¾‹»¸ûë½ÊB‡ ± •䯨+ÿ½hMz“ÞXÁƲ±}Š×·®omvÒ¬ŸY?v€l"›Š-.:¶èØò¤ôôÒÓý^–jTªQëy­Ž´:R¡Kùªå«n¸·áÞ†{»[în¹»¥œ"§È)´:­N«Ëä ò´C;´3®oºQ÷ï3]‡gva)MJ“Òr¹ˆ\$ßÅ|ó]8vàØcƒ{÷î!VË‹å/¬¼~!}ÚÙiý¦õ{ôåÑ‹G/àll/1¿µ]µQ ÅPŒ]gÃÙpGq7¦ã0˜Ìd&ã".â¢ñ1?Ü„lŽãþ*ˆ ††:¨ß Aå{=¥E m  *&Ü«ÿ|FfUé Ô]º+z eHà i$ÛÀƒÇq_Û‚hö‘X²mÝÄVa!®ŒM<Ñq§¾Êè#íW½žùKψ>®Ã¬+[—ü#ÝpóyðþÓEå:¡:‘ñd<O&“Éd²ñ'~…ɦE?ÈŸ¾‡ž£ç* ¬è[Ñ7æXŒ#­œ²ò—•¿$M›46Ñ5Ñ5ÑuV“YMf5)•^*½TºécÉ*²Š¬Â0 Ã0cßnéßaºÂ½-laKV“Õdµi• ÙA³ƒfo5l5l5¤š§š§šŸ*yªä©’} }¥¾’eËPKãÞ„b’ê™ê™¸A• J©æ©æ‰ªª¤&™Ifþv–¿­ÄÂq÷"OIÏ_ÿÕÛ]iR©¦íØ ux°¢§çõsèðºÁìrnD%”¦}É+âoL÷9ŽûÊpÔE5Rµ`£ÌoÐH¨6±É!î䦎ÚùòKÑöQ1“mô–!ÆËo*R±‚ï§&B­ ±hezžž§;„*B ë„uPc36Û®´}fû¬r`e¿Ê~Á9Áº`Ý€»î¸»·ìÞ²{Ë^1¿b~ÅüÄ/'~9ñK·«Ý®v»j±Òb¥ÅJcû­Ð ­ˆˆá«óò ˜þžhŒÇˆ@]G×ÑuJÖ^k¯µïé×Ó¯§ß™œ39grRú§ôOé¿ýØöcÛÕXVcY¯öµU–æä1ç8îw3QÂŒCM¸ÚJœt?tÓ– c÷ ¸÷)þà“Z·²ùFZµ€ÔpëÑ…‡ãþ‘†(ƒbt/ñÁIh`Ëñ¡a—*æclÊ›ÎÞÙÍF.ˆô“óÆm‹±ñšo×ÌÒ¸p$ÙŽ{à?`qÿÜ9œÃ9å0_õ|ÕóU¯™\3¹fr•éU¦W™4=hzÐôQ3GÍ5óâ닯/¾¾’ÿJþ+ù×Û¬·Yoö"ìEØ r€ ÆÀhKÚ’¶4®¢$‘¼^‰ƒé>©§p §ÈQr”U ŠêŠêŠêæzÏõžë}9óræåÌ‹º‹º‹º©·§ÞžzÛµ¿k×þÆסuhÃ13¶ö½oÆqÜ·€‚‚ÐRä01þb_~JÉJùs?Î9°·‡3˽×ÿȵÙk{wèOË’K¤µñQPíëMý8ŽSˆHÁ¼¤Óˆ¹ ç±/,ëCÿì[9ËšCtò ÖŠ jÚ%íÌW™-~ˆ;²+ˆ¼Žû?4B#4R6«Wü]ñwÅo_º}éö%ïºÞu½ë­x°âÁЧntºQÌÓ˜§1OËö(Û£l1sÇÌ3·šªšªšjM…5ÖTx°õÁÖ[•†iÚ†¶‘µ²VÖbVa•±¿9yÈû)b« ÁRVP)(AëÒº´®(ÊÊÒ U U U=nö¸Ùã¦S¦S¦Sæ»6ïÚ¼k³ÚfµÍj›ÍG7Ý|T~+¿•ßÒÛô6½-GÊ‘r$†°¯¦´rÇý/dÈ`´?½N,åµRIf]mpél7O›~¶'Ì ¸JæË^g¶¦;¿Ü,‡±÷¬ú '®c)Nã#ÇýS*º‚WsïlU¡KqsƦé»Ú})8âMÄVöi‚cÌ¥Z—ŠûºŸUêÃx„_û|íóµ“w&ïLÞ¹¢ÐŠB+ •Y\fq™ÅÆÇöFoô&$€üÓö9ŽãþwaðGq!‰^&#•‚åÍï®U†±¤‹ƒ+0–2¨LãÕo­'ØÔ@ýI0´ÐüðŸç÷_" âxI•‚ö=Ë¥½Î2¦8vn—}yä‚H[Æ&ˆ1'Ûì-w«¸q‹ž¸sÿÎûÊx¬l,Õýa˜Q(´Ph¡ÐÿÿÿP1T GÁÑ8äÃù1?6‡Î¡shʼ”y)ó’¯'_O¾¾´êÒªK«–ÿXþcù_J¯ô¾+~¤Ô4’"DˆÆ)§£1£•â 3+̬0sݬu³ÖÍJ&É$™\r¾ä|ÉyðñÁÇ7koÖÞ¬½10[éVºõ«‰¿¦ãã9Žã~/–°„%I&ƒˆ1ˆEû66£-V&[æy…%&ø hóaÑÁK½ÆødÊv ôu%yð8î_}hµ_Ç7ŸVúHa_Æ&6ì´(·Û¨j‘¿06þuÌΨºÈ·€R‡'îÜ¿Å4èˆD$"]Ð]Š®-º¶èÚœœœÀ#G8Þw¼ïx_©®Y Y YÐtTÓQMGíz¶ëÙ®giŸÓ>§}>;õìÔ³SûOí?µÿT—p—p—ð¯NFÃh˜ñ?”>øïwb¥é(ó:¨ƒ:ô*½J¯K¾à ¾D¿Œ~ý2¾c|ÇøŽ©íSÛ§¶ßßi§ý7hÜ qÓÆŒ{Öš.9j:>žã8î?eúéjØ(4D0z„Zã.È~CŠZç{›w9¾_¯¹Œ{Ó§PJð²B¾¶áÃM®'¡¿mÊÆqÜ?#\£ÎĸJLý\oOχRÒ¸m1/òžŒºù±ñ©1+‡mZñ­ñÒâ‰;÷ß©ŒÊ¨Œ ‹°‹JÊ%å’rhjhjhjµiÕ¦U›fëiëiëiú ‚] v)ØeÔûQïG½?ÓìL³3Í®h®h®h¶ïÙ¾gûž›lj°I DãÀº‚® +‹XÄW4W¾B|/I¼iÊ~'p‚$‘$’¤¸¦¸¦¸¦L0uÂÔ Iš$M’&Y“¬IÖÌWÍWÍWM/š^Ô¸¼&)AJ؉ØilígPÄqÜÁ°@@”Fi”F4¢C8„C؆mØö÷"õˆ#>ÛÛ®µ­y¨ïãFî^¢«õñh*Íbo·Þ^™˜Q©|ïšÇj΂/|àC7 ABe¾’Çý B ’Jº+ÇÕkvΟöyਉQ~†Ø1Öíã¿2fØ´/ äjÞÆK‘'îÜÊ´÷½ º  *¢"* Äa°ÒÇJ+},ìtØé°ÓU V)X¥ åBË…– •mƒL›©±´ÆÒKWXýaõ‡”Å)‹S'žM<›xvª˜?ø¼yïÊ9+;ŽÏih•¥â=µâ”ý ‹/_¹|&iJb½Äz,'DMˆ²Í²Í²5vÒ ô½ðÕ§ÿ‘ãHw\ÿuúšM5ó­f ¯¸öÜÚ$±ñÕ:Öóé#Üïñæ1ö íÇ~ìWŠ­j[Õ¶ª]5¬jXÕ°° ° ° 777R–”%eÓ¤* *ydùªÞù­ó[ç·#FŒ8UýTõSÕÓË¥—K/·;lwØî°f훵oÖ^ë¥õÒz)õé$:‰NÂ,Àãó1½ý^Lÿ±Ù†mØF»ÓîÔ8·Ä.Ö.Ö.vl…±ÆV¸ðì³ Ï.¾\ør᥹Ks—æúŒñã3Æ07âFÜld[ãK:rÜÏCùrî¸G¢·@ ´ÀLÌÄLÜÁÜùªˆŠ¨¨^ª^ª^j‘d‘d‘äåååãìãìã0'`NÀœQ5¢jD .\0$>$>$>¤]H»v!/B^„¼2:dtÍü5ó×ÌÐ! C@ß{¾÷|ïy8{¸x¸Ù…Ú•´Sk«i¨OR†ÅGûÅ6dìüÁþ-;û¾ßñ«K|§;†kÝ¿~j;4ªÑ(àXä±5ÇÖ¤UO+•Vje§•Vvò¶ò¶ò¶RêÑvavÆ3î§–ˆ!ˆÁx@ íÉ1rûüœØ¬‘ŒMHèèÅØ¸#¯téq´q¤ñz¹ŒwØÍÃÆý!Ò‘ãº(öQöQöQÕ7TßP}ChththtÑÇE}l袌’Wöû|xA[ÓÖ´µicUTUTUTKË/-¿´üeëËÖ—­·&nMÜ:wÐÜAsùò9äsÈ´>mB›Ð&¦xþ§i÷O µ£vÔδ¤âãŠ+>^_{}íõµS;§vNí¬ŒeïÓ;¦wŒÅd‹É“¿znk°kŒæ);ÇýxL?7”NŠöhöH@‚¤üß Ð©t*j[Û¶¶mí‚æÍ š—r,åXÊÑ?Ê?Ê?*poàÞÀ½Á˃—/Þ¼=x{pFpFpFpZpZpZHéÒ!¥ƒZµjá¿Ë—ÿ®ROK=-õÔ#Ù#Ù#9_ç|óuVÛ©íÔ_}Ž‚¿wjUq©µŒ]8`—Üöä—>‡rUñÚ^q• {çå·rKuF]Cµt¤í©q˜J>• V*¸µÜÖŠ[+^±¸bqÅâ@äÈ‘µßÕ~WûÝWçJ#i$í×?•÷¾s?§ü°…•M>“X¥àÈ¡ö‰µº16ii§UìÓ8»Awãû:7«†X‹x†NDex!?÷»Qþ¹RF4>ÅSð* •„JJö¨ö¨öh×ö]Ûwm¼ûñîÇ»§uHëÖaË©-§¶œ ~ü0øáWYD‘EÆ)§Ê`ÞÛÄqß;å*VzЕëZùS¶HÓA± ÄâŸ5 8 ΂³euËê–ÕÝD7ÑMôŽ÷Ž÷ޝxµâÕŠW«7¨Þ zƒI!“B&…Ì ™2/¤rHåÊ¡¡¡Ákƒ×¯­y°æÁš«4¨Ò Jƒ2…Ë.SØc»Çví¶‹lÙ.Òdk²5ÙÿôùÏÀļ{hI2ž¨Wúv¡ëùfÌàY·kúq§WõÌØÅ'ÜläwMyFÞÿ¶HÀŒÆ(rˆ"Æç@ç@çÀ¹Ò\i®tÙò²åeËsÛÏm?·½ó‹Î/:¿ íH;ÒμL’I2í(Ÿ÷³Ѧä$œà ç]mû„ìblÒòN§Ùž±Ñýe ˜ß²¦õ$³åÚFÆ<ÀDôæqãþùùˆ–h‰V)Èß1ÇüƒbƒbƒbƒGíîéîéîi¬¿k±Ö¸Æ°B -´ô$=IOš6\üSñOÅ?MI’:%5¡JB•„*)³Rf¥ÌZ¶6lmXÍÊ5+׬lZŸ¬"«È*ìÀìøµèŸ ¤QJLz€ˆ7ñ&Þ``0ŽJ/v¤Ø‘bGŸ_|~ñùä¥ÉK“—&¹&¹&¹N>1ùÄä.\:¹Wr ‹Éb²È@†±}>å”ã~$Êm{Ø+Ÿxÿ¬¢°_Ø/ì·zmõÚêµË)—S.§J-q´ÄQÿgþÏüŸzzz999¿ ~ü2Ä/Ä/ÄÏxœ’’äääSyJå)•§”)U¦T™REÚi[¤­C]‡ºu…-ÂaË?}ž6° ©H*’Šxƒ7xºG3ÌAo‘Òx†ñ¢ €,:g7¯{‹µŒW÷cìBƒµ6¹¡® ™O°—®#) †3è5T¿Í&RC 5M£i4ÍX¤NR'õÕwVßY.\ HÖ&k“µSöLÙ3e3u¦ÎÆÏX*R‘Šð†7¼ ŸÀÊý (ˆ` ÎdR°vO‹y·›ø¸Sù@ÜØ¨W/ÅÁºÖyîËìOÛUê“Þ¸…=Ü}¸ûðàKÁ—‚/õ êÔ×ÕÓÕÓÕÓXÿ ¾à ò#?òõñ‹\ä’ö¤=io<Émr›Ü®Q'¢NĶìmÙÛ²SO¤žH=qÞÿ¼ÿyÿQ7FÝuÃ}û:÷u_](céX:ö«g«œåï~®¥/è ú´$<><><þà°­¥r€IDATƒÃK±M±M±=²ÿÈþ#ûÛŒm3¶ÍXq­¸V\k|lSÚ”65nn¢àSN9îgðÿØ;ë€(¶öÏÌ.Kw‡  H#H *vw·bQvwa]»»»»¥;Q @®Ý9¿?f½ïú»÷¾ï}ã¦óÙgÏžΜ9óÌsžØ‹½Ø«µNkÖ:Ë8Ë8Ë8###/‰—ÄK43hfÐ̰waïÂÞ…‘0F¤¥¥¥¹Ò\i®4X, u u u jÔ4¨©‡½‡½‡}Ý ºAuƒ .\2¸¤ê¥ê¥êõ‹Gç×Þnè†n|ØGÌÄLÌäíã¿ÙEì8³ý˜%d<_1«ÎQã!”&©Ç® ôVbôƒ7«öid§s]­ ¦¡/É+2÷¿9ÖOWN[Æ–±U®is Í6Î{ž÷<ï™.M—¦K÷tßÓ}Owwwwůâ™x&ïðï?Ó„&4… %ð7‡=Käd_^3¥}Ó )”ÎT(O˜™Õo@þéÉ^½VºÂb¼ñyÅ}ÇG”ã&ð›ãx •¨ä+ꞯ{¾îùð†á Æ4iÒØØÄØÄØD13‡!däCŽØˆ||t˜Á fdÙ@6(Lkú7õoêߌ‹‹‹¿–s-çZΣæš?j~<èxÐñ nÝ ºHâ%ñ’x¾=3˜Ì V¼N(‹Ô‘ˆD$3ŠÅŒâ+´çkÏמ?MmšÚ4µÄé‰Ó§ß ¹r/d›É6“m&.&.&.ŠsFWtEW"!òÕf]Öþ~(Y¨ë\Õ¹ªs5¸upëàÖ7>Þø¸ÿþ ‚nݺ:'tN蜰Åa‹Ã‡5kÖ ¬]X»°vaaa¡¡¡õëÖ÷óó³ogßξ®®®Š†Š†ŠSŸ©ÏÔÿ™s8‡s8G ˆ1À ¬À >Z—"á¿ðÓEX0¼¦œÉaܾæ~i^ããdݽvŵõcGÈúßjUYçRêèЦü#ë´äÛ«¤#ýH”tíßöÿƒÅXŒÅä$9INòí=Ú{´ß;yï体ïÙܳ¹gsþÀùç´åÚrm9ånˆ1"FŠ?ÃB¿7ìòœ(ŽÅ-ýÚÓŠyc –UÌÖ·º¸xšaŸûvM-oÌÌ,Mœ…qø Q^p½á otFgtF‚T?«~Vý¬ðÀðÀðÀ`ƒ`ƒ`½{z÷ôîýªŽUˆ QaY–e¿y„øùùùùùm4Øh°Ñ Ý+Ý+Ýën“»Mî6Y™»2we®›ÜqÿV?TÀÞdo²ñ¢þ¢þà vn7Ü.¸]Ø»=n{\ZUZUZUBJBJBÊäüÉù“óõ«õ«õ«=La¦0SŠT¤*:ýwíéþ*|Æg(â”ó62ÍÝš»5w yò0äahFhFhF¨z¨z¨:¯A   N N NõXè±Ðc¡}û:öuLMMµ ­uD>j;¯Èà#Ïð{’<¿F¨U諨Mf{ä˾†Ë5¼äöÔôŸ-;y£"ê(¥)ÓÇyÎ|: ¼ñ¾ »‚9AV¢'ÂÑZPÿ—Æ~ªP…Â<£0 £X=VU8š0a6bMõšê5ÕwGÝuwTB»„v í"3#3#3U‡¨QUøé1LSñÍZ*døûÁš’S_]ñ¦0aï½ßQ:wýÀ{²:3Jûn­ô™ñ°_VËÍNm')Ú«³¤Ÿ0n¿9Ê^p·…-lÉx2žŒwÞá¼ÃyG¸G¸G¸G`·ÀnÝx½O'ŸN>¬[¶:Ì?´H3ÒŒ4û5TÝ®º]u{‡äÉ’Ï8<ãðŒ‡'žxxârÅå÷—ß3æÆ˜ÚœÖp­áßüì0ôÍïu²×É‹.Û_lŸÞ"=4=ôTö©ìSÙmüÚøµñSŽWCf“Ùdö7:!A3$ ð÷æ-Þâ-JO_O_O?Ü/Ü/Ü/8#8#8#Ä:Ä:Ä:øeðËà—Žû÷;î7½hzÑô¢ÆX±cÙ(6Šú™>ù$Jë°ëi•Z ZÀîpW¼ü÷kË%Ä£¹M:! QˆF³Snó“ÛšQš”çOi’Jì–ëW&t^ª~_Õ[ô‰B}²žxÿ&µüÙ*™;’»ä.¹Ë—5whîÐÜ1þËø/ã¿$W$W$W¤%¦%¦%Æ'Å'Å'ÙÙÙñ-™ÇÌcæ1à‡ozø{Àl%ãˆbr]ï7Ëå0ÇqÀÃÚý3N÷/³œÝyÀÊnw<~pPãÛ°3I9Y$Œ›Àï5A•¬!çaæñºñ)ñ)ñ©F²F²F²°aÂ:H/J/J/65njÜÔ8pyàòÀ宕®•®•¼ˆï`à`à``kjkjkjµÏjŸÕ>3©™ÔLj8ÆpŒáÃs†ç Ïi^Õ¼ªyU|F|F|Æ®]»3NÎ89ãäÍ‹·ôoéß+»;ûîì}MŽv=Úµ3 Ó€NaŽ&vš¸8t“t“ô^ì뷯ߦi¦F§F¯œ±r÷ÊÝöùöùö_Ùå!y$„„E ¿=- ð=PƒÔðE++«ˆÙ³#f¯^¼"ävÈíÛ¡ö¡ö¡öd"™H&þL9ÈA1!&ÄÛ° Û`s˜+¾ýß ¦¼yÌ´€3;žÙôÕ˜v’yÏãÞy”&ž+˽!Šª—=ôèô!ãëUZê^TœH[pøšaƒWNüg(EŒ!ÉErQùËεk;×^®¼\y¹òÞÈ{#ïÜsqÏÅ=]‹\‹\‹¿ò'þÄŸ4&Ic¥óLhþ’|»m´©ô9?Ï‹V:Ô„pY\}éX‚WìÆ“9¨ÕLE.j8Xâ ̤Â8 üpàÀ)–Ú)˜‚)$ŽÄ‘¸Ú6µmjÛTž¨nán‘•d%YI>’ä#ÙJ¶’­ä=yOÞóº|y•¼J^%7’ɸ.…K)¿Y~³üæIד®']óêiÆ<`ê’Îcèhå~þÃ3)A JxÅ mF›Ñf¤!iHžð<,>,>,þÐîC»íbîÄ܉¹ã¼Àyó‚%–4ZÒhddäxâñÄã‰|g$ä‘>d|Èøz‡êªwèü€Pm\m\mLòI>ɧNÔ‰:¡Å(æ³(Ž" ðWŒÅ}ìåË^V¦–UËg´ê›\ã4óo#*[8rÈ©»¥žËø6¢tf))6šþ0x›N€©†©†©†“““õ{ë÷Öïí-ì-ì-ômômômþ>§a¦‰ÜDn"7Iª$U’ª‘ ‘ ‘ ³Jg•Î*S¹¹¦¹¦v”fC͆ƒOONšœôö1¥”&¦W¯­^ûÌRJOÖ¾}ÿö=Æ` ¦0s˜Œ"”…]@@@á"yGqÐ ôÞë½×{t+èVЭ0Û0Û0[—–.-]Z"ˆPüŠ·Sÿ=¹Ð…)e“âK °o;íBD¥‰9±ñ”ÞvÁõ+¿tQÓ¡úPÜ !ZØŒ"œE¤¢‡ßÎ EÙÄ…Ï×1™ÆLã+TUU£Ô£Ô£Ô×%®K\—¦—¦—¦·R}¥úJuk?k?k?¾%#a$ŒÁþ1ë«^à/°„(³·¿ÆX-š[¡VUÀ½æ¶ÒWdNôÁ’%$G#N4‚éˆ!#àLÌAÁXFàwÃ|*ÿTþ©OñOQuPç›–1ˆAŒbË•wØâ#Äóöå|¶Â÷x÷ˆ(ƒ 2ÈÉÉU£Š0(~VÒ¯¤ÖÒtGn½œ97jžUVVV2æ(FqÉÉÒ®¥]¿ÄæÉ?'¬Æjzœž§ç%ÛVï~q9òO…¤BR!‘7–7–7æERµ×j¯Õ^ã^à…·ç÷‰ˆ¢ °p‚5 ØL>±’Ÿç’é²—Û-qwÛÛ"Úy ׬6RÞ²4¼|bM×áñˬ¯¨•®*®ÝA^!ð†Zb°Â2^ùo¤½æ÷]yñ½5¨áæps¸9|¨ßš75ojÞ¬¸½âöŠÛŸg}žõyÖÀF liîkîkîÿ9þsüç××Wæsˆ9Ämá¶p[0“1YŠ—×Á ü©‰GK(ÞDµU$Ź%¥Sz7¬>1£m߉”.‘ëñƒJËy¾Ý¡ hˆg0wˆþß %6Q#jDÌ!sÈÒŸô'ýI<‰'ñxˆ‡x¨h¯hì§ðB<Ÿ¯=Ú£=ÆaÆ)Ü¿®ã:®# ÙÈy‹,DÈF9ÊŠú.ô}+z[ÿmývªí굫‡qø?°ÙìGÁùI@@àgàó¤ÖG}Ôç³>û®ó]ç».Ì2Ì2Ì2ˆ b‚Ñ<Ñ<‘Âô›Ì ¿bˆ¾>ÇS² gz'MÅ%ÎçÇŽì!?Ã&ÊU6ÿv»þ³#¶:Iù6l+f&™XAêPýCB.*ïgÞÇ}ÜWŽæ°/`_À¾CƇŒßít·ÓÝN—_~|ùqÇt| øÕ>ìÃ>Þꛞ…5\àOÍ`x ™¤"go0ï²LèÒ#ªvÑLÇ~z”.š:$wÛâŽ'‚Í·«+é‹w„@x ƒ'ðýÀƲ±l,_^°{Á’KÞÚ¼©}SÛ¶EÛmIØ<6ÍÆJ@@àáõ»×í®Û]·Ks¤9Òœ&M<šxhUiUiU)ZÄ@ üMÎAI,%š¸‹ ¸ŠUh«õF=E¥ÝÝ›6öœBém³èrJ“übomˆµ‘>GŽc,«Á´"]°3ÐòO1žHð5Ý*¬Â*’D’H_a1Àb€Å€õnëÝÖ»¥Æ¤Æ¤Æ$&$&$& £Ãè0Êp Ç(ö˜&…IQ(z~!7¶€ÀÅ·QÉMŽ~À d•¶®½'¿ÀœÇ],¸Îô€ÖcÕÉ*†Ø†‹HäÊi>\Ð ¤aø>àµ/üf·t¡‹öƒ1È#&Ä“±;`Ø(Úü~%)CÊx±<´<´<[°[xUõËê—Õ/+ÚûÁïë~øÿ>Í+ìFæ,£E\q÷ Yx`è¼€FžC\&˜_àD´¥=×ÈMž6uËÚ¤«Ø‚u8Ç™s?PgôÀ,œU¸´þ±ðvüØŽÆhŒ¦~Ôú1ÙáÌð¬mYÛ²¶EmŽÚµùÐC7Ý`Ø6`ð„ÁOX®·\o¹ž…—…—…çËùr¾ŒcÄ)ÿ)¹Æ “WàåÛ-­*ȾZ¤QO*Åòòžµä“Ér•Lè8ZO«±d’Цø†¸¸MmFmum)é‹Þp¬Ü¾ ”m+Kñ_PŠBBdÈG6²‘Ld ¬¿¿’ð‚`ªPU1³bfÅL\À\`j˜¦FÃAÃAÃAá–ʧXúߢ5ˆQŽJÔ2*Ì|òQÌ=¥½ú.hnì8`DßN}Üåç*'ÔæVMãšrû†§,mwE=¯êKËJc¦/cHq[9;:óðñ·[~A·ž[Ï­çÅ÷ªFUª-Æb,FFmFmFmä‰È‘'õõõ¬ü­ü­üggÎΜ™Þ/½_z?Òˆ4"øNô}A_(²±V ÂDøýùöݱ²¯Zwù3ªE;—xÖÌ“ !OI6ÜDz_ó…d¯8@M"*dïC €ÎpC=a(þ3Ê•/*_D/Ð ôCÆ1êOÕŸª?E! QH<ˆñøŸŒ·h/G%jÉ|ÒÇ8kî)½ìn'5\´¼íèÍMÆRoy{Ú‹m¡ÚBÔtÎúÍ­ÍE÷å³Ë˜#d·ƒkD+Á‚ù8òO7 ¼øÎ;˜2`Àðâ;€>wÇñññÄ–[Nl™¡‘¡‘¡a£j£j£ºh좱‹Æ¶éئc›Žô(=Jò"»"q/²ÿ>îÂ?áÿ îµ_o?º–ÊiÛ’ëÕ_jýáL¾ý]Á}Ò¼¨b#¾¬:E+ŠC 8Pt& a+ ¥€€€€€À¿A9ÊQÎ놫U/ª^$“‡ÉÃà7¸©ÌR™¥2‹7ÿ þÔŸú+Ì6þ{j!G>“<…b¨j;«oP غo‚~ÓúNzÔs˜lÕÕ¢GV\êûÜfQ£}‡îª3<Æd9Ç]¦'± çð¸¿DP9ÞÐ…w` @è$:‰NbuXV'U=U=U=Ê$Ê$ÊäZص°ka†ç ÏžŸxf♉gb½b½b½Ô¨-P[À'Îc:1˜N ÷b!ˆ¤ÀïÈ·‚{d?f¦œ)Š£ªN×GòÉTq—a¤.·=Um#zËÞãDš£,„¡ø7ÈB²xݰü„ü„üDÅœŠ9s„ ‰“ÅÉâdÉ É É œÇyœG[´EÛÿꈺЄ«…Pfñ&§éq*ÇðE놿 Œö2t)5ç¸R¹Œ«÷l쫟sFÝ_azí)¦aš`&éÄa:û¿–,—7OÚƒ=Ø#§r*§¤šT“êìnÙݲ»M š45èÀºë¬cÕYuV½GfÌ™stæèÌÑ1iiÒÒ¤%w„;Âa™D&¾ð…¯"•ž`/ð»ðÿ÷ZȰf CJæTOªÑCÊp‰›OOQ#õ—*cÙ몥¢jæªâWmЀ‚»€€€€€À¿CrÃÇB‘¨ì[Ù·²/ $$Pü@ü@ü@â(q”8*„Âfh†fÿá±xQû ÊPÍÌ!ö8"ŸÊõ¤ã»¦‡Ü®×ixP§§îïj÷VÅÉÖ+z³Ææ¯t»æðigáÔŠîìv¦šXÒa4 ­æ1µÿðˆû‹¡œµµ¨¥*¡Ò‰t"*ÏUž«<·xÇâ‹w,Î]œ»8·È±È±È1<><><>Þ9Þ9ÞÙÕÁÕÁÕ³ål9[æ)ó”yªÈ"8° ü.üÁ½µd=z µ¨AmQ½Êþ5KÑuÅËŸ1“§n§òLÅHm—Ä[Ò¶p‚à úÂdø7à5î+±+i5­¦Õ¼àˆ>èƒ>â8qœ8Nu©êRÕ¥¼PHz’ž¤ç¿}~½2pL9*.—Ž‚™}¨…žÎá¥÷Fâ¦Ö.ææ‰{ª.6Ù³2uÖ¥½iµïç3Ém"–7á>Ó»ŠÞäó˜_C%*QÉ[«Ó#ô=BTˆ QáõñGUŽªU™8}âô‰ÓŸ§?OžîÒÓ¥§KÏE›m^´¹}aûÂö…\)WÊ•òQöÉ=rÜÄwßšŸšÊȰvó¥ÊÏV$â@Å¥Gæn©ê—öÚÕùåƒk—ÙôcF’I˜Ê¼!¸]¨0€6T!Š`ï% ðOÈG>òÉZ²–¬å-°+#*#*#¨)5¥¦l›Ä&IîJîJîB ZÐB&2‘©H÷ëC†t! Ö¡“†’âClØZÛ˜™a;-Ìßëž`æŠ Sp¥ áú­©7¶Ø%u%+‰'ÎqSé Ú »q Ïÿ¶q²øÐ½ 0´†ÖÐ^ƒN(¡„Þmv·ÙÝfc¹±ÜXîÆCn 1J7J7JŸP4¡hBQÔʨ•Q+EN"'‘õ¤žÔ“Ä b)Äwþª Æþ§üœÆ½±"A|E®˜ÓxZzÉûcØÑ¼yv„Ý)yÜøxøˆ}§ôOãbiô”ýÀõ¥nà`;ÜÇfôb2g² %¤c¢Ñ?“&±€€€€Àw}@мvMHMHMˆ¬@V +€4 ¡Z¢Z¢Z‚R”¢”6¥MiSÃÆÿ¢gþËÇV¯A-äįÈLn5¡¯§äöÛhJÓÍþóꎔ‡Ê^r»>UçÍ/³<´¢ÿµs23¹/—F¢ÑNpÇ ìþÑ¢ýï÷™µy!{æaoBÃ0LA®n®n®î¸öãÚk¿ÅþûWpù\>—ß»¦wMïšù]çwßÕ8Â8Â8‚ÛÂmá¶|’OòÑMÐDßFp`øMP‡ ÄŒ?;€ÆW4#Ý;x>W¡”Ò„.”Rš\D)¥ÏÜ(¥4rOçyæÕ»fñB'ðŸwÌ,&ÄNÔ‹mA>1~ä(ªpKÐAñ5+ˆò%Ø(6ŠâË rä,Èy«ýVû­vÛcmµ=¦h“Ãæ°9ÂX ü NàNðwÍΚ5;ûÿàÿƒÿáîáîáî® ]º6$+È ²BÑžwˆüç(=U™-¤ŠØñåö‡­lÏË,®OûL¾ñÚš±jú\¯‰òk4°Øn©¢ý;Æ´€:$Aö;4ùø‰¡ËO-_Ú´/h_p©ôRé¥Ò{‡ï¾wx_·}Ýöuóûì÷Ùï3ßF!¾óÙ=x4  aÊ üwÓS™ Ô {P*|Eñ³’J»ˆ“ä¥r±fµ[•¿¸›¼DnVþ²úaÅ”Uec…TÞë¸éIS÷Ó·˜öŠ\—sDº­Ç«°ç¶õçXè&ë,׸®’Χ4C¶G~ŽšrI´#TÑãpŒ9ʨrtD©ƒç˜Ž;XîèŠPÔ‡âßPÁ^@@@@àïÇ9œÃ9^ã^Õ¤ªIU“Z‡Z‡Z¼Æk¼Vm§ÚNµÁF° ùѦ0ýÅÞx-»(3Œ<"º\ íFÕìîX8é<^5:Æ6l#s™C²˜!ª·DK–YïUM­>Þñ¶NF,«Á´&ݸV\1½ƒ TCäQ'ÔÿeV1Ä+*~Àøì'ûÉþãÇ ŽL7uÜÔqo>½ùôæSƒš5 jæšÍ5›kÖqXÇa‡QCjH as˜“v¤i§Ê(,ÿ€Ÿ{“–Ö|‘ güÙµ4…ÕbsåëT¢Áô0üé{4Àlø`8ö“—Ø…¾"Ë’›l¦'éCBQ†¥Ð‚ú×— ÁäF@@@@à/¯q_…UX%--];¬vXí0šL“i²ZZZèèèB 4‡9̦^ä@A‘€Õ膤7¼ˆ1ÉÁÚ%aÃ_³Ì1 Ñ^‹ýl£ž&zXœ¥3gÉΉ)WÉ¢­¸´ã- „p| 'U¨Bc0chÍ ÌTf*35e}Êú”õQvQvQvׯ^ÔÙ¤³IgSì¥ØK±—¢R£R£RUת®U]KOÐôbR‘ —7¡9 ü÷0÷ÙÞl¾ìº"Ô.ƒ–^)Ý}\T›ÿüaPYZñ¦[ïòú|R?¿vuöàå¹6'nGæV2_ŒÖ¡ôúë±Ö”&ÄF›Pšx%¦;¥I÷b«)Mý<žRzË"úè§1Ç–Õ}¼}ûÒ>ÑÛÂ':6Íïâ2¸^OËH£1š«4djb±Û/›h,Û‹”°zL{Ò¸#óa sèÀ:Pœb~Sÿ-Äœ˜sÞ”¢J•*Ò*i•´JÚZÚZÚZç±ÎcÇŠ¦ÑˆFôÏt!þ‡Y 3‡d…pëÑÕÓÓÒ£˜-ÜæëO£HA۳̈·Þ§ M&7Lo’D¾špJ±_¼HJ¾"—ä’\¾¬ê¢ê¢ê·;nwÜîämÉÛ’·¥I’:d¥ÁJƒ•µµµŠ^ˬeÖÂ.pù¦g_ÁÏ½ç­æJ¸£|±øÅ“Wé;Õ_Î“Ž°µÉ”¬gYæ¦ø¨lÍÝ4IF»i=¿=fÍš ŠQŒâo 9x¾ÆV—ƒcž0 HsΙ³ ‚#ÜêYÄÌ=´g€%µ“äE„ŠƒÙ}®¯~vs^Z›ú¹)lE†ÈÏs-ènEo•|¨¿?¼Žœ²5¡ MjBM¨ ‘‘U‰ªDU¢øÞñ½ã{¿É|“ù&sD“MF4 ª ª ª²Š°Š°Š˜›37gnÎ=³{f÷̈ñ"^h‡vhÇëãÚw>d•Ÿ  Mh¢ U¨RÄú.ù9Á}?žÓ,€ie‰ì¶Ü¾l`­ü–i3µ*ÃÑMðÜð´FcÕ¬¢™ŸÇ|Ú—z%ÿm^½õ2ß¹i˜Ü5ë¦ë¥›®·ÌÌHo€$Î2ß L<¥nW£q’wvN¦Ôo;޳8¡Vc?ÎÔR­ŸØME`˜è£%ê«þY²Á¥¯ÓNÓ|4lhvà<é‰/1ù!域~T¸çѧŒŠ|¯äŽO|2¸UóP”5ìUÚÇ7_V°™6ã ¾Îö1¬3– 'È6¹Rn̹õ´ˆöƒ6ZbƒÒ;®p‹üðÏŸx¼ÐVݵºkuWJ(¡„,'ËÉrµ7joÔÞ(L,”+”,ÚÉs2÷h(7šž0Õ?©¾~Ó½q'ÂO¨‹$ᢄŠ3Ø­›V¿o¸y÷Y‡'›™fä,¨ü 7˜ê"_P©x& ÏÃ_s½ÊP†2EIQ‘B Ø‰ØyÔæ¨ÍQ›­>´úÐ*N#N#N£~Jý”ú)‹‚/ ^ßc}õ=Žì;²ïÈ>ÜÅ]Ü%7ÉMr“Ó`¬ˆ?Ëïß3¼'ÿšzGq”L&“Éd„ !4’FÒH¸Â® C&^ ÿøÁΦW‘Žé¨ Q©Mu™y¡¼òUu)¦ëE¨_…œ[D‹Mdš­Õ®1Û˜˜¸0®.7¦EÈ_YÞª¤Wá½1z¶zöÕ3ÌžX².ºªmŸ.Îü,ÞÂÆ2 Ô:‰Û“‹FþÚ†â ]LÚ²ž¶'Œº‹ã<µì£1Üâ³ažFo³e&ãtBÕFâMºnÆ 4'7†q¹æþÆð(·ªìP•W»¢l`e÷Z’)þ„’‘7uøe½¾q2=äcÏÇšo“ VlñÙ¬,«´nÅÜšõH°ÀQ{l`Rsâ‡Vt"=N;c:ÎйtR°§ð›p ð¹(UˆöÂ2& ðÛqq‘/–5+kVÖŒëÃõáú°íÙöl{-5-5-5” %ø‚/øòXÓapÀ'¡œîÄk¼ýáì˜E!›ë_µl˜pUôfªÓƒø¬Fo˜r»!É%ÑxEwaŽc<>¡DPaý‡ðãÏ‚KåTN娂-ØÂz°¬Gê™Ô3©g¢Ó£Ó£Ó'<˜ð`ƒÀˆÀˆÀˆ˜Þ1½cz[eYeYe­­­UWW“äyA¥TJ¥ÈCòâûO÷Xþ®ð¯¦p€ŸÖ ½Ñ½ŠP„*¦çs<Çs¬Çz¬W¼Ä~7"û/B¬±‹ø²XUôLTx!sÀë–ãhå|ÇAM¸˜Yãû?ÞÐežØŽõ`Ž£ :£ñ%š?wÆLÒßðó{§Ì&ùM®4Y:^j!ýX/èL“+~í’ƒe®¹žË}ÕÛW¿aýYÁ±žŸìEU[ìrÂÒ+‘+ƒÄß¶C£’ÙçGêQšnQi·s§"OÞr^Õ­ËîÕÆc…jjØò™óh··ö ´Õr$ƒDêÿ|Ø!Ì22“Åì&‹ÈÒ wÐÁ°ýúµ`ÿ÷½#ظ ü±€,x7£Ëè2ºþíüÛù· kÖ>¬}ã´ÆiÓˆ±#v ƒkXÃÆÐ…:Û–™Eâønb|»šz†Pšt'N"·¼n:ö@ñÞó]FJ<ìì—Yñm˜çŒ=i¬8®`Ñþ¿BÙNF‘Œ  .R©‹b¢b¢b¢û$öIì“Z“Z“Z³¼ryåòJ«ÎV­:+~êÌ83΄APüöo^y¬€¼Á¼ÁxŒÇøŸ6×:§uNëœ}©}©}©}[û¶öm , , , \Æe\þ~&ÚÏiÜ`7N1¯‰NÕî–5”…ç.}V> #Ù·L]y»šÇðÑ+S9*’3ÙÈÁCdÀíéê‡†ÈÆGX¡:  `ƒü3 gä_+XP¸XË[ËZKdac¡oktÞ(ÓxŠÆUµÁ*þšíÕzŠ¥ô½ÞiÍzÅëÊò*—^Xðìbþ”W“ïML"uk^˜\×å$c< òMuC'{ܵêìášiq¥Ž‹‰¿VœV´º±ÊP¦™:«R¨¹ß`–†<œFu çÔm TªÕ^ÎûP8´|Iñ²ÁÕ-Ÿç½ŸR´ùF؃zÝ®—ßOû˜–Q’ݬxÅ—ñe}«[ÊÇs1t¦b8fÛ’™D&á£gE×RWº‚æ¢7®á>²P‚rÔ ¨ôÿ65¨A ¯óæ“øTv¬ìXÙQ­ƒZµl$ÉFª>T}¨ú°R£R£R}уIvÊWpN4Þk]ýBãu3 ¼mÜLž_]*sg?¨´­Ÿ±¦èæ¦û¯£?÷eôÉ |âpQÔT‘V©²ï0àão²<Q$cšAf³*fUÌZ¶bÙŠe+2Wf®Ì\éééJCi(µÔ´Ô´Ô\^½¼zyu¢$Q’(aü?Æ»Ì]æ.#áç#ý+æÉ_~ˆ×‘7Fc4æ `` KX¶_Õ£ìöû@ÇAÇAÇÁ¬Ð¬Ð¬PïžÞ=½{’Ç’Ç’Ç-‰–D+ãPÆ¡ŒCþþþ$•¤’Ôïg»èçlÜà<ÙQä2Ó“s£a\iѪŠ÷U‰É80%¡z´öFvžhK˜…ÕQrp€!T!F²ÅÇ:…ô ‡÷x÷üE*M+}Wšý<í9^¨¼7xÿðÃ0‹MŸ,–Í220Z¤æ¤vHí¬ÎM+Õzrí :»Û…Xêå%}6/°x³ Óç½Ý‘N7 ^ûYqcËkÅÉÖ³µœ¦» p³ Ìwûª953ržd3HWýõVõŽ74ÍÔ ¨í6¶2¬c¼C±¢ì¼ ·y¬n÷ÿ@_gvËéXü)ñäãQ9ç“Ö>=”Óçqÿ7I7žxg^X'·G©ˆÂY,øcÕÁ°'É66“WØKQô¦Ûh)õÁtà œF-ä ?nD üªQj†èŒÎè\á[á[᫬¬Ìö`{°=Ô/¨ŸW?[I*I%aÖ‘–$›+¡ïi/õɪA¢Àµ¶Ñ·¤Ë´Œ´–K†’7¬*óà¨û¥Ï­¸t¤KúvÓŠ,•wåd4Pƒe¨D­0ðÿcxù‘7qQ Tè,:‹ÎR8SÖ¢µGÕŽªUË^™½2{åè½£÷ŽÞë8×q®ãÜÙV³­f[­5]kºÖôèæ£›nÆflÆf²‰l"›è:„QåÏì |nF0‚º£;ºÃŽpÄb,ÆbÜÄMÜTÌöáŽá:Þ:Þ:ÞzMõšê55Ñ1Ñ1ÑÑ<¦yLó{”=Ê•_”_”_„¼à¥‡šŠT¤*Žøý˜øyÁ½2p¸Š px’²PYyJ¸;ô6<1ç˜ ä4‰3nª­±ë- R‹Yh‹&˜ƒkHWôÃÛáÕAÔQ8 Ä@ D&2‘Y±¡bCņWx…Wø8ðc¿½Mìù²ñ‹Õ—)¹»?½ÈµÎyõÉôÓˆW·>Îùâÿ ñÛÃS¨öTé,rv¶bt¨ËÊKï~ãÓÎffCŠÌpH¶Ú¦×Zwæm ‹S¢ULS@’κÛ°é`pÖuÆõD;'W—ªWEÆ‘¯¿d½ùöjÌÇ‹_tSû?—ä^¼iõðb–GZÉó©¹gªíjÕä×é1 „P@[qSÌÄDöëÍ| t'uåJ¸ñÔœ~;*¶&éï>^xWtEWlÅVl­*«*«*ヲ§ÙÓìiÕªÙªyüsƒŒ!uÈ-hцôS|ÏAº>¥îE–÷Ð@vPžû*þíúB‡ÈãËÛ]‹‘s ]Ä“UÈÃ|ŒF¬|ðw‚׎óšr^Ó<s0‡1eLÓä±Éc“Ǿ‰|ù&rê멯§¾ö;ëwÖïlœUœUœUÝuÖ¸Ön­ÝZ»Ê!•C*‡°!l"¿)¿)¿©èŸ(båýñb«²ÇŸ Œ×¦ón£ð€‡rsÉlÉlÉlãCƇŒé/Ò_¤¿HïÞ½*¥*¥*¥r¹‹Ü¥t{éöÒí¹+rWä®(é_Ò¿¤¿è±è±è1ŸE¸¢wEïŠÞ|o´”–ÒRaºA4MÞò娸àóîk(]`3D³&~F³¾n5Á3¥ýV4¹o¿Îj‰bþœA%Õ¥å€€ÏøŒÏÊMÄÍÅÍÅÍ­¯[_·¾îËú²¾¬ô¼ô¼ô¼TUª*U•n“n•n Í Í ýèóÄç¾O¢Ål óDuU5?U÷îœ ™&ÞÂ6ÕߨũºH¥žFVsêîwèÊ¢åVÞÚí_2€«zéíhJï<÷„Ò;Ïǽ¥4eË8GJïÔ·ŒÒ[7¢*Ç\̵ýãÁÃk?²cvnk‹Q¯:NrWñ™áhjrÁô‹~²zñ/ÀFL\²ïI41ÁNTã2F#‘† Ì ­tC üIlÜþÇðvÌ—p —ø £^F½Œz… 6*\5\.±?gÜ~Öa<ÚðmÝnyÞy¥·cbêÉz\+»°2ôÒÞÑ*Á©n^ ù6ä.éó£nRðÑú£øÉ˳€YÀ(vñUžª }úDº]º]ºÝ7Ù7Ù7Ùæ´ÍQ›½ª½Tõ$Ç  Œ?éwÒèâÚ??) CÃiÕmÒýOØjNß÷‚¯î1Ñ\ÇÖ¯ß×?xl ¥ =cSšT'ö¥I-cÓ)MJŠ3£4)66‡ÒäÍq[)½QõñÉ™!}.ïõž–Ù"x¼Iâu,Ìßó²ÕjmõL•¦ÿbÌÇ0kÈ\v9s”,'HÜEG4°àþéîApø-¸‹»¸Ëµ[j·Ôn2‘LF ’1ÿg®Bcf$‰f÷37ÈFr—ôE¡œPfд tóÀÝ!î¿°x]¦Z¡Z¡Z¡_¹_µ ß>:ÜÓ}µ‡†Ç~MmõÆ’W)Ö=éöŒÒ„º1ç)Mž7éÄ®y7Ûìf2_Ò“ a&’hÒo1KÑ³ð¤ø³¡+f¶aÓ˜iÌ(¢ýxßô¾é}sÿ™ýgöŸI·H·H·¸¼ãòŽË;ºLë2­Ë4ånH?ÒôSü¡ãÿ¿ÖùÞxk bCÄDLÄ?m®Ú[µ·joËDËDËDÏsžç<Ï5©hRѤ"¢wDïˆÞÒiŒ4Æg‡ÏŸ¶}mûÚöåÅ=2ŸÌ'ßJ>û°û01Q! ê@:ÂdùU0ÓÉXRŸ/”ØX(¾5•öÙ#˜¹¸Ÿ¥s+iÍòk&óU¼å°$ôý_XiÓ§ º  ±$–Äò§ ¯^7¼î2Ûe¶Ëì&Ó›Lo2=Ì'Ì'Ì'ônèÝÐ»ÒæÒæÒæA³‚fͲßb¿Å~‹¦³¦³¦ó7]ð ‡Óp'H YHÀÞdžÝ¢æly÷ÏOSÏ]³J²¾%ãûÁfÆÜÁƒŠü™ÓÖ Eí,_îߣÝ/Ò¹Q{(½S6.ŸÒäqë)M7‘Ò¤)±_(½Ý1F—Ò5Q™o?ï1Ðk¯Ë´5- Çèvòwï&äQme`:]‡zÑ/Þ0&çI+\gö1 I2éŽdœÂB´ƒìK´°Tÿë­ ¸ üô@ô1ļ\ç9Õó’çÆæ§›ŸkîòØÓÂçÊò¡cç4«Giˆ˜sÜ®7¢Îçè½5dSýÖVbݾò™Äâ…¢OAdÿ3£¬-Ž@"ØÑìhv4_aqÁâ‚Å…E¹‹rå¦ÎI“:'qOâžÄ=±¦±¦±¦jÕ:ªuä[2Ý™îLw8Ã_åœ_/Ä+ëÔÝà7Eˆ‘(D!ê§ÍÅÞbo±·áYó†g—:.u\lll~3üføÍfëš­k¶ÎßÕßÕßÕá’Ã%‡K†ï ß¾cv2;™?stÞ»c5Vcµ"¼ãOÏJàW]ÇÄYP‡"ç³B£aŸ·MZÕK“óœeÝ/žÖÎËtcEqÛSøöì*R@¦ü&ͯ^Ñæ4|p~%t5t5t5œú;õwꜜœ **ÊkâÃ:„uëð$àIÀ§h§h§hí%ÚK´—ü̱x‡Z¸À/±ýÉ%Ò·² E$Šc®c%ºüÒÉÚX›†h‡Ïò:jÅOé‘èvòÕ|YÛáyýW½Gý¯¿‹2§ô¶]t-¥ÉFq-)½³yÜ JS—¡4ÍküÊG­|T»½A»c׿žkã3¥[ï<Iµë ÕÛ*{Ù½¿xÕ$¸(Q{ñ`m˜^¤/ÑCúHŒ"Ëžp+ü·SRÜ~ ¼á /å Çt‡™õ77ê×èQãmSÛ<ÛÔ˜ë%øjîÁÕ ‘]9÷›^ÑIØÀ»Ö|{&ÿÑ€ø(ðçç'Ofò<$ù²ÊI•“*'G{Œöí‘”‘”‘”‘Ú;µwjïå6Ëm–ÛXž° ¾ëþäºv-*I=êu7Ê6p½aq¹a¶­Žáš§êë×5¯g¸K£‡¾›¡“F}Õ!5.5„~±zTÃçf3Û‡4Ya´*¿êy­má’÷U*)·ž&|Út}xú‰\ÊÍgg?Ý|_•Û¥”äX4)_!Ó“u1¿`À¬ EĆŽÂ z3° w°˜îC]‹ãx€ƒ¸†—¸Œ»x/D¹ø]ùGœ1Àj¨b7³ÓY†>åZË«4n­19èâ§ßhT®Å`“Ïå»ô¼%{ÙpF¯vÍêðÕSDK¿­q­Ãt%äÞÜÚ ”¢â/óû{C9œ4 A]©+u%±$–ÄÖ ­Z3tÕ§UŸV}ÊZ—µ.kÝðžÃ{ïjjjiagaga·ôÔÒSKO¥´Ii“Ò†éÏôgúsé\:—®Ðèó/¼|4@ÔC=ÔC‚„‘‰‘ŠS¸‹»¸«V¦V¦V¦Ÿ¤Ÿ¤ŸdòÉä“É'mV›Õf%êu‰º¬§¬§¬gÑ¢¢EE‹ c c cs5s5s5+NVœ¬8IûÑ~ô«éÎK¼ÄKd#Ùè…^è…ƒ8ˆƒJQõ‰ãˆ?ì`‰\L@wFL6’þ/wMîÔ”Ò9¤”.˜?xÓ‡>&M‡òÍEjŒ ™]¨ÿoNÊï¦üÛ¡’C2êÇÔ©³]n»Üvy€M€M€ô’ô’ôRèÃЇ¡¥[¥[¥[C;…v íäúÄõ‰ëÃDÃDß‹ó Ÿðé÷Yþ”FO`>Ú2.d7ÊØ Ìy²šñ%‡ÿU^Õ'*/Ù"ÿ¹ ÍnDZ·«qµI2nlx—{u7-è)w¹¦5ÖÒd³¸Ž”&]ŠÓ¡4ùZÜaJ“÷Ä­¥4E6n$¥7ëEÉŸ”ìÝçÙ¾ÖÓO·¸4á\Oïaás¼N×±×®Ô˜®²ã_<5ÂÉYBDV¬%¹ËÌ$ˆR±=¾y¨(!hÜþ+þ‘¦G3˜¼!. !£qÈ!¾~nÀÎfÛƒ²ïPJiÂ(ùlJÓ](¥ô@ð=;ùÚsTöÌz&¹J& ì†öo‚²¡ /øV¢•|…;çιs{<÷xîñ¼ßï~¿ûý.§]¾ù~‡;.u¸ôcçqž­e‹²Ùç¢QÛ]. ÿ™C‹‚EÁ&–&–&–N>N>N>A{‚öíiú¬é³¦Ïšš55kjð)àSÀ§úï뿯ÿÞð‘á#ÃGŒ+ãʸþÌ™ó>Šë±ëùDœßÌyß|mÉDÎðå¤7ÃÅm»Qùœ‹Ò(÷aP£„©C^´ö!k˜:Ìp|F8ã&Æ¡ÿp¢¼Þ&0A´Aä!yÊM$·$·$·¬3­3­3ol¼±ñF©ÔGê#í.í.í.夜”kò²ÉË&/=k¼êÊÕȯÿàrNýœ Í}•)~,Äû;Á(}`0fŒcÆi0Ä`ˆÁøÂøÂøÂ´Öiþiþ‰Ë%>3vt»Ñí˜Û?ß%)#i$Mk¼Öl­Ùö‡ìØð]ä»ÈwQ¸f¸f¸fó}Í÷5ß¼1xcðF>üº™ª™ª™ªä”ä”äÔÏtwWq-Ñ-r‘`úò‡Á‚!Çð ;a3Ÿ½4`BË…”Î)PFåsí¼|pa”¬Ãk] õ/j±Š 1 ¯qò>se1z6a.â".*7Ù‹ìEöV{¬öXíñzèõÐë¡´´´tžtžtž´­´­´mhEhEh…·¾·¾·¾™™™™™™Š¥Š¥Ê·n²¼#Ñ2,Ã2儽¿(ÊóµJ:l¢ŠŒcELsÒQ”Ìnb¬É b…_¶bÏ#“±Ë«Ä!ÆDc´oǦng7™Ó 7Kù¸¾C÷Íå»/ÌYLiªýøF”¦î߉Ò;7–Ò¤Ô¸º”Þ.IéÍëÑß~Þÿb ÿ¡¾³&·j<{ÇÀ ~-:4êl·«ožzÿBCO,ðS˜Õ¤”ÔeüÈT¼Ål„à V?.7ãwkApøUüd%$ˆ=ΓÒ§•ëëeX•^léB‹_XIéõÎC´>~Ê9~ûCòTJ)½S[;´úÌ‹¯(èÜ|eÑçšï<¨É…zZfVúeÿüôÙL9Éæ0%ä,É$‘x‚¥åæo¢¡w$?š:œÅ* MbG1ßDÚÖ¡!–\›z¡‹µëŽ& »@iò½¸K”Þ>û”Òk¹CUÞ¦¿O½^œt…kÇõI ª¹]íðB;Ã^yøìгƒø~Ø•¢I¢IÂÿÍù‰›)¹B®+Ê5Íç…} ûrabò¹äsÏ (¥ôÍiJ)}×™RJ_Ô£”ÒG[]muÕ¿µßV¿­ ê6ðkà§¿@þ‘ºH]ôm$xÞ>Zéc;Ø —âO²à¾ôrYàJçF ìÅ›U¯ß„ܰIo{›¸/±¼h²\1¯n“ˆô/0é¢!]¢Kt¿ùÇ“ñd¼AŠAŠAŠÛ:·unëšø7ñoâ6 l@Øi¨4Tú2ôeèKÿ\ÿ\ÿ\Ûž¶=m{ªQ;£væ›cÂ)œÂ  EÐI刭ÿ.¼Q ¿Á*…',Ès2؇Ì;rHt•]ËÿÒOÕ‚TŠYι¸î,ƒaÃ϶³ruÛi2¹Qó†÷¯m~ØË¤HzzîðJ“¤±9”¦6ßÒ”¢q])½siÜ}J“Ôb÷Ë"®ÆŽ9úåð™+#v%NY“Öµzþð!³ÔZnjÜÞ&¡ÞxËPÝAªÇTV±™?sxGØÁ” 'gÀ‘Ó¤%®‘&(Fÿ)åÓÝIºótÙίó¥NxF“—š/51³0 M†0E6¿7Ê’W-? ? 6a'°B;…Z„ZÈ^±lº¦4 ’¤"Ñ.Ñ®ì:9s&Ê.ɳåÙ‹X€ôDOÞj€n¡[èÌÁ̆ùÏÉ¿!¸çˆJWt0[åc¸Û´ŽF‰¸ZtGç䎘à&NØLZ¡,ÿôR–r¢-Ø‚-Ø…]Ø XÀ}Ñ}a kX/^8¼…(D–W–W–—E‹ ÇŽ3'Îg‹³%S%S%S-OZž´â3Ê„0g¼Rb°ƒÃh‘ÍDƒêc­#Å-¦Ñ*ÓÅþ¢fmv4µï9Á¯g¦÷›FÃ62ÝÈÏÊ´˜Ö•×È!Oüò8'gãìˆíç“§\~v"s€Þt$›Åê2ª\y&w²"­Ê³jôó/L^¨5}ÖtgÓŽeN¥N¥—Þ\þxù#q IC*§r*ˆìßüëÙlÀÞÞ›Å9rŽƒš8hbıfÍ›5/[V[[2¾X­Xãää*Z—_/¿Îx0ƒ™ÁPEC4DŠQ¬p*ýwå?éê¤d*Óz¤Ó¤º“飹ï¬Ì›.êÓ‰Ò͇H»åºÙ7áÛˆ:1mÈ¿ð¦Šò–ô ^fç§µšó4çiΫ§WO¯žž„„DØü°ùaó¥šRM©¦´—´—´WHbHbH¢ÛB·…n gÎ0œÝØÝßq+¶b«"?™²/öo±9ÅÛð↳L7Ò[t‹]ÏX‘ `á?ïÀUÛö„a¯(t¾äÑa«û„ÁMÛÞ^¹z@×¥£ÏˆÓœDÁnðbZ1­˜Vü—ýõ_ÔÑ˼—y/óVÌ]1wÅ\¶Û‡íCV“Õdµ"Q¼Àß•¯A¨Y°ð‡?ü•s‘¶¿ÞþvûÛ‰‰Á‰Á·:ßÒ¸¥#Šª‰ªiÔÜ;Ä;DäÇú³_ýÍ|á Wa8ÿºü+»RX©ò¢%ŸÐD#ŒNª‹ù"]¦FëŒè<€@ûÑ®ãÔ_t<”5ñ|U}èC_‘F8±ˆE5ªQ]6¥lJÙ”Wx…Wø8áã„LRLRLRÌDf"3‘ÚeµËj—™;ÌæŽA+ƒV­ô¦êMÕ›Z<µxjñÔ¬ì¬ì¬ì¼5ykòÖ` b â®lL“Æð„'f.5—šKMýMýMý³¤YÒ,)¹N®“ët]D ëÝßÞâ¼5¨á¯5§Â©p*ž ž ž £{î5ºéOzÇŽ«p¡4Cο.ÿJpÏGõWQ¯¸kåáê®Üzùgºl† †a=aŽîµ–’Pƒ*Tˆéˆ‡%ô (BÉ_xl”¾'x‚'x†gx¦ØNšŒÉ˜Œ¹˜‹¹•L%SÉd"™øØôcÓM̢̢͢Ì>˜}0û y\ó¸æqf$3’©×@¯^]©®TWj9Ér’å¤Aƒ>}Éø’ñ%£&¹&¹&üç§4Gs4çmñ±äù3©A jø×‰oÊÊ5U¨BÕ7åÊŸ|và¾ÐJ¸a-¼h–A†ZÔ ž¨  rœ4Ã5¦ s•0$Hײ€ÊAµóSñ¹HÅsäNßó!Ï zDe6›VWËlÎò&uÝVY, >à¦iéëlX÷˜­åQ£‡š9ú±†4Õö™o"3ÏÐ 1E{Ýåà^eÙ¬g“ðY •שL¨=žu3ß±ì~êýçÃso^Ú—öä]ßô¯Z}>ünk®géÎ/ ÊšU{É ßÆÀ(ÅxgÂÈpt)àN! o°šÁ:«pëpñy(,é(ç1mŽÆ¨Gîc úãL¹ÅEpô"Nhä:Ô¾IÇ;pþÇÚÿÖ¬¸­j»¨Ý(ì••¯¾w+L[qþð¡ÙÛÎn}¤]^]yµº Þ(Ø@f6Y%ïÅM§ý@p£}K”^£×è5~=ÿàúÁõƒëÇ‚ êt¯Ó½Nw›Ó6§mNgÕ˪—U™ÌLf&Ë©œÊ…•ìï¯eçEöýd?ÙOU¨ U±r³r³r›òfÊ›)oô·èoÑßr¾çùžç{9|äÈ‘#õKê—Ö/-èUи 1NÂ~˜JgШÀ,Ìõ¯Ë¿Ü‘ûUø®iÃÍ¥[ ÞWªÒM—1my²ü •©^}í;¨Ä9TɃ¹¡ô"jð °Wqço5Z¼ Ìk»çc>æc%Vb%6c36ób½l©l©lé‡K.}¸”ý"ûEö £¡FC†Z„Z„Z„êXèXèX3bFÌtwêîÔÝ©ç¢ç¢çRr³äfÉÍ¢9EsŠæpŸ¸OÜ'ö û…ý’{<÷xîñ’½%{Kö¢=Ú£=.à.üæÿ©=ìa¯HeÅ¿0´Fk´†7¼ˆ7ˆÓÁ;0ˆ¢%LcòÄ‘eL=²E4æÊYî,]WQÓ]îý ïPˆgoßu*t\ïs ‰'°ÖÇêIŒ¦º–Û 6´õêãÐÖ¤Ü%¹îÃf9u"õêǬÖHÄF¬–Æ{•ó¢:õ¡óQ­s}»;†Wzù·)n¨QôÅ·²ùƒy)ùë3d/)–Þ}ú""ïz‚ÅãÙ÷µ_eçµ®í.kÅ1pÿæ?s°Ö0d/3ÉN¼ÆGs™t(Õ£sè;tÇ' Rå¾#øUÈ[ 8’J†ã3é„:xÊåR'4¡(Ü;Õïe¦Ù»}g××½ö„9ÜV¯Ô¸%Êäøq½‡‘ïCòÖWþ°Æ÷ؤ”¤Ý]ŸYgoû¬WœƒmÀg±¡c¹L#¿ÍYÓÑ #F~GTù·vÆÜî w† &ƒÉà¬Y²d'f'f':uuêêÔÕFËFËF+¡"¡"¡‚.¦‹ébÄ!qÈ@­ê_¨@E!²o ÈNÃi¸Ö[­·Zo'wžÜyrgûrûrûò´óiçÓÎ/y¹äå’—ÆÆÆ¤éAz”¾.}Uú êP…*ŠQ„¢ÿpÇ^àOÿÜï#Å|±º¯\›++ê]Ý­ö¼ažÊ%UoPÎ…¶0Þ§IÕ&òšyIWS{.»1°òOYæòtç5ßC0C u¨+¢œÆ#ñr¹ƒÜá>á>oÿ¼ýóv½'zOôžX>²|dùHç²ÎeË"o‘·È[ë™Ö3­gº}tûèöA(BJ‘F¤‘I“.&]jœjœjœ0#1RþBþBþ¢¶ymóÚæ²7²7²7²«²«²«µ›k7×n–Ê e…²N²N²Nµµµ²Å²Å²Åµåµåµå2™¿ÌŸ èš@h÷˜{Ì=¦géYz–¾¦¯ékzŠž¢§p÷q«•>?ù×5Ÿa…xøËùzíÿòò#¶  s•‰%†Ìc2ŸØWß®= oœóôà§ äOñ ˜qêúcèt×ð”êÝÔ28­°Y®ââÞß²:ø€[ªå0»3:ýtWjl”ô%j^S9®vK¿†ScèÍV¿Ódqè…Úõr¿¢&Ë{²¥/«š?tÉx?àÂ¥Ôòwú)ŸV~ZöÞ0·Ké•“¥ «råœ)íðÍÍÎ6&¹tÝ}œ!]FÒ T‚±HG>+tóù(þštZ@@à/H‘i”€`:ÀŸmÄŒ#Óå8jįv–iÆouÌÇ^íjëµjЀ§ë.Q÷@ûê…µê+c+ %TÝÚ<òìýgõ–_>°$5ç“[ÁȲ+NL*ãBzs;8úŠÂ]¦QŒUWÙˆñ§„#áäyGÞUëTëT뼎ÿ:>˜“`â í í ÍV°l…%‘FÉ{2™E–‘ùÀV±þ.N±ÿDÉíŸ%}ˆŽœ%í¸õÔ‡Þ’¯çѦ&1úÏ´¦íÕ¶Ê5slŸNkÜš<1˜£¶¨m.wä½å #JŠj»ïŒ¿¸ÿQáêÙG¯¥_ÎøüñyÁc¸!ëÙõÌ!2ó ×è®·–êC /!Bª!û7'þ‰`A-¨FaF½žðzÂë ¥cJÇ”Žiø¾áû†ïµmµmµm‹2‹2‹2É2…Ld³¿<ü%ŒB¢˜Ì f'ãdœl°é`ÓÁ¦m*ÚT´©(S4¦hÌ’K:,éù óAæuKuKuKñSñSñSYSYSYÓÊ Ê Ê Å¼ç eþâü Á&â=>£DU5‘ÛÊÛç/+_Q=›Â<‡„{Îe6SªzXÒVÔ“Ù^=´V†îÄu`ø.Ê•àPB %h‰–h 7¸Á‡.hUЪ UAEAEAEè§ÐO¡ŸØ-ìv ͦÙ4›YÈ,d–Õ/«_VŸÞ 7è ±X,‹É²‡ì!$€àÞáÙB¶-¼éù@>xƒ7x÷ÄtLÇt2ŸÌ'óùÝv7»›Ý­R_¥¾J}bH ‰!ÌasÃÆ0ƒÌpçqmÑm[®#1#éh:šŽæÒ¹t.+ä ¹Bn·ÛÇùp>œw…»Â]‘ï’ï’ïâÜ9wÎKâ’¸d.Œ ã¸*®Š«âîq÷¸{5Kj–Ô,‘Ý—Ý—Ý•ÛËwÈ&É^Ɏ˧ʟËÏÊÊ2deIµjN×>“…ËûËfgÔTùìtí«䃸váXæ$¹loa¡¡;Ëþ¢Å|>ŽMM7HÝ=wYÎp?i£MªkŶl=Ñs•[l)ÀödLëVY¯×Ë« »ƒ†Î;— Óþ2³rͳ°wž…þoZå4+Öyà÷zå箎¥vxgvOú²cžeÕ’šòfÔ‰n…7¿–ràÈf!Ã1ãØÓì:º»±…-勊Ù|Q¶(Y4æAêPG*P!,7¼f]98Ôƒ-¬ÙL:9+÷à´©3|(4ª·–,Ù¥cÏãý5[:70¶=¢ïˆ'5ïkSšM»rã¹Qjs™dL›_´³or³‡.¯oçæB.‘ö¸m¸„òÕÜ$:ñ‹À‚ƒJTCöoŸ¹rÈéú€>à4÷ößÛoÙ‘²#eGÌך¯5_«W©W©WY$*‰†0„á$Nâ¤pÙÿ’hBš0€ Ø·ì[ö­\&—ÉeM]›º6uíµÿÕþWyO†õ©ëS×§¦Lr$YV‡Õa Kدú+>âÍ(ŒÂ(ÅÎ_ÃÓä#ᔢ¥ô1}LScjLùØù4’.¦§éêJã1 Ѓ†ÒÚ„¶£i]ŒÂi¨àÝFW%äæÉëÈä­+žWæU‘²mªu¸~ÚZ]ôØ;·ï绫nõÿ|D[O=F´Ú½žíBÝsÒD‹× =ê^ÔaúRgx³Ñm™x9¯Òšy%*QíÈVºÀ)Ü4ß.ÏÌuÛ!¤g½µzMh¤U|©|zµ4uÙsÍÜÙæßiøÎäþûWÝ>GgëÆTîÊhõqb!S•Z²²d7c%ß/¿WÜ>ÿNþyÙY±(G´E®,²óòœ  ø]`”öÀcš’RЏ“ØÄ‹ì:¾šmÔT[/ ¸a×}Òê^©Rœ'ØG럸IÜ€ âÖ¬Žh虬Ì ÉžN©âÛÁ®¼/ f¯3wÈ.FÒf´)=/¨CbT"µŠ£Ëÿ‹Ùü„O8/ƒ ²œå9Ës–ç–å–å–éŸÓ?§ÎËÚËÚËúÙ³7f?þï¿6ÁŸÀŸ~G½ e(#Èr@ÞJÞJÞÊýû!÷Cq×ã®Ç]×ÈÔÈÔÈÜÛmo·½ÝeÊ8”Áì`v0;8KÎ’³Ô¡1Bc;ˆÄ*¯,¯,¯”ϑϑÏ6´¡ø€Â0ÿÕùWûà Oö0§íƒÓËÞ·Êõ׊¶ :ìl^ÃU.®•>‘-¥Æ®v«|ŽöÊÖ(©S>˜Ä ké2 Râ?é…?FŽ‘c¬kÀˆz‰z‰z±rVÎÊÙ!ìvû™ýÌ~fKÙR¶TQŸÃæ°9"M‘¦H“íÌvf;³ÍØfl3QkQkQk¶[‡­#z+z+z+Òé‹ôYSÖ”5eÛ±íØvl(ʆŠˆˆ0˜FL#ÜÆmÜVì?ð:~^ëÏ—-a KØÂ¶Ä˜cÔG=Ôƒ La 3A—PrÈTbC‘2rÑœgyw‰;ÉÕå^Òûµïå\³—Ú.TôšÉ@';]*™d[e"W;`ßÄÌ_=Ëy‚U·v#M ê§›£õB|Àr `Ò }ÈA€8‘FkÏx4ÜüÐémeÎÓË3}%“ºHÛýÁñrýíön_¹Qp3?É895ÙcGÀ EKÙtæ‘ü5Ê®£E¨°¨åh ûÙÿ[”B7¢'ZÃÕcº‘ò5\ÚW¹a7«°MN‘ÑIݧ{=÷µhØÂ¤PÛCV0£ h¢v¥ë½›Yí×&Ðüè‡~/Î`|™Gd ©äÑZ‚»x‚LEDN)AÞÿ >L°.t¡ËûPM7uÞÔyŒ:u2:ïqÞã¼Ç¤a“†MFú>¤ÝEwÑ]ÂtøË ô¢E^“×ä5µ§öÔެĬĬ$¾"¾"¾Â¹›s7çnz\èq¡ÇÌi3§ÍœÆocãá•R)•:^q¼âxŦ›M7›nO<=òôÈ»&ïš¼k‚ÇxŒÇ|ôw” ä/ñï»ç_G•É@Ó„x±\•ªS‚Aåõ*üp‘-anʳ¹‹´‘–ŠÊD¶­(ìïê7Ð…º0¸¿ u¨CT“jR -hAKa…f S˜ÒBCp ·p H Ql¢ñf-FJc¥_c˜À†0ä{SD,„AD;дƒ ÿø(˜õ+E©ÿ©¿+º¢+óùÀ| §È)rŠéÂtaºm¢M´™@& $£Éh2šÉb²˜,•‡*UŠ‹‹‹>ˆ>ˆ>ˆ>Š>Š>Š>‰>‰>‰f‰f‰f©˜¨˜¨˜°ÓØiì4•k*×T®‰²DY¢,bM¬‰5DRC4IoR‡Ê `º1–d?Ù@J˜L WËP fŸkÆ©vE&Bê|¬üÒ™½ÞgW6âÒáÇmKê×X(ÊÔš©v˜}iÿÉ´¥Z KQ—êmœ$–úêÕuô ·IF¨ÏVQg6‹—«:0bËε:brY¥r@¼´ ËãgbcÝFs*ŠPÈ-iæÝnN»eιÒU¡Þ—ÝZ|¢2¶ÆkÄÛ‹YL&˸çô*–ãÒQ‚ Ôü4Ž„€€À¿ Ÿ © 5‘6DŒƒÄ#à _ε¢nÄŠt$÷[´ñ˲ïÙÃÞ«m°¶k®™ ±µ Gyy<Àöb>lö2:ÿýì†;—Ü©9ó1áù벪5:µ‘€áyN^ ަKÆ}¤hj”\K ‘ç^à¿;ÊyržœgÒ¹¤sIçz¼îñºÇk³[f·ÌnOâI<©õ¡>ŠàÅiHCš05þÔ(‹ìÎÄ™8ÓTšJS5£5£5£'˜<`òçÎ=œ{<èþ ûƒîK¶-Ù¶d[åçÊÏ•ŸÉ.²‹ì¢Ãè0:Œ7ÇU-R-R-’ߔߔ߬wl*PAwÐtöc?öcöaøLT¿Ï*מiÏ´­­­õõõeg²3Ù™¢Q¨@|B|B|‚ `ØñQññaö8{Š=/®'V}7%ŠDµ¢IÌ}6ƒ­#šÀÍÀ&•Â…¤U21_Ï»‰ÄìDæn]Æ´±F+Ƕ–×5÷»ä[ÏÕr³¦ÆKÔ-m+´îTn©iî|ºåÎg'¬µ;«~‘\Ýš4ÌWõ®ôûœWž»C>êÚ† gÙ—›NäÝšýZVêR1¡æ‹âÆË$#ñˆÔ…)´9oº>|üßPc' ðwBùN‘Âõ˜j2“|¤ÁIãéú#ù†!:'¬'DJ;>r¯×åhÈ2»L€il@nÃâ•"É]‹'sí¶xÑ|¢µÅô´óCR³©¶³l‚báÔd-ÈÙrù`:C0 ûÆ0¨úÑæ÷ù§#™H&’ÛÏíçö;::n¶yØæaÅ'ŠOŸˆMŒMŒM|jûÔö©-I $Ñ $Ìü‰çðWs¦.è‚.¤iFšÑ[ô½5I2I2IÒ¥¬KY—²wäyG&^Ÿx}âõÙ/²_d3ã™ñÌxN‹Óâ´0 Ó0MR")‘”xºxºxº¨”ª”ª”ÞvØýa% K–,Ä]ÜÅ]žÀ_ѯiD§"˜{eÎ\6–Ë÷quJTIGäÑÓXjj£-×(|ò(oq‘ž rüIáU믕>ÿüºóvï•>|æ¶ Ѐ†bÀ ^ðRìð¶tÊß*—ù¨´|ʧÚ_ø(§‘âÏ™/W¡ UÜqî8w¼†ÿ 5€RH¿9õÝØÝŠ²Ô V”÷ákÒçdAº°GØÌIö(Ó…mÌ3ç‚ gÌF¦ÉÃÏo‘¶G^P}2—Ì$3Ù&.ÅZœ^È«2¨W̸5Ε=W {&®)* ºD¥J¯ŸÇzoÃ:Zð^d—›žü¬ù'ÃÝ—Ö>;±ÙúôÈÇEÅ6åãk\ø…ÝÌ|$'9U:“ZQºЏÎ5),â…;J@à+ÚЀ%(G5‰"¶¸Æ˜¡ä´|×’.E€‘ήu«MoÚÿjcÛvOŸÔ•JŽªIXm@6š[`:[ðáuÞ¥Êüø.Ôï¶ß9î¼óŸ/Ñ¥ý+›ð!oH$S1À6™•¼-µÃÌU(»~w‘]±&WÐ ZÁûå\ɹ’såÅÍ7_ÜtMsMsMs¬ïXß±þÓéO§?Îçí–srN.ˆìVx‘½z ³ŒYÆ,ãÌ83άÏò>Ëû,ïТC‹-JG•Ž*µ¸Ïâ>‹û¼Øûbä¹Cîð!e303Ô©=R{¤¡¡QÞ»¼wyïÊØÊØÊXÅdv`‡0ä߬Œi@ð嶃ê.ç¦Ì:hXuäô}nP:÷ÙÀ}¯= î*–¼óÈÄ^aÜþ+È/|”“CÄHŒÄb,ÆbÁQl—¢¥Ä’XK‡;îIz’ž לˆÿñyíÄ-¾Ðøh+¶Í³ýƒ®V\­Ø¼ûƈÌëôìÏ íΆòðË "Ršø æ¥‰×b“)½Ý*Æøý¥CAƒ¢bçtëè¹Õ:Òd·VªrçŒ79‚jÒ°X‡ht‡Â½ŽBM |—ðšuÔƒªp ±Œ#9ø­Ù!¢ÎcCëÕ‘±#š=-ó½à<*ŸÒ$÷ØLJoŒ;„Ò;’q{²ËvnÚˆþ©Yz´íÕŽ+÷ 2dH)¢Ã/øbˆþ_nŠ?>J˜ñ!>ŠŠuÓ×M_÷êö«Û¯nÚ¿†Éô&ž0J¹šrÙåÊQ²Õr¹Ê%²“\ðªÆªšºêG„wÿ3~IÓüïî|ÄG|Tý—q—žˆ@„€¯á£ýð¦D¼o€La ÃêJ‰ž`¹ÌèßäFgŠN9vÇõSÀpiåâôÌú&Z§n;Sqø††©ZA¡'è_fΨvQÙhn>G';><ºôÙ¨Õz¹_8T~Ýý•hó†Ó¦ž½ŒùhøEÂ[¥'¬Â<¦ãNšÉõ¹4zkq éß¸ß ü]Q2G!«I0«ˆ'WåBéRXj¾Ô¨­ö²è]Ïxè_1ÅÑÅpáBµ[@íù€6§óJl*.Ê;î°8Öå~Új‹#6÷å/·}°+°À:`\Éf¼¥]±eSå÷©vàÕj‚ZÈþIj¤ßŸÙ˜ÙÌUæ*sUÞ]Þ]ÞýõÛ×o_¿­4«4«4s.v.v.Ö¸­q[ãv¹W¹W¹i@¦ݟ¥L¨L“ÇäqÑ\4íbábábÛ,¶Yl3­nZÝ´ºíß³Ïþ=û öì/`Æ{Žâ^)}šÀ&´7íM{#)HQ V V ægH¥A¥A¥B¸OÆ“ñ´œ–Óraø¿#˜DòQ˜"¸_²‰>‘ŽLCÆÃ¸Òä¦ÉîP;id˜e£¶‹‚¶ú!èJËg':pžÔB§äËù²‘'(Mzg@ibFìVJ“Åqí?«:<|äú±±a]¶¯ÛÖ`Ê7o@6£€”Éx SèCj@$èáþvw:T¡=hCƒ©e:‘qÊMLÕ ì4ïÍsöCHØÇ–GFMiJ—qç(½±hìJ“râ"Êw\:>fþ†ñã÷Dô·Ÿm™¬Ÿ¢ÜÛ–YFÖ`!F!¦0€¦RöÔ¿À*Ätgº3Ýùóõûì÷Ùïó5ïkÞ×¼Ïë×;¯W×¼®y]sè@:Œ£Æ¨ ÓêOÒü"ăxðe''§]I»’v%¥?K–þliÃ¥ —6T®:\u8øwpw”ç¡aH Ò‚´piíÒÚ¥uxhxhx¨Ù,³Yf³-y?´¿ÂìøŸ®„8¡jPÈ*GÿºNÙ«¹1³ºN¦tö›þÉ”Îm0°Þy«áŠKApøŽàSI_Åe\â+l3l/Ù.k6¡é„p÷Ð ¡C_ºñxä½ÈÉFé ž˜ÜÜrnB¦³ žœÚ7<€Òd‡¸v”Þ¾Ó‡Ò¤¡±Ùe«ÎÏé¾nXÌhéÆ`×[ÎßÑÖ0b6 bO‚ñK¾Þ¨áC@@Øš Ta;³Žsèþ£‰~´N; ÝèÒn•*?è±ÖœÒÄ·±Ó(½¥-¡4¡{t-—ychô«½53 Ûº[#î“jÒk˜Nä±STñž$E#´'x‚'¼ŒîtÝéºÓ‡9rÿÀý÷4Jj”Ô(‰÷,bz1½˜^ à ? Þ7ŒŸ‡IgÒ™O•¨®®®®®¾´biÅÒŠ#Œx0bß´}ÓöM3n<Üx¸¢}) ?ÎX $Šr;´C;~½MMM÷màÛÀ·Aè”Ð)¡StzëôÖé­h9£1Z¸ßdžâ8_Ö^ªÞXÍ7=cÔnÓª¹M¼£tNÁ€Š³çtl©°º#'‘]‚!ðÁg+ìƒ>èC²I6ÉòÐñÐõ0Þ”þ íö:l¬ô½Ë#—Ž (ÿ¨á;[Æ`GüÑÈÓAEù NOi¢V¬¥ %±ª”¦¬çXnu¡ÅÈC'zÍ7j«Þ´²‘g‹D)è­ÜHÕ"IŠ6pQT‰!#\?)ʶãúЇÇ&Ç•›0k˜¥ÌºA»ÚÜwO|T¸c[ÿf”&'ŽEé§cÏQšë+/ºîuîÄñE ;í ëå=Ä&û›z’{D,!®8‘è ?Å|Ó¿8¤.©Kêòåå–XþáᑇGÚwhß¡_#Öóá ma [aÒý0J3­3:£3™B¦Ånj̇˜1î ¸7àÞ€3©gRϤ:ntÜè¸Qq}Ÿ‘gä™â·?}õŠD$"y)KÝUÝUÝ5txèðÐá~~~¢U¢U¢U ŒÏ™*ðݱCÑ™¸`¤ˆ !äÀ­NƒµjOé|ëAC©|ÎÞ—SvÚö)ü`‡:ä> …dËß!k±kù¢z¶z¶zvÀ³€gOC¾„| )’ÊÃÄaºVÖ–ë->áîÿw³êeÌj^š;uP‰_ùë&{ßöCi’NìJŸÇÎ¥4qCì(YÏë’±ñ—ì—FuôkuÜÏ¿®¿Ú^‰¡H[Ñ…=¬ MrÈ8<'ú¸‡‰p„5ôß /Ò,"°? 1cÐ ÉvŒkd-±ÆLÅ]c©:YeU»¢ ûõ7$¤­ÓëÕÒÛKbÎSz«*z ¥ úÑ·)½9,&þÖ§5z¬kyÝ¿}½Nè…Ù_§69Cêa43™”PEÿûwšý,X° ‡û}؇}ƒ& š4hRÚÑ´£iG×Z7jÝ(ƃñ`ÆAB„ ø‡Ñ]Ð…iÊ4ešò=Ízšõ4K¾ž|=ùúuóëæ×Íž< Pˆé|vsÅo™_xÉä3é õ õ õÃ÷‡ïßï9Ûs¶çlôGôW´ä}·¾;4 ±(±# ßç³ãúŒiº€Ò»¡tNØ€aÏ£ÆèÎK\°ý` -hƒ'ðÝñð€/š…š…š…J‡H‡H‡„8‡8†8ß ¾|S[¦ýNû*ãHã)!GH{åÌ iôŠu›èùüéüíú.¤4ác¬6¥ ƒcÎPš¨kAéͪèþ×¹UÎ]Fm1Ý)™YCŠˆ£r?l/f1Ïh%Èùæ •#uüvüäu‘¹Ë¸’Ä wÐR¹¾ýÚà…·oŠVOè.£4±M\Jo;E7¦ôÖèA”&iÇV&0ëM{ í¸¦É— Ñ”¨1šßô|†Ñ"؆™èª¨âݸÿ¦£JÚ‘v¤_á]å]å]uçÃw>œñ?ãÆ_rGrGrG¡©íè!LÆß>ü±¬`Ť1iŒ" VˆAˆAˆÁµªkUתRî¥ÜK¹×Ë»—w/ožÊ\e®¢Z Å×iýÁ¿§Æ` ÆðG±N·N·NoÚ±iǦë×/®_¬0ª±€,xoá‚|§ˆ²h@sï‰nþ¡”.Ð<šfÏnÛE&ÕÕ^뱚®äžÂšë f"R7ï~IåãÙóA*õsëçÖÏ•fJ3¥™¡¥¡¥¡¥Þ»½w{ïíííÄ,Á4At‘Êöb’‰Ê]êßÐVQ r¤uzë3·õ>HéÍѺ”&=г¢4i~l9¥7¸¨[÷å[Ôzµ‰ä:tu›¡W¨5J’ Ü»„9@âñû160…¶"Ó¤€Àÿú.¾ Í60ƒ.^á¢D*¬6ùÆIÔÇÍ)Öbé™î‹ouz,Ó¼Ñ?z¥ ½cúQz34Ê”Ò$¸.ên¿ØŸ úЦÐ#\c•š©ŠâžÂ0ØŒ.ÙDÄðÌ¡ ¨~?ûJ|žTÞ–Ý4À4À4àªùUó«æ×]®»\wqõtõtõäc˜@„=·ß e‹ö¡d(Q„e¬—\/¹^òɺ'랬›¾,}Yú²‰ý'öŸØŸœ'çÉyÆ™qfœñÏñüÇûèŸ]¯É˜ŒÉ|Ñy¤óHç‘Í2še4˰Xb±Äb‰âæb.æ~c/ðA@@Ø£¤ŠÌæ+Öx´÷šG¹ùõ½å.ÎÑ/åSÉD›ùö–FUú½ù_(GŠ0xß)±ˆE,â‡8QŽ(G”ãëëz2ôdèÉ0Ó0Ó0ÓúUõ«êW)ÚoÃV>¨$D䈻ì f%™¤Ü¥8€-dú žÜª°akV6ïBémµ1¥‰-cÝ)MX“Fi’zì†çvïK£˜Î#<œê˜¯Ñ ý憮ƒ·˜Ã,$¹ÄÑè /Å‚(/ðŸ¡lc}è0,YÒ1\¹¡{Výafu7UL8q´6õšfÔqJ$1î”ÞìBiò鸬Œ´ƒ…C ¢º…úh«]TõT™«Ü›ÇÔ’;HĶ]îþlÑÖîáîñEµNjÔ:­¹þåú—iÒ¤è_§þuàx0ñL</LÒß%í8ÙGö‘}p \ô“ô“ô“¶îݺwëÞô÷éïÓ߯J]•º*U}§úNõð†7¼q'pâëûOæ3¯âÓÆ` öééÓÓ§g³ÎÍ:7ë¬{B÷„î×~^à^—廆mIRÉ ¾?†Hzˆ§²Ö­û[Õ­ºt™¨ã ÙÓkýǶ¦4q`l;Jׯ§4ñcì〉ã®^´zXn` kÃ]šªÊý0kI11g<ÈT~½Õÿ¢±6~_La+Å”ÌtfzŠªÄGÅGÙbu±R»X³s†kµ–êŽ:!=šï~Æ~äDJ“Šâ4(½åušÒ¤AqÖ9ñÇ]†_·½ç;ß’:ëM}u¿É…LjÉž>ž>žP‡:Ô™L&“Ɇí7Á°`0EÀßöí Ú$öKì—Ø/±{b÷Äî­¯¶¾ÚúªâÒɉœü‡y‰/ñ%¾0ƒÌ,o[Þ¶¼Ý|EóÍW8Mvšì¤°zÇ0 Ã08ÂŽÂÅù¾W‰GD ùrø ‡UÖ%5Å3ô˪™3#¤¯;¥ó“‹Îºæ¶’o#Šb“g¸ (XX]èBWu¨êPÕ¡~[ý¶úm u u u’ÆKã¥ñvjvjv_3ÀPlž*ëu”mh@¨#r“tE³‹T‘zʇu‘Ô}m°kýûØ]a®]Ow~Ò¤§qm)M‰ÙOiRtìƒ/GÎMÜr²ûü m{7ÜbÎâb ^†h'&€C-á Cê?¦|ø«b hA oÔÅzŒC rôÃ[v!sŽ"—‰üôGúëµ3ÔuÜŒêÏ2WÙÒ±YÃY·Ýj·ÇâýqJ)}K)¥©£(¥ô­É©¨[^x!rø¬mõ'hu¿¡±íãoÒÁˆTXòW°ƒQ¦ÐQ¼<3ë×À‡öhöêÓÕ§«OßôpÓÃMŸn}ºõéÖZ\hqoÈnb7±›„½³ÿ¼9ŠH˜¶L[¦-_íiìiìi|áò…Ë.ß½p÷ÂÝ Ãû ï3¼ÿ-s¹À\ÀXŒÅXÞuøß¸"|`Ç—x‰—|Eýµõ×Ö_Û¢E‹-ZØ<·ynóÚІ6 'á$üßÐâ ü]!Íp?ðe—f ³*¯L¿Ý·[uÙ ç¾þ´t‘åPûY‹Â]½v€*ÔErf;‘ K„€À7Kó\Á¾hðÑà£ÁÇ~!ýBú…†††š„š„šô6èmðÕ<à1}aþÅ%^¢¤% ‡7¬ÙžÌ2IØÊ \©³Yïtü¬HIÐåì5Gw ™NiÊ’qÍ)½½;&˜Ò„O±b.ìšlìâå³&´Ó^5°»=éŽlS’“‘ÄõG3 þÌAþÏ«ä6ê†z0#ÛIs8ùàä{Y÷²îeÍן¯?__e†Ê •dÙ@6 9?çýw_¢Ú  Ú(~z…\!WܪݪݪÃmÃmÃmsssŽ­å(G¹p¡€9ÿ}BsÊ~±yÉ‹)E½ÅÕù3†ö]HéõaÒe“[°>]`âõÌ ÆR6ÊËôFl„"C^ݼºyuó¬ììCJBJBJü²ý²ý²UóTóTóà7¸a6fcö¯:вè¼ÃHG&%d ^)7¬·ÄÒCwàtÿþ}«~j~løPJfǤRš³›ÒäñqË)½q!jßÍŠU&]zwÌ ^e?XÁz“wÊýˆ±cK<Ç E•:T[ä?圠0‚9Nºá#[Éê“B‘kN~á—ãt†jšIJ›K|Ëì—ÆŒÊ ó¾"]~½s^®Û‰)#öQšð9î¥wzÇݤ4)8f¥wÚO8DéU騂™ïpÊáéqJ)}r‘RJQJéá–¯½VD°f{²í˜Û¤'ä˜1èŽÀ¯HéÕBà?‚éÇôcúñ&y=;÷ìܳó´;iwÒ¶>ÝútëSõrõrõ¯bܼÁaÄþC”×ð$$!‰w V×R×R×Zí³ÚgµÏým÷·Ýß¶}äö‘ÛGN3œf8MñÓ6¤ ióõ‚ýGºðEX„Eü9¨Bªðëê×Õ¯kðÀàÁ5_i¾ÒüºÂó»»Sþ‡ë[¡”/Ö@^(ßWò¡v•LßD.ΗôƒÇq]ŒÝ4»ªïG6,“ߢ~\ÌE,ÂTœÂ a¸¾k((¨bɾöÏ{ÿ÷þïýußë¾×}¯7Lo˜Þ0µ®j]ÕºÚÛÛ?ñxâñÄe(Co×øÎæ§p øêä7 ‘@Ê ã1y@úâ£B“ÒWŽM¿„ÍÆöûÉXSsÌ0}ë¨^¼Ý[÷ˆ OqhëÐÈv¡À¾`N©ym¨ãøÌõ†EÆýW^ŸíWÇãÒŽí½ÙýµEá„ÒñÕ6~À,òDá)Ó¸DY„b9ÎâÿÚ»ï¸(Žÿ௙½½ƒÒD@ÅŠ-öÞ{7*bì½wc‰5–Ø+öQì…"¨Ø+( ÒÛÝÎï=óÁ_â盢ù˜8OŸïws·»·7;»Ì;ç=—‘¢ËS£…Æ+Â_"5¤º$ƒ 6c Z“«dÚ¡*ÂDWÚcÙ8Êš3'”ÑBûKÁ›ç›D¼t¾kÓÆhqå·±VÝê—¯Z½ 9T¡£Õ++S“ÕªAt¢’Œ²­ä :‰ú€0 ù@ ż—-_MÎOMÉ|µ$ûô1¯s£î,~[dý¶•ë5¸¦¸&bðƒ¾eå>£+ÞÓšjÚv³Ž°Ú‘ýjÏëNdYCF¡/ÛÎÎëH-D~bÿJ}`Øvïðïâdq²8Y^û¼öyí]œ]œ]œM_˜¾0}‘¯ÎWç«IÒ…ta¥nÜï"Ý·¥À¤t¤#¢‡è!ÏâYü·fßš}k¬ V+Ÿ¹?sæ>C>C>CþæÎ›;oîBRH ™Š©˜ÔÞV¡…(üÃÇ ¥€d``ò{ò{ò{ú!ú!ú!ù¹ù¹ù¹ùÝò»åwÓ u]õ>#å¾V]áwiQþLwÞÌæÝ†ˆm¦Dt+dlf­^-]êѸa‘L%k#›­»«Xc3fòÂã¸ßpGqTZ4¨`PÁ Bȶm!ÛÂÆ‡_'°N`À²[Ên)»E·¾Ý(åñý£Jïóƒ,h89F@6ºïCw$Vv&'õ6vlq®Ò¡¤§ët~ÍØù¬ˆï»P/b'cç¯Etaìâ³óâÜÖœí8sø¨6wü̬ÒM{ê‡~ðg¨9 ¤ëH1qÿè‘pÿ]é>”|Côp@hCW’Ͳ½Âú¤Üõ¸ícÕ¤O›¦›*Xì0äB­‰ñ½Ü×uYAߟ†¾aìò³ÈÅŒ]œ1…±KíGLeìbâˆñŒ]ˆØZ2÷|éõ´Ü|kéßúן(Ì€ÕçVø®ð½ž7!nÂÈË#ÓF¦‘¤=iO­©5µÆ¬ÁƒûÉHsmÙ(Ù(Ù¨ßíønÇw±–±–±– n6¸Ù@nG𒦤)tÿ“× +\áJi Õ%sìnÕݪ»Õå]—w]ÞufÄ™gF„Z‡Z‡ZënuCè:°€ÅïJõø1R<ý^ìÅ^iÙê‰Õ«'õóëç×Ï÷uñuñuÑ­Ù ÝПß·?Òãž"”H‘´šmâ"¦}s½`zÑò“Yƒd‰÷ÄÑ&çU?*cÕqÊVòïªk”š †Pøb /jŽ+Ej²Hn§` ¦äMÊ›”7éžé=Ó{¦ZUhU¡•ö¡ö¡ö¡óCç‡Î³²²Þ¹½s{ç†}؇}Òp´ú_ÿ;±Tow<îá(°ÆŒâ6ÌÑ«‰ÚÂ3êKÂ_O{W¯ ó2D!›GŸìz'¬éºà’r[†n“QùJå–ný¬&B™—ßÝ slüàµÎöÝpï6ã*—üˆ#æ·Ü~lxøíMŸçaéërwPÂÏô&ùI\"z°wì)<0 ·‚·(†÷¶þ<àKTƒ'l0­@§Jä"H °HÛXôd´`ý° `@(4$Õv­…›Av¹vÔä@ø¸j\5Ø]åûÅ.õl-v›=3^ª÷P6Ì­¿ö<@g“T@AÅ åÚ”—oêä<¾y2ejæÑ3Ž×·¿wè› ¹÷¾ð|Ó4OýîqNaÁ Ä Œ €a#¼OºÔa ÑšËÎÉÚÉ~*UÜ­¸Ó–s;ÂvÔõJö!>ä›ûßüæàé>§ûžî»-v{ìvâJ\‰+™ÈÄ?P‡¹IG:Ò¥2ÔiŠ4EwËÜ-s·Lùíå·—ßî7Ào€ß€cËŽ-;¶ ×p ×x™ÿR)  ä¹ Z‹Ö¢u˜&L¦éy§çžw¤uVì^±{Åîs¯Î½:÷ŠúR_ê+žOˆ'ðoðæ/ƒ4ûé,Áh F=_=_=ŸMgÓÙôÜðÜðÜp]Ö2éG?³œN=¸£,€ æ nßÈnöalÚ¥ë›:¨û ÛÉúm/Ø_051ª.mDrˆ=žðÂã¸ß $r‡;ÜuznInInIu¼êxÕñªT+¨VPU÷ªîUÝeÁ²`Y0áÇ™ý•þiÛRqÆäiŒ3ÂRz,øà`­épòM—#õó<OŽZX»å*Æb~6ž±‹ŠjÆÎÝ~±‹ßôºÍ¾â~Ž36ö.®>³bºóuó3|âRL@z–Z’*XƒH¼Ÿjçë‰u.ýÌ! óÑ…ºÝÄL¨G'’ d))ƒiÛÔpªÁ<=³ç+·rd}”ßû¸l­ÁñH£›ÙD6‘MAÅAÅAÅuRê¤ÔIQOPOPë†Àb8†c8?Ü{^°…1C7T„03¥aHÀØÌy½¶Õž¸³KlQ«);z,°*³ÜJw;¦Éâà ã>ªôŸÏa†aÒ¢áNÆ;C¯‡^½V?¬~XýÚåj—«]ÎöºíuÛëºMõ‰>Ñ×e(Ý+ó©þ$—ž«²êÂM¸OÓÉÖiò0 »ï›Yfê!õ¬ûMoW:Õô[cÆ.gGÞgì\üð³Œ]ü~DŸ"½“š!žkjR¯ou¯h5ïƒb¸Oú#‘ÄV¸ˆGØŽž üf3ñK>ƒþðD¤á(F‘•$§È)ÒgÈJâ‡}€åoíÀé¥]kÓÛ¡W+}Sfþ¸ùÝ|«O¸¶fÍË®Ór:3tš)ϼ¶±K½#Û2v)aÄpÆ.v‹P3võÎÈúŒ{5bÛ£K;Vôž¦æØ H¬5ªÊ1¯iöãåÛdCè˸,[8E+ ‡éS’Dôq ü¹LêR3¥Ê¡mE[ÑVÒËmδ9ÓæL¼Q¼Q¼Ñ¡*‡ªªâüƒóÎ?覭 ¦Á4˜ß>A5¼F®‘kÒ²ÆNc§‰¢Q4ŠžŸ{~îù¹uÚÔiS§ôT„^¤éE^bÿýZ&zDè3bFÌ”£”£”£f¯›½nöºë¯w¼ÞqëÁ­·´ñ¶ñ¶ñÖ­oOì‰ýûK ²O˜Y«¡‘´¨­­¦¦¦Ò(¤QH#…ƒÂAá ;ò.èòËs0ŽƒŒ¡¦ÒtiìÈZ=×{ c³ zßÌï>¡Oç\ÆfÖéÝ#øˆã÷EøÃö胦ðENá;ÚÜ%ÞšMÎÿz#åMÅùv‡V™FÕ¨~ÑõæFùxڤν[ôè•UåHΠ-Œß3b#cWöEbìâþsÆ®´ô`ìòÉ‘ksõŽWRçÙÖ}=Nîo9[Õ2¶ïîf~®e­­Í ³Ôúk•û~ý¹tIC¡0ƒ!»I_b‡ƒè„zðBuø ,L`ˆÏ¸XºÏò09LKË+V¬Œ™3+fÖ…í¶_Øú~øž¤ç/?xx¶™¿PòÂFa£°Qz¡íA{ÐÛ+o¯¼½rÞ€yæ ¯‘¯‘¯ÑÚ%#ɼØÞ_´ÿip—~^ÔbD‹-F\ö¾ì}Ùû|Úù´ói C†6ÔeТq4ŽÆ!¡ýŒõö^à…4ë¶ÓY§³Ng럯¾þy·ZnµÜjéîÒMÐMà g8ó“ùo¿Ðÿ a¹@Zj³`¶·–¿óB[Utlÿk߸äÕÉñÈ48exR¯C×úÛ[©²édÂðûÆôGRÏÅì\ð(â…Îq¿K´A¤ )ò†ò†ò†~™~™~™ú©ú©ú©Ò ¬dGÆÑ tÝð¨ê£ªªæ·Êo•ߪx{ñöâí%UJª”T)N+N+N+6.6.6f£Ø(6êOO]ÔE]4+õ¯(À$ã„›‡”B ­Bª‰ Å\ö3ËCEL—vP.Ýn´qË~ ¾iî­×upƒ]žólºÛ61>hêhä"¡€6—µ=Õ=.æiÓ{£$>ŒêyÎàa¼ø=3fºÉƒhMr€ Åö3kÉN¢î/÷³?Ÿ+£t¦ù¾h‰jtiD®rƒÄd±‹ciÿ­ù( # 附ùV–•I¯$w9d.†4ªô¸ìÍjzó­˜È+Lô„/@s€b ±$€8¯ž—–’7#éâ£é§®Z$#5$Æ")-µëÅ%IEÏJŠ JˆÆû7nßY¤= Íh >‡ÂE ak™5~ÂaÄA(4ÿ£¼=0€ŠP„"rŽœ#çX bA/"^D¼èjÐÕ «ÁC7Ý84H3H3H“Ó'§ON–ÂRXŠBÃo½AoÐb¤)FÖu¨ëP×aʦ)›¦lJ»žv=íú·Ã¾öí°Ç_q\š}“ÕauX^nºÒëF»ÑnâFq£¸±šºšºšzzé=¦÷0 2 2 Z“µ&kMÖª«¬@¾'ß“ïÙ2¶Œ-Ã}ÜÇýÏ’«Gz•ˆD$J#š*Ì«0¯Â<‡@‡@‡À†7 o¾ð}áûÂW ›dZ¦eZéºãgóßê7Ü-Ȭ}ú³ A™eµÖû/¦ö}Òä^áÌ¢‚âêMúó”cmNôO¸9ëÕéêqOÉ2lBO¶C±ñïx¡sÜÿy]þçÀr,Çr  2«aVì†ïXß±¾cµW´W´WPõQgqgå³ä³ä³¤dšššZ­ÖFC4DC4Þo·V¦•ieE>E>E>Ŏ/Z8´phá†Â …Š”EÊ"eQqQqQ±vvvøH|$>Òõ¸ÿ~-Ð-HÒ˜¸’rd+†WíV1PÔÍàX¾o™&³[œ ê:³¿[Ó[Þ휔­o¶@c6 ÃÈ= „jõ.´¸qüå󵇳nŽÝq:úÞ]Ï‚IE‰Z]Ï–lš0€ˆÚµCÙ–LÑÅg£Ú¡"•p ¼áHΑÞäЄþL»Ì^2Kí;1–=.½‘l†p‰&Ø_²¼i˜QÿxÕ..7ÂŒ|=lkz{:5_ãuÛÉÄÜQxcPWÖж՞ F'€š }€"ªé“§)¸WÒý±IÚËÜ­çäIwRkì¿{ÞãÞÏǽؔÝéáò—gßù0¥8JûÁÏòšŒÀ=\Æ-¼@î#SÙVÜ`]1±§ëåþÒ’ÀQPP]ÃÝ“y2O›w6ïlÞ-·ZnµÜʹ­s[ç¶+ W®4\½cõŽÕ;è:N“Åd1{°{øÍàÞ7È2L`SÙT6µ\­rµÊÕZ2hÉ %ƒÌw™ï2ßÕKÓKÓK“|"ùDò Ú‘v¤ÅUâ*qÕWZbR$ºhhYZ––ŸŠOŧ®Æ®Æ®ÆsÃæ†Í s9ârÄåÈẇë®;!uBê„Tq¬8VË|˜ó<àñÁôLŸ–Ý‹XÄJs øûû›Ü7¹or?þyüóøçRD>Ëe¹,—_ ÿöjû±ï‘ˆgèyö%™ÚÃYÅ 4‰¯éPˆ¡â¤2ž&³ÔÓ‘  Y&FaÌ k<æÎq¿ç2ûOæ`ÜÁÜ‘nßy­òZåµÂxŒÇxÝ ÝÞðÖ…¾¨¡†šÞ¦·émÅÅÅ)Ú•%²D–¨ë’2 ;ÂŽÌ‹y1/Ö‡õaºžNfÁ,˜“1“o+ÞV¼­hqÑâ¢Å…- [¶,jZÔ´¨iÑ¢¢EE‹ £ £ £´îZw­{ÉÂ’…% 5?k~Öü¬9¡9¡9¡ÒFi£X‹Òu>Ͱå}‹’¬Å!à~ïçMÞž‹mQ±Xm}pì UŸ¦5½ßt‰lÐÓë²WW—ÕÅ]Á28ÊÏÚar0*™Û?;·StÕ†óÏí8ûfïÔ³s\|3!kE!° ñ¤'â±»‘ÀrX(æ`¢qÖ0ƒ?a Ú—dº¡¬@«Ha÷™ ™Œ}Ëò4ÿ™a4×á–õ[“†> ËE›í ™U©…c™Úf~ e4–9Ž1ªipP/R± P(GY8 b›2€ü i\x5¼ßäyð;Û;^Oº½}|jU³Ôn‡×^:ø Â³Áig³škçˆ21º©Z`-€Ù a7­&¾fãYeñ‘Øš½eVl:ÜtQõï3ßW°ñÿ«3_hMfÁ,˜ &‚‰`’ö.í]Ú» "6DLØ1aÇ„mnµ¹ÕæÖÅü‹ùóož¸yâæ 2™L&“Ù>¶íÓ5†x^êß_ÚëÙz¶ÇqÇ…? ž¶6mmÚZ§µNkÖº-t[è¶0ùtòéäÓ̃y0]æï¿žküŸ¥T“T#ÕH51ALŒãããGŽ èÜǹsŸky×ò®å-ÇâÚ¶Ú¶Ú¶ä*¹J®¢-Ú¢ígl²K: :àŽàˆªƒªƒªƒÒAé t(h^м ya^a^a´ÐBËV³Õlõi‚¹måý£â*» ÐË­_2L£ÿîTaŸâeÆÏ (b¹°1OÓ£œŒb8¡3& ›Q®Ÿp„5Ç} ´ÐB«@vGp„¥CéP)þR÷G7™È¤ñ4žÆß?wÿÜýsì{ö=û^¯¹^s½æò`y°Y½² ‹+^©xçEú¥3mv§´¹ÞêAÅ·‹ã îÎ|uåuXF…œ2ºOÚ¦ûÿî–£Ô´%~èÇÖà¡x€QÖWc¡­+NEŠqä—\ÐøGNVUªÁ­í¬í¬í,…gœ˜vbÚ‰iµÍk›×6»v3ìfÏ¥=—ö\ñ,âYÄ3ÆaF0‚,Õ·?9Eü×éžáÙN¶“íÌ’Y2ËûÇî»ÌÏÏÏÏϯʤ*“ªLÚ7mß´}ÓØX6–Õ¥”ýzîÒóL 4Ðè:AÖaÖуô =‘‘‘° `AÀ‚;·ïܾs{Ò¸Iã&{]ëu­×µÈ6²lcXÖá³7Ù¥ƒíNº“îŒ2ʨÊOå§òS½T½T½ÌšŸ5?k~ajajaª.ßüìÀ^ý¿¼Ç}+’ð @AlIsmrîƒâHÍn$«o*[Ì›yZhôS•qdéCìÙr¶Œ†PüéÉ~9îk&M(^8¼pøùÎç;Ÿï¬û“#Å2.Á,)t.t.ü`X±&ÖÄš®¢«è*¡“ÐIèDch Q2%S2E/E/E/½ zô*¨ìUö*{Å2Å2Å2ÕÕÕYYYú>¤…‰ÂDa"íJ»Ò®R¦ÁB°,„©ÂTaªÞ+½Wz¯ô*êUÔ«¨kìÇ~ì—“±hÍ¢Å1FŒÑ^Ö^Ö^¯ŠWÅ«bœ!¦1vœÝ*yWr½dkÉwÅç‹R²ä9yyfQ¸Ú÷­Þé7·¦Ô°c•SeöéÑXß««ï¥r.&ZÙDeÚ¿ÒÏcmŽT‚GY›…CÅV±¾Í[ì1¹ž²%æð¸„šÏ+¼©¹¯¸ƒ8 YW°ÕZ71­fæÕÐîY“êÕ»¸ì¬rÔí¹ùSû'–[Ô[Œ/õSA´ýÄuâ÷MdçmkªŸýcÖÉ‹§^íÈþ!¶Æ½+onwÉýÑ‚Kƒo®~ùM@Öñ‚íEÅZ ¨€ªÂ-úˆD1:ã„h/Îa–hƒÑØŠÕˆE®8\|Ì. aÐÂÀ¤o¸ÿŠ~f©©´ ˰ =Ñ=‹ Š Š Ö­ ZTyIå%•—– ,X¦±ccÇÆŽ‡gž}x6‰%±$–° {ú$ý”å~Oig ÈG>òcÓcÓcÓÛ,n³¸Íb÷Cî‡ÜÉ3äòŒ’¬’¬’,݈iFÕ¯¡d$«±«¥¼Ú—Ú—Ú—={8öpl|®ñ¹ÆçÞô{ÓïM¿¹±scçÆ¾¨õ¢Ö‹Z´­CëˆÄbÝ0ÖÏG.uÙX–ÈE.rõvëíÖÛ-ß.ß.ß^èTèTè$¦‹éb:nàn *ª¢*¯þ_Ç%þG7è†kØÂ~B5tUÏRe«œŒìú®~Xhž£·ÃDÍ}1=!ñͪ£ªFËÛG™kö‹.â÷èˆÊpÃV$à/tŽû,.â".ê²ÁH7ñ—x‰—ng´<-OË+ú)ú)ú)Í”fJ3E]E]E]eeeÅjÅjÅjù4ù4ù4ùAùAùAÅ"Å"Å"ÅrÅrÅrùùù¹ÜGîC‰#qÔå®)F1Šu}{ÒL±YÈBá°ãìgC9™BÑNdo‘¬dŸæRÑÂK±%YÊšj„†yg´Ì `]¹Êr—7†3éMùbz n€d•ì½w¾èf™Vkâ.íÈ)I]žîš•,·PlQ<"NõŽ´Q”9ûêŽéiK3#W@ ÝêDZ‰€h h§ÂïaÿgG²^~{ÛËê×+Ý_úfÜù¤›~i¸h‘äöäÝÇÊMhM#HKŒÇdLŸ±þÌŒ agP)x‰Ì¯zªy©¹ÓЈæÒ\š+Þï‹÷{öìÝDzeË›#nޏ9bÈ´!Ó†L˼–y-óšÔÊj²šŒ'¹ûˆ?ñ'þì»ÅnÙt°é`ÓakúÖô­éRÉ^?xýàõ7]nºÜtÑ­ËbYì¿¶fþj^ @h€xM¼&^kØ0°aàØcWŒ]!ó–y˼gfÌ̘™qÐê ÕA+A!(…¶Š¶Š¶Šîùšø¹9Á Nº,1§q§Ëß,³üMç7ÎoœßÜzèý¡sç<ÎA b8À×ü¯Áïq_‹HÂFˆÐæÇ”f»f}‡ä)¶#{ÂNZ$«Ôò½d éWìÿåsx„"Çýq¥›zF0‚‘.ŠQzÔûþ:–A††hˆ†º×­a k]bGib&S˜ÂT—ÒQúЇrÈuY¥þå!yâ,q–8«0²0²0ò7â¤ÈKÉŒÀÙ}Ù}Ù}™™ÌLf&‹”EÊ"…%Âa‰ÔˆW]W]W]W]R]R]RîWîWîW=P=P=PLTLTL”5’5’5"KÉ"2ŸŒ&-IÚ“>¢eæ‚)}¬ˆ”í—½ÅFrgî&æ«âœS:=ÙèÕ¬Lœ¾ªYfsEp‰g¸é:• ÎV/ôÍ®½¥Ç®Z&þá†Sð(Ê`oP ÇW Lß\'èyÁ(Ö׮ͭžoPtâÖð§ë²N¶ˆµ~ºîtå¸U.¿¬“úT¶ä]íX6£?÷|îùÜš84qh¢~ýú6 d9xûà탷)¥”RmCmCmCÝSÄ¿“Ô?Ó8M[ÓÖ´µÁ9ƒsç´KµKµKs/ä^Ƚ »«ïÃ>ìãužû¸¡¨jô Æeé…íZª‘ÊØœÁ}’Š+Lú©kLÎÓñ];73êªÜ)O×mµ~kZoŽã¾8ÒÏøÀGÊfƒ½Ø‹½x…WxE\ˆ q!½H/ÒKzåO~Ê|ÌÇ|âI<‰§,C–!ËP¿P¿P¿°ˆ´ˆ´ˆ,S±LÅ2]ö»ìs‰òŒö<ãyÎ'×'Ó'­j•*uôªÕ­ömµ þ‡ªŽ­®v ‰¯i0Ä §¼e³³Ok“~Ëó~›hÏ }‹ô _ª‘–Sÿ|FáØÂ~×§<ŽN¼x}Áü~-2˜èÝd^¿n-MýG;œ´^b|”,$‘¤Ù¯“Ü'Á*»$ì¤tÑ’Æhº¨¨{[øÏ¤Tܨ]RÙ¾ /È i¹ÞËz/ë½¼\õrÕËU££¢£¢£*«|¬ò1ÝšCÈ2D·žåý÷¦]›€ ˜@ÓÁtð„À o ¾5øÖà‘·FÞyKWœ"é?mìÄï'uOHµèyEt÷+›$›$›¤m¶ Ø6 aIÂ’„%s¼æxÍñR¹©ÜTn¤3éL:—žïPë:£3:KAbòLy¦<3ø\ð¹àsaÕª…UÓo¢ßD¿‰nÍoð ¾áUžû8ò¾ô Õƒ”-ÞÚȽZcóŒúÕ*Ì›x§«Eþ–‰.]n”_`9˴ÁÏ ãþU¤øË„ =Ð=031»° »€$HÃj1#1ük?ài%@ƒUU^Ê»ÆÖFC W˜«Ì.™EX8Yo·;aØÐ0ÞäöÂj»VïØôl.cŒ%4aŒ±G™Œ1¶3¹`Öµ£¹mÓe>¶â†ShE_Ó*¤!Õ#?‚Õ‡Vï?þSÎ-úU“šS•Q•‰@"HÏyf÷›Ýov¿„C ‡­°ZaµÂJqTqTq”8'â¤KÊý†0„¡PU¨*èâž›ov¼Ùñ;¦wL¨¾¢úŠêÊhe´2Z÷Œî ÎàÌ¿°ŽIR‚é¹ÁÒK,]X)±Rb¥õë Ö˜V5­jª++ò޼#ïtÛ–ú©ù·Žá.-ªÍÕæjó:—ê\ªs©zÏê=«÷$gÉYrV÷$Áv°ãUþëñÇ«c1´ÐâÞ@‹7(†6gJñIí+4`õI ž± ²|ª +lå|séÈÜ…ïÑuѽÞOÅÂqÜ?^z©çq¿1‡¨®§Júã' 1”Âudº ‚((l`TAT‘sð‡?ü¥^R‘T$ÙV¶•mCÄ1¤0±Eî…(L.€ïøã2öcüððF«„>‰ç+¶­ òÞ”Þ¨X(:fÚOa ltóæÝú7|³“ƒ¶kšêøÄäz®Ý”ܼÖ%®Çi°±LÁ.±;øW˜­Ç^B‹k`è ü’M\JLÈýuR¸‹4­Ì3<Ã3i¦Õ«3VgøÅûÅûÅtèÐᛌo2¾ÉØ“²'eO µ¢VÔJ4 ECi¸OùQ9ÈAÛ¶°-¨‰š¨ù¼Íó6ÏÛ¤y¥y¥y9Öt¬éXÓ¹À¹À¹àŽìŽìŽLtþ™S¤ü]¤æ¬TǶc;¶K/ D‚†ºuê2!dBÈ„§xЧ˜9mæ´™Ó2¯f^ͼJZ“Ö¤53a&ÌDw¿*”øw’NQËÔ2µLzbë•ë•ëŲ…l¡®þKc‡8î¿\dik¢þm›ŸÉŒÍ¬Ò»aqƒI¶]µU§Üíߺl¥(·ÚÒ:´ â‹ã¸?¤ô2+XÁ MÑMuýú§q§‘‡\ä Oðš´%.ÿW»ƒz¤ºrL3åÕþÉ[Tûé$zƒNÔ½íˆh8ò‚ÿ[Ïo;´C;²‹ì"»¤—ûæôÍé›7 n@Ü€¨Q ¢Ø5´kh׫° «ÈIr’œüŸõƒþ£Ê–T!UHé£qFãŒÆmزaˆ-I—“.']®WT¯¨^‘4R˜-ÌfÿK¾»T7Ú£=ÚÓQtÕÍÝqlDZÇ^ ¼x50º{t÷èî!6!6!6º;ÃT:•NÕu%H#þ·") ¯Ë}—û.÷ë%×K®—\®°\a¹÷CŽª¡ªéf)æ¸ÿNØK ÈJi¹óIÿ—Űi~=+•8MÑ5œ­˜Ö©GAÿ+Õwùè²Ód©ÈËã¸ÏBj¨¥ER–ô"½¨’¶£íÈuÚÖ%%´%mKÑŠä,@j½ßˆ4þ÷þ?K-Yüò_U…V¨ŠšT5P*€Í|JĘc<ÄC<Ôo ß@¿ÁÆN;mìtýäõ“×OŽ~2úÉè'º5‘F¤‘®Å›,ÿ L`BGÒ‘t¤ô”&SšLir×ï®ß]¿!fC̆èfD–ff@+´ú%0ìŸHýŸû@ÐÒruRT'Ñ»£wGï¾²ìʲ+ËÚEµ‹j¥[3–ÆÒXôGôÿå@þç×÷@ Ä@i±Ò©J§* 7 7 7³··×Õ)[ÿËý‚’!ݤåF{½N–›Xà9éF·Tá¤ô®+›~¬ç³ñë램2X·¾9FZórã8îâ?„•”p¥Çà ÖLtÿ“”€öÿÿ1T_¨aAÂaäPüÆþ¹?ªôpÕoÈ7D7Ì.taèÂÐ…—.\ ˆ‰ˆ‰ˆ‰¨¦®¦®öþçYÉ#y¿œ3>\õ¿ É4™&KÏ+ú7ë߬³„ -Z,J[”¶(M‘®HW¼O#!HùG~ÉÿÔò„Ó1†Ñ0Fõ©>ÕŸpÂý ÷“ì’ì’ìÖ6ZÛhm#ãŸ6þ™d’L’Ij’š„çwÿ8 J¾'ߓ勵¿¡¡¡ç¾?÷ý¹ï><øð`³»fwÍîJÁ!ÄžØûØw,ýÃ/‘$’D –/-_Z¾\×p]Ãu sssæaæAù\ù\ùœ´ -H i‚ª_ïçl>æc¾´¨ªªZÿ† ÿ ³AgƒÎªzAŸá_,¢,˜ˆD$*c•±ÊØu“ÖMZ7éºëu×ë®3ÎÏ8?C—~”!GÈ©éYºéÏé8ÂŽx‡wx'½Ð£UV=Z%OŸ4~éÀ¥—êA’BBþÏ.¤íC0C„!@^nÐ. ]À¥ŒK—2.Ù]²»dW7¸npÝ`é]Z‹Ö¢ï‡¦™õÄð(ÁÝËÆËÆË&ü§ðŸÂrðpðpðà?âGüxÕæþ)ÕÔ9¤b†£BÏ ë;ô›!¬xZF|V2=¨ÇƒDåà]-îÝÐï¡×N·Ñ·¸ó7OÌq÷çèÿÒ|wÂ8Á@väÃ&²Yn¯d³pR6ã—e°‡ ïóÏöÄö°&*Xÿ’FÐ}÷Û%ÿK*É&Ù$[Z®²¼Êò*ËÏï<¿óüÎsîçÜϹ×|^óyÍçÒ»´%mI[þzœn˜ã:N€5¬aààà”¨LT&*w{ìöØíaÒÖ¤­I[( €ÉHFòú]JE¢SJ)ÕýÀ©R?¤~ôúèõÑëã,â,â,Y ²d¥[s8N‡ë&ð’¾ã—©z¡—´(<ž Ïýûù÷óïW+¯V^­<óPóPóP]ÝŽE,byÕæþä0a³ôÂ~m·¦ n16Ý«§cS㻟|`q¹í¾²[ÌMB¡‚2ªG|Ç ã¸ÿ4UTp$/á âWëÉY÷cé"…Ú„>PªWžÇeÿ6©ßw –` ý™þL–©ej™zt‹Ñ-F·H2M2M2Ý0mô ÓL&›L6™LUTEUdD}ѳÿUqÚQ;ª›_ÓUî*w•ÿL~&?““¯O¾>ùÚ‘ÿ"ÿE0‡9Ì¥‰®¾¸>éRÇCŽ’£ä¨î»tsíæÚm¿Õ~«ýVq5âjÄÕ˜ÖoZ¿iý‰ŠDE"YKÖ’µ4s¿äu±¥oª  ’’’Ò?¤H=ªGõÞß-c0óZÍýaäR°UZ^]±UfXcÓ÷l/^ŸÖm^Úð1ƒ;©Ô¿Œƒµ­îÆqœÌ'¡¼Ü8Žû#@@YpÂK8AŽ2¿L®þ¾Ÿ^ À ft›ƒH·‘õÏ’ßïBhÀ‘P8B€=„_ý¼—ø·‹|™GæIËÒüî{ºïé¾§{ü£øGñú7èß ¿.? $$P·Ïo]º ݉;q‡Œ`¤ž¡ž¡ž±bÌŠ1+Æ$ù%ù%ùµ;ÑîD»ºÚyZ8-œþ‚½tªÇoÉ·D7ªD½R½R½ruÜê¸Õq×®\øÑãG=L˜<0y ÛV -´ÿ˜úp÷pOZ4igÒΤ]}‡úõªî¯º¿ê~LÀL@ Ô@ ÃƼV>Y_Oj^nÛÂP>pO³g¬–^[y´àgxK1^¦ËøN¦£¼y¡s÷Æ ƒO¡E ì‚)OÏ6#U[S1¡14&w\î¸Üqwäwäwäú~ú~ú~.ë\Ö¹¬ÃXŒÅXÑUt]Ñ}Ñ÷|ÐRS[„‡q‡ÑÍÑ\* •…FDDøøø=½õôÖÓ[3ìgØÏ°çúÎõ+]MWÓÕº~zi&Ô/'oÌGê9öaöéòÉü¤ÿ“þOˆA bò¾Éû&ïLÃ4LCUTEUd! Y¼VsXé÷!kCŽWÊalz|ϵEYŸvy©­>mzÏK—{¦;–ÖP{²—ÇqÿrÆcè¡9ô0À|Yd•}²Hµ|gSµ\oÀºÛzdûÝÆË>ó£@eàñ›¤Ð—8€DFdD&¿(¿(¿¸¤É’&Kš$y&y&yÎSÌSÌSQd¥ë—½ƒ;¸Ã ¯4a0H„:¨ƒ:MW4]Ñtŵ—×^^{ùSÑOE?™››Kk’Ñd4ýEt34C3H©îYJß]}wõÝuíðµÃ×G7nÝ´Êê*««¬ÖyÒƒôÐmûOí`#Á¶°…)LaêvÔí¨ÛÑz}êõ©×ÇIí¤vRë’WÅP å£8¾fŸ®ÇýJv…|¼† LYTÂwô‚lºÐZ=B^ k¡»‚†¢yeã8î_ŒÈÂÈB1Ž¡‘$‘šùךkæçîj;-w³<}†Yªf/{¥š­WwÔZ½ºt½éKº¶ø¶(Kdæ±áPŒb£)𢩔ø¯¤zIõ’ê?ªTÿ¨~küÖø­q5fÔ˜žžžÏ–°%l KÇÒ±0 Lx¿»T¢½h/ÚãNáTòä!ÉC^=|õðÕCת®U]«ÚÙÙIXÉCò<üß­B©#u/‹—ÅËMÄ&b±k~×ü®ù%µKj—Ô^¾`ù‚å ®õ½Ö÷Z_úý‰þÄ.±Kì’®¯ýŸ2{ŒôÓ4©HÅHŒÄHuŠ:E‚Y0 ÎÉÎÉÎÉÖM%• Ÿ竾”ÿŠRMð´˜ì˹}aEš ‚vS²H—YÒQêù}zQ·ÒVÔ‡7¯lÇý‹Iá.rhQ-Œ1lhCØ 9*¡yáÔM §„vò)eIÅÓX’pÓ4L¸‰'0Ç8âg8¢ôýU€)(¾òn"N§‹Ó¥l3‰Û·'n?@ÐTn&7“›u3èfÐÍÀä;“ïL¾EgÑ™ä’Ã{(u“1mb›Ø&)ÉæÃ3Ï<<“9:stæhcccccc;+;+;+]âÈC8„CRòÁ¿õ8¥~e"DêOý©¿¸D\".ñÝï»ßwÿ¨!QC¢Tyª¦ù˜æîFîFîF ݺ'tŸÓjN«9­DoÑ[ô&UHR¡E¨nˆç?«¯]ªõPõ¤ã7Xi°Ò`¥ d‚,/%/%/E[[[[[[—!ç)žâ)¿©r¶¾µÆq,’–­â ô‡?­:ª[ljš­“ëw-alfï^ƒ·:µ?Z7Œl'oa؉žhÆKã8 8AlJ%ª#Âèc„éV9Õäºâ”zÍâê54Üî ÿ`¡tþ“fWÊÿ•DsQùž|O¾ „ó¼çyÏó¾azÃô†éâæ‹›/n®$J¢$DJZnA,ˆ›!H#ÒHj.—÷*ïUÞë’ÿ%ÿKþ'›lv²™C¢C¢C¢®1ýñ9#ÝKŸ‹õXõdÙCö éH;pìÀ±ãGÅŠµ¯î¾ºûêº&º&º&ê6=OÎÝì¹ÿôÔŸ„JtW­k‘k‘kQ·n ÜÊÕ(W£\ ÝJ«±«a+X}͵—ûkU­6b¢ô'¤¼^¶ÊóúðosZaÓ¦wd…Ó×öTù¹ÇÙÆ­cå²;º‹ë.ƽ$ÄqÇýŒ† ”ƒ’$) H’ž"╞Â`á±k •çûOTž§£Ãéû¼2¸~U9ËKÏ®ú–¼%o¥e¯ò^å½ÊŸ8pâÀ‰ל¯9_snžÐ<¡¹.>˜œ#çȹ_Jì«Íò^ºµlÜܸ¹qó]λœw9_êr©Ë¥.M77ÝÜt3ª¡ªéf'ýÜ“19À$–ÄÝ4I²;ewʾºàê‚« ¢³¢³¢³‚·o Þ&½K7ÑMtÓ¿$—¹”Ifö`üáŸlŸlŸìðwáïÂßÙ|góÍwÒ7%žÄ“xòaÖÜ_“ƒ¹ø€ ‚ÞsEšÂõô½¾QMo36ípŒM]Óý§k^ƒ«µ½}zûô,Â-Â-Þ?©¸Û¸­[þ:{ßgafI¡24ŽÆÑ¸‰ &&Ü ½z3tDƈŒÒŠ‚JP ªÏr R• !H‚…`éå†m¶mØöÜýs÷ÏÝ¿´ûÒîK»Ûºµukë&½KÝ©;ý0ÔöŸuK­ l`CH À&lÂ&™£ÌQæXõMÕ7Uß„í Û¶ÓXn,7~?*ƒÉpÒUð—¶ŽÆ<‡4Ð&i*k|_]ÎíT0¡=ÁÜÅîì¡Q[¥“¥OéSQ-ªE5c1²O—†£Åd.™Kæj/h/h/TœSqNÅ9C † -P—S—S—Ûu{×í]·wÞÛyoç=ÝÑÎç‰ó>xðåŸAéÉ€<à†hˆ†º‰–ŽáޱXËbeZ™V¦ zô2è¥^s½æzÍÙ=vÝó‘ùÈ|d*w•»Ê¾ð…/ú úðÛ#÷g BÈBŒ‹¹XÕdiõåŒÍÝǤ¸ê¤À®!é[ÇUíœo7ÞhÁi2çñ/<Žã¸ÿ“Ô¹"Ãû¦wU’ƒªý%ç QDÇ‚ë^’Á2 ÔdNj<Þ‚ ¼a†0{¿ñ¿"Ťԋ©=èÑ´ÕM¾Sûií§µŸ^¬p±ÂÅ 111ÕžV{ZM×gIÑAtÐ×x t:PUP¥Æ¹çjœ»:âꈫ#öï ÞìtÈéÓ!]g‘,’õ ú¶KçéL:“ÎÒ²õ`ëÁÖƒ7õÙÔgSŸ„* Uª,¬´°ÒÂJªUŠ*…˜b‚{¸‡{œñ/¹6vFgtÆ]ÜÅ]D"‘[Ýh˜Ñ0£a.Z­‹¶ŽW¯:^a¦a¦a¦5Ój¦ÕL«k^×¼®¹^K½–zï3ÉŒÀŒà7ƯÙ_‹ð»„GxAmÉ@b¨5dÌàÍšÜ6ùýšFšj_ˆØ@£r*ë%{AD¬Ì‚;LJ%:ã8Žã>Füåÿ2P0\e&¸ « ,ˆ,ØK¦Ï^ÂY»Îú䕚Ú] ŽÈÅ -pLxЦðÄm–‰ÛºŒ4ïsÚüóH}®(@è%z‰^t1]LŸÝyvçÙÑÑÑÑÑÑM{6íÑ´GOÚSÖS–”œt7én!)$…ˆD$ˆ@¤ã^}µJʈ?Eœ"NÜàöØû±÷cïg¡ÏBŸ…:lrØä°©ìe,ûcJÕ”ª)UiwÚv×2-Óþµ"åE)F1ŠY1+fŲò²ò²ò‘î‘î‘î>ž>ž>žIû’ö%í›»lî²¹Ë HÒ€4޳tþ™/¡ uÿÌas Æ` &kÉZ²–mf›ÙfHÿ4ˆÑ ½<½<½<«AVƒ¬™¬3Yg²Î0Û0Û0[ÏBÏBÏ¢ ¬ ¬ Gpº¬>š;š;š;ì {ÃÞ Qˆâyܹ¿ÖÓ§H¥H. yÈK× `+2ˆœÈD9+Ãú(nÊ[Ð1§äï/–ƒú+‰¿ä8Žût¤F¼@ P‚—ì^ ˜ÁU`ðË:€› P^62ÒK6¢þ!ÙìÔÀN]“Ý–¼€-¬IUXC€”ˆ’ü²‡© 5#1’-f‹ÙbM¤&R¹¶ÇÚÞk{?ïö¼ÛónþÛü·ûooqµE|‹xæÉܘ™Eæ’¹_Q“]ÂÀÀØ<6Í#Á$˜?3yfòÌä‰É“'&&ÏLž™W_W_W_«V;¬vhµZ­Vûzâ뉯'ª&©&©&)”J¥›ÒMé¦:¤:¤:DŒ‰11Öý@5„! ùÍûKdóho¢³ßyWeÃòáŒÍ>Ôצ@ž.NìÝtMϵ¹ªËøé®‚cHÁV^nÇqŸ‘ò``@›Û ´¹ºÎ6gu½'«è=‘E¹þ ‹ú`}CšüKƒ€Àê oº—nŽÂ(Œ’’BJ“Þ }…¾B_y¤ƒÌ 3ŒŒŒœ­­­ý¦ûM÷›^«L­2µÊ„›†›†›Ö-S·LÝ2¡$”„ÏížÛ=·[Ï·žo=_³þfýÍ´mF›Ù˜Ù˜Ù˜YW³®f]ÍÚËÚËÚËÆËÆËÆKh,4ë>Ìžðä·7î/‘)¨7Ù--7Û_!Êù¡ølz|¯uE5&þÐå§ßë¹¹“·ßf÷Uœ7Ü9Žã>7ªû_E¶l#ìCŒjgïªM4Õ[4î•Þ"²ß¢˜ì×m¥@ËR±ñ7)Gµ4l´?ú£¿nXd4¢M‚H "ÇÉqrœÚS{jO ?Ð0ã1þ¿ïز±IžIÞ®=û_ìäørñåè9éUÒ«\8™Z9µòÔ›ën®[z}CbH Õ£zTØ[b‹Ù˜ÙABtÃaÿéÈN²“씦þ©Ý³vÏÚ=Ï8?àü€ýóöÏÛ?Ï$ß$ß$_·¦)1%¦`ÿRó×Þð¦¶Ô–ÚJ/‡¶mÚþT¿SýNõ»ÖöZÛkmÛ¿mÿ¶½.¡']B—Ð%p„#ÿÖr6 Lt3ÅJ}ê'p'~½¢,_–/Ë767676w:ãtÆéLUTEUÔH¯‘^#½þ™úg꟩?´þÐúCƒc‚c‚c|ü}ü}üm«ÙV³­¦Q„(BøÍ‰û+>A[6šÅà&¦Â ȉ-ÎÐ+LÑDi_Ék’Ú$·`m5SÝJï ¾Aç÷ÃX9Žã¸ÏH„ÀM©ÈF*jjP³kQÁÛ%Á_~rt¬ü¤á¼M™†óòÍ:ä›kÞžÔÓ¼…ÝÜ[áÎ'8©ÇZ„–°„%á‘äyA¢H‰"[ÉV²•ÕcõX=QQÀJ¬ÄÊһѥ G8ÂuË1¥wíVÙ­²[eŸdŸdŸd~Øü°ùaKKKÛ\;w;wë~¦/M_Õ7{möZ[C^M^ͨ¡E{‹ö†ÛßùAAõ…º†u ï _=|õ¸æcýÇúºO)@ 0£11ˆA UPU 6j£¶¸P\(.Ä À]zJ)×Í—O -´¬<+ÏÊKgç®þ]ý»ú• *T² ± ± ±{e÷ÊîÕ;ö޽cRêF]ö§}è#ùȧ2*£21ULS=R=R=RGÍ5oÔÓ4ÃñVV„·¶ÙHˆxéÎ0†ÊB}¼‚¡.Ë À~YÖ@-4Р¡‘”£Z×@I^’—(ƒ2(£­¦­¦­ÆðŸ:[°[¤E¡–PK¨¥XªXªXªo§o§oçXìXìXìü½ó÷Îß;ˆ¢ƒh×Ä®‰])4Ûl¢ÙD³‰æžæžæžÆÆÆF5jÕ˜;sÏQ½~]òذ“a§BÓ’–%-QOÌóßz’·ä­½ÆÖÌÖlÆ¢i•¦Uz¾ü•ù+ó”õÏ?>wàÝw^||ññÅÇ÷fÞ›yofaÍš…5?h59À‚¥`)XЦ¢©hÊrXËÑWHC ¿„Á”3Ã1%(AIj@j@j@Úê´Õi«=GyŽòåûØ÷±ïãä*ÉU’«Hy{>hþþš”|äãîàŽè!zˆ&åMÊ›”•>*}Tz™9eæ”™sùñåÇ—/ ]º0TsAsAsxâw¸Ãýÿø”ßOÚÔØ5‚Œ00L&“Éd¶‰mb›¤êÒêôGú#ýѰ’a%ÃJVVV&£LF™Œ2Xg°Î`ÊGå£ò)ù±äÇ’‹ÔEê"uÖ ¬AYƒ^+^+^+²ke×Ê®U8©pRá$v™]f—uÃI¥O_à^à,Îâ,R‚ö”=eOÑmк íw|]Þdÿê}Šy㱂íƒ2¨ß<ÏÏ-”Ý©ðÇâþ–»UôˆïlWîÒó}_99Žã¸¿  BE؉"$² H„;nÀ§„ œÒ ©f©b€{Ì·Tê=9(´È‚ZÜ€E ã“BŒ`¼B:Ò±Û±Iÿ~Õ¡žÔ“zZ5°j`ÕÀ´³igÓÎÆÎÆÎÆÎV¹V¹V¹å Ê”3°ßb¿Å~KÙ§eŸ–}j¶×l¯Ù^======ywywywÅ!Å!Å!e–2K™E’d`v|v|v|z™ô2éež¤=I{’özÔëQ¯G½m—Ñ?£ÿ£§÷¦Þ›ÚdåP÷¡î¶ØíµÛûnèÀ‹ªEÆEÆwr“Ý“Ý+úTnX¹¡{Y·²neC–‡,YÞ1ºctÇè'ò'ò'òË—.;$µOjŸÔþù³çÏž?{Üäq“ÇMt-si¢$ IH"×È5rM7ÄÓ€0)[ÈÔoš dHáIâzq½¸þ惛n>ð¶÷¶÷¶÷¾è}Ñû"®à ®À0øhëRúFZh¡%õI}RŸT$IEy´w|îøÌ2™e2Ë$ïBÞ…¼ ¤/éKú²Õl5[-í E(ú“ßÈ f0“žÌ 2*£²îø¥ÙI#éKn‚›àflllÒפ¯I_Ëi–Ó,§©“ÔIê$™…ÌBfAoÑ[ôVîæÜ͹›ßÈßÈßÈßõ~×û]ï7 ß,|³°°waïÂߘ žx/âÅz±^¬—”mF÷îSý á¾bŸà!ùpˆÍ…+šïÑ¿«wøì‹ževóégãk| vŽl}ø&í]ãN\ŽZ“xˆM¬\Ñ•W_Žã¸¿•4 ƒ jxA ;rvx‚@¯¾`àhà¨.V«‹ÕÕÕõvëíÖÛ­m®m®mžµ8kqÖâwïÞdT˨–Q-sYæ²Ìeo[¿mý¶õ‹6/Ú¼hó¬äYɳ’;;ïì¼³3ýtúéôÓÅÅÅÅß[ü­öŒöŒöÌG¿Õ[¼Å[a¼ÐGèÚ³¦¬©.v»ÿþbQ½T½T½´±³±³±«f\͸šq%R‰T"åË%–Ktî<Üy¸Ù!³Cf‡råÊ9”¾7}oúÞTçTçTç···+å®”»Rî‘÷#ïGÞ¯ékúúƒì4¤ iBšSä9Åô™>ÓgsÙ\6W×ø;ŒÃ8ü÷DÌS_êK}Å;âñŽËi—Ó.§×­ Z¤ùQó£æÇÈ¥‘K#—&]Oºžt¤“t’ά™5³ÖýÌ(Õ€–ž0°*¬ «Òäl“³MÎŽÆcÒˆ4"¦ž6zÚè£cŽŽ9:† èq8H„gx†g¿ë@¥YHË¢,Ê¢<Ê£<Ú¡Úa,Æb,â!J+ÊÜeî2wýýý + + +‹"‹"‹"½z;ôv¨©©±l[ç‘ç‘ç‘ó$çIΓ7ƒÞ z3è­Í[›·6E&E&E&hŒÆxŸÑe"&b¢nîҞ艞ºÐ.HŒ7Ó¹èA%s¢¦dŠôÂÑZ]âê]alÖêÞ[›öMa·/Ûµ¥n4:©‹•èCÅ ã8î‹6‘4|?×µº½›‰QëwÓv»iÏc‰£c,É„1ÆrÕyT'áVìàØÁñ,,£õ¢õ¢õ6ïÚ¼kó®ùæO˜?a¨×P¯¡^í&µ›ÔnRý§õŸÖê»Ôw©ïR³L³L³Ì?zhÄ’XKCch }NŸÓçÔƒzP2‚Œ #° °Æ°€…´>-C7ÑMBl±l±0W6X6X¸%[,[L ³…ÙdéMz jÁD0!cÉX2öcŸkYѲ¢eÅ 2dôÜÿqÿÇ+ŒV­0:kpÖà¬A«„W ¯â]ã]ã]ãY<‹gQâ†E ûnîws¿›Û4¾i|ÓxÏZžµ84GâH© u¡.¢·è-z³Óì4;­ëc–"ÂÿJßüTLÅT"‘ˆR¯öË –,»ë:¬ë°ÕVT[QmÁᇦÛévº]\)®WJ!d)YJ–²!lR&´Lh™Ð…M6]ØÔí{·ïݾ?ª8ª8ª7yÜäq“Ùz¶ž­—ŽY74SjÅKe.-K?a‘5d Y£ì[ CçÐ9úuôëèױееŠ5Ýkº×t¯:R©ŽÔ3Õ3Õ3-‰.‰.‰.lWØ®°]Ö7Yßd}“˜˜˜]”]”]Tp à@ÁÝbÉ:¬Ã:¤"©8Ó8'x‚'xЧxú—bî9î ¼¹á )&Ó¤~ðm¾54މ3ý{¥ŠISFv»™6fÔÃGË%XÖ5•¦r ädâæëÅ~iuã>¡I }¥åª—[°Â•zUÕîŸ×-<³û¸½OUéì8Ý6 µHSbÂËã8î‹æw¸K‹t‹ÐThZ÷z[Y[YƒZvhY߼݊v+¾QvhÙ¡¥…µM¾M>éKú“þôµà)x’cä9Fê‘z¤ž®§¼šý2ºéŸÛ<*=—j5TC5¢Oô‰>9CÎ3ÄŽØ»Â*J1L6L6L®T¾RùJå;6ïØ¼cóE½õ^ÔûÄÃO<¼¼êòªË«’Þ%½KzwKqKqKq`ÄFÌ6›m6Û¬—q/ã^ÆW\\q±kþ±N §„S´­Ek¡ Áû7>f#…»Ô¦µim)mbÕΉU£ ¢ ¢ Ž8~àøçUΫœWéÖ¼J¯Ò«dDI;øÎá;‡ï¶%lKض+hWЮ ò©åS˧êNu‰"Qº3~—q™#bô±ãW¿T¿T¿të4Öi¬ïHß‘¾#ÃÒÂÒÂÒÂG† Y'ºNtèÌÌL/o/o/oë%ÖK¬—èõÑë£×ç7vç8è"Ôçb.æBš3‰7й¯M&ËH°´<,¬Æ‰Ê5›v»g}ÍòÉž]/ä?œt¢Ûõ†O¼¦•«§[Ÿ‘C¤ /7Žã¸•Ǭ¢…Ô—ls˜KÓ6Qê@ÁCðøõê²²²V«­V[­nÚ µAꤗ“^Nz¹)lSئ°˜»1wcî>hð Áƒ‰»w%îú¹ëÏ]îúÓ˜ŸÆü4&Bˆ"„ 5Ak‚ÖX?µ~jý”Ô&µIíÒû'.Ä…¸PCjH I9RŽ”Ó%Fì„Nè¤ËÎ.Y…UX%¥†ÔÕÕÝ~jû©í§·%nKÜ41hbÐD)FöBöBöBÚ¨cPÇ ŽAWG^yuäé§oœ¾Qݹºsugé]A)(¥.ä),}lÒUõêÕ?:>t|èøPJý_³gÍž5{†»‡»‡»×_TQýEÕ›Wo^½yňŠ#¬£¬£¬£§§§£ü7b#6ê&Qª†j¨¦«“ŸalÇýƒÑ~¤#1—–»ì¨B¼"Å~S§÷h_’0éJ×™qêÎ×:œó›ê®ž",!"YÄËã8î‹Vºw¹¼à%Œ”µ”µ6ÊÆËÆ 3d}e}…Dzñ²ñ(!A$H·¦!L` ïƒÒ³ƒìH $ÒD?ä¹@.|lSý©úSõ§V?Zýhõ£Ýú‡u[ôpÑÃEc,b,b,N&œL8ŸŸŸgggõ<êyÔó)ÙS²§d·èÝ¢w‹ÞÞ¼xø?0™&ÓdZŸÖ§õ¥l6¤éFºIïÎŽ›7;.ñxâñÄãƒâÅŠ'5H RCz·‘I#“F&1šMŒæÊ¹+箜kÛ­m·¶ºmII"I¿þD)ý¢c ÇŽ-|3|3|3jí©µ§ÖžzsëÍ­7·Þˆz#ê©R)¤’W°W°W°¾¾¾Š¨ˆêã½ãñuqê_fÀÇ}iÈ}bˆÛÒr}Gp§É%“ÏvË/ÖNѵ9c3žö¶\!¸±w‰´Ž,„6#Wx¹qÇq_‘ÒMIxÀCê•G"‘HF’‘d$ ¡!4ä×›ª†ª†ª†:884iߤ}“össçæÎÍÝ3kϬ=³Î/9¿äü’ä˜ä˜ä˜oo¼½ñöØ“cOŽ=ùaùËX1'bNÄœÊÝ*w«ÜM]¤.Rt¨¥,^/‹'ÉCò°¿þýû÷MŠMZµlÕêU«¥u| |µ¾Ú•Oøð‹ïß=¾ûȵ#׎\[z?tD'”””8‡8‡8‡øôé?²¦²¦²¦²Áµ×\««_W¿®~pfpfpf…é¦W˜nímímí­§§÷·[±“0 “P5QŽp„#äCÎ+÷uÜB>ÕŽZá4V±=¨…~•:ÙûZæ_žÛëpÃÉÂ"2ä#õž(ïx|NÜâ§N׈¿)»@ç M°8Š™ñÓÀqÇqLÃt·q›ÒBZ(ňk§j§j§þz#u[u[uÛ@‡@‡@ϧžO=ŸV4«hVѬ|ÝòuË×µíaÛöGa›Â6…mòmómómß4}ÓôMÓ«·¯Þ¾zûrþåüËùÏÇ<ó|Ì}½ûz÷õÄWâ+ñ•´çÀ!,;¹ló²Í/¿yÙäe“‘ûGy`lå±c|J|Œ}Œ£Y´,Z6¡`Bþ„|…\!WÈ-Œ-Œ-̃̃̃Œž=3z&/////O‘GäQΤœI9“²ŽeË:–a•a•aõöÅÛo_”4-iZÒôƒ/æw¸KÑð¬«Ãêèæå³r_±O÷i>"‘8ŠËFæÊéòøÝGîm×GÑWð¢M®ê-z'öL‰èuôíÕ òzŽê—ŒÝÄGü4pÇqÜJ7Lm`Ä"±ä¹Cî`9–c9˜À]y)ê0u˜:Ì)Ã)Ã)Ãã®Ç]»S¦Lõ}áûÂ÷…qeãÊÆ• &L4˜HshÍyºóéΧ;ï¾;øîàû¯î¿ºÿêÂÎ ».ìzµøÕÂW 7 ÞÐkC/ùDùxùøTšJS©Û2·En‹žŒ{2÷ÉÜ…>Zø({Jö”ì)ÖÖÖrs¹¹Ü\ã§ñÓøÏ,žY<ó­Ñ[£·FoF¿ýftŽwŽwŽwArArAòß×îpGk´Fk]z¢%=‹àÕãÞß>•ðGy¬Gî+Æ èŽÇuFôk×Ãê–~…‘l°^7ÅÃ]®Ô½ëÑ}ó^ï³Ï„r¤jë°'h58~28Žã8îw‘•JÃ.aé2½(‰’(µ‡µ‡µ$©¤KèºÄ¸Ä¸Ä¸¤ÒàJƒ+ ...pOsOsOsìçØÏ±ŸmÛ ¶Š6ee¿j’Ú$µIîY…ÆÂ¶V-ÛZ¶ÂlÙ)Ù)Fj’šd¾Ø@l°¤Õ¹Cæ>Ü|«õ­Öz•Ô>jŸìô¬UY«rbrbrb^—{]îu¹wÏÞ={÷¬xzñôâé(D!ÞOutçq¦0…©”)_—_šTzæÀqÜgÔþïS†ÉèéäšÃŽ´é¨}0Å¿Û%ÆfÕîí²¯}ç±õÍÉ8’@r± Ž`*ñÂã8Žã¸?©tܼj¨‰;q'ît@'PjBM>¶©þ}ýûú÷ƒË— .×}T÷QÝG-]µ4oiÞ©'_œ|‘Ð(9*9*ncŒÅždŒ±«÷Ä;â¤ÙŒ1ÖÄ¥Õ¬V³Êº¨]Ô¶•mØ.PUUýèqÞÅ]ÜÅZ¬ÅZØÂ¶¿qüÇýMš£"ÊI©–¨ yLǤõ»Ý¬K›:¦ûA–;½¨gÛ³™}÷7õV+UQÊ|éb%]qõ—©"8Žã8ŽûëJ7…¥,+ýÑýq'p‚´#íH;Z—Ö¥u½©þV}­¾Ö!Ëá‡Ú7éÖ©[§xçâqÅã..².²¾ä[˜P˜°³xqñâr—<“=“ãÓ¥TŒc1cQ5PCw |)Ç}AêÃŽºF=¬ÃÃýqÝî5¼ÃØ´ù=¾clZÝòëþÕk•a5ÉÈ[í =Pr q¼ð8Žã8îoRjX¤ )ô.½Kï õ…ú³´ÚÊž9=K­Çc0ÆØÃ¶Œ1ö21ƴ唀‘˜ùt› 'èa Æ`ŒncÞÎqŸåòýT²P„b´‚>ö 'ª½Z™W¶p ´4²S?íbÓµª ­ú;Å Y—׸±ä;Œ |H8ÇqÇýM4Ð@£[v†3œE&2‘Iýâ¤?™If"¶°ÍjôvÔÛQÝ-ÛömÛW[C0DŠ?Ê`9–¿%©Ñ©Ñ0ÄZ¬©vvæ` êöÌó½pÜ­laAdh 7P³Ã!hc3kõŠ(¹9éZ×eoÖoÙå~{›Õ惥èlÒ‹XðÂã8Žã8Žã¸ÿîÓõ¸¿CЉ9CìÄЗßf¥çÅä ÓF°Îì¬ñE¤|¥~uûlv A€{´hh‰éPST9Ô‚~hÇ\Í&éÍSäÐÆô¢…5”|p*ÇqÇqÇ}ܧîq_Ž H„ZhóÿPò4ëEáOÅ]`H_“É¢’%3o‹ ÕtÅ!Ÿ“XhÁò¬2ÇqÇq÷ß|ê÷ñ8ˆ³t±E”X¤-Ðn»!¯CAS@èCÓÄ­¬MŒÛ(M…h¹G¦é¶Òƒì“ ÇqÇqÇý‹|êæòbœÂáù‘¶€ dÈÌD~¹B9@3èOâöŒU0l(Ÿ$›aCµ[·Õ Ô€??ÇqÇq÷1Ÿºá^€”àŠ Ä+ˆ Ù{ŠC´“ 0°8'$Ò4²Ó~ ‰‘£´ÙŒîhÆOÇqÇqÇ}̧n¸`Ýð3» â»Åñ_ÈÄŸÄ™ä(ñ†¾ð†n¤-²ÔeU÷u[}Gê €Ÿ Žã8Žã8Žû˜OÝpgÀF"·¤²z]+ÉÃ÷Ú¾¬2f£",eß‘D2ØÆÈPÐwÖ!‹Ñ”„ò“ÁqÇqÇqóy†„vfûqYZÌð-ˆ(–—ÄhhãH6¾ES¼ -È ó‹z”«tëCu¸ó“ÁqÇqÇqóYîì¬ÇIiùÍÚü9…“ Wh<Äšä™î($‰›mºDo¤´Yp>8•ã8Žã8Žã>îó4ÜØD¶ zAH5ËÎÈK-ZrA“B÷܆Š’5æL¥7Aâ RŒ<ÇqÇqÇqú< ÷ºXŠí(€Ú×»sÏæÛN,Ù®CÆdr O0èb €?laN¢Ð!ÐB”bä9Žã8Žã8ŽûÐç‰q¯ùØH*c Fd—+°/ê[¨é©ñG{@d«‡¦Ã•§åK‹—x#&²},=_~J8Žã8Žã8î×dŸe¯·ŠtÜFÔd®¬[ðΧ(O£¯1ZÑP4S§ªš)½”*ùù ¢Õ%MK𑲆y ¸„ëüÄpÇqÇq\iŸ§Ç]ŠV¿‡7È‚ ¬aùΤx¦(©O‚ SÄÆ&£õê)[ºl„rÈÉs2ýø)á8Žã8Žã¸_û< w)Z] <Ä+¤§ß/ø¹x#€:ðgïØvGm¢)gÒMï„bJP‚ìF'ÎO ÇqÇqÇýý{>&³Cáñ’~|à(Ƴ'¬†~{ÙU!Ôð®rž|ˆ4$•Ì@]øðSÂqÇqÇq¿ö75ÜS;ät+T›ØA<Él Ö)ÉRŒ')È›èVÚ@¾A5~J8Žã8Žã8î×þ¦†û³òïºåDp†µh/ : Kioõh¹Rè)­C†ÁŽ<“;ÇqÇqÇýÚßÔpíšã–¿ ׉L´?2c6¯dfÂhÃBù[á®n¥Í¨‹Š<“;ÇqÇqÇýÚßÕã¾ý]™l'ø"å˜;†—°"†èdä£Ì—›B¨±qPCŸŸŽã8Žã8Ž+ís6ÜÓQ­´˜·¾(ºÄJôÓ¶fË„zÄ”œÑ‰ÊŒ4½at …ÈC®¶™ØEsøÂŸŽã8Žã8Ž+ís6Üãñ¹Òbq=ñ5{Y¯H­IöÓUD ˆ»ÅÊÖ “õ«ãE޳艨W8ðÃqÇqÇq¥}Άûy¼Ä[i±PÐ'¦_-X_4AæHï“–(ýØZÓ9zr¥µÜEè$dâ)ÈP v°à'†ã8Žã8ŽãJûœ ÷›x…,(AAJºi+ˆ6ïÆ†”ÄCº•8A)BüÁb„þ$ÕdU‚ì¹p´Ðêp€%?1ÇqÇqWÚgl¸³+xŽ7(‚VÔØik¿í’ÿ¤h/ ÉÚg,Óx²Žü¥¢•°›^×ÅÃ{ÂFüÄpÇqÇq\iŸ³Çý ž" ƒ` VÒO­U½Y›×³`#T”’Eš:b–`–¥z$ÿVñB° åu[ùÁ &üÄpÇqÇq\iŸ³á¾7ð€`±[lÍsÓ¬¹ÓáŒà¥ÝÇ&3‘Lñ³lœL$½È^ÝVž0…?1ÇqÇqWÚçl¸ŸÅ}<¥†$œ˜C5Œ^WÉy­Ð–<׆ŠYEe¤|Ý Oä…º­\`?1ÇqÇqWÚçl¸g£E(7¸£¹ÈÎy[œ¥¹Šb{Ó²¤¼aä¶ÕŒ©ïé¶"ü¤pÇqÇqÜÿïóÏœ:gqGZÌm]⥭wM9íNÚ”¤‘ ìRmÆ«Oñ“ÁqÇqÇqóÙîl Îã¶´œ=´ø¡æHÉÍ m­OTä(d¸gÖf†ëôeüdpÇqÇqÜÇ|þ†{Ûˆ3ÒrÆÜü×Å·³+uÒLª…ÄÀÜ´=lØQ/ŠŸ Žã8Žã8Žû˜Ï*Ó {qu§P¿Ø*/¿¸BÉ.êM»À%$Û…¾Ò¯ÎOÇqÇqÇ}Ìçïqï=ì4ȳ†Ù'åU+vÔô%]‰€‹H2 Q½”OÒmP-´ |˜*ÇqÇqǽ÷ù{Ük±eØ”¼½“—WPœs¬htñ€^%ßì$»bÖFÙ]¾ÁpG9ØÂF```üôpÇqÇqœäó÷¸·À ì¤WI#<ÖìÖdk s&Ö.ºBÓÁ~Â~ÓVÊnÂq\À]<Â\ÁA%?=ÇqÇq'ùü=îQHÄ]º‡“48à æo’ ú—ø¤ FLÍ*¨†ÊæÈfê×P$É_³óè…EØ„^hÁOÇqÇqÇIþ,¿²ßÔªƒœIEND®B`‚routino-3.0/doc/html/tagging.html 644 233 144 73414 12520735115 12274 0 Routino : Tagging Rules

Routino : Tagging Rules

Tags And Attributes

The different tags and attributes in the
OSM format XML that are used by Routino are described below.

Routino handles the tags in the input file after they have been processed according to a set of rules defined in a configuration file. The first half of this file describes the tags that are recognised by Routino after being processed; the second half of the file describes the transformations that are in the default tagging configuration file.

Tags Recognised After Processing

This section describes the tags that are recognised by Routino after the tag transformations have been applied. This is therefore a much reduced set of tags compared to the original OSM data and also includes tags which are specific to Routino.

In all cases of tag processing values of true, yes, 1 are recognised as being affirmative and any other value is negative.

Node Tags And Attributes

The node attributes id, latitude and longitude are used. The id attribute is required to associate the node with the ways and the position attributes are required to locate the node.

Transport Specific Tags

One tag is recognised for each of the different modes of transport: foot, horse, bicycle, wheelchair, moped, motorcycle, motorcar, goods, hgv and psv. These indicate whether the specific type of transport is allowed to pass through the node or not.

By default for nodes all types of transport are allowed to pass through a node and specific tags must be used to remove the permissions for the transport.

The roundabout Tag

The roundabout tag for mini-roundabouts is recognised and used to improve the description of the route.

Way Tags And Attributes

The tags from the ways in the data are the ones that provide most of the information for routing. The id attribute is used only so that the many segments associated with a way can share a set of tags taken from the way. The nd information is used to identify the nodes that make up the way.

The highway Tag

The most important tag that is used from a way is the highway tag. This defines the type of highway that the way represents. Any way that does not have a highway tag is discarded.

There are more highway types defined than are used by the router. The subset that the router uses are:

  • motorway
  • trunk
  • primary
  • secondary
  • tertiary
  • unclassified
  • residential
  • service
  • track
  • cycleway
  • path (1)
  • steps (2)

Note 1: This changed in version 1.3 of Routino - the bridleway and footway types were included within the path highway type.
Note 2: This changed in version 1.3 of Routino - the steps type was separated from the footway type.

Transport Specific Tags

One tag is recognised for each of the different modes of transport: foot, horse, bicycle, wheelchair, moped, motorcycle, motorcar, goods, hgv and psv. These indicate whether the specific type of transport is allowed on the highway or not.

By default for ways no types of transport are allowed to pass along a highway and specific tags must be used to add the permissions for the transport.

The name Tag

The name tag is used to provide the label for the highway when printing the results.

The ref Tag

The ref tag is used to provide the label for the highway when printing the results.

The lanes Tag

The lanes tag is used to identify whether a highway has multiple lanes for traffic and this is used to derive the multilane highway properties.

The paved Tag

The paved tag is used to identify whether a highway is paved or not, this is one of the available highway properties. A paved tag may exist in the original data but normally the surface tag needs to be transformed into the paved tag.

The multilane Tag

The multilane tag is used to indicate that a highway has multiple lanes for traffic.

The bridge Tag

The bridge tag is used to identify whether a highway is a bridge and therefore set one of the available properties.

The tunnel Tag

The tunnel tag is used to identify whether a highway is a tunnel and therefore set one of the available properties.

The footroute Tag

The footroute tag is used to identify whether a highway is part of a walking route and therefore set one of the available properties. This is not a standard OSM tag and is normally added to the individual highways by looking for route relations that are designated for foot access.

The bicycleroute Tag

The bicycleroute tag is used to identify whether a highway is part of a bicycle route and therefore set one of the available properties. This is not a standard OSM tag and is normally added to the individual highways by looking for route relations that are designated for bicycle access.

The cyclebothways Tag

The cyclebothways tag is used to identify whether a highway allows cycling in the opposite direction to a signposted oneway restriction.

The oneway Tag

The oneway tag is used to specify that traffic is only allowed to travel in one direction.

The roundabout Tag

The roundabout tag is used to specify that a highway is part of a roundabout to improve the description of the calculated route.

The maxspeed Tag

The maxspeed tag is used to specify the maximum speed limit on the highway; this is always measured in km/hr in OpenStreetMap data. If the tag value contains "mph" then it is assumed to be a value in those units and converted to km/hr.

The maxweight Tag

The maxweight tag is used to specify the maximum weight of any traffic on the highway. In other words this must be set to the heaviest weight allowed on the highway (for example a bridge) in tonnes. If the tag value contains "kg" then it is assumed that the value is in these units and converted to tonnes.

The maxheight Tag

The maxheight tag is used to specify the maximum height of any traffic on the highway. In other words this must be set to the lowest height of anything above the highway (like a bridge) in metres. If the tag value contains a measurement in feet or feet and inches then attempts are made to convert this to metres.

The maxwidth Tag

The maxwidth tag is used to specify the maximum width of any traffic on the highway. This must be set to the minimum width of the constraints at the wayside in metres. If the tag value contains a measurement in feet or feet and inches then attempts are made to convert this to metres.

The maxlength Tag

The maxlength tag is used to specify the maximum length of any traffic on the highway (usually from a traffic sign) in metres. If the tag value contains a measurement in feet or feet and inches then attempts are made to convert this to metres.

The area Tag

The area tag is used to specify that a way defines an area. This is used only so that in the case of duplicated segments those belonging to an area can be discarded in preference to those that are not.

Relation Tags And Attributes

The tags from the relations are used to associate more properties with the highways that are part of that relation. The id attribute is used so that relations that are members of other relations can be identified. The member information is used to identify the nodes and ways that make up the relation.

The footroute Tag

The footroute tag is used to identify whether a relation defines a walking route and therefore should be applied to the individual member highways.

The bicycleroute Tag

The bicycleroute tag is used to identify whether a relation defines a bicycle route and therefore should be applied to the individual member highways.

The type, restriction & except Tags

For turn relations the information about the allowed or disallowed turns are stored in the type, restriction and except tags. For a turn restriction the type must be equal to "restriction", the restriction must define the type of turn relation and except defines transport types which are exempt from the restriction.

Tag Transformations

This section describes the set of tag transformations that are contained in the default configuration file. The configuration file tagging rules are applied in sequence and this section of the document is arranged in the same order.

Node Tag Transformations

Barrier Defaults

The first part of the tag transformations is to decide on defaults for each type of node. This uses the barrier tag in the OSM file and converts it into a default set of disallowed transport types.

Transport types through different barrier types
Barrier foot horse wheelchair bicycle moped motorcycle motorcar goods hgv psv
kissing_gate, footgate, stile, v_stile, turnstile, squeeze, squeeze_stile, cycle_barrier, bicycle_barrier yes no no no no no no no no no
horse_stile, horse_jump, step_over yes yes no no no no no no no no
horse_barrier, cattle_grid yes no yes yes yes yes yes yes yes yes
motorcyle_barrier yes yes yes yes no no no no no no
bollard, car_barrier, car_trap yes yes yes yes yes yes no no no no

Generic Access Permissions

The access tag is used to specify the default access restrictions through the node. If the tag value is no or private or a selection of other values then all transport types are denied access (later tag transformation rules may add specific transport types back again).

Other Access Permissions

A tag named vehicle means any of the bicycle, moped, motorcycle, motorcar, goods, hgv and psv transport types. A tag named motor_vehicle is transformed to mean any vehicle except a bicycle.

Specific Access Permissions

The final part of the access permissions is to use the specific transport type tags.

One tag is recognised for each of the different modes of transport: foot, horse, bicycle, wheelchair, moped, motorcycle, motorcar, goods, hgv and psv. These indicate whether the specific type of transport is allowed through the node or not; the values listed for the access tag are also accepted here.

Mini-roundabouts

If the highway tag has the value mini_roundabout or the junction tag has the value roundabout then a junction tag with value roundaboutis passed through.

Way Tag Transformations

Highway Defaults

The first part of the tag transformations is to decide on defaults for each type of highway. This uses the highway tag in the OSM file and maps it into one of the highway tags that are recognised by Routino, defining the default allowed transport types and adding a number of properties.

The first part of the highway tag checking is to ignore the highway tag if it has a value that indicates a non-highway. These are the proposed and construction values for future highways, the no, abandoned and disused values for previous highways and a small number of other values.

The second part of the highway transformation is to convert the highway tag into one that is recognised by Routino.

Mapping of equivalent highway types
Original tag Transformed tag
motorway_link motorway
trunk_link trunk
primary_link primary
secondary_link secondary
tertiary_link tertiary
minor, road unclassified
living_street residential
access, services, layby service
byway, unsurfaced, unpaved track
footway, bridleway, pedestrian, walkway path
route=ferry ferry (1)
Note 1: A ferry route is converted into a highway of type "ferry" so that routes using a ferry can be calculated.

The type of highway also determines the defaults for the types of transport allowed on the highway. The default assumptions are as shown in the table below.

Transport types on different highway types
Highway foot horse wheelchair bicycle moped motorcycle motorcar goods hgv psv
motorway no no no no no yes yes yes yes yes
trunk no (1) no (1) no (1) yes yes yes yes yes yes yes
primary yes yes yes yes yes yes yes yes yes yes
secondary yes yes yes yes yes yes yes yes yes yes
tertiary yes yes yes yes yes yes yes yes yes yes
unclassified yes yes yes yes yes yes yes yes yes yes
residential yes yes yes yes yes yes yes yes yes yes
service yes yes yes yes yes yes yes yes yes yes
track yes yes yes yes no no no no no no
cycleway yes no yes yes no no no no no no
path yes yes (2) yes yes (2) no no no no no no
steps yes no no no no no no no no no
ferry (3) no no no no no no no no no no

Note 1: A trunk road may legally allow foot, horse or wheelchair access but in the absence of other tags is considered to be too dangerous.
Note 2: A path allows bicycle or horse access by default only if actually labelled as a highway of type "bridleway".
Note 3: Ferry routes must be explicitly tagged with the allowed transport types, it is not sensible to try to guess.

Finally for the highway tag a number of default properties are added depending on the highway type.

Default properties on different highway types
Highway Properties
motorway paved, oneway, multilane
trunk paved, multilane (1)
primary paved, multilane (1)
secondary paved
tertiary paved
unclassified paved
residential paved
service paved
track paved (2)
cycleway paved
path paved (3)
steps
ferry

Note 1: A highway of this type has the multilane property by default if it is oneway.
Note 2: A track is paved only if it is tagged as tracktype=grade1.
Note 3: A path is paved only if it was originally tagged as highway=walkway or highway=pedestrian.

Generic Access Permissions

The access tag is used to specify the default access restrictions on the highway. If the tag value is no or private or a selection of other values then all transport types are denied access (later tag transformation rules may add specific transport types back again).

Other Access Permissions

A tag named vehicle means any of the bicycle, moped, motorcycle, motorcar, goods, hgv and psv transport types. A tag named motor_vehicle is transformed to mean any vehicle except a bicycle.

The designation tag is used as an alternative method of identifying the legal right of way on a path (in the UK at least). The tag transformations convert these tags into a set of allowed transport types as shown below.

Aliasing of designation types
Designation tag Equivalent access permissions
restricted_byway foot=yes, wheelchair=yes, horse=yes, bicycle=yes
public_byway, byway, byway_open_to_all_traffic foot=yes, wheelchair=yes, horse=yes, bicycle=yes, moped=yes, motorcycle=yes, motorcar=yes
permissive_bridleway, public_bridleway, bridleway foot=yes, wheelchair=yes, horse=yes, bicycle=yes
public_cycleway foot=yes, wheelchair=yes, bicycle=yes
permissive_footpath, public_footpath, footpath foot=yes, wheelchair=yes

In addition to these there are some other tags and values that will modify the transport permissions on the highway.

A highway that is tagged as motorroad with a value of yes will deny access to foot, horse, wheelchair, bicycle and moped transport.

A highway that is tagged with footway or sidewalk and one of a set of popular values will allow foot and wheelchair access even if the road type would not normally do so.

A highway that is tagged as cycleway with one of several values will allow bicycle access. If the value of the cycleway tag is opposite_lane, opposite_track or opposite then the cyclebothways tag is set.

A highway that is tagged as oneway:bicycle with the value no will also cause the cyclebothways tag to be set.

Specific Access Permissions

The final part of the access permissions is to use the specific transport type tags.

One tag is recognised for each of the different modes of transport: foot, horse, bicycle, wheelchair, moped, motorcycle, motorcar, goods, hgv and psv. These indicate whether the specific type of transport is allowed on the highway or not.

Highway Properties

If there is a surface tag then the highway is assumed to be unpaved unless the tag value matches one of the following: paved, asphalt, concrete or many other values listed in the configuration file.

Support for the obsolete paved tag is also provided and the highway is paved if this is set to a true value.

The lanes tag is passed through to be used to set the multilane highway property.

The bridge and tunnel tags are copied directly from the input to the output.

Highway Restrictions

The oneway, maxspeed, maxweight, maxheight, maxwidth and maxlength are copied directly from the input to the output without modification.

Roundabouts

If a highway is tagged as junction=roundabout then a roundabout=yes tag created on the output.

Highway Names and References

The name and ref tags are copied directly from the input to the output.

Highway Areas

The area tag is copied directly from the input to the output.

Relation Tag Transformations

The type tag is passed through without change.

Routes

The route tag can be used to determine whether a relation is part of a walking or bicycle route so that the footroute or bicycleroute properties can be applied to the highways that make up that relation.

The tag transformations that are applied for route relations are defined in the table below.

Route properties from different route types
Relation Tag footroute Property bicycleroute Property
foot, walking, hiking yes no
bicycle no yes
bicycle;foot, foot;bicycle yes yes

Turn Restrictions

No tag transformations are defined for turn restriction relations but the restriction and except tags are passed through without change.
routino-3.0/doc/html/limits.html 644 233 144 17142 12520735050 12147 0 Routino : Numerical Limits

Routino : Numerical Limits

32/64-bit Data IDs

The OpenStreetMap data uses a numerical identifier for each node, way and relation. These identifiers started at 1 and increase for every new item of each type that is added. When an object is deleted the identifier is not re-used so the highest identifier will always be higher than the number of objects.

The identifier needs to be handled carefully to ensure that it does not overflow the data type allocated for it. Depending on the data type used to store the identifier there are are a number of numerical limits as described below:

  1. If a signed 32-bit integer is used to store the identifier then the maximum value that can be handled is 2147483647 (231-1) before overflow.
  2. If an unsigned 32-bit integer is used to store the identifier then the maximum value that can be handled is 4294967295 (232-1) before overflow.
  3. If a signed 64-bit integer is used to store the identifier then the maximum value that can be handled is 9223372036854775807 (263-1) before overflow.
For the purposes of this document the possibility of overflow of a 64-bit integer is ignored.

The part of Routino that handles the node, way and relation identifiers is the planetsplitter program.

ID Above 31-bits

The first identifier exceeding 31-bits (for a node) is predicted to be created in the OpenStreetMap database in February 2013.

All versions of Routino use unsigned 32-bit integers to store the identifier. Therefore all versions of Routino will continue working correctly when node number 2147483648 (231) or higher is present.

ID Above 32-bits

The ability of Routino to handle identifiers larger than 32-bits does not depend on having a 64-bit operating system.

Before version 2.0.1 of Routino there was no check that the identifier read from the input data would fit within an unsigned 32-bit integer. Earlier versions of Routino will therefore fail to report an error and will process data incorrectly when node number 4294967296 (232) or higher is present.

From version 2.0.2 the code is written to allow the node, way and relation identifier data type to be changed to 64-bits. This means that a consistent data type is used for handling identifiers and the format used for printing them is consistent with the variable type.

From version 2.0.2 onwards it is possible to make a simple change to the code to process data with node identifiers above 4294967296 (232) without error. The binary format of the database will be unchanged by the use of 64-bit identifiers (since the identifiers are not stored in the database).

To recompile with 64-bit node identifiers the file src/typesx.h should be edited and the two lines below changed from:

typedef uint32_t node_t;

#define Pnode_t PRIu32
to:
typedef uint64_t node_t;

#define Pnode_t PRIu64

A similar change can also be made for way or relation identifiers although since there are currently fewer of these the limit is not as close to being reached.

Between version 2.0.2 and version 2.4 a bug means that route relations will ignore the way or relation identifier if it is equal to 4294967295 (232-1).

From version 2.4 onwards when a numerical limit is reached the planetsplitter program will exit with an error message that describes which limit was reached and which data type needs to be changed.

Database Format

The other limitation in Routino is the number of objects stored in the database that is generated by the planetsplitter data processing. This number may be significantly different from the highest identifier in the input data set for two reasons. Firstly any nodes, ways or relations that have been deleted will not be present in the data. Secondly when a partial planet database (continent, country or smaller) is processed there will be only a fraction of the total number of nodes, ways and relations.

The limiting factor is the largest of the following.

  1. The number of nodes in the input data files.
  2. The number of segments in the input data files.
  3. The number of highways in the input data files.
  4. The number of relations in the input data files.
Normally the number of nodes will be the limiting factor.

32-bit Indexes

Before version 1.2 the database could hold up to 4294967295 (232-1) items of each type (node, segment, way) since an unsigned 32-bit integer is used.

Versions 1.3 to 1.4.1 have a limit of 2147483647 (231-1) items since half of the 32-bit integer range is reserved for fake nodes and segments that are inserted if a waypoint is not close to a node.

From version 1.5 the limit is 4294901760 (232-216) for the number of items of each type that can be stored. The small remaining part of the 32-bit unsigned integer range is reserved for fake nodes and segments.

64-bit Indexes

When using a 32-bit operating system it is not possible to create a database that exceeds about 2GB in total. This will be fewer than 232 objects in the database in total. The use of 64-bit indexes will require a 64-bit operating system.

From version 2.0.2 onwards it is possible to make a simple change to the code to index the database objects with 64-bit integers insted of 32-bit integers.

To recompile with 64-bit index integers the file src/types.h should be edited and the two lines below changed from:

typedef uint32_t index_t;

#define Pindex_t PRIu32
to:
typedef uint64_t index_t;

#define Pindex_t PRIu64
This change will affect nodes, segments, ways and relations together. The database that is generated will no longer be compatible with Routino that has been compiled with 32-bit indexes. The size of the database will also grow by about 50% when this change is made.
routino-3.0/doc/html/readme.html 644 233 144 26021 12575035402 12103 0 Routino : Software

Routino : Software

Routino Introduction

Routino is an application for finding a route between two points using the dataset of topographical information collected by http://www.OpenStreetMap.org.

Starting from the raw OpenStreetMap data (in the form of the '.osm' XML files available on the internet) a custom database is generated that contains the information useful for routing. With this database and two points specified by latitude and longitude an optimum route (either shortest or quickest) is determined. The route is calculated for OpenStreetMap highways (roads, paths etc) using one of the common forms of transport defined in OpenStreetMap (foot, bicycle, horse, motorcar, motorcycle etc).

When processing the OpenStreetMap data the types of highways are recorded and these set default limits on the types of traffic allowed. More specific information about permissions for different types of transport are also recorded as are maximum speed limits. Further restrictions like one-way streets, weight, height, width and length limits are also included where specified. Additionally a set of properties of each highway are also recorded. The processing of the input file is controlled by a configuration file which determines the information that is used.

When calculating a route the type of transport to be used is taken into account to ensure that the known restrictions are followed. Each of the different highway types can further be allowed or disallowed depending on preferences. For each type of highway a default speed limit is defined (although the actual speed used will be the lowest of the default and any specified in the original data). To make use of the information about restrictions the weight, height, width and length of the transport can also be specified. Further preferences about road properties (e.g. paved or not) can also be selected. The simplest type of turn restrictions (those formed from an initial way, a node and a second way) are also obeyed.

The result of calculating the route can be presented in several different ways. An HTML file can be produced that contains a description of the route to take with instructions for each of the important junctions. The contents of the file are created based on a set of translations specified in a configuration file. The route is also available in a GPX (GPS eXchange) XML format. format file containing either every point and highway segment (a track file) or just a waypoint and translated instructions for the important junctions (a route file). Additionally there are two plain text files that contain all data points or just the important ones (intended for debugging and further processing).

One of the design aims of Routino was to make the software are flexible as possible in selecting routing preferences but also have a sensible set of default values. Another design aim was that finding the optimum route should be very fast and most of the speed increases come from the carefully chosen and optimised data format.

Disclaimer

The route that is calculated by this software is only as good as the input data.

Routino comes with ABSOLUTELY NO WARRANTY for the software itself or the route that is calculated by it.

Demonstration

A live demonstration of the router for the UK is available on the internet in both OpenLayers and Leaflet versions:
http://www.routino.org/uk-leaflet/
http://www.routino.org/uk-openlayers/

The source code download available below also includes a set of files that can be used to create your own interactive map.

The interactive map is made possible by use of the OpenLayers or Leaflet Javascript library from http://www.openlayers.org/ or http://leafletjs.com/.

Documentation

A full set of documentation is available that describes how to install and use the programs as well as what should go in the configuration files and how it works.

Status

Version 1.0 of Routino was released on 8th April 2009.
Version 1.1 of Routino was released on 13th June 2009.
Version 1.2 of Routino was released on 21st October 2009.
Version 1.3 of Routino was released on 21st January 2010.
Version 1.4 of Routino was released on 31st May 2010.
Version 1.4.1 of Routino was released on 10th July 2010.
Version 1.5 of Routino was released on 30th October 2010.
Version 1.5.1 of Routino was released on 13th November 2010.
Version 2.0 of Routino was released on 30th May 2011.
Version 2.0.1 of Routino was released on 7th June 2011.
Version 2.0.2 of Routino was released on 26th June 2011.
Version 2.0.3 of Routino was released on 4th August 2011.
Version 2.1 of Routino was released on 3rd October 2011.
Version 2.1.1 of Routino was released on 23rd October 2011.
Version 2.1.2 of Routino was released on 12th November 2011.
Version 2.2 of Routino was released on 3rd March 2012.
Version 2.3 of Routino was released on 21st July 2012.
Version 2.3.1 of Routino was released on 11th August 2012.
Version 2.3.2 of Routino was released on 6th October 2012.
Version 2.4 of Routino was released on 8th December 2012.
Version 2.4.1 of Routino was released on 17th December 2012.
Version 2.5 of Routino was released on 9th February 2013.
Version 2.5.1 of Routino was released on 20th April 2013.
Version 2.6 of Routino was released on 6th July 2013.
Version 2.7 of Routino was released on 22nd March 2014.
Version 2.7.1 of Routino was released on 17th May 2014.
Version 2.7.2 of Routino was released on 26th June 2014.
Version 2.7.3 of Routino was released on 8th November 2014.
Version 3.0 of Routino was released on 12th September 2015.

The full version history is available in the NEWS.txt file.

Changes in Versions 3.0

Version 3.0 - Windows compilation and library providing routing API.
Bug fixes:
Use a single definition of MAX_SEG_PER_NODE to avoid confusion.
Fix bug with built-in translation strings if no XML translations available.
Fix bug with makefiles related to creating new translations.
Remove some pthread code that was still there when compiling without pthreads.
Fix a use-after-free memory error and use of uninitialised allocated memory.
Ensure that allocated strings are long enough for temporary filenames.
Programs:
Add a '--version' option to all of the programs.
Source Code:
Various C language cleanups including using '-pedantic' compiler option.
Various changes to allow compiling with Microsoft Visual Studio C compiler.
Various changes to allow compiling with MinGW or Cygwin on Microsoft Windows.
Makefile updates: 'make clean' = release, 'make distclean' = SVN repository.
API:
Create a library API that can perform routing functions.
OSM tagging:
Remove cycle_barrier and bicycle_barrier since they do not block bicycles.
Translations:
Updated Dutch and German translations.
Added Hungarian and Polish translations provided through translation web page.
Documentation:
Add meta tags to HTML to help mobile devices, tidy up the CSS.
Create instructions for compiling on Microsoft Windows.
Create API description for Routino library usage.
Web pages:
Allow drag-and-drop of waypoints within the list and onto the map.

Note: This version is compatible with databases from version 2.7.1 - 2.7.3.

License

This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.

It is important to note that for this program I have decided to use the Affero GPLv3 instead of just using the GPL. This license adds additional requirements to anybody who provides a networked service using this software.

Copyright

Routino is copyright Andrew M. Bishop 2008-2015.

Homepage

The Routino homepage has the latest news about the program.

Download

The download directory contains the latest version of the source code.

Subversion

The source code can also be downloaded from the Subversion repository with a command like the following:
svn co http://routino.org/svn/trunk routino

The source code can also be browsed in the Subversion viewer which also has a list of the latest changes.

routino-3.0/doc/html/configuration.html 644 233 144 24522 12520734744 13526 0 Routino : Configuration

Routino : Configuration

XML Configuration Files

New in version 1.4 of Routino is the use of configuration files to allow more information to be provided to the programs at run-time. The configuration files that are used are:
  • Tagging transformation rules for the planetsplitter program.
  • Routing profiles for the router program.
  • Output translations for the router program.
In keeping with the nature of the input and output files the configuration files are also XML files. Each of the files uses a custom defined XML schema and an XSD file is provided for each of them.

Tag Transformation Rules

The default name of the tagging transformation rules XML configuration file is tagging.xml in the same directory as the generated database files. Other filenames can be specified on the command line using the --tagging option. When processing the input it is possible to have a different set of tagging rules for each file; for example different rules for different countries.

The tagging rules allow modifying the highway tags in the source file so that the routing can be performed on a simpler set of tags. This removes the special case tagging rules from the source code into the configuration file where they can be easily modified. Part of the provided tagging.xml file showing the rules for motorway_link and motorway highway types.

<?xml version="1.0" encoding="utf-8"?>
<routino-tagging>

  <way>

    <if k="highway" v="motorway_link">
      <set v="motorway"/>
    </if>

    <if k="highway" v="motorway">
      <output k="highway"/>

      <output k="motorcycle" v="yes"/>
      <output k="motorcar"   v="yes"/>
      <output k="goods"      v="yes"/>
      <output k="hgv"        v="yes"/>
      <output k="psv"        v="yes"/>

      <output k="paved"      v="yes"/>
      <output k="multilane"  v="yes"/>
      <output k="oneway"     v="yes"/>

      <unset k="highway"/>
    </if>
...
  <way>

</routino-tagging>
The rules all have the same format; an if or ifnot element at the top level for matching the input and some other elements inside to be used if there was a match.

Within the if and ifnot rules any of the rules can be used. These are if, ifnot, set, unset, output or logerror elements.

The rules for matching the if or ifnot elements are the following:

  • An if rule that has both k and v specified is only matched if a tag exists in the input that matches both.
  • An if rule that has only the k attribute is matched if a tag with that key exists.
  • An if rule that has only the v attribute is matched for each tag with that value (i.e. the contents may be used more than once).
  • An if rule that has neither attribute specified always matches.
  • An ifnot rule that has both k and v specified is only matched if no tag exists in the input that matches both.
  • An ifnot rule that has only the k attribute is matched only if no tag with that key exists.
  • An ifnot rule that has only the v attribute is only matched if no tag with that value exists.
  • An ifnot rule that has neither attribute specified never matches.

For set, unset, output or logerror elements inside of an if rule an unspecified value for the k or v attribute is replaced by the values from the tag that matched the outer if rule. This makes it simple to delete tags that match a particular rule without having to specify the parameters more than once. For elements inside of an ifnot element an unspecified value for the k or v attribute is replaced by the values from the outer ifnot rule. This means that either the outer ifnot element or the inner element must specify both k and v attributes between them. For nested if or ifnot elements the outer k and v attributes are not inherited by the inner elements.

The set and unset elements either create or delete a tag from the input data that was read from the file. If the set element is used and the tag already exists then it is modified. The output element adds a tag to the set that will be used by Routino to determine the data properties.

The logerror element will cause an error message to be added to the error log file that reports that the key and attribute combination are not recognised. If the k attribute is specified but not the v attribute then the tag value that matches the specified key is looked up and used. An additional message attribute can be specified to be printed at the end of the logged error.

The default logged error message is:

Node XXX has an unrecognised tag 'key' = 'value' (in tagging rules); ignoring it.

The specified message attribute will replace the final part of the logged error.

Routing Profiles

The default name of the routing profiles XML configuration file is profiles.xml in the same directory as the database files. Other filenames can be specified on the command line using the --tagging option.

The purpose of this configuration file is to allow easy modification of the routing parameters so that they do not all need to be specified on the command line. In versions of Routino before version 1.4 the default routing parameters (preferred highways, preferred speeds etc) were contained in the source code, now they are in a configuration file. When calculating a route the --profile option selects the named profile from the configuration file.

Part of the provided profiles.xml file showing the parameters for transport on foot is shown below:

<?xml version="1.0" encoding="UTF-8" ?>
<routino-profiles>

  <profile name="foot" transport="foot">
    <speeds>
...
      <speed highway="cycleway"      kph="4" />
      <speed highway="path"          kph="4" />
      <speed highway="steps"         kph="4" />
    </speeds>
    <preferences>
...
      <preference highway="cycleway"      percent="95" />
      <preference highway="path"          percent="100" />
      <preference highway="steps"         percent="80" />
    </preferences>
    <properties>
      <property type="paved"        percent="50" />
      <property type="multilane"    percent="25" />
      <property type="bridge"       percent="50" />
      <property type="tunnel"       percent="50" />
...
    </properties>
    <restrictions>
      <oneway obey="0" /> 
      <weight limit="0.0" />
      <height limit="0.0" />
      <width  limit="0.0" />
      <length limit="0.0" />
    </restrictions>
  </profile>
  <profile name="horse" transport="horse">
...
  </profile>
...
</routino-profiles>

Output Translations

The default name of the output translations XML configuration file is translations.xml in the same directory as the database files. Other filenames can be specified on the command line using the --translations option.

The generated HTML and GPX output files (described in the next section) are created using the fragments of text that are defined in this file. Additional languages can be added to the file and are selected using the --language option to the router. If no language is specified the first one in the file is used.

Part of the provided translations.xml file showing some of the English language (en) translations is shown below:

<?xml version="1.0" encoding="utf-8"?>
<routino-translations>

  <language lang="en">
...
    <turn direction="-4" string="Very sharp left" />
    <turn direction="-3" string="Sharp left" />
    <turn direction="-2" string="Left" />
...
    <heading direction="-4" string="South" />
    <heading direction="-3" string="South-West" />
    <heading direction="-2" string="West" />
...
    <route type="shortest" string="Shortest" />
    <route type="quickest" string="Quickest" />
    <output-html>
...
    </output-html>
    <output-gpx>
...
    </output-gpx>
  </language>
</routino-translations>
routino-3.0/doc/INSTALL.txt 644 233 144 32656 12572106465 10703 0 Routino : Installation ====================== Quick Start Guide ----------------- The instructions below are a complete list of the minimum required to get Routino installed and running under Apache on Debian Linux. Other Linux versions will be similar and other UNIX based systems will also be similar although may have distinct differences. There is some support in Routino for compiling on Microsoft Windows which has its own installation instructions. *********************************************************************** *** These instructions should not be considered as complete or a *** *** secure installation for the reasons given in more detail below. *** *********************************************************************** The starting point for the installation is in the Routino source code directory after it has been uncompressed. Most of the steps will need to be run as the root user. The first thing to do is to install the packages which are required for compilation of Routino as described in the Pre-Requisites section below. apt-get install gcc make libc6-dev libz-dev libbz2-dev After this the programs can be compiled: make The files for the web interface can now be copied to the web server directory. On Debian this is '/var/www' and the files changed to be owned by the user Apache runs as. cp -a web /var/www/routino chown -R www-data:www-data /var/www/routino To be able to use Routino some data will need to be processed and a script is provided for this. This will download the data for the UK which may take a while and then process it. cd /var/www/routino/data sh -x create.sh The routino web pages also requires either the OpenLayers or Leaflet Javascript library to be downloaded and installed and scripts are provided for this. cd /var/www/routino/www/openlayers sh -x install.sh cd /var/www/routino/www/leaflet sh -x install.sh To make full use of the location search feature on the Routino web page you will need to install some extra perl packages. apt-get install libwww-perl liburi-perl libjson-pp-perl Finally to make the web pages work you will need to add the extra lines to the Apache configuration file as described in the Configuration of Web Server section below. You don't have to use 'vi' and can use any text editor. vi /etc/apache2/sites-enabled/000-default apache2ctl restart Now everything should be set up and the web page should work if accessed at 'http://localhost/routino/www/routino/router.html'. When everything is working you should read the rest of this document carefully and make the following changes: * Download your choice of OSM data - edit the file data/create.sh and run it again. * Edit the www/routino/mapprops.js file to match the downloaded data and personal map preferences. * Move the files in the web server directory so that only the contents of the www directory are accessible by the web server. * Edit the file www/routino/paths.pl to reference the new file locations. Pre-Requisites -------------- The programs are written in standard C language with minimal external requirements so only a small set of development tools are required (gcc, make). The compilation tools to use and the command line options are defined in the file 'Makefile.conf'. There is some support for multi-threading that uses pthreads and additional development libraries for this may be required (on Linux this might be part of the standard C language development files). The multi-threading is enabled by default but can be disabled at compile time by commenting out two lines in the file 'Makefile.conf'. To use the built-in gzip file decompression function and to process all PBF format files the zlib (or libz) development library is required (on Linux this might be in a package called libz-dev). The gzip function is enabled by default but can be disabled by commenting out two lines in the file 'Makefile.conf'. To use the built-in bzip2 file decompression functions the bzip2 (or libbz2) development library is required (on Linux this might be in a package called libbz2-dev). The bzip2 function is enabled by default but can be disabled by commenting out two lines in the file 'Makefile.conf'. To use the built-in xz file decompression functions the liblzma development library is required (on Linux this might be in a package called liblzma-dev). The xz function is not enabled by default but can be enabled by uncommenting two lines in the file 'Makefile.conf'. To compile the source code from subversion requires the Perl Graphics::Magick module to generate the web page icons (on Linux this might be in a package called libgraphics-magick-perl). The released source code packages contains the icons so this package is not required for compilation. To use the web page interface an http server is required. Instructions below are for Apache but any server that supports CGIs should work. The web pages use the Perl scripting language and a number of the default Perl modules. To use the search function on the router web page the Perl module JSON::PP must be installed (on Linux this might be in a package called libjson-pp-perl if not part of the standard Perl installation). Compilation ----------- To compile the programs just type 'make' at the top level of the source tree. This program has been written to run on Linux, no cross-platform compatibility has been specifically included but on the other hand other platforms have not knowingly been excluded either. Any information on improving the compilation process on anything other than x86 Linux is welcome. Installation ------------ After compilation the executable files are copied into the directory web/bin and the default XML configuration files are copied into the directory web/data. This is in preparation for using the supplied example web pages but is also a useful location to copy the files from for normal use. The required executable files are 'planetsplitter', 'router' and 'filedumper' and the '*-slim' versions of the same files. They can be copied to any location and need no special installation environment. The 'filedumperx' executable is for debugging and not required. The configuration files are called 'profiles.xml', 'tagging.xml' and 'translations.xml'. The names of the configuration files can be specified on the command line but by default are also looked for in the directory that contains the routing database with these names. Example Web Page ---------------- The directory 'web' contains a set of files that can be used to create a working set of web pages with interfaces to the routing algorithm. The files in the 'web' directory will require copying to a location that is accessible by a web server. After copying the files some of them need to be edited; search through the files for lines that contain the words "EDIT THIS" and make appropriate edits. The files that need editing are 'paths.pl' (to set the directory paths) and 'mapprops.js' (to set the map properties). Configuration of web files -------------------------- The assumption in this description is that the whole of the directory called web is copied into a directory that is accessible by an Apache web server. ************************************************************************** **** This is not a secure configuration but an easy one to configure. **** **** Only the directory 'www' should be accessible by the web server. **** **** Do not use this configuration unmodified in a public web server. **** ************************************************************************** The directory structure is as follows: web/ | + /bin/ <- The Routino executable files (when compiled). | + /data/ <- The Routino database and default configuration | files. | + /results/ <- An empty directory to store the results. | + /www/ <- The files that must be available to the web | server are below this level. | + /openlayers/ <- A directory to hold the OpenLayers library | (optional; leaflet can be used instead). | + /leaflet/ <- A directory to hold the Leaflet library. | (optional; openlayers can be used instead). | + /routino/ <- The main HTML, Javascript, CSS and CGI files. | + /documentation/ <- The HTML version of the Routino documentation. The directory 'bin' will be filled by running the compilation process. For a secure installation the 'bin' directory should be outside of the web server, the file 'www/routino/paths.pl' contains the path to the 'bin' directory. The directory 'data' must contain the Routino database and is also the default location for the configuration files. The routing database is created by downloading the OSM files for the region of interest and running the 'planetsplitter' program. There is a script in the directory that will download the OSM files and create the required database. The script should be edited to set the names of the files to be downloaded. For a secure installation the 'data' directory should be outside of the web server, the file 'www/routino/paths.pl' contains the path to the 'data' directory. The directory 'results' is a temporary directory that it used to hold the GPX and text files generated by the Routino router. The directory must be writable by the web server process since it is the CGI scripts that are run by the web server that writes the results here. For a secure installation the results directory should be outside of the web server, the file 'www/routino/paths.pl' contains the path to the results directory. The directory 'www' and its sub-directories are the only ones that need to be within the web server accessible directory. A Javascript map drawing library is required and either OpenLayers or Leaflet can be used. The library is loaded dynamically when the HTML is opened based on the value that is selected in 'mapprops.js'. The directory 'www/openlayers' is for the OpenLayers Javascript library that can be downloaded from 'http://www.openlayers.org/'. (This version of Routino has been tested with OpenLayers library versions 2.12 and 2.13.1). The file 'www/openlayers/OpenLayers.js' and the directories 'www/openlayers/img/' and 'www/openlayers/theme/' must all exist. There is a script in the 'www/openlayers' directory that will automatically download the files, create an optimised 'OpenLayers.js' and copy the files to the required locations. The directory 'www/leaflet' is for the Leaflet Javascript library that can be downloaded from 'http://leafletjs.com/'. (This version of Routino has been tested with Leaflet library versions 0.7.1 and 0.7.2). The files 'www/leaflet/leaflet.js' and 'www/leaflet/leaflet.css' and the directory 'www/leaflet/images/' must all exist. There is a script in the 'www/leaflet' directory that will automatically download the files. The directory 'www/routino' contains the main HTML, Javascript and CSS files as well as the CGI scripts that perform the server-side routing functions. The description below lists all of the files that contain editable information. paths.pl This contains the names of the directories that contain the executable files, router database and temporary results; the prefix for the routing database; and the names of the executables. mapprops.js The parameters in this file control the Javascript map library (defaults to OpenLayers), the boundary of the visible map (defaults to UK), the minimum and maximum zoom levels (defaults to between 4 and 15 inclusive), the source of map tiles (defaults to the main OpenStreetMap tile server), the data editing and browsing URLs (default to the OpenStreetMap website) and the number of waypoints allowed (defaults to 9). The directory www/routino/documentation contains the HTML version of the Routino documentation. Configuration of Web Server --------------------------- The file 'www/routino/.htaccess' contains all of the Apache configuration options that are required to get the example web pages running. The only problem is that because of the way that the "AllowOverride" option works one of the configuration options has been commented out. This must be enabled in the main Apache server configuration file. If you have copied the routino 'web' directory into '/var/www' and named it 'routino' then the entry that you need in your Apache configuration file is this one: AllowOverride All Options +ExecCGI This can be placed anywhere between the and tags which should be at the start and end of the file. -------- Copyright 2008-2015 Andrew M. Bishop. routino-3.0/doc/OUTPUT.txt 644 233 144 30700 12561371522 10615 0 Routino : Output ================ There are three different formats of output from the router, HTML, GPX (GPS eXchange) XML format and plain text with a total of five possible output files: * HTML route instructions for each interesting junction. * GPX track file containing every node. * GPX route file with waypoints at interesting junctions. * Plain text description with the interesting junctions. * Plain text file with every node. The "interesting junctions" referred to above are junctions where the route changes to a different type of highway, more than two highways of the same type meet, or where the route meets but does not take a more major highway. When the route follows a major road this definition eliminates all junctions with minor roads. The output files are written to the current directory and are named depending on the selection of shortest or quickest route. For the shortest route the file names are "shortest.html", "shortest-track.gpx", "shortest-route.gpx", "shortest.txt" and "shortest-all.txt", for the quickest route the names are "quickest.html", "quickest-track.gpx", "quickest-route.gpx", "quickest.txt" and "quickest-all.txt". The HTML file and GPX files are written out according to the selected language using the translations contained in the translations.xml configuration file. The text files contains untranslated header lines (in English) but the data is translated. HTML Route Instructions ----------------------- The HTML route instructions file contains one line for the description of each of the interesting junctions in the route and one line for each of the highways that connect them. The coordinates are also included in the file but are not visible because of the style definitions. An example HTML file output is below (some parts are missing, for example the style definitions): Shortest Route ...

Shortest Route

1:51.524658 -0.127877
Start:At Waypoint, head South-East
Follow:Woburn Place (A4200) for 0.251 km, 0.3 min [0.3 km, 0 minutes]
2:51.522811 -0.125781
At:Junction, go Straight on heading South-East
Follow:Russell Square (A4200) for 0.186 km, 0.2 min [0.4 km, 1 minutes]
3:51.521482 -0.124123
At:Junction, go Straight on heading South-East
Follow:Southampton Row (A4200) for 0.351 km, 0.4 min [0.8 km, 1 minutes] ...
21:51.477678 -0.106792
At:Junction, go Slight left heading South-East
Follow:Vassall Road for 0.138 km, 0.2 min [6.3 km, 6 minutes]
22:51.478015 -0.104870
At:Junction, go Straight on heading East
Follow:Vassall Road for 0.087 km, 0.1 min [6.4 km, 6 minutes]
23:51.478244 -0.103651
Stop:At Waypoint
Total:6.4 km, 6 minutes
GPX Track File -------------- The GPX track file contains a track with all of the individual nodes that the route passes through. An example GPX track file output is below: Creator : Routino - http://www.routino.org/ http://www.openstreetmap.org/copyright Shortest route Shortest route between 'start' and 'finish' waypoints ... GPX Route File -------------- The GPX route file contains a route (ordered set of waypoints) with all of the interesting junctions that the route passes through and a description of the route to take from that point. An example GPX route file output is below: Creator : Routino - http://www.routino.org/ http://www.openstreetmap.org/copyright Shortest route Shortest route between 'start' and 'finish' waypoints START South-East on 'Woburn Place (A4200)' for 0.251 km, 0.3 min TRIP001 South-East on 'Russell Square (A4200)' for 0.186 km, 0.2 min TRIP002 South-East on 'Southampton Row (A4200)' for 0.351 km, 0.4 min ... TRIP020 South-East on 'Vassall Road' for 0.138 km, 0.2 min TRIP021 East on 'Vassall Road' for 0.087 km, 0.1 min FINISH Total Journey 6.4 km, 6 minutes Text File --------- The text file format contains one entry for all of the interesting junctions in the route and is intended to be easy to interpret, for example for creating other output formats. An example text file output is below: # Creator : Routino - http://www.routino.org/ # Source : Based on OpenStreetMap data from http://www.openstreetmap.org/ # License : http://www.openstreetmap.org/copyright # #Latitude Longitude Section Section Total Total Point Turn Bearing Highway # Distance Duration Distance Duration Type 51.524658 -0.127877 0.000 km 0.0 min 0.0 km 0 min Waypt +3 Woburn Place (A4200) 51.522811 -0.125781 0.251 km 0.3 min 0.3 km 0 min Junct +0 +3 Russell Square (A4200) 51.521482 -0.124123 0.186 km 0.2 min 0.4 km 1 min Junct +0 +3 Southampton Row (A4200) ... 51.477678 -0.106792 0.204 km 0.2 min 6.1 km 5 min Junct +0 +3 Vassall Road 51.478015 -0.104870 0.138 km 0.2 min 6.3 km 6 min Junct +0 +2 Vassall Road 51.478244 -0.103651 0.087 km 0.1 min 6.4 km 6 min Waypt The text file output contains a header (indicated by the lines starting with '#') and then one line for each waypoint or junction. Each line contains the information for the current node and the next segment to be followed. For each of the lines the individual fields contain the following: Latitude - Location of the node (degrees) Longitude - Location of the node (degrees) Section Distance - The distance travelled on the section of the journey that ends at this node. Section Duration - The duration of travel on the section of the journey that ends at this node. Total Distance - The total distance travelled up to this point. Total Duration - The total duration of travel up to this point. Point Type - The type of point; either a waypoint Waypt or junction Junct. Turn - The direction to turn at this point (missing for the first line since the journey has not started yet and for the last line because it has finished). This can take one of nine values between -4 and +4 defined by: 0 = Straight, +2 = Right, -2 = Left and +/-4 = Reverse. Bearing - The direction to head from this point (missing for the last line since the journey has finished). This can take one of nine values between -4 and +4 defined by: 0 = North, +2 = East, -2 = West and +/-4 = South. Highway - The name (or description) of the highway to follow from this point (missing on the last line since the journey has finished). The individual items are separated by tabs but some of the items contain spaces as well. All Nodes Text File ------------------- The all nodes text file format contains one entry for each of the nodes on the route. An example all nodes text file output is below: # Creator : Routino - http://www.routino.org/ # Source : Based on OpenStreetMap data from http://www.openstreetmap.org/ # License : http://www.openstreetmap.org/copyright # #Latitude Longitude Node Type Segment Segment Total Total Speed Bearing Highway # Dist Durat'n Dist Durat'n 51.524658 -0.127877 8439703* Waypt 0.000 0.00 0.00 0.0 51.523768 -0.126918 8439948* Junct- 0.119 0.15 0.12 0.1 96 146 Woburn Place (A4200) 51.522811 -0.125781 8440207* Junct 0.132 0.17 0.25 0.3 96 143 Woburn Place (A4200) ... 51.478015 -0.104870 8529638* Change 0.138 0.17 6.26 5.6 48 74 Vassall Road 51.478127 -0.104174 8529849* Junct- 0.049 0.04 6.31 5.7 64 75 Vassall Road 51.478244 -0.103651 8530008 Waypt 0.038 0.04 6.35 5.7 64 70 Vassall Road The all nodes text file output contains a header (indicated by the lines starting with '#') and then one line for each node and the segment that was used to reach it. This file therefore contains exactly the same model as is used internally to define a route (a series of results each of which is a node and the segment leading to it). For each of the lines the individual fields contain the following: Latitude - Location of the node in degrees. Longitude - Location of the node in degrees. Node - The internal node number and an indicator "*" if the node is a super-node. Type - The type of point; a waypoint Waypt, important junction Junct, unimportant junction Junct-, change of highway Change or intermediate node Inter. Segment Distance - The distance travelled on the segment defined on this line. Segment Duration - The duration of travel on the segment defined on this line. Total Distance - The total distance travelled up to this point. Total Duration - The total duration of travel up to this point. Speed - The speed of travel on the segment defined on this line (missing on the first line). Bearing - The direction that the segment defined on this line travels in degrees (missing on the first line). Highway - The name (or description) of the highway segment (missing on the first line). -------- Copyright 2008-2011 Andrew M. Bishop. routino-3.0/doc/DATALIFE.txt 644 233 144 21262 12422721567 10735 0 Planetsplitter Data Lifetime ============================ Key (memory mapping): nswr = Mapped into memory read-only NSWR = Mapped into memory read/write Key (structure parameter usage): C = Created (allocated then written; write-only) D = Destroyed (read then de-allocated; read-only) U = Used (read; read-only) W = Written (written; write-only) M = Modified (read then written; read/write) T = Temporary (written then read; read/write) | = Preserved unmodified for later * = In this loop the current iteration of (super-)segments are in uppercase, the next iteration are in lowercase. ............................. : Nodes \ : |Segments | Mapped into : ||Ways | memory : |||Relations / : |||| ........................... : vvvv : nodesx->idata : : | . nodesx->gdata : : | . | . nodesx->pdata : : | . | . | . nodesx->super : : | . | . | . | . nodex->id : : | . | . | . | . | ................................... : : v . v . v . v . v : segmentsx->firstnode : : . . . . : | . segmentsx->next1 : : . . . . : | . | . segmentsx->usedway : : . . . . : | . | . | . segmentx->node1,2 : : . . . . : | . | . | . | . segmentx->next2 : : . . . . : | . | . | . | . | . segmentx->way : : . . . . : | . | . | . | . | . | .................. : : . . . . : v . v . v . v . v . v : waysx->idata : : . . . . : . . . . . : | . waysx->cdata : : . . . . : . . . . . : | . | . wayx->id : : . . . . : . . . . . : | . | . | ............... Function name (in order) : : . . . . : . . . . . : v . v . v : relationx->id | : : . . . . : . . . . . : . . : | ........... v : : . . . . : . . . . . : . . : v : :......:...................:.......................:...........:...: (Parse XML etc) : : . . . . W : . . . . . : . . W : W : :......:...................:.......................:...........:...: SortNodeList : : C . . . . U : . . . . . : . . | : | : SortWayList : : | . . . . | : . . . . . : C . . U : | : SortRelationList : : | . . . . | : . . . . . : | . . : U : RemoveNonHighwayNodes : : M . . . . U : . . . . . : | . . : | : SplitWays : : U . . . . : . . . W . . W : U . . : | : SortWayNames : W : | . . . . : . . . | . . | : | . . : | : SortSegmentList : : | . . . . : . . . U . . | : | . . : | : ProcessSegments : n : U . . . . : . . C . U . . U : U . . : | : IndexSegments : S : | . . . . : C . . | . U . W . | : | . . : | : ProcessRouteRelations : W : | . . . . : | . . | . | . | . | : U . . : U : ProcessTurnRelations : Nsw : D . . . . : D . . | . U . U . | : D . . : U : CompactWayList : : . . . . : . . D . | . . | : . C . T : : :......:...................:.......................:...........:...: SortNodeListGeographically : : . C . . . T : . . . | . . | : . | . : : SortSegmentListGeographically : : . U . . . : . . . M . . | : . | . : : IndexSegments : S : . | . . . : C . . . U . W . | : . D . : : SortTurnRelationListGeogra... : s : . D . . . : U . . . U . U . | : . . : : :......:...................:.......................:...........:...: StartPruning : : . . . . : | . C . . U . U . | : . . : : <---+ PruneStraightHighwayNodes : nSw : . . . . : U . U . . U . U . | : . . : : \ o | PruneIsolatedRegions : nSw : . . . . : U . U . . U . U . | : . . : : | n | PruneShortSegments : NSw : . . . . : U . U . . U . U . | : . . : : / e | L FinishPruning : : . . . . : | . D . . | . . | : . . : : | o RemovePrunedNodes : : . . C . . : D . . . | . . | : . . : : | o RemovePrunedSegments : : . . | . . : . . C . U . . | : . . : : | p CompactWayList : : . . | . . : . . D . | . . | : . C . T : : | RemovePrunedTurnRelations : : . . U . . : . . . | . . | : . | . : : | IndexSegments : S : . . D . . : C . . . M . W . | : . D . : : | :......:...................:.......................:...........:...: ----+ ChooseSuperNodes : sw : . . . M . : U . . . | . U . | : . . : : CreateSuperSegments : nsw : . . . U . : D . . .*Uw. U . | : . . : : DeduplicateSuperSegments : w : . . . | . : . . .*Uu. . | : . . : : :......:...................:.......................:...........:...: IndexSegments : S : . . . | . : C . . . U . W . | : . . : : <-+ ChooseSuperNodes : sw : . . . M . : U . . . | . U . | : . . : : | L CreateSuperSegments : nsw : . . . U . : D . . .*Uw. U . | : . . : : | o DeduplicateSuperSegments : w : . . . | . : . . .*Uu. . | : . . : : | o :......:...................:.......................:...........:...: --+ p MergeSuperSegments : : . . . | . : . . . U . . | : . . : : :......:...................:.......................:...........:...: SortNodeListGeographically : : . C . . D . T : . . . | . . | : . . : : SortSegmentListGeographically : : . U . . . : . . . M . . | : . . : : IndexSegments : S : . | . . . : C . . . U . W . | : . . : : SortTurnRelationListGeogra... : s : . D . . . : U . . . U . U . | : . . : : :......:...................:.......................:...........:...: SaveNodeList : : . . . . : D . . . | . | . | : . . : : SaveSegmentList : : . . . . : . . . U . U . U : . . : : SaveWayList : : . . . . : . . . . . : . . : : SaveRelationList : : . . . . : . . . . . : . . : : :......:...................:.......................:...........:...: : m . m . m . m . m : m . m . m . m . m . m : m . m . m : m : : a . a . a . a . m : a . a . a . m . m . m : a . a . m : m : : l . l . l . l . a : l . l . l . a . a . a : l . l . a : a : : l . l . l . l . p : l . l . l . p . p . p : l . l . p : p : : o . o . o . o . : o . o . o . . . : o . o . : : : c . c . c . c . : c . c . c . . . : c . c . : : Note: waysx->odata, relationsx->rridata, relationsx->rrodata and relationsx->tridata are only used by the error log creation functions which are optional (all use malloc and not mmap). routino-3.0/doc/Makefile 644 233 144 3410 12313271732 10427 0# Documentation directory Makefile # # Part of the Routino routing software. # # This file Copyright 2010-2014 Andrew M. Bishop # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # # All configuration is in the top-level Makefile.conf include ../Makefile.conf # Files to install HTML_FILES=$(notdir $(wildcard html/*.html)) $(notdir $(wildcard html/*.css)) TXT_FILES=*.txt TOP_FILES=../agpl-3.0.txt ######## all: ######## test: ######## install: install-txt install-html install-txt: @[ -d $(DESTDIR)$(docdir) ] || mkdir -p $(DESTDIR)$(docdir) @for file in $(TOP_FILES); do \ echo cp $$file $(DESTDIR)$(docdir) ;\ cp -f $$file $(DESTDIR)$(docdir) ;\ done @for file in $(TXT_FILES); do \ echo cp $$file $(DESTDIR)$(docdir) ;\ cp -f $$file $(DESTDIR)$(docdir) ;\ done install-html: @[ -d $(DESTDIR)$(docdir)/html ] || mkdir -p $(DESTDIR)$(docdir)/html @for file in $(HTML_FILES); do \ echo cp html/$$file $(DESTDIR)$(docdir)/html ;\ cp -f html/$$file $(DESTDIR)$(docdir)/html ;\ done ######## clean: rm -f *~ rm -f html/*~ ######## distclean: clean ######## .PHONY:: all test install clean distclean .PHONY:: install-txt install-html routino-3.0/doc/README.txt 644 233 144 16714 12575035272 10527 0 Routino : OpenStreetMap Routing Software ======================================== Routino is an application for finding a route between two points using the dataset of topographical information collected by http://www.OpenStreetMap.org. Starting from the raw OpenStreetMap data (in the form of the '.osm' XML files available on the internet) a custom database is generated that contains the information useful for routing. With this database and two points specified by latitude and longitude an optimum route (either shortest or quickest) is determined. The route is calculated for OpenStreetMap highways (roads, paths etc) using one of the common forms of transport defined in OpenStreetMap (foot, bicycle, horse, motorcar, motorcycle etc). When processing the OpenStreetMap data the types of highways are recorded and these set default limits on the types of traffic allowed. More specific information about permissions for different types of transport are also recorded as are maximum speed limits. Further restrictions like one-way streets, weight, height, width and length limits are also included where specified. Additionally a set of properties of each highway are also recorded. The processing of the input file is controlled by a configuration file which determines the information that is used. When calculating a route the type of transport to be used is taken into account to ensure that the known restrictions are followed. Each of the different highway types can further be allowed or disallowed depending on preferences. For each type of highway a default speed limit is defined (although the actual speed used will be the lowest of the default and any specified in the original data). To make use of the information about restrictions the weight, height, width and length of the transport can also be specified. Further preferences about road properties (e.g. paved or not) can also be selected. The simplest type of turn restrictions (those formed from an initial way, a node and a second way) are also obeyed. The result of calculating the route can be presented in several different ways. An HTML file can be produced that contains a description of the route to take with instructions for each of the important junctions. The contents of the file are created based on a set of translations specified in a configuration file. The route is also available in a GPX (GPS eXchange) XML format. format file containing either every point and highway segment (a track file) or just a waypoint and translated instructions for the important junctions (a route file). Additionally there are two plain text files that contain all data points or just the important ones (intended for debugging and further processing). One of the design aims of Routino was to make the software are flexible as possible in selecting routing preferences but also have a sensible set of default values. Another design aim was that finding the optimum route should be very fast and most of the speed increases come from the carefully chosen and optimised data format. Disclaimer ---------- The route that is calculated by this software is only as good as the input data. Routino comes with ABSOLUTELY NO WARRANTY for the software itself or the route that is calculated by it. Demonstration ------------- A live demonstration of the router for the UK is available on the internet in both OpenLayers and Leaflet versions: http://www.routino.org/uk-leaflet/ http://www.routino.org/uk-openlayers/ The source code download available below also includes a set of files that can be used to create your own interactive map. The interactive map is made possible by use of the OpenLayers or Leaflet Javascript library from http://www.openlayers.org/ or http://leafletjs.com/. Documentation ------------- The algorithm used is described in the file ALGORITHM.txt with some notes about the input data in DATA.txt and numerical limitations in LIMITS.txt. The configuration files and in particular the default set of rules for processing the OpenStreetMap data tags are described in detail in CONFIGURATION.txt and TAGGING.txt. The format of the output files generated are described in OUTPUT.txt. Detailed information about how to use the programs is available in the file USAGE.txt and how to install it is in INSTALL.txt. Status ------ Version 1.0 of Routino was released on 8th April 2009. Version 1.1 of Routino was released on 13th June 2009. Version 1.2 of Routino was released on 21st October 2009. Version 1.3 of Routino was released on 21st January 2010. Version 1.4 of Routino was released on 31st May 2010. Version 1.4.1 of Routino was released on 10th July 2010. Version 1.5 of Routino was released on 30th October 2010. Version 1.5.1 of Routino was released on 13th November 2010. Version 2.0 of Routino was released on 30th May 2011. Version 2.0.1 of Routino was released on 7th June 2011. Version 2.0.2 of Routino was released on 26th June 2011. Version 2.0.3 of Routino was released on 4th August 2011. Version 2.1 of Routino was released on 3rd October 2011. Version 2.1.1 of Routino was released on 23rd October 2011. Version 2.1.2 of Routino was released on 12th November 2011. Version 2.2 of Routino was released on 3rd March 2012. Version 2.3 of Routino was released on 21st July 2012. Version 2.3.1 of Routino was released on 11th August 2012. Version 2.3.2 of Routino was released on 6th October 2012. Version 2.4 of Routino was released on 8th December 2012. Version 2.4.1 of Routino was released on 17th December 2012. Version 2.5 of Routino was released on 9th February 2013. Version 2.5.1 of Routino was released on 20th April 2013. Version 2.6 of Routino was released on 6th July 2013. Version 2.7 of Routino was released on 22nd March 2014. Version 2.7.1 of Routino was released on 17th May 2014. Version 2.7.2 of Routino was released on 26th June 2014. Version 2.7.3 of Routino was released on 8th November 2014. Version 3.0 of Routino was released on 12th September 2015. The full version history is available in the NEWS.txt file. License ------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. It is important to note that for this program I have decided to use the Affero GPLv3 instead of just using the GPL. This license adds additional requirements to anybody who provides a networked service using this software. Copyright --------- Routino is copyright Andrew M. Bishop 2008-2015. Homepage -------- The Routino homepage has the latest news about the program: http://www.routino.org/ Download -------- The program can be downloaded from: http://www.routino.org/download/ Subversion - - - - - The source code can also be downloaded from the Subversion repository with a command like the following: svn co http://routino.org/svn/trunk routino The source code can also be browsed in the Subversion viewer which also has a list of the latest changes: http://www.routino.org/viewvc/trunk/ http://www.routino.org/viewvc/trunk/?view=log -------- Copyright 2008-2015 Andrew M. Bishop. routino-3.0/doc/ALGORITHM.txt 644 233 144 46204 12572106465 11115 0 Routino : Algorithm =================== This page describes the development of the algorithm that is used in Routino for finding routes. Simplest Algorithm ------------------ The algorithm to find a route is fundamentally simple: Start at the beginning, follow all possible routes and keep going until you reach the end. While this method does work, it isn't fast. To be able to find a route quickly needs a different algorithm, one that can find the correct answer without wasting time on routes that lead nowhere. Improved Algorithm ------------------ The simplest way to do this is to follow all possible segments from the starting node to the next nearest node (an intermediate node in the complete journey). For each node that is reached store the shortest route from the starting node and the length of that route. The list of intermediate nodes needs to be maintained in order of shortest overall route on the assumption that there is a straight line route from here to the end node. At each point the intermediate node that has the shortest potential overall journey time is processed before any other node. From the first node in the list follow all possible segments and place the newly discovered nodes into the same list ordered in the same way. This will tend to constrain the list of nodes examined to be the ones that are between the start and end nodes. If at any point you reach a node that has already been reached by a longer route then you can discard that route since the newly discovered route is shorter. Conversely if the previously discovered route is shorter then discard the new route. At some point the end node will be reached and then any routes with potential lengths longer than this actual route can be immediately discarded. The few remaining potential routes must be continued until they are found to be shorter or have no possibility of being shorter. The shortest possible route is then found. At all times when looking at a node only those segments that are possible by the chosen means of transport are followed. This allows the type of transport to be handled easily. When finding the quickest route the same rules apply except that the criterion for sorting is the shortest potential route (assuming that from each node to the end is the fastest possible type of highway). This method also works, but again it isn't very fast. The problem is that the complexity is proportional to the number of nodes or segments in all routes examined between the start and end nodes. Maintaining the list of intermediate nodes in order is the most complex part. Final Algorithm --------------- The final algorithm that is implemented in the router is basically the one above but with an important difference. Instead of finding a long route among a data set of 8,000,000 nodes (number of highway nodes in UK at beginning of 2010) it finds one long route in a data set of 1,000,000 nodes and a few hundred very short routes in the full data set. Since the time taken to find a route is proportional to the number of nodes that need to be considered the main route takes 1/10th of the time and the very short routes take almost no time at all. The solution to making the algorithm fast is therefore to discard most of the nodes and only keep the interesting ones. In this case a node is deemed to be interesting if it is the junction of three or more segments or the junction of two segments with different properties or has a routing restriction different from the connecting segments. In the algorithm and following description these are classed as super-nodes. Starting at each super-node a super-segment is generated that finishes on another super-node and contains the shortest path along segments with identical properties (and these properties are inherited by the super-segment). The point of choosing the shortest route is that since all segments considered have identical properties they will be treated identically when properties are taken into account. This decision making process can be repeated until the only the most important and interesting nodes remain. To find a route between a start and finish point now comprises the following steps (assuming a shortest route is required): 1. Find all shortest routes from the start point along normal segments and stopping when super-nodes are reached. 2. Find all shortest routes from the end point backwards along normal segments and stopping when super-nodes are reached. 3. Find the shortest route along super-segments from the set of super-nodes in step 1 to the set of super-nodes in step 2 (taking into account the lengths found in steps 1 and 2 between the start/finish super-nodes and the ultimate start/finish point). 4. For each super-segment in step 3 find the shortest route between the two end-point super-nodes. This multi-step process is considerably quicker than using all nodes but gives a result that still contains the full list of nodes that are visited. There are some special cases though, for example very short routes that do not pass through any super-nodes, or routes that start or finish on a super-node. In these cases one or more of the steps listed can be removed or simplified. When the first route reaches the final node the length of that route is retained as a benchmark. Any shorter complete route that is calculated later would replace this benchmark. As routes are tested any partial routes that are longer than the benchmark can be immediately discarded. Other partial routes have the length of a perfect straight highway to the final node added to them and if the total exceeds the benchmark they can also be discarded. Very quickly the number of possible routes is reduced until the absolute shortest is found. For routes that do not start or finish on a node in the original data set a fake node is added to an existing segment. This requires special handling in the algorithm but it gives mode flexibility for the start, finish and intermediate points in a route. Algorithm Evolution - - - - - - - - - - In Routino versions 1.0 to 1.4 the algorithm used to select a super-node was the same as above except that node properties were not included. Routino versions 1.4.1 to 1.5.1 used a slightly different algorithm which only chose nodes that were junctions between segments with different properties (or has a routing restriction that is different from connecting segments in versions 1.5 and 1.5.1). The addition of turn restrictions (described in more detail below) requires the original algorithm since the super-segments more accurately reflect the underlying topology. Algorithm Implementation - - - - - - - - - - - - The algorithm that is used for finding the route between the super-nodes using super-segments is the A* algorithm (or a slight variation of it). This was not a deliberate design decision, but evolved into it during development. This algorithm relies on calculating the lowest score (shortest distance or quickest time) to each node from the starting node. The remaining score for the path to the destination node is estimated (based on a straight line using the fastest type of highway) and added to the current score and the result recorded. At each step the unvisited node that has the lowest current score is examined and all nodes connected to it have their scores calculated. When the destination node has been reached all remaining unvisited nodes with scores higher than the destination node's score can be discarded and the few remaining nodes examined. The algorithm used to find the route between super-nodes using normal segments is Dijkstra's algorithm (although it is implemented as the same algorithm as above but with no estimated cost). Since these routes tend to be short and the CPU time for calculating the heuristic cost function is relatively large this tends to give a quicker solution. Routing Preferences ------------------- One of the important features of Routino is the ability to select a route that is optimum for a set of criteria such as preferences for each type of highway, speed limits and other restrictions and highway properties. All of these features are handled by assigning a score to each segment while calculating the route and trying to minimise the score rather than simply minimising the length. Segment length When calculating the shortest route the length of the segment is the starting point for the score. Speed preference When calculating the quickest route the time taken calculated from the length of the segment and the lower of the highway's own speed limit and the user's speed preference for the type of highway is the starting point for the score. One-way restriction If a highway has the one-way property in the opposite direction to the desired travel and the user's preference is to obey one-way restrictions then the segment is ignored. Weight, height, width & length limits If a highway has one of these limits and its value is less than the user's specified requirement then the segment is ignored. Highway preference The highway preference specified by the user is a percentage, these are scaled so that the most preferred highway type has a weighted preference of 1.0 (0% always has a weighted preference of 0.0). The calculated score for a segment is divided by this weighted preference. Highway properties The other highway properties are specified by the user as a percentage and each highway either has that property or not. The user's property preference is scaled into the range 0.0 (for 0%) to 1.0 (for 100%) to give a weighted preference, a second "non-property" weighted preference is calculated in the same way after subtracting the user's preference from 100%. If a segment has a particular property then the calculated score is divided by the weighted preference for that property, if not then it is divided by the non-property weighted preference. A non-linear transformation is applied so that changing property preferences close to 50% do not cause large variations in routes. Data Pruning ------------ From version 2.2 there are options to "prune" nodes and segments from the input data which means to remove nodes and/or segments without significantly changing the routing results. The pruning options must meet a number of conditions to be useful: * The topology relevant to routing must remain unchanged. The instructions that are produced from the reduced set of nodes and segments must be sufficiently accurate for anybody trying to follow them on the ground. * Any restrictions belonging to nodes or segments that stop certain types of traffic from following a particular highway must be preserved. * The total length must be calculated using the original data and not the simplified data which by its nature will typically be shorter. * The location of the remaining nodes and segments must be a good representation of the original nodes and segments. Since the calculated route may be displayed on a map the remaining nodes and segments must clearly indicate the route to take. The prune options all have user-controllable parameters which allow the geographical accuracy to be controlled. This means that although the topology is the same the geographical accuracy can be sacrificed slightly to minimise the number of nodes and segments. The pruning options that are available are: * Removing the access permissions for a transport type from segments if it is not possible to route that transport type from those segments to a significant number of other places. The limit on the pruning is set by the total length of the isolated group of segments. This significantly increases the chance that a route will be found by not putting waypoints in inaccessible places. * Removing short segments, the limit is set by the length of the segment. This removes a number of redundant segments (and associated nodes) but rules are applied to ensure that removing the segments does not alter junction topology or remove node access permissions or changes in way properties. * Removing nodes from almost straight highways, the limit is set by the distance between the remaining segments and the original nodes. This removes a large number of redundant nodes (and therefore segments) but again care is taken not to remove node access permissions or changes in way properties. Turn Restrictions ----------------- The addition of turn restrictions in version 2.0 adds a set of further complications because it introduces a set of constraints that are far more complex than one-way streets. A turn restriction in the simplest case is a combination of a segment, node and segment such that routes are not allowed to go from the first segment to the second one through the specified node. Exceptions for certain types of traffic can also be specified. Currently only this simplest type of turn restriction is handled by the algorithm. The first complication of turn restrictions is that the algorithm above requires that super-segments are composed of segments with identical properties. A turn restriction is not the same in both directions so a super-segment cannot include any route through that turn restriction. The node at the centre of the turn restriction must therefore be a super-node to avoid this. In addition to this all nodes connected to the turn restriction node by a single segment must also be super-nodes to avoid any long-distance super-segments starting at the restricted node. The second complication of a turn restriction is that the optimum route may require passing through the same node more than once. This can happen where the route needs to work around a turn restriction by driving past it, turning round (on a roundabout perhaps) and coming back along the same highway. Without turn restrictions a route could be defined purely by the set of nodes that were passed; no node would exist more than once along a route between two points. With turn restrictions the route is defined by a node and the segment used to get there; no route between two points will ever need to follow the same segment in the same direction more than once. This means that the optimisation algorithm calculates scores for directed segments (indexed by segment and end node) rather than for nodes. A side-effect of this is that a route that works around a turn restriction must be calculable using the super-segments that are stored in the database. This puts a limit on the amount of database optimisation that can be performed because if too many super-segments are removed the optimum work-around may also be removed. The solution to this is to ensure that the database preserves all loops that can be used to turn around and reverse direction, previously super-segments that started and finished on the same super-node were disallowed. Another side-effect of having the route composed of a set of locations (nodes) as well as the direction of travel (segments used to reach them) is that via points in the route can be forced to continue in the original direction. If the chosen method of transport obeys turn restrictions then it will not reverse direction at a via point but will find an optimum route continuing in the same direction. The only exception to this is when the route ahead at a waypoint is into a dead-end and an immediate U-turn is allowed. A side-effect of having the starting direction at a via point defined by the previous part of the route is that overall non-optimal routes may be found even though each section between via points is optimal. For a route with a start, middle and end point defined it can be the case that the shortest route from the start to the middle arrives in the opposite direction to that required for the optimal route from the middle to the end. The calculation of the route in separate sections therefore may give a non-optimum result even though each section is itself optimum based on the start conditions. Overall the presence of turn restrictions in the database makes the routing slower even for regions of the map that have no turn restrictions. Data Implementation ------------------- The hardest part of implementing this router is the data organisation. The arrangement of the data to minimise the number of operations required to follow a route from one node to another is much harder than designing the algorithm itself. The final implementation uses a separate table for nodes, segments and ways. Each table individually is implemented as a C-language data structure that is written to disk by a program which parses the OpenStreetMap XML data file. In the router these data structures are memory mapped so that the operating system handles the problems of loading the needed data blocks from disk. Each node contains a latitude and longitude and they are sorted geographically so that converting a latitude and longitude coordinate to a node is fast as well as looking up the coordinate of a node. The node also contains the location in the array of segments for the first segment that uses that node. Each segment contains the location of the two nodes as well as the way that the segment came from. The location of the next segment that uses one of the two nodes is also stored; the next segment for the other node is the following one in the array. The length of the segment is also pre-computed and stored. Each way has a name, a highway type, a list of allowed types of traffic, a speed limit, any weight, height, width or length restrictions and the highway properties. The super-nodes are mixed in with the nodes and the super-segments are mixed in with the segments. For the nodes they are the same as the normal nodes, so just a flag is needed to indicate that they are super. The super-segments are in addition to the normal segments so they increase the database size (by about 10%) and are also marked with a flag. Some segments are therefore flagged as both normal segments and super-segments if they both have the same end nodes. The relations are stored separately from the nodes, segments and ways. For the turn restriction relations the initial and final segments are stored along with the restricted node itself. Each node that has a turn restriction is marked in the main node storage with a flag to indicate this information. -------- Copyright 2008-2013 Andrew M. Bishop. routino-3.0/doc/LIMITS.txt 644 233 144 14050 12572106465 10562 0 Routino : Numerical Limits ========================== 32/64-bit Data IDs ------------------ The OpenStreetMap data uses a numerical identifier for each node, way and relation. These identifiers started at 1 and increase for every new item of each type that is added. When an object is deleted the identifier is not re-used so the highest identifier will always be higher than the number of objects. The identifier needs to be handled carefully to ensure that it does not overflow the data type allocated for it. Depending on the data type used to store the identifier there are are a number of numerical limits as described below: 1. If a signed 32-bit integer is used to store the identifier then the maximum value that can be handled is 2147483647 (2^31-1) before overflow. 2. If an unsigned 32-bit integer is used to store the identifier then the maximum value that can be handled is 4294967295 (2^32-1) before overflow. 3. If a signed 64-bit integer is used to store the identifier then the maximum value that can be handled is 9223372036854775807 (2^63-1) before overflow. For the purposes of this document the possibility of overflow of a 64-bit integer is ignored. The part of Routino that handles the node, way and relation identifiers is the planetsplitter program. ID Above 31-bits - - - - - - - - The first identifier exceeding 31-bits (for a node) is predicted to be created in the OpenStreetMap database in February 2013. All versions of Routino use unsigned 32-bit integers to store the identifier. Therefore all versions of Routino will continue working correctly when node number 2147483648 (2^31) or higher is present. ID Above 32-bits - - - - - - - - The ability of Routino to handle identifiers larger than 32-bits does not depend on having a 64-bit operating system. Before version 2.0.1 of Routino there was no check that the identifier read from the input data would fit within an unsigned 32-bit integer. Earlier versions of Routino will therefore fail to report an error and will process data incorrectly when node number 4294967296 (2^32) or higher is present. From version 2.0.2 the code is written to allow the node, way and relation identifier data type to be changed to 64-bits. This means that a consistent data type is used for handling identifiers and the format used for printing them is consistent with the variable type. From version 2.0.2 onwards it is possible to make a simple change to the code to process data with node identifiers above 4294967296 (2^32) without error. The binary format of the database will be unchanged by the use of 64-bit identifiers (since the identifiers are not stored in the database). To recompile with 64-bit node identifiers the file src/typesx.h should be edited and the two lines below changed from: typedef uint32_t node_t; #define Pnode_t PRIu32 to: typedef uint64_t node_t; #define Pnode_t PRIu64 A similar change can also be made for way or relation identifiers although since there are currently fewer of these the limit is not as close to being reached. Between version 2.0.2 and version 2.4 a bug means that route relations will ignore the way or relation identifier if it is equal to 4294967295 (2^32-1). From version 2.4 onwards when a numerical limit is reached the planetsplitter program will exit with an error message that describes which limit was reached and which data type needs to be changed. Database Format --------------- The other limitation in Routino is the number of objects stored in the database that is generated by the planetsplitter data processing. This number may be significantly different from the highest identifier in the input data set for two reasons. Firstly any nodes, ways or relations that have been deleted will not be present in the data. Secondly when a partial planet database (continent, country or smaller) is processed there will be only a fraction of the total number of nodes, ways and relations. The limiting factor is the largest of the following. 1. The number of nodes in the input data files. 2. The number of segments in the input data files. 3. The number of highways in the input data files. 4. The number of relations in the input data files. Normally the number of nodes will be the limiting factor. 32-bit Indexes - - - - - - - Before version 1.2 the database could hold up to 4294967295 (2^32-1) items of each type (node, segment, way) since an unsigned 32-bit integer is used. Versions 1.3 to 1.4.1 have a limit of 2147483647 (2^31-1) items since half of the 32-bit integer range is reserved for fake nodes and segments that are inserted if a waypoint is not close to a node. From version 1.5 the limit is 4294901760 (2^32-2^16) for the number of items of each type that can be stored. The small remaining part of the 32-bit unsigned integer range is reserved for fake nodes and segments. 64-bit Indexes - - - - - - - When using a 32-bit operating system it is not possible to create a database that exceeds about 2GB in total. This will be fewer than 2^32 objects in the database in total. The use of 64-bit indexes will require a 64-bit operating system. From version 2.0.2 onwards it is possible to make a simple change to the code to index the database objects with 64-bit integers insted of 32-bit integers. To recompile with 64-bit index integers the file src/types.h should be edited and the two lines below changed from: typedef uint32_t index_t; #define Pindex_t PRIu32 to: typedef uint64_t index_t; #define Pindex_t PRIu64 This change will affect nodes, segments, ways and relations together. The database that is generated will no longer be compatible with Routino that has been compiled with 32-bit indexes. The size of the database will also grow by about 50% when this change is made. -------- Copyright 2013 Andrew M. Bishop. routino-3.0/doc/CONFIGURATION.txt 644 233 144 17706 12572106465 11603 0 Routino : Configuration ======================= New in version 1.4 of Routino is the use of configuration files to allow more information to be provided to the programs at run-time. The configuration files that are used are: * Tagging transformation rules for the planetsplitter program. * Routing profiles for the router program. * Output translations for the router program. In keeping with the nature of the input and output files the configuration files are also XML files. Each of the files uses a custom defined XML schema and an XSD file is provided for each of them. Tag Transformation Rules ------------------------ The default name of the tagging transformation rules XML configuration file is tagging.xml in the same directory as the generated database files. Other filenames can be specified on the command line using the --tagging option. When processing the input it is possible to have a different set of tagging rules for each file; for example different rules for different countries. The tagging rules allow modifying the highway tags in the source file so that the routing can be performed on a simpler set of tags. This removes the special case tagging rules from the source code into the configuration file where they can be easily modified. Part of the provided tagging.xml file showing the rules for motorway_link and motorway highway types. ... The rules all have the same format; an if or ifnot element at the top level for matching the input and some other elements inside to be used if there was a match. Within the if and ifnot rules any of the rules can be used. These are if, ifnot, set, unset, output or logerror elements. The rules for matching the if or ifnot elements are the following: * An if rule that has both k and v specified is only matched if a tag exists in the input that matches both. * An if rule that has only the k attribute is matched if a tag with that key exists. * An if rule that has only the v attribute is matched for each tag with that value (i.e. the contents may be used more than once). * An if rule that has neither attribute specified always matches. * An ifnot rule that has both k and v specified is only matched if no tag exists in the input that matches both. * An ifnot rule that has only the k attribute is matched only if no tag with that key exists. * An ifnot rule that has only the v attribute is only matched if no tag with that value exists. * An ifnot rule that has neither attribute specified never matches. For set, unset, output or logerror elements inside of an if rule an unspecified value for the k or v attribute is replaced by the values from the tag that matched the outer if rule. This makes it simple to delete tags that match a particular rule without having to specify the parameters more than once. For elements inside of an ifnot element an unspecified value for the k or v attribute is replaced by the values from the outer ifnot rule. This means that either the outer ifnot element or the inner element must specify both k and v attributes between them. For nested if or ifnot elements the outer k and v attributes are not inherited by the inner elements. The set and unset elements either create or delete a tag from the input data that was read from the file. If the set element is used and the tag already exists then it is modified. The output element adds a tag to the set that will be used by Routino to determine the data properties. The logerror element will cause an error message to be added to the error log file that reports that the key and attribute combination are not recognised. If the k attribute is specified but not the v attribute then the tag value that matches the specified key is looked up and used. An additional message attribute can be specified to be printed at the end of the logged error. The default logged error message is: Node XXX has an unrecognised tag 'key' = 'value' (in tagging rules); ignoring it. The specified message attribute will replace the final part of the logged error. Routing Profiles ---------------- The default name of the routing profiles XML configuration file is profiles.xml in the same directory as the database files. Other filenames can be specified on the command line using the --tagging option. The purpose of this configuration file is to allow easy modification of the routing parameters so that they do not all need to be specified on the command line. In versions of Routino before version 1.4 the default routing parameters (preferred highways, preferred speeds etc) were contained in the source code, now they are in a configuration file. When calculating a route the --profile option selects the named profile from the configuration file. Part of the provided profiles.xml file showing the parameters for transport on foot is shown below: ... ... ... ... ... Output Translations ------------------- The default name of the output translations XML configuration file is translations.xml in the same directory as the database files. Other filenames can be specified on the command line using the --translations option. The generated HTML and GPX output files (described in the next section) are created using the fragments of text that are defined in this file. Additional languages can be added to the file and are selected using the --language option to the router. If no language is specified the first one in the file is used. Part of the provided translations.xml file showing some of the English language (en) translations is shown below: ... ... ... ... ... -------- Copyright 2010-2013 Andrew M. Bishop. routino-3.0/doc/TAGGING.txt 644 233 144 47776 12572106465 10666 0 Routino : Tagging Rules ======================= The different tags and attributes in the OSM format XML that are used by Routino are described below. Routino handles the tags in the input file after they have been processed according to a set of rules defined in a configuration file. The first half of this file describes the tags that are recognised by Routino after being processed; the second half of the file describes the transformations that are in the default tagging configuration file. Tags Recognised After Processing -------------------------------- This section describes the tags that are recognised by Routino after the tag transformations have been applied. This is therefore a much reduced set of tags compared to the original OSM data and also includes tags which are specific to Routino. In all cases of tag processing values of true, yes, 1 are recognised as being affirmative and any other value is negative. Node Tags And Attributes ------------------------ The node attributes id, latitude and longitude are used. The id attribute is required to associate the node with the ways and the position attributes are required to locate the node. Transport Specific Tags - - - - - - - - - - - - One tag is recognised for each of the different modes of transport: foot, horse, bicycle, wheelchair, moped, motorcycle, motorcar, goods, hgv and psv. These indicate whether the specific type of transport is allowed to pass through the node or not. By default for nodes all types of transport are allowed to pass through a node and specific tags must be used to remove the permissions for the transport. The roundabout Tag - - - - - - - - - The roundabout tag for mini-roundabouts is recognised and used to improve the description of the route. Way Tags And Attributes ----------------------- The tags from the ways in the data are the ones that provide most of the information for routing. The id attribute is used only so that the many segments associated with a way can share a set of tags taken from the way. The nd information is used to identify the nodes that make up the way. The highway Tag - - - - - - - - The most important tag that is used from a way is the highway tag. This defines the type of highway that the way represents. Any way that does not have a highway tag is discarded. There are more highway types defined than are used by the router. The subset that the router uses are: * motorway * trunk * primary * secondary * tertiary * unclassified * residential * service * track * cycleway * path (1) * steps (2) Note 1: This changed in version 1.3 of Routino - the bridleway and footway types were included within the path highway type. Note 2: This changed in version 1.3 of Routino - the steps type was separated from the footway type. Transport Specific Tags - - - - - - - - - - - - One tag is recognised for each of the different modes of transport: foot, horse, bicycle, wheelchair, moped, motorcycle, motorcar, goods, hgv and psv. These indicate whether the specific type of transport is allowed on the highway or not. By default for ways no types of transport are allowed to pass along a highway and specific tags must be used to add the permissions for the transport. The name Tag - - - - - - The name tag is used to provide the label for the highway when printing the results. The ref Tag - - - - - - The ref tag is used to provide the label for the highway when printing the results. The lanes Tag - - - - - - - The lanes tag is used to identify whether a highway has multiple lanes for traffic and this is used to derive the multilane highway properties. The paved Tag - - - - - - - The paved tag is used to identify whether a highway is paved or not, this is one of the available highway properties. A paved tag may exist in the original data but normally the surface tag needs to be transformed into the paved tag. The multilane Tag - - - - - - - - - The multilane tag is used to indicate that a highway has multiple lanes for traffic. The bridge Tag - - - - - - - The bridge tag is used to identify whether a highway is a bridge and therefore set one of the available properties. The tunnel Tag - - - - - - - The tunnel tag is used to identify whether a highway is a tunnel and therefore set one of the available properties. The footroute Tag - - - - - - - - - The footroute tag is used to identify whether a highway is part of a walking route and therefore set one of the available properties. This is not a standard OSM tag and is normally added to the individual highways by looking for route relations that are designated for foot access. The bicycleroute Tag - - - - - - - - - - The bicycleroute tag is used to identify whether a highway is part of a bicycle route and therefore set one of the available properties. This is not a standard OSM tag and is normally added to the individual highways by looking for route relations that are designated for bicycle access. The cyclebothways Tag - - - - - - - - - - - The cyclebothways tag is used to identify whether a highway allows cycling in the opposite direction to a signposted oneway restriction. The oneway Tag - - - - - - - The oneway tag is used to specify that traffic is only allowed to travel in one direction. The roundabout Tag - - - - - - - - - The roundabout tag is used to specify that a highway is part of a roundabout to improve the description of the calculated route. The maxspeed Tag - - - - - - - - The maxspeed tag is used to specify the maximum speed limit on the highway; this is always measured in km/hr in OpenStreetMap data. If the tag value contains "mph" then it is assumed to be a value in those units and converted to km/hr. The maxweight Tag - - - - - - - - - The maxweight tag is used to specify the maximum weight of any traffic on the highway. In other words this must be set to the heaviest weight allowed on the highway (for example a bridge) in tonnes. If the tag value contains "kg" then it is assumed that the value is in these units and converted to tonnes. The maxheight Tag - - - - - - - - - The maxheight tag is used to specify the maximum height of any traffic on the highway. In other words this must be set to the lowest height of anything above the highway (like a bridge) in metres. If the tag value contains a measurement in feet or feet and inches then attempts are made to convert this to metres. The maxwidth Tag - - - - - - - - The maxwidth tag is used to specify the maximum width of any traffic on the highway. This must be set to the minimum width of the constraints at the wayside in metres. If the tag value contains a measurement in feet or feet and inches then attempts are made to convert this to metres. The maxlength Tag - - - - - - - - - The maxlength tag is used to specify the maximum length of any traffic on the highway (usually from a traffic sign) in metres. If the tag value contains a measurement in feet or feet and inches then attempts are made to convert this to metres. The area Tag - - - - - - The area tag is used to specify that a way defines an area. This is used only so that in the case of duplicated segments those belonging to an area can be discarded in preference to those that are not. Relation Tags And Attributes ---------------------------- The tags from the relations are used to associate more properties with the highways that are part of that relation. The id attribute is used so that relations that are members of other relations can be identified. The member information is used to identify the nodes and ways that make up the relation. The footroute Tag - - - - - - - - - The footroute tag is used to identify whether a relation defines a walking route and therefore should be applied to the individual member highways. The bicycleroute Tag - - - - - - - - - - The bicycleroute tag is used to identify whether a relation defines a bicycle route and therefore should be applied to the individual member highways. The type, restriction & except Tags - - - - - - - - - - - - - - - - - - For turn relations the information about the allowed or disallowed turns are stored in the type, restriction and except tags. For a turn restriction the type must be equal to "restriction", the restriction must define the type of turn relation and except defines transport types which are exempt from the restriction. Tag Transformations ------------------- This section describes the set of tag transformations that are contained in the default configuration file. The configuration file tagging rules are applied in sequence and this section of the document is arranged in the same order. Node Tag Transformations ------------------------ Barrier Defaults - - - - - - - - The first part of the tag transformations is to decide on defaults for each type of node. This uses the barrier tag in the OSM file and converts it into a default set of disallowed transport types. Barrier foot horse wheelchair bicycle moped motorcycle motorcar goods hgv psv ------- ---- ----- ---------- ------- ----- ---------- -------- ----- --- --- kissing_gate, footgate, stile, v_stile, turnstile, squeeze, squeeze_stile, cycle_barrier, bicycle_barrier yes no no no no no no no no no horse_stile, horse_jump, step_over yes yes no no no no no no no no horse_barrier, cattle_grid yes no yes yes yes yes yes yes yes yes motorcyle_barrier yes yes yes yes no no no no no no bollard, car_barrier, car_trap yes yes yes yes yes yes no no no no Generic Access Permissions - - - - - - - - - - - - - The access tag is used to specify the default access restrictions through the node. If the tag value is no or private or a selection of other values then all transport types are denied access (later tag transformation rules may add specific transport types back again). Other Access Permissions - - - - - - - - - - - - A tag named vehicle means any of the bicycle, moped, motorcycle, motorcar, goods, hgv and psv transport types. A tag named motor_vehicle is transformed to mean any vehicle except a bicycle. Specific Access Permissions - - - - - - - - - - - - - - The final part of the access permissions is to use the specific transport type tags. One tag is recognised for each of the different modes of transport: foot, horse, bicycle, wheelchair, moped, motorcycle, motorcar, goods, hgv and psv. These indicate whether the specific type of transport is allowed through the node or not; the values listed for the access tag are also accepted here. Mini-roundabouts - - - - - - - - If the highway tag has the value mini_roundabout or the junction tag has the value roundabout then a junction tag with value roundaboutis passed through. Way Tag Transformations ----------------------- Highway Defaults - - - - - - - - The first part of the tag transformations is to decide on defaults for each type of highway. This uses the highway tag in the OSM file and maps it into one of the highway tags that are recognised by Routino, defining the default allowed transport types and adding a number of properties. The first part of the highway tag checking is to ignore the highway tag if it has a value that indicates a non-highway. These are the proposed and construction values for future highways, the no, abandoned and disused values for previous highways and a small number of other values. The second part of the highway transformation is to convert the highway tag into one that is recognised by Routino. Original tag Transformed tag ------------ --------------- motorway_link motorway trunk_link trunk primary_link primary secondary_link secondary tertiary_link tertiary minor, road unclassified living_street residential access, services, layby service byway, unsurfaced, unpaved track footway, bridleway, pedestrian, walkway path route=ferry ferry (1) Note 1: A ferry route is converted into a highway of type "ferry" so that routes using a ferry can be calculated. The type of highway also determines the defaults for the types of transport allowed on the highway. The default assumptions are as shown in the table below. Highway foot horse wheelchair bicycle moped motorcycle motorcar goods hgv psv ------- ---- ----- ---------- ------- ----- --------- -------- ----- --- --- motorway no no no no no yes yes yes yes yes trunk no(1) no(1) no(1) yes yes yes yes yes yes yes primary yes yes yes yes yes yes yes yes yes yes secondary yes yes yes yes yes yes yes yes yes yes tertiary yes yes yes yes yes yes yes yes yes yes unclassified yes yes yes yes yes yes yes yes yes yes residential yes yes yes yes yes yes yes yes yes yes service yes yes yes yes yes yes yes yes yes yes track yes yes yes yes no no no no no no cycleway yes no yes yes no no no no no no path yes yes(2) yes yes(2) no no no no no no steps yes no no no no no no no no no ferry (3) no no no no no no no no no no Note 1: A trunk road may legally allow foot, horse or wheelchair access but in the absence of other tags is considered to be too dangerous. Note 2: A path allows bicycle or horse access by default only if actually labelled as a highway of type "bridleway". Note 3: Ferry routes must be explicitly tagged with the allowed transport types, it is not sensible to try to guess. Finally for the highway tag a number of default properties are added depending on the highway type. Highway Properties ------- ---------- motorway paved, oneway, multilane trunk paved, multilane (1) primary paved, multilane (1) secondary paved tertiary paved unclassified paved residential paved service paved track paved (2) cycleway paved path paved (3) steps ferry Note 1: A highway of this type has the multilane property by default if it is oneway. Note 2: A track is paved only if it is tagged as tracktype=grade1. Note 3: A path is paved only if it was originally tagged as highway=walkway or highway=pedestrian. Generic Access Permissions - - - - - - - - - - - - - The access tag is used to specify the default access restrictions on the highway. If the tag value is no or private or a selection of other values then all transport types are denied access (later tag transformation rules may add specific transport types back again). Other Access Permissions - - - - - - - - - - - - A tag named vehicle means any of the bicycle, moped, motorcycle, motorcar, goods, hgv and psv transport types. A tag named motor_vehicle is transformed to mean any vehicle except a bicycle. The designation tag is used as an alternative method of identifying the legal right of way on a path (in the UK at least). The tag transformations convert these tags into a set of allowed transport types as shown below. Designation tag Equivalent access permissions --------------- ----------------------------- restricted_byway foot=yes, wheelchair=yes, horse=yes, bicycle=yes public_byway, byway, byway_open_to_all_traffic foot=yes, wheelchair=yes, horse=yes, bicycle=yes, moped=yes, motorcycle=yes, motorcar=yes permissive_bridleway, public_bridleway, bridleway foot=yes, wheelchair=yes, horse=yes, bicycle=yes public_cycleway foot=yes, wheelchair=yes, bicycle=yes permissive_footpath, public_footpath, footpath foot=yes, wheelchair=yes In addition to these there are some other tags and values that will modify the transport permissions on the highway. A highway that is tagged as motorroad with a value of yes will deny access to foot, horse, wheelchair, bicycle and moped transport. A highway that is tagged with footway or sidewalk and one of a set of popular values will allow foot and wheelchair access even if the road type would not normally do so. A highway that is tagged as cycleway with one of several values will allow bicycle access. If the value of the cycleway tag is opposite_lane, opposite_track or opposite then the cyclebothways tag is set. A highway that is tagged as oneway:bicycle with the value no will also cause the cyclebothways tag to be set. Specific Access Permissions - - - - - - - - - - - - - - The final part of the access permissions is to use the specific transport type tags. One tag is recognised for each of the different modes of transport: foot, horse, bicycle, wheelchair, moped, motorcycle, motorcar, goods, hgv and psv. These indicate whether the specific type of transport is allowed on the highway or not. Highway Properties - - - - - - - - - If there is a surface tag then the highway is assumed to be unpaved unless the tag value matches one of the following: paved, asphalt, concrete or many other values listed in the configuration file. Support for the obsolete paved tag is also provided and the highway is paved if this is set to a true value. The lanes tag is passed through to be used to set the multilane highway property. The bridge and tunnel tags are copied directly from the input to the output. Highway Restrictions - - - - - - - - - - The oneway, maxspeed, maxweight, maxheight, maxwidth and maxlength are copied directly from the input to the output without modification. Roundabouts - - - - - - If a highway is tagged as junction=roundabout then a roundabout=yes tag created on the output. Highway Names and References - - - - - - - - - - - - - - The name and ref tags are copied directly from the input to the output. Highway Areas - - - - - - - The area tag is copied directly from the input to the output. Relation Tag Transformations ---------------------------- The type tag is passed through without change. Routes - - - The route tag can be used to determine whether a relation is part of a walking or bicycle route so that the footroute or bicycleroute properties can be applied to the highways that make up that relation. The tag transformations that are applied for route relations are defined in the table below. Relation Tag footroute Property bicycleroute Property ------------ ------------------ --------------------- foot, walking, hiking yes no bicycle no yes bicycle;foot, foot;bicycle yes yes Turn Restrictions - - - - - - - - - No tag transformations are defined for turn restriction relations but the restriction and except tags are passed through without change. -------- Copyright 2008-2015 Andrew M. Bishop. routino-3.0/doc/LIBRARY.txt 644 233 144 50701 12572106365 10667 0 Routino : Library ================= Library Usage ------------- This page describes the libroutino shared library that can be compiled from the Routino source code and used in other programs. Compilation - - - - - - The libroutino shared library is compiled by default when the Routino source code is compiled. There are two versions; a normal version and a 'slim' version that uses less memory but is slower. The names of the libraries are libroutino.so and libroutino-slim.so Including - - - - - To use the Routino library in another program the source code for that program should include the routino.h file. The functions that are available in the library (both versions) are listed in this file along with all of the constants and data types that are required. Linking - - - - After compiling the program that uses the library it needs to be linked to the library. For gcc this requires adding -lroutino or -lroutino-slim to the linker command line, possibly with a -L... parameter to specify the location of the library. Example Library Interface Code - - - - - - - - - - - - - - - An example of a program that can link to the libroutino library is provided in the Routino source code called router+lib.c. This is an almost exact re-implementation of the standard Routino router program using the libroutino library. Library License --------------- The source code for the libroutino and libroutino-slim libraries is the GNU Affero General Public License v3 the same as for the rest of the Routino software. Linking with AGPLv3 Source Code - - - - - - - - - - - - - - - - If libroutino is linked with other APGLv3 code then the same license applies to the combination as to the two parts. Linking with GPLv3 Source Code - - - - - - - - - - - - - - - The AGPLv3 license is almost identical to the GNU General Public License v3 except that network interaction with an AGPLv3 program requires the same source code access as distributing compiled GPLv3 programs. This means that libroutino can be linked or combined with code that is released under the GPLv3 without changing the license of that code. If there is no network interaction with the resulting program then the Routino source code can be treated as if it was GPLv3 code for the purposes of distribution and use. If there is network interaction with the resulting program then the AGPLv3 license will apply since this is required by section 13 of the GPLv3. The Software Freedom Law Center description of the GPLv3 and AGPLv3 licenses describes combining GPLv3 and APGLv3. My understanding is that only when modified Routino code is linked with GPLv3 code does network interaction require the modified Routino code to be released. Linking with Other Source Code - - - - - - - - - - - - - - - Linking libroutino with code released under any other license must preserve the terms of the Routino license on the combination if the software is distributed or interacted with over a network. Routino Library API ------------------- Preprocessor Definitions - - - - - - - - - - - - A version number for the Routino API. #define ROUTINO_API_VERSION 7 Error Definitions No error. #define ROUTINO_ERROR_NONE 0 A function was called without the database variable set. #define ROUTINO_ERROR_NO_DATABASE 1 A function was called without the profile variable set. #define ROUTINO_ERROR_NO_PROFILE 2 A function was called without the translation variable set. #define ROUTINO_ERROR_NO_TRANSLATION 3 The specified database to load did not exist. #define ROUTINO_ERROR_NO_DATABASE_FILES 11 The specified database could not be loaded. #define ROUTINO_ERROR_BAD_DATABASE_FILES 12 The specified profiles XML file did not exist. #define ROUTINO_ERROR_NO_PROFILES_XML 13 The specified profiles XML file could not be loaded. #define ROUTINO_ERROR_BAD_PROFILES_XML 14 The specified translations XML file did not exist. #define ROUTINO_ERROR_NO_TRANSLATIONS_XML 15 The specified translations XML file could not be loaded. #define ROUTINO_ERROR_BAD_TRANSLATIONS_XML 16 The requested profile name does not exist in the loaded XML file. #define ROUTINO_ERROR_NO_SUCH_PROFILE 21 The requested translation language does not exist in the loaded XML file. #define ROUTINO_ERROR_NO_SUCH_TRANSLATION 22 There is no highway near the coordinates to place a waypoint. #define ROUTINO_ERROR_NO_NEARBY_HIGHWAY 31 The profile and database do not work together. #define ROUTINO_ERROR_PROFILE_DATABASE_ERR 41 The profile being used has not been validated. #define ROUTINO_ERROR_NOTVALID_PROFILE 42 The user specified profile contained invalid data. #define ROUTINO_ERROR_BAD_USER_PROFILE 43 The routing options specified are not consistent with each other. #define ROUTINO_ERROR_BAD_OPTIONS 51 There is a mismatch between the library and caller API version. #define ROUTINO_ERROR_WRONG_API_VERSION 61 The progress function returned false. #define ROUTINO_ERROR_PROGRESS_ABORTED 71 A route could not be found to waypoint 1. #define ROUTINO_ERROR_NO_ROUTE_1 1001 A route could not be found to waypoint 2. #define ROUTINO_ERROR_NO_ROUTE_2 1002 A route could not be found to waypoint 3. #define ROUTINO_ERROR_NO_ROUTE_3 1003 Routino Option Definitions Calculate the shortest route. #define ROUTINO_ROUTE_SHORTEST 0 Calculate the quickest route. #define ROUTINO_ROUTE_QUICKEST 1 Output an HTML route file. #define ROUTINO_ROUTE_FILE_HTML 2 Output a GPX track file. #define ROUTINO_ROUTE_FILE_GPX_TRACK 4 Output a GPX route file. #define ROUTINO_ROUTE_FILE_GPX_ROUTE 8 Output a text file with important junctions. #define ROUTINO_ROUTE_FILE_TEXT 16 Output a text file with all nodes and segments. #define ROUTINO_ROUTE_FILE_TEXT_ALL 32 Output a single file type to stdout. #define ROUTINO_ROUTE_FILE_STDOUT 64 Output a linked list of points containing the HTML file information but as plain text. #define ROUTINO_ROUTE_LIST_HTML 128 Output a linked list of points containing the HTML file information as plain text and with all points. #define ROUTINO_ROUTE_LIST_HTML_ALL 256 Output a linked list of points containing the text file information. #define ROUTINO_ROUTE_LIST_TEXT 512 Output a linked list of points containing the text all file information. #define ROUTINO_ROUTE_LIST_TEXT_ALL 1024 Linked List Output Point Definitions An unimportant, intermediate, node. #define ROUTINO_POINT_UNIMPORTANT 0 A roundabout exit that is not taken. #define ROUTINO_POINT_RB_NOT_EXIT 1 An un-interesting junction where the route continues without comment. #define ROUTINO_POINT_JUNCT_CONT 2 The highway changes type but nothing else happens. #define ROUTINO_POINT_CHANGE 3 An interesting junction to be described. #define ROUTINO_POINT_JUNCT_IMPORT 4 The entrance to a roundabout. #define ROUTINO_POINT_RB_ENTRY 5 The exit from a roundabout. #define ROUTINO_POINT_RB_EXIT 6 The location of a mini-roundabout. #define ROUTINO_POINT_MINI_RB 7 The location of a U-turn. #define ROUTINO_POINT_UTURN 8 A waypoint. #define ROUTINO_POINT_WAYPOINT 9 Profile Definitions A Motorway highway. #define ROUTINO_HIGHWAY_MOTORWAY 1 A Trunk highway. #define ROUTINO_HIGHWAY_TRUNK 2 A Primary highway. #define ROUTINO_HIGHWAY_PRIMARY 3 A Secondary highway. #define ROUTINO_HIGHWAY_SECONDARY 4 A Tertiary highway. #define ROUTINO_HIGHWAY_TERTIARY 5 A Unclassified highway. #define ROUTINO_HIGHWAY_UNCLASSIFIED 6 A Residential highway. #define ROUTINO_HIGHWAY_RESIDENTIAL 7 A Service highway. #define ROUTINO_HIGHWAY_SERVICE 8 A Track highway. #define ROUTINO_HIGHWAY_TRACK 9 A Cycleway highway. #define ROUTINO_HIGHWAY_CYCLEWAY 10 A Path highway. #define ROUTINO_HIGHWAY_PATH 11 A Steps highway. #define ROUTINO_HIGHWAY_STEPS 12 A Ferry highway. #define ROUTINO_HIGHWAY_FERRY 13 A Paved highway. #define ROUTINO_PROPERTY_PAVED 1 A Multilane highway. #define ROUTINO_PROPERTY_MULTILANE 2 A Bridge highway. #define ROUTINO_PROPERTY_BRIDGE 3 A Tunnel highway. #define ROUTINO_PROPERTY_TUNNEL 4 A Footroute highway. #define ROUTINO_PROPERTY_FOOTROUTE 5 A Bicycleroute highway. #define ROUTINO_PROPERTY_BICYCLEROUTE 6 Type Definitions - - - - - - - - Typedef Routino_Database A data structure to hold a Routino database loaded from a file (the contents are private). typedef struct _Routino_Database Routino_Database Typedef Routino_Waypoint A data structure to hold a Routino waypoint found within the database (the contents are private). typedef struct _Routino_Waypoint Routino_Waypoint Typedef Routino_Profile A data structure to hold a Routino routing profile (the contents are private). typedef struct _Routino_Profile Routino_Profile Typedef Routino_Translation A data structure to hold a Routino translation (the contents are private). typedef struct _Routino_Translation Routino_Translation Typedef Routino_UserProfile A data structure to hold a routing profile that can be defined by the user. typedef struct _Routino_UserProfile Routino_UserProfile struct _Routino_UserProfile { int transport; The type of transport. float highway[14]; A floating point preference for travel on the highway (range 0 to 1). float speed[14]; The maximum speed on each type of highway (km/hour). float props[7]; A floating point preference for ways with this attribute (range 0 to 1). int oneway; A flag to indicate if one-way restrictions apply. int turns; A flag to indicate if turn restrictions apply. float weight; The weight of the vehicle (in tonnes). float height; The height of the vehicle (in metres). float width; The width of vehicle (in metres). float length; The length of vehicle (in metres). } Typedef Routino_Output Forward declaration of the Routino_Output data type. typedef struct _Routino_Output Routino_Output Type struct _Routino_Output A linked list output of the calculated route whose contents depend on the ROUTINO_ROUTE_LIST_* options selected. struct _Routino_Output { Routino_Output* next; A pointer to the next route section. float lon; The longitude of the point (radians). float lat; The latitude of the point (radians). float dist; The total distance travelled (kilometres) up to the point. float time; The total journey time (seconds) up to the point. float speed; The speed (km/hr) for this section of the route (ROUTINO_ROUTE_LIST_TEXT_ALL format only). int type; The type of point (one of the ROUTINO_POINT_* values). int turn; The amount to turn (degrees) for the next section of the route (ROUTINO_ROUTE_LIST_TEXT or ROUTINO_ROUTE_LIST_HTML or ROUTINO_ROUTE_LIST_HTML_ALL format). int bearing; The compass direction (degrees) for the next section of the route. char* name; The name of the next section of the route (ROUTINO_ROUTE_LIST_TEXT or ROUTINO_ROUTE_LIST_HTML or ROUTINO_ROUTE_LIST_HTML_ALL format) or previous section of the route (ROUTINO_ROUTE_LIST_TEXT_ALL format). char* desc1; The first part of the description of the next section of route (ROUTINO_ROUTE_LIST_HTML or ROUTINO_ROUTE_LIST_HTML format). char* desc2; The second part of the description of the next section of route (ROUTINO_ROUTE_LIST_HTML or ROUTINO_ROUTE_LIST_HTML format). char* desc3; The third part of the description, the total distance and time at the end of the next section of route (ROUTINO_ROUTE_LIST_HTML or ROUTINO_ROUTE_LIST_HTML format). } Typedef Routino_ProgressFunc A type of function that can be used as a callback to indicate routing progress, if it returns false the router stops. typedef int (*Routino_ProgressFunc)(double complete) Variable Definitions - - - - - - - - - - Global Variable Routino_APIVersion Contains the libroutino API version number. int Routino_APIVersion Global Variable Routino_errno Contains the error number of the most recent Routino function (one of the ROUTINO_ERROR_* values). int Routino_errno Function Definitions - - - - - - - - - - Global Function Routino_CalculateRoute() Calculate a route using a loaded database, chosen profile, chosen translation and set of waypoints. Routino_Output* Routino_CalculateRoute ( Routino_Database* database, Routino_Profile* profile, Routino_Translation* translation, Routino_Waypoint** waypoints, int nwaypoints, int options, Routino_ProgressFunc progress ) Routino_Output* Routino_CalculateRoute Returns the head of a linked list of route data (if requested) or NULL. Routino_Database* database The loaded database to use. Routino_Profile* profile The chosen routing profile to use. Routino_Translation* translation The chosen translation information to use. Routino_Waypoint** waypoints The set of waypoints. int nwaypoints The number of waypoints. int options The set of routing options (ROUTINO_ROUTE_*) ORed together. Routino_ProgressFunc progress A function to be called occasionally to report progress or NULL. Global Function Routino_Check_API_Version() Check the version of the library used by the caller against the library version int Routino_Check_API_Version ( int caller_version ) int Routino_Check_API_Version Returns ROUTINO_ERROR_NONE if OK or ROUTINO_ERROR_WRONG_VERSION if there is an error. int caller_version The version of the API used in the caller. This function should not be called directly, use the macro Routino_CheckAPIVersion() which takes no arguments. A wrapper function to simplify the API version check. #define Routino_CheckAPIVersion() Global Function Routino_CreateProfileFromUserProfile() Create a fully formed Routino Profile from a Routino User Profile. Routino_Profile* Routino_CreateProfileFromUserProfile ( Routino_UserProfile* profile ) Routino_Profile* Routino_CreateProfileFromUserProfile Returns an allocated Routino Profile. Routino_UserProfile* profile The user specified profile to convert (not modified by this). Global Function Routino_CreateUserProfileFromProfile() Create a Routino User Profile from a Routino Profile loaded from an XML file. Routino_UserProfile* Routino_CreateUserProfileFromProfile ( Routino_Profile* profile ) Routino_UserProfile* Routino_CreateUserProfileFromProfile Returns an allocated Routino User Profile. Routino_Profile* profile The Routino Profile to convert (not modified by this). Global Function Routino_DeleteRoute() Delete the linked list created by Routino_CalculateRoute. void Routino_DeleteRoute ( Routino_Output* output ) Routino_Output* output The output to be deleted. Global Function Routino_FindWaypoint() Finds the nearest point in the database to the specified latitude and longitude. Routino_Waypoint* Routino_FindWaypoint ( Routino_Database* database, Routino_Profile* profile, double latitude, double longitude ) Routino_Waypoint* Routino_FindWaypoint Returns a pointer to a newly allocated Routino waypoint or NULL if none could be found. Routino_Database* database The Routino database to use. Routino_Profile* profile The Routino profile to use. double latitude The latitude in degrees of the point. double longitude The longitude in degrees of the point. Global Function Routino_FreeXMLProfiles() Free the internal memory that was allocated for the Routino profiles loaded from the XML file. void Routino_FreeXMLProfiles ( void ) Global Function Routino_FreeXMLTranslations() Free the internal memory that was allocated for the Routino translations loaded from the XML file. void Routino_FreeXMLTranslations ( void ) Global Function Routino_GetProfile() Select a specific routing profile from the set of Routino profiles that have been loaded from the XML file or NULL in case of an error. Routino_Profile* Routino_GetProfile ( const char* name ) Routino_Profile* Routino_GetProfile Returns a pointer to an internal data structure - do not free. const char* name The name of the profile to select. Global Function Routino_GetProfileNames() Return a list of the profile names that have been loaded from the XML file. char** Routino_GetProfileNames ( void ) char** Routino_GetProfileNames Returns a NULL terminated list of strings - all allocated. Global Function Routino_GetTranslation() Select a specific translation from the set of Routino translations that have been loaded from the XML file or NULL in case of an error. Routino_Translation* Routino_GetTranslation ( const char* language ) Routino_Translation* Routino_GetTranslation Returns a pointer to an internal data structure - do not free. const char* language The language to select (as a country code, e.g. 'en', 'de') or an empty string for the first in the file or NULL for the built-in English version. Global Function Routino_GetTranslationLanguageFullNames() Return a list of the full names of the translation languages that have been loaded from the XML file. char** Routino_GetTranslationLanguageFullNames ( void ) char** Routino_GetTranslationLanguageFullNames Returns a NULL terminated list of strings - all allocated. Global Function Routino_GetTranslationLanguages() Return a list of the translation languages that have been loaded from the XML file. char** Routino_GetTranslationLanguages ( void ) char** Routino_GetTranslationLanguages Returns a NULL terminated list of strings - all allocated. Global Function Routino_LoadDatabase() Load a database of files for Routino to use for routing. Routino_Database* Routino_LoadDatabase ( const char* dirname, const char* prefix ) Routino_Database* Routino_LoadDatabase Returns a pointer to the database. const char* dirname The pathname of the directory containing the database files. const char* prefix The prefix of the database files. Global Function Routino_ParseXMLProfiles() Parse a Routino XML file containing profiles, must be called before selecting a profile. int Routino_ParseXMLProfiles ( const char* filename ) int Routino_ParseXMLProfiles Returns non-zero in case of an error or zero if there was no error. const char* filename The full pathname of the file to read. Global Function Routino_ParseXMLTranslations() Parse a Routino XML file containing translations, must be called before selecting a translation. int Routino_ParseXMLTranslations ( const char* filename ) int Routino_ParseXMLTranslations Returns non-zero in case of an error or zero if there was no error. const char* filename The full pathname of the file to read. Global Function Routino_UnloadDatabase() Close the database files that were opened by a call to Routino_LoadDatabase(). void Routino_UnloadDatabase ( Routino_Database* database ) Routino_Database* database The database to close. Global Function Routino_ValidateProfile() Validates that a selected routing profile is valid for use with the selected routing database. int Routino_ValidateProfile ( Routino_Database* database, Routino_Profile* profile ) int Routino_ValidateProfile Returns zero if OK or something else in case of an error. Routino_Database* database The Routino database to use. Routino_Profile* profile The Routino profile to validate. -------- Copyright 2015 Andrew M. Bishop. routino-3.0/doc/DATA.txt 644 233 144 11262 12572106465 10274 0 Routino : Data ============== A router relies on data to be able to find a route. OpenStreetMap Data ------------------ The data that is collected by the OpenStreetMap project consists of nodes, ways and relations. Node A node is a point that has a latitude and longitude and attributes that describe what type of point it is (part of a way or a place of interest for example). Way A way is a collection of nodes that when joined together define something (for example a road, a railway, a boundary, a building, a lake etc). The ways also have attributes that define them (speed limits, type of road and restrictions for example). Relation A relation is a collection of items (usually ways) that are related to each other for some reason (highways that make up a route for example). The OpenStreetMap Wiki explains the data much better than I can. Router Data ----------- The information that is needed by a routing algorithm is only a subset of the information that is collected by the OpenStreetMap project. For routing what is required is information about the location of roads (or other highways), the connections between the highways and the properties of those highways. Location of highways (nodes) The locations of things is provided by the nodes from the OpenStreetMap data. The nodes are the only things that have coordinates in OpenStreetMap and everything else is made up by reference to them. Not all of the nodes are useful, only the ones that are part of highways. The location of the nodes is stored but none of the other attributes are currently used by the router. Location of highways (ways) The location of the highways is defined in the OpenStreetMap data by the ways. Only the highway ways are useful and the other ways are discarded. What remains is lists of nodes that join together to form a section of highway. This is further split into segments which are individual parts of a way connected by two nodes. Properties of highways (tags) The ways that belong to highways are extracted from the data in the previous step and for each way the useful information for routing is stored. For the router the useful information is the type of highway, the speed limit, the allowed types of transport and other restrictions (one-way, minimum height, maximum weight etc). Connections between highways The connections between highways are defined in the OpenStreetMap data by ways that share nodes. Since the ways may join in the middle and not just the ends it is the segments defined above that are not part of the OpenStreetMap data that are most important. The information that is extracted from the OpenStreetMap data is stored in an optimised way that allows the routing to be performed quickly. Interpreting Data Tags ---------------------- The tags are the information that is attached to the nodes and ways in OpenStreetMap. The router needs to interpret these tags and use them when deciding what type of traffic can use a highway (for example). There are no well defined rules in OpenStreetMap about tagging, but there is guidance on the OpenStreetMap Wiki "Map_Features" page. This describes a set of recommended tags but these are not universally used so it is up to each application how to interpret them. The tagging rules that the router uses are very important in controlling how the router works. With Routino the data tags can be modified when the data is imported to allow customisation of the information used for routing. Problems With OpenStreetMap Data -------------------------------- The route that can be found is only as good as the data that is available. This is not intended as a criticism of the OpenStreetMap data; it is generally good. There are some problems that are well known and which affect the router. For example highways might be missing because nobody has mapped them. A highway may be wrongly tagged with incorrect properties, or a highway might be missing important tags for routing (e.g. speed limits). There can also be problems with highways that should join but don't because they do not share nodes. A lot of these problems can be found using the interactive data visualiser that uses the same Routino routing database. -------- Copyright 2008-2010 Andrew M. Bishop. routino-3.0/web/ 40755 233 144 0 12563633053 6772 5routino-3.0/web/translations/ 40755 233 144 0 12572577331 11521 5routino-3.0/web/translations/translation.fr.txt 644 233 144 25312 12572577277 15276 0# # French language translation phrases # # # Router output XML definition # %%copyright_creator_string%% Créateur %%copyright_source_string%% Source %%copyright_source_text%% Basé sur les données OpenStreetMap de http://www.openstreetmap.org/ %%copyright_license_string%% License %%turn_-4%% demi-tour à gauche %%turn_-3%% Très à gauche %%turn_-2%% à gauche %%turn_-1%% Légèrement à gauche %%turn_0%% Tout droit %%turn_1%% légèrement à droite %%turn_2%% à droite %%turn_3%% très à droite %%turn_4%% demi-tour à droite %%heading_-4%% Sud %%heading_-3%% Dud-Ouest %%heading_-2%% Ouest %%heading_-1%% Nord-Ouest %%heading_0%% Nord %%heading_1%% Nord-Est %%heading_2%% Est %%heading_3%% Sud-Est %%heading_4%% Sud %%ordinal_1%% Premier %%ordinal_2%% Second %%ordinal_3%% Troisième %%ordinal_4%% Quatrième %%ordinal_5%% Cinquième %%ordinal_6%% Sixième %%ordinal_7%% Septième %%ordinal_8%% huitième %%ordinal_9%% Neuvième %%ordinal_10%% Dixième %%highway_motorway%% autoroute %%highway_trunk%% route de jonction %%highway_primary%% route nationale %%highway_secondary%% route départementale %%highway_tertiary%% route locale %%highway_unclassified%% route non classifiée %%highway_residential%% rue résidentielle %%highway_service%% rue de service %%highway_track%% chemin %%highway_cycleway%% voie cyclable %%highway_path%% sentier %%highway_steps%% escalier %%highway_ferry%% ferry %%route_shortest%% le plus court %%route_quickest%% le plus rapide %%output-html_waypoint_waypoint%% Etape %%output-html_waypoint_junction%% Croisement %%output-html_waypoint_roundabout%% rond-point %%output-html_title%% Itinéraire %s %%output-html_start%% Débute à %s, direction %s %%output-html_node%% à %s, aller %s direction %s %%output-html_rbnode%% Quitter %s, prendre le %s sortir direction %s %%output-html_segment%% Suivre %s pendant %.3f km, %.1f min %%output-html_stop%% S'arrêter à %s %%output-html_total%% Total %.1f km, %.0f minutes %%output-html_subtotal%% %.1f km, %.0f minutes %%output-gpx_waypoint_start%% DEBUT %%output-gpx_waypoint_inter%% INTER %%output-gpx_waypoint_trip%% POINT %%output-gpx_waypoint_finish%% FINAL %%output-gpx_desc%% Itinéraire %s entre les étapes 'début' et 'fin' %%output-gpx_name%% Itinéraire %s %%output-gpx_step%% %s sur '%s' pendant %.3f km, %.1f min %%output-gpx_final%% Trajet total %.1f km, %.0f minutes # # Router (and some shared) translations # @@LANGUAGE@@ Francais @@LANGUAGE-WEBPAGE@@ Francais @@ROUTER-TITLE@@ Calculateur d'itinéraire pour OpenStreetMap @@OPTION-TAB@@ Options @@OPTION-TAB-HELP@@ définir les options @@RESULTS-TAB@@ Résultats @@RESULTS-TAB-HELP@@ Voir les resultats @@DATA-TAB@@ Données @@DATA-TAB-HELP@@ Voir les informations de la base de donnée @@ROUTINO-ROUTER@@ Itinéraires pour Openstreetmap Routino @@ROUTINO-WEBSITE@@ site web Routino @@DOCUMENTATION@@ Documentation @@LANGUAGE-BOX@@ Langue @@WAYPOINTS-BOX@@ Etapes de l'itinéraire @@TRANSPORT-TYPE-BOX@@ Mode de déplacement @@HIGHWAY-PREFERENCES-BOX@@ Préférences routières @@SPEED-LIMITS-BOX@@ Limitations de vitesse @@PROPERTY-PREFERENCES-BOX@@ Préférences des propriétés @@OTHER-RESTRICTIONS-BOX@@ Autres Restrictions @@FIND-BOX@@ Rechercher @@LINKS-BOX@@ Liens @@HELP-BOX@@ Aide @@SHORTEST-ROUTE@@ Le plus court @@QUICKEST-ROUTE@@ Le plus rapide @@STATISTICS-BOX@@ Routino Statistiques @@VISUALISER-BOX@@ Routino Visualiser @@WAYPOINT-POSITION@@ Etape XXX de l'itinéraire @@WAYPOINT-LONGITUDE@@ Etape XXX Longitude @@WAYPOINT-LATITUDE@@ Etape XXX Latitude @@WAYPOINT-LOCATION@@ position de l'étape XXX @@WAYPOINT-SEARCH@@ Rechercher la position @@WAYPOINT-GET@@ obtenir la position actuelle @@WAYPOINT-CENTRE1@@ Centrer la carte sur cette étape @@WAYPOINT-UP@@ Placer cette étape avant @@WAYPOINT-ADD@@ Ajouter une étape après celle-ci @@WAYPOINT-COORDS@@ Coordonnées de position @@WAYPOINT-HOME@@ Changer en position de départ @@WAYPOINT-CENTRE2@@ Centrer cette étape sur la carte @@WAYPOINT-DOWN@@ Placer cette étape après @@WAYPOINT-REMOVE@@ supprimer cette étape @@WAYPOINT-REVERSE@@ Inverser l'ordre des étapes @@WAYPOINT-REVERSE-BUTTON@@ Inverser l'ordre @@WAYPOINT-LOOP@@ Ajouter une nouvelle étape pour faire une boucle @@WAYPOINT-LOOP-BUTTON@@ Faire une boucle @@TRANSPORT-FOOT@@ À pied @@TRANSPORT-HORSE@@ À cheval @@TRANSPORT-WHEELCHAIR@@ Fauteuil roulant @@TRANSPORT-BICYCLE@@ Bicyclette @@TRANSPORT-MOPED@@ Mobilette @@TRANSPORT-MOTORCYCLE@@ Moto @@TRANSPORT-MOTORCAR@@ Voiture @@TRANSPORT-GOODS@@ Camionette @@TRANSPORT-HGV@@ Camion(15t) @@TRANSPORT-PSV@@ Camion(10t) @@HIGHWAY-MOTORWAY@@ Autoroute @@HIGHWAY-TRUNK@@ Trunk @@HIGHWAY-PRIMARY@@ Primaire @@HIGHWAY-SECONDARY@@ Secondaire @@HIGHWAY-TERTIARY@@ Tertiaire @@HIGHWAY-UNCLASSIFIED@@ Non classée @@HIGHWAY-RESIDENTIAL@@ Résidentiel @@HIGHWAY-SERVICE@@ Service @@HIGHWAY-TRACK@@ Chemin @@HIGHWAY-CYCLEWAY@@ Voie cyclable @@HIGHWAY-PATH@@ Sentier @@HIGHWAY-STEPS@@ Escaliers @@HIGHWAY-FERRY@@ Ferry @@PROPERTY-PAVED@@ Pavée @@PROPERTY-MULTILANE@@ Voies multiples @@PROPERTY-BRIDGE@@ Pont @@PROPERTY-TUNNEL@@ Tunnel @@PROPERTY-WALKINGROUTE@@ Itinér. piéton @@PROPERTY-BICYCLEROUTE@@ Itinér. cycle @@RESTRICT-ONEWAY@@ Respecter les sens uniques @@RESTRICT-TURNS@@ Respecter les obligations de tourner @@RESTRICT-WEIGHT@@ Poids @@RESTRICT-HEIGHT@@ Hauteur @@RESTRICT-WIDTH@@ Largeur @@RESTRICT-LENGTH@@ Longueur @@FIND-SHORTEST-ROUTE@@ Chercher l'itinéraire le plus court @@FIND-QUICKEST-ROUTE@@ Chercher l'itinéraire le plus rapide @@MAP-VIEW-LINK@@ Lien vers cet outil de visualisation @@EDIT-OSM-DATA@@ Editer cette donnée OSM @@ROUTER-NOT-RUN@@ Routage non lancé @@ROUTER-RUNNING@@ Routage en cours... @@ROUTER-COMPLETED@@ Routage terminé @@ROUTER-ERROR@@ Erreur de Routage @@ROUTER-FAILED@@ Le Routage n'a pas été lancé correctement @@VIEW-DETAILS@@ Voir les Détails @@NO-INFORMATION@@ Pas d'information @@HTML-ROUTE@@ Itinéraire HTML @@GPX-TRACK-ROUTE@@ Fichier chemin GPX @@GPX-ROUTE@@ Fichier route GPX @@FULL-TEXT-ROUTE@@ Fichier texte complet @@TEXT-ROUTE@@ Fichier texte @@OPEN-POPUP@@ Ouvrir Popup @@DISPLAY-STATISTICS@@ Afficher les données statistiques @@JAVASCRIPT-REQUIRED@@ Javascript est nécessaire pour cette page web à cause de la carte intéractive. @@ROUTER@@ Routeur @@GEO-DATA@@ Geo Data @@TILES@@ Tuiles # # Visualiser specific translations # # # Multi-line descriptive translations (router) # $$ROUTER-INFO$$ Cette page web permet de calculer des itinéraires à l'aide des données collectées par OpenStreetMap. Sélectionner les points de départ et d'arrivée (cliquer sur les icones ci-dessous), sélectionner les préférences, puis rechercher un itinéraire. $$ROUTER-INFO$$ $$ROUTER-OPTIONS-HELP$$ Aide simplifiée
Cliquer sur les icones de balises (ci-dessus) pour les placer sur la carte (droite). Puis les déplacer à la position choisie. Il sera sûrement plus facile de zoomer sur la carte avant de placer les balises. Autre solution, taper la latitude et la longitude dans les cases ci-dessus.

Selectionner le mode de déplacement, les types de voies autorisées, les limitations de vitesse, les propriétés des voies et les autres restrictions dans les options ci-dessus. Selectionner "Le plus court" ou "Le plus rapide" pour calculer l'itinéraire et le visualiser sur la carte.

Etapes
Cliquer sur les balises affichera ou supprimera leur apparition sur la carte. Quand un itinéraire est calculé, il affichera (le plus près possible pour le mode de déplacement sélectionné) chacune des étapes qui ont une balise sur la carte dans l'ordre défini.

Mode de déplacement
Selectionner un mode de déplacement restreindra l'itinéraire choisi aux voies sur lesquelles il est autorisé et définira les valeurs par défaut pour les autres paramètres.

Préferences des voies
La préférence de voies est définie par un pourcentage et des itinéraires sont choisis qui essaient de suivre les voies préferrées. Par exemple, si une voie "Primaire" a une préférence de "110%" et une voie "Secondaire" une préférence de "100%", alors cela signifie qu'un itinéraire sur une voie primaire peut être jusqu'à 10% plus long que sur une voie secondaire et être sélectionné.

Limites de vitesse
Les limites de vitesse choisies ici pour les differents types de voies s'appliquent si la voie n'a pas d'autre limite de vitesse définie ou si celle-ci est supérieure à celle choisie.

Préférences de propriétés
La préférence de propriété est définie par un pourcentage et des itinéraires sont choisis qui essaient de suivre les voies ayant cette propriété préférée. Par exemple, si une voie goudronnée a une préférence de "75%", alors cela signifie que une voie non goudronnée obtient automatiquement une préférence de "25%" ce qui fait que un itinéraire sur une voie goudronnée peut avoir 3 fois la longueur d'une non goudronnée et être sélectionnée.

Autres restrictions
Celles-ci permettent de touver un itinéraire qui respecte les limites définies pour le poids, la hauteur, la largeur ou la longueur. Il est également possible d'ignorer les restrictions de sens unique (e. pour la marche). $$ROUTER-OPTIONS-HELP$$ $$ROUTER-RESULTS-HELP$$ Aide rapide
Après le calcul de l'itinéraire, vous pouvez télécharger le fichier GPX ou la description au format texte (résumé ou version détaillée). Vous pouvez également visualiser la description de l'itinéraire et zoomer sur des tronçons sélectionnés.

Résoudre un problème
Si le calculateur aboutie à une erreur, la cause la plus probable est que il n'est pas possible de trouver un itinéraire entre les points sélectionnés. Por permettre de trouver un itinéraire, déplacer une ou des balises ou changer les options de recherche.

Formats d'affichage

Instructions HTML
une description de l'itinéraire à prendre à chaque intersection importante.
Fichier chemin GPX
La même information qui est affichée sur la carte avec des points pour chaque noeud et des lignes pour tous les sègments.
Fichier route GPX
La même information qui est affichée en texte pour l'itinéraire avec une étape pour chaque intersection importante.
Fichier texte complet
Une liste de tous les noeuds traversés ainsi que la distance entre eux et la distance cumulée pour chaque étape de l'itinéraire.
Fichier texte
La même information qui est affichée en texte pour l'itinéraire.
$$ROUTER-RESULTS-HELP$$ $$ROUTER-VISUALISER-INFO$$ Pour comprendre comment Routino voit les données, il y a un outil de visualisation qui permet d'afficher les données soujacentes de multiples manières. $$ROUTER-VISUALISER-INFO$$ # # Multi-line descriptive translations (visualiser) # routino-3.0/web/translations/translation.nl.txt 644 233 144 21470 12572577307 15273 0# # Dutch language translation phrases # # # Router output XML definition # %%copyright_creator_string%% Creator %%copyright_source_string%% Source %%copyright_source_text%% Gebouwd op OpenStreetMap data van http://www.openstreetmap.org/ %%copyright_license_string%% License %%turn_-4%% Haarspeld naar links %%turn_-3%% Scherp links %%turn_-2%% Links %%turn_-1%% Half links %%turn_0%% Rechtdoor %%turn_1%% Half rechts %%turn_2%% Rechts %%turn_3%% Scherp rechts %%turn_4%% Haarspeld naar rechts %%heading_-4%% Zuid %%heading_-3%% Zuid-West %%heading_-2%% West %%heading_-1%% Noord-West %%heading_0%% Noord %%heading_1%% Noord-Oost %%heading_2%% Oost %%heading_3%% Zuid-Oost %%heading_4%% Zuid %%ordinal_1%% Eerste %%ordinal_2%% Tweede %%ordinal_3%% Derde %%ordinal_4%% Vierde %%ordinal_5%% Vijfde %%ordinal_6%% Zesde %%ordinal_7%% Zevende %%ordinal_8%% Achtste %%ordinal_9%% Negende %%ordinal_10%% Tiende %%highway_motorway%% Autostrade %%highway_trunk%% Autoweg %%highway_primary%% Provinciale weg %%highway_secondary%% Nationale weg %%highway_tertiary%% Doorgangsweg %%highway_unclassified%% Niet geclassificeerd %%highway_residential%% Woongebied %%highway_service%% Toegangsweg %%highway_track%% Veldweg %%highway_cycleway%% Fietspad %%highway_path%% Pad %%highway_steps%% Trap %%highway_ferry%% Veerboot %%route_shortest%% Kortste %%route_quickest%% Snelste %%output-html_waypoint_waypoint%% Punt %%output-html_waypoint_junction%% de splitsing %%output-html_waypoint_roundabout%% rotonde %%output-html_title%% %s Route %%output-html_start%% Start bij %s neemt u de richting %s %%output-html_node%% Bij %s gaat u %s richting %s %%output-html_rbnode%% Leave aan de %s, neem de %s afslag richting %s %%output-html_segment%% Volg u de %s voor %.3f km %.1f min %%output-html_stop%% Stop U bent bij %s aangekomen %%output-html_total%% Totaal %.1f km, %.0f minuten %%output-html_subtotal%% %.1f km, %.0f minuten %%output-gpx_waypoint_start%% START %%output-gpx_waypoint_inter%% INTER %%output-gpx_waypoint_trip%% TRIP %%output-gpx_waypoint_finish%% FINISH %%output-gpx_desc%% %s Route tussen 'Start' und 'Finish' %%output-gpx_name%% %s Route %%output-gpx_step%% %s op '%s' voor %.3f km, %.1f min %%output-gpx_final%% Totaal trip %.1f km, %.0f minuten # # Router (and some shared) translations # @@LANGUAGE@@ Nederlands @@LANGUAGE-WEBPAGE@@ Nederlandse web pagina @@OPTION-TAB@@ Opties @@RESULTS-TAB@@ Resultaten @@DATA-TAB@@ Data @@LANGUAGE-BOX@@ Taal @@WAYPOINTS-BOX@@ Coordinaten @@TRANSPORT-TYPE-BOX@@ Transport Type @@HIGHWAY-PREFERENCES-BOX@@ Voorkeur Wegtype @@SPEED-LIMITS-BOX@@ Snelheidslimieten @@PROPERTY-PREFERENCES-BOX@@ Weg Eigenschappen @@OTHER-RESTRICTIONS-BOX@@ Andere Beperkingen @@FIND-BOX@@ Zoek Route @@LINKS-BOX@@ Links @@HELP-BOX@@ Help @@STATUS-BOX@@ Status @@SHORTEST-ROUTE@@ Kortste Route @@QUICKEST-ROUTE@@ Snelste Route @@WAYPOINT-POSITION@@ Waypoint XXX Position @@WAYPOINT-UP@@ Beweeg dit punt naar boven @@WAYPOINT-ADD@@ Voeg hierna punt toe @@WAYPOINT-HOME@@ Toggle als thuis locatie @@WAYPOINT-CENTRE2@@ Centreer dit punt op map @@WAYPOINT-DOWN@@ Beweeg dit punt naar beneden @@WAYPOINT-REMOVE@@ Verwijder dit punt @@WAYPOINT-REVERSE@@ Keer volgorde punten om @@WAYPOINT-REVERSE-BUTTON@@ Keer volgorde punten om @@TRANSPORT-FOOT@@ Te voet @@TRANSPORT-HORSE@@ Paard @@TRANSPORT-WHEELCHAIR@@ Rolstoel @@TRANSPORT-BICYCLE@@ Fiets @@TRANSPORT-MOPED@@ Brommer @@TRANSPORT-MOTORCYCLE@@ Motorfiets @@TRANSPORT-MOTORCAR@@ Auto @@TRANSPORT-GOODS@@ Goederen @@TRANSPORT-HGV@@ Zwaar transport @@TRANSPORT-PSV@@ Publiek transport @@HIGHWAY-MOTORWAY@@ Autostrade @@HIGHWAY-TRUNK@@ Autoweg @@HIGHWAY-PRIMARY@@ Provinciale wegen @@HIGHWAY-SECONDARY@@ Nationale wegen @@HIGHWAY-TERTIARY@@ Doorgangsweg @@HIGHWAY-UNCLASSIFIED@@ Niet geclassificeerd @@HIGHWAY-RESIDENTIAL@@ Woongebied @@HIGHWAY-SERVICE@@ Toegangsweg @@HIGHWAY-TRACK@@ Veldweg @@HIGHWAY-CYCLEWAY@@ Fietspad @@HIGHWAY-PATH@@ Pad @@HIGHWAY-STEPS@@ Trap @@HIGHWAY-FERRY@@ Ferry @@PROPERTY-PAVED@@ Verhard @@PROPERTY-MULTILANE@@ Meerdere Stroken @@PROPERTY-BRIDGE@@ Brug @@PROPERTY-TUNNEL@@ Tunnel @@RESTRICT-ONEWAY@@ Volg Eenrichtingsverkeer @@RESTRICT-WEIGHT@@ Gewicht @@RESTRICT-HEIGHT@@ Hoogte @@RESTRICT-WIDTH@@ Breedte @@RESTRICT-LENGTH@@ Lengte @@FIND-SHORTEST-ROUTE@@ Zoek de kortste route @@FIND-QUICKEST-ROUTE@@ Zoek de snelste route @@EDIT-OSM-DATA@@ Lees hoe je OSM data kan inbrengen @@ROUTER-NOT-RUN@@ Router niet in gebruik @@ROUTER-RUNNING@@ Router werkt... @@ROUTER-COMPLETED@@ Routing voltooid @@ROUTER-ERROR@@ Router error @@ROUTER-FAILED@@ Router werkt niet @@HTML-ROUTE@@ HTML directions @@GPX-TRACK-ROUTE@@ GPX track bestand @@GPX-ROUTE@@ GPX route bestand @@FULL-TEXT-ROUTE@@ Volledig tekst bestand @@TEXT-ROUTE@@ Tekst bestand # # Visualiser specific translations # @@INSTRUCTIONS-BOX@@ Instructies @@NO-DATA-DISPLAYED@@ Geen data getoond @@SPEED-BUTTON@@ Toon snelheidslimieten @@WEIGHT-BUTTON@@ Toon massa limieten @@WEIGHT-LIMIT-8@@ 8.0 ton massa limiet @@HEIGHT-BUTTON@@ Toon hoogte limieten @@HEIGHT-LIMIT-4@@ 4.0 m hoogte limiet @@WIDTH-BUTTON@@ Toon breedte limieten @@WIDTH-LIMIT-3@@ 3.0 m breedte limiet # # Multi-line descriptive translations (router) # $$ROUTER-INFO$$ Zoom naar straatniveau. Selecteer start- and eindpunten onder Coordinaten. (click op het marker icoon links, schuif het op map naar gewenste positie). $$ROUTER-INFO$$ $$ROUTER-OPTIONS-HELP$$ Quick Start
Click op marker-icoontje (Waypoints) om ze op de map te plaatsen (rechts). Sleep ze vervolgens naar de gewenste positie. Het is best om eerst naar straat niveau te zoomen op de kaart. Selecteer het transport type, toegestane weg-types, snelheidslimieten, wegeigenschappen en andere restricties uit de opties. Selecteer "Kortste" of "Snelste" om de route te berekenen en te tekenen op de map.

Coordinaten (Waypoints)
Click op het marker icoontje, nog eens clicken voor aan/uit. Wanneer de route berekend wordt, zal dit nauwkeurig aansluiten bij de volgorde van deze punten. (rekening houdend met transport type)

Transport Type
Wanneer je een bepaald transport type kiest wordt bij berekenen route hiermede rekening gehouden. Het transport type bestaat uit een lijst met default waarden voor ieder wegtype. Deze percentages kunnen ook nog eens manueel aangepast worden.

Voorkeur Wegtype
De voorkeur voor een bepaald type weg wordt uitgedrukt in een percentage. Bijvoorbeeld wanneer u het Transport Type "Fiets" kiest, dan zal er voor Autostrade 0% staan, en voor Fietspad 100%. Wanneer u Autowegen, Nationale wegen wil vermijden of beperken bij het maken van een fietsroute, kan u percentage naar beneden aanpassen.

Snelheid limieten
De snelheidslimieten worden afgeleid van het type weg. Het is mogelijk dat er voor een bepaalde weg andere beperkingen gelden. In dat geval worden die gekoezen. (het geval dat deze lager zijn dan de default)

Weg Eigenschappen
Voor het berekenen van de route, kan de de voorkeur gegeven worden aan een bepaalde wegeigenschap. Wanneer u kiest voor 25% verhard, zal er automatisch de voorkeur aan 75% onverhard worden gegeven. Ook al is het onverharde stuk 3 X langer, toch kan er dan de voorkeur aan gegeven worden.

Andere Beperkingen
Deze zullen toelaten dat er een route berekend wordt die rekening houdt met gewicht, hoogte, breedte of lengte. Het is ook mogelijk geen rekening te houden met eenrichtingsverkeer (bijvoorbeeld als voetganger of fietser) $$ROUTER-OPTIONS-HELP$$ $$ROUTER-RESULTS-HELP$$ Quick Start
Na het berekenen van een route, kan het GPX bestand, of de beschrijving als tekstbestand downloaden. Door met muis over de beschrijving te bewegen, ziet u die ook op de kaart gesitueerd.

Problem Solving
Als de router eindigt met een fout, dan is de meest waarschijnlijke oorzaak, dat er geen route mogelijk is tussen de gekozen punten. Het verplaatsen van de punten, of het aanpassen van weg-eigenschappen of voertuigtype kan een oplossing bieden.

Output Formats

HTML instructies
Een beschrijving van de route, met de te nemen afslag aan iedere splitsing.
GPX track bestand
Dezelfde informatie die op de kaart wordt weergegeven. Met coordinaten voor ieder knooppunt, en een track voor ieder segment.
GPX route bestand
Dezelfde informatie dat is opgenomen in de tekst van de route, met een coordinaat voor iedere belangrijke splitsing.
Full text bestand
Een lijst met alle coordinaten, met de afstand hier tussen. En een cumulatieve afstand voor iedere stap op de route.
Text bestand
Dezelfde informatie als wordt weergegeven in de tekst voor de route.
$$ROUTER-RESULTS-HELP$$ $$ROUTER-VISUALISER-INFO$$ Om te kijken hoe Routino omgaat met de basisdata, is er een tooltje dat de onderliggende data toont op verschillende manieren. $$ROUTER-VISUALISER-INFO$$ # # Multi-line descriptive translations (visualiser) # routino-3.0/web/translations/translation.de.txt 644 233 144 26565 12572577267 15271 0# # German language translation phrases # # # Router output XML definition # %%copyright_creator_string%% Urheber %%copyright_source_string%% Quelle %%copyright_source_text%% Basierend auf OpenStreetMap-Daten, erhältlich via http://www.openstreetmap.org/ %%copyright_license_string%% Lizenz %%turn_-4%% Sehr scharf links %%turn_-3%% Scharf links %%turn_-2%% Links %%turn_-1%% Halb links %%turn_0%% Geradeaus %%turn_1%% Halb rechts %%turn_2%% Rechts %%turn_3%% Scharf rechts %%turn_4%% Sehr scharf rechts %%heading_-4%% Süd %%heading_-3%% Süd-West %%heading_-2%% West %%heading_-1%% Nord-West %%heading_0%% Nord %%heading_1%% Nord-Ost %%heading_2%% Ost %%heading_3%% Süd-Ost %%heading_4%% Süd %%ordinal_1%% Erste %%ordinal_2%% Zweite %%ordinal_3%% Dritte %%ordinal_4%% Vierte %%ordinal_5%% Fünfte %%ordinal_6%% Sechste %%ordinal_7%% Siebte %%ordinal_8%% Achte %%ordinal_9%% Neunte %%ordinal_10%% Zehnte %%highway_motorway%% Autobahn %%highway_trunk%% Schnellstraße %%highway_primary%% Bundesstraße %%highway_secondary%% Landesstraße %%highway_tertiary%% Kreisstraße %%highway_unclassified%% Nebenstraße %%highway_residential%% Wohngebietsstraße %%highway_service%% Erschließungsweg %%highway_track%% Feld-/Waldweg %%highway_cycleway%% Radweg %%highway_path%% Weg/Pfad %%highway_steps%% Treppe %%highway_ferry%% Fähre %%route_shortest%% Kürzeste %%route_quickest%% Schnellste %%output-html_waypoint_waypoint%% Wegpunkt %%output-html_waypoint_junction%% Anschlussstelle %%output-html_waypoint_roundabout%% Kreisverkehr %%output-html_title%% %s Route %%output-html_start%% Start bei %s halten Sie sich Richtung %s %%output-html_node%% Bei %s wenden Sie sich nach %s Richtung %s %%output-html_rbnode%% Verlassen Sie %s, nehmen Sie die %s Ausfahrt Richtung %s %%output-html_segment%% Folgen Sie der %s für %.3f km bzw. %.1f min %%output-html_stop%% Stop Sie sind bei %s angekommen %%output-html_total%% Gesamt %.1f km, %.0f minuten %%output-html_subtotal%% %.1f km, %.0f minuten %%output-gpx_waypoint_start%% START %%output-gpx_waypoint_inter%% INTER %%output-gpx_waypoint_trip%% TRIP %%output-gpx_waypoint_finish%% FINISH %%output-gpx_desc%% %s Strecke zwischen 'Start' und 'Ziel' %%output-gpx_name%% %s Strecke %%output-gpx_step%% %s auf '%s' für %.3f km, %.1f min %%output-gpx_final%% Gesamtstrecke %.1f km, %.0f minuten # # Router (and some shared) translations # @@LANGUAGE@@ Deutsch @@LANGUAGE-WEBPAGE@@ Deutsche Webseite @@ROUTER-TITLE@@ Routen Planer für OpenStreetMap Daten @@OPTION-TAB@@ Optionen @@OPTION-TAB-HELP@@ Setze Routing-Optionen @@RESULTS-TAB@@ Ergebnisse @@RESULTS-TAB-HELP@@ Sieh die Ergebnisse @@DATA-TAB@@ Daten @@DATA-TAB-HELP@@ Sieh die Datenbankinformationen @@ROUTINO-ROUTER@@ Routino OpenStreetMap Router @@ROUTINO-WEBSITE@@ Routino Website @@DOCUMENTATION@@ Dokumentation @@LANGUAGE-BOX@@ Sprache @@WAYPOINTS-BOX@@ Wegpunkte @@TRANSPORT-TYPE-BOX@@ Fortbewegungsart @@HIGHWAY-PREFERENCES-BOX@@ Vorgaben zur Wegnutzung @@SPEED-LIMITS-BOX@@ Geschwindigkeitsvorgaben @@PROPERTY-PREFERENCES-BOX@@ Vorgaben zur Wegbeschaffenheit @@OTHER-RESTRICTIONS-BOX@@ andere Vorgaben @@FIND-BOX@@ Suche @@LINKS-BOX@@ Links @@HELP-BOX@@ Hilfe @@STATUS-BOX@@ Status @@SHORTEST-ROUTE@@ kürzester Weg @@QUICKEST-ROUTE@@ schnellste Route @@STATISTICS-BOX@@ Routino Statistik @@VISUALISER-BOX@@ Routino Ansichten @@WAYPOINT-POSITION@@ Wegpunkt XXX Position @@WAYPOINT-LONGITUDE@@ Wegpunkt XXX geografische Länge @@WAYPOINT-LATITUDE@@ Wegpunkt XXX geografische Breite @@WAYPOINT-LOCATION@@ Wegpunkt XXX Ort @@WAYPOINT-SEARCH@@ Nach Ort suchen @@WAYPOINT-GET@@ Aktuellen Ort bestimmen @@WAYPOINT-CENTRE1@@ Karte auf Wegpunkt zentrieren @@WAYPOINT-UP@@ wegpunkt nach oben verschieben @@WAYPOINT-ADD@@ Neuer Wegpunkt nach diesem @@WAYPOINT-COORDS@@ Koordinaten des Orts @@WAYPOINT-HOME@@ Umschalten auf den Standort des Zuhauses @@WAYPOINT-CENTRE2@@ Wegpunkt auf Karte zentrieren @@WAYPOINT-DOWN@@ Wegpunkt nach unten verschieben @@WAYPOINT-REMOVE@@ Wegpunkt entfernen @@WAYPOINT-REVERSE@@ Rückwärts @@WAYPOINT-REVERSE-BUTTON@@ Rückwärts @@WAYPOINT-LOOP@@ Einen Wegpunkt hinzufügen um eine Schlaufe zu machen @@WAYPOINT-LOOP-BUTTON@@ Schleife schließen @@TRANSPORT-FOOT@@ Fußgänger @@TRANSPORT-HORSE@@ Reiter @@TRANSPORT-WHEELCHAIR@@ Rollstuhl @@TRANSPORT-BICYCLE@@ Fahrrad @@TRANSPORT-MOPED@@ Moped @@TRANSPORT-MOTORCYCLE@@ Motorrad @@TRANSPORT-MOTORCAR@@ Auto @@TRANSPORT-GOODS@@ LKW @@TRANSPORT-HGV@@ Schwertransport/LKW @@TRANSPORT-PSV@@ Öffentlicher Personenverkehr @@HIGHWAY-MOTORWAY@@ Autobahn @@HIGHWAY-TRUNK@@ Schnellstraße @@HIGHWAY-PRIMARY@@ Bundesstraße @@HIGHWAY-SECONDARY@@ Landesstraße @@HIGHWAY-TERTIARY@@ Hauptstraße @@HIGHWAY-UNCLASSIFIED@@ Straße @@HIGHWAY-RESIDENTIAL@@ Wohnstraße @@HIGHWAY-SERVICE@@ Zufahrtsweg @@HIGHWAY-TRACK@@ Feld-(Wald-)weg @@HIGHWAY-CYCLEWAY@@ Fahrradweg @@HIGHWAY-PATH@@ Weg @@HIGHWAY-STEPS@@ Treppe @@HIGHWAY-FERRY@@ Fähre @@PROPERTY-PAVED@@ befestigt @@PROPERTY-MULTILANE@@ mehrspurig @@PROPERTY-BRIDGE@@ Brücken @@PROPERTY-TUNNEL@@ Tunnel @@PROPERTY-WALKINGROUTE@@ Wanderweg @@PROPERTY-BICYCLEROUTE@@ Radweg @@RESTRICT-ONEWAY@@ beachte Einbahnstraßen @@RESTRICT-TURNS@@ beachte Abbiegeverbot @@RESTRICT-WEIGHT@@ Gewicht @@RESTRICT-HEIGHT@@ Höhe @@RESTRICT-WIDTH@@ Breite @@RESTRICT-LENGTH@@ Länge @@FIND-SHORTEST-ROUTE@@ Kürzeste Route finden @@FIND-QUICKEST-ROUTE@@ Schnellste Route finden @@MAP-VIEW-LINK@@ anpassen dieser Kartenansicht @@EDIT-OSM-DATA@@ Bearbeitet die OSM-Daten @@ROUTER-NOT-RUN@@ Router läuft nicht @@ROUTER-RUNNING@@ Router läuft... @@ROUTER-COMPLETED@@ Routing fertig @@ROUTER-ERROR@@ Router Fehler @@ROUTER-FAILED@@ Router funktioniert nicht @@VIEW-DETAILS@@ zeige Details @@NO-INFORMATION@@ keine Information @@HTML-ROUTE@@ HTML @@GPX-TRACK-ROUTE@@ GPX Track-Datei @@GPX-ROUTE@@ GPX Routen-Datei @@FULL-TEXT-ROUTE@@ Volltext-Datei @@TEXT-ROUTE@@ Text-Datei @@OPEN-POPUP@@ öffne Popup @@DISPLAY-STATISTICS@@ zeige die Statistik @@JAVASCRIPT-REQUIRED@@ Um die interaktive Karte zu nutzen iWork Javascript benötigt. @@ROUTER@@ Router @@GEO-DATA@@ Geodaten @@TILES@@ Kacheln # # Visualiser specific translations # @@VISUALISER-TITLE@@ Visualisierung der Routing-Daten @@INSTRUCTIONS-BOX@@ Anweisungen @@ROUTER-BOX@@ Routino Router @@NO-DATA-DISPLAYED@@ Keine Daten angezeigt @@VISUALISER-FAILED@@ Fehler bei der Erstellung der visuellen Daten! @@VISUALISER-NUM-JUNCTIONS@@ # Kreuzungen verarbeitet @@VISUALISER-NUM-SUPER@@ # Super-Knoten/Segmente verarbeitet @@VISUALISER-NUM-WAYTYPE@@ # Wegtypen Segmente verarbeitet @@VISUALISER-NUM-SEGMENTS@@ # Segmente verarbeitet @@VISUALISER-NUM-NODES@@ # Knoten verarbeitet @@VISUALISER-NUM-TURNS@@ # Abbiegebeschrängkungen verarbeitet @@VISUALISER-NUM-LIMITS@@ # Limit-Änderungen verarbeitet @@VISUALISER-NUM-ERRORS@@ # Error Logs erstellt @@JUNCTIONS-BUTTON@@ Kreuzungen anzeigen @@JUNCTIONS-2@@ Aufeinandertreffen zweier Wege unterschiedlichen Typs. @@JUNCTIONS-3@@ Aufeinandertreffen von drei Wegen. @@JUNCTIONS-4@@ Aufeinandertreffen von vier Wegen. @@JUNCTIONS-5@@ Aufeinandertreffen von fünf Wegen. @@JUNCTIONS-6@@ Aufeinandertreffen von sechs Wegen. @@JUNCTIONS-MORE@@ Aufeinandertreffen von sieben oder mehr Wegen. @@SUPER-BUTTON@@ Super-Segments anzeigen @@TURNS-BUTTON@@ Zeige Abbiegebeschränkungen @@SPEED-BUTTON@@ Zeige Geschwindigkeitsbeschränkungen @@SPEED-LIMIT-80@@ 80 km/Stunde Geschwindigkeitsbegrenzung @@WEIGHT-BUTTON@@ Gewichtswegbeschränkungen anzeigen @@WEIGHT-LIMIT-8@@ 8 Tonnen Wegbeschränkung @@HEIGHT-BUTTON@@ Maximale Höhe anzeigen @@HEIGHT-LIMIT-4@@ 4.0 m Höhenbeschränkung @@WIDTH-BUTTON@@ Maximale Breite anzeigen @@CLEAR-DATA-BUTTON@@ Daten zurücksetzen # # Multi-line descriptive translations (router) # $$ROUTER-INFO$$ Diese Website erlaubt Routing mit den Daten, die OpenStreetMap gesammelt hat. Wähle Start- und Endpunkt (klicke auf die Marker-Symbole unten), wähle die Routing-Vorgaben und dann finde den Weg. $$ROUTER-INFO$$ $$ROUTER-OPTIONS-HELP$$ Schnellanleitung
Klicke auf die Marker-Bildchen (oben), um sie in der Mitte der Karte (rechts) zu positionieren. Dann ziehe das Bildchen auf die genaue Position. Das Zoomen der Karte vor der Patzierung ist vermutlich am einfachsten. Alternativ kann man die geografische Breite und Länge in den Kästchen eintragen.

Wähle die Fortbewegungsart, die Vorgaben zur Wegnutzung, die Geschwindigkeitsvorgaben, die Vorgaben zur Wegbeschaffenheit und die anderen Vorgaben von den obigen Auswahlfeldern. Ein Klick auf "kürzeste" oder "schnellste" ermittelt die entsprechende Verbindung und zeigt sie in der Karte an.

Wegpunkte
Ein Klick auf das Marker-Bildchen (oben) schaltet die Sichbarkeit in der Karte ein bzw. aus. Die Berechnung Route erfolgt in der Reihenfolge der Wegpunkte (so gut, wie es für die gewählte Fortbewegungsart möglich ist).

Fortbewegungsart
Die Auswahl der Fortbewegungsart bestimmt die bei der Routenberechnung erlaubten Wegtypen und die Vorgabeeinstellungen aller anderen Parameter.

Vorgaben zur Wegnutzung
Die Vorgaben zur Wegnutzung bestimmen die Priorisierung von Wegarten. Wenn z. B. Schnellstraßen mit 110% und Bundesstraßen mit 100% angegeben werden, wird bei zwei möglichen Wegwahlen die Schnellstraße solange bevorzugt wird, wie der Längen(oder Zeit-)unterschied 10% nicht überschreitet.

Geschwindigkeitsvorgaben
Die hier geannten Geschwindigkeiten werden für den jeweiligen Wegtyp finden Anwendung wenn keine andere Geschwindkeitsbegrenzung mit geringerem Wert bekannt ist.

Vorgaben zur Wegbeschaffenheit
Die Vorgaben zur Wegbeschaffenheit werden als Prozentangaben verwendet, um die Verhältnisse der Wegbenutzung zu steuern. Wenn z. B. befestigte Wege mit 75% angegeben sind, werden unbefestigte automatisch mit 25% angenommen, so werden Wege ausgewählt, die mindestens drei mal länger auf befestigten Wegen verlaufen.

andere Vorgaben
Die Berücksichtigung von Benutzungs-Begrenzungen durch Gewicht, Höhe, Länge und Breite ist möglich. Genauso können Einbahnstraßenbeschräkungen ignoriert werden (z. B. als Fußgänger). $$ROUTER-OPTIONS-HELP$$ $$ROUTER-RESULTS-HELP$$ Schnellanleitung
Nach der Routenberechnung kann man eine GPX oder eine einfache Textdatei (Kurz- oder Langfassung) herunterladen. Ebenso kann man die Routenbeschreibung ansehen und in ausgewälte Bereiche zoomen.

Problemlösung
Wenn der Router einen Fehler meldet liegt es meistens daran, dass kein Weg zwischen den gewälten Punkten unter Beachtung der Vorgaben gefunden werden kann. Das Bewegen eines oder mehrere Punkte oder das verändern von Vorgaben sollte es erlauben eine Route zu finden.

Ausgabe-Formate

HTMLs
Eine Beschreibung der Route mit Anweisungen für jede wichtige Abzweigung.
GPX Track-Datei
Die gleichen Informationen, die in der Karte angezeigt werden mit Punkten für jeden Abzweig und Linien für jedes Teilstück.
GPX Routen-Datei
Die gleichen Informationen, die im Text angezeigt werden mit einem Wegpunkt für jede wichtige Richtungsänderung.
Volltext-Datei
Eine aller Knoten und die Abstände zwischen ihnen, sowie die Gesamtentfernung vom i Startpunkt zum jeweiligen Konten.
Text-Datei
Die gleiche Information, die als Text angezeigt wird.
$$ROUTER-RESULTS-HELP$$ $$ROUTER-VISUALISER-INFO$$ Die Anzeige der Daten kann auf verschiedene Weise angepasst werden. $$ROUTER-VISUALISER-INFO$$ # # Multi-line descriptive translations (visualiser) # routino-3.0/web/translations/translation.ru.txt 644 233 144 12355 12572577322 15307 0# # Russian language translation phrases # # # Router output XML definition # %%copyright_creator_string%% Ðвтор %%copyright_source_string%% ИÑточник %%copyright_source_text%% ИÑпользованы данные OpenStreetMap http://www.openstreetmap.org/ %%copyright_license_string%% Ð›Ð¸Ñ†ÐµÐ½Ð·Ð¸Ñ %%turn_-4%% очень крутой поворот налево %%turn_-3%% крутой поворот налево %%turn_-2%% налево %%turn_-1%% плавно налево %%turn_0%% прÑмо %%turn_1%% плавно направо %%turn_2%% направо %%turn_3%% крутой поворот направо %%turn_4%% очень крутой поворот направо %%heading_-4%% юг %%heading_-3%% юго-запад %%heading_-2%% запад %%heading_-1%% Ñеверо-запад %%heading_0%% Ñевер %%heading_1%% Ñеверо-воÑток %%heading_2%% воÑток %%heading_3%% юго-воÑток %%heading_4%% юг %%ordinal_1%% Первый %%ordinal_2%% Второй %%ordinal_3%% Третий %%ordinal_4%% Четвертый %%ordinal_5%% ПÑтый %%ordinal_6%% ШеÑтой %%ordinal_7%% Седьмой %%ordinal_8%% ВоÑьмой %%ordinal_9%% ДевÑтый %%ordinal_10%% ДеÑÑтый %%highway_motorway%% автомагиÑтраль %%highway_trunk%% Ð¼ÐµÐ¶Ð´ÑƒÐ½Ð°Ñ€Ð¾Ð´Ð½Ð°Ñ Ñ‚Ñ€Ð°ÑÑа %%highway_primary%% дорога регионального Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ %%highway_secondary%% дорога облаÑтного Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ %%highway_tertiary%% дорога районного Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ %%highway_unclassified%% дорога меÑтного Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ %%highway_residential%% улица %%highway_service%% проезд %%highway_track%% дорога Ñ/Ñ… Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ %%highway_cycleway%% велодорожка %%highway_path%% тропинка %%highway_steps%% леÑтница %%highway_ferry%% паром %%route_shortest%% Короткий %%route_quickest%% БыÑтрый %%output-html_waypoint_waypoint%% Ð¿ÑƒÑ‚ÐµÐ²Ð°Ñ Ñ‚Ð¾Ñ‡ÐºÐ° %%output-html_waypoint_junction%% перекреÑтке %%output-html_title%% %s маршрут %%output-html_start%% Старт %s, на %s %%output-html_node%% на %s, %s, на %s %%output-html_segment%% Следуйте по %s %.3f км, %.1f мин %%output-html_stop%% Стоп %s %%output-html_total%% Ð’Ñего %.1f км, %.0f минут %%output-html_subtotal%% %.1f км, %.0f минут %%output-gpx_waypoint_start%% Старт %%output-gpx_waypoint_inter%% INTER %%output-gpx_waypoint_trip%% TRIP %%output-gpx_waypoint_finish%% Финиш %%output-gpx_desc%% %s маршрут от 'Старта' до 'Финиша' %%output-gpx_name%% %s маршрут %%output-gpx_step%% на %s по '%s' %.3f км, %.1f мин %%output-gpx_final%% Ð’Ñего - %.1f км, продолжительноÑть - %.0f минут # # Router (and some shared) translations # @@LANGUAGE@@ РуÑÑкий @@LANGUAGE-WEBPAGE@@ РуÑÑкий @@OPTION-TAB-HELP@@ Задать наÑтройки маршрутизации @@DOCUMENTATION@@ Ð”Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð°Ñ†Ð¸Ñ @@LANGUAGE-BOX@@ Язык @@TRANSPORT-TYPE-BOX@@ Тип транÑпорта @@SPEED-LIMITS-BOX@@ ÐžÐ³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ ÑкороÑти @@OTHER-RESTRICTIONS-BOX@@ Другие Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ @@HELP-BOX@@ Помощь @@STATUS-BOX@@ Ð¡Ñ‚Ð°Ñ‚ÑƒÑ @@SHORTEST-ROUTE@@ Кратчайший маршрут @@QUICKEST-ROUTE@@ БыÑтрейший маршрут @@TRANSPORT-HORSE@@ Лошадь @@TRANSPORT-WHEELCHAIR@@ Инвалидное креÑло @@TRANSPORT-BICYCLE@@ ВелоÑипед @@TRANSPORT-MOPED@@ Мопед @@TRANSPORT-MOTORCYCLE@@ Мотоцикл @@TRANSPORT-GOODS@@ Товары @@HIGHWAY-MOTORWAY@@ ÐвтомагиÑтраль @@PROPERTY-BRIDGE@@ МоÑÑ‚ @@PROPERTY-TUNNEL@@ Туннель @@PROPERTY-WALKINGROUTE@@ Пеший маршрут @@PROPERTY-BICYCLEROUTE@@ Велодорожка @@RESTRICT-ONEWAY@@ ОдноÑтороннÑÑ ÑƒÐ»Ð¸Ñ†Ð° @@RESTRICT-WEIGHT@@ Ð’ÐµÑ @@RESTRICT-HEIGHT@@ Ð’Ñ‹Ñота @@RESTRICT-WIDTH@@ Ширина @@RESTRICT-LENGTH@@ Длина @@FIND-SHORTEST-ROUTE@@ Ðайти кратчайший маршрут @@FIND-QUICKEST-ROUTE@@ Ðайти быÑтрейший маршут @@TILES@@ Тайлы # # Visualiser specific translations # @@INSTRUCTIONS-BOX@@ ИнÑтрукции @@NO-DATA-DISPLAYED@@ Ðет данных Ð´Ð»Ñ Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ @@VISUALISER-NUM-NODES@@ Обработано # нод @@VISUALISER-NUM-TURNS@@ Обработано # ограничений поворотов @@TURNS-BUTTON@@ Показывать Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð²Ð¾Ñ€Ð¾Ñ‚Ð¾Ð² @@SPEED-BUTTON@@ Показывать Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ ÑкороÑти @@LIMIT-CHANGE@@ Изменить Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ @@SPEED-LIMIT-80@@ Ограничение ÑкороÑти 80 км/ч @@WEIGHT-BUTTON@@ Показывать Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð¿Ð¾ веÑу @@WEIGHT-LIMIT-8@@ Ограничение веÑа 8 тонн @@HEIGHT-BUTTON@@ Показывать ограничение по выÑоте @@HEIGHT-LIMIT-4@@ Ограничение выÑоты 4.0 метра @@WIDTH-BUTTON@@ Показывать ограничение ширины # # Multi-line descriptive translations (router) # # # Multi-line descriptive translations (visualiser) # routino-3.0/web/translations/translation.hu.txt 644 233 144 16714 12572577303 15277 0# # Hungarian language translation phrases # # # Router output XML definition # %%copyright_creator_string%% KészítÅ‘ %%copyright_source_string%% Forrás %%copyright_source_text%% Openstreetmap adatok alapján http://www.openstreetmap.org/ %%copyright_license_string%% Liszenc %%turn_-4%% Nagyon élesen balra %%turn_-3%% Élesen balra %%turn_-2%% Balra %%turn_-1%% Balra tarts %%turn_0%% Egyenesen %%turn_1%% Jobbra tarts %%turn_2%% Jobbra %%turn_3%% Élesen jobbra %%turn_4%% Nagyon élesen jobbra %%heading_-4%% dél %%heading_-3%% délnyugat %%heading_-2%% nyugat %%heading_-1%% északnyugat %%heading_0%% észak %%heading_1%% északkelet %%heading_2%% kelet %%heading_3%% délkelet %%heading_4%% dél %%ordinal_1%% elsÅ‘ %%ordinal_2%% második %%ordinal_3%% harmadik %%ordinal_4%% negyedik %%ordinal_5%% ötödik %%ordinal_6%% hatodik %%ordinal_7%% hetedik %%ordinal_8%% nyolcadik %%ordinal_9%% kilencedik %%ordinal_10%% tizedik %%highway_motorway%% autópálya %%highway_trunk%% autóút %%highway_primary%% főút %%highway_secondary%% összekötőút %%highway_tertiary%% bekötőút %%highway_unclassified%% egyéb közút %%highway_residential%% lakóút %%highway_service%% szervízút %%highway_track%% földút %%highway_cycleway%% kerékpárút %%highway_path%% ösvény %%highway_steps%% lépcsÅ‘ %%highway_ferry%% komp %%route_shortest%% Legrövidebb %%route_quickest%% Leggyorsabb %%output-html_waypoint_waypoint%% Útpont %%output-html_waypoint_junction%% KeresztezÅ‘dés %%output-html_waypoint_roundabout%% Körforgalom %%output-html_title%% %s útvonal %%output-html_start%% Indulás %s, %s felé %%output-html_node%% Itt %s, menj %s %s felé %%output-html_rbnode%% Kijárat %s, %s kijárat %s felé %%output-html_segment%% Erre %s, %.3f km, %.1f perc %%output-html_total%% Összesen %.1f km, %.0f perc %%output-html_subtotal%% %.1f km, %.0f perc %%output-gpx_waypoint_start%% Indulás %%output-gpx_waypoint_trip%% Utazás %%output-gpx_desc%% %s útvonal a kezdÅ‘ és utolsó pont között %%output-gpx_final%% Az egész út %.1f km, %.0f perc # # Router (and some shared) translations # @@LANGUAGE@@ Magyar @@LANGUAGE-WEBPAGE@@ Magyar weblap @@ROUTER-TITLE@@ Openstreetmap alapú útvonaltervezÅ‘ @@OPTION-TAB@@ Beállítások @@OPTION-TAB-HELP@@ ÚtvonaltervezÅ‘ beállítások @@RESULTS-TAB@@ Eredmény @@RESULTS-TAB-HELP@@ ÚtvonaltervezÅ‘ eredmények @@DATA-TAB@@ Adatok @@DATA-TAB-HELP@@ Adatbázis információk @@ROUTINO-ROUTER@@ Routino openstreetmap útvonaltervezÅ‘ @@ROUTINO-WEBSITE@@ Routino weboldal @@DOCUMENTATION@@ Dokumentáció @@LANGUAGE-BOX@@ Nyelv @@WAYPOINTS-BOX@@ Útpontok @@TRANSPORT-TYPE-BOX@@ Közlekedési mód @@HIGHWAY-PREFERENCES-BOX@@ Út preferencia @@SPEED-LIMITS-BOX@@ Sebességkorlát @@PROPERTY-PREFERENCES-BOX@@ Út tulajdonságok @@OTHER-RESTRICTIONS-BOX@@ Kizáró tényezÅ‘k @@LINKS-BOX@@ Linkek @@HELP-BOX@@ Súgó @@STATUS-BOX@@ Ãllapot @@SHORTEST-ROUTE@@ Legrövidebb út @@QUICKEST-ROUTE@@ Leggyorsabb út @@STATISTICS-BOX@@ Routino statisztika @@VISUALISER-BOX@@ Routino vizualizáció @@WAYPOINT-SEARCH@@ Hely keresése @@WAYPOINT-GET@@ Aktuális helyzet @@WAYPOINT-CENTRE1@@ Legyen ez a pont a térkép közepe @@WAYPOINT-UP@@ Mozgasd feljebb ezt a pontot @@WAYPOINT-ADD@@ Új pont ezután a pont után @@WAYPOINT-COORDS@@ Hely koordinátája @@WAYPOINT-CENTRE2@@ Ez legyen a térkép középpontja @@WAYPOINT-DOWN@@ Mozgasd ezt a pontot lejjebb @@WAYPOINT-REMOVE@@ Pont törlése @@WAYPOINT-REVERSE@@ Útirány megfordítása @@WAYPOINT-REVERSE-BUTTON@@ EllenkezÅ‘ irány @@WAYPOINT-LOOP@@ Új pont létrehozása a kezdÅ‘pontban @@WAYPOINT-LOOP-BUTTON@@ Kör bezárása @@TRANSPORT-FOOT@@ Gyalog @@TRANSPORT-HORSE@@ Lovas @@TRANSPORT-WHEELCHAIR@@ Kerekesszékes @@TRANSPORT-BICYCLE@@ Kerékpáros @@TRANSPORT-MOPED@@ Robogós @@TRANSPORT-MOTORCYCLE@@ Motoros @@TRANSPORT-MOTORCAR@@ Autós @@TRANSPORT-GOODS@@ Kisteherautós @@TRANSPORT-HGV@@ Kamionos @@TRANSPORT-PSV@@ Buszos @@HIGHWAY-MOTORWAY@@ Autópálya @@HIGHWAY-TRUNK@@ Autóút @@HIGHWAY-PRIMARY@@ Főút @@HIGHWAY-SECONDARY@@ Összekötőút @@HIGHWAY-TERTIARY@@ Bekötőút @@HIGHWAY-UNCLASSIFIED@@ Egyéb közút @@HIGHWAY-RESIDENTIAL@@ Lakóövezeti út @@HIGHWAY-SERVICE@@ Szervízút @@HIGHWAY-TRACK@@ Földút @@HIGHWAY-CYCLEWAY@@ Kerékpárút @@HIGHWAY-PATH@@ Ösvény @@HIGHWAY-STEPS@@ LépcsÅ‘ @@HIGHWAY-FERRY@@ Komp @@PROPERTY-PAVED@@ Burkolt @@PROPERTY-MULTILANE@@ Többsávos @@PROPERTY-BRIDGE@@ Híd @@PROPERTY-TUNNEL@@ Alagút @@PROPERTY-WALKINGROUTE@@ Gyalogút @@PROPERTY-BICYCLEROUTE@@ Kijelölt kerékpárút @@RESTRICT-ONEWAY@@ Egyirányúsítás mellÅ‘zése @@RESTRICT-TURNS@@ Kanyarodási tilalmak mellÅ‘zése @@RESTRICT-WEIGHT@@ Súly @@RESTRICT-HEIGHT@@ Magasság @@RESTRICT-WIDTH@@ Szélesség @@RESTRICT-LENGTH@@ Hosszúság @@FIND-SHORTEST-ROUTE@@ A legrövidebb út keresése @@FIND-QUICKEST-ROUTE@@ A leggyorsabb út keresése @@MAP-VIEW-LINK@@ Link erre a nézetre @@EDIT-OSM-DATA@@ OSM adatok szerkesztése @@ROUTER-NOT-RUN@@ Az útvonaltervezÅ‘ nem fut @@ROUTER-RUNNING@@ Az útvonaltervezÅ‘ számol ... @@ROUTER-COMPLETED@@ Az útvonaltervezés kész @@ROUTER-ERROR@@ Útvonaltervezési hiba @@ROUTER-FAILED@@ Az útvonaltervezÅ‘t nem sikerült futtatni @@VIEW-DETAILS@@ Részletek @@NO-INFORMATION@@ Nincs információ @@HTML-ROUTE@@ HTML irányok @@GPX-TRACK-ROUTE@@ GPX file @@FULL-TEXT-ROUTE@@ Teljes szöveges file @@TEXT-ROUTE@@ Szöveges file @@OPEN-POPUP@@ Új ablak @@DISPLAY-STATISTICS@@ Statisztika mutatása @@ROUTER@@ ÚtvonaltervezÅ‘ @@TILES@@ Térképszeletek # # Visualiser specific translations # @@VISUALISER-TITLE@@ ÚtvonaltervezÅ‘ adatok vizuálisan @@INSTRUCTIONS-BOX@@ Útmutatók @@ROUTER-BOX@@ Routino ÚtvonaltervezÅ‘ @@NO-DATA-DISPLAYED@@ Nincs megjelenítendÅ‘ adat @@VISUALISER-FAILED@@ Sikertelen az adatok betöltése @@VISUALISER-NUM-JUNCTIONS@@ Feldolgozva # keresztezÅ‘dés @@VISUALISER-NUM-SUPER@@ Feldolgozva # szuper-pont/szegmens @@VISUALISER-NUM-WAYTYPE@@ Feldolgozva # út típus szegmens @@VISUALISER-NUM-SEGMENTS@@ Feldolgozva # szegmens @@VISUALISER-NUM-NODES@@ Feldolgozva # pont @@VISUALISER-NUM-TURNS@@ Feldolgozva # kanyarodási korlátozás @@JUNCTIONS-BUTTON@@ KeresztezÅ‘dések mutatása @@JUNCTIONS-3@@ három út talákozása @@JUNCTIONS-4@@ négy út találkozása @@JUNCTIONS-5@@ öt út találkozása @@JUNCTIONS-6@@ hat út találkozása @@JUNCTIONS-MORE@@ hét, vagy több út találkozása @@SUPER-BUTTON@@ Szuper szegmens mutatása @@WAYTYPE-BUTTON@@ Út típus szakaszok megjelenítese @@WAYTYPE-ONEWAY@@ Egyirányú szakaszok @@WAYTYPE-ROUNDABOUT@@ Körforgalmi szakaszok @@HIGHWAY-BUTTON@@ Út szakaszok megjelenítése @@TURNS-BUTTON@@ Kanyarodási korlátozások @@SPEED-BUTTON@@ Sebességhatárok @@LIMIT-CHANGE@@ Korlátozás változása @@LIMIT-NONE@@ Nincs korlátozás @@SPEED-LIMIT-80@@ 80 km/óra sebességkorlátozás @@WEIGHT-BUTTON@@ Súlykorlátozások @@WEIGHT-LIMIT-8@@ 8 tonnás súlykorlátozás @@HEIGHT-BUTTON@@ Magasságkorlátozások @@HEIGHT-LIMIT-4@@ 4 méter magasságkorlátozás @@WIDTH-BUTTON@@ Szélességkorlátozások @@WIDTH-LIMIT-3@@ 3 méter szélességkorlátozás @@LENGTH-BUTTON@@ Hosszúságkorlátozások @@LENGTH-LIMIT-9@@ 9 méter hosszúságkorlátozás @@PROPERTY-BUTTON@@ Út tulajdonságok megjelenítése @@ERROR-LOG-BUTTON@@ Hiba logok megmutatása $$ERROR-LOG-INFO$$ Lehetséges hibák fordultak elÅ‘ az adatok feldolgozása során $$ERROR-LOG-INFO$$ @@CLEAR-DATA-BUTTON@@ Adatok törlése # # Multi-line descriptive translations (router) # # # Multi-line descriptive translations (visualiser) # routino-3.0/web/translations/router.html 644 233 144 74222 12525660415 13764 0 Routino : @@ROUTER-TITLE@@
@@OPTION-TAB@@ @@RESULTS-TAB@@ @@DATA-TAB@@
@@ROUTINO-ROUTER@@ $$ROUTER-INFO$$
+ - @@LANGUAGE-BOX@@
+ - @@WAYPOINTS-BOX@@
+ - @@TRANSPORT-TYPE-BOX@@
@@TRANSPORT-FOOT@@:
@@TRANSPORT-HORSE@@:
@@TRANSPORT-WHEELCHAIR@@:
@@TRANSPORT-BICYCLE@@:
@@TRANSPORT-MOPED@@:
@@TRANSPORT-MOTORCYCLE@@:
@@TRANSPORT-MOTORCAR@@:
@@TRANSPORT-GOODS@@:
@@TRANSPORT-HGV@@:
@@TRANSPORT-PSV@@:
+ - @@HIGHWAY-PREFERENCES-BOX@@
+ - @@SPEED-LIMITS-BOX@@
+ - @@PROPERTY-PREFERENCES-BOX@@
+ - @@OTHER-RESTRICTIONS-BOX@@
@@FIND-BOX@@
+ - @@HELP-BOX@@
$$ROUTER-OPTIONS-HELP$$
@@ROUTER@@: Routino | @@GEO-DATA@@: | @@TILES@@:
routino-3.0/web/translations/translations-body.xml 644 233 144 11765 12572577331 15765 0 <!-- %s = [shortest|quickest] --> <start text="%%output-html_start%%" /> <!-- 1st %s = [waypoint|junction], 2nd %s = [heading] --> <node text="%%output-html_node%%" /> <!-- 1st %s = [waypoint|junction], 2nd %s = [turn], 3rd %s = [heading] --> <rbnode text="%%output-html_rbnode%%" /> <!-- 1st %s = [roundabout], 2nd %s = [first|second|...], 3rd %s = [heading] --> <segment text="%%output-html_segment%%" /> <!-- 1st %s = street name --> <stop text="%%output-html_stop%%" /> <!-- 1st %s = [waypoint|junction] --> <total text="%%output-html_total%%" /> <subtotal text="%%output-html_subtotal%%" /> </output-html> <!-- GPX output --> <output-gpx> <waypoint type="start" string="%%output-gpx_waypoint_start%%" /> <!-- For the first route waypoint --> <waypoint type="inter" string="%%output-gpx_waypoint_inter%%" /> <!-- For the intermediate route waypoints --> <waypoint type="trip" string="%%output-gpx_waypoint_trip%%" /> <!-- For the other route points --> <waypoint type="finish" string="%%output-gpx_waypoint_finish%%"/> <!-- For the last route waypoint --> <desc text="%%output-gpx_desc%%" /> <!-- %s = [shortest|quickest] --> <name text="%%output-gpx_name%%" /> <!-- %s = [shortest|quickest] --> <step text="%%output-gpx_step%%" /> <!-- 1st %s = [turn], 2nd %s = street name --> <final text="%%output-gpx_final%%" /> </output-gpx> </language> �����������routino-3.0/web/translations/translations-head.xml�������������������������������������������������� 644 � 233 � 144 � 1527 12572574760 15707� 0�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="utf-8"?> <!-- ============================================================ An XML format file containing Routino output translations. Part of the Routino routing software. ============================================================ This file Copyright 2010-2015 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. ============================================================ --> <routino-translations xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.routino.org/xml/routino-translations.xsd"> �������������������������������������������������������������������������������������������������������������������������������������������������������������������������routino-3.0/web/translations/translation.en.txt����������������������������������������������������� 644 � 233 � 144 � 34257 12572577273 15275� 0�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # English language translation phrases # # # Router output XML definition # %%copyright_creator_string%% Creator %%copyright_source_string%% Source %%copyright_source_text%% Based on OpenStreetMap data from http://www.openstreetmap.org/ %%copyright_license_string%% License %%turn_-4%% Very sharp left %%turn_-3%% Sharp left %%turn_-2%% Left %%turn_-1%% Slight left %%turn_0%% Straight on %%turn_1%% Slight right %%turn_2%% Right %%turn_3%% Sharp right %%turn_4%% Very sharp right %%heading_-4%% South %%heading_-3%% South-West %%heading_-2%% West %%heading_-1%% North-West %%heading_0%% North %%heading_1%% North-East %%heading_2%% East %%heading_3%% South-East %%heading_4%% South %%ordinal_1%% First %%ordinal_2%% Second %%ordinal_3%% Third %%ordinal_4%% Fourth %%ordinal_5%% Fifth %%ordinal_6%% Sixth %%ordinal_7%% Seventh %%ordinal_8%% Eighth %%ordinal_9%% Ninth %%ordinal_10%% Tenth %%highway_motorway%% motorway %%highway_trunk%% trunk road %%highway_primary%% primary road %%highway_secondary%% secondary road %%highway_tertiary%% tertiary road %%highway_unclassified%% unclassified road %%highway_residential%% residential road %%highway_service%% service road %%highway_track%% track %%highway_cycleway%% cycleway %%highway_path%% path %%highway_steps%% steps %%highway_ferry%% ferry %%route_shortest%% Shortest %%route_quickest%% Quickest %%output-html_waypoint_waypoint%% Waypoint %%output-html_waypoint_junction%% Junction %%output-html_waypoint_roundabout%% Roundabout %%output-html_title%% %s Route %%output-html_start%% Start at %s, head %s %%output-html_node%% At %s, go %s heading %s %%output-html_rbnode%% Leave %s, take the %s exit heading %s %%output-html_segment%% Follow %s for %.3f km, %.1f min %%output-html_stop%% Stop at %s %%output-html_total%% Total %.1f km, %.0f minutes %%output-html_subtotal%% %.1f km, %.0f minutes %%output-gpx_waypoint_start%% START %%output-gpx_waypoint_inter%% INTER %%output-gpx_waypoint_trip%% TRIP %%output-gpx_waypoint_finish%% FINISH %%output-gpx_desc%% %s route between 'start' and 'finish' waypoints %%output-gpx_name%% %s route %%output-gpx_step%% %s on '%s' for %.3f km, %.1f min %%output-gpx_final%% Total Journey %.1f km, %.0f minutes # # Router (and some shared) translations # @@LANGUAGE@@ English @@LANGUAGE-WEBPAGE@@ English language webpage @@ROUTER-TITLE@@ Route Planner for OpenStreetMap Data @@OPTION-TAB@@ Options @@OPTION-TAB-HELP@@ Set routing options @@RESULTS-TAB@@ Results @@RESULTS-TAB-HELP@@ See routing results @@DATA-TAB@@ Data @@DATA-TAB-HELP@@ View database information @@ROUTINO-ROUTER@@ Routino OpenStreetMap Router @@ROUTINO-WEBSITE@@ Routino Website @@DOCUMENTATION@@ Documentation @@LANGUAGE-BOX@@ Language @@WAYPOINTS-BOX@@ Waypoints @@TRANSPORT-TYPE-BOX@@ Transport Type @@HIGHWAY-PREFERENCES-BOX@@ Highway Preferences @@SPEED-LIMITS-BOX@@ Speed Limits @@PROPERTY-PREFERENCES-BOX@@ Property Preferences @@OTHER-RESTRICTIONS-BOX@@ Other Restrictions @@FIND-BOX@@ Find @@LINKS-BOX@@ Links @@HELP-BOX@@ Help @@STATUS-BOX@@ Status @@SHORTEST-ROUTE@@ Shortest Route @@QUICKEST-ROUTE@@ Quickest Route @@STATISTICS-BOX@@ Routino Statistics @@VISUALISER-BOX@@ Routino Visualiser @@WAYPOINT-POSITION@@ Waypoint XXX Position @@WAYPOINT-LONGITUDE@@ Waypoint XXX Longitude @@WAYPOINT-LATITUDE@@ Waypoint XXX Latitude @@WAYPOINT-LOCATION@@ Waypoint XXX Location @@WAYPOINT-SEARCH@@ Search for location @@WAYPOINT-GET@@ Get current location @@WAYPOINT-CENTRE1@@ Centre map on this waypoint @@WAYPOINT-UP@@ Move this waypoint up @@WAYPOINT-ADD@@ Add waypoint after this one @@WAYPOINT-COORDS@@ Coordinates for location @@WAYPOINT-HOME@@ Toggle as home location @@WAYPOINT-CENTRE2@@ Centre this waypoint on map @@WAYPOINT-DOWN@@ Move this waypoint down @@WAYPOINT-REMOVE@@ Remove this waypoint @@WAYPOINT-REVERSE@@ Reverse order of waypoints @@WAYPOINT-REVERSE-BUTTON@@ Reverse order @@WAYPOINT-LOOP@@ Add a new waypoint to make a loop @@WAYPOINT-LOOP-BUTTON@@ Close loop @@TRANSPORT-FOOT@@ Foot @@TRANSPORT-HORSE@@ Horse @@TRANSPORT-WHEELCHAIR@@ Wheelchair @@TRANSPORT-BICYCLE@@ Bicycle @@TRANSPORT-MOPED@@ Moped @@TRANSPORT-MOTORCYCLE@@ Motorcycle @@TRANSPORT-MOTORCAR@@ Motorcar @@TRANSPORT-GOODS@@ Goods @@TRANSPORT-HGV@@ HGV @@TRANSPORT-PSV@@ PSV @@HIGHWAY-MOTORWAY@@ Motorway @@HIGHWAY-TRUNK@@ Trunk @@HIGHWAY-PRIMARY@@ Primary @@HIGHWAY-SECONDARY@@ Secondary @@HIGHWAY-TERTIARY@@ Tertiary @@HIGHWAY-UNCLASSIFIED@@ Unclassified @@HIGHWAY-RESIDENTIAL@@ Residential @@HIGHWAY-SERVICE@@ Service @@HIGHWAY-TRACK@@ Track @@HIGHWAY-CYCLEWAY@@ Cycleway @@HIGHWAY-PATH@@ Path @@HIGHWAY-STEPS@@ Steps @@HIGHWAY-FERRY@@ Ferry @@PROPERTY-PAVED@@ Paved @@PROPERTY-MULTILANE@@ Multiple Lanes @@PROPERTY-BRIDGE@@ Bridge @@PROPERTY-TUNNEL@@ Tunnel @@PROPERTY-WALKINGROUTE@@ Walking Route @@PROPERTY-BICYCLEROUTE@@ Bicycle Route @@RESTRICT-ONEWAY@@ Obey oneway streets @@RESTRICT-TURNS@@ Obey turn restrictions @@RESTRICT-WEIGHT@@ Weight @@RESTRICT-HEIGHT@@ Height @@RESTRICT-WIDTH@@ Width @@RESTRICT-LENGTH@@ Length @@FIND-SHORTEST-ROUTE@@ Find shortest route @@FIND-QUICKEST-ROUTE@@ Find quickest route @@MAP-VIEW-LINK@@ Link to this map view @@EDIT-OSM-DATA@@ Edit this OSM data @@ROUTER-NOT-RUN@@ Router not run @@ROUTER-RUNNING@@ Router running... @@ROUTER-COMPLETED@@ Routing completed @@ROUTER-ERROR@@ Router error @@ROUTER-FAILED@@ Router failed to run @@VIEW-DETAILS@@ View Details @@NO-INFORMATION@@ No Information @@HTML-ROUTE@@ HTML directions @@GPX-TRACK-ROUTE@@ GPX track file @@GPX-ROUTE@@ GPX route file @@FULL-TEXT-ROUTE@@ Full text file @@TEXT-ROUTE@@ Text file @@OPEN-POPUP@@ Open Popup @@DISPLAY-STATISTICS@@ Display data statistics @@JAVASCRIPT-REQUIRED@@ Javascript is <em>required</em> to use this web page because of the interactive map. @@ROUTER@@ Router @@GEO-DATA@@ Geo Data @@TILES@@ Tiles # # Visualiser specific translations # @@VISUALISER-TITLE@@ Data Visualiser for Routing Data @@INSTRUCTIONS-BOX@@ Instructions @@ROUTER-BOX@@ Routino Router @@NO-DATA-DISPLAYED@@ No data displayed @@VISUALISER-FAILED@@ Failed to get visualiser data! @@VISUALISER-NUM-JUNCTIONS@@ Processed # junctions @@VISUALISER-NUM-SUPER@@ Processed # super-nodes/segments @@VISUALISER-NUM-WAYTYPE@@ Processed # way type segments @@VISUALISER-NUM-SEGMENTS@@ Processed # segments @@VISUALISER-NUM-NODES@@ Processed # nodes @@VISUALISER-NUM-TURNS@@ Processed # turn restrictions @@VISUALISER-NUM-LIMITS@@ Processed # limit changes @@VISUALISER-NUM-ERRORS@@ Processed # error logs @@JUNCTIONS-BUTTON@@ Display Junctions $$JUNCTIONS-INFO$$ Each node that is a dead-end, a junction of two highways of different types (or different properties) or a junction where more than two segments join are shown colour-coded. $$JUNCTIONS-INFO$$ @@JUNCTIONS-1@@ only one highway - a dead-end. @@JUNCTIONS-2@@ two highways of different types meet. @@JUNCTIONS-3@@ three highways meet. @@JUNCTIONS-4@@ four highways meet. @@JUNCTIONS-5@@ five highways meet. @@JUNCTIONS-6@@ six highways meet. @@JUNCTIONS-MORE@@ seven (or more) highways meet. @@SUPER-BUTTON@@ Display Super Segments $$SUPER-INFO$$ Each super-node and the associated super-segments are shown (see algorithm page for description). $$SUPER-INFO$$ @@WAYTYPE-BUTTON@@ Display Way Type Segments $$WAYTYPE-INFO$$ Each highway segment of special types (one-way, cycle-both-ways and roundabout) are shown. For one-way segments a coloured triangle indicates the allowed direction. The colours of the triangles depend on the bearing of the highway segment. $$WAYTYPE-INFO$$ @@WAYTYPE-ONEWAY@@ One-way segments @@WAYTYPE-CYCLE-BOTH-WAYS@@ Cycle-both-way segments @@WAYTYPE-ROUNDABOUT@@ Roundabout segments @@HIGHWAY-BUTTON@@ Display Highway Segments $$HIGHWAY-INFO$$ Each segment of the chosen type of highway is drawn. $$HIGHWAY-INFO$$ @@TRANSPORT-BUTTON@@ Display Transport Segments $$TRANSPORT-INFO$$ Each segment allowed for the chosen type of transport is drawn. $$TRANSPORT-INFO$$ @@BARRIER-BUTTON@@ Display Barrier Nodes $$BARRIER-INFO$$ Each barrier blocking the chosen type of transport is drawn. $$BARRIER-INFO$$ @@TURNS-BUTTON@@ Display Turn Restrictions $$TURNS-INFO$$ Each turn restrictions is shown with a line indicating the disallowed turn. $$TURNS-INFO$$ @@SPEED-BUTTON@@ Display Speed Limits $$SPEED-INFO$$ Each node that joins segments with different speed limits is shown along with the speed limit on relevant segments. $$SPEED-INFO$$ @@LIMIT-CHANGE@@ Change of limit @@LIMIT-NONE@@ No specified limit @@SPEED-LIMIT-80@@ 80 km/hour speed limit @@WEIGHT-BUTTON@@ Display Weight Limits $$WEIGHT-INFO$$ Each node that joins segments with different weight limits is shown along with the weight limit on relevant segments. $$WEIGHT-INFO$$ @@WEIGHT-LIMIT-8@@ 8.0 tonnes weight limit @@HEIGHT-BUTTON@@ Display Height Limits $$HEIGHT-INFO$$ Each node that joins segments with different height limits is shown along with the height limit on relevant segments. $$HEIGHT-INFO$$ @@HEIGHT-LIMIT-4@@ 4.0 m height limit @@WIDTH-BUTTON@@ Display Width Limits $$WIDTH-INFO$$ Each node that joins segments with different width limits is shown along with the width limit on relevant segments. $$WIDTH-INFO$$ @@WIDTH-LIMIT-3@@ 3.0 m width limit @@LENGTH-BUTTON@@ Display Length Limits $$LENGTH-INFO$$ Each node that joins segments with different length limits is shown along with the length limit on relevant segments. $$LENGTH-INFO$$ @@LENGTH-LIMIT-9@@ 9.0 m length limit @@PROPERTY-BUTTON@@ Display Highway Properties $$PROPERTY-INFO$$ Each segment of the highways with a particular property is drawn. $$PROPERTY-INFO$$ @@ERROR-LOG-BUTTON@@ Display Error Logs $$ERROR-LOG-INFO$$ Potential problems found by Routino when processing the input data. $$ERROR-LOG-INFO$$ @@CLEAR-DATA-BUTTON@@ Clear data # # Multi-line descriptive translations (router) # $$ROUTER-INFO$$ This web page allows routing within the data collected by OpenStreetMap. Select start and end points (click on the marker icons below), select routing preferences then find a route. $$ROUTER-INFO$$ $$ROUTER-OPTIONS-HELP$$ <b>Quick Start</b> <br> Click on marker icons (above) to place them on the map (right). Then drag them to the correct position. Zooming the map before placing the markers is probably easiest. Alternatively type the latitude and longitude into the boxes above. <p> Select the transport type, allowed highway types, speed limits, highway properties and other restrictions from the options above. Select "Shortest" or "Quickest" to calculate the route and display it on the map. <p> <b>Waypoints</b> <br> Clicking on the marker icons will toggle the display of them on the map. When a route is calculated it will visit (as close as possible for the selected transport type) each of the waypoints that have markers on the map in the order given. <p> <b>Transport Type</b> <br> Selecting a transport type will restrict the chosen route to those on which it is allowed and set default values for the other parameters. <p> <b>Highway Preferences</b> <br> The highway preference is selected as a percentage and routes are chosen that try to follow the preferred highways. For example if a "Primary" road is given a "110%" preference and a "Secondary" road is given a "100%" preference then it means that a route on a Primary road can be up to 10% longer than on a secondary road and still be selected. <p> <b>Speed Limits</b> <br> The speed limits chosen here for the different types of highway apply if the highway has no other speed limit marked or it is higher than the chosen one. <p> <b>Property Preferences</b> <br> The property preference is selected as a percentage and routes are chosen that try to follow highways with the preferred property. For example if a "Paved" highway is given a "75%" preference then it means that an unpaved highway is automatically given a "25%" preference so that a route on a paved highway can be 3 times the length of an unpaved one and still be selected. <p> <b>Other Restrictions</b> <br> These allow a route to be found that avoids marked limits on weight, height, width or length. It is also possible to ignore one-way restrictions (e.g. if walking). $$ROUTER-OPTIONS-HELP$$ $$ROUTER-RESULTS-HELP$$ <b>Quick Start</b> <br> After calculating a route you can download the GPX file or plain text route description (summary or detailed version). Also you can view the route description and zoom in to selected parts. <p> <b>Problem Solving</b> <br> If the router completes with an error then the most likely cause is that it is not possible to find a route between the selected points. Moving one or more markers or changing the routing options should allow a route to be found. <p> <b>Output Formats</b> <br> <dl> <dt>HTML instructions <dd>A description of the route to take with directions at each important junction. <dt>GPX track file <dd>The same information that is displayed on the map with points for every node and lines for every segment. <dt>GPX route file <dd>The same information that is displayed in text for the route with a waypoint for each important junction in the route. <dt>Full text file <dd>A list of all of the nodes visited as well as the distance between them and the cumulative distance for each step of the route. <dt>Text file <dd>The same information that is displayed in text for the route. </dl> $$ROUTER-RESULTS-HELP$$ $$ROUTER-VISUALISER-INFO$$ To see Routino's view of the data there is a data visualiser that allows displaying of the underlying data in various ways. $$ROUTER-VISUALISER-INFO$$ # # Multi-line descriptive translations (visualiser) # $$VISUALISER-INFO$$ This web page allows visualisation of the data that Routino uses for routing. Only data relevant for routing is displayed and some will therefore be excluded. $$VISUALISER-INFO$$ $$VISUALISER-INSTRUCTIONS$$ Zoom in and then use the buttons below to download the data. The server will only return data if the selected area is small enough. $$VISUALISER-INSTRUCTIONS$$ $$VISUALISER-HELP$$ <b>Quick Start</b> <br> Zoom to an area and select one of the buttons to display that type of data. <br> More data options can be found by expanding the details below each button. <p> <b>Data Failure</b> <br> If the area selected is too large (depends on the data type) then the status will say "Failed to get visualiser data" - zoom in and try again. $$VISUALISER-HELP$$ $$VISUALISER-ROUTER-INFO$$ To perform routing on the map use the link below. $$VISUALISER-ROUTER-INFO$$ �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������routino-3.0/web/translations/translate.pl����������������������������������������������������������� 755 � 233 � 144 � 25623 12564147067 14122� 0�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/perl # # Routino translation replacement Perl script # # Part of the Routino routing software. # # This file Copyright 2014-2015 Andrew M. Bishop # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. # use strict; # Constants my @translation_files=(<translation.*.txt>); my $xml_output_file="../../xml/routino-translations.xml"; my $html_output_dir="../www/routino"; my @html_template_files=(<*.html>); my %languages=(); my %translations=(); # Sort so that English is first @translation_files=sort {if($a eq "translation.en.txt"){return -1;} if($b eq "translation.en.txt"){return 1;} return $a <=> $b;} @translation_files; # Read in the translations foreach my $translation_file (@translation_files) { $translation_file =~ m%translation.([^.]+).txt%; # Add to list of languages my $language=$1; if(! defined $languages{$language}) { $languages{$language}=1; $translations{$language}={}; $translations{$language}->{codes}={}; $translations{$language}->{html}=0; $translations{$language}->{xml}=0; } # Process the file open(FILE,"<$translation_file"); while(<FILE>) { s%\r*\n%%; next if(m%^#%); next if(m%^$%); # Single line HTML entries if(m%\@\@%) { my($code,$text)=split("\t"); if(defined $translations{$language}->{codes}->{$code}) { print STDERR "Language: $language DUPLICATED codeword '$code'\n"; } else { $translations{$language}->{html}++; $translations{$language}->{codes}->{$code}={}; $translations{$language}->{codes}->{$code}->{text}=$text; $translations{$language}->{codes}->{$code}->{usedX}=0; $translations{$language}->{codes}->{$code}->{usedR}=0; $translations{$language}->{codes}->{$code}->{usedV}=0; } } # Multi-line HTML entries if(m%(\$\$[^\$]+\$\$)%) { my($code,$text)=($1,""); while(<FILE>) { last if(m%\$\$%); $text=$text.$_; } $text =~ s%\r*\n$%%; if(defined $translations{$language}->{codes}->{$code}) { print STDERR "Language: $language DUPLICATED codeword '$code'\n"; } else { $translations{$language}->{html}++; $translations{$language}->{codes}->{$code}={}; $translations{$language}->{codes}->{$code}->{text}=$text; $translations{$language}->{codes}->{$code}->{usedX}=0; $translations{$language}->{codes}->{$code}->{usedR}=0; $translations{$language}->{codes}->{$code}->{usedV}=0; } } # Single line XML entries if(m%\%\%%) { my($code,$text)=split("\t"); if(defined $translations{$language}->{codes}->{$code}) { print STDERR "Language: $language DUPLICATED codeword '$code'\n"; } else { $translations{$language}->{xml}++; $translations{$language}->{codes}->{$code}={}; $translations{$language}->{codes}->{$code}->{text}=$text; $translations{$language}->{codes}->{$code}->{usedX}=0; $translations{$language}->{codes}->{$code}->{usedR}=0; $translations{$language}->{codes}->{$code}->{usedV}=0; } my($n_strings_en)=$translations{en}->{codes}->{$code}->{text} =~ s/%s/%s/g; my($n_strings) =$text =~ s/%s/%s/g; if($n_strings != $n_strings_en) { print STDERR "Language: $language WRONG number of '%s' in text '$text' ($translations{en}->{codes}->{$code}->{text})\n"; } } } close(FILE); } # Sort out the languages my @languages=(); push(@languages,"en"); foreach my $language (sort (keys %languages)) { push(@languages,$language) if($language ne "en"); } # Create the HTML files foreach my $html_template_file (@html_template_files) { my $usedtype=""; $usedtype="R" if($html_template_file =~ m%router%); $usedtype="V" if($html_template_file =~ m%visualiser%); foreach my $language (@languages) { next if(!$translations{$language}->{html}); print "Language: $language File: $html_template_file\n"; my $language_meta=0; my $language_meta_string=""; open(HTML_IN ,"<$html_template_file"); open(HTML_OUT,">$html_output_dir/$html_template_file.$language"); while(<HTML_IN>) { my $line=$_; # Language selection - special handling if($line =~ m%\*\*LANGUAGES-META\*\*%) { $language_meta=1-$language_meta; if($language_meta==0) { foreach my $language2 (@languages) { my $LANGUAGE2=$language2; $LANGUAGE2 =~ tr%a-z%A-Z%; $line=$language_meta_string; if($language eq $language2) { $line =~ s%~~CHECKED~~%checked%g; } else { $line =~ s%~~CHECKED~~%%g; } $line =~ s%~~lang~~%$language2%g; $line =~ s%~~LANG~~%$LANGUAGE2%g; if(!$translations{$language2}->{html}) { $line =~ s%<a.+</a>%%; } if(!$translations{$language2}->{xml}) { $line =~ s%<input .+>%%; } foreach my $code (keys %{$translations{$language2}->{codes}}) { if($line =~ s%$code%$translations{$language2}->{codes}->{$code}->{text}%g) {$translations{$language2}->{codes}->{$code}->{"used$usedtype"} = 1;} } if($line =~ m%((\@\@|\$\$|\*\*|\~\~)[^\@\$*~]+(\@\@|\$\$|\*\*|\~\~))%) { print STDERR " Unmatched codeword '$1' in line: $line"; } # Remove un-needed spaces $line =~ s%[\t ]+% %g; $line =~ s%\n %\n%g; $line =~ s%^ %%g; print HTML_OUT $line; } } next; } if($language_meta) { $language_meta_string.=$line; next; } # Replace with translated phrases foreach my $code (keys %{$translations{$language}->{codes}}) { if($line =~ s%\Q$code\E%$translations{$language}->{codes}->{$code}->{text}%g) {$translations{$language}->{codes}->{$code}->{"used$usedtype"} = 1;} } # Replace what is left with English phrases foreach my $code (keys %{$translations{$languages[0]}->{codes}}) { $line =~ s%\Q$code\E%$translations{$languages[0]}->{codes}->{$code}->{text}%g; } if($line =~ m%((\@\@|\$\$|\*\*|\~\~)[^\@\$*~]+(\@\@|\$\$|\*\*|\~\~))%) { print STDERR " Unmatched codeword '$1' in line: $line"; } # Remove un-needed spaces $line =~ s%[\t ]+% %g; $line =~ s%\n %\n%g; $line =~ s%^ %%g; print HTML_OUT $line; } close(HTML_IN); close(HTML_OUT); } } # Create the XML file open(XML_OUT,">$xml_output_file"); open(XML_IN ,"<translations-head.xml"); while(<XML_IN>) { print XML_OUT; } close(XML_IN); foreach my $language (@languages) { next if(!$translations{$language}->{xml}); print "Language: $language File: translations.xml\n"; open(XML_IN ,"<translations-body.xml"); while(<XML_IN>) { my $line=$_; $line =~ s%~~lang~~%$language%g; $line =~ s%~~language~~%$translations{$language}->{codes}->{'@@LANGUAGE@@'}->{text}%g; # Replace with translated phrases foreach my $code (keys %{$translations{$language}->{codes}}) { if($line =~ s%$code%$translations{$language}->{codes}->{$code}->{text}%g) {$translations{$language}->{codes}->{$code}->{usedX} = 1;} } # Replace what is left with a note about missing translations if($line =~ m%\%\%%) { foreach my $code (keys %{$translations{$languages[0]}->{codes}}) { $line =~ s%$code%$translations{$languages[0]}->{codes}->{$code}->{text}%g; } $line =~ s%<%<!-- TRANSLATION REQUIRED: %; $line =~ s%>% -->%; if($line =~ m%((\%\%|\~\~)[^\%~]+(\%\%|\~\~))%) { print STDERR " Unmatched codeword '$1' in line: $line"; } } print XML_OUT $line; } close(XML_IN); } open(XML_IN ,"<translations-tail.xml"); while(<XML_IN>) { print XML_OUT; } close(XML_IN); close(XML_OUT); # Check the languages and usage my %usedX=(); my %usedR=(); my %usedV=(); foreach my $language (@languages) { $usedX{$language}=0; $usedR{$language}=0; $usedV{$language}=0; foreach my $code (keys %{$translations{$language}->{codes}}) { $usedX{$language}+=$translations{$language}->{codes}->{$code}->{usedX}; $usedR{$language}+=$translations{$language}->{codes}->{$code}->{usedR}; $usedV{$language}+=$translations{$language}->{codes}->{$code}->{usedV}; if(! $translations{$language}->{codes}->{$code}->{usedX} && ! $translations{$language}->{codes}->{$code}->{usedR} && ! $translations{$language}->{codes}->{$code}->{usedV}) { print STDERR "Language: $language UNUSED codeword: $code\n"; } } } # Print the translation coverage print "\n"; print "Translation Coverage\n"; print "====================\n"; print "\n"; print " Number Percentage Complete\n"; print "Language XML HTML XML router visualiser\n"; print "-------- --- ---- --- ------ ----------\n"; foreach my $language (@languages) { printf("%-6s %3d %3d %4.0f%% %4.0f%% %4.0f%%\n", $language, $translations{$language}->{xml}, $translations{$language}->{html}, 100.0*$usedX{$language}/$usedX{$languages[0]}, 100.0*$usedR{$language}/$usedR{$languages[0]}, 100.0*$usedV{$language}/$usedV{$languages[0]}) } �������������������������������������������������������������������������������������������������������������routino-3.0/web/translations/translations-tail.xml�������������������������������������������������� 644 � 233 � 144 � 30 12314102416 15636� 0�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������</routino-translations> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������routino-3.0/web/translations/translation.pl.txt����������������������������������������������������� 644 � 233 � 144 � 13347 12572577316 15301� 0�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # Polish language translation phrases # # # Router output XML definition # %%copyright_creator_string%% Twórca %%copyright_source_string%% Źródło %%copyright_source_text%% Oparte na danych OpenStreetMap ze strony http://www.openstreetmap.org/ %%copyright_license_string%% Licencja %%turn_-4%% Bardzo ostro w lewo %%turn_-3%% Ostro w lewo %%turn_-2%% W lewo %%turn_-1%% Lekko w lewo %%turn_0%% Prosto %%turn_1%% Lekko w prawo %%turn_2%% W prawo %%turn_3%% Ostro w prawo %%turn_4%% Bardzo ostro w prawo %%heading_-4%% Na południe %%heading_-3%% Na południowy zachód %%heading_-2%% Na zachód %%heading_-1%% Na północny zachód %%heading_0%% Na północ %%heading_1%% Na północny wschód %%heading_2%% Na wschód %%heading_3%% Na południowy wschód %%heading_4%% Na południe %%ordinal_1%% Pierwszy %%ordinal_2%% Drugi %%ordinal_3%% Trzeci %%ordinal_4%% Czwarty %%ordinal_5%% Piąty %%ordinal_6%% Szósty %%ordinal_7%% Siódmy %%ordinal_8%% Ósmy %%ordinal_9%% Dziewiąty %%ordinal_10%% Dziesiąty %%highway_motorway%% Autostrada %%highway_trunk%% Droga ekspresowa %%highway_primary%% Droga krajowa %%highway_secondary%% Droga powiatowa %%highway_tertiary%% Droga lokalna %%highway_unclassified%% Droga nieznanego typu %%highway_residential%% Droga osiedlowa %%highway_service%% Droga dojazdowa %%highway_track%% Droga polna %%highway_cycleway%% Droga rowerowa %%highway_path%% Ścieżka %%highway_steps%% Pieszo %%highway_ferry%% Prom %%route_shortest%% Najkrótsza %%route_quickest%% Najszybsza %%output-html_waypoint_waypoint%% Punkt %%output-html_waypoint_roundabout%% Rondo %%output-html_title%% %s Trasa %%output-html_start%% Start %s kieruj się na %s %%output-html_segment%% Podążaj %s przez %.3f km, %.1f min. %%output-html_stop%% Stop Na %s %%output-html_total%% Całkowity %.1f km, %.0f min. %%output-html_subtotal%% %.1f km, %.0f min. %%output-gpx_waypoint_start%% START %%output-gpx_waypoint_inter%% INTER %%output-gpx_waypoint_trip%% TRIP %%output-gpx_waypoint_finish%% KONIEC %%output-gpx_desc%% %s trasa pomiędzy 'start' a 'koniec' %%output-gpx_name%% %s trasa %%output-gpx_step%% %s na %s przez %.3f km, %.1f min. %%output-gpx_final%% Całkowita podróż %.1f km, %.0f min. # # Router (and some shared) translations # @@LANGUAGE@@ Polski @@LANGUAGE-WEBPAGE@@ Polski webpage @@ROUTER-TITLE@@ Planowanie trasy dla Danych OpenStreetMap @@OPTION-TAB@@ Opcje @@OPTION-TAB-HELP@@ Ustaw punkty trasy @@RESULTS-TAB@@ Wyniki @@RESULTS-TAB-HELP@@ Zobacz wyniki @@DATA-TAB@@ Dane @@DATA-TAB-HELP@@ Zobacz informacje bazy danych @@ROUTINO-ROUTER@@ Routino OpenStreetMap Planowanie Trasy @@ROUTINO-WEBSITE@@ Strona Routino @@DOCUMENTATION@@ Dokumentacja @@LANGUAGE-BOX@@ Język @@WAYPOINTS-BOX@@ Punkty @@TRANSPORT-TYPE-BOX@@ Typ transportu @@HIGHWAY-PREFERENCES-BOX@@ Preferowanie autostrad @@SPEED-LIMITS-BOX@@ Ograniczenia prędkości @@OTHER-RESTRICTIONS-BOX@@ Inne ograniczenia @@FIND-BOX@@ Znajdź @@LINKS-BOX@@ Połączenia @@HELP-BOX@@ Pomoc @@STATUS-BOX@@ Status @@SHORTEST-ROUTE@@ Najkrótsza trasa @@QUICKEST-ROUTE@@ Najszybsza trasa @@STATISTICS-BOX@@ Statystyki Routino @@VISUALISER-BOX@@ Wizualizer Routino @@WAYPOINT-SEARCH@@ Znajdź miejsce @@WAYPOINT-GET@@ Pobierz aktualna lokalizację @@WAYPOINT-CENTRE1@@ Wycentruj mapę na tym punkcie @@WAYPOINT-HOME@@ Współrzędne lokalizacji @@TRANSPORT-FOOT@@ Pieszo @@TRANSPORT-HORSE@@ Konno @@TRANSPORT-WHEELCHAIR@@ Wózek inwalidzki @@TRANSPORT-BICYCLE@@ Rower @@TRANSPORT-MOPED@@ Moped @@TRANSPORT-MOTORCYCLE@@ Motocykl @@TRANSPORT-MOTORCAR@@ Samochód @@TRANSPORT-PSV@@ Pojazd użyteczności publicznej @@HIGHWAY-MOTORWAY@@ Autostrada @@HIGHWAY-PRIMARY@@ Droga krajowa @@HIGHWAY-SECONDARY@@ Droga wojewódzka @@HIGHWAY-TERTIARY@@ Droga powiatowa @@HIGHWAY-UNCLASSIFIED@@ Niesklasyfikowana @@HIGHWAY-RESIDENTIAL@@ W obszarze zamieszkania @@HIGHWAY-SERVICE@@ Dojazdowa @@HIGHWAY-CYCLEWAY@@ Rowerowa @@HIGHWAY-PATH@@ Ścieżka @@HIGHWAY-FERRY@@ Przeprawa @@PROPERTY-MULTILANE@@ Wiele pasów @@PROPERTY-BRIDGE@@ Most @@PROPERTY-TUNNEL@@ Tunel @@PROPERTY-WALKINGROUTE@@ Trasa piesza @@PROPERTY-BICYCLEROUTE@@ Trasa rowerowa @@RESTRICT-ONEWAY@@ Respektuj ulice jednokierunkowe @@RESTRICT-TURNS@@ Respektuj ograniczenia skrętu @@RESTRICT-WEIGHT@@ Waga @@RESTRICT-HEIGHT@@ Wysokość @@RESTRICT-WIDTH@@ Szerokość @@RESTRICT-LENGTH@@ Długość @@FIND-SHORTEST-ROUTE@@ Znajdź najkrótsza trasę @@FIND-QUICKEST-ROUTE@@ Znajdź najdłuższą trasę @@ROUTER-NOT-RUN@@ Nie uruchomiono wyznaczania trasy @@ROUTER-RUNNING@@ Wyznaczanie trasy w trakcie... @@ROUTER-COMPLETED@@ Trasa wyznaczona @@ROUTER-ERROR@@ Błąd wyznaczania trasy @@ROUTER-FAILED@@ Błąd uruchomienia wyznaczania trasy @@VIEW-DETAILS@@ Zobacz szczegóły @@NO-INFORMATION@@ Brak informacji @@GPX-TRACK-ROUTE@@ Plik trasy w formacie GPX @@GPX-ROUTE@@ Plik nawigacji w formacie GPX @@TEXT-ROUTE@@ Plik tekstowy @@TILES@@ Kafelki # # Visualiser specific translations # @@INSTRUCTIONS-BOX@@ Instrukcje @@NO-DATA-DISPLAYED@@ Brak danych do wyświetlenia @@TURNS-BUTTON@@ Wyświetlaj zakazy skrętu @@SPEED-BUTTON@@ Wyświetlaj ograniczenia prędkości @@SPEED-LIMIT-80@@ Ograniczenie prędkości do 80 km/h @@WEIGHT-BUTTON@@ Wyświetlaj ograniczenia ciężaru @@WEIGHT-LIMIT-8@@ Ograniczenie ciężaru do 8.0 ton @@HEIGHT-BUTTON@@ Wyświetlaj ograniczenia wysokości @@HEIGHT-LIMIT-4@@ Ograniczenie wysokości do 4.0 m @@WIDTH-BUTTON@@ Wyświetlaj ograniczenia szerokości @@WIDTH-LIMIT-3@@ Ograniczenie szerokości do 3.0 m @@LENGTH-BUTTON@@ Wyświetlaj ograniczenia długości @@LENGTH-LIMIT-9@@ Ograniczenie długości do 9.0 m @@CLEAR-DATA-BUTTON@@ Wyczyść # # Multi-line descriptive translations (router) # # # Multi-line descriptive translations (visualiser) # $$VISUALISER-ROUTER-INFO$$ Aby wyznaczyć trasę na mapie użyj linku poniżej $$VISUALISER-ROUTER-INFO$$ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������routino-3.0/web/translations/visualiser.html�������������������������������������������������������� 644 � 233 � 144 � 53565 12327763504 14644� 0�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta name="keywords" content="openstreetmap routino verifier"> <meta name="viewport" content="width=device-width, height=device-height, initial-scale=1, user-scalable=no"> <title>Routino : @@VISUALISER-TITLE@@
Visualiser Router Data
@@VISUALISER-BOX@@ $$VISUALISER-INFO$$
+ - @@LANGUAGE-BOX@@
@@INSTRUCTIONS-BOX@@ $$VISUALISER-INSTRUCTIONS$$
@@STATUS-BOX@@
@@NO-DATA-DISPLAYED@@
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ - @@HELP-BOX@@
$$VISUALISER-HELP$$
@@ROUTER@@: Routino | @@GEO-DATA@@: | @@TILES@@:
routino-3.0/web/bin/ 40755 233 144 0 12575036711 7543 5routino-3.0/web/INSTALL.txt 777 233 144 0 12031126065 13407 2../doc/INSTALL.txtroutino-3.0/web/results/ 40755 233 144 0 12216114770 10466 5routino-3.0/web/data/ 40755 233 144 0 12575036711 7704 5routino-3.0/web/data/create.sh 755 233 144 637 12302124007 11470 0#!/bin/sh -x # This script can download from the GeoFabrik server. # EDIT THIS to set the names of the files to download from GeoFabrik. files="europe/great-britain-latest.osm.bz2 europe/ireland-and-northern-ireland-latest.osm.bz2" server="download.geofabrik.de" # Download the files for file in $files; do wget -N http://$server/$file done # Process the data ../bin/planetsplitter --errorlog *.osm.bz2 routino-3.0/web/Makefile 644 233 144 14575 12563633053 10502 0# web directory Makefile # # Part of the Routino routing software. # # This file Copyright 2010-2015 Andrew M. Bishop # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # # All configuration is in the top-level Makefile.conf include ../Makefile.conf # Web file paths and other paths WEBBINDIR=bin WEBDATADIR=data WEBTRANSDIR=translations WEBWWWDIR=www/routino WEBICONDIR=www/routino/icons WEBDOCDIR=www/routino/documentation XMLDIR=../xml DOCDIR=../doc SRCDIR=../src # Files to install STANDARD_XML_FILES=profiles.xml \ translations.xml \ tagging.xml SPECIAL_XML_FILES=tagging-drive.xml \ tagging-ride.xml \ tagging-walk.xml PROFILE_FILES=profiles.pl \ profiles.js TRANS_FILES=$(wildcard $(WEBTRANSDIR)/translation.*.txt) DOC_FILES=$(notdir $(wildcard $(DOCDIR)/html/*.html)) $(notdir $(wildcard $(DOCDIR)/html/*.css)) EXE_FILES=planetsplitter$(.EXE) planetsplitter-slim$(.EXE) router$(.EXE) router-slim$(.EXE) filedumperx$(.EXE) filedumper$(.EXE) filedumper-slim$(.EXE) ######## all: all-bin all-data all-doc all-profiles all-translations all-icons #### all-bin: all-exe @[ -d $(WEBBINDIR) ] || mkdir -p $(WEBBINDIR) @for file in $(EXE_FILES); do \ if [ -f $(SRCDIR)/$$file -a ! -f $(WEBBINDIR)/$$file ] || [ $(SRCDIR)/$$file -nt $(WEBBINDIR)/$$file ]; then \ echo cp $(SRCDIR)/$$file $(WEBBINDIR) ;\ cp -f $(SRCDIR)/$$file $(WEBBINDIR) ;\ fi ;\ done #### all-data: all-xml @[ -d $(WEBDATADIR) ] || mkdir -p $(WEBDATADIR) @for file in $(STANDARD_XML_FILES); do \ if [ ! -f $(WEBDATADIR)/$$file ] || [ $(XMLDIR)/routino-$$file -nt $(WEBDATADIR)/$$file ]; then \ echo cp $(XMLDIR)/routino-$$file $(WEBDATADIR)/$$file ;\ cp -f $(XMLDIR)/routino-$$file $(WEBDATADIR)/$$file ;\ fi ;\ done @for file in $(SPECIAL_XML_FILES); do \ if [ ! -f $(WEBDATADIR)/$$file ] || [ $(XMLDIR)/$$file -nt $(WEBDATADIR)/$$file ]; then \ echo cp $(XMLDIR)/$$file $(WEBDATADIR)/$$file ;\ cp -f $(XMLDIR)/$$file $(WEBDATADIR)/$$file ;\ fi ;\ done #### all-doc: @[ -d $(WEBDOCDIR) ] || mkdir -p $(WEBDOCDIR) @for file in $(DOC_FILES); do \ if [ ! -f $(WEBDOCDIR)/$$file ] || [ $(DOCDIR)/html/$$file -nt $(WEBDOCDIR)/$$file ]; then \ echo cp $(DOCDIR)/html/$$file $(WEBDOCDIR) ;\ cp -f $(DOCDIR)/html/$$file $(WEBDOCDIR) ;\ fi ;\ done #### all-profiles: all-exe all-data @if [ ! -f $(WEBWWWDIR)/profiles.js ] || [ ! -f $(WEBWWWDIR)/profiles.pl ] || \ [ $(WEBDATADIR)/profiles.xml -nt $(WEBWWWDIR)/profiles.pl ] || \ [ $(WEBDATADIR)/profiles.xml -nt $(WEBWWWDIR)/profiles.js ]; then \ echo update-profiles.pl ;\ ( cd $(WEBWWWDIR) ; perl update-profiles.pl ) ;\ fi #### all-translations: $(WEBWWWDIR)/router.html $(WEBWWWDIR)/visualiser.html \ $(WEBWWWDIR)/router.html.en $(WEBWWWDIR)/visualiser.html.en \ $(XMLDIR)/routino-translations.xml ifeq ($(HOST),MINGW) $(WEBWWWDIR)/router.html: $(WEBWWWDIR)/router.html.en @echo cp $< $@ @cp -f $< $@ $(WEBWWWDIR)/visualiser.html: $(WEBWWWDIR)/visualiser.html.en @echo cp $< $@ @cp -f $< $@ else $(WEBWWWDIR)/router.html: $(WEBWWWDIR)/router.html.en @echo ln -s `basename $<` $@ @ln -s -f `basename $<` $@ $(WEBWWWDIR)/visualiser.html: $(WEBWWWDIR)/visualiser.html.en @echo ln -s `basename $<` $@ @ln -s -f `basename $<` $@ endif $(WEBWWWDIR)/router.html.en: $(WEBTRANSDIR)/router.html $(TRANS_FILES) $(WEBTRANSDIR)/translate.pl @echo translate.pl @cd $(WEBTRANSDIR) && perl translate.pl $(WEBWWWDIR)/visualiser.html.en: $(WEBTRANSDIR)/visualiser.html $(TRANS_FILES) $(WEBTRANSDIR)/translate.pl @echo translate.pl @cd $(WEBTRANSDIR) && perl translate.pl $(XMLDIR)/routino-translations.xml: $(WEBTRANSDIR)/translations-head.xml $(WEBTRANSDIR)/translations-body.xml $(WEBTRANSDIR)/translations-tail.xml $(TRANS_FILES) $(WEBTRANSDIR)/translate.pl @echo translate.pl @cd $(WEBTRANSDIR) && perl translate.pl #### all-icons: $(WEBICONDIR)/ball-0.png $(WEBICONDIR)/ball-0.png: $(WEBICONDIR)/create-icons.pl @echo create-icons.pl @cd $(WEBICONDIR) && perl create-icons.pl #### all-exe: cd $(SRCDIR) && $(MAKE) $(EXE_FILES) #### all-xml: $(XMLDIR)/routino-translations.xml cd $(XMLDIR) && $(MAKE) all ######## test: ######## install: all @echo "******************************************************" @echo "* Note: web directory is not installed automatically *" @echo "******************************************************" ######## clean: clean clean-all-bin clean-all-data clean-all-doc clean-all-profiles clean-all-translations clean-all-icons rm -f *~ clean-all-bin: -cd $(WEBBINDIR) && rm -f $(EXE_FILES) clean-all-data: -cd $(WEBDATADIR) && rm -f $(STANDARD_XML_FILES) -cd $(WEBDATADIR) && rm -f $(SPECIAL_XML_FILES) clean-all-doc: -cd $(WEBDOCDIR) && rm -f $(DOC_FILES) clean-all-profiles: clean-all-translations: clean-all-icons: ######## distclean: distclean-all-bin distclean-all-data distclean-all-doc distclean-all-profiles distclean-all-translations distclean-all-icons distclean-all-bin: clean-all-bin distclean-all-data: clean-all-data distclean-all-doc: clean-all-doc distclean-all-profiles: clean-all-profiles -cd $(WEBWWWDIR) && rm -f $(PROFILE_FILES) distclean-all-translations: clean-all-translations -cd $(WEBWWWDIR) && rm -f router.html* -cd $(WEBWWWDIR) && rm -f visualiser.html* distclean-all-icons: clean-all-icons -cd $(WEBICONDIR) && rm -f ball-*.png limit-*.png marker-*.png ######## .PHONY:: all test install clean distclean .PHONY:: all-bin all-data all-doc all-profiles all-icons all-translations all-exe all-xml .PHONY:: clean-all-bin clean-all-data clean-all-doc clean-all-profiles clean-all-translations clean-all-icons .PHONY:: distclean-all-bin distclean-all-data distclean-all-doc distclean-all-profiles distclean-all-translations distclean-all-icons routino-3.0/web/www/ 40755 233 144 0 12304345636 7616 5routino-3.0/web/www/leaflet/ 40755 233 144 0 12525706122 11226 5routino-3.0/web/www/leaflet/install.sh 755 233 144 245 12525706122 13230 0#!/bin/sh -x version=0.7.3 # Download the file. wget http://leaflet-cdn.s3.amazonaws.com/build/leaflet-$version.zip # Uncompress it. unzip leaflet-$version.zip routino-3.0/web/www/openlayers/ 40755 233 144 0 12304345516 11774 5routino-3.0/web/www/openlayers/install.sh 755 233 144 740 12304344522 13772 0#!/bin/sh -x version=2.13.1 # Download the file. wget http://openlayers.org/download/OpenLayers-$version.tar.gz # Uncompress it. tar -xzf OpenLayers-$version.tar.gz # Create a custom OpenLayers file (cd OpenLayers-$version/build && python build.py ../../routino.cfg && cp OpenLayers.js ..) # Copy the files. cp -p OpenLayers-$version/OpenLayers.js . cp -pr OpenLayers-$version/img . cp -pr OpenLayers-$version/theme . # Delete the remainder rm -rf OpenLayers-$version routino-3.0/web/www/openlayers/routino.cfg 644 233 144 2230 12260565540 14167 0# This is a configuration file to allow building an optimised OpenLayers # Javascript file that contains all of the features required for Routino. [first] OpenLayers/SingleFile.js OpenLayers.js OpenLayers/BaseTypes.js OpenLayers/BaseTypes/Class.js OpenLayers/Util.js [last] [include] OpenLayers/BaseTypes/LonLat.js OpenLayers/BaseTypes/Bounds.js OpenLayers/Control/DragFeature.js OpenLayers/Control/LayerSwitcher.js OpenLayers/Control/Navigation.js OpenLayers/Control/PanZoomBar.js OpenLayers/Control/PinchZoom.js OpenLayers/Control/SelectFeature.js OpenLayers/Control/ScaleLine.js OpenLayers/Feature/Vector.js OpenLayers/Format/GPX.js OpenLayers/Geometry/LineString.js OpenLayers/Geometry/Point.js OpenLayers/Geometry/Polygon.js OpenLayers/Layer/Boxes.js OpenLayers/Layer/SphericalMercator.js OpenLayers/Layer/TMS.js OpenLayers/Layer/Vector.js OpenLayers/Map.js OpenLayers/Marker/Box.js OpenLayers/Projection.js OpenLayers/Protocol/HTTP.js OpenLayers/Renderer/Elements.js OpenLayers/Renderer/Canvas.js OpenLayers/Renderer/SVG.js OpenLayers/Renderer/VML.js OpenLayers/Request/XMLHttpRequest.js OpenLayers/Strategy/Fixed.js OpenLayers/Rule.js OpenLayers/Style.js [exclude] routino-3.0/web/www/routino/ 40755 233 144 0 12575037323 11316 5routino-3.0/web/www/routino/maploader.js 644 233 144 2421 12273230550 13623 0//////////////////////////////////////////////////////////////////////////////// ///////////////////// Map loader (OpenLayers or Leaflet) /////////////////////// //////////////////////////////////////////////////////////////////////////////// function map_load(callbacks) { var pending=1; var head = document.getElementsByTagName("head")[0]; /* Call the callbacks when everything is loaded. */ function call_callbacks() { if(!--pending) eval(callbacks); } /* Javascript loader */ function load_js(url) { var script = document.createElement("script"); script.src = url; script.type = "text/javascript"; script.onload = call_callbacks; pending++; head.appendChild(script); } /* CSS loader */ function load_css(url) { var link = document.createElement("link"); link.href = url; link.type = "text/css"; link.rel = "stylesheet"; head.appendChild(link); } /* Load the external library and local code */ if(mapprops.library == "leaflet") { load_css("../leaflet/leaflet.css"); load_js("../leaflet/leaflet.js"); load_js(location.pathname.replace(/\.html.*/,".leaflet.js")); } else { load_js("../openlayers/OpenLayers.js"); load_js(location.pathname.replace(/\.html.*/,".openlayers.js")); } call_callbacks(); } routino-3.0/web/www/routino/page-elements.css 644 233 144 4616 12261523234 14572 0/* // Style sheet for page elements. // // Part of the Routino routing software. // // This file Copyright 2008-2014 Andrew M. Bishop // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . */ /*-------------*/ /* Tabbed DIVs */ /*-------------*/ DIV.tab_box { padding: 3px; margin-top: 3px; width: 100%; } DIV.tab_box SPAN.tab_selected { border-top: 2px solid; border-left: 2px solid; border-right: 2px solid; border-bottom: 1px solid white; z-index: 5; padding-top: 3px; padding-bottom: 3px; padding-right: 5px; padding-left: 5px; font-weight: bold; font-variant: small-caps; background: #FFF; } DIV.tab_box SPAN.tab_unselected { border-top: 1px solid; border-left: 1px solid; border-right: 1px solid; padding-top: 3px; padding-bottom: 3px; padding-right: 5px; padding-left: 5px; cursor: pointer; font-variant: small-caps; background: #CCC; } DIV.tab_box SPAN.tab_unselected:hover { background: #DDD; } DIV.tab_content { width: auto; padding: 3px; border: thin solid; } /*----------------*/ /* Show/Hide DIVs */ /*----------------*/ DIV.hideshow_box { min-height: 1em; border-top: 2px solid; border-color: #AAA; padding-bottom: 2px; overflow: hidden; } DIV.hideshow_box:first-child { border-top: none; } DIV.hideshow_box SPAN.hideshow_show { float: right; display: block; font-weight: bold; text-align: center; width: 1em; padding-right: 5px; padding-left: 5px; padding-top: 1px; padding-bottom: 1px; cursor: pointer; background: #CCC; } DIV.hideshow_box SPAN.hideshow_show:hover { background: #DDD; } DIV.hideshow_box SPAN.hideshow_hide { display: none; } SPAN.hideshow_title { display: block; font-weight: bold; text-decoration: underline; padding-top: 1px; padding-bottom: 1px; background: #EEE; } routino-3.0/web/www/routino/router.html.de 644 233 144 75225 12573351567 14171 0 Routino : Routen Planer für OpenStreetMap Daten
Optionen Ergebnisse Daten
Routino OpenStreetMap Router Diese Website erlaubt Routing mit den Daten, die OpenStreetMap gesammelt hat. Wähle Start- und Endpunkt (klicke auf die Marker-Symbole unten), wähle die Routing-Vorgaben und dann finde den Weg.
+ - Wegpunkte
+ - Fortbewegungsart
Fußgänger:
Reiter:
Rollstuhl:
Fahrrad:
Moped:
Motorrad:
Auto:
LKW:
Schwertransport/LKW:
Öffentlicher Personenverkehr:
+ - Vorgaben zur Wegnutzung
+ - Geschwindigkeitsvorgaben
+ - Vorgaben zur Wegbeschaffenheit
+ - andere Vorgaben
Suche
+ - Hilfe
Schnellanleitung
Klicke auf die Marker-Bildchen (oben), um sie in der Mitte der Karte (rechts) zu positionieren. Dann ziehe das Bildchen auf die genaue Position. Das Zoomen der Karte vor der Patzierung ist vermutlich am einfachsten. Alternativ kann man die geografische Breite und Länge in den Kästchen eintragen.

Wähle die Fortbewegungsart, die Vorgaben zur Wegnutzung, die Geschwindigkeitsvorgaben, die Vorgaben zur Wegbeschaffenheit und die anderen Vorgaben von den obigen Auswahlfeldern. Ein Klick auf "kürzeste" oder "schnellste" ermittelt die entsprechende Verbindung und zeigt sie in der Karte an.

Wegpunkte
Ein Klick auf das Marker-Bildchen (oben) schaltet die Sichbarkeit in der Karte ein bzw. aus. Die Berechnung Route erfolgt in der Reihenfolge der Wegpunkte (so gut, wie es für die gewählte Fortbewegungsart möglich ist).

Fortbewegungsart
Die Auswahl der Fortbewegungsart bestimmt die bei der Routenberechnung erlaubten Wegtypen und die Vorgabeeinstellungen aller anderen Parameter.

Vorgaben zur Wegnutzung
Die Vorgaben zur Wegnutzung bestimmen die Priorisierung von Wegarten. Wenn z. B. Schnellstraßen mit 110% und Bundesstraßen mit 100% angegeben werden, wird bei zwei möglichen Wegwahlen die Schnellstraße solange bevorzugt wird, wie der Längen(oder Zeit-)unterschied 10% nicht überschreitet.

Geschwindigkeitsvorgaben
Die hier geannten Geschwindigkeiten werden für den jeweiligen Wegtyp finden Anwendung wenn keine andere Geschwindkeitsbegrenzung mit geringerem Wert bekannt ist.

Vorgaben zur Wegbeschaffenheit
Die Vorgaben zur Wegbeschaffenheit werden als Prozentangaben verwendet, um die Verhältnisse der Wegbenutzung zu steuern. Wenn z. B. befestigte Wege mit 75% angegeben sind, werden unbefestigte automatisch mit 25% angenommen, so werden Wege ausgewählt, die mindestens drei mal länger auf befestigten Wegen verlaufen.

andere Vorgaben
Die Berücksichtigung von Benutzungs-Begrenzungen durch Gewicht, Höhe, Länge und Breite ist möglich. Genauso können Einbahnstraßenbeschräkungen ignoriert werden (z. B. als Fußgänger).

Router: Routino | Geodaten: | Kacheln:
routino-3.0/web/www/routino/statistics.cgi 755 233 144 2261 12306670414 14210 0#!/usr/bin/perl # # Routino data statistics # # Part of the Routino routing software. # # This file Copyright 2008-2014 Andrew M. Bishop # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # use strict; # Use the directory paths script require "paths.pl"; # Use the perl CGI module use CGI ':cgi'; # Print the output print header('text/plain'); # Run the filedumper my $params=""; $params.=" --dir=$main::data_dir" if($main::data_dir); $params.=" --prefix=$main::data_prefix" if($main::data_prefix); $params.=" --statistics"; system "$main::bin_dir/$main::filedumper_exe $params 2>&1"; routino-3.0/web/www/routino/router.html.en 644 233 144 74522 12573351567 14202 0 Routino : Route Planner for OpenStreetMap Data
Options Results Data
Routino OpenStreetMap Router This web page allows routing within the data collected by OpenStreetMap. Select start and end points (click on the marker icons below), select routing preferences then find a route.
+ - Waypoints
+ - Transport Type
Foot:
Horse:
Wheelchair:
Bicycle:
Moped:
Motorcycle:
Motorcar:
Goods:
HGV:
PSV:
+ - Highway Preferences
+ - Speed Limits
+ - Property Preferences
+ - Other Restrictions
Find
+ - Help
Quick Start
Click on marker icons (above) to place them on the map (right). Then drag them to the correct position. Zooming the map before placing the markers is probably easiest. Alternatively type the latitude and longitude into the boxes above.

Select the transport type, allowed highway types, speed limits, highway properties and other restrictions from the options above. Select "Shortest" or "Quickest" to calculate the route and display it on the map.

Waypoints
Clicking on the marker icons will toggle the display of them on the map. When a route is calculated it will visit (as close as possible for the selected transport type) each of the waypoints that have markers on the map in the order given.

Transport Type
Selecting a transport type will restrict the chosen route to those on which it is allowed and set default values for the other parameters.

Highway Preferences
The highway preference is selected as a percentage and routes are chosen that try to follow the preferred highways. For example if a "Primary" road is given a "110%" preference and a "Secondary" road is given a "100%" preference then it means that a route on a Primary road can be up to 10% longer than on a secondary road and still be selected.

Speed Limits
The speed limits chosen here for the different types of highway apply if the highway has no other speed limit marked or it is higher than the chosen one.

Property Preferences
The property preference is selected as a percentage and routes are chosen that try to follow highways with the preferred property. For example if a "Paved" highway is given a "75%" preference then it means that an unpaved highway is automatically given a "25%" preference so that a route on a paved highway can be 3 times the length of an unpaved one and still be selected.

Other Restrictions
These allow a route to be found that avoids marked limits on weight, height, width or length. It is also possible to ignore one-way restrictions (e.g. if walking).

Router: Routino | Geo Data: | Tiles:
routino-3.0/web/www/routino/visualiser.cgi 755 233 144 7733 12327764564 14232 0#!/usr/bin/perl # # Routino data visualiser CGI # # Part of the Routino routing software. # # This file Copyright 2008-2014 Andrew M. Bishop # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # use strict; # Use the directory paths script require "paths.pl"; # Use the perl CGI module use CGI ':cgi'; # Create the query and get the parameters my $query=new CGI; my @rawparams=$query->param; # Legal CGI parameters with regexp validity check my %legalparams=( "latmin" => "[-0-9.]+", "latmax" => "[-0-9.]+", "lonmin" => "[-0-9.]+", "lonmax" => "[-0-9.]+", "data" => "(junctions|super|waytype-.*|highway-.*|transport-.*|barrier-.*|turns|speed|weight|height|width|length|property-.*|errorlogs)", "dump" => "(node|segment|turn-relation|errorlog)[0-9]+" ); # Validate the CGI parameters, ignore invalid ones my %cgiparams=(); foreach my $key (@rawparams) { foreach my $test (keys (%legalparams)) { if($key =~ m%^$test$%) { my $value=$query->param($key); if($value =~ m%^$legalparams{$test}$%) { $cgiparams{$key}=$value; last; } } } } # Data or dump? my $params=""; my $data=$cgiparams{"data"}; my $dump=$cgiparams{"dump"}; if(!defined $data && !defined $dump) { print header(-status => '500 Invalid CGI parameters'); exit; } if(defined $data) { # Parameters to limit range selected my %limits=( "junctions" => 0.2, "super" => 0.2, "waytype" => 0.2, "highway" => 0.2, "transport" => 0.2, "barrier" => 0.3, "turns" => 0.3, "speed" => 0.3, "weight" => 0.3, "height" => 0.3, "width" => 0.3, "length" => 0.3, "property" => 0.3, "errorlogs" => 0.5 ); # Check the parameters my $latmin=$cgiparams{"latmin"}; my $latmax=$cgiparams{"latmax"}; my $lonmin=$cgiparams{"lonmin"}; my $lonmax=$cgiparams{"lonmax"}; if($latmin eq "" || $latmax eq "" || $lonmin eq "" || $lonmax eq "" || $data eq "") { print header(-status => '500 Invalid CGI parameters'); exit; } my $subdata=$data; $subdata="waytype" if($data =~ m%waytype-%); $subdata="highway" if($data =~ m%highway-%); $subdata="transport" if($data =~ m%transport-%); $subdata="barrier" if($data =~ m%barrier-%); $subdata="property" if($data =~ m%property-%); if(($latmax-$latmin)>$limits{$subdata} || ($lonmax-$lonmin)>$limits{$subdata}) { print header(-status => '500 Selected area too large'); exit; } # Print the output print header('text/plain'); print "$latmin $lonmin $latmax $lonmax\n"; # Set the parameters $params.=" --visualiser --data=$data"; $params.=" --latmin=$latmin --latmax=$latmax --lonmin=$lonmin --lonmax=$lonmax"; } else { # Print the output print header('text/plain'); # Set the parameters $params.=" --dump-visualiser --data=$dump"; } # Run the filedumper $params.=" --dir=$main::data_dir" if($main::data_dir); $params.=" --prefix=$main::data_prefix" if($main::data_prefix); system "$main::bin_dir/$main::filedumper_exe $params 2>&1"; routino-3.0/web/www/routino/router.html.ru 644 233 144 75405 12573351572 14223 0 Routino : Route Planner for OpenStreetMap Data
Options Results Data
Routino OpenStreetMap Router This web page allows routing within the data collected by OpenStreetMap. Select start and end points (click on the marker icons below), select routing preferences then find a route.
+ - Язык
+ - Waypoints
+ - Тип транÑпорта
Foot:
Лошадь:
Инвалидное креÑло:
ВелоÑипед:
Мопед:
Мотоцикл:
Motorcar:
Товары:
HGV:
PSV:
+ - Highway Preferences
+ - ÐžÐ³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ ÑкороÑти
+ - Property Preferences
+ - Другие ограничениÑ
Find
+ - Помощь
Quick Start
Click on marker icons (above) to place them on the map (right). Then drag them to the correct position. Zooming the map before placing the markers is probably easiest. Alternatively type the latitude and longitude into the boxes above.

Select the transport type, allowed highway types, speed limits, highway properties and other restrictions from the options above. Select "Shortest" or "Quickest" to calculate the route and display it on the map.

Waypoints
Clicking on the marker icons will toggle the display of them on the map. When a route is calculated it will visit (as close as possible for the selected transport type) each of the waypoints that have markers on the map in the order given.

Transport Type
Selecting a transport type will restrict the chosen route to those on which it is allowed and set default values for the other parameters.

Highway Preferences
The highway preference is selected as a percentage and routes are chosen that try to follow the preferred highways. For example if a "Primary" road is given a "110%" preference and a "Secondary" road is given a "100%" preference then it means that a route on a Primary road can be up to 10% longer than on a secondary road and still be selected.

Speed Limits
The speed limits chosen here for the different types of highway apply if the highway has no other speed limit marked or it is higher than the chosen one.

Property Preferences
The property preference is selected as a percentage and routes are chosen that try to follow highways with the preferred property. For example if a "Paved" highway is given a "75%" preference then it means that an unpaved highway is automatically given a "25%" preference so that a route on a paved highway can be 3 times the length of an unpaved one and still be selected.

Other Restrictions
These allow a route to be found that avoids marked limits on weight, height, width or length. It is also possible to ignore one-way restrictions (e.g. if walking).

Router: Routino | Geo Data: | Тайлы:
routino-3.0/web/www/routino/visualiser.html.fr 644 233 144 52204 12573351574 15044 0 Routino : Data Visualiser for Routing Data
Visualiser Router Data
Routino Visualiser This web page allows visualisation of the data that Routino uses for routing. Only data relevant for routing is displayed and some will therefore be excluded.
Instructions Zoom in and then use the buttons below to download the data. The server will only return data if the selected area is small enough.
Status
No data displayed
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ - Aide
Quick Start
Zoom to an area and select one of the buttons to display that type of data.
More data options can be found by expanding the details below each button.

Data Failure
If the area selected is too large (depends on the data type) then the status will say "Failed to get visualiser data" - zoom in and try again.

Routeur: Routino | Geo Data: | Tuiles:
routino-3.0/web/www/routino/index.html 644 233 144 3240 12520735533 13324 0 Routino : Route Planner for OpenStreetMap Data

Routino : Route Planner for OpenStreetMap Data

routino-3.0/web/www/routino/profiles.pl 644 233 144 20051 12573351566 13536 0################################################################################ ########################### Routino default profile ############################ ################################################################################ $routino={ # contains all default Routino options (generated using "--help-profile-perl"). # Default transport type transport => "motorcar", # Transport types transports => { foot => 1, horse => 2, wheelchair => 3, bicycle => 4, moped => 5, motorcycle => 6, motorcar => 7, goods => 8, hgv => 9, psv => 10 }, # Highway types highways => { motorway => 1, trunk => 2, primary => 3, secondary => 4, tertiary => 5, unclassified => 6, residential => 7, service => 8, track => 9, cycleway => 10, path => 11, steps => 12, ferry => 13 }, # Property types properties => { paved => 1, multilane => 2, bridge => 3, tunnel => 4, footroute => 5, bicycleroute => 6 }, # Restriction types restrictions => { oneway => 1, turns => 2, weight => 3, height => 4, width => 5, length => 6 }, # Allowed highways profile_highway => { motorway => { foot => 0, horse => 0, wheelchair => 0, bicycle => 0, moped => 0, motorcycle => 100, motorcar => 100, goods => 100, hgv => 100, psv => 100 }, trunk => { foot => 40, horse => 25, wheelchair => 40, bicycle => 30, moped => 90, motorcycle => 100, motorcar => 100, goods => 100, hgv => 100, psv => 100 }, primary => { foot => 50, horse => 50, wheelchair => 50, bicycle => 70, moped => 100, motorcycle => 90, motorcar => 90, goods => 90, hgv => 90, psv => 90 }, secondary => { foot => 60, horse => 50, wheelchair => 60, bicycle => 80, moped => 90, motorcycle => 80, motorcar => 80, goods => 80, hgv => 80, psv => 80 }, tertiary => { foot => 70, horse => 75, wheelchair => 70, bicycle => 90, moped => 80, motorcycle => 70, motorcar => 70, goods => 70, hgv => 70, psv => 70 }, unclassified => { foot => 80, horse => 75, wheelchair => 80, bicycle => 90, moped => 70, motorcycle => 60, motorcar => 60, goods => 60, hgv => 60, psv => 60 }, residential => { foot => 90, horse => 75, wheelchair => 90, bicycle => 90, moped => 60, motorcycle => 50, motorcar => 50, goods => 50, hgv => 50, psv => 50 }, service => { foot => 90, horse => 75, wheelchair => 90, bicycle => 90, moped => 80, motorcycle => 80, motorcar => 80, goods => 80, hgv => 80, psv => 80 }, track => { foot => 95, horse => 100, wheelchair => 95, bicycle => 90, moped => 0, motorcycle => 0, motorcar => 0, goods => 0, hgv => 0, psv => 0 }, cycleway => { foot => 95, horse => 90, wheelchair => 95, bicycle => 100, moped => 0, motorcycle => 0, motorcar => 0, goods => 0, hgv => 0, psv => 0 }, path => { foot => 100, horse => 100, wheelchair => 100, bicycle => 90, moped => 0, motorcycle => 0, motorcar => 0, goods => 0, hgv => 0, psv => 0 }, steps => { foot => 80, horse => 0, wheelchair => 0, bicycle => 0, moped => 0, motorcycle => 0, motorcar => 0, goods => 0, hgv => 0, psv => 0 }, ferry => { foot => 20, horse => 20, wheelchair => 20, bicycle => 20, moped => 20, motorcycle => 20, motorcar => 20, goods => 20, hgv => 20, psv => 20 } }, # Speed limits profile_speed => { motorway => { foot => 0, horse => 0, wheelchair => 0, bicycle => 0, moped => 48, motorcycle => 112, motorcar => 112, goods => 96, hgv => 89, psv => 89 }, trunk => { foot => 4, horse => 8, wheelchair => 4, bicycle => 20, moped => 48, motorcycle => 96, motorcar => 96, goods => 96, hgv => 80, psv => 80 }, primary => { foot => 4, horse => 8, wheelchair => 4, bicycle => 20, moped => 48, motorcycle => 96, motorcar => 96, goods => 96, hgv => 80, psv => 80 }, secondary => { foot => 4, horse => 8, wheelchair => 4, bicycle => 20, moped => 48, motorcycle => 88, motorcar => 88, goods => 88, hgv => 80, psv => 80 }, tertiary => { foot => 4, horse => 8, wheelchair => 4, bicycle => 20, moped => 48, motorcycle => 80, motorcar => 80, goods => 80, hgv => 80, psv => 80 }, unclassified => { foot => 4, horse => 8, wheelchair => 4, bicycle => 20, moped => 48, motorcycle => 64, motorcar => 64, goods => 64, hgv => 64, psv => 64 }, residential => { foot => 4, horse => 8, wheelchair => 4, bicycle => 20, moped => 48, motorcycle => 48, motorcar => 48, goods => 48, hgv => 48, psv => 48 }, service => { foot => 4, horse => 8, wheelchair => 4, bicycle => 20, moped => 32, motorcycle => 32, motorcar => 32, goods => 32, hgv => 32, psv => 32 }, track => { foot => 4, horse => 8, wheelchair => 4, bicycle => 20, moped => 16, motorcycle => 16, motorcar => 16, goods => 16, hgv => 16, psv => 16 }, cycleway => { foot => 4, horse => 8, wheelchair => 4, bicycle => 20, moped => 0, motorcycle => 0, motorcar => 0, goods => 0, hgv => 0, psv => 0 }, path => { foot => 4, horse => 8, wheelchair => 4, bicycle => 20, moped => 0, motorcycle => 0, motorcar => 0, goods => 0, hgv => 0, psv => 0 }, steps => { foot => 4, horse => 0, wheelchair => 4, bicycle => 0, moped => 0, motorcycle => 0, motorcar => 0, goods => 0, hgv => 0, psv => 0 }, ferry => { foot => 10, horse => 10, wheelchair => 10, bicycle => 10, moped => 10, motorcycle => 10, motorcar => 10, goods => 10, hgv => 10, psv => 10 } }, # Highway properties profile_property => { paved => { foot => 50, horse => 20, wheelchair => 90, bicycle => 50, moped => 100, motorcycle => 100, motorcar => 100, goods => 100, hgv => 100, psv => 100 }, multilane => { foot => 25, horse => 25, wheelchair => 25, bicycle => 25, moped => 35, motorcycle => 60, motorcar => 60, goods => 60, hgv => 60, psv => 60 }, bridge => { foot => 50, horse => 50, wheelchair => 50, bicycle => 50, moped => 50, motorcycle => 50, motorcar => 50, goods => 50, hgv => 50, psv => 50 }, tunnel => { foot => 50, horse => 50, wheelchair => 50, bicycle => 50, moped => 50, motorcycle => 50, motorcar => 50, goods => 50, hgv => 50, psv => 50 }, footroute => { foot => 55, horse => 50, wheelchair => 55, bicycle => 50, moped => 50, motorcycle => 50, motorcar => 45, goods => 45, hgv => 45, psv => 45 }, bicycleroute => { foot => 55, horse => 50, wheelchair => 55, bicycle => 60, moped => 50, motorcycle => 50, motorcar => 45, goods => 45, hgv => 45, psv => 45 } }, # Restrictions profile_restrictions => { oneway => { foot => 0, horse => 1, wheelchair => 0, bicycle => 1, moped => 1, motorcycle => 1, motorcar => 1, goods => 1, hgv => 1, psv => 1 }, turns => { foot => 0, horse => 1, wheelchair => 0, bicycle => 1, moped => 1, motorcycle => 1, motorcar => 1, goods => 1, hgv => 1, psv => 1 }, weight => { foot => 0.0, horse => 0.0, wheelchair => 0.0, bicycle => 0.0, moped => 0.0, motorcycle => 0.0, motorcar => 0.0, goods => 5.0, hgv => 10.0, psv => 15.0 }, height => { foot => 0.0, horse => 0.0, wheelchair => 0.0, bicycle => 0.0, moped => 0.0, motorcycle => 0.0, motorcar => 0.0, goods => 2.5, hgv => 3.0, psv => 3.0 }, width => { foot => 0.0, horse => 0.0, wheelchair => 0.0, bicycle => 0.0, moped => 0.0, motorcycle => 0.0, motorcar => 0.0, goods => 2.0, hgv => 2.5, psv => 2.5 }, length => { foot => 0.0, horse => 0.0, wheelchair => 0.0, bicycle => 0.0, moped => 0.0, motorcycle => 0.0, motorcar => 0.0, goods => 5.0, hgv => 6.0, psv => 6.0 } } }; # end of routino variable 1; routino-3.0/web/www/routino/router.openlayers.js 644 233 144 154223 12573346365 15446 0// // Routino router web page Javascript // // Part of the Routino routing software. // // This file Copyright 2008-2015 Andrew M. Bishop // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . // var vismarkers, markers, markersmoved, paramschanged; var homelat=null, homelon=null; //////////////////////////////////////////////////////////////////////////////// /////////////////////////////// Initialisation ///////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // Make a deep copy of the routino profile. var routino_default={}; for(var l1 in routino) if(typeof(routino[l1])!="object") routino_default[l1]=routino[l1]; else { routino_default[l1]={}; for(var l2 in routino[l1]) if(typeof(routino[l1][l2])!="object") routino_default[l1][l2]=Number(routino[l1][l2]); else { routino_default[l1][l2]={}; for(var l3 in routino[l1][l2]) routino_default[l1][l2][l3]=Number(routino[l1][l2][l3]); } } // Store the latitude and longitude in the routino variable routino.point=[]; for(var marker=1;marker<=mapprops.maxmarkers;marker++) { routino.point[marker]={}; routino.point[marker].lon=""; routino.point[marker].lat=""; routino.point[marker].search=""; routino.point[marker].active=false; routino.point[marker].used=false; routino.point[marker].home=false; } // Process the URL query string and extract the arguments var legal={"^lon" : "^[-0-9.]+$", "^lat" : "^[-0-9.]+$", "^zoom" : "^[0-9]+$", "^lon[1-9]" : "^[-0-9.]+$", "^lat[1-9]" : "^[-0-9.]+$", "^search[1-9]" : "^.+$", "^transport" : "^[a-z]+$", "^highway-[a-z]+" : "^[0-9.]+$", "^speed-[a-z]+" : "^[0-9.]+$", "^property-[a-z]+" : "^[0-9.]+$", "^oneway" : "^(1|0|true|false|on|off)$", "^turns" : "^(1|0|true|false|on|off)$", "^weight" : "^[0-9.]+$", "^height" : "^[0-9.]+$", "^width" : "^[0-9.]+$", "^length" : "^[0-9.]+$", "^language" : "^[-a-zA-Z]+$"}; var args={}; if(location.search.length>1) { var query,queries; query=location.search.replace(/^\?/,""); query=query.replace(/;/g,"&"); queries=query.split("&"); for(var i=0;i=1;marker--) { var lon=args["lon" + marker]; var lat=args["lat" + marker]; var search=args["search" + marker]; if(lon !== undefined && lat !== undefined && search !== undefined && lon !== "" && lat !== "" && search !== "") { markerAddForm(marker); formSetSearch(marker,search); formSetCoords(marker,lon,lat); markerAddMap(marker); markerSearch(marker); vismarkers++; } else if(lon !== undefined && lat !== undefined && lon !== "" && lat !== "") { markerAddForm(marker); formSetCoords(marker,lon,lat); markerAddMap(marker); markerCoords(marker); vismarkers++; } else if(search !== undefined && search !== "") { markerAddForm(marker); formSetSearch(marker,search); markerSearch(marker); DoSearch(marker); vismarkers++; } else if(vismarkers || marker<=2) { markerAddForm(marker); vismarkers++; } var searchfield=document.forms["form"].elements["search" + marker]; if(searchfield.addEventListener) searchfield.addEventListener("keyup", searchOnReturnKey, false); else if(searchfield.attachEvent) searchfield.attachEvent("keyup", searchOnReturnKey); // Internet Explorer } // Update the transport type with the URL settings which updates all HTML forms to defaults. var transport=routino.transport; if(args["transport"] !== undefined) transport=args["transport"]; formSetTransport(transport); // Update the HTML with the URL settings if(args["language"] !== undefined) formSetLanguage(args["language"]); for(var key in routino.profile_highway) if(args["highway-" + key] !== undefined) formSetHighway(key,args["highway-" + key]); for(var key in routino.profile_speed) if(args["speed-" + key] !== undefined) formSetSpeed(key,args["speed-" + key]); for(var key in routino.profile_property) if(args["property-" + key] !== undefined) formSetProperty(key,args["property-" + key]); for(var key in routino.restrictions) { if(key=="oneway" || key=="turns") { if(args[key] !== undefined) formSetRestriction(key,args[key]); } else { if(args["restrict-" + key] !== undefined) formSetRestriction(key,args["restrict-" + key]); } } // Get the home location cookie and compare to each waypoint var cookies=document.cookie.split("; "); for(var cookie=0;cookie100) value=100; if(value< 0) value= 0; document.forms["form"].elements["highway-" + type].value=value; routino.profile_highway[type][routino.transport]=value; paramschanged=true; updateURLs(); } // // Change of Speed in the form // function formSetSpeed(type,value) // called from router.html (with one argument) { if(value == "+") { value=routino.profile_speed[type][routino.transport]; if(value<10) value=2*Math.floor(value/2)+2; else if(value<30) value=5*Math.floor(value/5)+5; else value=10*Math.floor(value/10)+10; } else if(value == "-") { value=routino.profile_speed[type][routino.transport]; if(value<=10) value=2*Math.ceil(value/2)-2; else if(value<=30) value=5*Math.ceil(value/5)-5; else value=10*Math.ceil(value/10)-10; } else if(value == "=") value=document.forms["form"].elements["speed-" + type].value; value=Number(value); if(isNaN(value)) value= 60; if(value>150) value=150; if(value< 0) value= 0; document.forms["form"].elements["speed-" + type].value=value; routino.profile_speed[type][routino.transport]=value; paramschanged=true; updateURLs(); } // // Change of Property in the form // function formSetProperty(type,value) // called from router.html (with one argument) { if(value == "+") { value=routino.profile_property[type][routino.transport]; if(value>=40 && value<60) value=2*Math.floor(value/2)+2; else value=5*Math.floor(value/5)+5; } else if(value == "-") { value=routino.profile_property[type][routino.transport]; if(value>40 && value<=60) value=2*Math.ceil(value/2)-2; else value=5*Math.ceil(value/5)-5; } else if(value == "=") value=document.forms["form"].elements["property-" + type].value; value=Number(value); if(isNaN(value)) value= 50; if(value>100) value=100; if(value< 0) value= 0; document.forms["form"].elements["property-" + type].value=value; routino.profile_property[type][routino.transport]=value; paramschanged=true; updateURLs(); } // // Change of Restriction rule in the form // function formSetRestriction(type,value) // called from router.html (with one argument) { if(type=="oneway" || type=="turns") { if(value === undefined) routino.profile_restrictions[type][routino.transport]=document.forms["form"].elements["restrict-" + type].checked; else document.forms["form"].elements["restrict-" + type].checked=value; routino.profile_restrictions[type][routino.transport]=value; } else if(type=="weight") { if(value == "+") value=routino.profile_restrictions[type][routino.transport]+5; else if(value == "-") value=routino.profile_restrictions[type][routino.transport]-5; else if(value == "=") value=document.forms["form"].elements["restrict-" + type].value; value=Number(value); if(isNaN(value)) value= 0; if(value>50) value=50; if(value< 0) value= 0; document.forms["form"].elements["restrict-" + type].value=value; routino.profile_restrictions[type][routino.transport]=value; } else /* if(type=="height" || type=="width" || type=="length") */ { if(value == "+") value=routino.profile_restrictions[type][routino.transport]+1; else if(value == "-") value=routino.profile_restrictions[type][routino.transport]-1; else if(value == "=") value=document.forms["form"].elements["restrict-" + type].value; value=Number(value); if(isNaN(value)) value= 0; if(value>25) value=25; if(value< 0) value= 0; document.forms["form"].elements["restrict-" + type].value=value; routino.profile_restrictions[type][routino.transport]=value; } paramschanged=true; updateURLs(); } // // Set the feature coordinates from the form when the form changes. // function formSetCoords(marker,lon,lat) // called from router.html (with one argument) { clearSearchResult(marker); if(lon === undefined && lat === undefined) { lon=document.forms["form"].elements["lon" + marker].value; lat=document.forms["form"].elements["lat" + marker].value; } if(lon === "" && lat === "") { document.forms["form"].elements["lon" + marker].value=""; document.forms["form"].elements["lat" + marker].value=""; routino.point[marker].lon=""; routino.point[marker].lat=""; updateURLs(); } else { var lonlat; if(lon==="") { lonlat=map.getCenter().clone(); lonlat.transform(epsg900913,epsg4326); lon=lonlat.lon; } if(lon<-180) lon=-180; if(lon>+180) lon=+180; if(lat==="") { lonlat=map.getCenter().clone(); lonlat.transform(epsg900913,epsg4326); lat=lonlat.lat; } if(lat<-90 ) lat=-90 ; if(lat>+90 ) lat=+90 ; lonlat = new OpenLayers.LonLat(lon,lat); lonlat.transform(epsg4326,epsg900913); markers[marker].move(lonlat); markersmoved=true; document.forms["form"].elements["lon" + marker].value=format5f(lon); document.forms["form"].elements["lat" + marker].value=format5f(lat); routino.point[marker].lon=lon; routino.point[marker].lat=lat; routino.point[marker].used=true; markerCheckHome(marker); } } // // Set the search field from the form when the form changes. // function formSetSearch(marker,search) // called from event handler linked to router.html (with one argument) { clearSearchResult(marker); if(search === undefined) { routino.point[marker].search=document.forms["form"].elements["search" + marker].value; DoSearch(marker); } else { document.forms["form"].elements["search" + marker].value=search; routino.point[marker].search=search; } } // // Format a number in printf("%.5f") format. // function format5f(number) { var newnumber=Math.floor(number*100000+0.5); var delta=0; if(newnumber>=0 && newnumber<100000) delta= 100000; if(newnumber<0 && newnumber>-100000) delta=-100000; var string=String(newnumber+delta); var intpart =string.substring(0,string.length-5); var fracpart=string.substring(string.length-5,string.length); if(delta>0) intpart="0"; if(delta<0) intpart="-0"; return(intpart + "." + fracpart); } // // Build a set of URL arguments // function buildURLArguments(lang) { var url= "transport=" + routino.transport; for(var marker=1;marker<=vismarkers;marker++) if(routino.point[marker].active) { url=url + ";lon" + marker + "=" + format5f(routino.point[marker].lon); url=url + ";lat" + marker + "=" + format5f(routino.point[marker].lat); if(routino.point[marker].search !== "") url=url + ";search" + marker + "=" + encodeURIComponent(routino.point[marker].search); } for(var key in routino.profile_highway) if(routino.profile_highway[key][routino.transport]!=routino_default.profile_highway[key][routino.transport]) url=url + ";highway-" + key + "=" + routino.profile_highway[key][routino.transport]; for(var key in routino.profile_speed) if(routino.profile_speed[key][routino.transport]!=routino_default.profile_speed[key][routino.transport]) url=url + ";speed-" + key + "=" + routino.profile_speed[key][routino.transport]; for(var key in routino.profile_property) if(routino.profile_property[key][routino.transport]!=routino_default.profile_property[key][routino.transport]) url=url + ";property-" + key + "=" + routino.profile_property[key][routino.transport]; for(var key in routino.restrictions) if(routino.profile_restrictions[key][routino.transport]!=routino_default.profile_restrictions[key][routino.transport]) url=url + ";" + key + "=" + routino.profile_restrictions[key][routino.transport]; if(lang && routino.language) url=url + ";language=" + routino.language; return(url); } // // Build a set of URL arguments for the map location // function buildMapArguments() { var lonlat = map.getCenter().clone(); lonlat.transform(epsg900913,epsg4326); var zoom = map.getZoom() + map.minZoomLevel; return "lat=" + format5f(lonlat.lat) + ";lon=" + format5f(lonlat.lon) + ";zoom=" + zoom; } // // Update the URLs // function updateURLs() { var urlargs1=buildURLArguments(true); var urlargs2=buildURLArguments(false); var mapargs=buildMapArguments(); var links=document.getElementsByTagName("a"); for(var i=0; i" + data_text + ""; document.getElementById("attribution_tile").innerHTML="" + tile_text + ""; } change_attribution(0); // Define a GPX layer but don't add it yet layerGPX={shortest: null, quickest: null}; gpx_style={shortest: new OpenLayers.Style({},{strokeWidth: 3, strokeColor: "#00FF00"}), quickest: new OpenLayers.Style({},{strokeWidth: 3, strokeColor: "#0000FF"})}; // Add a vectors layer layerVectors = new OpenLayers.Layer.Vector("Markers",{displayInLayerSwitcher: false}); map.addLayer(layerVectors); // A set of markers markers={}; markersmoved=false; paramschanged=false; for(var marker=1;marker<=mapprops.maxmarkers;marker++) { markers[marker] = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(0,0),{}, new OpenLayers.Style({},{externalGraphic: "icons/marker-" + marker + "-red.png", fillColor: "white", graphicYOffset: -25, graphicWidth: 21, graphicHeight: 25, display: "none"})); layerVectors.addFeatures([markers[marker]]); } // A function to drag the markers var drag = new OpenLayers.Control.DragFeature(layerVectors, {onDrag: dragMarkerMove, onComplete: dragMarkerComplete }); map.addControl(drag); drag.activate(); // Markers to highlight a selected point for(var highlight in highlights) { highlights[highlight] = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(0,0),{}, new OpenLayers.Style({},{strokeColor: route_dark_colours[highlight], fillColor: "white", pointRadius: 10, strokeWidth: 4, fillOpacity: 0, display: "none"})); layerVectors.addFeatures([highlights[highlight]]); } // A popup for routing results for(var popup in popups) popups[popup] = createPopup(popup); // Move the map map.events.register("moveend", map, updateURLs); var lon =args["lon"]; var lat =args["lat"]; var zoom=args["zoom"]; if(lon !== undefined && lat !== undefined && zoom !== undefined) { if(lonmapprops.eastedge) lon=mapprops.eastedge; if(latmapprops.northedge) lat=mapprops.northedge; if(zoommapprops.zoomin) zoom=mapprops.zoomin; var lonlat = new OpenLayers.LonLat(lon,lat); lonlat.transform(epsg4326,epsg900913); map.moveTo(lonlat,zoom-map.minZoomLevel); } else { map.setCenter(map.restrictedExtent.getCenterLonLat(), map.getZoomForExtent(map.restrictedExtent,true)); map.maxResolution = map.getResolution(); } // Unhide editing URL if variable set if(mapprops.editurl !== undefined && mapprops.editurl !== "") { var edit_url=document.getElementById("edit_url"); edit_url.style.display=""; edit_url.href=mapprops.editurl; } updateURLs(); } // // Callback for a marker drag occuring on the map. // function dragMarkerMove(feature,pixel) { for(var marker in markers) if(feature==markers[marker]) dragMarkerSetForm(marker); } // // Callback for completing a marker drag on the map. // function dragMarkerComplete(feature,pixel) { for(var marker in markers) if(feature==markers[marker]) dragMarkerSetForm(marker); updateURLs(); } // // Set the feature coordinates in the form after dragging it on the map. // function dragMarkerSetForm(marker) { var lonlat = new OpenLayers.LonLat(markers[marker].geometry.x, markers[marker].geometry.y); lonlat.transform(epsg900913,epsg4326); formSetCoords(marker,lonlat.lon,lonlat.lat); } //////////////////////////////////////////////////////////////////////////////// /////////////////////////////// Marker dragging //////////////////////////////// //////////////////////////////////////////////////////////////////////////////// var dragged_waypoint=null,dragged_marker=null; var dragged_waypoint_over=null,dragged_marker_over=null; var dragged_icon_x,dragged_icon_y; // // Drag a waypoint up or down the list. // function dragWaypointStart(e) { var w=e.target; while(w!=null && w.className != "waypoint") w=w.parentElement; if(w===null) return; w.style.opacity = "0.5"; dragged_waypoint=w; dragged_marker=Number.parseInt(dragged_waypoint.id.substring(8)); dragged_icon_x=e.clientX-e.target.offsetLeft; dragged_icon_y=e.clientY-e.target.offsetTop; } function dragWaypointEnd(e) { e.preventDefault(); if(dragged_waypoint===null) return; dragged_waypoint.style.opacity = ""; dragged_waypoint=null; dragged_marker=null; if(dragged_waypoint_over===null) return; dragged_waypoint_over.style.border = ""; dragged_waypoint_over=null; dragged_marker_over=null; } // // Drag a waypoint over another one up or down the list. // function dragWaypointEnter(e) { var w=e.target; while(w!=null && w.className != "waypoint") w=w.parentElement; if(w===null) return; if(dragged_waypoint_over!==null) dragged_waypoint_over.style.border = ""; if(w==dragged_waypoint) return; dragged_waypoint_over=w; dragged_marker_over=Number.parseInt(dragged_waypoint_over.id.substring(8)); if(dragged_marker>dragged_marker_over) w.style.borderTop = "3px solid black"; else w.style.borderBottom = "3px solid black"; } function dragWaypointOver(e) { e.preventDefault(); } function dragWaypointLeave(e) { var w=e.target; while(w!=null && w.className != "waypoint") w=w.parentElement; if(w===null) return; if(w==dragged_waypoint_over) return; w.style.border = ""; } // // Drop the waypoint after dragging up or down the list. // function dragWaypointDrop(e) { e.preventDefault(); if(dragged_marker_over===null) return; if(dragged_marker_over>dragged_marker) for(var m=dragged_marker;mdragged_marker_over;m--) markerSwap(m,m-1); } // // Drag a waypoint over the map. // function dragWaypointMapEnter(e) { e.preventDefault(); if(dragged_waypoint_over!==null) dragged_waypoint_over.style.border = ""; } function dragWaypointMapOver(e) { e.preventDefault(); } function dragWaypointMapLeave(e) { e.preventDefault(); } // // Drop the waypoint after dragging it over the map. // function dragWaypointMapDrop(e) { e.preventDefault(); var rect = document.getElementById("map").getBoundingClientRect(); var lonlat = map.getLonLatFromViewPortPx(new OpenLayers.Pixel(e.clientX-rect.left-window.scrollX-dragged_icon_x+8, e.clientY-rect.top -window.scrollY-dragged_icon_y+21)); lonlat.transform(epsg900913,epsg4326); formSetCoords(dragged_marker,lonlat.lon,lonlat.lat); if(!routino.point[dragged_marker].active) markerToggleMap(dragged_marker); } //////////////////////////////////////////////////////////////////////////////// /////////////////////////////// Marker handling //////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // // Toggle a marker on the map. // function markerToggleMap(marker) // called from router.html { if(!routino.point[marker].used) { routino.point[marker].used=true; markerCentre(marker); markerCoords(marker); } markerAddRemoveMap(marker,!routino.point[marker].active); updateSearchButtons(); } // // Show or hide a marker on the map. // function markerAddRemoveMap(marker,active) { if(active) markerAddMap(marker); else markerRemoveMap(marker); } // // Show a marker on the map. // function markerAddMap(marker) { clearSearchResult(marker); markers[marker].style.display = ""; routino.point[marker].active=true; routino.point[marker].used=true; updateIcon(marker); markersmoved=true; updateURLs(); } // // Remove a marker from the map. // function markerRemoveMap(marker) { clearSearchResult(marker); markers[marker].style.display = "none"; routino.point[marker].active=false; updateIcon(marker); markersmoved=true; updateURLs(); } // // Display search string for the marker // function markerSearch(marker) // called from router.html { clearSearchResult(marker); document.getElementById("coords" + marker).style.display="none"; document.getElementById("search" + marker).style.display=""; } // // Display coordinates for the marker // function markerCoords(marker) // called from router.html { clearSearchResult(marker); document.getElementById("search" + marker).style.display="none"; document.getElementById("coords" + marker).style.display=""; } // // Centre the marker on the map // function markerCentre(marker) // called from router.html { if(!routino.point[marker].used) return; clearSearchResult(marker); var lonlat=map.getCenter().clone(); lonlat.transform(epsg900913,epsg4326); formSetCoords(marker,lonlat.lon,lonlat.lat); } // // Centre the map on the marker // function markerRecentre(marker) // called from router.html { if(!routino.point[marker].used) return; clearSearchResult(marker); var lon=routino.point[marker].lon; var lat=routino.point[marker].lat; var lonlat = new OpenLayers.LonLat(lon,lat); lonlat.transform(epsg4326,epsg900913); map.panTo(lonlat); } // // Clear the current marker. // function markerRemove(marker) // called from router.html { clearSearchResult(marker); for(var m=marker;mmarker;m--) markerCopy(m,m-1); markerClearForm(marker-1); } // // Add a marker after the current one. // function markerAddAfter(marker) // called from router.html { if(vismarkers==mapprops.maxmarkers) return false; clearSearchResult(marker); markerAddForm(++vismarkers); for(var m=vismarkers;m>(marker+1);m--) markerCopy(m,m-1); markerClearForm(marker+1); } // // Set this marker as the home location. // function markerHome(marker) // called from router.html { if(!routino.point[marker].used) { markerMoveHome(marker); } else { clearSearchResult(marker); markerSetClearHome(marker,!routino.point[marker].home); } } // // Set this marker as the current location. // function markerLocate(marker) // called from router.html { clearSearchResult(marker); if(navigator.geolocation) navigator.geolocation.getCurrentPosition( function(position) { formSetCoords(marker,position.coords.longitude,position.coords.latitude); markerAddMap(marker); }); } // // Update the search buttons enable/disable. // function updateSearchButtons() { var markersactive=0; for(var m=1;m<=vismarkers;m++) if(routino.point[m].active) markersactive++; if(markersactive<2) { document.getElementById("shortest").disabled="disabled"; document.getElementById("quickest").disabled="disabled"; } else { document.getElementById("shortest").disabled=""; document.getElementById("quickest").disabled=""; } } // // Update an icon to set colours and home or normal marker. // function updateIcon(marker) { if(routino.point[marker].home) { if(routino.point[marker].active) document.getElementById("icon" + marker).src="icons/marker-home-red.png"; else document.getElementById("icon" + marker).src="icons/marker-home-grey.png"; markers[marker].style.externalGraphic="icons/marker-home-red.png"; } else { if(routino.point[marker].active) document.getElementById("icon" + marker).src="icons/marker-" + marker + "-red.png"; else document.getElementById("icon" + marker).src="icons/marker-" + marker + "-grey.png"; markers[marker].style.externalGraphic="icons/marker-" + marker + "-red.png"; } layerVectors.drawFeature(markers[marker]); } // // Move the marker to the home location // function markerMoveHome(marker) { if(homelon===null || homelat===null) return; routino.point[marker].home=true; routino.point[marker].used=true; formSetCoords(marker,homelon,homelat); markerAddMap(marker); } // // Set or clear the home marker icon // function markerSetClearHome(marker,home) { var cookie; var date = new Date(); if(home) { homelat=routino.point[marker].lat; homelon=routino.point[marker].lon; cookie="Routino-home=lon:" + homelon + ":lat:" + homelat; date.setUTCFullYear(date.getUTCFullYear()+5); routino.point[marker].home=true; } else { homelat=null; homelon=null; cookie="Routino-home=unset"; date.setUTCFullYear(date.getUTCFullYear()-1); routino.point[marker].home=false; } document.cookie=cookie + ";expires=" + date.toGMTString(); updateIcon(marker); for(var m=1;m<=mapprops.maxmarkers;m++) markerCheckHome(m); } // // Check if a marker is the home marker // function markerCheckHome(marker) { var home=routino.point[marker].home; if(routino.point[marker].lon==homelon && routino.point[marker].lat==homelat) routino.point[marker].home=true; else routino.point[marker].home=false; if(home!=routino.point[marker].home) updateIcon(marker); } // // Move this marker up. // function markerMoveUp(marker) // called from router.html { if(marker==1) { for(var m=1;m1;m--) markerSwap(m,m-1); } else markerSwap(marker,marker+1); } // // Copy a marker from one place to another. // function markerCopy(marker1,marker2) { for(var element in routino.point[marker2]) routino.point[marker1][element]=routino.point[marker2][element]; document.getElementById("search" + marker1).style.display=document.getElementById("search" + marker2).style.display; document.getElementById("coords" + marker1).style.display=document.getElementById("coords" + marker2).style.display; document.forms["form"].elements["search" + marker1].value=document.forms["form"].elements["search" + marker2].value; formSetCoords(marker1,routino.point[marker1].lon,routino.point[marker1].lat); markerAddRemoveMap(marker1,routino.point[marker1].active); } // // Swap a pair of markers. // function markerSwap(marker1,marker2) { for(var element in routino.point[marker2]) { var temp=routino.point[marker1][element]; routino.point[marker1][element]=routino.point[marker2][element]; routino.point[marker2][element]=temp; } var search_display=document.getElementById("search" + marker1).style.display; document.getElementById("search" + marker1).style.display=document.getElementById("search" + marker2).style.display; document.getElementById("search" + marker2).style.display=search_display; var coords_display=document.getElementById("coords" + marker1).style.display; document.getElementById("coords" + marker1).style.display=document.getElementById("coords" + marker2).style.display; document.getElementById("coords" + marker2).style.display=coords_display; var search_value=document.forms["form"].elements["search" + marker1].value; document.forms["form"].elements["search" + marker1].value=document.forms["form"].elements["search" + marker2].value; document.forms["form"].elements["search" + marker2].value=search_value; formSetCoords(marker1,routino.point[marker1].lon,routino.point[marker1].lat); formSetCoords(marker2,routino.point[marker2].lon,routino.point[marker2].lat); markerAddRemoveMap(marker1,routino.point[marker1].active); markerAddRemoveMap(marker2,routino.point[marker2].active); } // // Reverse the markers. // function markersReverse() // called from router.html { for(var marker=1;marker<=vismarkers/2;marker++) markerSwap(marker,vismarkers+1-marker); markersmoved=true; updateURLs(); } // // Close the loop. // function markersLoop() // called from router.html { if(vismarkers==mapprops.maxmarkers) return false; if(routino.point[vismarkers].lon==routino.point[1].lon && routino.point[vismarkers].lat==routino.point[1].lat) { if(routino.point[vismarkers].active) return false; else { markerToggleMap(vismarkers); return true; } } if(routino.point[vismarkers].used) markerAddForm(++vismarkers); markerCopy(vismarkers,1); markersmoved=true; updateURLs(); updateSearchButtons(); } // // Display the form for a marker // function markerAddForm(marker) { document.getElementById("waypoint" + marker).style.display=""; } // // Hide the form for a marker // function markerRemoveForm(marker) { document.getElementById("waypoint" + marker).style.display="none"; markerClearForm(marker); } // // Clear the form for a marker // function markerClearForm(marker) { markerRemoveMap(marker); markerCoords(marker); formSetCoords(marker,"",""); formSetSearch(marker,""); updateIcon(marker); routino.point[marker].used=false; routino.point[marker].home=false; routino.point[marker].active=false; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////// Route results handling //////////////////////////// //////////////////////////////////////////////////////////////////////////////// var route_light_colours={shortest: "#60C060", quickest: "#6060C0"}; var route_dark_colours ={shortest: "#408040", quickest: "#404080"}; var highlights={shortest: null, quickest: null}; var popups={shortest: null, quickest: null}; var routepoints={shortest: {}, quickest: {}}; var gpx_style={shortest: null, quickest: null}; // // Highlight a specific item in the route // function highlight(type,line,action) { if(action == "clear") { highlights[type].style.display = "none"; drawPopup(type,null); } else if(action == "zoom") { var lonlat = new OpenLayers.LonLat(routepoints[type][line].lon,routepoints[type][line].lat); lonlat.transform(epsg4326,epsg900913); map.moveTo(lonlat,map.numZoomLevels-2); } else { // Marker var lonlat = new OpenLayers.LonLat(routepoints[type][line].lon,routepoints[type][line].lat); lonlat.transform(epsg4326,epsg900913); highlights[type].move(lonlat); if(highlights[type].style.display == "none") highlights[type].style.display = ""; // Popup drawPopup(type,"" + routepoints[type][line].html + "
"); } layerVectors.drawFeature(highlights[type]); } // // Create a popup - independent of map because want it fixed on screen not fixed on map. // function createPopup(type) { var popup=document.createElement("div"); popup.className = "popup"; popup.innerHTML = ""; popup.style.display = "none"; popup.style.position = "fixed"; popup.style.top = "-4000px"; popup.style.left = "-4000px"; popup.style.zIndex = "100"; popup.style.padding = "5px"; popup.style.opacity=0.85; popup.style.backgroundColor=route_light_colours[type]; popup.style.border="4px solid " + route_dark_colours[type]; document.body.appendChild(popup); return(popup); } // // Draw a popup - independent of map because want it fixed on screen not fixed on map. // function drawPopup(type,html) { var popup=popups[type]; if(html===null) { popup.style.display="none"; return; } if(popup.style.display=="none") { var map_div=document.getElementById("map"); popup.style.left =map_div.offsetParent.offsetLeft+map_div.offsetLeft+60 + "px"; popup.style.top = map_div.offsetTop +30 + "px"; popup.style.width =map_div.clientWidth-120 + "px"; popup.style.display=""; } var close="X"; popup.innerHTML=close+html; } // // Remove a GPX trace // function removeGPXTrace(type) { map.removeLayer(layerGPX[type]); layerGPX[type].destroy(); layerGPX[type]=null; displayStatus(type,"no_info"); document.getElementById(type + "_links").style.display = "none"; document.getElementById(type + "_route").innerHTML = ""; hideshow_hide(type); } //////////////////////////////////////////////////////////////////////////////// /////////////////////////////// Server handling //////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // // Define an AJAX request object // function ajaxGET(url,success,failure,state) { var ajaxRequest=new XMLHttpRequest(); function ajaxGOT(options) { if(this.readyState==4) if(this.status==200) { if(typeof(options.success)=="function") options.success(this,options.state); } else { if(typeof(options.failure)=="function") options.failure(this,options.state); } } ajaxRequest.onreadystatechange = function(){ ajaxGOT.call(ajaxRequest,{success: success, failure: failure, state: state}); }; ajaxRequest.open("GET", url, true); ajaxRequest.send(null); } // // Display data statistics // function displayStatistics() // called from router.html { // Use AJAX to get the statistics ajaxGET("statistics.cgi", runStatisticsSuccess); } // // Success in running data statistics generation. // function runStatisticsSuccess(response) { document.getElementById("statistics_data").innerHTML="
" + response.responseText + "
"; document.getElementById("statistics_link").style.display="none"; } // // Submit form - perform the routing // function findRoute(type) // called from router.html { tab_select("results"); hideshow_hide("help_options"); hideshow_hide("shortest"); hideshow_hide("quickest"); displayStatus("result","running"); var url="router.cgi" + "?" + buildURLArguments(true) + ";type=" + type; // Destroy the existing layer(s) highlight("shortest",-1,"clear"); highlight("quickest",-1,"clear"); if(markersmoved || paramschanged) { if(layerGPX.shortest!==null) removeGPXTrace("shortest"); if(layerGPX.quickest!==null) removeGPXTrace("quickest"); markersmoved=false; paramschanged=false; } else if(layerGPX[type]!==null) removeGPXTrace(type); // Use AJAX to run the router routing_type=type; ajaxGET(url, runRouterSuccess, runRouterFailure); } // // Success in running router. // function runRouterSuccess(response) { var lines=response.responseText.split("\n"); var uuid=lines[0]; var success=lines[1]; var link; // Update the status message if(success=="ERROR") { displayStatus("result","error"); hideshow_show("help_route"); link=document.getElementById("router_log_error"); link.href="results.cgi?uuid=" + uuid + ";type=router;format=log"; return; } else { displayStatus("result","complete"); hideshow_hide("help_route"); link=document.getElementById("router_log_complete"); link.href="results.cgi?uuid=" + uuid + ";type=router;format=log"; } // Update the routing result message link=document.getElementById(routing_type + "_html"); link.href="results.cgi?uuid=" + uuid + ";type=" + routing_type + ";format=html"; link=document.getElementById(routing_type + "_gpx_track"); link.href="results.cgi?uuid=" + uuid + ";type=" + routing_type + ";format=gpx-track"; link=document.getElementById(routing_type + "_gpx_route"); link.href="results.cgi?uuid=" + uuid + ";type=" + routing_type + ";format=gpx-route"; link=document.getElementById(routing_type + "_text_all"); link.href="results.cgi?uuid=" + uuid + ";type=" + routing_type + ";format=text-all"; link=document.getElementById(routing_type + "_text"); link.href="results.cgi?uuid=" + uuid + ";type=" + routing_type + ";format=text"; document.getElementById(routing_type + "_links").style.display = ""; // Add a GPX layer var url="results.cgi?uuid=" + uuid + ";type=" + routing_type + ";format=gpx-track"; layerGPX[routing_type] = new OpenLayers.Layer.Vector("GPX (" + routing_type + ")", { displayInLayerSwitcher: false, protocol: new OpenLayers.Protocol.HTTP({url: url, format: new OpenLayers.Format.GPX()}), strategies: [new OpenLayers.Strategy.Fixed()], style: gpx_style[routing_type], projection: map.displayProjection }); map.addLayer(layerGPX[routing_type]); hideshow_show(routing_type); displayResult(routing_type,uuid); } // // Failure in running router. // function runRouterFailure(response) { displayStatus("result","failed"); } // // Display the status // function displayStatus(type,subtype,content) { var child=document.getElementById(type + "_status").firstChild; do { if(child.id !== undefined) child.style.display="none"; child=child.nextSibling; } while(child !== null); var chosen_status=document.getElementById(type + "_status_" + subtype); chosen_status.style.display=""; if(content !== undefined) chosen_status.innerHTML=content; } // // Display the route // function displayResult(type,uuid) { routing_type = type; // Add the route var url="results.cgi?uuid=" + uuid + ";type=" + routing_type + ";format=html"; // Use AJAX to get the route ajaxGET(url, getRouteSuccess, getRouteFailure); } // // Success in getting route. // function getRouteSuccess(response) { var lines=response.responseText.split("\n"); routepoints[routing_type]=[]; var points=routepoints[routing_type]; var table=0; var point=0; var total_table,total_word; for(var line=0;line")) table=1; else continue; } if(thisline.match("
")) break; if(thisline.match("")) { var rowtype=RegExp.$1; if(rowtype=="c") { thisline.match(": *([-0-9.]+) *([-0-9.]+)"); points[point]={lat: Number(RegExp.$1), lon: Number(RegExp.$2), html: "", highway: "", distance: "", total: ""}; point++; } else if(rowtype=="n") { points[point-1].html += thisline; } else if(rowtype=="s") { thisline.match("([^<]+)"); points[point-1].highway = RegExp.$1; thisline.match("([^<]+)"); points[point-1].distance = RegExp.$1; thisline.match("([^<]+)"); points[point-1].total = RegExp.$1; thisline.match("^(.*)."); points[point-1].html += RegExp.$1; } else if(rowtype=="t") { points[point-1].html += thisline; thisline.match("([^<]+)"); points[point-1].total = RegExp.$1; thisline.match("(.*)"); points[point-1].highway = RegExp.$1; } } } displayStatus(routing_type,"info",points[point-1].total.bold()); var result=""; for(var p=0;p" + "
#" + (p+1) + "" + points[p].highway; } result=result + "
"; document.getElementById(routing_type + "_route").innerHTML=result; } // // Failure in getting route. // function getRouteFailure(response) { document.getElementById(routing_type + "_route").innerHTML = ""; } // // Perform a search // function DoSearch(marker) { // Use AJAX to get the search result var search=routino.point[marker].search; var mapbounds=map.getExtent().clone(); mapbounds.transform(epsg900913,epsg4326); var url="search.cgi"; url=url + "?marker=" + marker; url=url + ";lonmin=" + format5f(mapbounds.left); url=url + ";latmin=" + format5f(mapbounds.bottom); url=url + ";lonmax=" + format5f(mapbounds.right); url=url + ";latmax=" + format5f(mapbounds.top); url=url + ";search=" + encodeURIComponent(search); ajaxGET(url,runSearchSuccess); } var searchresults=[]; // // Success in running search. // function runSearchSuccess(response) { var lines=response.responseText.split("\n"); var marker=lines[0]; var cpuinfo=lines[1]; // not used var message=lines[2]; if(message !== "") { alert(message); return; } searchresults[marker]=[]; for(var line=3;line"; for(var n=0;n0) innerHTML+="
"; innerHTML+="" + searchresults[marker][n].name + ""; } results.innerHTML=innerHTML; results.style.display=""; } } // // Display search results. // function choseSearchResult(marker,n) { if(n>=0) { formSetSearch(marker,searchresults[marker][n].name); formSetCoords(marker,searchresults[marker][n].lon,searchresults[marker][n].lat); markerAddMap(marker); } } // // Clear search results. // function clearSearchResult(marker) { document.getElementById("searchresults" + marker).style.display="none"; } routino-3.0/web/www/routino/router.html.nl 644 233 144 75026 12573351571 14204 0 Routino : Route Planner for OpenStreetMap Data
Opties Resultaten Data
Routino OpenStreetMap Router Zoom naar straatniveau. Selecteer start- and eindpunten onder Coordinaten. (click op het marker icoon links, schuif het op map naar gewenste positie).
+ - Coordinaten
+ - Transport Type
Te voet:
Paard:
Rolstoel:
Fiets:
Brommer:
Motorfiets:
Auto:
Goederen:
Zwaar transport:
Publiek transport:
+ - Voorkeur Wegtype
+ - Snelheidslimieten
+ - Weg Eigenschappen
+ - Andere Beperkingen
Zoek Route
+ - Help
Quick Start
Click op marker-icoontje (Waypoints) om ze op de map te plaatsen (rechts). Sleep ze vervolgens naar de gewenste positie. Het is best om eerst naar straat niveau te zoomen op de kaart. Selecteer het transport type, toegestane weg-types, snelheidslimieten, wegeigenschappen en andere restricties uit de opties. Selecteer "Kortste" of "Snelste" om de route te berekenen en te tekenen op de map.

Coordinaten (Waypoints)
Click op het marker icoontje, nog eens clicken voor aan/uit. Wanneer de route berekend wordt, zal dit nauwkeurig aansluiten bij de volgorde van deze punten. (rekening houdend met transport type)

Transport Type
Wanneer je een bepaald transport type kiest wordt bij berekenen route hiermede rekening gehouden. Het transport type bestaat uit een lijst met default waarden voor ieder wegtype. Deze percentages kunnen ook nog eens manueel aangepast worden.

Voorkeur Wegtype
De voorkeur voor een bepaald type weg wordt uitgedrukt in een percentage. Bijvoorbeeld wanneer u het Transport Type "Fiets" kiest, dan zal er voor Autostrade 0% staan, en voor Fietspad 100%. Wanneer u Autowegen, Nationale wegen wil vermijden of beperken bij het maken van een fietsroute, kan u percentage naar beneden aanpassen.

Snelheid limieten
De snelheidslimieten worden afgeleid van het type weg. Het is mogelijk dat er voor een bepaalde weg andere beperkingen gelden. In dat geval worden die gekoezen. (het geval dat deze lager zijn dan de default)

Weg Eigenschappen
Voor het berekenen van de route, kan de de voorkeur gegeven worden aan een bepaalde wegeigenschap. Wanneer u kiest voor 25% verhard, zal er automatisch de voorkeur aan 75% onverhard worden gegeven. Ook al is het onverharde stuk 3 X langer, toch kan er dan de voorkeur aan gegeven worden.

Andere Beperkingen
Deze zullen toelaten dat er een route berekend wordt die rekening houdt met gewicht, hoogte, breedte of lengte. Het is ook mogelijk geen rekening te houden met eenrichtingsverkeer (bijvoorbeeld als voetganger of fietser)

Router: Routino | Geo Data: | Tiles:
routino-3.0/web/www/routino/profiles.js 644 233 144 15601 12573351566 13544 0//////////////////////////////////////////////////////////////////////////////// /////////////////////////// Routino default profile //////////////////////////// //////////////////////////////////////////////////////////////////////////////// var routino={ // contains all default Routino options (generated using "--help-profile-json"). // Default transport type transport: "motorcar", // Transport types transports: { foot: 1, horse: 2, wheelchair: 3, bicycle: 4, moped: 5, motorcycle: 6, motorcar: 7, goods: 8, hgv: 9, psv: 10 }, // Highway types highways: { motorway: 1, trunk: 2, primary: 3, secondary: 4, tertiary: 5, unclassified: 6, residential: 7, service: 8, track: 9, cycleway: 10, path: 11, steps: 12, ferry: 13 }, // Property types properties: { paved: 1, multilane: 2, bridge: 3, tunnel: 4, footroute: 5, bicycleroute: 6 }, // Restriction types restrictions: { oneway: 1, turns: 2, weight: 3, height: 4, width: 5, length: 6 }, // Allowed highways profile_highway: { motorway: { foot: 0, horse: 0, wheelchair: 0, bicycle: 0, moped: 0, motorcycle: 100, motorcar: 100, goods: 100, hgv: 100, psv: 100 }, trunk: { foot: 40, horse: 25, wheelchair: 40, bicycle: 30, moped: 90, motorcycle: 100, motorcar: 100, goods: 100, hgv: 100, psv: 100 }, primary: { foot: 50, horse: 50, wheelchair: 50, bicycle: 70, moped: 100, motorcycle: 90, motorcar: 90, goods: 90, hgv: 90, psv: 90 }, secondary: { foot: 60, horse: 50, wheelchair: 60, bicycle: 80, moped: 90, motorcycle: 80, motorcar: 80, goods: 80, hgv: 80, psv: 80 }, tertiary: { foot: 70, horse: 75, wheelchair: 70, bicycle: 90, moped: 80, motorcycle: 70, motorcar: 70, goods: 70, hgv: 70, psv: 70 }, unclassified: { foot: 80, horse: 75, wheelchair: 80, bicycle: 90, moped: 70, motorcycle: 60, motorcar: 60, goods: 60, hgv: 60, psv: 60 }, residential: { foot: 90, horse: 75, wheelchair: 90, bicycle: 90, moped: 60, motorcycle: 50, motorcar: 50, goods: 50, hgv: 50, psv: 50 }, service: { foot: 90, horse: 75, wheelchair: 90, bicycle: 90, moped: 80, motorcycle: 80, motorcar: 80, goods: 80, hgv: 80, psv: 80 }, track: { foot: 95, horse: 100, wheelchair: 95, bicycle: 90, moped: 0, motorcycle: 0, motorcar: 0, goods: 0, hgv: 0, psv: 0 }, cycleway: { foot: 95, horse: 90, wheelchair: 95, bicycle: 100, moped: 0, motorcycle: 0, motorcar: 0, goods: 0, hgv: 0, psv: 0 }, path: { foot: 100, horse: 100, wheelchair: 100, bicycle: 90, moped: 0, motorcycle: 0, motorcar: 0, goods: 0, hgv: 0, psv: 0 }, steps: { foot: 80, horse: 0, wheelchair: 0, bicycle: 0, moped: 0, motorcycle: 0, motorcar: 0, goods: 0, hgv: 0, psv: 0 }, ferry: { foot: 20, horse: 20, wheelchair: 20, bicycle: 20, moped: 20, motorcycle: 20, motorcar: 20, goods: 20, hgv: 20, psv: 20 } }, // Speed limits profile_speed: { motorway: { foot: 0, horse: 0, wheelchair: 0, bicycle: 0, moped: 48, motorcycle: 112, motorcar: 112, goods: 96, hgv: 89, psv: 89 }, trunk: { foot: 4, horse: 8, wheelchair: 4, bicycle: 20, moped: 48, motorcycle: 96, motorcar: 96, goods: 96, hgv: 80, psv: 80 }, primary: { foot: 4, horse: 8, wheelchair: 4, bicycle: 20, moped: 48, motorcycle: 96, motorcar: 96, goods: 96, hgv: 80, psv: 80 }, secondary: { foot: 4, horse: 8, wheelchair: 4, bicycle: 20, moped: 48, motorcycle: 88, motorcar: 88, goods: 88, hgv: 80, psv: 80 }, tertiary: { foot: 4, horse: 8, wheelchair: 4, bicycle: 20, moped: 48, motorcycle: 80, motorcar: 80, goods: 80, hgv: 80, psv: 80 }, unclassified: { foot: 4, horse: 8, wheelchair: 4, bicycle: 20, moped: 48, motorcycle: 64, motorcar: 64, goods: 64, hgv: 64, psv: 64 }, residential: { foot: 4, horse: 8, wheelchair: 4, bicycle: 20, moped: 48, motorcycle: 48, motorcar: 48, goods: 48, hgv: 48, psv: 48 }, service: { foot: 4, horse: 8, wheelchair: 4, bicycle: 20, moped: 32, motorcycle: 32, motorcar: 32, goods: 32, hgv: 32, psv: 32 }, track: { foot: 4, horse: 8, wheelchair: 4, bicycle: 20, moped: 16, motorcycle: 16, motorcar: 16, goods: 16, hgv: 16, psv: 16 }, cycleway: { foot: 4, horse: 8, wheelchair: 4, bicycle: 20, moped: 0, motorcycle: 0, motorcar: 0, goods: 0, hgv: 0, psv: 0 }, path: { foot: 4, horse: 8, wheelchair: 4, bicycle: 20, moped: 0, motorcycle: 0, motorcar: 0, goods: 0, hgv: 0, psv: 0 }, steps: { foot: 4, horse: 0, wheelchair: 4, bicycle: 0, moped: 0, motorcycle: 0, motorcar: 0, goods: 0, hgv: 0, psv: 0 }, ferry: { foot: 10, horse: 10, wheelchair: 10, bicycle: 10, moped: 10, motorcycle: 10, motorcar: 10, goods: 10, hgv: 10, psv: 10 } }, // Highway properties profile_property: { paved: { foot: 50, horse: 20, wheelchair: 90, bicycle: 50, moped: 100, motorcycle: 100, motorcar: 100, goods: 100, hgv: 100, psv: 100 }, multilane: { foot: 25, horse: 25, wheelchair: 25, bicycle: 25, moped: 35, motorcycle: 60, motorcar: 60, goods: 60, hgv: 60, psv: 60 }, bridge: { foot: 50, horse: 50, wheelchair: 50, bicycle: 50, moped: 50, motorcycle: 50, motorcar: 50, goods: 50, hgv: 50, psv: 50 }, tunnel: { foot: 50, horse: 50, wheelchair: 50, bicycle: 50, moped: 50, motorcycle: 50, motorcar: 50, goods: 50, hgv: 50, psv: 50 }, footroute: { foot: 55, horse: 50, wheelchair: 55, bicycle: 50, moped: 50, motorcycle: 50, motorcar: 45, goods: 45, hgv: 45, psv: 45 }, bicycleroute: { foot: 55, horse: 50, wheelchair: 55, bicycle: 60, moped: 50, motorcycle: 50, motorcar: 45, goods: 45, hgv: 45, psv: 45 } }, // Restrictions profile_restrictions: { oneway: { foot: 0, horse: 1, wheelchair: 0, bicycle: 1, moped: 1, motorcycle: 1, motorcar: 1, goods: 1, hgv: 1, psv: 1 }, turns: { foot: 0, horse: 1, wheelchair: 0, bicycle: 1, moped: 1, motorcycle: 1, motorcar: 1, goods: 1, hgv: 1, psv: 1 }, weight: { foot: 0.0, horse: 0.0, wheelchair: 0.0, bicycle: 0.0, moped: 0.0, motorcycle: 0.0, motorcar: 0.0, goods: 5.0, hgv: 10.0, psv: 15.0 }, height: { foot: 0.0, horse: 0.0, wheelchair: 0.0, bicycle: 0.0, moped: 0.0, motorcycle: 0.0, motorcar: 0.0, goods: 2.5, hgv: 3.0, psv: 3.0 }, width: { foot: 0.0, horse: 0.0, wheelchair: 0.0, bicycle: 0.0, moped: 0.0, motorcycle: 0.0, motorcar: 0.0, goods: 2.0, hgv: 2.5, psv: 2.5 }, length: { foot: 0.0, horse: 0.0, wheelchair: 0.0, bicycle: 0.0, moped: 0.0, motorcycle: 0.0, motorcar: 0.0, goods: 5.0, hgv: 6.0, psv: 6.0 } } }; // end of routino variable routino-3.0/web/www/routino/router.pl 644 233 144 12023 12306670331 13217 0# # Routino generic router Perl script # # Part of the Routino routing software. # # This file Copyright 2008-2014 Andrew M. Bishop # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # use strict; # Use the directory paths script require "paths.pl"; # Load the profiles variables require "profiles.pl"; # Use the perl Time::HiRes module use Time::HiRes qw(gettimeofday tv_interval); my $t0 = [gettimeofday]; # # Fill in the default parameters using the ones above (don't use executable compiled in defaults) # sub FillInDefaults { my(%params)=@_; $params{transport}=$main::routino->{transport} if(!defined $params{transport}); my $transport=$params{transport}; foreach my $highway (keys %{$main::routino->{highways}}) { my $key="highway-$highway"; my $value=$main::routino->{profile_highway}->{$highway}->{$transport}; $params{$key}=$value if(!defined $params{$key}); $key="speed-$highway"; $value=$main::routino->{profile_speed}->{$highway}->{$transport}; $params{$key}=$value if(!defined $params{$key}); } foreach my $property (keys %{$main::routino->{properties}}) { my $key="property-$property"; my $value=$main::routino->{profile_property}->{$property}->{$transport}; $params{$key}=$value if(!defined $params{$key}); } $params{oneway} =~ s/(true|on)/1/; $params{oneway} =~ s/(false|off)/0/; $params{turns} =~ s/(true|on)/1/; $params{turns} =~ s/(false|off)/0/; foreach my $restriction (keys %{$main::routino->{restrictions}}) { my $key="$restriction"; my $value=$main::routino->{profile_restrictions}->{$restriction}->{$transport}; $params{$key}=$value if(!defined $params{$key}); } return %params; } # # Run the router # sub RunRouter { my($optimise,%params)=@_; # Combine all of the parameters together my $params="--$optimise"; foreach my $key (keys %params) { $params.=" --$key=$params{$key}"; } # Change directory mkdir $main::results_dir,0755 if(! -d $main::results_dir); chdir $main::results_dir; # Create a unique output directory my $uuid; if($^O eq "darwin") { chomp($uuid=`echo '$params' $$ | md5 | cut -f1 '-d '`); } else { chomp($uuid=`echo '$params' $$ | md5sum | cut -f1 '-d '`); } mkdir $uuid; chmod 0775, $uuid; chdir $uuid; # Run the router my $safe_params =""; if($main::data_dir) { my @pathparts=split('/',$main::data_dir); $safe_params.=" --dir=".pop(@pathparts); } # This works in newer Perl versions, but not older ones. #$safe_params.=" --dir=".pop([split('/',$main::data_dir)]) if($main::data_dir); $safe_params.=" --prefix=$main::data_prefix" if($main::data_prefix); open(LOG,">router.log"); print LOG "$main::router_exe $params$safe_params\n\n"; # Don't put the full pathnames in the logfile. close(LOG); $params.=" --dir=$main::data_dir" if($main::data_dir); $params.=" --prefix=$main::data_prefix" if($main::data_prefix); $params.=" --loggable"; system "$main::bin_dir/$main::router_exe $params >> router.log 2>&1"; my $status="OK"; $status="ERROR" if($? != 0); my(undef,undef,$cuser,$csystem) = times; open(LOG,">>router.log"); printf LOG "\nTime: %.3f CPU / %.3f elapsed\n",$cuser+$csystem,tv_interval($t0); close(LOG); # Return the results return($uuid,$status); } # # Return the output file # # Possible file formats my %suffixes=( "html" => ".html", "gpx-route" => "-route.gpx", "gpx-track" => "-track.gpx", "text" => ".txt", "text-all" => "-all.txt", "log" => ".log" ); # Possible MIME types my %mimetypes=( "html" => "text/html", "gpx-route" => "text/xml", "gpx-track" => "text/xml", "text" => "text/plain", "text-all" => "text/plain", "log" => "text/plain" ); sub ReturnOutput { my($uuid,$type,$format)=@_; if($type eq "router") { $format="log" } my $suffix=$suffixes{$format}; my $mime =$mimetypes{$format}; my $file="$main::results_dir/$uuid/$type$suffix"; # Return the output if(!$type || !$uuid || !$format || ! -f $file) { print header('text/plain','404 Not found'); print "Not Found!\n"; } else { print header($mime); system "cat $file"; } } 1; routino-3.0/web/www/routino/router.css 644 233 144 10202 12525636273 13403 0/* // Routino router web page style sheet. // // Part of the Routino routing software. // // This file Copyright 2008-2015 Andrew M. Bishop // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . */ /*--------------------------------*/ /* Left panel - override defaults */ /*--------------------------------*/ DIV.hideshow_box { overflow-x: auto; } /*------------------------------*/ /* Left panel - generic options */ /*------------------------------*/ DIV.scrollable { overflow: auto; height: 20em; } /*-----------------------------------*/ /* Left panel - specific tab options */ /*-----------------------------------*/ DIV#tab_options_div DIV.waypoint { clear: both; } DIV#tab_options_div DIV.waypoint SPAN { vertical-align: 50%; } DIV#tab_options_div DIV.waypoint DIV.waypoint-buttons { float: right; } DIV#tab_options_div DIV.waypoint IMG { cursor: pointer; } DIV#tab_options_div DIV.waypoint IMG.waypoint-icon { cursor: move; } DIV#tab_options_div DIV.waypoint IMG:hover { background: #F0F000; } DIV#tab_options_div DIV#waypoints-buttons { clear: both; } DIV#tab_options_div TABLE { padding: 0; border: 0 hidden; margin: 0; } DIV#tab_options_div TABLE TD { padding: 0; border: 0; margin: 0; } DIV#tab_options_div DIV.center { text-align: center; } DIV#tab_options_div A:hover { background: #F0F000; } DIV#tab_options_div INPUT { padding: 0; border: 1px solid; margin: 0; } DIV#tab_options_div INPUT[type="text"] { text-align: right; } DIV#tab_options_div INPUT[size="18"] { text-align: left; } DIV#tab_options_div INPUT:hover { background: #F0F0C0; } DIV#tab_options_div INPUT#shortest { margin: 3px; border: 3px solid; border-color: #00FF00; background: #C0F0C0; text-align: center; } DIV#tab_options_div INPUT#shortest:hover { background: #F0F000; } DIV#tab_options_div INPUT[disabled]#shortest { border-color: #004000; background: #E0F0E0; } DIV#tab_options_div INPUT#quickest { margin: 3px; border: 3px solid; border-color: #0000FF; background: #C0C0F0; text-align: center; } DIV#tab_options_div INPUT#quickest:hover { background: #F0F000; } DIV#tab_options_div INPUT[disabled]#quickest { border-color: #000040; background: #E0E0F0; } DIV#tab_results_div TABLE { border-collapse: collapse; border: hidden; } DIV#tab_results_div TD.distance { text-align: left; } DIV#tab_results_div TD.highway { text-align: left; padding-left: 10px; } DIV#tab_results_div DIV#shortest_links A:hover { background: #C0F0C0; } DIV#tab_results_div DIV#shortest_route TR:hover { cursor: pointer; background: #C0F0C0; } DIV#tab_results_div DIV#quickest_links A:hover { background: #C0C0F0; } DIV#tab_results_div DIV#quickest_route TR:hover { cursor: pointer; background: #C0C0F0; } /*-------------------------------------------------*/ /* Popup - using the styles defined in HTML output */ /*-------------------------------------------------*/ DIV.popup table {table-layout: fixed; border: none; border-collapse: collapse;} DIV.popup tr {border: 0px;} DIV.popup tr.c {display: none;} /* coords */ DIV.popup tr.n {} /* node */ DIV.popup tr.s {} /* segment */ DIV.popup tr.t {font-weight: bold;} /* total */ DIV.popup td.l {font-weight: bold;} DIV.popup td.r {} DIV.popup span.w {font-weight: bold;} /* waypoint */ DIV.popup span.h {text-decoration: underline;} /* highway */ DIV.popup span.d {} /* segment distance */ DIV.popup span.j {font-style: italic;} /* total journey distance */ DIV.popup span.t {font-variant: small-caps;} /* turn */ DIV.popup span.b {font-variant: small-caps;} /* bearing */ routino-3.0/web/www/routino/router.cgi 755 233 144 5676 12306665765 13370 0#!/usr/bin/perl # # Routino interactive router CGI # # Part of the Routino routing software. # # This file Copyright 2008-2014 Andrew M. Bishop # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # use strict; # Use the generic router script require "router.pl"; # Use the perl CGI module use CGI ':cgi'; # Create the query and get the parameters my $query=new CGI; my @rawparams=$query->param; # Legal CGI parameters with regexp validity check my %legalparams=( "lon[1-9][0-9]*" => "[-0-9.]+", "lat[1-9][0-9]*" => "[-0-9.]+", "heading" => "[-0-9.]+", "transport" => "[a-z]+", "highway-[a-z]+" => "[0-9.]+", "speed-[a-z]+" => "[0-9.]+", "property-[a-z]+" => "[0-9.]+", "oneway" => "(1|0|true|false|on|off)", "turns" => "(1|0|true|false|on|off)", "weight" => "[0-9.]+", "height" => "[0-9.]+", "width" => "[0-9.]+", "length" => "[0-9.]+", "length" => "[0-9.]+", "language" => "[-a-zA-Z]+", "type" => "(shortest|quickest)", "format" => "(html|gpx-route|gpx-track|text|text-all)", "reverse" => "(1|0|true|false|on|off)", "loop" => "(1|0|true|false|on|off)" ); # Validate the CGI parameters, ignore invalid ones my %cgiparams=(); foreach my $key (@rawparams) { foreach my $test (keys (%legalparams)) { if($key =~ m%^$test$%) { my $value=$query->param($key); if($value =~ m%^$legalparams{$test}$%) { $cgiparams{$key}=$value; last; } } } } # Get the important parameters my $type; my $format; $type=$cgiparams{type}; delete $cgiparams{type}; $type="shortest" if(!$type); $format=$cgiparams{format}; delete $cgiparams{format}; # Fill in the default parameters my %fullparams=FillInDefaults(%cgiparams); # Run the router my($router_uuid,$router_success)=RunRouter($type,%fullparams); # Return the output if($format) { ReturnOutput($router_uuid,$type,$format); } else { print header('text/plain'); print "$router_uuid\n"; print "$router_success\n"; } routino-3.0/web/www/routino/visualiser.css 644 233 144 3165 12260522707 14233 0/* // Routino visualiser web page style sheet. // // Part of the Routino routing software. // // This file Copyright 2008-2013 Andrew M. Bishop // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . */ /*--------------------------------*/ /* Left panel - override defaults */ /*--------------------------------*/ DIV.hideshow_box { overflow-x: auto; } /*-----------------------------------*/ /* Left panel - specific tab options */ /*-----------------------------------*/ DIV#tab_visualiser_div INPUT { padding: 0; border: 1px solid; margin: 0; text-align: center; } DIV#tab_visualiser_div INPUT:hover { background: #F0F0C0; } DIV#tab_visualiser_div TABLE { padding: 0; border: 0 hidden; margin: 0; } DIV#tab_visualiser_div DIV.center { text-align: center; } DIV#tab_visualiser_div TABLE TD { padding: 0; border: 0; margin: 0; } DIV#tab_visualiser_div INPUT { padding: 0; border: 1px solid; margin: 0; } /*-------*/ /* Popup */ /*-------*/ DIV.popup { font-family: monospace; font-size: 10px; } routino-3.0/web/www/routino/maplayout.css 644 233 144 3634 12270724606 14064 0/* // Routino map layout web page style sheet. // // Part of the Routino routing software. // // This file Copyright 2008-2014 Andrew M. Bishop // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . */ /*----------------------------------*/ /* Body HTML formatting */ /*----------------------------------*/ BODY { /* fonts and text styles */ font-family: sans-serif; font-size: 12px; /* colours */ background-color: white; color: black; } /*------------*/ /* Left panel */ /*------------*/ DIV.left_panel { width: 23em; position: absolute; top: 0; bottom: 0; right: auto; left: 0; padding: 3px; } /*-------------*/ /* Right panel */ /*-------------*/ DIV.right_panel { position: fixed; top: 0; bottom: 0; right: 0; left: 23.5em; } DIV.map { position: absolute; top: 0; bottom: 1.5em; right: 0; left: 0; border: 3px solid; text-align: center; } DIV.attribution { position: absolute; top: auto; bottom: 0; right: 0; left: 0; margin: 0px; border: 0px; padding: 0px; text-align: center; white-space: nowrap; overflow: hidden; } /*-----------------------------*/ /* Leaflet base layer selector */ /*-----------------------------*/ FORM.leaflet-control-layers-list { text-align: left; } routino-3.0/web/www/routino/router.html 777 233 144 0 12573351577 16274 2router.html.enroutino-3.0/web/www/routino/router.html.fr 644 233 144 76771 12573351570 14211 0 Routino : Calculateur d'itinéraire pour OpenStreetMap
Options Résultats Données
Itinéraires pour Openstreetmap Routino Cette page web permet de calculer des itinéraires à l'aide des données collectées par OpenStreetMap. Sélectionner les points de départ et d'arrivée (cliquer sur les icones ci-dessous), sélectionner les préférences, puis rechercher un itinéraire.
+ - Etapes de l'itinéraire
+ - Mode de déplacement
À pied:
À cheval:
Fauteuil roulant:
Bicyclette:
Mobilette:
Moto:
Voiture:
Camionette:
Camion(15t):
Camion(10t):
+ - Préférences routières
+ - Limitations de vitesse
+ - Préférences des propriétés
+ - Autres Restrictions
Rechercher
+ - Aide
Aide simplifiée
Cliquer sur les icones de balises (ci-dessus) pour les placer sur la carte (droite). Puis les déplacer à la position choisie. Il sera sûrement plus facile de zoomer sur la carte avant de placer les balises. Autre solution, taper la latitude et la longitude dans les cases ci-dessus.

Selectionner le mode de déplacement, les types de voies autorisées, les limitations de vitesse, les propriétés des voies et les autres restrictions dans les options ci-dessus. Selectionner "Le plus court" ou "Le plus rapide" pour calculer l'itinéraire et le visualiser sur la carte.

Etapes
Cliquer sur les balises affichera ou supprimera leur apparition sur la carte. Quand un itinéraire est calculé, il affichera (le plus près possible pour le mode de déplacement sélectionné) chacune des étapes qui ont une balise sur la carte dans l'ordre défini.

Mode de déplacement
Selectionner un mode de déplacement restreindra l'itinéraire choisi aux voies sur lesquelles il est autorisé et définira les valeurs par défaut pour les autres paramètres.

Préferences des voies
La préférence de voies est définie par un pourcentage et des itinéraires sont choisis qui essaient de suivre les voies préferrées. Par exemple, si une voie "Primaire" a une préférence de "110%" et une voie "Secondaire" une préférence de "100%", alors cela signifie qu'un itinéraire sur une voie primaire peut être jusqu'à 10% plus long que sur une voie secondaire et être sélectionné.

Limites de vitesse
Les limites de vitesse choisies ici pour les differents types de voies s'appliquent si la voie n'a pas d'autre limite de vitesse définie ou si celle-ci est supérieure à celle choisie.

Préférences de propriétés
La préférence de propriété est définie par un pourcentage et des itinéraires sont choisis qui essaient de suivre les voies ayant cette propriété préférée. Par exemple, si une voie goudronnée a une préférence de "75%", alors cela signifie que une voie non goudronnée obtient automatiquement une préférence de "25%" ce qui fait que un itinéraire sur une voie goudronnée peut avoir 3 fois la longueur d'une non goudronnée et être sélectionnée.

Autres restrictions
Celles-ci permettent de touver un itinéraire qui respecte les limites définies pour le poids, la hauteur, la largeur ou la longueur. Il est également possible d'ignorer les restrictions de sens unique (e. pour la marche).

Routeur: Routino | Geo Data: | Tuiles:
routino-3.0/web/www/routino/icons/ 40755 233 144 0 12573351606 12432 5routino-3.0/web/www/routino/icons/limit-1.png 644 233 144 1031 12573351601 14416 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÎIDAT8Ë­”±j*Q†ÿsÀUÖB K!· ViÒZÙŠ…¾‚>€‘ô¾ƒ‡ØÒ*"`ÀÆÂ. ”¬»óÝbw¹zÕ¤ñ‡SÌœÿŸs朙’„÷É#‰JåÒçÞ¨×áæ&¥^çÞ&ù¾|®*U*É1TžÃ/†Cxy1V+øü„Õ*³‡CÃ/¤§œïr½DxÊeÑlÞ!}ÐíÂr™ f)‡Èì„å2¥ÛéƒfóŽrY†èõB¤wÆc€oÀØïa¿³«ðßŒÇ ½Óë…4yšÒ3ý>@L’@’](IÒ4=tœ˜~¤çâÍî à óyvâ™@fÆ 2ž1ŸCnî…4a4Hòž( E‹ÅâÈ)'ŒF M¼¤GµÛ’ääœáœÓt:U§ÓÑl6“$¥izHÈt™þÑ«V{È /ï‚™™œsº½½•™é߫ݖjµ/ïQèÌLƒÁ@­VKÛíV’÷x™9ű~ÂÙ["Ž%3çµÙ¼*Š$ÉtAT­VU*•Î’é¢HÚl^üÍëõšÝnwºñßoþZgq¡Î~퀓¢½ØWíÍ«N«Î³+Nڿ樄/¨è™IEND®B`‚routino-3.0/web/www/routino/icons/limit-0.6.png 644 233 144 1302 12573351603 14564 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“wIDAT8Ë­”=K+A†ßÝ"‰ËE"–¯…VšZÔÚFRh$þ+ƒé,¬mìñ7X(b!ä¦P ‰ âÎÇs‹ÝÍ5xoçÀÀ™™3ïÌœyÎ’D†H!’(•~!wLMÁô´cj ‚àé8[R˜íÊ…J¥)`{»„tH½ÓlÂÙ™çù†Cx~NÇÍ&DÑ;Òaædû% …bQT«sH¿ÙÜ„n×ï_[:¶t»ŽÍM~S­ÎQ,ŠB!³³¢^îÙßø<Æ€1àýßžÏ>Ùßéžz=bv6{¦Ôbk ÁZ\’`ŒÁ{?v1çÆ\’€µ©ÿÖH­ó´ÛEoH‹B:foÀú$ ÝnsttÄÃÃÃèFN‡V«ÅÍÍM*˜ú[öö@:Ò5§§xpý~Ÿååe–––XXX`80 XYYaccƒÕÕUÓƒÀqz Òu¨ÉÉšÖ×å¤P’...T,u{{«r¹¬óósIÒåå¥:Ž*•ŠÖÖÖT©T$Ij}]šœ¬… CT((oÆÅq,I*—Ëúøø$YkGB'''ººº’$yI*¤0$”÷’DA&V­Võòò¢^¯§§§'ÍÏÏË£(ŠDZvww533£^¯§z%‰ä}0Šà2†h4ÄqÌÁÁÃáZ­Æëë+Fƒ‰‰ vvv0Æ€si¬³˜ýf.æœc0àœÙÞ{¬µôû}lŠEðØo~ã,GÁ97ÆÙhÞûÿrö-øn.4fg>ß3àGsóG«ÆÖ³¬´›ˆžÏ+ÁIEND®B`‚routino-3.0/web/www/routino/icons/limit-13.png 644 233 144 1240 12573351601 14503 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“UIDAT8Ë­”±J#Q†¿%†]‰"Ân°Ù+[±0¶vú>õ¦÷ ,â X¥±r]XdÁ%•…`a0°(ÉÌÜo‹IÖ°d·òÀ-νç?çþ÷þç `ÇB,`µúI81о;?¯>ÎÏk}N†çñ‡ŒU«‘ÙhT…/&É/´Õ ><èÓ“><”þÁ&É/áË0>âÁJ%vf×Ö> ?ÝÞÖûûBÍ ¡pÜJ?÷þ¾p{[á§kk™ÁJ%ÆåeÜÙI„©öÕ`–i–iok´§Aí{t¤ðÃÄåå!Mhº»«:0Ï5ÏUÍóÜ¢(/W…Y–•þ[ÌÀÝ]…æèÍê&IÏ»»²âX¢Â]ø‹mвHðîN“¤'ÔN<>fuu•N§C¿ß‡R›%nsÒôsLK¥Â¸…h4¬¯¯óôôD­VcŸÓÓSºÝ.išEQ ¨T Ž !b0`’eYÆââ"———lllÐjµ˜åæææOQ!Šéõ¾ÑnF‡C›››ãåå…­­-–––XXX ^¯Óh4˜*oh·¡×û6ñ7Göüüìë뫪Y–ùøøh63á7'êìo]‹÷:ûgLk©ètÀ»öæ»Nwgï8i¿AfR»ÔöIEND®B`‚routino-3.0/web/www/routino/icons/marker-50-grey.png 644 233 144 2702 12573351600 15616 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“wIDATHÇu•OhTYÆ¿{î}õ^^ZÒ±&X* IHhâ,Kl´ãfHÑÛ….f½éš ÕP™Í:ÛÁÍ„¨hf£‰ k2CbtÇ$&¦Ð –˜T Ë”úþÜ{fÑ©ê¨=\x.çþÎùîÙlë"¥²Ù¬Éår_1óŸƒ èò<ü"¶m[X–õ_!ÄÙlöV.—£0 À€X7•̬™ù ˲Îù¾ÿMFE"‘51XXX@¥Ra˲D$ ‚à{!Ä’BÐ 1³°S)•¯Õj;c±XxèÐ!J¥R¶m|*Ïó0;;Ëù|^¯¬¬|ãºîoµÖ‡˜ù™‚äþýû@«Rêß¾ïïL&“Á‰'¬]»v )%˜ù³¥”B<T.—ƒ×¯_Ç,Ëú1æ3¿‘===ð×wïÞH&“ÁéÓ§-Û¶¡µ†¿ $¢Æž™¡µ†ëºèêê’ÏŸ?cŽãlmjjúù¾ÿµïû߯b1Ó××gÕM”R ¢Æª› !@DPJÁèëë³b±˜ñ}ÿ[ß÷¿–™Læïžçµ=z”“ɤ€·oߢP(`yyKKKXYYÁ–-[@DX^^F¡P@†ˆF£Š•R<77',ËjSavG£QN§ÓT¯d~~W®\A4…çy°mgΜÁ³gÏpñâE8Žƒµµ5d2>|N§illŒkµZ·ò<;::¨©© ZkH)Q,ÑÑÑ“'OBkH$"B>ŸÇŽ;pêÔ)ܿ׮]Cww76oÞ ×u‘H$ă ýÜúhd˜…BgÏžÅùóçñøñccðâÅ tvvÚÛÛ¡”B©Tú¨™ˆ¤”¦Z­"H)ZkìÙ³ýýýhiiÁàà Êå2¤”ˆD" °ž$@­VrG?}úÔÌÌÌ4õööâØ±chooG?ˆ¥R ÍÍÍxÿþ= ‚Æ”@±XD±XdÇq4øI)E·nÝ «Õ*´Ö¸páîÞ½ xøð!´ÖH&“ضm¦§§SSSPJ!‘H€™122¢ÅÏú›<~üøÄ‡ÚªÕêžÅÅŰ»»›‚ ÀÍ›7qûömÌÏÏcß¾}H¥RˆÅb˜œœÄ;wðäÉd2ìÞ½ÃÃæP(HÇqf‚ èð˲&ÖÖÖv×)v5!Éé˜b晹f¸ïA@À8Ž…XÀöö?„E£¨fw·öôdvwkÕ„Åæ;BÜìC®ÚÛ#!rb¢]xj¡ðÍÙY}ý:X¯ëׯZ¯7âÙY-¾ O›õQ³ÌåbÛÚp``Høl¥¢{{™šBæÖˆS÷ö2+…Ï ÙÖ†¹\Œ}}X­„O.,¨^ªÁ$Ñ$ѾûuNƒzé‚Â'«Õ‚}}Í1á™ããªW¦©éå¥Yª&IrãªY&†««Fýø¸Â³ëÝ·P8v{[5¤——†&ÐÏB¸y ijÐàö¶ ÇÂý–¿áž<ù“Ç3“$Žs9ÖÖÖP)‹¼zõŠÕÕU677)—Ëìîî²²²BßÝ»»»#K¥,úò%ÏÆF †++ª™Yæ‹/lmmõåË—&Iboo¯ÕjÕééikµš£££–Ëe‡‡‡ý÷à 1ùóç 1]]xô JE”J%òù<ëë뜞ž’¦)SSSlmmP«Õèììäí»w¾‡¡«ëALK.@‰‰ FFF899¡T*199I¥Ra~~ž7oÞÐßß@gg'gggxçı1!D\]ñ£©ÄqL½^gpp™™zzzÈçó°³³Ãîî.Ã÷î¥)„Åäý{€@ttt R.—Y^^¦X,244ÄÒÒƒƒƒ”ËeÆÆÆø«±žÐòáDXtnN5mÒ££#ÏÏÏU½¸¸pß,kˆ!Ë2q£>unNañž™¦¿åU–e†¾ƒ&É/<û­ÂÿÞä’Äæ§?)àVµy«WãVïÙ-^Úÿ„fJ×õˆßÚIEND®B`‚routino-3.0/web/www/routino/icons/limit-6.png 644 233 144 1112 12573351601 14423 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÿIDAT8Ë­”¿N*QÆ¿=ÅBŽ&ƒ¡$ñV–Ö©m6v&€ÇžÚ†Îð (¤°0Aƒ … …‰ì9çgÁ.•knÁ$[Ìž™oþ|3#$! c ’Aùü¤QôH±GGžb¢èi¾ ɤ~BP>!E\^æ‘n°öƒNîîó9,0Ÿ¯ôN¬ý@ºIí£Ô_"Ž ¹œ¨TNži4`6ó€#Ϧ¬tÇlæi4@z¦R9!—qlD¹,šM‹ôD¯ð ’’Bøþ²€Oz=žh6-årZ¦Ô§ÕXâ8·NÆ{O’$x¿‘ä·Í’V ¤~Ö³S¬}g2YEÜ !BØÒ·!0™€µïH§BÐí¸´„-ÇétJ¿ßg<ÿ\Ù;º]Bz`8ðYV™Ãb± Z­rqqA­Vãååe]úFvžá¤£BáLõº$#IòÞK’îïï5NU*•t~~®R©$IŠ¢H’”ÚÕëR¡pfd ŠcíçÜèööV£ÑH’BØ6ŒcÉŒBˆ´\n½e‘upp v»­ããc½¾¾J’€m°åR !ÚÙ³M¹ººÂZËõõ5IJК„¿zöO6¿'Àñöö†Ûh›¿ÎYÆœ÷þ¿æì× ø1[¿nÀ^ws¯Wc¯÷l—ö oω hµÐIEND®B`‚routino-3.0/web/www/routino/icons/limit-1.3.png 644 233 144 1263 12573351603 14570 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“hIDAT8Ë­”½J$]†Ÿn—VÛ`Äv ÷ÔÌP S3½ïÀt'70 æ"&1r]Ø@pAdeÅéÓçù‚žñ[uC_hº«ê­êªsª Ó4R'&¾G&ÉOëuž.­×5I~ GC;B:ôCF&&!±Ñ˜¾™çÜÛÓv;z{«¿ëím%ïíižÿ¾ ùÉÐ̲Ôñq\Zú,ürsSonJ5céߨäàÍM鿦Â/—–>;>ŽY–âì,nmåÂ¥ªÏj´(´(4ÆÿŸ‘N£úìÁÂ¥[[¹³³Ã2¡éö¶êÀ¢Ð²4„`Y¾N¬,K‹¢° 4„Š¿½­ÐÙŠyÞ÷êªúc†Œ1¾©ð\‹^]iž÷…„#÷÷UƒEñâÔét¼¾¾~ÉHõòòÒf³éùùyp0¨üö÷޾Ûj©–ÃóðôôÔ,ËlUzU»Ý®ÓÓÓîì츰°àÙÙ™U$K[-…վ²¾26FŒ‘$I˜™™!ÆÈEQpxxÈÜÜÝn—ççç‘)e}jµ¯ŸHSɲdd‰1Òh48>>æññ€ËËË,..²»»ËÃõZ € Ë MM‰1a0à-Fôz=NNNX]]¥Ýn355ÅÅÅEÅ Æ$¥ßÿA§Séÿ*+Ïs&''ØØØ`mmùùyêõ:+++4 Æ Òé@¿ÿãÝmŽÐëõ|zzRõþþÞ£!ïîî,F¼êýê6ßõÙ¿c|i‘²,£IxÓg¯' }Ӵヌœ÷ð¡³ù¡[ãC÷ÙnÚÿUúf[³8IEND®B`‚routino-3.0/web/www/routino/icons/limit-15.2.png 644 233 144 1462 12573351604 14656 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“çIDAT8Ë­”±K›kÆŸïSLü4%©B4Á^ ÍPpëP‘*(JÛ)±ƒíæà?páŽíæàæ$¹½h¥tl¯.¼Ö Ú¡´4ù¾÷ýÝ!‰mé½›œáœ÷œ‡óžs„$$áº.’‹$ÂáßæqœD£pó¦!Çù€4_’[¯j…Ã’ÃãÇa¤çx^™éixõÊR,ÂÉ ‹5z<¯Œô¼žïÔë%ZZ\B!‘LÞB:dl òyXkø5? Ÿ7ŒtH2y‹PH´´¸"ããÒGfg*€Å÷Á÷ÁÚïÖˆ*Ì΂ô‘ñqx¼þMéTƒJS+À÷ý+³Ö^5hªUüJU>éEcf·ñ¼3 ÀÚ:ÑÿÁZ[#6 Ö€ç!Ýnú]úCOžÜcrÒ¸’û÷æ¦Åb1-//kccC»»»êëëS(’ã8ÚÛÛÓŸ/_ª=râwîòùVg{»IHÛd³æ¯l–ææf–––ð}ŸÎÎN&&&H§ÓËåˆD" ’ìéáŸOŸ ¯_HÛ®nܸ«û÷e%×ijRGG‡Z[[•Ëåt~~.@£££J$’¤££#ÍÌÌh}}]푈v67]=x ÚÚîŠXÌðå I ÍfÙßß'“ɰ°°@WW«««WsÛÚÚ"•J1™É`¾~ÅF£Æ•µŽªU5Èu]‹EõööjjjJÝÝÝ* ò}_¹\NCCCJ§Óš››“•¤JE޵ޫ³³½{'©ook T*¥ÅÅEÅb1õ÷÷kddDÃÃÃZ[[“$­¬¬¨'‘Л·o­Þ¿WðíÛŽæyú ÀNOO¹¸¸àòò’R©„1k-'''”ËeJ¥…BãÏŸ¹€€gϰÒüwÔ”?ë ®È~‚1µütöËXßç¿>€õýšý²׺›×z5®õž]ã¥ý¯•r¬¯´i0IEND®B`‚routino-3.0/web/www/routino/icons/limit-10.5.png 644 233 144 1471 12573351604 14654 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“îIDAT8Ë­”ÍK›Y‡Ÿ÷$™HÒ$R’•’Ž 6`ÆU™Eq×Í¥]»ÐíÿY¶{ÿI-…¸fÕi™‚‹"uº(˜ÄÏ€JËÛ÷ãÞß,’XgºõÀ…sù—çëºW€’ÉËrœÊf¥|Þ(›•ç£`¹wŽÀíéýDɤ#p47—O«Õ¢ÑhP(Èår„aH³Ùä¯7oøgsÓùéÁ“h·Ðû÷1›ZY‘$óbeEZ]]UE×ÄÄ„ÆÆÆÔét$I*‹š™™Ñ£z]_¿½|)›.™Ì]îßÇ‚ëÄb ‘N§Y__'‘H°µµE:fmm € ...įÕ*ÅDÂÕ½{¸7nÜu‰ÅD<Žæj5Êå2žça­epp€t:çyär9êõ:Õj•ßž>åÏׯqnÞÄHr±Ö!è›$‚ `xx˜ÃÃCöööØÙÙattß÷Ùßß§T*1??O±Xäøø¬EÆ8.ççxûÀd2<Ï£R©099I¹\¦V«Q©T˜šš¢T*Ñh4Èe³ü|çêuK³IìË—–µ¸(I‘ŒÑÙÙ™<Ï»äìôôTÆctrr"Iò}_GGG2AÐÕ-.J°ü³íí.7QtÉ–é²$cÌ÷Ì##Y{…³ï:À†¡ú ûâÿû6ŠÔƒ;Ðì앸ÖÞ¼Ö©q­óì'í¿ÀfT·1÷ÞþIEND®B`‚routino-3.0/web/www/routino/icons/limit-38.5.png 644 233 144 1517 12573351606 14671 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”ÍK›YÆŸ÷­$™×6‘(&~€Åâªà¦˜±ÐÅ ‹ J,*Ž .t;Å@Æe‹[Wn ¶”~ÿ`bJi¡ƒU\dL‚ÐjA“÷½÷7 «Ã,½páœsÏóÜs/Ï9B’p]ÉE‘ÈH8ÎZZ 7´´€ã|@Ú¨Ÿ É­ã„D‘ˆƒäðøqé)ž÷¥%xûÖR,Âñ1‹þÒxÞ7¤§õ|§Ž—…\ÂaÑÓÓô™t `­áêºð é4HŸééé'¡+ 1>î!}be  X||¬ý¾1°@••>1>î‘HÔŸ)=#“Á@ͯV1µÆ|ßǘëúÕ*~­†52ž5þìž÷Õ\ÜXþ—ÀZ{ͯçYÀó¾"Ý»µ*­±°0ìÌÏ›¿>~tŸom) ©««KûûûÚÚÚR4U"‘$ù¾¯l6«?¶·õg>ïÜ5ábñÞ¿¿%#åy÷Ž¿M<#“É000Àêê*½½½ÌÌÌÐÝÝM.— X,’L&™˜˜`vzšÎÏ ¯_c¤¼«;wîëáC_¾¸¿¯­ijjJ:;;“çySgg§NOO%I{{{:99 _Òi%Ãa—äÆb÷›Ü¦&d­3Ð߯îùyý:7§J¥"ß÷ÕÖÖ¦ÍÍM•Ëeµ··K’âñ¸¦§§•J¥ôÛ“'Š%M¥d7¨Õݾ­oÞè§TJÙlV­­­Z__×ÈȈ¶··ÕÜܬÝÝ]* êëëÓ‚’ɤÊå²d­0Æ‘•ò¼zÅ ˜Ÿ="2;;K.—chhˆx<Îââ"…Bááavvv¤%c~nŽ /_b¥¼6X^üósJ¥þ…0©V«ÖZ*•Êe¼T*5ô°¼ ÒÆ5™ºÎ¬µ— Í5lÛ°Á€µWtö½&'jÖ÷!þW¬—„A€½¨¾Æä䕸Ñ޼ѩq£óì'í¿,\i—©a IEND®B`‚routino-3.0/web/www/routino/icons/limit-8.1.png 644 233 144 1266 12573351604 14601 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“kIDAT8Ë­”1K[QÇïOyJ‰ "íTœ:ˆ£ƒ Nâ`6gý~Œdws (ô88d H T(Xpq‘ VmòÞ»¿/IMÛÑw8÷žóçž{ç `ÇB,àÔÔáÈ(úê쬾{W8;«QôU8œ#㚦]¯®ÊB²Ì0VYù¥XðêJÓ´+|D8òà@5ý¾ªívÛZ­æåååHp(Òl6½¾¾.÷ËøÜƒ…#„/6æZ¨žY©TÜÛÛsiiÉ‹‹‹‘àÉɉI’Øh4TÍ~ýR-l4¾ÄÌÌ|b} (Š‚4MÙÚÚbqq‘§§'ò<'Š"*• !ˆã2o}ff>Åı$ Cët:ÌÏÏs||Ìýý=sss¨T«UVVVx~~fÌ’âØ˜"úý’`àôô”ÕÕUÎÏÏ™žž¦ÕjÑívÉóàÏ­^[¿!D1Ýn›f“@½^§ÕjQ©TX[[css“ HÓ”‰‰ ÊfºÝöØo€´×ëyww7B¡Ó錘{xxðåå¥Ä£ŒûÍ1Ί,aPÅgÑû_Îþé_Ãù¸!‡1ÿvÀ›öæ›N7go8i“jà“9IEND®B`‚routino-3.0/web/www/routino/icons/limit-145.png 644 233 144 1351 12573351602 14575 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“žIDAT8Ë­”½K\AÅÏñ¹¼Æ%( "B¶Ù”ñ0XŠ. ®…‚°¶‚à?‘”‚ ˆÕ ")%¤\lD$E` e1?#Qß×Ì/Å~¸&)½0Å™sçνç\! Ic ’ÈdrHkxÞ7²YxóÆ’Í‚ç}CZkœ É4pBÍ@™Œ‡äQ,f>¿)•àógÇù9\_ÃùyÝ/• ~#}lÜ÷x ß7tu‰¡¡·HÇ pvfç,íV÷SÎÎ,…HÇ ½¥«Kø¾}}br2@úÎò2@8’’œ{^Í=p@Äò2Hß™œ èëk|SúÄô4@Lš’FÖ¹VBÖZÒ4 I’0$‰cÄLOƒô©Y³wÁ/ªU—F®-sî…ßöB=Ãj‚àÒ;!­±¸º8 R©prrÒÂU«U*• ;;;¬®®²¾¾ÎýÍMW*´&¤C¶¶,Ö²½½ïû”Ëe¢("—Ë166F†ôöö255Åìì,?j5ëÊeº»ßkdD’Œyž§žž’¤••=>>jppPº¿¿ ‰‰ õ Éx>HÝÝïŒA¾/IrΩX,*ŸÏ«³³S»»»*—ËÕþþ¾NOO577§ññq---éë—/ò$ÙŽÉŒœóÇj7眬µ2ÆhxxXGGGªÕjÚÛÛS>Ÿ×‚úûûõóò²ˆcÉ9ïEÍ’0 P(°¹¹ÙjÀÆÆ333\]]‘ËåÈf³ÌÏÏ“FQ½f[[ ¾èfƒÜÝÝñôôÔâØÃ÷··„aÈÅÅÖÚ&S[Ý|Á3äüŸµsÎÖIûÏþQ€ûOÀf¸gYý¥€WÕæ«NWg¯8iÿZ•Á>¢zIEND®B`‚routino-3.0/web/www/routino/icons/marker-64-grey.png 644 233 144 2633 12573351601 15627 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“PIDATHÇm•AhTIÆ¿U½¼×Ýxx6QlÄFiÒim Œ‚H :"ºL„Åç²9ìö²»,spè/{YAö*“HÖIÚ>ÌÛì’ èÒÆ$„¶eÈnÇV»“Ævû½zU5“7ÑøAAßûׯ¾ú?*‹ØB X,êR©ô¹1æ¯Rʾï„_dlÛ&˲þCDß‹ÅJ¥ Ã4Ц)7Æ(cÌ^˲nAð•”Ò¸®KétŒ±ÈQk••´ÛmcYõõõJ)ÿ@D/‰ˆP3Æ(…^·Û=˜L&ÃsçαÁÁA²mË÷}ÌÏÏÏóÔ›7o¾ŠÇã§”RçŒ1?ãgΜ1ö !þÁÁL&#¯_¿n:tˆ8ç0ÆìB¤R)`ÍfS¾~ý:iYÖ¯´Öÿ0Ælð‹/Àßß½{WÈd2rddÄrZë¨2ƈ( ”B,ÃÐÐ_^^–kkkIÇqúc±Ø÷,‚/‚ ø:™Lêááak‹çŒ10Æ`ŒÙ@͇‡‡­d2©ƒ ø:‚/˜1æ;)% …\×…R œs´Z-]»v! CpηSSSŠÞë¿víÚl¯×;¼±±‘o6›á‰'X?¦§§áyjµNŸ>S§NáÈ‘#8vì²Ù,*• ._¾Œl6‹‰‰ ]«Õ¸ã8sRÊ_ó|>­õŽã 7Ýaê¡¡!ÊårØ·o_„aë‰niïÞ½Èd2¨Õj¦\.³x<þ­õ"úŸ`Œ ÿÕZÿ&ÿsvvÖìß¿¹\®ëFŒ·?QÎ9òù<:&''CÛ¶-"ú–ˆ `Ñ4cìDħ¦¦d»ÝEÿ”ÊårØn·­¾¾¾±l6û7 @¸Õ(%±“'OÞ²m{¬Ýn[÷ïß·Çe{?%"|ø0)¥¢ÆÂëW¯0>>n,Ë"¿%¢GD$(`¥R)*‚1&c«Zë‘x<Ž™™3??ÎyT¡”£££aŒs~‹ˆÆX›Q*•À¶&›ÚÁwrrR®¯¯GyôÅ×¶í/›Ífr}}Ý<}úTu»]nYÖŸŒc"ŽÛŠÂެlûe ¡1æ,clÚ÷}%„àBoppðó……¦”Ò~püO`Øâû/cÌ7ŽãpÎùªRêwÕj5꽟ÒÏy³à‹TSÏIEND®B`‚routino-3.0/web/www/routino/icons/limit-22.0.png 644 233 144 1526 12573351605 14654 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ IDAT8Ë­”=H\Y†ß{]ÉÍ5£pí†üÁFdüí¶QIa“A0©MLºEÜÂraA„¤ÛBÐÊ"É ¤¦Ò*X¬ÜfIÂÄnÔÁ•C¢˜¹sΓÂqW­ýàÀùÎ9ïÇ9‡çý„$$áº.’‹$âñ›Hs8Î{ ¸vÍH€ã¼Gš«ï É­ë„N Åã’Ãq¤§xÞðê•¥P€R …ã|b<ïéiý¼S×K45¹Äb"™¼ô™tòyÔ°Öp:Žóù¼!é3Éä b1ÑÔäŠ ##ÒG¦¦*€%Š ŠÀÚÿÇÉX ÂÔHñ‚ú3¥gŒŽb U*˜jc QaÌÙ šj•¨RÁB•ÑQžüÙ<ï«Íå°`© O°Öb­=;7 Öærày_‘î4ü.ýÁ£G¿8šÞ½s_.-Éó<µ··kssS™LF¾ï+c亮¶¶¶ô2“QÐÚê´Ü¾mÈç/9aØ šòú5mm™fÏcppŽŽæçç ‚€¡¡!’É$a°··Gww7]]]ü|ë`XZÂH¡+ßïÑÝ»Êúäþ:9©ÕÕU% e³YMOOkeeE¾ï+ CIR6›U,ÓÆÆ†š¯^U6“q•NË^¾ÜóSCc#öèȽwOí--J¥RêééÑââ¢ÖÖÖ”J¥Ôß߯±±1I ß÷%IÍW®è{¹,Åb’ë"ãû–/_øûÃ.ÅãÌÌÌ`Œa}}Ïó˜åððr¹L±Xdyy™ÎÎNòù<7¯_gõí[øöšï[U¥7oøóùsÓèºôõõ‘L&¦­­ÞÞ^Z[[YXX```€b±Èøø8¾ïóÛä$€áÅ ¬ iŽ'OøµwvØÙÙ¡P(pppÀþþ>ÛÛÛìîîR.—)•Jc0ÆP,1• @ÇAšû3r¹c²Ïz>¬µÇ ƒ9ÇÙX¨Ú(ÂFö § VÃÛªÊýû§p¡Þ¼Ð®q¡ýì;íéJtiÈwaëIEND®B`‚routino-3.0/web/www/routino/icons/limit-8.png 644 233 144 1141 12573351601 14427 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”¿J+AÆ¿™b¦I`À&à­,Sh›JÐ&¤ˆ¥mòyŒØ§³L!ø‚O "*ˆ±LD´THvg~·Ø]M®ÞTù`aΞïœ9gÎ! IXk‘,’(ÿ 0æ–rÖÖ<å2s‹4ÈôB²™Pî¨X4H†ƒƒ"RçÞétàô40™Àë+L&©Üé€sïHýŒo2{‰(² ¢VÛDz¤Ù„ñØ !xæ‘Ê ã±§Ùé‘Zm“BAD‘ÕªhµÒ=½ÀÄ1Ä1„ðýåÿ Sz=îiµÕj–¦tD» 0#I I¾‚ñÞÇ1ÞÏùÍ™Ñnƒt”¿Ùν1¥7Î9 !BXB`4çÞ¶„4 ÛH² ¯¯¯é÷ûÜÝÝýt˜òº]VÒŽ I22F’ä½—1FgggÚÝÝÕÍÍö÷÷uyy)cŒB’¤Œo2û«R©ž VÖjÞ{9ç´··§ }~~J’€”ò­ ©Tª[Y‹¢H¿áååEëëë:>>Öóó³*•JY$F‘d-V!Íf ºüæ““mooëüü\Î9]\\HÒwš9f3)#¤+†CŸW2oƒ‡‡êõ:•J…ÃÃC>>>‹ò=Ã!HWÿ­fŽétÊÓÓñ/º«¹´Ï¼÷_QÌŸ—õÙÒ øÑ[K'`¥³¹Ò­±Ò}¶ÂMûœ]áô¶´IEND®B`‚routino-3.0/web/www/routino/icons/limit-14.8.png 644 233 144 1374 12573351604 14665 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“±IDAT8Ë­”¿K[mÇ¿÷¦^Ã¥i‚ÒAèë`Ç q-§ D »Æ?@ðŸHw·8]i‡B‡V1ô…‚¡YD …*ææÞó|:$¹¯•Žx†sžç{žóã{Ž„$|ßGò‘D>ÿ/Òž÷•‰ xúÔ˜˜ÏûŠ´5¼’?Ä åó’Çêj©Nþ¢Vƒ——ðã\^ôZ ÂðR}øÞâ%‚Àg|\ÌÌ.‚ÀSSby9DúÆÆ@ 8’’œûÿŒlà€˜ ¾±¼255LSzÇÊ @?clÀÌHÓô­ß'‰c úT« ½Õìaø“V‹œ»ãÈ9‡sî^¦C›Ù@=;ƒ0ü‰ôBH[¬¯ã 8<<¤ÝngàV«ÅÁÁA%Àéé)õzÿšM€ÔÕj m é„û°³CDQ@ÇÌÎβ¸¸˜9ßÛÛ£X,²¶¶Æô³g|þþÝøô‰T:ñõäÉK½z%'ù^.§b±(@’´¹¹©^¯§B¡ ‘˜™Â0ÔÒÒ’þ™žÖm§ã«\–?~é+—CA 'iõõkÍÍÍillL»»»Š¢HårYÇÇÇj·Û’¤N§£ÉÉI5 ]__«X(H¾//—×sžúýìgçœÌL¾ïk~~^ÍfSj6›23EQ¤……íïï+ C}þòEzôH.M½¬f @¥Ra{{;«Q£Ñ Z­âœ£T*qttD©T¢P(ðöÍnÀxÿ'dÝRÌèv»ÜÞÞfÝ»¹¹¡Ûíbft:œsÄqÌÕÕI¯7À­¯gÝðììlÀì{½/f–ñÌþ³?&À% ÷Žˆ›8M’»ÏÊÊ xÐÙ|Эñ ûì7íoÓA‘MX¿OIEND®B`‚routino-3.0/web/www/routino/icons/marker-27-grey.png 644 233 144 2674 12573351600 15632 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“qIDATHÇm•ßk“YÇ¿çWÞ7o/¸ ÅÔÐVŒ!$[¨s#PP[p±àÜLÁYaov–a†Ì ao¶ÁÞZT¥X ÒÝ¡Kq´¶u¨] ÙʤšÄ@2¾ïyÏ9saû]¿pàœ›ïyžÏóœçB¡€ QÎ9 …‚.‹GŒ1—RþÑó<€à½ŒeYDñˆò]¡PøW±X¤A€²aÊŒ1Êó!ĸïû£RJÇI"‘¥4tÔZcuuFÃ!H$™Rþ•ò+!„P5Æ({9çåv»½×uÝàðáÃ4N˲ð±<ÏÃòò²)—Ëêõë×£Žã|¦”:lŒù/!„²C‡=œóŸ|ßßÛ××'Ïž=+’É$aŒÁó‹sŽ]»v‘T*Ekµš|õê•+„øBk}Ýó†Æb1!.v:Þd2)ÇÆÆÄöíÛ¡”‚1ælJ?@`ŒAضmÆÆÆD2™”N§Wq1‹ú¾Ì÷ý/]×Õ###b“c,4ûØœR Î9yW¿‘‘Ắö}ÿKß÷qcÌRJäóyÄãq(¥ÀC­VCµZÅ–-[Ð××c *• ‚ ÍŒ1ؽ{7\×E>ŸÇ7 „ø‘A0ÇM&“¡ÀÃÒÒ&&&°uëV´Z-d2 cjj ívœs@½^ǹsçàº.Òé45ív{ˆ{žgR©F£0Æ€‚ééiär9œ>}kkkG6›Å… Ðétà8&''ÑjµN§¡µF,C"‘ ?Öôª÷EPJ!Nchh›‘Û¶Êq<{ö +++8uêTˆa“9ÊcºÕjQ)%„ ”âĉPJa~~333ÈårØ·o_˜ÉÌÌ 2™ vìØ­uxa»Ý¥TsÛ¶Õ‹/°¸¸HAA½^Ç¥K—àyNž<‰l6V*¬¯¯ctt4Œ’RŠ••<þÜØ¶­(€8ç´\.FpõêUh­qþüyär9H)¡”îÜ蜜s !è¿p®|,%IS0}„O,-}`aÁãœUa­eï=…B€4MÙÞÞfoo££#ÞŽŒ‹c£Rɛ߿ûøö-²À{&& €1†­­-&''9<<¤‹ËËKVWWÙÝÝ¥^¯s{{ ¦CÉøï-ýýï2ÇE„0ÆP*•!ô’p}}$¦¦¦(—ËÈ{ X&& ¿ÿÅZÇ=RZ­ÆØØwww½ýb±ÈÜÜÕj•µµ5vvv0Q„ˆc°V– í6OÑ}!Àéé)Fƒ¡¡!)—ËœŸŸÓ=í6„`,Íæwêu€À£²’$¡¯¯ILOOS©TØÜܤP(0>>Îüü~IEND®B`‚routino-3.0/web/www/routino/icons/limit-32.8.png 644 233 144 1517 12573351606 14666 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”ÏK[YÇ¿y…˜y‰£U!83tpᥳšEÑÅ7"š Û… ºü†QÜ´W‚›‚LÀRZºsçÆÝ`”´NWA%"6iˆÉ{÷~º0ZíÚî9ç~Ïýõý! I8Žƒä ‰Pè¤÷47CK‹¡¹÷H+õ¼œ:Nè²P(@ ðøqé9®û…©)xóÆrr…œœ\øSSàº_ž××êx‰`С¡AÄã÷‚\Î>֮ۅ†@: ¿GCƒŠáaé#óóUÀâyày`í·q T™Ÿé#ÃÃ.ÑhýšÒ FG1PóªUL­€1Ïó0ææM­†W­b Æè(H/.߬×ýl÷÷/v¬¯°Öb­½9¿È[»¿®û©çΟÒÏžýxúÔü÷ჳ–N«!TGG‡²Ù¬Ö×׉DFe­•ã8Êf³ú;Öáp ÚÛkÈå~d2wd¤ oßò¡`ZššH¥Rtww³¼¼L{{;ýýýÄãq¶··ØØØ ­­ññq:ÛÛùçðÐðî¾”qÔØøPÉÿôÉùkaAcccŠÅb:<<ÔÜÜœ677‰D´»»+IòŸçèèˆããcÊå2…Bk-Õj•|>w~à3= ÒÊ ž™:ÏŒ1W¼úÞ®rÆ`¾ãÙ7¤R5ëyàû7z°ø>öBV5R©k ¸UmÞj׸Õ~v‹ö+Áa“2¸cŠÿIEND®B`‚routino-3.0/web/www/routino/icons/limit-32.1.png 644 233 144 1472 12573351605 14656 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ïIDAT8Ë­”ÍK›YÆŸ÷µ“d^R¿ 4ÒÁBqc×Ó".\ŽŠMW¶ºü†qÙn!t–Ö…¦`ÿ¡L·&ØJ;â"¨U$kƒMî{ïo‰V‡Yzà.νç<÷|<çIHÂ÷}$IÄb¿ eñ¼´¶B{»¥µ<ïR¶ñ.$¿á't‹yHÅžߘš‚\α¿¥ìï×õ©)‚oHOö^Ã_"ñ‰FE:}é3CCP,Z Ä9Ëe©ë!Å¢eh¤Ï¤Ó·‰FE$â‹dRŒŒHŸ˜¨cÀpîÇ9¿T™é##Éd#Méb¡fªUl­€µc Ö^ 0$4 52ž×ì.Apâ¶¶ê?6/8çpÎ] qaX·ßÚ‚ 8AºÛô»4Ç“'¿zÛ¿?~ô_¾T4Q*•񮮠–——Ç•L&H’|ß×_ïßËV«^Û;–bñgo}½IVZçÍþ)•l{K ™L†žžæççéèè```€t:M>Ÿ¿ˆree…H$«ÅEk^¼iÝ×Í›÷Ô߯°\öÿ˜›ÓØØ˜:;;µ½½­™™­­­)«P(H’Œ1ò>Ž©©)H)Á¾ »wï1+.\¸ðm»Ý}÷îÝg[[[áØØçr9lnn‚ˆ°³³ƒv»v»R©„/^ T*¡ÝnCkT*…Û·o›b±(\×] ‚àç433ƒJ©oÆ&&&Ìää$7›M´ÖpNZëž\!”R(‹öÆäyÞ1?¶Ö%3K¯Œ1¿ð<ïŸ?¶CCC8~ü8¬µ=ïö>,Ýù>àÁƒ¡RJÑ HPDô 3ÿ–ˆÄ­[·‚Z­"‚1¦wqÝÖÅÝ»wÃjµªÇ™O¥RÀBÞ]ˆˆÇÇǯ8Ž3_¯×ÕÍ›7ÃnîîmÝ(Ÿ&Ü'ÿ6týý—µök×u…¢¬µþÕÊÊJ¯º>…ÿ¤¼Õ•`‘˜IEND®B`‚routino-3.0/web/www/routino/icons/marker-14-red.png 644 233 144 2032 12573351600 15416 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“ÏIDATHÇ••¿kTYÇ?÷¾{'f@‹ ¸È¼Ô­{'FC‚)ÅÊÅ–‚ÅJ¦Øvý 6Mš,¤P SØØ ÁU ÁERɌŲ !˜˜÷æÝïïN&™ìâîǹïïû~¿÷œó`öĉ`dddÎ{ÿâªÃÿ½÷oGFFæbží™¸&@üà½_êõz·$©V«™F£÷žÖZò<çõë×|ùòEÆãœkåy¾üuçà g“$éª×ëùÊÊJ±½½­‚GAÛÛÛZYY)êõz(æí+î3N“$ùhzz:k·Û’¤¢(”çù±«( IR»ÝÖôôt?i k-ιG€fgg³>X–ç ½žÔëi8Bʾ}SïÍÎÎf€œs¬µP©T¥iZt:IRžçRRdt,â~A;ŽÒ4-U*•œso-//GK}ÒË—}zGõì™Ôn+ïY^^."Û7all,lnn–¹’´¿/mmI33Òü|™uØŠÇ%ÖÖÊçCÐææ¦ÆÆÆ, F£ajµE–•5¶¾ðêœ:UeQ@’À»w°¸ Ò`€"˨Õj4 ÈÖ{€l¬†K—àÃh4`k«Ü«T`g®_‡…¨Vaw—Ãq¬B·Ûeooç’àäI8}FG!„AÖÝ»05¿ÿ^ŽŽFÂe}þü `­Í€buuupòy´nNº|¹üýþ½ä½tñ¢tíZéé¹sê=}*Iúc}]@0ÆdÖó+`T*Hœcøùþý0ÖÚUªÕ*ÞûDZøsIêíï—ìæç¥+W§ß/« T¬­I’~ºs§ˆ]õ'Pí»U÷ÞÔl6 IÊ$éÅ éùóA}æy ¾·§üáCéÓ'­=y"à®1f²è¢ÙW­µz­Vkàï?6TÙÝnWãããýÞoÆðÆœs‹€ÆÓ4kÇ–-²ì8hRºuófgkkbb‚$I&T<g'''ñÞ·Žø;4Púì—––ŠØ=˜N‡ÆC©÷¾sÄßȶ/{ccCÕjµ(ûÅÞ–=ßõ÷ëׯšššÊãðø-¾ç;qÄß4M³þH”¤f³Ù—½TïÝ»ƒÏҿǰ¿333¹$µZ-…µVƘ«ññ什Ãþ:ç:€nß¾.\¸Ð—ÝŒ²Ý<â/pÅ# >?þ<Î9ûüë/I’ÈZÛ~Rs,þÁÖE"û`}®IEND®B`‚routino-3.0/web/www/routino/icons/limit-146.png 644 233 144 1325 12573351602 14577 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ŠIDAT8Ë­”?K$AÅß4:.“(Ëz&‚x&^xF&«†š »æêünn¸¬`p¡™† +xÁ â©° *œf§»̸ºw†4TuWUwW½WB’0Æ $Q(L m?‚bÑ14Aði+?’Éã„^ R@µZ@Ú$Šþ°º ?~xÚm¸½…v;³WW!Šþ mæþA/††16ö©EÃÕ•,Þ;ÞKf[®®q R‹±±¯ ˆ04bdD,.FH¿X_HOšBš‚÷oëu<°¾Ò/#FFòoJ5*€Öb“ç}÷AÎ9¬µ]=}yÁu:™¥Ríµf߈¢ÎμMü»DÞû®ý^ÇZè©Yúò@ÇÔëõnêõ:q°´´DE,//“>?g5ÛÙ©ÙÓÍÜßßóœ9âœãññ‘»»»–››› wözºÙƒ³ÜáCñÞã\Æ0—¦âì?øöùVÿ0àS¹ù©SãSçÙ'NÚ¿öדÃ>+‹IEND®B`‚routino-3.0/web/www/routino/icons/limit-9.6.png 644 233 144 1325 12573351604 14603 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ŠIDAT8Ë­”1K+A…Ï.¸ÆUP 6BÀg£•©ƒZØ$¤ÐVD€¥?Á4VÖ6v‚@ …ˆ1¢!DEQÑÝ™ù^±Ÿyò:æÎœ{˜{ï¹WHB¾ï#ùH"“ù´ç14¿~Y††ÀóζÓw!ù©ŸP‡(“ñ<3H›„á ««°·çh6áþšÍÄ^]…0|AÚLñ^ê/>½½"ŸCºd~nn,`pÎòu%¶áæÆ2?Ò%ùü½½"|12"*•é‚õu€ÀÇÇàÜßݹ|°¾Ò•JÈÈH¦Tea ÂlÇ1ÖvÌZ›ÜG“à@ªvr6A>Q¯'Ä1î3*‡sîÛÀ%dŽzÂð iBHÛ¬­EÔj5¶¶¶¸ººÀ$Ž4 ªÕ*§§§ a‚7¬­´-¤vw±`ÎÏϧX,255E«Õ ÝnS,)—ËLOOs}}„–Ý]N| 4;+'ù’ttt¤\.§ÃÃCA ýý}IÒÁÁ†²Ù¬fff”Íf%IžäkvV,øò} “¤R©¤××W•ËeÕj5õôôH’Œ1ŸD;;;:>>–$9I É÷ñ圧(Rg½½½irrRsssV>ŸWEêïï×ÀÀ€VVV”Ëåt{{«ŽèE’sÞgÎ\š³ççgJ¥£££lllðøøH¡Pàáᥥ%úúúX^^&Žc°6ñKsÖUÍT¼¿¿sww‡sk-ívçÆZ­ÖguS|W5»uf 6ÕÓWÑvˆ¬sÿÕÙ·À˜nþ{N1ß;àG{óG§ÆÎ³œ´q¿… ut‘IEND®B`‚routino-3.0/web/www/routino/icons/marker-59-grey.png 644 233 144 2735 12573351601 15636 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“’IDATHÇu•Oh”ÛÆŸ÷ü™ïË'*ãhê¤Á42A3 Z2Åÿ’ Þˆ’…z!×E]´‹nÚR.HœÂl¤›º°Û.Õ¨XãB¦iIK &qbFSƒ Îd “Në÷çœÓ…™¹Qo8ðÎáá=¿÷9ç£T*…U1!R©”N§Ó_cþàûþ×u Â÷2–e‘”ò_Dô]*•zN§Y €VM¹1Fc~$¥¼ìyÞ7¾ï›p8LMMM`ŒÕµÖ˜››C©T2RJ …Bý¾ïÿšˆ DÄ(€c€f!Äp¥RiŽD"A{{;kmm%˲ð¹\×E&“1ÃÃÃjiiéÇq~¦”j7Æü›ˆ?xð Ð(„ø‡çyͱXÌïéé‘Û·o'Î9Œ1_ !(³ÅÅEÿíÛ·)e§Öú¯Æ˜ÿðŽŽøÓû÷ïÇb1ÿüùóÒ²,(¥@ô=JÆXmnŒR Žã`Ïž=üÕ«W~>ŸØ¶½¥®®n€yž÷µçyßF"ÝÝÝ-«&B0Æj£jFD`ŒA­5 »»[F"íyÞ·žç}Í9ò×u?nb±ÀÊÊ ²Ù,ŠÅ" …–––°iÓ&0ÆP,‘ÍfáyÂá0´ÖpB3==MRÊA[86‰D‚U+™™™ÁÍ›7‡áº.,ËÂ… ÉdpõêU¬_¿+++Ø·oNž< H$lddÄT*•6Ắ‰Ç㬮®J)pΑËåÇqîÜ9A€êÚ;w°ÿ~œ8q³³³èëëC2™D}}=ÇASS=yòD‹=`ŸDƃl6‹K—.Á¶mœ:u ;vì€ïû‡Ã€ 6À÷}äóyÔ××ך € ι.—ËÌ÷}Hù±OJ)ìÞ½{÷îÅøø8úúúpñâE:t˜E¡P€ëºŸ$¤R©€1¦™mÛêåË—zjj ºººpæÌìܹ§OŸ†/^¼@{{;:;;ADH&“ظqc­\.‡\.glÛV Àï…ìÁƒA¹\†R W®\ÁãÇSSS0Æ`Û¶mèïïÇòò2zzzÀƒ”ÍÍÍPJappPÑGý™Ÿ={vìÇ-åryw>ŸÚÚÚ˜ïû¸ÿ>>|ˆ™™8p‰DD„ÁÁAŒŒŒ`aaˆF£ÐÏŸ?ç¶mOù¾šz{{àÇRʱwïÞýäèÑ£º££ƒ-,, P( ¡¡[·n­¿X,âõë׈F£ˆF£˜œœ4×®]#Çqþ«µþ©1æ™`Œ ZëŸ;Žó·±±1ÓØØˆD"††QÍЃ-[¶`óæÍ "”Ëe ¡PHQ/= €€$¢ÆØoˆˆß»wÏ/•J "h­k®W¯çÐÐPP*•d(º¾k×®?`‚j@}"bÉdò²eY×K¥’¼}ûvP5ú<ÜsÅèè(ÇÖúWBˆ÷CCC€Y˯ü_˲º#ËËËfrrRU*.¥ü-€~cL㚢ðik¬ùe 1æclÄu]%„àBˆáÖÖÖ¯¦§§™RJnøÉñC•ïß1ßÙ¶Í9çóJ©_NLL@)…ÿ§ÿ¿žÉa’^þÍIEND®B`‚routino-3.0/web/www/routino/icons/limit-46.png 644 233 144 1237 12573351602 14520 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“TIDAT8Ë­”1K+Q…Ï^! Û$„H!h*Ët61–Ú„joaòþ Ó§”¦óˆ½B-d5B ADPÁÍÞû½b7yy/Ï.–Ù{Îν3gFHBÆ$ƒ$2™2RÏ»'—ƒ|Þ’ËçÝ#u“}!™„'4ýQ&ã!ydNñýšM¸¸pŒÇðú ãqì7›àûH§ ÞKø©”!¥ÒR@½£‘"œ³Ì¯Ø,õ:H¥Òé´H¥Œ(E£á#ý¢Ýø“ L&àÜŸgú ðM» Ò/ Ÿb1¹¦Ôa $РаÖÍÙ“0ÄZË&d¤Î4g›øþ;Ãa1!;çpÎ-ØÓc%8Çp¾ÿŽ´)¤.­@”\!ŽAÀÕÕÕÌît:ÜÞÞÎ$øˆV ¤®ôû–(šÀZK¹\fww—(ŠØÚÚboojµÊããcŒ Ø×ïƒ40Êf+ªÕ$ÉÈóäyž$éääD___Z__×å奂 P¡PÐöö¶ …‚$É[Y‰yµš”ÍVŒŒA©”$É:'Iêõz:??×ÎÎŽƒnnn´¶¶¦jµª^¯§ëëkI’KðJ¥$c0rÎSj~cT©Ttww§‡‡===)ŸÏëøøX«««z~~–$1! %ç¼…œL’BœQ¯×8<<Ä÷}ŽŽŽfû.~Ïröc5­µ|~~òööF¬„ˆ———™î’¨ Õü¯Îþî"7“‹µ6ÖYì/èìǘéé_ûÇXjo.uj,už-qÒþ“v0ÞéIEND®B`‚routino-3.0/web/www/routino/icons/limit-35.0.png 644 233 144 1515 12573351606 14657 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”ÁK\W‡ïE|:yãX³Á‚Ž5VÝ8qÛ”@݈ƒàÌjh0 êÖ`ÿ€R—ÉÞ}!Ö“YTׂ+7š@Šq“Ž0øPkR“â›÷îýº˜cJ—^8pÏ=÷œ{Îå;GHB®ë"¹H¢£ã¤çÝÝÐÓcèîÇy…´Ò´ Émú µut8H…BÒc‰ÌÏË–Z NO¡VkèóóH|Dzܼï4ý%ÚÛ]ÍIEND®B`‚routino-3.0/web/www/routino/icons/marker-17-grey.png 644 233 144 2516 12573351600 15624 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“IDATHÇ}•ÏkTWÇ¿çÜ{ç½Ì,âÌüA’ÁÌ"Ž¢]˜n$ÝU³”.‚¶‹‚´¡ØE™Ê,,ÝÔ¿ Ë…1`Ufa‡´"ÄcñW"ØÐÄ8ÉÀL|?î½]˜yÍ/ú…ï½Ëû¾s>çœ{©P(`],¥D¡P0Åbñ¤µö§0 ?ñ}ß ü'ë8)¥&ˆèJ¡Pø½X,rE`€ÖM…µV[kÛ”R׃ 8†¡M§ÓÔÑÑfŽ1˜››CµZµJ)J$Ãa~MDÿ‘ %¶Öj]RÊJ½^ïò¦§§m¥RÑËËËç’Éä§ZëÖÚ7DÄâøñãÀ>)åŸAt8p <þ¼Êf³$„€µvÛ%¥Äž={¨§§‡ÃwïÞyJ©ÏŒ1·­µ«œJ¥ ”ºÖh4:³Ùl888¨víÚc €ˆÀÌ›XkEZ[[188¨²ÙlØh4:•R×R©8‚ÓA\ð<Ï ¨æGD›Æ•\7gfH)ãµåyž ‚àB§¥µöj†èïïG:†1D"BµZÅêê*:;;¡µÆ‹/EQlf­ÅÞ½{áyúúú022¥ÔUEѱt:m:ÄÍh´Öˆ¢¥R pñâEø¾;wî Ñh@xÿþ=.]ºÏóÏçyttÔÖëõcÒ÷}ÛÓÓÃ---ÐZC™™”J%Ôj5=zàº.†††`Œëºñz>Ÿ‡1©T ôøñcÃãMüöïßË—/£»»kkk1S¥\×Å«W¯0;;‹3gÎÄšY`)„0µZÃ0„R à8˜J)h­·õéƒpøðad2câΨ×ë`fîëê™™355OÌNjvÄóçϱ´´„ÞÞÞMïgggñúõk뺮f?H)¹R©DÕj̧ÓìÑš˜˜À¾}ûN§a­…aâþýûš>ênooÿ1‘Hüº¼¼,GFF¢­ãøáÀQáåË—Èår›²º{÷®yûö­H$Sa‰#GŽÀóÐuÝ………ŒÖÚär9€t:®®.d2™Ø$“É —Ë¡¥¥ÌŒ©©)[.—9™L®cNÑߢ¿¿_Ñ*€)¥ÔçoÞ¼1mmm¼{÷n´¶¶Âó¼MÕÞÞ×uAD¨Õj¸qãFdŒBˆïü@2€€"¢Qfþ†ˆÄ½{÷••0ó¶Âcbæår9ªV«*‘HÜ‚o'''㟉¾¾¾fkÐÜÜœÕZ?t]÷ì‚§µ6ÝÝݤµŽ»‚™±´´„[·nY¥ø‚ˆÆ‰HÐÀÅb1ÎŒ™%3Ïc“É$ÆÆÆìôô4„ñF†!†‡‡£ XqˆnPëQ,ÁÍ›uý/_¨T*f~~^:Žó—ïûߟ:u  ±[Œ·ñ-•J<}úcccH&“0Æ|%¥l”ËeÀnd.6>ìÄ×qœ³‹‹‹ÞÊÊŠ}ò䉮×ëB)5`ØZsܶ•vÑ-DÖÚ~fõ}_K)…”²’ÏçO>{öŒµÖf«á¦ôwÀÐäû‡µöŠëºB1¯µþrrrrÇÝ«©3QTJH)IEND®B`‚routino-3.0/web/www/routino/icons/limit-4.3.png 644 233 144 1300 12573351603 14563 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“uIDAT8Ë­”±J+Q†ÿ].Ö"  Em,óbce!¢ÑÎ6>€àØšÞNÄÂ.Ï`g¥Q,† ¢ ˆ ÌžóÝb³¹I¸¥¶˜sæÌüç›’D†H!’È忑ނ[FG¡P0FG!n‘Ž:~!…sBY \.@ ØÚÊ!E_”ËP­zžŸáýžŸS»\†(úB:ìì:ç%††B†‡ÅÌÌRƒµ5x|4 Á{£w¥vÂ㣱¶Rƒ™™9†‡ÅÐP(&&Äúz„Tgo  xœçÀû_ö<Ðfo¤:ëë2¥ ¥@Œs`†™‘$I_bf†s‹cH}1¥H•L³E¢¨ÅÝ]z£Þ{¼÷Øi0ÏÝDQ iQHGìî$8‡Y*S£Ñàüü¼›@½^§R©pyy™ŒãôÜî.HGBºâì À|ªfÆÂÂ+++ÝLšÍ&…Bíím¦§§¹¸¸ „qvÒÕåóE-/KR„¡$i_???W¶œs:88ÐÔÔ”šÍ¦Úívæ µ¼,åóE16f¼¾’I}rrÂää$;;;ÌÏÏsßÕìóó“ fgg©Õji¯¯06f¡¼ÇÝ Â0T±XÔÍÍžžžt}}-çœNOOµ´´¤jµª‘‘Õj5I’—¤8–¼ú4#IpÝŽÙÜÜ X,òððÀêê*ù|žR©D«Õ¢\W³ÿ¾¦™ñýýÍÇÇfÆÛÛÞ{’$áåå¥{aà¾×ìçlÔ^Î2DÌ ŸuÂgý$Ý]P{õÞÓ³g ~µ7ujüê<ûÅIû¸t¹^FSnIEND®B`‚routino-3.0/web/www/routino/icons/marker-77-red.png 644 233 144 2003 12573351601 15426 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“¸IDATHÇ•U1lI}3;crŠ+¼V°r4‰" Dª,!•EyN“>:!ÅB뮤º”'ƒ"!t‘EM—.E$$d§HA@b“yWì¬í˜ ¸/fökæíÞÿ MNLLHÈçó7´Ö¯€ó3G¿µÖ¯òùü ðçd$ü°~ÑZo$IR'ÉÉÉI±°°­5œsRƒR!”R-cÌ€ƒœÁ*At°T*™f³i»Ý.s5ç»Ý.›Í¦-•Jý¹JÆ8‹8 ‚`£(ŠÛí6IÒZKcÌ7ÃZK’l·ÛŒ¢(öÀ{ÂVJ(¥`µZIÒ& ã~Ÿ.ŽIcÒa-™$¤1tq̸ߧM’dµZP)õXJ är¹›†¡ít:$Iã#ù‘eû:Ã0´˜Ëån*çÜŸpïî]T*$½Ô³gÀñ1 D:HàÊàÍàÓ' )¡¬Erõ**—.áÞú:~¿}ž+‹îý»wéE|ø@^¸@¤”ä™3éúÁòâÅ¡¿P º'OH’ïX,—l­V#I&IB:G~ùB~ü˜r¬×ÉÅÅt=î¿vmxŽd­V#«H­5€dJwb8{xþxñxù2ÕH.wºß9 àq$Øùùyöz½™]ÔåËäÚš¿“²8ÅŸI,Š"°RÆìææfºçë×tóÓ§i>½fǧúïßÞÞ&'„ˆÁX.—Í@ô$yëEY¥‘Žùðè舳³³‰/‚¿Q( µþ«KK†$“ÏŸÉsçÈû÷‡ÔI²×#ÏŸøíñ1IreeÅzÀ× Y™–´Ö{ظsÇ’düð!é‹aã~Ÿ|ôˆìtèí­-ç{Bˆ™ P€bIJII«ÕJôR·ìbö÷÷Y.—³ÚoŒâ€B@)µ€å0ŒÛoßžÖ¦Ô|½^7¾·¶¦¦¦Á C¥ðJÉ™™h­[¾¹˜Qa1SâÖîºÓHÛØ#ÔZw°Ñh¤ùõ²É¢ÞÝÝe¡P°(¥ümœö¸}?¿>B/ã[Ý_BÐøÈo†qÖI²Ñhd´wVWWGŸ¥ïÛx~ I¶Z-°RJ !–FÞ·Ÿ²A~•R\^^vsss톧­~ðD~\B@â#üwzzJ)ùùõóz”RîøuŒÍ7öd5¥tLþŽ‚IEND®B`‚routino-3.0/web/www/routino/icons/marker-2-grey.png 644 233 144 2516 12573351600 15536 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“IDATHÇ}•ÏkTWÇ¿ç¼{ç½¼Ùd:BA"ã<5:Aƒ DˆˆPÌ¢X1 ;‹vÑM[Š™Â,„nê_P\X‚YÑAéÔ–©B(1NDQSÓ„ŽÊ$Á™ú~Ü{»03MŒíÃûÁ}ßsÎçœû.år9¬ !Ëåt>Ÿ?bŒù. Ãß÷ ¿flÛ&)åïDt6—Ëý”Ïç9Š"Ð@k¢–1Fc>”R^‚à“0 M"‘ T*fn+j­±°°€z½n¤”‹Å&Â0ü’ˆþ"" €Ø£¤…ÅF£‘N&“ÑÈÈg2²mïšïû¨T*¦X,ªW¯^}âºî RjÄó±544dt !~ ‚ ÝÝÝž>}ZzžG–eÁ³É…غu+íÙ³‡kµZøòåˤ”ò#­õ¤1f…ãñ8¤”ç›ÍævÏóÂl6+;;;¡µˆ̼ Cgg'²Ù¬ô¢(j 33Œ1€±±1™L&uãAµ†‡‡ô}¿ëرc¦»»›´Ö툵Z —/_ÆÔÔîÝ»ß÷áy^; Ö®ëBJi*• I){8Š¢ý‰DÂôõõq+ƒVÙZk\¹r¾ïãÔ©S8tènß¾r¹ÜFÐZß××ljDÂDQ´Ÿ}ß7©TŠ:::Ú[e­®®¢Z­bhh½½½ÁîÝ»177·a´Öèèè@*•"ß÷ ¿MŽ7,"z;ëñxÙl;vì,..b~~étï³5–eéÕÕUÃRÊ ‹¤”èííE†m¦»víÂÁƒ7o]˜Y ÇqÔóçÏ1;;ËûöíÃûuñâE4›M?~ƒƒƒ›¸33æççñìÙ3ã8޾Bœ/‹‘çy"‘H´1¸té¶lÙ‚3gÎà]L­’Ã0ÄÍ›7YDôƒuòäÉßÞ¼yÓ³²²Ò_«Õ¢nEúô)îܹƒD"'Ož \.czz+++ð<J)03nܸ¡?~l9Ž3†áÇV?´ÖÓŽãŒ---} ”Ò;wî$xýú5¢(‚mÛˆ¢RJh­‘L&‘N§Á̘5…B]×ý[k=JD‹‚™€?µÖŸº®ûs©T2]]]Èd2ضmÆÇÇ7•¼~änݺÅb1IDçˆèÁ"’ˆî2óWDdMMM…ËËË`f(¥ µÞà-ÑB¡Õëu‹Å®îÝ»÷{ j‘‰ˆ8pÁ¶í«õz]NNNF­F¬÷Ö»û÷ïër¹,âñx5‚offfÚÁ¬Ã‡·J¢……£”švçÄÒÒRR)¥{zz¨Õֿŋ¸víš‘R€Ïˆè> 8ŸÏ·w3 f®j­³®ë¢T*™J¥˲ µ! CLLLDA°eYˆè*¹†ù|ܺY³ÿå ÅbQW«UaÛö#ß÷ÏŽŽb½ ÖÀâáM|¯_¿ÀÇQ*•àº.´Ö_!š…BÁ`ÖO‡µþá}|mÛ>Q«Õ’ËËËæÁƒªÑhXRʯLcÚ×%µáè¬;²€È3ÌÌw}ßWBKQÌd2GæææX)¥ßÜPþ{0´øþbŒ9ë8ŽeYVU)õùÌÌ ”Rø/û©?\ IEND®B`‚routino-3.0/web/www/routino/icons/limit-6.7.png 644 233 144 1351 12573351603 14577 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“žIDAT8Ë­”½K\QÅÏ»šu}JÔDW¬„‹í­m¶A^aJ DÑ?`K›@ʤ•-Eð£Ê`%¸``E Z¸,²°H²÷ã—â½11·˜¹3‡3Ù’„1É ‰|þ5R…(úÊà ¼xá„(úŠTÉþ…d²:¡P>!E¼y“GúH·X]…ÏŸ××ÐhÀõu꯮B·>fùQV/‘ËzzÄøø+¤o,,Àå¥!xþ´Ôw\^z@úÆøø+zzD.gÄè¨H’©J¹ ðX ÖB÷¯ƒü¤\©J’ÄŒŽfmJŸX\hãÞZ¬µxïÿ °YÜþøAHAÛ,.‚ô©3³"qÜäì,­±–ÂG͹”áÙÄq©Øõ^ú wï¦õö­ÇZ={¦Z­¦ÍÍMõööjllL’t~~®íímU«Užžªÿùs E¼|é£ïß{urÒ%¤vw àÓÓÓÌÍÍ133C­Vààà€©©)J¥Q±¿¿ŸÏî.H'b` pu…ÍØïííQ(XZZb}}V«€MgÄÆÆËËËø´U¸º‚`d ÊåÔ1眆‡‡5;;«­­-K’º»»U¯×U©TT.—õÀr9ÉŒBˆÔn+ÊâýýýêëëÓÊÊŠ …‚...Ôh4$I;;;Q±X”÷^Ƙ´¨Ý–BˆŒšÍ/:éÕxÒ{ö„—öž¬lÝm ÐIEND®B`‚routino-3.0/web/www/routino/icons/limit-5.7.png 644 233 144 1347 12573351603 14603 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“œIDAT8Ë­”±K[QÆ¿÷ZcxH4‚'%! NNY3 òÅATЭ‹F»ŠtqRq)ÔŠ“ˆ8–B‡€1’‚DbÞ»ç×á%V[ 0à‘ Ê„aÀðp§Mé#ssm¢ˆèñ‘(Šˆ¢3ëeO¾¨ÕÂÐ6ss }ìά@4¹¸H~ŒcþË’8ãâ‚ ‰Tx+é½––2wrîMd¦¯_¾¨Z­*•JiaaA™LF———:<Öëõ¸×ë‘$­µ4ÆÐÄñøg ­µ$É^¯Çz½{ð>€0ÅJ ¥Ô}l4q‹ã8U™$d^m’Ð9Ç8ŽGðF£ Rê¾”( W0 CEIÒ“Õšæãcr8Lsîy¶/Š"†ah°P(\…Rê¶Ûm;ô*øèyê ¥ÙnÜn·­Wû\¥RqƒÁ`t#…Ÿ?“å2yå ùä yçN ùr ’ ¬T*ηl³Ùô{’I•oß’çϓϟ§ë÷ïSèƒô2'Þk6›`©µôMá»b~x÷88nÞž>.\®_÷Ý ž#%×ï÷q|| ¥Ô J…Bº-I€3g€(>|€W‘Þ ‘Þ¡ƒƒpRÆìÖÖÖØøÌÓ^|øŒãqKÍÏ“7nŒ<ÍJßÙÙ!'„ˆÁ/X«Ǫ̃é3ÈãÇ©‡Ïž¥ë/_ȳgɵµôP½§GGG\\\Lü%ø årZëß}ó›‰;9!—–ÈB¼v<}:m«W¯&>¾¾¾n=ðOå̽ªÖz[­–%Éøä$üHÞ»G^¼HÞ¾M¾y“ÚäÛÛÛÎÿB,ŒŽÃ›}IJII·ÛýÚß\X_I¿ßg­VËî~+Ï-„€Rê®÷wuû._"wéëcc¯‘~²°ˆ°Öð4:8ââ°°ÒOÆÆ^Ó×'âqW ‹ÅEé««-À††`ícöîÀ-VWAúÁâ¢Ïðp÷™R‰¥%€6QDÔja¬ÀC†cq³‰i·;ýKK •zößop~`£V Û²Ö>œ{B8а`9?ßo ½‰}”þÖ‡éý{Cºn<®ƒƒEQ¤d2©ÓÓS•Ëeõ÷÷kddDÕjUJø¾FGGR)ãÔj œÄ„tÂçÏcØÞÞ&‹±··Çññ1CCC,//3>>Îþþ>ù|žùùyfggùç×/cËeN\ ¾U.'I®9Ž£t:-I²Ö*‘H(ŸÏkrrR»»»ªV«J¥Rš››S:›•$W¹œ48øÖ•ë¢xü\(455¥»»;Õëue³Y­¯¯ëææFA(år9mnnêèè¨Ã{õJr]\Yë¨ÝÖÓ0ÆÈó<íììhffF•JEžçéììLÙlVÅbQ™LFµZM’D»-Yë¸j4¾©R‘$+k%Ij6›*•J:<8./¡Û…ËË|ßh@Þ!½íÇ{}¾D¡àbfæÒ1Õ*œŸ[ÀàœåWË÷†ósKµ Ò133ÏQ(øbrRÔj!ÒW¶¶z€#Ë ËÀ¹Ÿk€zlmô•Z-dr²ÿLéëë©éõ°9k-Y–᜻wA›¦d½RÞ¼éÝàÏ^†·cÀ¹~"çÜ0Ƀ¾µ8p®Ý†0¼Ez!¤67q`Z­'''±½½Íéééð¦ív;Çó8ã v„ô‰Ý]û×î.£££4›MŒ1ÌÍÍ1??O¥R¡ÛíÐétXXXÈñçÏù,Í&Vúä«\~©×¯å$ßÑÄÄ„¢(ÒÁÁ‚ Ðáá¡¢(ÒÞÞž$iÿ'þä‰þ~ÿÞWµ*W*½ô52‚ 9Iõºâ8V’$rΩT*I’¢(R’$’$cŒÆÆÆr¼\Ö¿?~HA ù>¾œó”¦ 4M5==­««+]\\èììL³³³JÓTSSSêt:9þí›~¯T¤ïßåçëöö³Z-Ir’T.—•$‰µ´´¤8ŽU¯×µ¼¼¬ÕÕU­­­ieeEqëÏZM¼zåôñ£ü»»ÏÃjk¹¹¹!I’aõ®¯¯±Ö>ì÷z9ossXÍ\gív®lc†zHÁZ{OgÖZ°û€Îîu€Ë2 äÿùÆÐwÊúú/ð¨½ù¨SãQçÙ#NÚÿf/o#ŲIEND®B`‚routino-3.0/web/www/routino/icons/limit-27.6.png 644 233 144 1521 12573351605 14662 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”ÍK[iÆŸ{¥Ñ\3bªA† Bg£eº,a•ˆ¸PDÛE¤±Ý•â?00Ëv¡+.,ˆÐE‹íNÛYÈ€*FR†Œ+¿’Üû¾¿Y$:µ3K_8‹ç=œsxž#$! ×u‘\$QSóÒ,Žó™úz¸}ÛP_Žói¶â’[ɺ,TSã 9<|XƒôÏ;erÞ½³ÀׯppPÆ““ày§H/+ñN%_"r©®--w‘¾08Ù¬¬5|ûÊ8 ›5 ‚ô…––»TW‹PÈMMbhÈCJ35P,¾¾Öþk—`"SS ¥òhjªŒ)½bd%¿XÄ”JXkñ}ÿʬµW ßÇ/1Pbd¤W—;kÃóò6“Á‚Ŭµ×’¯OZñS†™ x^©­ê7éwžåó†·o1Ò¦«Häž’IewvÜç/^hmmM€jkkµ²²¢ááa«¯¯O’´ººªÝÝ]566ê×®.5†Ã® 9uu÷D4jÌá!|úDGGcccW]ÄãqÒéôÕÎhoognnŽæ;wXýø ‚º:ãZßwÜPH©tZ½½½ÕÌÌŒ$iqqQ±XLmmmº¸¸Ðññ±Âá°"‘ˆ&&&‹Åô÷þ¾ÂÇ5§§)mlhckË¥’–––ÔÜܬõõu¥R) H’NNN”L&ÕÓÓ£ÖÖVyž§Ÿ;;5úè‘Õû÷ª:;K i–gÏ8ƒàpŸýŠ òù<çççenÃÑÑÖZ‚ —Ë‹OŸ‚4{Å32™2³ù¯¾ÇÆ0óÏ®)ÀBÉú>¶,™ÿ-@\Æ”xðàܨ6oôjÜè=»ÁKû%ƒsPuq©IEND®B`‚routino-3.0/web/www/routino/icons/limit-39.0.png 644 233 144 1466 12573351606 14670 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ëIDAT8Ë­”ÁK[YÆ¿Ÿx\d2÷>1508g¹.Ýpp`™šé™Ì=âqÑ×ç‹ÑQQ($v˜›¸QQÎ}[=8à’¹9v(ŒŽvŸ)=çñc,„Ñå%6 ¯Š1Æ`­½Vœ#º¸ C"]±Òó^ϲ$§no¯“±ëèœÃƒsŽÿ”Î=ÇÞ$§HÙØoÒôž<±»?úT*ŠÇãJ§Óò}_²Ö*IÒþþ¾–——µ³»«í÷。‰ œ ¸Z-&+½ååKþ:>¶#wî0==M:fss“µµ5b±+++W­¯¯399I>ŸÇ“ø³V³¼~M$½½¥Û·'ôè‘L«åÿ>?¯ÓiÕëuµÛmù¾¯T*%çœ$)Š"år9U«U-,,h,“Ñ/øîógÝJ&'DXšMþ>;£X,266F­V ŸÏ³´´@Øý˜££#ÆÇÇÙÙÞр °¾ COCCZyñB?çrZ]]Õàà ¶¶¶$IÆyž'Iª×ë’¤J¥¢T*¥ìýû²’|c$ç¼ÏG’ÈDZâµ5ei*IŒ…axÃZ ¥Ré( (вF£!IJ O¾†æ¾F£¡(Š2@¥Réh`Œ¹é½~¿xQ?9bÒÕU‰ xúž=ƒçÏazzz`}îÜ/`z;;Kº};=[·ÒQ*é¯{÷Œ1æßÝÝí_/,ä±´$uuI Y+•Ëù|rRªÕòyggn»ºäß¼‘$½^XPww·/RŽlxxX’”¦i®Ûû÷R±Y##Òù|h(Ÿ¯¬HKKùÞ,ËÏIYÀ:çÆ@g'tuÁýû09 ããEVxô(·{7ܽ Ö‚÷<Ö~~~žµµ5Â0üH pþ<œ< »v”k:4·oÃþýpü8Ôë˜Â©W¯^x¬µ1ç7º¾ž‡:1!mÚ$9«¤¹9iu5_¿}+£ôúuIÒ?ðÆ˜˜ ~Ô××—´’^’Ž“*•ù³¸(mÙ"]¾œ¯¯\‘7FššÒФþ={Ò¢þ¤\.㜻 hp` ‘¤ôÝ;ióféÒ¥œ Žs{áB~ëA ²³g%I¿œ:•„Ó@¹Y¦½Î¹—€ªçÎe’_½*ÅЪ&IzòDºvMÉãÇ’¤[·nù‚pÕ³·Iæk¬µÒZ­–ë[¤J E5k~nN}}}ÍÚ¯¶ó8c ažÔEq}vö‚ÒTY!ÇÈÈHRôÖÚ¶mÛ‚ Õ¡rú0´{÷îÅ9W+šKÒ*ˆözOIÒèèhVηºS[ÛcÃÈ9×T­Vs} Ïš^ÏĮ̀\.g€¬µ?o {#¾¬oááÊÊŠúûû“¢ÕýaòBq|ŸèEQÜl‰’T­V›aÏåÓ§O·ÿ–¾Œú:t(‘¤Z­–7 keŒhû¿}Zú†aØtâÄ ¿oß¾fØÕ"ìð[ ?ÑøÑ# -<ü{ç΄ahÿ/aKßÂþ¬µóÀ÷¢ù ÿö tý¥Ä-AIEND®B`‚routino-3.0/web/www/routino/icons/limit-39.4.png 644 233 144 1435 12573351606 14670 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÒIDAT8Ë­”±KcYÆ¿÷ŠD„¨KP°d‚0]’.0;Äu›‘ L‚•mü»rl¬R(ZÌ000“"ík!V AP0+[„ 3î(1ïÝûÛâ%®â–¸pϹç|çÞs¿s„$$áº.’‹$††ž#Upœ}†‡atÔ0< ޳TéŸ ÉíÇ €††$‡Rié‘ÈOÊeøöÍrrprèå2D"?‘>ôý~¼D(ä‹D"‰Ô P€fÓ>ÖîK û4›†B¤‰D’pX„B®33¤Cn‹ççµÿ­ ,pËâ"H‡ÌÌDë?SZáÝ; ô¼Û[L¯€1Ïó0æáñ}ŒçáCb¤•AÍ^‰ü°GGAÆ~à}k-ÖÚ‡ºïþGG‰ü@z!¤Š-—üÃý}VVVØÝÝ ^¯³ººÊñññÈ I£ÑàÏïß|[.ƒT‘‘ö¨VùëâÂŒÆb‹ER©kkk¤Óir¹étš³³³€©TŠßÞ¼0þ§O í¹ŠF3zýZ~§ãþñþ½J¥’’ɤ¶¶¶ǵ³³£P(¤Z­¦,--©Ûíê—x\’\^½’b±Œ1ô³þsuÅìì,“““Ôj5r¹SSS„Ãa677X__g||œùùyž'“üÝjÁå%&3®ßë9zöLŸ¿~Õ¯/_ªZ­*j{{[ÙlVù|^###J$º¹¹‘$e³YÕëu5›MHŽ#Œqd¥=¾|á Ìïù<±XŒ¹¹9Z­ÓÓÓLLL°¼¼L§Ó!“ÉÐn·ØØØ ðömP³AÚR……ßëvi·Ûx1év»œžžÞýüüÏó°Ör}}ÍePŸ……à7ïóÌôyfúÁn="m`ü_žP,ô¬çA@È;*<Úû>ø>öQéÔxÒyö„“ö_n:¢äÁ BIEND®B`‚routino-3.0/web/www/routino/icons/marker-97-grey.png 644 233 144 2644 12573351601 15637 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“YIDATHÇu•ÏkTWÅÏ÷þxóKŒ“Vt`’A³ˆ“;U £XH‚iv…tÓ€í¢›¶”"–i™EK7õ/èÂEI„45ÎÂNc‰ Ehâ+þš‰fL&˜è{÷Ý{»0óµ=ðà½Í¹÷û9çÞG…BbB S,ß¶Ö~§”Úçyž@øW6‰”òw"ú¢P(ü\,Y`€6L¹µV[kßRžö}ÿ=¥”M&“”N§Á 1XXX@½^·RJrgT)õ =!"@ ÌZ«t !ÊÍf³ÓuÝàèÑ£,›ÍR$Á«ò<óóó¶\.ë•••÷âñø[Zë£ÖÚ?‰ˆñþþ~ %„øÕ÷ýÎÝ»w«ááa™Édˆskík;wî¤îîn¶¼¼¬ž>}êJ)c~²Öþ͉¤”߬¯¯wd2522"·mÛ­5¬µ/`3ök-‚ @[[FFFd&“QëëëRÊo‰˜ïûïø¾ÿ¾ëºfhhH¶¸qÎC³WÍcB€èE~CCCÒu]ãûþû¾ï¿#¬µ_+¥Ïç‘L&¡µçµZ >„ëºèèè€ÖwîÜA¡™µ»ví‚ëºÈç󘘘€”òkÁ›ÉdÒööö2àœ£R©`ll [¶lA£Ñ@?099‰gÏžsX]]ʼn'àº.²Ù,›žž¶ÍfóMáyžíîîf±X,¬Ì¹sçpðàA;v ÕjgΜÁþýûqòäI<þ±X ãããh4Èf³0Æ ‘H NÓìì¬a/Pý‚ÖA ™L¶nÝ ¥?~ "B,ý{÷P­V188bh1ÀçÜ4 ¦”çRJ8p“““¨V«xòä <Ï{©§—.]Boo/ÚÛÛaŒ ›Ñl6Á3,ê˜J¥&}äÈ ‚ˆËåÐÖÖÇq·oßF­VC.— wID¨V«¸ÿ¾F£šøJÁÊår°ºº "Âèè(êõ:†‡‡Áƒ”ét0;;‹T*…d2 k-8çPJajjJÓ ýÀvìØñ­ã8?®¬¬ˆ‰‰‰öíÛ‡«W¯âÔ©S¸|ù2Ž?ŽX,¥îÞ½‹®®®0T8þ¼yôèw§¢”úŒ÷õõÁó[4ZZZj‚À:tˆzzzJ¥pøðatvv†£¶··£«« ±X Œ1T*[*•X<fŒ ¢¿cLxdŒù ÿråÊ›J¥ÐÓÓƒíÛ·ƒˆBnBôõõ…i7 \¼x1pGÑ—DôÁ$M3Æ>%">55¥êõ:ˆƘðµFn™–J¥ ^¯KÇqÆöîÝû= hTËår§#‘ÈX½^—-¾› ÃÛœ1\»vÍ\¿~]$‰Eß÷?Ÿ›› ãù|¾Å‹¬Öú·h4úîÒÒ’«µ6{öì!­uX7ÆjµΞ=k¥”àC"ºFD€V,ÃÉc‚1¶hŒ‰Ç㘙™±óóóàœ‡”R |ßgœóÓD4@n`D±Xk½lè5¾.\Pkkká©)—ËfqqQD"‘?<Ïûr``› ±¯¿Æw||<€›7obffñxƘ…ë¥R‰°›™óÍÿÅ7‰¼»¼¼ì®­­Ù7nèf³É¥”ŸµÖ†7m ¯E»é—-ÖÚÃŒ±iÏó´‚ !ÊÙlöí[·n1­µyÕð¥ñÿC‹ïekíÑh”sεÖÍÍÍAkÿÓ?r¯®y/>"?IEND®B`‚routino-3.0/web/www/routino/icons/limit-0.4.png 644 233 144 1270 12573351603 14566 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“mIDAT8Ë­”AK*QÇÿ3¼TEy-\ ½‚Z•} Z‹ Û¶Ô }†Úµpç.w­¢u_ @‚ÝHR‘ET¤3sïï-F}ùz¼•î¹÷œ?sÏý#$! ×u‘\$‘HüBªã8Wd2ðó§!“ǹBªÏ…äŽó„&B‰„ƒä°³“@:ÀóÞ©TàäÄÒïÃ`ý~äW*àyïHãxgœ/‹¹Äã"—[BêP,B¯g€k _-òCz=C±R‡\n‰x\Äb®ÈfE©ä!ÝP«ŒK@€µ¾ÉX`D­Ò ¥’G6;¾¦tH¹ à†ß'¬µümÆÂÑÂ0Š/—A:œÔl Ï{¥ÝŽ.†SkíŒàŒ‰YÚmð¼W¤5!Õ©VBëû´ÛmŽŽŽèv»Sc¢òu:ÎÏÏ£ý(>¤Z©.¤KšM,€ÇÇG666X__guu•çççÁååe¶··£Ÿ Í&H—®Òé¼ É•¤³³3ÅãqµZ-¥R)žžjb{{{‡Z\\”$á8’äªPÒé¼+×E±Ø4!%“IIR*•ÒÛÛ›$©ÑhèøøX[[[º¸¸P·ÛÕ……ÖXLr]\YëÈ÷åŒÅr¹œîïïuww§ÛÛ[­¬¬èóóS’´¹¹©V«¥^¯§ëëkI’•$ß—¬u¦5̘!vwwI&“ìïï3 Èçó<<<Ðh4(‹ÃáLÍf^s"fŒáéé cÌt=áîãプ——(~æ5¿q6ÁÀóOpÿÇÙ·à ¸,fZtó½æÚ›ssgsœ´¿"÷”z>áÚ³IEND®B`‚routino-3.0/web/www/routino/icons/ball-3.png 644 233 144 202 12573351601 14173 0‰PNG  IHDR à‘bKGDÿÿÿ ½§“7IDATÓ¥A Ã:ÿÿçz’¨Iìm!°¨,BjSºz˜7b ‚ø µ6õBû‡wzšáÚÐUÌhIEND®B`‚routino-3.0/web/www/routino/icons/limit-148.png 644 233 144 1327 12573351603 14604 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ŒIDAT8Ë­”¿K+AÇ¿·à®Q ¢èk´°ÐZ;« b¬´Õ? àß ÄÞF±1‚…¥­b!O6"Añæ™ËÝî牧yÏÒ…™Ù™Ù™ïŒ„$Œ1HId2¿Vñ¼ :;!›µtv‚ç] ­6ï…dš~B2É#ŸÏ  ‚7`gÇqwpw× ÞŠM{¯é/áû†övÑ×7€T&—ƒÛ[ $8gùJ 9áöÖ’ËT¦¯o€öváûFtu‰©©éŠB q q Î}ž8 ¢P銩©€®®fšÒ 33u’„$Š°Î¥²Ö’$IÊǵ¶^oØÏÌ€´òQ³!‚à…ëk—DîK ç\*åI8®¯!^†„´Êâ"@â¯qppÀÍÍM°\.³··ÀÙÙÅb‘ËËKšù&,.‚´*¤S¶¶,Ö²½½ïû”J%¢(¢¿¿ŸééiŽŽŽÈf³ÌÍÍÑÓÓÃÉïßÌ77A:5êèÑø¸$ò¯ÁÁAµµµiwwW¥RI:>>Öáá¡z{{µ¶¶¦J¥¢0 %IžïKÆ`䜧z]_É9'k­Œ1Õùù¹*•Š–——566¦ýý}A “““†}IÎy-5‹k5r¹iÖ××™åááááaÂ0d~~žêë+€u[[ ¶t³ HžŸŸyOqU­VyzzJrOœ$ÐÀ^K7[pÖ4ø–¬µ)Îl‹³ÿ&À}°ÈŸcõÏüèlþèÖøÑ}öƒ›ö/ÀÑ’žj–u_IEND®B`‚routino-3.0/web/www/routino/icons/limit-5.9.png 644 233 144 1375 12573351603 14606 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“²IDAT8Ë­”½K\MÆŸ;Á»ûÞÆË&Æ5¯,ÄÊVba±‹‚Á"P[A°¤LzÿÁ" XXÚXØXlL#Öå")¢®;wæ÷ww“ oçùxΙ3Ï<çIHƒdD±ø/ÒAð•8†RÉÇ_‘ö:çB2?¡n b1@ xû¶ˆô‰(úÅæ&|ùâ¹¾†?àú:_onBýBúÔÁ‰04 blìÒ7ªU¸ºr@†÷Ž?-_g\]9ªU¾16öŠBA„¡ƒƒbi)Bj°³ðx¬kÁûߣ»x`g¤KKƒƒgJŸYYhc-öák-ÖZ¼÷½ÄœsXkqÖB–åø•>w9{Mýäâ"¿1=2ï}/°|Žó\\@ýDzýìƒôQïßÏêÝ;'çŒõ^‡‡‡:99Q­VS¹\V¡PPª×ë:88ÐÀ‹*=.¬ ‚—/¾ÿGççÏ„tÎþ>@’$ ±¼¼ÌÚÚÍf€z½Îää$³³³LOOsssÓÍÒ±¿Ò¹QÿÍÍÉKF’ÎÎÎt{{+@•JE###êî èôôTaêèèH’ä$£¹9©¿ÿ‘1( (·R©¤ÕÕUU«UmooëøøX’´°° ûû{-..ªV«©¯¯O= CÉŒ¼Ônç –Ôl65>>®õõu «Õj)MSÝÝÝijjJóóóŠãX’”'ÑnKÞ=Î\‡³F£A¹\&Žc666H’„™™.//©T*ŒŽŽ²»»›q®¹gBÚck ë’¦)I’àœÃ{ß#;MSZ­ÖoíåøŒ­-öéÌÿ!Ôn°®ÎœË«Ëyßí_:{\Y†Ï²¿”ÿhžeÿSOZ›OÚ5ž´Ÿ=a§ýçÇdbÊÎãÖIEND®B`‚routino-3.0/web/www/routino/icons/limit-23.9.png 644 233 144 1534 12573351605 14665 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”ÁK[Y‡ïI“øLÀ$¢‚âh¥RÃtÑ•‚ UÜTÜÛín(þ³´Wneì(dèÒU3R&ŠEÑ’ve%#]Tâ˜ä½{¿.ŒŽÎÚ ‡{Ͻçî½|¿#$! ×u‘\$‰ü„4ãìR[ ‰„¡¶gi¾r.$·’'tU(q&&"H³x^éix÷Îr| ß¾Áññ¥?= žW@š­Ä;•|‰PÈ%ÍÍ­H_†\ÎÖnŽK? —3 ƒô…ææVÂa ¹"™##Ò33%Àâûàû`ívµ(13Ò##Édå™ÒÆÆ0PöK%L¹ €1ß÷1æöM¹Œ_*a ÌØHo®þìž÷Ýf³X°Tÿ_ÀZ{=[kÁ,X›Í‚ç}GzPõ«ô/^t;ÏŸ›½wyeEžç©¾¾^ûûûZ\\T8VCCƒ¬µr]W{{{úceEuñ¸“¸ßËU;ÛÛU ¤mÖ×ùûëWó<úúúèèè`uu•¦¦&ÆÇÇill$N°»»K[[ÝÝÝüüð!ÿau#m»ŠFéÉå>vyýZŠF£Êd2šÕÄÄ„’ɤ...$I›››ª««S:V¨ºZ./»zúT¶¦æ‘ˆÇÉçHø@WWSSSXk) ŒŽŽÒÒÒÂÖÖ‡‡‡¤R)†††ß»ÇïoßBàÇbƵ¾ï¸¡v400 ÉÉI-,,hiiI===Z[[SMM2™ŒJ¥’ÎÎÎÔÙÙ©þþ~ÕÆãjmm•ÎÏå€ãšBaG?ê¯OŸlP.k}}]‰DB€ÚÛÛ‹Å”J¥488¨ÞÞ^E£QŸŸknnNSÏž©ûñc«÷ïUU(ìižW¯ø‚üÑG+‹cÈçóø¾µ–ÓÓSŠÅ"'''ØK^¾iþš3²ÙK²+|Yk¯Y3ÆÜâÌT83`¹ÁÙ-X([ßÇ^J欷ÖApSf|ü†îT›wÚ5î´ŸÝa§ý4€q+‚†QIEND®B`‚routino-3.0/web/www/routino/icons/limit-37.3.png 644 233 144 1465 12573351606 14670 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“êIDAT8Ë­”ÏK›iÇ¿o,&ûnj~ zIé$Jo[AzðàAB’znôðX؃‡ö UðlS„¾Þ<{òÁŠ i©H¢Ô F«æ}ßçùì!1í–Ý›s˜yfæ™ùò’D$AŠ ‰Xì7¤5ç#É$¤Ó†dç#ÒZï]H‘^žÐm¡XÌArxþ<†ô ×½d~<Ïrt­uíùypÝK¤W½x§—/18!Ùì#¤OÌÌ@³i€k ?J×i6 33 }"›}D4*#"“ù¼‹Tcq X‚‚¬ý®·>°@‡ÅEjäó.™LoLé5Å"ü ÓÁø>ÖZ‚ 諵¶ß ñ}‚N>Å"H¯o1Ëáºç¶ÑèþhLo"ËIßß³¶Ñ×=GÊ ü!ýÉË—¿;/^˜úÞ^dýÝ; É÷}­¯¯«V«i_ñx\©TJŽã¨^¯ëm¹¬è½{ÎƒÇ Íæ/Nµ: #U©TøÜj™t"A±Xddd„¥¥%¦¦¦˜œœÄq677h4¤Óifggyɰ]¯>| ”ª2÷ï[Z-ê_¾°úæ žç166ÆÖÖ+++ÌÍÍõǬ×묮®vãž<áïímh· ãq+R)Ãׯ\´Û ²Ù,»»»\^^2::J­VëÁÔÅóââ‚B¡ÀÃl–½=øö “H˜HèûŽâqýõþ½&ž>•çyŠÅb:88P¥RÑðð°r¹œ®¯¯Õn·U.—511!Ïóô«ëªº³# Ȇ¡#+UÙØ  fêÙ3’É$ù|€b±Èòò2ÇÇÇŒsxxÈôô4‰D‚R>Ï966°RUHk,,„ÁÍ ''']brvvÆÕÕUÄÓÓS¬µ„aØ»¹YXií_<3=žcú|ú™oÖÚ.vÆ`~âÙ÷ (•|†ÿ[€0Äv»÷)•~Ø€;ÝÍ;½wzÏîðÒþH«­;ÎJ˱IEND®B`‚routino-3.0/web/www/routino/icons/limit-141.png 644 233 144 1247 12573351602 14575 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“\IDAT8Ë­”½J+Q…×ȦPQ!¥àµ0¥¾€6iBŠ|Óð%´Ï$`aia%éEDHÐ&E:Ñ€39ç|·˜dnr½Ü* N±fÿœ=g¯½…$$aŒA2H"Ÿÿ…Ô$îY^†•Çò2Á=Rsl’Ç MåóR@­–G:!ŠÞ9<„ósÏ`//0¤üð¢èédìŒã%Âа° Ö×7z”ËÐï;Àâ½c)·ôûŽr¤ëë,,ˆ04¢P•J„ôH£žÑF#ðþÏ™|Ä4 =R©D ãß”N©V¬ÅÆ1Îû¬ çÖÚŒÛ$Á%Iê_­‚t:y³"Q4¤Ûð6ŽñS‰¼÷3ÜZ›rçÒ »]ˆ¢!RQHMêuëÓÛèt:Óh•lÁiѬüQÓ‚táR±ëI èº8ÀÀ,\´ ©Ù ¢mI²vá¿M‹)V*J ™Ði£æ½wïg‰Ú)Üsï=çžsùœ#$! ×u‘\$þ„”ÇqÞ’HÀÐ!‘Çy‹”ï Éíù ]ŠF$‡Ç£Hψž²¼ ¥’åøšM8>îÚËË‹}EzÖ»ïôü%úû]"166ŽôÅE¨Õ b­á[éÚ!µšaq¤Œ‰ˆþ~W$“"Ž!UY]è– € k¯ôb,Ðau¤*étŒd²W¦ôœL~Ðé`|k-A\ªµö2Aãû|2ž_üYŠXì³Ýßï¾hL¯"ËÄZÛ=3 ÖîïC,ö)uãwéž<ùÅÉfÍûwïÜÂË—ŠÇãò}_…BAÕjU{{{òKKßtÀµöæµNkg×8iÿ5dŒ³]ÐÚçIEND®B`‚routino-3.0/web/www/routino/icons/limit-16.0.png 644 233 144 1417 12573351604 14655 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÄIDAT8Ë­”OK[kÆŸsÄ$œž¦DÁи6-²¨±Ü¥›KµŸ@âðc4;®ÝH¯ÐÕ­wÙ µÒE!Q0U"ö¢Ô(99ïüî"®»tà…™ygÞyç™’„ïûH>’H¥~CÚÆó¾11™Œcb<ïÒvÿ^H~?Oh”JyHkk)¤Á• |úd\^ÂÏŸpyÙ³+‚;¤ýx¯Ÿ/‘Hø$“bnî%RƒR ÎÏcæx,=;æüÜQ*Ô`nî%ɤH$|13#Êåé;››Àèv¡Û³ÿÎÀtØÜé;årÀÌL¿L©Êê*@w:¸^Î9ºÝ.Î>ÐEÝNƒˆwï@ªþìApK£A f} 3ÃÌUh£~ç00«×!n‘^ i› b€Z­Æéé)FƒjµÊÑÑqP¯×ÙÚÚâ¬[¥Ò¶¾°» àþÚÝe||œ½½= …+++‹EÎÎÎhµZ,..²°°À|6Ë?àØÛÃI_|¥Ó¯õö­Lò½±1e2…a¨ƒƒœœhjjJËËËšœœ”$íïï+™LêøøXÏ_¼Ðß?ú*•dÏž½ö56† ™¤µ÷ï•Ëåt/3íììèððP’E‘Â0”$=O§ußnKɤäûø2óE 3S† ÃPëëëšžžV³Ù ÙÙYµZ-]\\èG³©ßçç¥_¿äçëöö«j5I2IJ§Ój·ÛZZZR6›UÊçó*•JÊçó*‹* Êårú³\ÖoÞ˜>–w÷uØM Æ9nnnxxxvïêê çfÆõõ5Î9œs=½Óéåml »ÙãY½Þcv¿ýf6$ëlÄïîx62Öí2|LÖ=Žé“;buõÑ<él>éÖxÒ}ö„›ö_kÌk~-@]IEND®B`‚routino-3.0/web/www/routino/icons/limit-7.5.png 644 233 144 1351 12573351604 14577 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“žIDAT8Ë­”¿KAÇ¿»‰ç±\¢·;¼€p`a}­ý±‚Q,TÐ.†¶"i¬D®I!"XzXK Å)9ðÔ;ƒ¹ÛÝ™OŠÝõGB …S¼7o¾óÞw¾ï IHÂu]$Iäóï‘vpœ¯ŒŽÂ»w†ÑQpœ¯H;é¹ÜôžP”Ï;H>ä‘6ñ¼_¬­ÁçÏ–v~þ„v;±×ÖÀó~!m¦ñNz_"—s¥Réµ´Zˆ±Öðt%vL«e¨Õ@úF©TfxXär®Aà!5ÙØ–(‚(kwæ ØØ©IxŒ§eJ[ÌÍ„6Šˆú}¢("Š"¬µ‰e¾h0À& !ss meœUð¼ççÉ‹qÌ­$Îr~ž×Cª¼–ôQKKoíä¤q¥WßüÐÑÑ‘ …‚†††T­VU.—†¡uuu¥\.§ùùy½)&'³´ôVŸ>}ÒûûÄ`NNN¨V«ÌÌÌà8ÇÇÇ´Ûm|ßgvv–ÅÅE.//IÉ3ìïƒt&FF,Ùo§enoo³ººúPÕÁÁžçõz= Ï(¹¸€‘+ŠEC·›šD N‡©©)šÍæØéé)+++ìîîâûþCÆ1@· Å¢qe­£0”$c$I{{{S¥RQ¿ß×ÍÍZ­–&&&´¼¼,ß÷Õét”‰^a(Yë¸êõ¾¨Ñ$ëX+Ij4 ‚@’tww§Z­¦R©¤z½®b±¨ééi-,,HÆè•dÕhH½Þ!í°¾ždœh‡ÛÛ[îïï0ÆÐMi \__cR:Òø˜õuvþ©³§bÍìÌgŒÉȦ³¿:€8~ü¥'@Ïã8íð¢½ù¢SãEçÙ NÚߨמ^i‡ÄIEND®B`‚routino-3.0/web/www/routino/icons/limit-24.3.png 644 233 144 1466 12573351605 14664 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ëIDAT8Ë­”¿K\YÇ¿ïÍ:ÊÓU3“, [H°ÒÆÊ"ðl„ÈÀm»Iº%øØXDPÜÂÂNH‘b«V‹dYG#(þÁgÍÌ»÷~¶g6î¦ôÀ)νçç½ßï’„ïûH>’hjúiÏÛ¡½ K{;xÞÒâý½üû8¡Z¢¦&ÉãÕ«&¤wÁ-Ù,ärŽósøòÎÏ«v6 Ap‹ôîÞß»—ˆÇ}E*Õ´ÏÈ[Ààœå{©Ú†ãcËÈHû¤RÝ46ŠxÜɤH§¤SSeÀEEàÜ¿Z;”™š©@:LÞ)Í’É`¡•ËØJ¥ÞŒµc̃m¥BT.c¡B&ÒlíÍž7®XÄÃZœsô᤮V¥j‹7HÏ…´è²Y³Ï377ÇÎÎN=xŸõõõz—…BÙÙYþúô À¸l¤Ei“ÕUþüüÙþ„aH*•"ŸÏÐÝÝM†õä$ ÆÆÆø%™ä½=Ëê*FÚôÕÒÒ§0ÔñÞžÿÛÛ·Z[[Sss³vww533£»»;utt¨&QizzZãããzúì™*WW¾^¼ZZú~Š54àno½ÌË—zúä‰z{{†¡Œ1ZXXP†ÚØØÐá᡺ººÔÓÓ£ÎÎNMNNêêëWµµ¶J±˜¼X ßE‘çÇãÚ*444¤‰‰ ÍÏÏK’úûûµ½½­““mmm)Š"-//kppP¹\NÍA Í|^ŠÅäŒñT‘6ùø‘ßß¿· ¾ÏÀÀ­­­¬¬¬°´´D&“ ¯¯££#†‡‡ikkc4æ,>à¤M!-òæ ƒ¹8=åôô”³³3J¥¥R‰ëëk¬µ\^^âœÃÃÅÅÑ·o†×¯«¿YÃÅbÙö!ƒþ+ι*D¬Åþgu8¨¸(ÂU)ó? ÖkLͧÂèèw xTn>êÖxÔ}öˆ›ö~׋y0?t‡IEND®B`‚routino-3.0/web/www/routino/icons/limit-38.6.png 644 233 144 1520 12573351606 14664 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”ÏK[YÇ¿ïµÍ§MmŒ€âlì¦PtSÒ¦¥‹lDˆEDȨˆþþ2.[ܺ’é™R°Å­;—5„:X†LMÔ±`_Þ»÷3‹$ÓÚÙzárï9÷|Ï=÷ò=_! I¸®‹ä"‰Xì'¤uç]]LººÀqÞ!­·Î…ä¶pBíD±˜ƒäðôi éž÷…ÅExýÚr| õ:7íÅEð¼/HÏZñN /‰¸D£bppé#ããP© ÄZÃ÷£i‡T*†ñq>288L4*"W¤ÓbbÂCúÀò2€X‚‚¬ý6Û>°€Ïò2H˜˜ðH§[Ï”ž“Ïc ø>¦ÑÀCs¹@¾ù¯^?[[;;GF084„t*ſ޼Bˆ_Àf³Y{ppgH’§§d«ENN’33g¡­¬Ù×ÛÚV‹$yðù3³Ù¬u%‡¨\.“$ÃÓÓØùõkòòåØñÎ3ÒÛ·ÉB<:"¿|éH:mËå2D€ÔZ(]5ܸìì…Ðjuµ‡66€àêUàåËxÏZ€ã‘€m6›899R $þ~`h¸t ˆ¢˜Ž[·€/€ë×»wzµ¿¿RÊ@´ººzvòÆÄéNO“SSñý·oäÞy|¯¿~%…`øô)Iòï·o À !xž÷æóyÓ)ú ˆçæÈR)¾ßß'ûûÉGâõãÇ´B››<"9~íZèš`™LZëç®øÍ¹›™‰+ ÁÇñáy 0zð€$ùÛ½{‘#ÜIŽ §µÞÀJ¥‘d@’ïÞ‘ëët=ÛÈ'OhÞ¿'I®­­YGx,„K!nJ) ¬ÕjgúvÃ'½ßÜÛc>ŸOz¿ÒÍZ¥Ô}Ìû~Pw-ÛÑ7Avöæçç›­µááaxž'Ñ ¥”ƒÖºvNßîÒýòòrä›éÔ5öгák­çôu‘%iooo3“ÉDq¿È_{ÓîÅ…úq||ܸQ÷§4.À9}}ß’‘H’•J%I{@fqq±û·ôcôê;99iH²V«ÅCJ !nº×½ {õUJ5paaÁNLL$iW\Ú꿞ÓÀ”‚Báúèè(”RòÿvôuöwÏó(¥lø¹'›ïð/ÌßsßZ|IEND®B`‚routino-3.0/web/www/routino/icons/limit-1.4.png 644 233 144 1224 12573351603 14566 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IIDAT8Ë­”ÍJ#A…O—c'ô&A…,Ž} ¸5d‘¼Bò_B÷îA.|q¯ ‚B"düIÒUõÍ¢;qb˜E.4MÝ>çÖís„$$aŒA2H"›ýt@ÜÏÂ#Ÿ‡ ¸A:H¿ ɤ<¡Q l6@ ¨Õ²H{DÑ;õ:œyz=x~†^/9×ëEïH{)>HùahÈdD±¸ŒÔ¡\†n×ï[r¶t»Žr¤Åâ2™ŒC# Q©DHw4›ÀÇÇàý÷3ò4› ÝQ©D éoJûT«CâœÃZ‹s“‰8ç°ƒX›à«UöGš­Eo´ÛÉÖb­Å{?È{ÿíO‚yÚmˆ¢7¤U!ÐhXâx ¾¸¸àþþ~d”e§Óáüü<ñ‡ ¯Ñé@HW´Z.ÕƒÓÓSÂ0¤•ø‰S¿sŽ••¶··“䃄×jte”Ëm¨T’$£¹9yï–––ä½—¤ñ{wwWý~_‹‹‹’$‚ á•JR.·ad CÌ{¯Z­¦µµ5}~~J’Â0ÔÑÑ‘NNN´µµ¥ËËK=<<è×ü|Ò¬a(ƒ‘÷†Cý´Q†’ÔëõhssS×××êv»º½½Mp’4JÞ“šY;Öggg‡ããcÖ××y||àððr¹œhÙïOh6UÍ‘½¾¾òõõÀÓÓqZé^^^H+3UÍ©>û/ûGŸMN€µð£i6°O1Ó0ÓÙœéÖ˜é>›á¦ýQ›J‘÷‘IEND®B`‚routino-3.0/web/www/routino/icons/limit-4.7.png 644 233 144 1305 12573351603 14574 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“zIDAT8Ë­”½J+Q…×As‡‹š+ AQ› ­·ÔZ#V"($¸pKm,ÄN,Ôΰó‰ˆHŠSøƒ *:3ç|·˜IŒ?ÜÊ ‡Ã™³Ö¬³ö’„1É ‰Tji Ï+ÑÛ ¿~Yz{ÁóJH[ɽL'ÔL”JyH )¤5|ÿ‘|ÜÞB£ŸóyðýG¤µÄßKâ%:; ]]bhhéœÙY¨Õ,ᜥÝâsD­f™霡¡ººDg§™Œ˜›ó‘Ê‹¯€# ! Á¹·Õüx¥X©ÌÜœO&“ü¦´N.†`-ÖZ¢(jåÃ0^//¸8i@.Òz“³,¾ÿ@¥W´çÎ9þkq!G¥¾ÿ€”íø#ýÕÊÊo-/[E‘qž'cŒ...tzzªááaIRµZÕîî®Êå²ÎÎÎô³»[étÚ£¯Ïzõúwé˜ý}›@ÇZËØØ333- GGGLMM1==çyÆÁ²¿Ò±èéq\^’d X,288Èââ"A´øÛÜÜduu5vorzy ==N¤Ó–ëkšTïìì000ÀÒÒ£££T«Õº««+&&&(—Ëï“]_C:mœójš1F“““:99Q½^W©TR£Ñ$ííí©¿¿_ÙlVÖZcâ  œóÞqF&¼moo3??Àøø8¹\Žä1£æ‹¶q&mQ(Ä\†!6ÑØÓÓ÷÷÷Xk¹¹¹Á9ÇÝÝÏÏÏoòˆ G m}ÖY›P¿²–þ¾ÐÙçxƒß ü¸·ù|è€oíÍoß:ϾqÒþ.ÄÑ¿wIEND®B`‚routino-3.0/web/www/routino/icons/marker-68-red.png 644 233 144 2123 12573351601 15431 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“IDATHÇ•UÏkI}U]5F10A"LA²‡˜¼åd~8ˆê\Ýä’ƒ9å–9,¬ÿ›Ë`ˆde7sñ  ìÞ"ˆ’Ã"‚™‰d¼lœˆ˜üèžê·‡ªžL&,î~Ð|]E¯¿÷ªß×ÀQÈ®®. ÉdòŠÖzD.³}­µ^M&“WÀÕÉH¸ì0zµÖóÍfs’${zzÄ¥K— µFER" C¬¬¬`gg‡B¡”*…a8àï6œÖÎ{žWÀL&...šz½Î(ŠØQ±^¯sqqÑd2™]Ýù˜qܱïyÞ&ŽŽŽår™$iŒa†'.c I²\.stt4pÀ›| +%”R0—Ë$i¢ˆÁá!£ ›ÍcÒFAÀàà žËåTJ=–R‰Dâú¾o*• I2 ²¶+nea’$+• }ß7˜H$®A)õ‹Å¢!ÉððÐVll/^®˜$ùþ=¹´D>{Fîï3tLŠÅ¢qݾ€(NGµZÍI®­‘çΑ§O“™Ï[Àåe»>sÆæ±1Fûû$ÉÚ—/L§Ó‘ûä`ò®¨wyõ*yó¦½õŠÌfÉoß,øð°Ý_[³ÀOŸ2V=ŸÏ€Q¤Ö°‚õ:°º œ= ¤R@: ܽ twù<03\¿|úŒŒcc-÷8)DÕjû{{PÎ288°à÷ï/ÓÓÀׯÀç϶º^  Rvw[ÚÞÞ€RÊ€ùuiÉžèî.ÙÕE.,XNµ©µ]÷ö’÷îÚ… lÞºE’üóåKˆ„<Ïû³ÙlXþøÑ~9ccä¶pa‚|÷Ž oß¶û>0êî&ïÜaƒäÐÀ@Ó™`©T Zëß071’dóõkòÔ){Y(X 'Ol×BÍȹ³Ãé™ãÿŠ5Îh­7°07gH2ØØ >$ß¾MoóÖùèÃçÏI’¿//GpO1*B\–R@³´¼lõ-Úá¨ØžÕ­-f}?ö~¡´J©9ÌúþÑP ‚Þ÷&''C7[K}}}ð<¯5¡,¼RrppZë’.Vߎû}~~Þ8Àjk:µ=tløZë  «¯ë,¦½¾¾ÎT*ePJùc'íÎ8©o©t¬ÃF£Á¡¡¡Ð _„ ñ8¦¯ïûA<I²P(ĴפfggÛKÿúއ$Y*•ÀH))„¸ì÷¾ Ø©¯Rª€SSSÑððpL»àh«ÿ xL_Bhºÿèïï‡RJþ_À–¾.ÿäy¥”U?t°9ÿk«Š9`ˆéIEND®B`‚routino-3.0/web/www/routino/icons/marker-70-grey.png 644 233 144 2655 12573351601 15630 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“bIDATHÇu•MhTY†ßïüܺuC‘ª©ÅHV§HŒäLjBt¡$`ÛÕÐqÕ`oÌbf13aèMSµèÁ͸uáìfˆBŒšN™B#j“&jB(§°*eÅ`ÕxÎùfÑ©ê¨=/¸÷rxÏwŸïçP.—î„R ¹\ÎæóùÏ™ùb†G|ßg„ŸÅ±XŒ´Ö‰è›\.÷Ï|>/¢( ´k*™Ù0ó¯µÖ—‚ ø* CN¥R”Éd „h;Zk±¹¹‰z½ÎZkrg& Ã?Ñk"’Œ ˜ÙèQJFO:ŽN:%†††(‹ácù¾••. ¦V«}åyÞqcÌ)fþ‘ˆ„|ÖÚï]×,—Ë¿²ÖÚþþ~J$èïïG<ÑOC*‘H`ddÉd'NœÀÈÈ–——ùÎ;Âó¼ÿZkOÑ”Bxe­=ïyÞ½û÷ïsWWŽ=Ú)3£³³GŽaggóóó‘ã8šˆ¾%¢(  ‰hQñG"’·oßß¼yóI5´ZµuØÂÂBT¯×µã8Wÿ @ˆZƒ2$"qìØ±K±Xìj½^×7nÜø¹VöNhfH)ñàÁûðáCÕÑÑQ ‚àOÅb±€km¦ÍÍM6Æ|ïºî—år9mŒ±}}}dŒiG-„@µZŵk×XkM~KDˆH0 òù|{¨ !”¢d­ò<KKK¼²²)%¬µ "„aˆ™™™(!¥¼DDWè]ŒÈçó­‡]}Â÷Ö­[áööv»ƒ …‚-•J*‹ýàûþ·§OŸÆ^Cì‚ÅGÆŸðàÙ³gXZZ‚çy°Öþ^)Õ\XXx/w¹÷å—øÆb±/+•Jz{{›Ÿ>}j†ÔZO˜aæ6Ç=A}põö\Ù @ÄÌãBˆEß÷RJ*¥ CCCŸ¯®® cŒýØðƒßÿ -¾ÿbæo\וRÊ’1æwÅbÆü?ý”°ÎªSOIEND®B`‚routino-3.0/web/www/routino/icons/limit-2.5.png 644 233 144 1405 12573351603 14571 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ºIDAT8Ë­”¿K[Ç¿3²ë¾aÅ5vºÅ‚X¤±Ia£`£(˜j‹Õ-´´ðxðʤ\,,µ X ¢Xˆ0 >˜rW×øc‹HvîÜûyŬ‰>Szàr¹?Îáœ/Ÿs„$$áû>’$r¹×HËxÞ1…¼xa)ÀóŽ‘–;ïBò;~B÷r9ÉããÇÒ'‚à'óóðå‹£Ù„V šÍôßköŽ øÁÉIZˆ1¸_U9œsüÑ’$Íðä‚àÒ»®¿¥T­~P¥b1Æ÷2ý{|¬õõuåóy‹EI’1FÚÞÞÖÑё޼}«îlÖãåKë5)Šº„±¶† ppp@OO£££”J%¢( Ùl†!ÓÓÓ”ËeÎÏÏéˆgY[)òÕÛû^##Bò%©^¯kqqQ[[[ÊçóŠ¢H’´¿¿¯››š˜˜P†ÂZy’¯‘©·÷½èë³\]`SØÛÛchhˆJ¥BÇìîîR­VY]]% C677Sé®® ¯ÏúrÎSËIò»ºtxx¨±±1•ËeÕj5%I¢ëëk5 hnnNaêòòR÷Ð+Ž%ç¼_š™ŽfµZL&Ãðð0ýýý¬¬¬0>>ÎÎ΃ƒƒ fggI’’ä‘fBZfa!Í8I¸»»ãâûwNOO9;;ãöö–V«…sŽv»ÍÅÅÅoþRÖ@Z~ÂY‡Ÿ'ö9k-îœ=ícpÆë»ÅIrgœÖ öÚkÿ?kíõ¯%$!‰0 ‘B$Q(üƒtLü Žáýû”8† øt<ô )â„FD…B€P.>E¿¨V¡Ñ0îï¡Õ‚ûûÌ®V!Š~!}¾†x‰|>djJ,/@ºegîîRÀc–òûÊlÏÝ]ÊÎH·,/`jJäó¡XX»»ÒO€á8fÿïÑ0àð¤ŸìîF,, Ó”jìí¼øÁ€4¦)Î9ÒôÏñï)¼°·Rmôg‰¢.··x0™Ù« í7.yŸExsQÔEú(¤c0ðI’Ðl6¸¾¾¦V«quu5&‘&I¿77ÞªUŽ…ôz =­×ÉårœÑn·)‹T*¹¸¸žžž’Ïç©ùº¯_Aú–Ó»wŸ´±!“Â`bB¥RIf&ï½ŽŽŽ´´´¤f³©Á` IòÞ+ÍÍÍÉ‚@’BmlHÅâ§P(Ÿ—I*W*Z]]U«ÕR©TÒþþ¾NNNÔn·DZ$ P¹\ÖÊÊŠúý¾$I““RÊ,ÐË‹FË9§ÙÙYŸŸk}}]FCÓÓÓº¼¼ÔÓÓ“¼÷’$3“`’Ì‚PÝîw%‰$™$ÍĮ̀ßïkkkKóóóŠãXkkkÚÞÞÖææ¦z½ž$)Š"Mær’dA’HÝî÷q5OšÒétx~~À9ÇÃÃÎ9ÌŒÇÇDZæ:Ͻ^†;8W3ÓYVf#Óf6¦iú—îÈ|éì0ç¾ëøì=Cq¿ê€7íÍ7o:ÏÞpÒþñ¼o¦dˆî‰IEND®B`‚routino-3.0/web/www/routino/icons/limit-16.7.png 644 233 144 1456 12573351604 14667 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ãIDAT8Ë­”ÍK›YÆïú‚Ôà*CÇî‹àD» H@BÑn EôÈ?00Ëvm¶ *T誫q#2ÍB¡”Æâ'"Ô…A4¥Æš÷½ç™E’©Ò­.Üó<çÞËóïû_€:;”äyŸÔÝ-¥RNÝÝ’ç}”šçü&Ñ"êìôžfg;/ß4?/½yc:;“..¤³³Æz~^ ‚o‚—Í|¯‰Åã¾::P&óH°¯éiéôÔIŠdæt7ëH§§NÓÓì+“y¤Žû(F…B ØU±(I·’La(…¡döc´ö$“t«bQ‚] Òéæ3á•ff$©ÝÞÊ5rÎ) C9çî\Î~ÿ®°^W(ÕíéS ^µþlPAPÕþ¾"ɬIdf2³{$÷¢QÀ´·'AU0ûþâÅ‹ßõü¹óÁÿçÝ;¢("•JqxxÈÒÒ]]]ô÷÷p||ÌÊÊ »Ÿ?óïÇ^bxØýòõk—íìļ×Úš$¹×kkjoo×úúº$illLSSSš˜˜ÐÑÑ‘$issSãããÊårò@ïì8½}«Þ·‘Lóä ¾‹‘J¥H$lllppp@>Ÿgdd„t: @6›¥\.³¸¸È¯™ <~ìÛ—/´%“Ã>±˜ˆÇ1`öÙ3†††¨Õj˜===LNN²¼¼Ìöö6mmmT*J¥ÅbÚÛ!“™G½N+$af$ ‰sssôõõqrrÂÅÅ«««ôöö284„ü(3ϧZýÀÖ€$“I®¯¯Éf³ £££äóyr¹’(—Ë …V}ck ªÕJZX¤HÎéêêJ777’¤(Št~~.çœÌL•JEf¦ËËKÕj5)Џ… J?t¶·×ÐM#Afö¿X[d÷œÕÈ»§³Ÿ`aتø“X[s‹¢–­êš™¹ã€õæƒvígØiÿ 1HO‚40üIEND®B`‚routino-3.0/web/www/routino/icons/limit-1.2.png 644 233 144 1264 12573351603 14570 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“iIDAT8Ë­”1K+A…Ï®ÄEIòÒ_eaá/H£–!E¬RØ%¥E~†‚…EÀ°ÐF°± X !˜Bˆ`4 Q0wwæ{Åf£Ææ90ÅܹwæÜ;ç^! I¸®‹ä"‰Tê/RÇé’ÉÀŸ?†L§‹Ô˜œ ÉÄ Å¥R’Ãîn éÏS­ÂÙ™e0€·7 ¢}µ ž7F:˜ø;“x‰DÂ%™ùüÒ=Å"ôû±ÖðÑ>¤ß7‹ ݓϯ‘LŠD¹œ(•<¤;êu€OÀ`í׊m`Oêuî(•~L’ÜÙÚb±X´ÞrH§§§I’É·oŽ×Ôyö¬›¯¯; •·ö‡³Z%/\pû¼¶ÓÓÓ*Rk xg®]nÜ®\>Î&'ÝýýÀ‹À«WÀë×@ÀãH À¶Z-t:(¥ð§OîåvØÛ¢Èͳ¸}¸~’"ÛÛÛ`!¥Œ¤¿ß½ënôëWRkriéðšÏœ!gfÜüéSòÄ Ò{9‰c’äêê*X!DŒ ~À04Mo©´T"oÞt ?’§O“·n¹õÕ«d¹ì.Õ[jooccc‰/‚ßP( µ~€•ÉIC’É“'¤R¤î’Οwd yò$yçŽ;Üûynn.õ€(d*•´Ö›X[XHI2n6Éû÷É—/ÉÌyïE4^™ååeëÿBŒf€ „¥”4=rúz«ôVTVû­V‹Yí׺ñ@ ! ”Zðú6•8>Z¢ÆÔ|µZ5¾·6Dw(¥äèè(´Ö ß\L·±1ñ¥¥¥Ô¶ºSWÛCσPk`­VsúzÛd´766X(R”RÎôÒîãú6G2ôö1¾Õý*„ïÄ}Ã0Œ³–H’µZ-£½ 0??ßýYú÷èÕwÒû·Ñh@*¥¤â¢=ø.`¯¾J©gggíøøxF»æi«ÿ xD_? ! ñþ9<< ¥”ü¿€úúñç (¥léas,þ=l?0§eIEND®B`‚routino-3.0/web/www/routino/icons/limit-14.0.png 644 233 144 1367 12573351604 14657 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“¬IDAT8Ë­”AK[[Çÿ÷ˆ÷†ÛÔJ7B_ॵ~"¸¾Ñ~!®‹Å/Ñî\¸ÓUB_¡«§kq¯²($DÚg@Pì3¥MÍͽçüÞ"É­•·tàÀ™9ç?gÎÌFHBÆ$ƒ$r¹?vñ¼:““ðô©er<¯Ž´;<’â„FŽr9Éc}=‡ô–0üA¹ ?:..àëW¸¸èå2„ᤷÃûÞ/áû† ssÏšDœŸ[ Å9Ë]è)çç–(©ÉÜÜ3‚@ø¾33bu5DúÄÖ@ 8’’œûµF6p@ÌÖHŸX] ™™~SzÇÚ@?c쀵–4M Ðöû$qŒƒ>¥HïF9{N~£Ù$çî8rÎ᜻÷Ó¡ÍZ8×h@~Cz.¤]67qsvv–›Í&GGGY”Fƒ>·Z©+—AÚÒ)Õ*€ý«ZÅ÷}*• qS(XYYÉœ_]]±¸¸ÈÂÂÅBÁòáV:5š˜x¡—/å$ãizzZ€$i{{[½^OSSSÉÁÁ‚ P­VÓã'Oô÷û÷FQ$÷èÑ £±1äûr’Ö_½R±XÔøø¸U©T´¼¼¬““µZ-IR’$Êçó’¤ÇúÙíJA ƒ‘sžúýìe眬µ2ÆhiiIµZMív[õz]½^O³³³º¼¼T»ÝÖ?_¾èÏbQúþ]xYΰQ±¿¿ŸåhooR©Àüü<777lllÏçyóú5€¥ZÅI§Y5két:ÜÞÞfÕëv»t:¬µ\__c­ýµãns3«æ€gÆ€Ù÷z_œsŠX‹ýžýÖ.I¸ïpDÜŒÀiÊÜ}ÖÖîtÀƒöæƒNg8iÿˆî•W_ÁαIEND®B`‚routino-3.0/web/www/routino/icons/limit-3.1.png 644 233 144 1264 12573351603 14571 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“iIDAT8Ë­”¿J\QÆ÷¯r-vYD‘-„¤4B@lÄN±pmíô|ÛØ[Ø/Xø[؈!bÁ°6‚`ÄÕ Éýs~)î®qcJN1s¾ù˜9ç›A@À8Ž…XÀ‰‰ÂQôÍz]Òz]£è›p0¸GˆyÈhb""[­ á³iúÓím=>^]ézuUùÛÛš¦?…Ï|4È“$v|çæÞ ß][ÓËËR- ¡ô¥U~áåeéÚšÂwçæÞ;>ŽIãÌ ®¯§B×Ý]Õßj0Ï5Ï5„¿gÓ þvwW¡ëúzêÌÌ MØwcC5³(,³Ì<Ï-ËÑÂT‹¢°Ìs-Š ¿±¡°?|³¦ißóóª‘ ô¢³0BôìW¸àù¹¦i_øˆpàÎŽj²LÕn·ëþþ¾gggÏ„C’N§ãÅÅE¯ð…;; _l·-µTíõz6 777m6›žœœ<™$‰ív[Õü×/ÕÒv[áË;jµO,-ÄEQ°··Çìì,½^,ËÆ£(bjjŠÄq•·´µÚ§wı$I(óóó4›M¶¶¶¸½½¥V«Q]I«ÕâððÇÇGF,I Ž !"Ë(¢ˆv»Íââ"ÇÇÇLNNrzzÊýý=EQü­ê¥e„Åôû_étˆ! ¬®®2==M½^gaa••–——yxx MSÆÆÆ0:è÷¿Žüæ@æyîõõµyžBðæææYswww>==9¾úÍQ½kY–#:ûG½ÿÕÙ« ð¥8ÿnÁ!æõ¼él¾éÖxÓ}ö†›öólËŽ…²IEND®B`‚routino-3.0/web/www/routino/icons/marker-42-red.png 644 233 144 2110 12573351600 15414 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“ýIDATHÇ•UAkI}U]53ÎÁÈìaZ –$CbTŒ"Á‹²É*{<éûÌæXBXÁw"zA7·Y1{›ÉAsØbÈ$SÕUo]ÓNÆ]t?hª«{êÍûÞ÷}¯Ï! …‚€|>^kýø°²s¯µ~“ÏçÏ@8'Û@"¬à;­õL’$$yèÐ!144­5¼÷RÂZ‹ååelnnR!”R5kí]wàdÿp,Š¢–Ëe;77ç¶¶¶è½ggxï¹µµÅ¹¹9W.—-†sÇÚ·ÇQ­`¥R1õz$霣µö‹Ë9G’¬×ë¬T*&¯ˆSX)¡”ZÀÑÑQÓ3Ƥ,“„ìdë½14{{øèè¨@¥Ô‚”ÈårcDZk4$Ikm°/ºöÖ’d£Ñ`Çs¹Ü”R¯pvvÖý+àóçdƒ$ùþ=9?O>{F¶Z´IB’œuí+ð¥RÉolld…`ø!I€\XH÷¤ûR)]¯\É ¹±±ÁR©äCËÁ“$“$ù øö-yøpz¸VKŸõô7n¤÷¯_§ïžzDC ¤Rd>OJI õÓ;.þ  Ø6”²ÖzÙZÛ[­Výôô´´­4 <~ œ9”ËÀÓ§@³ H¼‡:x¿¯®òÇ©) ±ëïIþ „g¥”ÔB eƒÐ.dòa}GNœHg_©j ¨²nB@)u7èkêad]«õyö­%¡3†ôžׯÛà­µžžDQ”9T ¯”(¥äÿÌô ëTE”R~p¢+›/â*Ÿ#IÁ¼¦IEND®B`‚routino-3.0/web/www/routino/icons/limit-5.4.png 644 233 144 1307 12573351603 14574 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“|IDAT8Ë­”=K3Q…ÏnaÂ6F-\+ň`iþ@[ƒ‚Vb¡ ù‚BKAL™J;{ A¦°ø±~ …d÷Þû¼Å&j^´ËÀw÷̹³gÎŒ„$|ßGò‘D6›GÚÇó®Èå`xØ’Ëç]!íw¾ Éïä u‰²YÉcy9‹´C|°¹ ÇÇŽû{x}…ûûô¼¹ Að´ÓÁ{|‰ŸLFŒO"Õ)• Ñ°€Á9ËÏHφFÃR*Tg||’LF øbtT,,H5¶¶Ú€#I IÀ¹ï§ûÐfk ¤ ££ß”vYZˆI’v›$IH’ç\OqÖZL» Ƥø¥%v»šÍïÜܤ7¦ _Ã9÷Mžâ77ïH3BÚ§\0CDZ··ÇÁÁÍfó«"€z½ÎééiJÇi^¹ Ò¾.¨Vq`¢(" CYYYáááá«*k-SSSÌÍͥŵۖj¤ _ƒƒ³*å$_’ÎÏÏÕl6h~~^aÊ#Ïó´½½­V«¥‘‘Iž'I¾ŠEippV YžŸézàììŒõõu*• arrrÀáá!a²ººJ>Ÿçöö–n[y~†¡!ëË9Oqœ:XÒÝÝ&&&´¶¶¦±±1=>>Ê#çœ …‚.//Õh4t}}-Ir’Ç’sÞ—f¶£Y­Vczzš\.ÇÆÆOOO ¢( R©P*•HZ­Íz»™’V«EEXkqÎñòòòå¹ÏÏOÞÞÞRMR|O7{|æ~µKöküá³Þ 0gLÉÿ„Θ?& ¯³Ù×­Ñ×}ÖÇMûdh¾ÜFªNÇIEND®B`‚routino-3.0/web/www/routino/icons/marker-63-grey.png 644 233 144 2715 12573351601 15627 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“‚IDATHÇm•Mh[†ßïü¤ª+‹Ð4I MìQ’”rm†ë¨H”’ 8܃7x7º˜YÌÆ; Y2Ò¸™Í¸™…›YBü›ÌÆ$(¶™ ÊÐÆî$[2ÛØÝËIýœsfaº&þ¼PPUïùêùÞóÖ˜ccc:—Ëõcþ†aÖ÷}€ð˲HJùo"»—ËåXE €¶L¹1FcÚ¥”—‚ ø1 C“L&)“É€1;j­Q.—Q«ÕŒ”’šššÆÃ0}ZîÞ½›8ç0Æ|u !N§iÏž=¬R©„ëëë))寵Ö7Ƽ烃ƒð×?ötuu…gÏž•¶mCkWƈ`Œ(¥à8²Ù,ùòe¸¶¶–²m»5‘HüƒA0ÁO©TJ É7Î9c`ŒÅFƘø"^xhhH¦R)ÁOA ð£G^õ}¿cppÐtuu‘R œsT«U,..Âó<$“I} ÀÊÊ ^¼x(ŠL&¡µ†ã8Ršb±HRÊnEÑ÷ÉdÒìÛ·ç•JW®\Að<®ëbxxwïÞÅìì,ZZZP¯×ÑÛÛ‹¾¾>€ëºìþýûÆó¼ï™ïû&“ÉP"‘€R 055…t:óçÏãÌ™3X__Ç›7o0;;‹ŒŒŒàĉ¸wï|ß8ŽƒL&C¾ïñ©ŸrÈ9Çææ&ÖÖÖÐÜÜŒ‹/"‘H ¿¿íííF[[J¥ŠÅ"\×…eY0Æ€ˆyfŒs®766†aÜí0 áû>Ž?Žöövܸqõz®ëB)…›7obii MMMŸå×ó<0Æ4³m[=þ\/,,@›žžìß¿'OžáéÓ§XYYAKK .\¸€sçÎáÑ£G(•J ",//cyyÙØ¶­€? !X>ŸªÕ*,ËB:ÆÒÒàÉ“'`Œ¡¥¥—/_F±XŒ+BÄÕNNN*ú¤¿ñS§NÍonnv¿ÿþ»J¥e³YÖÚÚŠ™™äóy<{ö ‡ÂÁƒ†!îܹƒùùy d³Y>|zii‰Û¶½†áohttvH)ç?|øð‹cÇŽéÁÁAV­VQ.—ÑÖÖ†;vÄÕ½zõ ëëëhmmEgg'ÌÕ«W©¹¹ù¿Zë_ccLøÖúŒã8÷çççMGGöî݇¾Ñ]c vî܉ÎÎN666055Y–%ŒÑ"ÁD$Í0Æ~&">99Öj5´Öñnj7¶çôôtT«ÕdSSÓ5×uÿ€ˆƒ2$"vàÀK–e]«Õjrbb"jm—1œsë8æææL±Xç<Ɔ!ÆÇÇ£ çü] ·0"—Ë5n¶ôßÛ·o‡õz=>Ròù¼^]]–e-ú¾?Úßßí†Ø‹/Œ¿â{ëÖ­¨±æææà8´Ö¿B|œžžæÌvî|û÷øZ–õC¥RIÕëuóøñcåy—RþÀ¸1&渭(|ÞZÛŽl 2ÆeŒÍø¾¯„\‘w]·¯T*1¥”þÒð³ßÿ†ßcFlÛæœóU¥Ôï …B<{¿¥ÿ—?ÆF­ŒÉ‰IEND®B`‚routino-3.0/web/www/routino/icons/limit-3.3.png 644 233 144 1244 12573351603 14571 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“YIDAT8Ë­”?K#]‡Ÿ™]b‹Œ) (ì[Ha;;ÅÂØÚéðØnz[«tù‚h㺰E K* AD!°MæÏ}¶HtÍëË[9p™{ŸùË=sç `ÇB,`µúpfý4Mµ^/MS¢ŸÂÙä;B<‰C^6ªV#!²Õª ßL’ßi·¼¿×§'½¿¯Ž4I~ ß&úhV*±33¸²òEøåî®ÞÝ•ja¥oŸñºðî®twWá—++_œ™ÁJ%Æ…ÜÛK„ž''ª#5˜çšçÂßñÂ4¨#ONzîí%.,LÒ„¶ûûª™Ea™eæynYN¬,Ë1Ï2-б~_¡ýòÏš&ÉÐ~œÈXô&³0õ~åc]°ß×$ M„3U‹eªöz=Ûí¶777¯'ú/>Ñ+œ!|·Ó±ÔRu0X¯×=88°Ñhxyy©j¿ßŸâWWWŽw²´ÓQøþ™Zí+››1@Qœžž²¸¸È`0`4ñˆÙÜ„ZíëgâX*•(PVWWi4òüüÌÜÜÍf“åååW^«Õˆ*ˆccBˆÈ2J€(¢Óé°±±A·Ûevv–ëëkÎÏϧøíí- Ë „(f8üÁÅ1”æççIÓ”µµ5¶··Y__gkk‹¥¥%Ò4¥ÙlÒjµø‹ LÝæÄæyîÃÃyžBðññÑ‚EQ¼ò‰ðÝmNûìY˲œòÙ©„ùì]XS&}7ŸhÞWÀ‡Öæ‡vígØiÿž0eý>àIEND®B`‚routino-3.0/web/www/routino/icons/marker-30-grey.png 644 233 144 2677 12573351600 15627 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“tIDATHÇu•_hTÛÆ¿µÿÌ9!f´ ÑSe¢âL@‚Äú ŽzÕÄËpñ‚¡>ô>Ü[J@ÂTæ­/õ¥öÉJmú" ʤQ"%PÇ8£Žšà”ØDqÌDÏŸ½wÌœFk?Øp6l¾³Öo¯µ6e³Y¬ˆ !Ífu.—ûÆó‡ º=Ï3ÿ•±,‹¤”ÿ$¢l6›Ïår, CÐ@+¦Ü£Œ1?“R^ô}ÿû L<'×uÁ‹µÖ˜››C­V3RJŠÅbCAœ#¢ fŒQ¶ !ÆšÍæÖD">|˜¥Ói², _Êó<‹E366¦Þ¼yó½ã8¿PJ6Ƽ "Æ÷ïßot!îú¾¿5™L§OŸ–Û¶m#Î9Œ1ÿ³„ظq#íÚµ‹-,,¯_¿NH)©µþ«1æïëë€?-//H&“ÁÙ³g¥mÛPJèJƈ(Úc ”‚ã8èîîæ³³³Á«W¯¶m¯_³fÍߘïû½¾ïÿH$t¿lqB€1ÆŒ1‘1!´Ö€þþ~™H$´ïû?ø¾ßË3™Ì_<Ïë8~ü¸I&“¤µc /^¼Àóçφ!ÚÛÛ#ÃÅÅE”Ëe„aˆx<E,„0¥R‰¤”" Þx>nšÍfó<ϸ®KŽã|ßG>ŸGoo/pâÄ äóyÀ½{÷àº.Ο?“'OâÎ;¨×ëÇqàº.yžgاàXÄŒsŽ3gÎ`ÇŽ(•J(‹Ø½{7|ßÇË—/‘J¥;wî„Õj5*µÆ8çºÑh ‚èR©´Ö¸~ý:ž|ø‚ „T*T*cÛ¶b~/„`ù|>|ÿþ=”R¸téŠÅ"DõDZyóf¦”­[·099‰B¡€={ö §§‰DSSS¸ÿ>ž>}ŠL&ƒíÛ·cxxX—ËenÛöLßÑàà l’RN.--ýüàÁƒº¯¯ÍÎÎâí۷ذa6mÚuÓ»wïP©T°~ýzlÙ²333æÊ•+ä8έõcÌcÁþ¥µþ•ã8Ÿœœ4èêê‚ëº ¢Ï:jݺuèîî¡Ñh`dd$ŒÅb’ˆ‰è1Á„$3Æ~CDüæÍ›A­VAkEÙúA«=GGGÃZ­&c±ØÕT*õG @Ø”±½{÷^´,ëj½^—ÃÃÃaËhµZµ<55¥§§§ÅÚµk«¾ïÿ®P(Dñ´ÓÜÜœQJýöíoçççJ)ÝÙÙIJ©h°0ư¸¸ˆk×®)%ø5M‘ €år¹h¨3Æc¬ªµ>ë8&&&L±Xç<†††Bß÷çü"] W0"—˵>VôU¾õz=ê ±±1]­V…eY=Ïr$ããã’¤8޳Ú}ü(½Ÿž˜FG³¸Z•&'³øþ}©T’ž=Sœ H|À:çÆ@_ìÜ wîÀ½{ðð!¤)|ø{ödóR«A³g°o9ŽH<¨õõõîvrà€45õ¹3çÏg´“êõ,nµT´¯ÑhH°Ö†@rùò嬣Ù‰ùyiÇ)ŸYIÒêª4=-<)]¼(õõ)¾y3«ÆÝ»RcLˆçy¿ª×ëQwè%éÔ)©ÑÈg'ÊüÑ£Ò¹sY<=­t`@êt´¶¹©‘áá8ÁŸT*œsWŽF’¯®JýýÒ¥KÀæfæ¯_Ï(ƒ´k—’7$I?Ÿ9“䀕B¦5çÜK@Í I çæ¤\ JÓÏŠZZ’ææ=~,IºvíZš®c† @À3j­·Z­Œuk‹å ,äùúÕ+ÕëõBûÍ^<gŒÁ÷ý)@õ —_¼ØÐ œäòœ˜˜ˆòÝÚÚ½{7žçu7Tïûvxxç\+_.QW½zÏ›633“䀯»Û©gí±íFàœkj6›Y}óÌŠ¬U©T@ÖÚŸ¶ÓÞn_¯ožáÚÚšFFF¢|ÕýaŒpü‡m©oa±%©Ùl´Êäädïgéë¶½¾‡Ž$©Õj H¬µ2ÆŒö|߾ɺõõ}¿ èôéÓéþýû ÚÍœ¶ÿ­€[ê ühŒçþµwï^|ß·ÿ°[ßÜÿâyž¬µ¯ï·±ùÂþA™L|ëã/IEND®B`‚routino-3.0/web/www/routino/icons/marker-80-red.png 644 233 144 2106 12573351601 15424 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“ûIDATHÇ•UAhSY=ïý÷’6X‘œE~-Òq“Z\.´¡c„¸uRÙ¹è®Yn]¸œlChg¡LÍÆË`g×E7.Š´¸0)4º˜’*)dÚþŸ÷Ï,Þûiš28sáqóïï¼{Ï¿÷82944$ ™LÞÐZ¿@‘óìÖZ¿O&“7À“1pÞ`ü µ.u»ÝIމ™™h­E¤”ë««ØÝÝ¥B(¥ªa.ø«§wÃyÏó˜N§ÃJ¥bÚí6£(b¿EQÄv»ÍJ¥bÒét€îÜù¸â8cßó¼-Ìf³A½^'Ic†á‰eŒ!IÖëuf³ÙÀoð-¬”PJ½À\.Ä`Áá!£ ÃìÏÖFAÀàà žËåTJ½’R‰Dâú¾oI2<<ä@Ívsì‚0H’Fƒ¾ïL$· ”ZÀr¹lú7rs“\Z"ß¾%÷÷.ØÜ$ÉÕÕcÀårÙ¸l× Z­–MŠ$«U OŸ¶þÚ5 øî)%yæŒ?~Ì8ïV«ÅÑÑÑȵL>Ÿ'Iv쎛7ÉK—ìï,ÀÊ yç93cã‹‹6¾µÅ®Îçó`$©µ\g<Ö×Û·û÷«W €Z ¸wÏîÉç­_[ëMÑ @Ôl6åþþ>† €øôÉîj·Nøö ØÛH`dľSÊú èMÐÎÎDRÌïKK–ø¯_I­ÉRéèã\¼HÞ½Kž;G¾xacŸ?“»Õ*IòÏZ"!DÏóžà¸ï‡u×R&&=²‡?~$GFÈçÏÉB¼|ÙÆŸ=c4ÑïÃñ±g6ƒ»;˜Ír¿ß‡0|BÚ/ð¦àK¥RÍæ¤)QI†ïŸ-÷3’ÄE Mi6ÿP©ˆ °¢ÑÝnˆtÍpðxÒÒ¼ÿxïÀï ‡ ]Óí†4ÅoJôzs² ² çYqȲ ç=8·:§×é`‘³aøÈd’+dï=Þû/>ûÎ3™@>"µ„4b0È 5œËS5N999)ù§§§ÜÞÞ–b>c0i$¤sâÀñIÝ9Çææ&ÛÛÛÄqLÄ9–4M_çˆcέjµ¶:I²2FÆIÒÞÞžÞÞÞ´¾¾.I2ÆhccCÞ{•fmÎët¤Z­me- I’+€‡‡‡:::ÒÖÖ–ÎÎÎtss£ÝÝ]µZ-½¼¼è‡d-VÞÍç_j·Ûº¸¸P’$ºººÊŜӯ6ŸKÞ›9+óŒÇc¢(* EãñxiΖVÓ9Çóó3÷÷÷e°‡‡^__?Úã—jþÚgÿµ%}¶tÊ~ú~þÀ|›€•ÎæJ·ÆJ÷Ù 7í?Ì~o¤WEäIEND®B`‚routino-3.0/web/www/routino/icons/marker-80-grey.png 644 233 144 2716 12573351601 15627 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“ƒIDATHÇm•_hS[Æ¿µ÷>9'§Q”Nm¦’ŠâPÇ1âEoó2Ü /x_FaæÁ—™a¸ %y»/#È}½‚R+NçEÛ3íØª„!ÖT+&Ž Ú¤%IilÏŸ}Ö<ØæV½8ßùöo­½6e2lH(¥Éd‚l6û3ïy^Òq@øIlš&†ñ"ú.“ÉÜÏf³Â÷}€6L%3kfÞmÆU×u¿ñ<#‘Åb1!ÚŽA \.£^¯³a …F<Ïû#-‘ ÁÌ@¯R*×jµz£Ñ¨êÔ)ÑßßO¦iâS9ŽƒB¡À¹\N///cÛöo´Ö§˜ù¿D$äñãÇ@·Rê_®ëöÆãqïüùóƾ}ûHJ fþìQJ¡««‹:$ªÕª·´´5 ã·Aü™›rpp~xÿþý‰x<î]¸pÁ°, A´“ !@D ú€–™¡µ†mÛH&“òÍ›7Þ»weí ‡Ãÿ®ë~éºî·Ñh426¹I)!„€ÌÜ6#"! ”jÿxhhȈF£ëºßº®û¥L¥R7ÇéN§ÓÇIk )%jµ^¾|‰f³‰H$ÒN[«Õ°°°ß÷‰DÚ‰•RÜ,ÄÀÀªÕ*nܸ۷oãàÁƒØ¹s'J¥‰àÀPJ¡R©|TPBI)ƒ••áy¤”€ååe03Çã8hµZX__3# m5hïZ­„²,K—J%ÌÍ͉#GŽ`mm <@:ƱcÇ×®]C.—Cgg'ÖÖÖžç”R€b±ˆb±È–eià¯J)‘ËåüF£p8ŒŽŽ,..–––Ðl6‹ÅÐÝÝ|>ÈçóPJ!‹™1>>®éƒ~”çΛY__ïk6›¿Z\\ô“ɤرcîß¿©©)ÌÎ΢«« ét{öìÁÌÌ fggñêÕ+¤R)ìß¿cccÁ‚´,kÎó¼¯ixx~aÆÌêêê/Ož< Šz½Žr¹ŒÎÎNôöö¶y7›M‹EìÚµ ===˜››ã›7o’mÛkAüš™Ÿ+!„ð¿ ~gÛö?gff¸»»‰DÛ·oowÄæ‰Ú¶m’É$ˆ+++÷C¡ADÃDô€|M !þDDòÞ½{^½^AkÝ6%"0sûxNLLøõzÝ…B·>ü7€¿9(="G½jšæ­z½nŒù[[gkZ)%=zŸoÏyâĉͩ\.³Öúß–e}õöíÛ¨Ö:èëë#­u{°!P«Õ0::ʆa€ßÑ#"R4ˆl6ÛêB%„¨ApÁ¶mLOOs¡P€”A€ˆàyFFF|×u…”ò*Ý`l`D6›…Ø|ÙÐg|ïÞ½ë56†\.T*ešæsÇq†Ïœ9ƒ­†Ø‹OŒ?ã{çΞ={†ééiض .)¥ÞOLLH¼•»Üºø9¾¦i~U­V£FƒŸ>}ª[­–4 ãÏF˜¹ÍqK¨®^À–+[ð™9%„˜tG+¥¤R*×ßßÿÅüü¼ÐZŸ~´ýŸÁ°ÉwŠ™¿³,KJ)+Zë?äóùú÷Sý‰Áè^r»aIEND®B`‚routino-3.0/web/www/routino/icons/limit-162.png 644 233 144 1446 12573351603 14602 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÛIDAT8Ë­”¿K[]Ç¿÷ŠÉ}/·*I BBu©N!C¥Å, ‚šÉÁRDÁÕà…Ží"®¥ø«Cx7ÁBq,"éP°:Y  ­I“{Ïù¼C’6ý1zàÀóëûå<‡ïóIHÂu]$IxÞ ÒŽó¾>H$ }}à86Zy!¹-œP›Èó$‡BÁCzïci Þ¼±\]Á—/puÕô—–À÷¿!½hÕ;-¼D,æ‹Læ>Ò'¦§áüÜÖ:OÓ8?7LOƒô‰Læ>ñ¸ˆÅ\‘N‹™é#««uÀ††`íÏÛŽꬮ‚ô‘™ŸtºÕ¦ô’¹9€QDT¯c¬ÀC†c~úß¿cfýÜH/Ûö߯pr`£zÛ"²Öþ°ÛD?:Ž",XNNÀ÷+Hºþ•žëÙ³GZX0„¡ëÆb:<tåº(“$YkU(4<<¬jµ*k­R©”ÆÇǵ¶¶¦ÁÁAÍÎÎjddD£££ZxúT’Ôåy’ëâÊZG†: k­‚ PZ\\T6›ÕÞÞž¦¦¦4??¯õõuYk%INJÖ:®*•c½{'IV­dOOnoo566¦¡¡!Åãqår9e³Y•Ëe‹E è¿bQ’¬yûVªTŽ…´Áò2@Ô$777Ôj5¢(¢\.cŒ¡V«q}}ÍÅÅ———Ô¾~mâ–—AÚøCgDQÇôØ_ÄÚ©9šñ_tö× °„mÒNÛ†!¶ÙÅop§³y§[ãN÷ÙnÚÿ$G_K`ÙçIEND®B`‚routino-3.0/web/www/routino/icons/limit-11.png 644 233 144 1074 12573351601 14506 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ñIDAT8Ë­”½J+Q…¿sÄÆ"AË€·+[mC >A|€<†ö>‚ øé´,›é¢Ü8s¾[d1Ü& N±fÖÚûüì½0Æ(D«Õ?Â¥!>æî( „±oì?ˆÔjû%‰¬¬R"„ÀÖÖê4Áææ&)%¦ˆqì;<„Zm?£T*Ì"¥D»ÝfooNOOçø*ˆÑHJшß0·‹_ø£¤"Ãá=½@â‡x}}ÕÕÕ…¼Ô'z=ï}Í ÞÞÞüüü\ȾæÂ:û/ÔÙ˜+ÒYþ­ùÑKíÍ¥N¥Î³%NÚP (ð>+[@IEND®B`‚routino-3.0/web/www/routino/icons/marker-5-red.png 644 233 144 1740 12573351600 15343 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“•IDATHÇ•U1kIþfvF2*e‚ ­Á®lBº€;ÂEH¡.»qï."\‘"? ç‚C…›pf!mÒNCÒ$p…KÉ…*9FŽãý®ØÙ•VÉ]î £ÝyïÓ÷¾yï-01977' X,nh­? €Øíœ~ÖZ,‹àâd $Üî°´Ö»Qm’äüü¼¨×ëÐZ#ŽcH)aŒÁáá!ÎÎÎ(„J©ÀóÀÉNö7=Ï`¥R1Ýn׎ÇcÆqÌi‹ã˜ãñ˜Ýn×V*€.îfšqÊØ÷<ïFØï÷I’ÖZchÂ0·¬µ$É~¿ÏF£:àc~+%”R¯°Ùl†)X† ˦)Ûp ¼Ùl†¨”z%¥ …Âô}ß’¤1f‚p}MžŸ“_¾$ëâ‚tç©ß`0 ïû …Â(¥>`§Ó±9À(JöçÏI€”’T*ùýú5jæßét¬cûâr¹F£,µ4€$ùð!¹´DA@v:¤ÓœÖfþ£Ñˆår9v%Ûjµ¹(m’þ­[ä£Gäû÷ä§OߟOŵZ-°€ÔZH"gççÀp¼yÜ»ܹÔëÀÅ\@ÎÝáH ‡¸ºº‚R*¬°¾¼x‘½} ¼{¼|™œ[›tHzèôôbH)CvooïÇ7}¿¸FƒÜØÈÞ¥©÷z=ˆ…!<Ïû«ÕªÉŠ> “ ƒƒä¶{½äù䄼qƒ|ú4‘Ö¸¼¼äÊÊJäšàw”J%h­ÿpÅoH2JÙ~ûFÞ¾MjTÁÂY«‘®ž­óÛÞÞ¶ð/¥T½ŠÖúÛí¶%É0MûógòÙ3òîÝ„aÚ .›ýýýØ~B,g×áľ/¥$€(‚‰¾?hSët‡¬V«iï·§ñ@ ! ”zâô •(J!Š’emÖó›››ÆÍÖ V«Áó<‰iSJÉååeh­ƒœ¾é­“ö$www­fÓijìaæ…¯µäôuú¥ ŽŽX*•,J)Ϧ=kÿ®ï¤|Œ¿¹Â×ø‰åôõ}?LG"I¶Ûí4í#¥éÏÒ?Û¬¾kkk†$ƒ H†”BÜwîÞOgõUJ pkk+^]]MÓn»´ÕÌé `]A‘cøçââ"”RòÿfúºýÏó(¥XšÉæ;ûcŦÈ0#IEND®B`‚routino-3.0/web/www/routino/icons/limit-7.4.png 644 233 144 1320 12573351604 14572 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“…IDAT8Ë­”¿J+QÆ¿]AsA#ø§¼¨MÀFKo©u´P¬DPÐÈ \¸¥6b'!`ç r%  1D ‚J²»çün±õú§ËÀ)fÎÌœ™ï|3B’p]ÉE©ÔÒ!Žó—ÁA2 ‚ãüE:Lî…ä&qBD©”ƒä°ºšBÚÅóžØÞ†“Kµ P­Æúö6xÞÒnâï$ñ½½.}}bbbéŠl*DXkx/±Q©²Y®˜˜˜¤¯OôöºbtT,/{H>¹@°„!„!Xûv:6°@›\$ŸåeÑѤMi•€À†!a«E†„aˆµö¿âŒ1Dí6D@ÀÊ H{Ì2xÞ#¥Rübìô¥Xkß’Ç~–R <ï)Óó[ú£ÍÍ_vcÃ8’[¾¹Q>Ÿ—ïû*‹êïïW:–1F®ëêúúZ———ú99)ÂÐqFFŒnoèü¼GHç D`ÎÎΘŸŸgaaÇq8==M ‰0Æ0==Íââblk· …Hçb`Àrw×éƒ(ióàà€­­-Âtr¹ãã㬭­Åö ˆãîî``ÀŠtÚÐhĹLÌ„z½ÎÌÌ ¾ï¿âu||ÌØØëëëLMMQ.—é|+¤ÓÆ•µŽ‚@’dŒ‘$åóy +“ɨÕj©^¯ ÐÜÜœ...T©TT,%IV’‚@²ÖyÅ 0Q«ÀÒÒûûûÔj5fgg©Õj‘Ífã6cÿw˜I‡ììD !i6›¼¼¼¼òêþþþ•sÏÏÏ4›M0㸿åÙG²~’/xöiˆ"ìâ~Ll£è› èêlvuktuŸuqÓþù°Î*•WIEND®B`‚routino-3.0/web/www/routino/icons/limit-30.5.png 644 233 144 1507 12573351605 14657 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“üIDAT8Ë­”ÁK[YÆ¿÷ªI|6$q“€A'ˆE7]ʤºÜLPAh f£Û)®Ü ã²Ý»èÔÒVÌ_Ð.%‹©ÐAg!ŠDblcA_Þ»÷7‹$SK™Üsï9ß9÷ò}GHB®ë"¹H"ûiÇù@2 ##†dçÒFï^Hn/O¨‹9H 1¤§xÞ–—áÍK­­Ôj]y<ï ÒÓ^¼ÓË—ˆD\¢Q‘ÍŽ#P(Àñ±B¬5\_]?äøØP(€t@6;N4*"W¤ÓbnÎCúÈê*€X‚‚¬ýjý3°€Ïê*H™›óH§{Ï”žQ,b ø>¦ÓÀCXk¿i0ð}‚N‡:‹ =ëÿÙ<ï³ÝßïV4æ? >ˆµö;À^œe<ï3Ò[¿Ië”Ë?9KKæï½=÷çωD4::ªƒƒmnn*N+•JI’‚ Ðöö¶Þ¾{§¿ªUgbvÖDkµ!Þ¿¿%#UÙÚâŸVËŒ$,,,Íf©T*äóy¦§§™œœ¤ÕjpzzJ&“a~~ž‡‹‹œ^]^½ÂHUWñø]Ý¿¯ðÓ'÷÷õu•J%MLLhkkK±XL{{{ŠÇãªT*’¤ÝÝ]µÛmú¥PP&u™™‘›HÜpµÎäø¸~XZÒÃGt~~®\.§¡¡!IR<×åå¥$)•JiqqQù|^¿>y¢D:­Ù|^pÃNÇÑíÛúóõkÝËçU©T488¨f³©v»­ÃÃC)—ËÉ÷}œœhllLårY™LFggg’µÂGVªòò%m0??x@2™¤X,rqqA¹\fxx˜µµ5333ììì055E2‘`éñcB0¼x•ªBÚ`e ®®¨×ë]bbŒ¡ÙlbŒÁC£ÑÀ÷}êõzŸ!++ m|Ã3Ó㙹fÿË9c0`í5ž}U@©бAaxMŽö»½ Cl·û¥Ò5ܨ6otjÜè<»ÁIû/§klçù|îIEND®B`‚routino-3.0/web/www/routino/icons/limit-24.9.png 644 233 144 1462 12573351605 14666 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“çIDAT8Ë­”¿K\YÇ¿ïmf4o²b"b# ÌÚDS¬6–óD-F„I:ëIº%û/X$à-¦°NR„a‹6‚°¨›'ƒaÌ"¢£²+ßêÌ{÷~¶˜×IíÃåœ{Ïáœ{¾ß#$! ×u‘\$ÑÞþRÇÙ¦³=2tv‚ãl#÷BrqBÍDíí’ógíH¯ð¼K øðÁr| ß¾ÁñqÝ.Àó.‘^5Þ;x‰dÒ¥­M¤Ó¤]&'áàÀ1ÖnKÝŽ980LN‚´K:¡­M$“®èéSSÒ33UÀEE`íÿÚôªÌÌ€´ÃÔ”GOO£Mé5ù<jQµŠ©ÕnŠ1ÆÇqK¦V#ªV1P#ŸéuóÏãyç¶\ƂŬµ-ÚÚiÃg ¬-—ÁóΑ ©h €8ØÚbnnŽííí›àÝÝ]VWWoª‚€……þ*—b[(€TT,mòñ#|ýj~ô<|ß'N³µµ@&“Á÷ý›ä¥R‰¾¾>FFFøùÉþ‰cÃû÷iÓÕƒƒò}|ùâþòò¥VVV”J¥T*•4;;«««+uuu©)ëëëêîîÖÚÚš’÷ïë÷wï\år²©Ô ûC"½¼T>—Óøø¸äû¾â8Öâ⢲٬666´··'IS†š˜˜Pðù³‰„tïžäº¸6Š7™ÔŸ;;Õôô´æçç%ICCC ‚@‡‡‡ ‚@çç纸¸P¿²Ù¬:>T&“‘ÂP8ªI›|úÄooÞ˜„ë2<Y«Õ:€ÛÛÛK£Ñ(1 Ʋ,d2=99)K¥ÒÓ4¿’Röj­ŸB(Û±c‡ÐÎ9ÿÛ¶íŽp8ì=zT¬_¿ž0Æ µþhqÎ I$¡ÅbÑY\\ !ö+¥þÐZ/±þþ~øíõë×;Ãá°344$ À”„¼SI)mìµÖRÂ4MlÞ¼™=þÜÉçóÇó™×ëý“Ú¶½×¶íc@@8p@Ô!œsPJ«#„€R Î9´Ö€ƒŠ@  lÛ>fÛö^¶k×®Q˲Út8&°¼¼Œ\.‡…… ”J%¬Y³”R,,,àÑ£GXZZ‚ßïx½^!t&“!BˆNîºnßï×±XŒÖOòðáC\¼x~¿–eÁ0 œ8qÙlç΃×ë…eYX·nA)E4¥ÉdR×jµnY–ŽD"ÔëõBJ Æž>}ŠH$‚ÁÁAH)!„¥©T ­­­F±XÄ©S§ðøñcD"˜¦‰P(Dfff[ú^Ëh­‘ËåpòäIx< bË–-¸rå FGGQ©TÐÕÕ…ŽŽŽ÷Š €RƘªV«pŒ1€”ÝÝÝ8tèÚÚÚpöìYÔj5T«U(¥`YlÛF©T‚eY h­V¥T±¾¾¾‘b±HZZZH0„ëº‡ÃØ´iÖ®]‹ 6 NÃçóazz½½½Ø¿?¶mÛ†;wî ŸÏ#âÉ“'H&“Ú0 IüÌ9§7nÜp«Õ*¤”8sæ Òé4`vvRJ„B!†B¡X\\Äòò2ZZZ’¼ÍïìðáÃÓoÞ¼é¬V«Ýù|Þíé顎ãàúõë¸yó&r¹¶oߎîînø|>$“ILMM!N£­­ ûöíÃÄÄ„Êf³ÌãñÌ:ŽsˆŒŒŒÀBˆéW¯^­Û½{·êïï§/^¼@¡P@0Dkkk£ñ—––ðìÙ3˜¦‰®®.ÌÎÎêÑÑQÒÜÜü¯RêK­u–SJ9€J©oLÓLNOOëöövÄb1ƒAB@­5|>6nÜBªÕ*ÆÇÇ]Ã0€BH§\‚2E)ýÂÆÇÇr¹ B”R;_+¥êÝJ¥"šššÎÇb±_Pn½ABݺuëiÃ0ΗËeqùòe·ú°‡c¸uë–º}û6onnž·mû§™™™Æ,`;wLæææ´”òÇóõË—/RJÕÙÙI¤” ”Bkݸÿ.\ÐBà[BÈ-B €&‰ÆP§”rJé¼RjÈ4M¤R)ÉdÀkhpccc®mÛ”1všr€XшD"ZXÉG~¯^½êT*•Æø›œœTóóóÜ0Œ¬eY#{öìÁj VÄâðG~/]ºäÀýû÷‘J¥`š&”RÜó××®]côjïlõæS~ ÃøºX,*•оwÕjLñ#€1­uÃãªCáýÒXõËæ\­õ.Jé”eY’sÎ8ç“Ñh´ïÁƒTJ©>¾÷ùŸÐP÷û—Öú¸ÇãaŒ±y)åwwïÞ…”ÿ—ÿíÍ*R 1IEND®B`‚routino-3.0/web/www/routino/icons/marker-49-red.png 644 233 144 2055 12573351600 15433 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“âIDATHÇ••¿kTYÇ?÷¾{'ãXDd‘y!·Jü n‚’Ø„`µdKEq!SØîZm·iÒÄ HTF°±Š+XXب¬!62£,Vb‚Nò~}·xïɸ‹»†ûÎãÝÏ;çûî÷ | [­V-@__ß)ïý3@@V¬Ú›{ïŸõõõ(öÙdŠ5Rà;ïýB’$s’488hNœ8÷ž,˰ÖÇ1Ož<áãÇ2Æç\3Žãyà¯=œîF‚ hª×ëñÒÒRºµµ¥,Ë´7²,ÓÖÖ––––Òz½*ö”—‡A¼4>>µZ-IRš¦Šãø«_𦒤V«¥ñññ¨¿Âk-ι@“““Q ‹¢(¯2I¤½Õ¦©²(R´³Ó…ONNF€œs+ÖZ¨T*Ó€Â0LÛí¶$)Žã.`_ôäqI’Úí¶Â0LU*•iœsO-..¦ÿ|ð@*ä$­¯KËËÒãÇR–uÁ‹‹‹iQíS€l`` ÛÜÜì~%I¸}[ie%ÏoÞÌóC‡òõâE•Âlnnj`` +ŽéÌÌŒ$)I’/À/¤Ã‡óÍwïæ÷úû¥Ë—óëG¤JEZ[S±C333R Xï=Ê2ØÞ†ÙY˜ž†`g'?#ÛÛ0<œ_×ëE°¶ÖuOÁ±È666èt:8çÀ… 06ׯC§S<\¹W¯ÂÔœ>]ØÇtôáÀ km¤7–—ó/úò¥ä½tü¸45•·?2"­®æï·ß¤3gòµZUrÿ~®ÆÃ‡2cLd1¿ö×k×’öû÷¸ÁA²ÙY8rvw¡RÉË8xΞ…·oau‚U«|Ž"~žŸOc­½A­VÃ{»8ü±$%åaßÞÎ+½u+ÏïÜÉsúû•Þ»'Iúéüù´pÕŸ@­Ô¸î½¨Ñh¤’íìHNzýúË9}õJZ^Vüüyñž;YülŒ-.×ÛLXk$Ífs¿³zUÚsãÝ; •Þoìåxc ιy@Caµ ˦»»_y?-\477³µ9<ill,.†ÇïÆÏ7bŸ¾aFåH”¤F£Q¶½Ô.]º´÷oéߣWß“'OÆ’Ôl6óa­Œ1ÅãÁ7½ú:çÚ€Î;—;v¬l»Q´íþ+pŸ¾ÀÆIQáGÅ9gÿ/°«o±^ ‚@ÖÚ àûžn¾Š¿xÇkxµ¯èþIEND®B`‚routino-3.0/web/www/routino/icons/limit-125.png 644 233 144 1446 12573351602 14600 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÛIDAT8Ë­”½K\[Å×½3ãeðcPf e>6¦N‘€hçGa ¼)#haaá?ðà•I)8e‚"A´Œ¥„7EÀ`!ãÕ ‘€)îÜ{Îù½bFãûê\pàìsö^œ³Yk IHÂ÷}$Id³¿ ­ãyuúû!Ÿ·ô÷ƒçÕ‘Ö»÷Bò»uB7DÙ¬‡äñüyéAðƒÅEx÷Îqy ß¿Ãåe'^\„ øôª›ïuë%ÒiŸLF —¾03† ÎYî¢ ËÌ H_.‘ɈtÚ…‚˜› >³º ÐIIÎý\7gà€6«« }fn. Pè~SzÍü<@Œ1˜vëÖZ’$ÁÚÎ#“$!‰"’8ÆAÌüx $ß{öLêë{,,WWæÆ1“““T«Ujµccc,//S«ÕXXX`ccƒb±Èþû÷˜f¬/ç<űî£\.§0 555¥r¹¬µµ5]\\hddD•JEÅbQß®®:q,9çùjµ>éÃIrrN’r¹œŽŽŽdŒÑÎÎŽ …‚ÎÎδ··§ÞÞ^ë·/$Éù?J­Ö'!­³´`º‚äúúš(Šˆ¢ˆf³I†„aHEÄqL³Ùì讓oXZiý_:Ãþwug;¢ý›ÎþÓîá Á­÷ÓVÿpÀ½zó^§Æ½Î³{œ´±Çp¢Üµ±hIEND®B`‚routino-3.0/web/www/routino/icons/marker-4-red.png 644 233 144 1742 12573351600 15344 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“—IDATHÇ••±oGÆ3;s‡ ¯Há³ʈÎåbË)vC‹(8¤T–øâÆQ‚Nâo B)\ú(®!Ƈ†ÝùRììùÎÈ!ù¤ÑÜξýö{ß¾÷Ž`O:ešÍæŠ÷þ5 ¦]“×Þû×Ífs =gk"“ö ÀÞûͲ,×$©Ýn›n·‹÷ž#ÖZŠ¢àåË—|øðAÆãœëEñø{‚gü† Y– ÍÎÎÛÛÛa4)ƨIÄ5´½½fgg @é¹ uƵâN–eo-..æ»»»’¤‚Š¢8Zy®¢(B$íîîjqq1OÄoNEk-ι'€–——óš,Ïói•1V+©Íó|L¾¼¼œrÎ=±ÖB£Ñ¸¨Óé„Á` I*ŠBß Féà Z uÜ`0P§Ó €Æuœs¯mmm… “"-,H7nT¿ËrŠxkk+$µ¯âÌÌLÜßß§6…<¯ö‡%nÝš"­ã÷÷÷533hu»]Ón· !`L]e@Y‚÷ðûïðô)œ= _¾0 c !Úí6Ýnײ€õÞ é(:Fp¸{î߇¥%8 ‰ÇZ ‡CqÎUÄRº¬¯ÃÕ«°±?B³IR0¥`oo b­Íðøñã#ãëõüyõŠ…iuU:wN:sFº}{\eŠ}ñâ…€hŒÉ3km)iåÍ›7åêêªm·ÛÄ1ÖÂÁ¼{§OWþîíU /^„ÕUÔh`áóá!7oÞ ïß¿·Y–ýF«ÕÂ{ÿG*þ¢ú°åtÔÊWVª•Îêâ¿sçNH]õЪm™õÞ¿ÔëõBUIyUðE!}ýZ=z$mlTœéìÙ³g1~6ÆÌׄ.™½d­Pöûý“;+µ±$ ‡CÍÍÍսߛäðÆœsÍÍÍM •©Î*K…TðkkkEš­ýóçÏ“eÙxBUôÎÙùùy¼÷ýó·V¿¹¹áp<&ÆÇ:ÞûÁ7þN¨ÞÙÙQ«Õ €¬µ?Oû8¾ëï§OŸtùòå" _Sá{¾ƒ);N^DIêõzuÚ;@ëÞ½{pô·t2Žû{íÚµB’úý¾€`­•1f)…gß%<î¯snh}}=^¹r¥N»—Òvÿ•pÊ_à'cŒ€2)üóÒ¥K8çìÿ%û›ö_²,“µvüx,›oð.VY¸dçIEND®B`‚routino-3.0/web/www/routino/icons/marker-66-grey.png 644 233 144 2665 12573351601 15636 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“jIDATHÇu•OlùÇ¿¿™ñ  (% —àD8Z-•Ä åPm@ì¥ÚÃ^vWÕ^"ïÊâÒK¹ôÚH( ÐT’¨I«DH¢„`P€˜ÅŠ`ÀG8õÌø÷{=Ol¿Òh~ó4úþÞ|Þ¼÷cÙlkâRJd³Y“Ëå¾ ¢?„aØãû>`øŸÈ²,¦”úcìûl6û·\.Ç`k¦‚ˆ4mQJ ‚`0 Cr]—µµµs9cP*•ày)¥XKKËH†ß0Æ^1Æ-p"ÒvI)óµZmW<o9r„§R)fY>–ïû( ”ÏçõÛ·oÇù¥ÖúýÄãâÀ`‡”òAìêè臆†T{{;B€ˆ>¹¤”H&“¬³³“—ËåðÍ›7q¥Ô¯Œ1!¢ªèëë€?­®®f:::Â3gÎ(Û¶aŒ‰2㜃1ÆÞ£%"h­á8zzzijgÏÂ¥¥¥¸mÛ›c±Ø_y½A|ÇÍÀÀ€jrB€sÎ9ˆ(2kn"¥Œ6PñxÜAðU½œˆ~ ÙL®ëBk !*• îܹƒ'OžDfŒ1xžÅc0ÆÀu]:ta‚ˆ~”Fãs×u©»»›€årçÏŸG¨ÕjH¥R8uê^½z… .Dñ®®. R©¿yó&ÕjµÏ¥ïûÔÙÙÉc±X”åÄÄ’É$NŸ>b±ˆ«W¯buu7nÜÀ¶mÛ044„b±ˆk×®Áó<¸® ÇqÐÖÖÆîÞ½kä{DïÿC!êõ:–––ÐÚÚŠ³gÏ"‹¡··J)¼xñ6lˆâGýÙšçB³²²‚0 £j‡aß÷ÑßßD"ÑÑQT*@½^G?¶lÙ‚ÑÑQT«U!µZ œsÃmÛÖÅbÑÌÍÍEÅ "d2¤Óiœ8qD„çÏŸC)…ƒ"Nãøñã "‹EÀÂÂȶmÍü ¥äù|¾Q©T`Y’É$æçç…BZk´··#‘HàÑ£GQ¶nÝ ×ì½þ,Nž<9S¯×wW«Õ½år¹ÑÓÓÃ7oÞŒ©©)äóy<~üû÷ïGww7âñø'ñt:±±13??/lÛž Ãð×lxx¶+¥fÞ½{÷‹Ã‡›¾¾>^©TP*•H$°}ûvc¨V«xúô)6mÚ„;wbnnŽ.^¼ÈÇù1æ3"z(9çÀ¿1¿qçæÌÌ íØ±]]]p]7bܼoܸ{÷îc +++˜˜˜h´´´(ÆØ0cì!É4(ÆØçü[Ƙ=Ï‹:¦ÙóMãf{NNN6<ÏS---—öìÙóG@£9(CÆß·oß9˲.yž§ÆÆÆM£õ""!pëÖ-sûömÙÚÚºÁïggg£v™L¦ù2+•J¤µþ§mÛ_¾|ù2®µ6»wïfZëh°pÎñúõk\¾|™”R Àoc·c€žË墡Î9—œóEcÌÇq0==M…BBˆC†iAÀ…çc—¨5ŒÈåràÍÅš>á{ýúõpyy9:Ròù¼Y\\”–e=ô}øØ±cXoˆ5°øÈø¾W®\iÀýû÷1== Çq`ŒùZJ¹:99)ÐzîbýÃÏñµ,ëËr¹_^^¦{÷îéZ­&”Rß!¢ˆãº¤ðai¬;²%€âœOù¾¯¥”BJ™O¥R_yž333È ÒjA¯÷ujš#ABðááÁ²,1úøø8ÑÜÓÓ“///É 㧦9­³&‰c²ÿÄÿèì ðµ8ÿ%Ü£ã˜?7àMwóM¯Æ›Þ³7¼´ÿ…Èg,'ûëIEND®B`‚routino-3.0/web/www/routino/icons/marker-28-red.png 644 233 144 2144 12573351600 15427 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“IDATHÇ•UÏkTWþî}÷΄AÆ@óbªéÂ$fWÆ…™¤þ‚lÓL݈`v΢ÿÛl%h6:îDÁ…Ð J‚¸(𠆙¨YÕ$‹(ùõî»÷ëâ¾7N’–Ú—óÞûÝó}÷œsÏ&ÛÚÚ$d³Ùa­õ àÏÖ­õ‹l6; É>™‰Ä,€¯´ÖSq‘äÑ£GE?´ÖpÎAJ c æçç±¾¾N!„PJÕŒ1×üÕ‚Ó<áx , fffÆnllÐ9ÇVsÎqccƒ333¶P(LöO§‡A,`©TŠêõ:IÒZKcÌe­%IÖëu–J¥(^zX)¡”º€år9JÁ¢º("ãxO¦´–.Šíì4ÁËår€J©;RJ “ÉœÀ0 m£Ñ IšÝÝ@tÎû3Æ$Ã0´˜ÉdÎA)õ §§§-Iš(ò;^½"oÝ">$[Y\$oß&ïß'··i&ÓÓÓ6Éö¸|>ïÖÖÖüEäÜ ù¼÷çÏ{À»wýÿáÃÞ Ðmo“$×VW™Ïç]Rr°###$É8¥×ÕEŽûïçÏ=ÀÓ§äåËä©S>þò¥ß»ÇTõ‘‘° €ÔZ(EÀð00>î뢭Í{.].^Þ¾ŠE`` Ù= Ž[,¹µµÕ¬C’^Ç›7ÉL†¬T|lrÒgwæ ÙÙI¶·“ËËL¯¯T*€…”2`gggý’äÒÙÝM;F&q~üHjMNM}¾´înÆ££$É?="'„ˆÁ$vtt˜fÑŸ>Möô>øÍŸ>‘Qä¹zÕÇ^¿¦;r„¼qƒ›${OžŒ“&ø¹\Zë9,Ÿ=k¸ºÊøÐ!2ÈlÖ{À—ÐãǤ~´Å"¹¾Î¯\± àŸré@)h­ç1_W¯]s?ŽJóæ>€Ý] \NœÞ½žÞ.=IªT*2¬µ1]»v­ÈèúzqyvVêé‘|ÍjyYš™ÙåáC ”Þ¾-Iº÷®€ÜÁvÑKÒÉ“R¥²Q?¯^ÞÕjÅþÑ#å>+’†÷íK}üE¹\Æ9wÐèÈH"IéÇÒöíÒÅ‹¯G;·Q==ÊΜ‘$ýzútæ ÿÊ­6íwνT=>“¤øÊÉ7ƒ:û~^ºzUɃ’¤¿oÞÌ=áª1f¨EcF¬µÒz½^蛦ÚŸVbÞ¼~­(jõ~µ“ÀcÃpÐ@ÅK/^l"h#M•y9&&&?[ë{öì!‚ö„*èÃÐ ᜫûá’´¢³ß“D’4==yÂ7íéÔ1öØr9瀪Õj¡¯÷¬åõââ¢ÊårÈZ;¾5ì­ø¶¾ÞÕ• '~ÔýiŒpü6éEQ܉’T­V[a/å³gÏvþ–¾­ú>|8‘¤z½. ³ÖÊ3Òñû.´õ ðèÔ©Sùþýû[aW}Øá÷nÒøÙ# õÞÛ»w/aÚÿKØÖ×Ûß‚ µö ðã–h¾Âð›(2MZIEND®B`‚routino-3.0/web/www/routino/icons/limit-10.8.png 644 233 144 1433 12573351604 14655 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÐIDAT8Ë­”OKQÅÏLBÆ&H”Q¨[n\”î\‰PÍ¢¸ŽÀàHw.ܹ+ZDpã"Û†’ÐBQ ˆ  -ÓÌÌ{¿.ò§-íÒ î}ïÃ}ïž{…$$áº.’‹$2™I¤-ç3ÃÃðð¡axç3ÒVï\Hn'Ô'Êd$‡•• RÏûN¥ïÞY®®àÛ7¸ºêÆ• xÞw¤jï¾ÓÃK¤R.é´˜˜x‚tÊâ"\\ ÆZßÖc.. ‹‹ 21ñ„tZ¤R®KKÒWÖ×:€%Š ŠÀÚß«¿è°¾ÒW––¶Z†÷O®r¹çzñBVrDBù|^ÙlVJ§Ój6›Êf³Úßß—$EQ$Ïó´°° Çcc |ßÕË—ÒƒÏ]%(•’•´R.«X,*Yk544$IÊf³ ‚@’äû¾FFF´½½­ëëkòyÉuå$¸²ÖQªo€Â0Ôøø¸Úí¶.//u~~®ÉÉIÚÝÝÕÜÜœŽŽŽäyž>ÖëR2)ÇŽ«»»†j5I²’”ËåfggU*•T,U.—U*•4??¯ Õëu •ž=Sùõk«”øñ£1¨&c ···A0¨ÞÍÍ ÆŒ1ø¾µ–N§C»Ý&úù³‹[[T³«³““®²ãx §¾Œ1 |c0ÿÑÙ_`£ˆ>aŸô?Žé‰;dyù¸×޼שq¯óì'í/'ên4IEND®B`‚routino-3.0/web/www/routino/icons/limit-12.0.png 644 233 144 1444 12573351604 14651 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÙIDAT8Ë­”ÁK[K‡÷^È··VŠàFˆôžu-ˆ.º¨D\…<»qá..]øg´àBÁÿ ô*ˆÝ¹ÊÂehÈ¢ ´5Q"˜‡RóHrïÌ÷Iú,¼î<00gf~‡™9ß9B’p]ÉEÉäoHû8N…±1xüØ06ŽSAÚì É脆’IÉam-‰ô† ¸%Ÿ‡,ÐjÁÅEßÏç!n‘Þ Î;½D"áâû"•z‚tJ&ggˆ±Öp×ú~ÌÙ™!“é”Tê ¾/ WLLˆl6@úÌö6@°DDXûß®ºloƒô™l6`bbðLé-¹@/îv1}Æ¢(˜Ÿ/hz=¢n =^½éíðÏž7œžƒµƒ@ÖZ¬µ¿žƒk«U‚¤gBÚgs 1@±X¤V«P.—ÙÙÙ¡R©Ç1Õj•ÝÝ]¾ôÏÅ6Ÿi_H% óW¡€çyR«Õayy™T*E©T Ùl277Çìì,ÓOŸò7Þ¿ÇH%W££Ïõò¥¬ä:ž§ññqyž§z½®­­-+ C•J%IÒÑÑ‘|ßW¹\ÖÃGtôî«LFöÁƒç®<%²’Ö^¿V:V£ÑÐÒÒ’VWW•N§5??¯ I 0 %IGGõO»-ù¾äº¸²ÖQ¯§¡Åq¬0 Õh4´²²¢õõuííí)ŽcµZ-MNNêòòRõz]ß¾~ÕïÓÓÒ÷ïrÀqusóIÅ¢$YI ‚@aêääDqëàà@SSS* ÊårZXXÐââ¢fffôg6«?^¼°úøQîíí§ÙbŒáúúšN§C§Ó¡ÙlÒh48??§ÝnÓjµ0Æ`Œáêê Óíöu››?²Ùç¬Zí“=Hÿ¯ÌZÛ‡ØÌÿpöSØ(bpè]`À1€»G.w§îµ6ïµkÜk?»ÇNû/Å?m¯S+¤¦IEND®B`‚routino-3.0/web/www/routino/icons/limit-17.6.png 644 233 144 1463 12573351604 14665 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“èIDAT8Ë­”ÏK[YÇ?ïe“gS aVJgcÅÎB(a,¨ÜH Z(³(Ñ? ÿÀÀ,ÛµYN¦ 0ÐBqåÆEºª ) ¨C¦(«Æ4†ä½{¿³HbK;³óÀY|ï=ç{ðýëºW€¢ÑŸ9NYÃÃÒ½{FÃÃ’ã”…Þ>·×‡èE£ŽÀÑÊJTðBž÷YkkÒ›7V§§Ò§OÒéi¯­Iž÷Yð¢WïôúA‘ˆ«4:z_p¤¥%©Z5’Ykôutq jÕhiI‚#ŽÞ×ÀŠD\”J¡\ÎT”ÏKR[’•ïK¾/Yû%ûk’•ÔV>/AE¹œ§Tª÷Lx©åeIêí¶¬ïËZ+ß÷oÓZ{{AãûòÛm©£Ç%xÙÿ³´<¯®£#’µÝ“ÿ7¬µ]bcºððPò¼º ú ~çùóŒž=3.¸¥wï‡Ã4 ŠÅ"•J…ƒƒâñ8‰DÇq899áb‘X8ìü85eT­Æœýý‚}mmI’ùkkK¡PHÛÛÛ*—Ëš™™Ñüü¼ÇÑÎÎŽ$©V«)“ÉhqqQ¿<|¨¿ëu£×¯e`ÿ††ðè\'"•Jq}}Íää${{{lll066F6›`ww—ããc²Ù,?OO3‹¹d28CC\B!‰`•'O˜˜˜ ÙlpvvF¡P ŸÏÓ avv–?_½bïý{H$° k:Ûbk-Æ677I&“¤ÓiZ­Äb1âñ8«««$“Iþùø$dŒãR¯ T°ƒƒƒD"J¥¹\€F£ÁÂÂsssŒãyÓSSüúô©åí[BÍæ­¯KR ctuu¥V«%Iº¼¼ÔÍÍMW[Æèüü\ÖZA Z­¦ Ýîö­¯KPø¢³Ãà;]}‹1’12ßèì;XßWŸð¿ˆ$IA ž¸;Z^þÊwêÍ;w:ÏîpÒþ 3LF‘^Áy4IEND®B`‚routino-3.0/web/www/routino/icons/marker-home-red.png 644 233 144 2103 12573351601 16122 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“øIDATHÇ•UAkIþªºj&‚™Ž!ÉžròhB6ƒˆˆŒ†ÝäàšƒÁ‹ƒû'6 ËÜ$É: $¿` BJÐÂNç0Ü09ŒšD§»êÛCU'“ÑÅÝÅ{ÝUïë÷½zï5p,²§§G@6›½¨µ~€¬×ì|ÖZ¿Êf³ÀûÉHx0~ÐZ/$I2C’}}}b||Z)Ø$ ÄÆ`cc{{{B¥T-ŽãûþîÀ9úÂ`æóù¸Z­šV«Ek-;ÅZËV«Åjµjòù| €Þo0eœFA° €íz½N’4q̘düú5ãK—/.2öïI²^¯sbb¢í·„VJ(¥°P(´IÒXËöá!-IF94D¤äÒ-ÉöÁ1$ÉB¡Ð@¥Ô¢”Èd2—0 CEI2þüÙq"rpÐf³d8{iÉ;8ðÇ"†ah0“É\†RêV*C’ñ—/ßTŠÔÚ­N`@¥R1>Ú`{{{m³ÙtA’oÞJétº„8¶?fzÍf“½½½Ö—L±X$I&)íÛ·ÓÐ93C^»F–JäÍ›ä­[ä… nÿìYòãG&¸X,2-)–J%G¥Ýv»»»ÎizÚ=ûÛ>Ò++nÿÉ“Á”J% `¡‚€S§\¡)|øT«N߸œ9ãl×z®ƒ„ë¡ÝÝ]°RJi677m­V¤t±[ëœNŸ^¾îÝž?¦¦€«W­Ý¾µ0d&ƒµµ5¬¯¯SaÁ¯Øßß×ß¾uEßj9zssä³gÎ^]=n«ÕU ]Y!Iî·ZM|üŽ\.­õ2&'c’L=r%tþËA­f€k Wqa‡Ôj†\¤d2·ñ<º"•ss>ÒËËÀ`í«wè°¼ Òss>©Ôå3¥§äóè¦Ûí7†!Æ|Û`Ðét»Ð%ŸéiïÏîàûŸmµŠ‹1Xk±Ö†!ÖZþ,Õ*øþg¤;‘ߤß)•~v>4ïï»<{¦x<®T*%×uµ½½-cŒ’ɤ$)mnnêÏW¯ô×Þžóãô´ñÞ¾(”öxù’7?šï}ŸÉÉI2™ •J…r¹L$amm­ßP³Ù$N3??O±PàŸ¯_ ÏŸc¤=Wñø]MNªöþ½ûËÒ’¶¶¶ǵ»»+ß÷5<<,k­zØÙÙÑÙÙ™ÍärJ{žË½{rï~¹u Ûj9ù™¥“Ie³YkaaAÑhTcccj·ÛýdCCC* š˜˜Ð¯KKL¥4=1!¸67ÕþÁ¦¦¦T,µ²²"@’ÈqIÒÑÑ‘jµšFGGU*•”N§u||,Y+Œq\ÓjíkgG¯+v»ÚØØÐÈȈÊå²$Éó< Ðìì¬2™ŒÖ×וL$ôS6«b¡`µ¹©È—/ûBZåñcÚ6ëuêõ:‡‡‡´ÛmNOO9??àää€N§C³Ùìñ1äÑ#Vû<£Z½àÍ5‚^Gƒƒk¯ðìXèÚ À^H¦|}oðçÓåþý+ ¸QmÞèÔ¸Ñyvƒ“ö_"Wjå|ºëIEND®B`‚routino-3.0/web/www/routino/icons/marker-20-grey.png 644 233 144 2730 12573351600 15614 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“IDATHÇuUMhTë~ÞïgÎÉ‘q‚3$!$édJìBqÀ‹Þ,´ÜÅ fS½B]ô–rQÂf×MÝtᦩFÅŸ…!éK.1U(“?‰8±¦è˜™ÉèIçü|ß×…™s£½}àÀ9px¾ç{Þ÷y_ÊårØB —Ëé|>ÿ™1æ¾ïº®k¾‡±,‹¤”ÿ$¢or¹Üßòù< ‚4Ð6)7Æ(c̤”—=ÏûÒ÷}‹Å(™L‚12j­±¶¶†Z­f¤”‰DÆ}ßÿ-}GD€˜1FèBÇéŒÇãÁ±cÇX*•"˲ð)\×ÅÒÒ’) jccãËh4ús¥Ô1cÌ¿ˆˆñ#GŽBˆ¿{ž×ÙÕÕåŸ={V8p€8ç0ÆüÏ#„À¾}û¨¯¯U*ÿíÛ·q)å/´ÖwŒ1›|xxþ¼µµu´««Ë?wmZëPc D¢Öc ”B4Åàà õê•ÿæÍ›¸mÛ{ÛÚÚî1Ïó>÷Ôáû>TJ!•Jahh-åííípårýýý€ÞÞ^!P.—?*(Æ8çºÑhÀ÷ý°'OžDGGfggqåʤÓiôööbkk ¶mï$Àv’Žã€1¦…mÛjuu ,“É€ˆP­Vqýúu¸®‹S§N!N#H)Ñl6¾ï„€R©„R©dlÛV À„¬P(µZ pëÖ-h­qþüy¤Ói4›M!H$P,ÅbB$“Ic099©èþÂÏœ9óm³Ùì®×ë?­V«Aww7»ÿ><ÏÃÜÜ>|ˆ`ÿþýÈd2˜žžÆÜÜ^¼xl6‹žžܽ{W¯¬¬pÛ¶|ßÿ%À¥”ß:Žó“Çë¶±±Î9ˆA ³³{öìÁææ&J¥öîÝ‹D"……síÚ5ŠF£ÿÑZÿÌóL0Æ€k­eÛöÃ'Ož˜žžd2™0AáÌ3»wïÆàà ˆF“““A$‘D4FDÏ ‰hšsþµÖšß¹sǯV« "(¥ µ0Æ„ñœšš jµšŒD"7úûûÿ€Z ê;tèÐeÛ¶olnnÊ{÷î­ÖiE´¥–sŽÙÙYýôéSÑÞÞ^ö<ï÷Åb1 ?zôhëgZ[[3J©ضýÅëׯãJ)ÝÝÝMJ©p°0ư¾¾Ž›7o)%ø5Í‘ €åóùp¨3Æc¬¬µ>F133c–––À9‡ÖDß÷1>>xžÇ8ç—‰è¹m#òùˆŠNSp™¾ ÛyÑÂŽ 3Ã0ˆ%yÛ—Õ‡DØ·B 8Š`ôAcw­q±6¶Ôi ‹6iMl›ÈïϽwl2­Î ÷Þ‡ÃwÎwø>–Éd° B “Éèl6û…1æ¾ïïq]×`øƲ,&¥ücì§L&s'›ÍR €­’rcŒ2Æl‘Ržó<ïkß÷M$a±X DÔfÔZ£\.£V«)%Û°aèïûß1Ææc€È£ìBÆŽh49r„’É$³, Âu]‹ES(Ôâââ׎ãüE)uÄócŒø €!Ä<ÏÛ‘H$üÁÁAÇçƘŽ[·ne»ví¢J¥â/,,D¥”ÕZÿjŒyËûúúà—f³y0‘Hø'Nœ¶mCkÝ®ŒˆÀcï­5Æ@)Çq°gÏ>;;ë¿~ý:jÛö'¡Pèyž÷¥çyßD£Q=00 [¾qÎAD "cÚdŒ1„íÿFµçyßxž÷%?tèЈëºétÚ$ ¦”çÕj¥R oß¾E$iW[©TP*•°¼¼ŒH$pRJS,™”²SAЉDLww7çÅb¹\¶mÃu]lß¾CCC˜ššÂèè(6mÚ„¥¥%ìÞ½ƒƒƒ€d2IwïÞ5F£—\×5±XŒ…B!¬f <À–-[pöìYœ:u Ïž=ÃÌÌ îܹƒT*…3gÎàôéÓ˜œœÄÌÌL»ÚX,Æ\×5â}Þç°ÕˆÞÞ^\»v ###¨×ëèêê¶mÛ°sçN$“I´Ù¶½.ëwœs½´´D¾ïƒsX\\„1®ëÂó<,//#ô÷÷#LLLàöíÛèééAWWW»FD¤…mÛêÅ‹xòä íÝ»ï޽ý{÷N§±ÿ~ÀùóçQ(ÐßßK—.Á÷};v ©T Zk^¾|‰çÏŸÛ¶øYA…B!¨×ë…B‡Ã˜ŸŸ,,,`eeÑh¹\Zkœ¯Ø{ü‹]¼xóóó#FãoÁÐИžžF.—(¥Ç‘N§qáÂ8çPJ¡Ùlâøñã˜Õccc‡Ÿø¾¿Ÿ À§RÊû+++Ÿ>|X÷õõQ­VC¹\ÆÆÇ¡”B©T‚ïû`ŒAk Û¶ñæÍ“Ïç™eYïŒ1Ÿc¦ ÿ×Zwçîýû÷MGGº»»±yóæv"ˆ¨ÝùVcšÍ&nÞ¼pÎ% k­§Œ±1"úž1Æóù¼_«ÕÀƒRjÝØk¸~ýzP­V¥eY—S©Ô?€ 2Ÿ1Fûöí;gYÖåZ­&¯^½¬ÉÞÚ‚sމ‰ ýèÑ#‡ç<ÏûñáÇíYÀ<Ø’ÄÊå²QJý×¶í¯^½zUJéÎÎN¦”j"BµZE.—3RJà Ƙ €²Ùl[ "šÓZŸpããã¦X,‚s­5cð}£££çyÄ9?Ç» @®Úˆl6 j]Vñ‘¿7nÜðëõz[z¡PÐsss²¬i×u‡=е„X5äï•+W˜ššÂøø8ÇÖú”¢yëÖ-À¬]7|íãÏüµ,ë«J¥­×ëfrrR5 .¥üÀ¨1¦í㚢֭^Àš•-ƘCD4溮Bp!D!™L~ñôéSRJé ×ÉÿZþþÛó“mÛœs>§”úöñãÇëòû!~̨ÓÍ™²ètIEND®B`‚routino-3.0/web/www/routino/icons/limit-16.9.png 644 233 144 1435 12573351604 14666 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÒIDAT8Ë­”½K\[Å×½fFss‘ÉàG)ø¦Éâ :¦„#B4]xŒ€F¦™ÊÚÆð ©iìcb„€£(X((E¯:sïÙ¿WÌÇÓW{àÀÙûœµØûìµ·„$|ßGò‘DOÏHËxÞO2Èf™ xÞO¤åÖ½üN¨MÔÓã!yÌÏ÷ }$®)•àËãä~ÿ†““¦]*A\#}l½÷Zx‰tÚ§»[ #Õ˜™ãc$˜9p|옙©ÆÐÐ0ÝÝ"öÅà ˜ ~±´PŒ8†8³ÿvÛÔYZé³³ƒƒ­4¥2ss¤^Ç58çˆãçè âz Þ½©Üþ³Á%µ ˜µˆÌ 3»—¡=ô;‡ÙÞÁ%Ò !-³¸ˆAP­V988 V«Q.—ÙÞÞîD °³³C¥Rá`o ±R ¤e!}cuÀý½ºJ*•bmm €ÑÑQŠÅ"…BÃÃCvwwÉårŒñçË—œ%‰ãógœôÍWoï+½y#“|¯«KÙlVaj}}]ûûûêëëÓÄÄ„²Ù¬$issSýýýÚØØPúéSýó铯·oeÏž½òÕÕ…Òi™¤ù÷ï•Ïçuss#3ë­¬¬hkkK’455¥(ŠT,µóã‡R©”ôä‰äûø2óÔh¨½™™Â0T†ZXXÐÀÀ€ŽŽŽT¯×uuu¥|>¯ÉÉIež?×ðð°EòÀóuyù]Õª$™$õöö*Š"+—Ë)ŒŒhzzZ…BAa*Š"U*ýõáƒÆ^¿6}ýª®ëëïj ÎqqqÁíí-I’pvv†s3ãüü€»»;NOO±F£‰[\ìT³©³f™$éè©-…6YÇßÒ™ã:{ÐÇ´ ï‹õÁ9Ih‰»ÁÜܽxÔÞ|Ô©ñ¨óì'í¿žêki /wIEND®B`‚routino-3.0/web/www/routino/icons/marker-19-red.png 644 233 144 2031 12573351600 15422 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“ÎIDATHÇ••½kIÆŸ™‘,‘#Wh… ¾JÆA,ì(¸r‘êl×&)¢Âp]jçFpwÁF„”é‚ãì"8Œ“"H†¸:ccD°íhæ¹bgeI¹Ãw/ˆÙöýéý˜ç]àÒäÈȈ€t:}Oký8¿²¯µþN§ï€÷“ Hø5`ü¤µ^ív» $966&¦§§¡µ†sRJc°³³ƒ““ !„RªaŒy à¯>NïnAÐÀ|>oêõºm·Ûtαߜsl·Û¬×ë6ŸÏô~·’Œ“ˆÃ °T*EÍf“$i­¥1懟µ–$Ùl6Y*•">ÆX)¡”z€år9J`‘1tÝ.ÙíDJk颈Ñ÷ï=x¹\ŽP)õ\J ¤R©9 ÃжZ-’¤1†tŽôNýÀ~3QD’lµZ ÃÐ`*•šƒRê=Öj5;Œó#ß¾îï“kkä»w¤s=p­V³>Ú÷àr¹œ;>>ŽA’yzJÎÌ•Êehëë$@ŽŽÆëÇLÚx||Ì\.çü•ƒŸŸ'Iv;øW¯È7bÇû÷ã³ósrlŒ|ü8Þ¿yC¦RäÞ“ªÏÏÏ€•¤Ö@éoÃíÛÀ—/Àô4pzŸY |ûŒÇû|ˆ"`o¯§Ï‘ €;<<”Èd2 qý: ÉÆÄ×®OžËËÀæ&ðù³—è)èè蜔RÚÝÝ]×h4|@öR¸äàó³gÀÊ ÀÒ02›É@ØzýÛÛÛBXAð Ó»ô¾£œ›#ïÞ½lT¥B>z?¯¬ÐŽ’í6Ï:N‹]/‚?Íf¡µ^÷—ß 4¬R!gg/¡/^ÄÍÈ›7i_¾$IþúàõÀ?d“äòZë¬V«–$#’ÜÚ"77ïé§OäÚÍÇ$É ççBˆbTq½Å)%tÆ¥²þAQ‰<¿~e¡PH´_íç€B@)õ a5½d{õí'g ÆÏÖÆøø8‚ è7¥”,‹ÐZ7ê;4P’èWWW­ö¦SߨÃÐA¨µn Ô×G–¤½¿¿Ïl6kc½È_†Ó¶+ë{vvÆÉÉIã‡ÇïBиÂê†a”ŒD’¬V«IÚû²KKKýŸ¥·áúÎÌÌ’l4ñÀ’Bˆ;þõàJàp}•R-\\\tSSSIÚUŸ¶ú¯Àú˜B@×G¸911¥”ü¿À^}ýº¥”‡~ÊæûJêq°;  þIEND®B`‚routino-3.0/web/www/routino/icons/marker-57-red.png 644 233 144 2113 12573351600 15425 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“IDATHÇ••ËkTIÅU÷Vwl]H"Ì"Eâ€D\¹Mû"‚’0Ľ»428þ¢›É2"¨DAFÁq—‚A¢ÓJ%>LZï£Î,nu#ƒÎÅw«¨:Uç| «f{zz,@¹\>èœ{ðÁkíÜ9÷¨\.çlÈ9ð‹sn"˲1Iêëë3ÃÃÃ8çðÞc­%MSfggyÿþ½Œ1&ŽãFš¦ãÀÛ58+7l¢¨ ¨¿¿?ššÊÛí¶¼÷ZkÞ{µÛmMMMåýýý) pn{—q÷ÅÕ(Š^ªÕjÉüü¼$)Ïs¥iúÝÈó\’4??¯Z­–àW@µ€µ–8ޝI$)Ï2%Ž|’HiZ ïW¾}’(ét”g™$idd$Çñk-”J¥Ã€ªÕjÞl6%Iišêg, /n6›ªV«9 R©t82Æ\õÞWÏ;§C‡™ ˆß¼[·àÅ xú^¾„­[áömxüææàùsì³gd==ô RvNݹcŒ1¿øÞÞ^¿¸¸(y//I““H==…ß²Ezýºð Y+U*È_»&IZ|ûV½½½>¤ùèè¨$)ûò¥àuô¨4<,--I>zæ¹ôù³ôñc±glLÚ»·8´[À:ç dvˆÌÎÂæÍ°s'ܸQ¬•JÅÚÝ»pï\¼Xì÷€€c-à[­N‡¸\.€——áȸ~öìcÇ ]Ãåœ9'NÀŽe˜(àÝ»wkmä§§‹ˆv:Ò‚´¼\ÐüôI2Fº|¹˜ß¼)mØ …\Î’D’tÿþ}Þ“EÑ€ªÕt~aAj·•oÜ(]¸P€LNyð@A8©V+ª+¤ÔÒÒ’víÚ•…"˜¤R©àœ» hdÿþT’²³g‹(GQáOŸV8-mÚ$?_TÜׯ’¤“'Oæð Ò M¿sî úøx.IÉÇÒô´ôäÉj¶w:Ò¥KR³©nyÌÌÌø¸lŒêÆÆ˜ÖZYcf¦Ð7¤ŠÍ®uk¿Õji`` [ûõµxÎCÇãAßÕ¦²¾dÓt¥æÇÆÆÒÐ[Û¶m#Š¢•UÀDZÂ9×Í%]›Ø«˜Å%yl­t§5mu Uç\P½^/ô iÓ¥=77§J¥’²Öþ¶žözû^ßF㛆ôIC«ûÓàø}£oµZMº-Q’êõz—öP9uêÔÚßÒÛz}÷íÛ—JR£Ñ(†µ2ÆÛ£®×7Žã& ãÇûÝ»wwi×íøg¿ÑØoŒ…þ=88HÇöÿ®èüïQÉZÛv¬cóý ’än™Ži»IEND®B`‚routino-3.0/web/www/routino/icons/limit-25.6.png 644 233 144 1541 12573351605 14662 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”ÍK\gÆŸ{%ŽsŇqHA±(FAt†–€™… ?Àdf“¨˜€‹ü ]&KAA¤î 1ÁD\Z’.¤ bÃD™ê0³œ¹÷}]8cµté³8_ïyyž#$! ×u‘\$QUõ=Ò$Žó‰ÚZ¸uËP[ Žó i²T’[š*UU9HU!½ÄóN…·o-¹|û¹Üy<: žw‚ô²Ôï”æ%*+]B!ÑÐЄô…¾>Èf `­á²ÇÙ¬¡¯¤/444 ‰ÊJWÄbb`ÀCÚb| X||¬ý×Ë9°@ñq¶ðˆÅJkJ¯Ä@Ñ/0Å"¾ï_¸µöâÆ÷ñ  éUùÏîàyÇ6“Á‚ŘÒF–ÿ3kíyí¼ÏÚL<ïéNÅ/Ò¯<}špž<1›ëëîï¯_+‰(‹innNétZjiiQ(’ã8ÚÙÙÑo³³ ߸áÄ;: ÙlØY[«P ­ñþ=mo›jÏ£»»›ææf–––hjj¢¿¿ŸT*E.—àèèˆD"AOO?Þ»Çîñ±áÍŒ´æ*¹«”ýüÙýùÅ ­¬¬(jjjJ¾ïË£ÞÞ^ÅãqIÒòò²¶··UWW§ŸîßW]8ì*‘SSsWܼiÌÁ~üH{{;ccc¤Ói†‡‡™™™¡¾¾žÅÅEfggikkczzšïnßæà쌠¦Æ¸Ö÷·²Rë[[J&“J¥Rš˜˜Ðþþ¾544¤x<®|>/I ‡ÃŠD"Q4Õß{{cלœ¬kuU«››6(5??¯X,¦ÝÝ]-,,¨ººZ]]]êííUgg§’ɤZ[[åyž~èèPêñc«wïTqzº.¤Iž?炃½=öJ~vvF±X$ŸÏcŒÁZËׯ_±Ö‡‡‡…@À³g M^ðŒLæœÙ—xVæZ¬œ7Æ€1˜ÿðìŠ,­ïcÏ%s𠑃 ÜSäáÃK ¸Vm^ëÕ¸Ö{v—ö^žkÄüþ8ÞIEND®B`‚routino-3.0/web/www/routino/icons/limit-10.4.png 644 233 144 1362 12573351604 14652 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“§IDAT8Ë­”ÁJA†ÿew(‘àM!Q0‚ÈúÊBnŃæà¬ >ƒÞ’$r¹wH+xÞº»áõkKw7xÞ¤•¦_H~3N¨”ËyHÓÓ9¤E‚à¥|ýê8?‡zÎÏ»T‚ øƒ´Ø<ï5ã%2ŸlVô÷¿EªR,B­fƒs–ÿ%± µš¥X©Jÿ[²Y‘Éø¢·WLNH?™›xq q Îý[­=pÀ#ss ýdr2 ··ùLi‰©)€†y|Ä&Xk‰ãçÜ“1Çh05ÒR«fï ‚ßT«p® äœKAþ×SÛ˜$ÃÃC‚ßHï…´Âì, ÀÎÎGGG°¼¼Ìññq bmRÆjµÊ÷oߌ+•@ZÒöËÆííílnnbŒadd„ÑÑQ†††¸¹¹y800À‡BÀšµ5ö|½z•×Ä„œä{mmêééQ†ÚÞÞV6›U¥RQ†ÚÚÚRKæççõðð ž7o$Ég|\êêÊûjkC™Œœ¤éOŸ4<<¬(ŠäœSGG‡$) CÝÝÝI’Êå²Ö××U(´»»«ã³3µ‡¡œ„/ç<5é­€†úúútqq¡ÓÓSœœhppPQI’ÆÆÆT©TT«Õ´¿¿/yž°ÖKkƒ(‹¬®®033Cgg' Ôëuòù<———”ËeŠ?&5ûü¤½ô7ƒµÜÞÞEQʳëëk¬µ©ÞâÝýý=¿®®’¸ÙÙô7ž&¼Iøó„ÖÚçÄM|Ïxö¤\Ól>ÓcpÏ:àE{óE§Æ‹Î³œ´8†”àÚ2œIEND®B`‚routino-3.0/web/www/routino/icons/limit-104.png 644 233 144 1326 12573351602 14572 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“‹IDAT8Ë­”¿J+QÆ¿]bV‚b +´P"ÖZX/¦ñôô-´±LP°K±V /&HÔbá_PãfÏ9¿[d“k®­gæÌÌ™™óÍIHÂ÷}$Id³cH;xÞýý00`éïÏ»@ÚIî…ä'~Bí@Ù¬‡äQ,f‘6‚wVV`ßqOOpß’WV Þ‘6{/ñ—H§}2122ŠT% ¡^·€Á9ËwjɆz݆ U%“é´/Åâb€ô‡µ5€pÄ1Ä18÷Û:p@ÄÚHX\ LÊ”6YZhb &аÎ`­%Žc\"Ø8ÆDQË~i ¤ÍvÏ& ‚7*g¢¨ãèœûqîè¬meX©@¼!M i‡ÕUãšM޹¾¾àêꊭ­-nnn:™U«UŽŽŽHê5¬®‚´#¤3Êe‹µìîî’J¥ØÛÛÃÃÔÔÓÓÓŒóüü ÀØØ °”Ë ¥Ô×7£¹9IòÈó<åóyår9(“ÉèääD³³³:<<ÔÝÝ>??•Ïç•´É×ÜœÔ×7ãË÷Q:-IrΩX,ªP(¨ÑhÈ9§ÞÞ^IÒÐж··U.—5??¯ÓÓSÝÔjJI¢§Gò}|9ç©ÙÔwÔl65<<¬‡‡ÝÞÞªV«ibbB…BAçççª×뺼¼l%E’s^WÏâ¯/Â0¤T*°¼¼L.—c}}c ¥R‰0 ˆ¿õ¬ë7@òúúJ£Ñèàìññkm‡?>>xyyi¸ë7»pFòz[¶…'¬µ]ÀMì~àìǸoÛA»È\+«ÿ&àWgóW·Æ¯î³_Ü´­’™«º=IEND®B`‚routino-3.0/web/www/routino/icons/marker-82-red.png 644 233 144 2131 12573351601 15424 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“IDATHÇ•UMkTI=U¯*z¥³pÑO‰\d@ÁÄŒ­ˆ¢f'dÁEV¦Yú4›†!˜q!Cz#ˆ »q—… .FLpaw„¬¦‰’N^½ª3‹ª×i;ˆ3Šûª¨:}ï¹÷žöLöööJÈår—´Öo€ ž{­õÛ\.w Â;™‰à#À!­õ|š¦S$Ùßß/FGG¡µ†sRJc°¼¼ŒÏŸ?S!”RUcÌ,€:pÚ¿p,Š¢:‹E³°°`›Í&sì4ç›Í&l±X4ÞË2Î"Ž£(ZÀ±±±¤V«‘$­µ4Æì[ÖZ’d­VãØØX€×ÄVJ(¥ž`©TJ2°dw—.IHcÈÎh­¥K&;;mðR©” Rꉔèéé¹€qÛz½N’4»»ìÊÙ¯’™I’d½^gÇ{zz®@)õ+•Ší¼ÈÕUrq‘|þœlµöÞ¿'="_¾$wwiÒ”$Y©Tlˆö5¸B¡à666|P$Y­’Ù×çý¹spiÉï ï¯_orccƒ…BÁ…–ƒ˜˜ I¦;;þñåËäéÓþûÝ;ðì92BNMùó7oÚçiHbbb‚¬ µÖ@èlÀÍ›À;ÀµkÀ§OÀÙ³{krÒßéí µ§'àH À­¯¯£ÕjA)å?~ô·šM`kËï[- RΜ<FF€[·€7 œ4 pR&ì‹‹¾¢››¤Öäüü^qN"oß&77É'È#GÈÇIk™†B½zõŠœ"AE¿àá86µÐR¶X$ïÞõ€>÷ï“W¯’'O’†/ê—/d’pk{›CCCi‚ß‘Ï硵þKãã†$Ó§OI¥H!|1Ο÷;x”’ÌåH)iC¡~½wÏÀ¿ä3A)j­—1?”gg݃‡¥©×¡——C‡€‹$^¼¶·©sP}}XZ[ã/ss"¢å€I®€!Ä)%¤Õ¥%Ïoà«=QÙ¤†ïõFƒ‡÷³¯T9¨ÚÝ „€Rj6ð»'*Ù„‘^’ÄŸ9Ç©ÉI´µzôèQDQÔV(¯”„ÖºÄÅó›EÛÆ5$Éùùy×ÛêÔ!{è:ˆµÖu,—Ë–$“m¦J+++Ìçó¥”?w§Ýmûù­V¿Špkk‹CCC&ˆÇC!h|Ǿâ7Žã$“D’,—ËYÚ+ò333Kß¶n~ÇCÿV«U°RJ !.„ëÑw»ùUJÕpzzÚ gi—CÚê¿~Å/€Ÿ„†ÿ€RJþ_À6¿ÁÏEQD)å:€ã]Ù쳇9r,!÷¹IEND®B`‚routino-3.0/web/www/routino/icons/limit-29.9.png 644 233 144 1525 12573351605 14673 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ IDAT8Ë­”ÁK[YÆ¿÷¬‰>;`!®"dDTª¤‹.ÄQˆ E°]I™Áv7ÿY¶.Ô@“RD†.Ýe¤Œˆ¦KÚ]Å‘.*yCò^îýÍ"±£Ì,½pàœsÏw8÷ò}GHB®ë"¹H¢«ëG¤Mç#½½z{Áq>"m¶ï…ä¶qB׺º$‡'Oº^ãy5–—áÝ;ËÙ|ý gg­xy<¯†ôº]ï´ñ‘ˆK4*úûÓHŸ™›ƒjÕM¬5Ü<­¸Iµj˜›é3ýýi¢Q‰¸"™óóÒ1++ À††`í¿v 4XYé˜ùyd²ýLé ÂFcÃcnh‚€°ÑÀ@ÀÂHo®ÿlÏûf+,XÚÀ› ¬µXkoûÆ`ÁÚJ<ïÒpÇ/Ò¯<>á<{fʇ‡n¾PçyêëëS©TR¡PP"‘P<—µV®ëª\.ë·BA‰X̉ªÕnçà CMé€þüòÅüàyLNN244ÄÖÖcccŒ“Éd¸¸¸ \.300ÀÄÄ™ø«Ù4¼}‹‘\Ý¿ÿPSSª~úäþüê•vww•L&µ±±¡T*¥½½=E"íììH’ŠÅ¢‰„ŠÅ¢"ÝÝú=Ÿw5;+ÛÓóÐíèìÄÖjZ˜U.—Óè訕Ïçurr¢\.§R©¤h4*IÊårò}_333*©³³SºwOr]\†Ž‰èðøXÓÓÓZ\\Ôúúº|ß×ð𰦦¦‹Å”J¥tuu%ß÷522¢l6«ÞXLétZò}9ฦV;Ô‡úãèÈ6ƒ@ÛÛÛJ&“Úßß ÕÕU---)“É(›Íª§§G¾ïkmmM?=}ª‰G¬Þ¿WG­v(¤M^¾äoh^œžrÚ¶z½NœŸŸc­ÅÃåå%õz½•oñ±É‹ m~ç•J‹Ùm~]7ø?Ι6Ï Xnðì–,6 ±-É|ÿÇo6¯k?¾¡€;Õæn;Ýgw¸iÿC@Sö¸5æéIEND®B`‚routino-3.0/web/www/routino/icons/limit-32.3.png 644 233 144 1523 12573351605 14655 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”ÁK[YÆ¿ðOµj]]är9XYY¡»»›±±1Òé4Åb€ÃÃC‰ù|žžd’¿K%C¡@ Ý¿ÿDOŸ*øúÕY\ZR>ŸW*•ÒÑÑ‘æççµµµ¥X,¦I’çyZ\\ÔÔÔ”~ëî–÷å‹£±1){"<0œŸPûþl6K__ûûûloo344Äôôô­Öj5²Ù,ýé4Û{{ຘ®.#¿£ÃryÉú»wd†‡annŽT*Åòò2µZ ×u¹¸¸`mmL&ÀÐà ½yõ:~G‡uÚ\wG?ê\Îþúð¡:;;•ÉdÔÛÛ«óós õ÷÷kccC¹\N£££êééQ<×àãÇÊ?nU(¨Íuw„´Êì,@à×ëT*‚ àòò’³³3Ž999Áu]ªÕ*ÖZ‚  R©à×ë³³ ­Þâ™iñÌsͧŸÌZÛìŸ1˜Ÿxv­€\À³¾Ap‹¬ÿ#l`›²òÈån(àNµy§SãNçÙNÚá…´cwz™IEND®B`‚routino-3.0/web/www/routino/icons/limit-0.png 644 233 144 700 12573351606 14404 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“uIDAT8Ë­”1Në@†¿Ý‰Ü$¢I‰WqZn¥WHc@ŸSpˆ´4HH¡Œ”t–hpœý(l ôŠÖó/m1»ÿü;³;3c¢€ÃáacÏŽÇzqqv<Öž…MsŽ?¤ƒ¼½ wæù»Ë¥><$G}{Óã±¶—KÍówá®á‡Æ̲è`€Óé¥ðêl¦ûýY­LéìwÔvå~v6Sxu:½t0À,‹8™à|ž /®×ªjòtÒÓISúZíž&õÃõZáÅùçýMÚOì*2›a'IEND®B`‚routino-3.0/web/www/routino/icons/limit-28.2.png 644 233 144 1515 12573351605 14662 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”ÁK[K‡¹“Þ&+‘ Ò·ª6‹.ÄÅ[""H7.úÚ(.¤øÆ‚ À˜›4¾OP«aÀgx¤W—ö×=±Å",õÄÿ°Ö^ÍÖZ0 Ö‹àº'Hïü)ýÅóç¿Gž=3;[[Îë·o庮Z[[U(´¸¸¨ÆÆF¥R)Ykå8ŽvvvôúÍÅ£ÑHêÑ#C©t7²¹yG¡´Éû÷|úöÍ$\—l6K&“avv–öövFFFH§Óxž€çy$ r¹é4…ïß Ë˄Ҧ£xü±r9•ööœÉ/´¶¶¦x<®B¡ ææfõ÷÷«­­Mggg’¤ýý}MNNjuuUñDB[ëëŽòyqïÞcÑÔdL¥ÀÆú:]]]LLL°°°@OOÙl–ÎÎNvww¯þoccƒL&ÃOŸb~üÀ&“F&·üüIaw—»±ÓÓÓäóyÆÇÇèîîf~~ß÷ñ<×u™™™áôä„àà­cªÕ-yž>noÛÐ÷µ¼¼¬––e³Yííí©©©I½½½êëëÓÀÀ€VVV$IKKKJ·µéזּ·žžn iޱ1Î ¬”Ë”ëv~~N†!ÖZŽ©V«T*Êå2ûûü!ccXiîŠ3ŠÅ ²¯qvÉÖõõ/rÍEü5În(À‚oƒ{!™°Þ·cÿ§€[Õæ­v[íg·Øiÿ$Ê‹À–ËýIEND®B`‚routino-3.0/web/www/routino/icons/limit-4.6.png 644 233 144 1276 12573351603 14602 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“sIDAT8Ë­”±JkA†ÿ³EBD#)^!µhllBÀØ ‚$ð%Lo'¤Ðΰ±T$…ÄBH!Fôœ³ûÝâ$1‘{;¶ØÝ™ÙÙ¿! Ic ’H¥þ ãyMææ`~Þ27ž×D:ž É ý„FR)Écw7…t„ï¿S©Àù¹£ß‡Áúýx]©€ï¿# í½¡¿D"aH&E.·„Ô¦X„n×ÎY&G¼Žèv-Å"Hmr¹%’I‘H‘ÍŠRÉGº§VøaaÎ}ÏÑ8à‹Z ¤{J%ŸlvøL©N¹ †`-ÖZ¢(šJÌZK†Ø €ø, \©>ÒlߣՊo´çι/œÞsq0G«¾ÿ†´"¤cªU€ˆ0ÄÚX¦v»Íååå8#€N§C½^çöö6±_µ Ò±n8;°.Ök-ËËËlmm3 ¬­­±½½Íúú:±-XÎÎ@º1J§ó*$ÉxÆH’õùù©……ÆÅÅ…:Ž2™Œ666”Éd$IždT(HétÞÈ”HÈJ’1j4:==Õææ¦®¯¯õðð I ‚`¨ÑhèêêJ’ä$)‘ŒÁÈ9OA0ÎÀ£|>¯»»;õz=5›MA T*¥ÙÙYhqqQ½^O#è’sÞ”fDáP·““vvvX]]ååå…½½=fffØßßí¬ÅMhöÏß´ÖòññÁëë+ÖZžŸŸqÎEOOOßüÅOýæ4g?@äl„ˆuMW@èC:«sLØü¨€_­Í_í¿ÚÏ~±ÓþÞ˜QØgœDIEND®B`‚routino-3.0/web/www/routino/icons/limit-36.5.png 644 233 144 1515 12573351606 14665 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”ÍK[Y‡÷VòqiÉqt`˜âª HŠÐŤ› Š„AF7q;Å`—íÞ­dJéŠ.fÕ)¸ÉbZè` ²ˆ$¢¶¡ “{Ïyf‘hºôÀóžó~ž÷’„ëºH.’ˆÅ¾CZÃqÞáûÐßoð}pœwHk½w!¹=;¡ G±˜ƒä07Cz‚ç}¡X„W¯,õ:œœ@½Þ•‹Eð¼/HOzúNÏ^"q‰FE6;‚ô‘|j5„Xk¸ººrH­fÈçAúH6;B4*"W¤ÓbzÚCúÀÊ @°Xûu_ÜÚ¬¬€ôéitºW¦ô”ÙY t‚vÓé`Œ!Œ¹ž`Ðnt:Ðav¤§vÏûlº{†Æ¬µW*´×öô,àyŸ‘îÞú]ZeiéGgqÑü÷þ½ûg©¤H$¢¡¡!U*­¯¯+kppP’677õÏÛ·ú·\v¾ôÈDëõ8ûû·d¤2¯_sxrbú æææÈf³ìììËåÈårLNNR­V8::"“É033Ã/óóŸ^¼ÀHå>ݹsOSS ?}rÿX]U*Öéé©¶··U©T4>>®±±1%“IIÒÞÞžZ­–ýœÏ+ºÜ¿/7‘¸çº}}ÈZý02¢_U*•tvv&Ïó”L&555¥ íïïK’|ß×üü¼òù¼~{üX¿y#'•’ܰÓqtû¶þzùR“hkkKñx\‡‡‡J¥R*‹PµZ Z­¦ááa---)“ɨÙlJÖ cY©Ìóç´Àüôð!¾ïS(hµZ,,,‹Å(‹Ôëu&&&ØÝÝett?‘`qa Ïža¥²ÖX^ƒósALÂ0¤Ùl^br|| @»Ý¦Ñh\ð²¼ ÒÚ5ÎL3c-ƘKX¯2g­ížÁ€µW8ûÚ…@Ç„á7a½t†Ønö …+p£½y£SãFçÙ NÚÿHØl ‹IEND®B`‚routino-3.0/web/www/routino/icons/limit-18.6.png 644 233 144 1474 12573351604 14670 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ñIDAT8Ë­”ÏK[YÇ?ï…æÇS&DÈ t6A¦ H c»âF„j¡ŒP(¢€ÿÀÀ,›½;§SPi¡àÊ…‹2]DE*]T„!SD†´èË{÷~g‘¤3[\¸çÜûýž{.ßs @®ë \J&¬Éq>ª¯OÊdŒúú$Çù(XkŸ#pÛ8D‡(™tŽ’‚ò¼/Z^–Þ¼±:?—j5éü¼å//Kž÷Eð¢}ßiãAñ¸«D ßœhvV*—¤HÖu[ËT.ÍÎJp¢áá»J$P<î¢\ÍÍy‚OZ]•¤@’UJa(Yû}ub’•huU‚Oš›ó”˵˄¢æç%©L cŒÂ0”17hÂPaÈHM=~,A±óg÷äyuœ(’¬mYke­íªÐÞŒ·X{|,y^]p/ö+üÆóçy={f\pÿzÿž(ŠÈd2±±±ïûär9Œ1¸®ËÙÙ¿¿|IêÎ燱1£r9åÆjsS’ÌŸ››ŠÅbÚÞÞÖÁÁÒé´544¤ýý}IRµZU>Ÿ×ÌÌŒ~~ð@×ëF¯_ËÀ¡‹ïßçáC,¸N,F6›ÀZK*•¢P(088H£Ñ`gg‡ÓÓS²Ù,S‘M¥\òy߿x ,××׋EJ¥Ùl–ÉÉI …ãããLOO322‚çyü46Æ/OŸZÞ¾%öõëkZY‘¤HÆèòòRWWW’¤ tqq¡(Šd­UµZ•µVQ©R©( ‚neE‚µï:;>n);о ¶£­î½µ¶%bcdþ£³ÿu€ Cu»ÅzcEj‹»©ùù®¸ÕÞ¼Õ©q«óì'í¿ïŒEú¸Ì(TIEND®B`‚routino-3.0/web/www/routino/icons/limit-200.png 644 233 144 1416 12573351603 14570 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÃIDAT8Ë­”½KœYÆŸ÷ ÑÉ Ã+i¬DÈŠ1£Ó9 Y”ÁB”Tb«€­µM,,l³TIÀÚ*,…$š"8SèÌà³0CÐÉûq~[̇β¥nñ»‡{îyž#$! ×u‘\$‘Hü†´ƒã|¥¯>ŒéëÇùŠ´ÓÚ’Ûº'Ô”H8HÏž%žãy?Y]…·o³3øñÎΚ¼º ž÷éyë¼Óº/ÑÓãÒÛ+!•XX€j5"Ìbn>«1 •|Do¯èéqE¿X\ô¾±¾ð 0ÂÂÌnf{ øÅú:HßX\ôèïo¥)Èç‚8 â¸ù¨8Ž Ã3»áF €€|¤BûÏžày5ŠE Ì¢¨“UÇ fÖÍQ„Q,‚çÕži‡µ5 "€ƒƒ¶¶¶ØßßàððíímŽŽŽºøøø˜V¾kk íéSüò%@ü÷Ç$“I²Ù,CCCìíí111Áèè(ccc‹EÆÇÇI§ÓŒŒŒðÏ÷ï±½zÒ'áûU«¼yý𠦦¦˜œœd~~€\.Çôôt‡3™ ¾x@T­‚ï›+×åÞƒ2IäóÊårJ¥RÊd2Z^^V’$ß÷U¯×•L&%IÉdRWWW’$îß—\WfŽ5r%íþ¬ÙÙY­¬¬¨P(h``@ççç*—Ë*•Jš››S¥RQ¹\V¥RÑÈãÇ’$'Š$3ÇU­öÅÞ½“$ûëÃEQ¤ÝÝ]ù¾¯(Š433£T*¥l6«ÍÍM +NkiiI¿?}*Ivïý{©VûÒ©&]Õë\\\prrÂéé)××ט———]ºëpSÀ]Õìè 0âµµu[sÃÿÕY—, ±[Šoí²hBSÜÿqÀzóN»Æö³;ì´ÿ%Ž’Ì$ïAIEND®B`‚routino-3.0/web/www/routino/icons/limit-12.8.png 644 233 144 1501 12573351604 14653 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“öIDAT8Ë­”1HœIÇß÷…U¿|ˆ˜Å%‡°’«B`I8±¹"D¶!ºE„ZZØY\™”‚UV½"+ ±›¬²hP¬ÖUƒ°bäv÷›™ÿ»{ñ|00ofþïÍ ¿÷ @¾ï |êìüQ°,Ï;TOÔÛkÕÓ#yÞ¡`¹µÀoéí@žÀÓäd§àÂð›fg¥÷ïÎÏ¥ËKéü¼éÏÎJaøMð¦uÞkéA‰„¯Ž”N?klL*•¬$#ç¬n[Ó7*•¬ÆÆ$8V:ýH(‘ðQ*…ÆÇCÁ-,HR]’SKq,9÷}´×$'©®… ¾h|%÷ê•cs“àæ¦ˆ`Yss’dd­ªÕªjµšjµš*•ŠÊå²ÎÎÎtss£ËËK9çT¯×U©T×jMÝÜœËß9;:j’mŒþϬµqfÿÁÙ¿*ÀűÚÛ€ÞV’dŒZp741q«î´6ï´kÜi?»ÃNû'fUKIH‚cIEND®B`‚routino-3.0/web/www/routino/icons/limit-53.png 644 233 144 1351 12573351602 14513 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“žIDAT8Ë­”¿Kc[Ç?÷_,b„Å u_%аõÖ v‹+˜ÊÊÎêÁ+w ;[A›ÿDlte‹W´pQH±Bd “›{?¯¸‰ïÇâ«<0Åœó9gŸ ÃPìíý]Ø4¾Øß¯±ýý_„ÍÎ9B؉Cº‰z{!°Zí>˜ÏÿteE?}J¼»Ó?ôî.õWV4Ÿÿ)|èèƒN<˜Í†ær82òZøæÜœÞÜÄjÛ$‰ýçJý¶77±ss ßym.‡Ùlˆƒƒ8?Ÿ¾º¶¦ÚT£H£H“äoëîi¢6][Søêü|ÞÁÁN™ðÑ…Õ–í¶¶ÛFQôdªqE‘qÛÕ¨->vÿlÜ|¾áÅEzc*úOuɯ~§ú‹ ÍçÂxÏð'ïß¿åÝ»˜v;$“!Š"ö÷÷988àüüœÉÉI®¯¯ÙÚÚ"—ËQ.—â8àÕ«˜ïßãô´áÔÝ]Õ8iµT­×ë–J%+•ŠËËËY*•¬V«{||œ–ÞlªÆîî*œf(Þ0= &@prrÂÃó³³ ±¾¾N¹\æêêŠf³ )›!ÓÓP(¼ CÉf‚€©T*Ôj5.//Y]]e{{›ûû{ …¿ôd³††$I@«E`€ÛÛ[FGGYZZbbb‚ fffØßß§¯¯³³3’$IZ-H’ ¤ÑøÌá!@˜¦›ššbgg‡b±ÈØØ{{{d2ŠÅ"ãããT«UzÒ—%B£ñaÓZMµÝRÕÇÇGëõzÊ•E‘õzý‰»ÎfW«)lþÊY›$É[q?Y×޳g; yVýŸxÑÞ|Ñ©ñ¢óì'í_ÄÄ?œ\q‘IEND®B`‚routino-3.0/web/www/routino/icons/marker-90-red.png 644 233 144 2073 12573351601 15430 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“ðIDATHÇ•U1K\Yþî}÷Ž:Á YȼA‚[)¶©ÜLRX„)R­BØ*E )œBØ.¤Ha±6Â2ØÍ+òB‚YZˆÁÂÀØ„‰’be,&Á5¾7÷~[ÜûÆ™‘%Ùóîá¾ïžóÝs¾\˜ìïï—Ð××wGk½ €¬÷ì\k­wûúúî€ÿN¦@Âû€ð“Öz¹ÕjÍ’äÈȈ˜šš‚ÖÖZH)‘$ ¶¶¶prrB!„PJEI’,ø»§} ê˜Ëå’J¥bšÍ&­µì4k-›Í&+•ŠÉår úïn¤§‡A`¡PˆkµIÒÃ$I.=Æ’d­Vc¡Pˆ=ð€ÐÁJ ¥Ôs,‹q ŸŸÓÆ1ÙjueJchã˜ñ·omðb± Rê¹”Èd23†¡©×ë$ÉäüüPÛwБÄ1I²^¯3 C€™LfJ©m\YY1Y­’««ä»wÝ`ûû.¾µÕ¼²²b|¶Û`‡‡‡m£ÑpA’kk$@ 9ÿà|õŠ ‚‹øâ"Ó¼‡‡‡­o9˜R©D’lYKÆ192B>zäv¿}K*E~úDÎÌ…‚‹¯®:àƒ¦¬—J%0€ÔZ(Ðj_¿££®/®_w±×¯Ý]àÞ=/•œßÞnOÇ‘ €=::’gggÈdÀˆÇÅE`cØß÷câtk¥œãö€•RJ³³³c£(‚ÆZàÉ`i `~¸rúû/_ÂÙÀd2þzó›››BAð;æóù¤öñ£ëœÛ·É‡QKKäÕ«îýî]òæM÷þìíÀùù3O“„ãã-?"›ÍBk½€Åéé„$[Qä.!퀗/Ðû÷äà yí)%ÍÓ§$Éßîß7p@6å8§µ>Àò‚!ÉøÃwÃ{{ÝpxHV*L|Ÿ®¯¯[øb<TîÄ-)%´¢/\c§#š6¾µ¤µ4~}txÈ|>ŸÎ~¹´J©̇ᅨ$É¥‘5~Šfgg¯­Ñèè(‚ h+”ï%ÇÇÇ¡µŽ¼¸8~{%ñ‡,//xÔV§ÙCO ÔZ×°\.;~}f©*U«Uf³Y€RÊ_{ËîµËüFQW†§§§œ˜˜H¼xü!„ïX¿aÆ©$’d¹\NË®ÈÎÏÏwþ–þÛzùöýE‘ ))„¸å·ßìåW)UÀ¹¹9;99™–]öe«ìâÀ/Bhù 7ÆÆÆ ”’ÿ°Í¯÷‹APJyàçžj.Ù¿—d~*U IEND®B`‚routino-3.0/web/www/routino/icons/marker-62-grey.png 644 233 144 2717 12573351601 15630 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“„IDATHÇmU]hTÛ]û/ç̇áæÂ™*fü¹\íƒ$â…ÜAHI|º6÷Å·Âõ¡-—‹¦0èC_êK_ŠÅZ'"vLK$RÄbâ$*þ4£)ƉNæFÏèùÙûëƒÉiüY°aïÃa±¾µ×þ>V(° .¥D¡P0Åbñ+"úcÛ=Ï# ÿY–Å”RÿfŒýX(þ^,y†`€-“ "ÒDô¹Rê„ïûßA@‰D‚¥ÓipÎ#Fc ªÕ*I)ÅZZZ†ƒ ø-cì9cLÐ'" `ƒ”²ìºî†d2îÙ³‡g³YfY>„çy¨T*T.—õË—/¿qg§Özý‡1ÆÅ®]»@›”òŸ¾ïoÈd2ÁÀÀ€Ú¸q#B€ˆ>ZRJ¤R)¶iÓ&^«Õ‚/^$•R¿2Æü•ˆ~ù|þÜl6»2™L088¨lÛ†1&RÆ9c Œ½³–ˆ µ†ã8ؾ}»˜ æçç“¶m‹ÅþÆ}ßÿÚ÷ýo“ɤéïïW+¾ !À9çD‘1ÆÀ9‡”2úÞß߯’ɤñ}ÿ[ß÷¿ÝÝÝ?yž×–Ïç)“É0­5„¨×똙™ëºH$‘ÒZ­†û÷ïãÕ«WH$Çq ”¢J¥Â”Rí2 Ã/‰mÙ²…€µZ gΜïûp]Ùlû÷ïÇÔÔFFF°fÍ,--¡³³€l6˯]»F®ë~É=Ï£t:Íb±´Ö€ÑÑQ¤R)=zƒƒƒ¨Õjh4¸rå r¹Ž9‚ÇcrrwïÞÔ¦ÓiæyÉw÷ð.‡B¼}ûóóóˆÇã8vìb±zzz°víZttt`ëÖ­Ñ¿¶m¿—áå=—B³´´Äƒ €R <ÏÃÞ½{1==sçÎaýúõèííE†˜˜˜ÀÕ«W‘ËåÐÑÑ] ëºàœnÛ¶~ôè‘™šš0Æ@DèêêB.—þ}û`ŒÁ“'OðæÍœ}ú§OŸF† "twwcçÎ8~ü8”RB@kf³‰`vvÖŒñx<>Á/ÙÐЬSJ]ýúõ/vïÞmòù<¯×ë¨V«hmmźuëàû>€;wî`||ŽãÀó½”²yùòe€V±úð)-Ëê«ÕjÉF£A“““Úu]¡”ú=€a"Š|\%ê½Ñ X5²%€ˆº9çcžçi)¥R–³ÙìWÓÓÓ\km>$|¯üOذâï?ˆèGÛ¶…bNký›Û·oG½÷SøYbÖÝõ=yºIEND®B`‚routino-3.0/web/www/routino/icons/limit-25.png 644 233 144 1404 12573351601 14510 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“¹IDAT8Ë­”½K\MÆŸƒ»¹ø0÷vʾ(S§°K? Ó¸E`-,,ü)“RÐÆV ‚Õ+h#H4BÀT²Y¿I±Dï½3¿·¸»&ï+é80gæœ3ç<óœ#$! k-’Eùü?HËó•®.xñÂÑÕÆ|EZnÜ É6ü„šòyƒdxû6ô‘ øÅì,|þì9?‡Ÿ?áü<Ógg!~!}lØ›†¿Dk«%—½½¤ïŒCµê€ï®LO©Vãã }§··@.'Z[­C19 }cqàð$ $ xÿ[šgà{AúÆäd@6Ê”>15“¦¦8çH’ç²ä’$yß°b¦¦@úÔÄìAPçä${Ñ9¼÷xïÿ¨ÎóheÁ<''u¤W-ï¥*•ÞèÝ;§4µX+cŒŽµ¾¾®¶¶6…a¨ U*i``@¹|^$‰1/_:ýøñ\-B:`m À¹û{ö÷÷ioogdd„þþ~Êå2…B‰‰ ŠÅ"YÆq àX[éÀª³óµ†‡¥Œ3’¤jµª……moo«§§G+++J’DÎ9)Š"2ÏžI’Õð°ÔÙùZtw;nnšà<¾»»Ëàà óóóT*fffX]]%Š"Êår[ö³psÝÝÎÊ{£8–$yçd­Õáá¡FGGU,µ´´¤³³3õõõ©T*)Š"]__K’I’âXòÞXÕë_´³#IÞ;'IÚÛÛSš¦ÚÜÜT†:==ÕÖÖ–:::444¤ééiIR‹1’äµ³#Õë_„´ÌÜ@Ú $···\]]Q«Õ¨ÕjÜÝÝÇ1———04È—ùÍÍ´ü˜gþ×E¿yçœÃg›G<ûk44ƒü‡Èí€'íÍ'O:ÏžpÒþ yòx»ûñßûIEND®B`‚routino-3.0/web/www/routino/icons/marker-31-grey.png 644 233 144 2603 12573351600 15615 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“8IDATHÇu•QhT׆ÿµöÞ3''(ŽÃ¥ Á‰2A0 µÅ@F,ÍC±`ªpûP[J^Ê4ÌÛ}ðúÒGïss-‚2[IJ´Lt¦æÁ¤IïØ¨Ìtd¢çì³÷¾fÆDí‚ ë<ìýë[ëœCÙlkÁRJd³Y›ËåsÿÒZï ‚À ¼ ÇI)õ+d³ÙÉ\.ÇQ€ZÎ9ãœû@)u> ÃÏ´Ö.‘HP*•3·­µ(—˨V«N)E±XlLk}–ˆþ$"ÀHìœ3vH)§ÆŽd2 p&“¡x<Ž·#‹E755ež?þ™ïûcœs¿‹ƒ:RÊÛaîH§ÓúĉjçÎ$„€sî#¥Ä¶mÛh÷îݼ²²¢Ÿ={–TJ}l­ý¯sî/qäÈøauuõP:Ö§NRžçÁ¢×(™DÔ:`ŒïûØ·oŸXZZÒOžL$.“Ép³Õ‰‰ ܾ}›7oF­VÃÀÀE¬µáôéÓ­‚===|ëÖ-×h4>ä \*•"ß÷abrrCCCÁ±cÇ011(—Ë8wî°iÓ¦ kÖÖÖ†T*EA8~mŽ[í !pòäIìÚµ ¥R Åb{öìtttàÌ™3èêêÂË—/ßYµ5f!„­×ëÐZƒˆÀÌèî—/_ÆüüXkAD˜…Ö½½½ "\½zÕÎÏÏ Ïóîk­?{÷î…µöÏó†+•ÊÖ(ŠìÑ£G)Ncûöí8pà@ërÓY"‘@gg'¶nÝŠ¹¹9wãÆ ö}ÿ¥µö0ýO2³ð‡µö ß÷oÍÌÌ¸ŽŽôôô •JˆZCi wvv‚ˆP¯×‘Ïç£X,¦ˆè;"ú €dED?1ó×D$®]»¦«Õ*ˆ¨ÕòÛÀ|>U«U‹Å.vwwÿˆšãÔDÄû÷ï?Ç/Öj5uåÊ•h½»õ‹Î̸s玕íííËa~[(ZÅÄ¡C‡šÕ©\.;cÌ/žç}R©T’ÆÛÕÕEƘև…™ñôéS\ºtÉ)¥À?‰èI8—˵L0³dæekí)ß÷1==íŠÅ"„- ZkŒEa²â<] Ö0"—Ë›ÉZ¼—o­VkíåÔÔ”]^^–ñxü· ¾;|ø0Ö b ,ÞÞÀ·Z­ªñññ/¸õÜÅú‡÷ñÇ㟬¬¬$kµš›››3FC(¥¾0æœkq\g G `Ý/[ˆœsýÌüSFJ)¤”S™Lf°T*±1ƾ-¸¡ý÷`hòýÙ97âyžB,c¾, 0ÆàïâÿH‘¥åŠòlõIEND®B`‚routino-3.0/web/www/routino/icons/marker-6-red.png 644 233 144 1750 12573351600 15345 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“IDATHÇ••¿kIÇ¿óK²ÕäâZa‚lü,œˆR© g“ĽVqpUê8§‚Îÿi¹s‘&…î"¹Pe#ä`vwæ{ÅήVòÝåîÁ0»£™Ï¾÷}ož€±É™™ Åbñ1æ3p~fþÝó¹X,>N¦ ágÀøÉ³ÇñIÎÍ͉••càœƒ”QáààgggB­u7Š¢-'9Nö…[J©>V*•¨ÝnÛÑhDçóæœãh4b»Ý¶•J%@îVqêq ”:ÀZ­öz=’¤µ–Q%# “E´Ö’${½kµZèÁÇ‚+%´Öï°^¯‡), ÃÄKçÈ8»j-s Ã0ƒ×ëõµÖ凜@¡Px€AØ~¿O’Œ¢(o2ÎÏÉËËñZn_¿ßg …Â#h­?`«Õ²×€Éùü9 R’oÞü-¸ÕjYïí'pårÙ ‡Ã,Œ$_¿N€ùêUòüáCò[gû‡Ã!Ëå²ó%Ûh4üžx ’äíÛäË—„[[äÞÞø=w®Ñh€•¤1@6''ÀÇ@©”Œ…àñc€”šØî9RpƒÁ@^]]avv$³!ç€ïß·o¯_/€7€'Ok¥ Drâôô¤”!ÛétÆÂ§áŸŸ“J‘;;c9îÞ%>ÌÂOCßßß''„¡”ú «Õj”/úÌîÜ!77“çoßȹ9òÙ³DzŸÌ‹‹ .--Åþì T*Áó‡/þ(>MÚ»wIÆk5òæM²P ¿|I>†$É ë‡J©zcÌ16›MK’aŽeØÛK OŸ’‡‡‰L¸»»ë<ðR±˜u’q_JIq·Û½®oάb0°Z­¦w¿™ç€B@k½åõh*Œãä2DÇ™ækkk‘ï­Ýùùy(¥äDi­åââ"Œ1ÝkúNÜÚ$9ÛÛÛÖYwʵ=L-Ƙþ5}sUqttÄR©dPJùËtØÓöïúŽË'òÍãw_ø?° }ƒ Ó–H’Íf3 û@iss3ÿ·ôÏ6­ïêêjD’Ýn7iRRqßoW?N뫵îàúúº[^^NÃnú°õNè àž‚bï០ÐZËÿ Ìôõó¯J)J)~žŠæšýÃG¤)ÑjµIEND®B`‚routino-3.0/web/www/routino/icons/limit-147.png 644 233 144 1405 12573351602 14577 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ºIDAT8Ë­”?H\[Æ¿s•»û.uÃKÙÅÆØ(¤lØF4¥Rh¯`ý eRk+[¤ XЬDrÁµ.h#q]ˆÊýsÎïwMÌHãÀ)æœo¾™3|3B’ð<ÉCåò8Ò:Æ|fd=²ŒŒ€1Ÿ‘ÖûïBòúqBwDå²A2¼|YFzK|cq>~tœŸÃׯp~^ø‹‹ßÞöñ¦/áû¥’{ŒÔavâØ9ÎYî[áçıev¤cc)•„ï{btT4›RÄÊ @8² ² œûqîîÀ ++ E4›££ýoJHÉsò$Á:÷½ k-yžãœ#Ë2²$!KS¤Ìσôî®g5‚ Çñ1€Ë“wÈ9÷“/CQáñ1A©6ðŸôF¯_?Ó«W–,ó<ß×ÞÞž¬µªT*2ƨÓéèääDÆmll(Š"}‰"ý[.›Ê“'–8þÇ é€,ÖÒjµð}ŸÍÍM’$¡Z­Òl6i·ÛLOOS¯×1;Ÿ>Øüý{5<üTÏŸK’ç@Æ…a(@’´ººª,ËT*•499©ýý}­­­©Z­êE£!'yõº4<üTT*–‹ ²4 ^¯ÓjµØÞÞ& C'Žc.//™˜˜ Š¢¢uP©ØA9g”¦ºoÎ9Ykåyž¦¦¦txx¨ÓÓSéèèHaªV«Éæ¹¥4•œ3žz½¶vw%ÉÉ9IÒÐÐ’$Q£ÑÐÎÎŽ–——Õh4433£­­-ÍÍÍY­-âvw¥^¯-¤u––ò¾ ¹ººâööö»Æ®¯¯év»t»]nnn yøœ¥%ÖÓyÎßÌ}ÜO:ûã¸?Þ ×9W˜_&àAgóA·Æƒî³Ü´ÿ]>vô IEND®B`‚routino-3.0/web/www/routino/icons/limit-35.3.png 644 233 144 1511 12573351606 14656 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“þIDAT8Ë­”ÏK[YÇ¿ï)Fߨ±!ÆM¤#‚"….\M¥´‹Y†à¯M6-¢nÜù ºlWnܸ²t@H ‚KApÁ f„ BPK5-˜÷Þ½ŸY$±Î0K/¸çÜó=÷œÃ÷! I¸®‹ä"‰öö_ÖqœOôô@,fèéÇù„´Þx’ÛÀ 5µ·;H33íHoð¼o,,@.g9?‡«+8?¯ë àyßÞ4ü^¢­Í%Éäc¤©”˱ÖpÿÔõrÙJT"™|L$"ÚÚ\‹tÚCúÌò2@ °XûCš6°@åe>“N{Äã2¥·LMaÀj5ŒïÁXkï4¾OP«aÀgj ¤·Íž áy×öø¸þ£1Š,ÿwîìu?kÁ󮑆Z~—VyýúWçÕ+S<:r7ß¿WGG‡‰„²Ù¬vwwuxx¨ÁÁAE"9Ž£b±¨Íwïimuúž<1”ËN¡Ð"#øð¿®®L,eff†þþ~òù<¤R)2™ ggg”J%b±³³³ôÅãüY,>~$” ­êêzªçÏ~ýꮬ®êçx\———ÚÛÛSµZ ‰‰ õõõI’Œ1ZYYQ"‘Ðߥ’ü/_\½x!uv>..¨ÞÜN§amm¥¥%666èííegg§Ñ*CµZerr’þd’ƒ£#øþ7ô}Gú#›ÕسgÊçóêêêÒöö¶†‡‡577§D"¡ÓÓSIÒææ¦ÆÆÆ”Ëåô“ç©pp µ´È†¡#+ØÚâÌo/_ÒÝÝM&“aŸ¡¡!¢Ñ(óóóT*FGG999a||œh4Êt:Í5¶¶°RAHë,.„Áí-•J… NLnº1k-Xk ðîw{ ²¸Òú¿xf00ù¼ªXk8mÇ~•|Þ00Òâñk46ІWÄbbpÐCzÇø8@°Xûÿ:9 ”郃±Xí™Ò††0P ÊeL¥€1† 0ælƒ¦R!(—1Pah¤''Ö†ç}µ¹,µÄÓ¬µXkÏîãÖærày_‘ÚêIpïÞ¯ÎÝ»æŸõu÷¯çÏåyžZZZ”Íf•N§åû¾b±˜¬µr]WÙlVÏææôSS“»~ÝÏ_r2™:U¥ ¯^ñúãGó£çÑÛÛK{{;©TŠX,F__ñxœµµ5ˆF£ Ózõ*¯?}2¼|IUʸòýݸ¡üû÷îïjiiIápXóó󚘘Ðââ¢|ß×úúº$)yž§d2©Ÿ[[uôù³«Þ^É÷;~¨«¯Ç:C7oªåòe% utthvvV+++J$êîîÖÈȈ$iooOÍÍÍš™™Q±XT4‘\WN]2¾oùò…¿ß¾åR(Äää$ÆVWWñ<©©)(•JìïïÓßßÏØØímm<›ƒ£#‚¦&«Š”aa?ÓiSïºtuuÇI&“D£Q:;;‰D"¤R)’É$ËËËôôô‰DøíÎJ`H§±RFHÓÝÝbtô+Ò5‹‹p{ë€3Çÿ#³Sno‹‹ ]3:ú•în¾KK!Ò%-ÀHH0û7Û{`@‹ .YZ ÊÓ”~²¼ “¦¸8&Iœë|˜s.ÛcHÓ ¿¼ ÒÏ6gã„á3WWY"I‚½ee˜Ù‡5€eÁŒ«+Ãg¤q!m³¾ZP­VÙÚÚâæææíE§§§”ËeÎÏϳ€>e}¤m!ýfwàâ₱±1fgg™œœ¤V«ppp@±Xdee…R©D¥RÉ.Çî.H¿}õô|×ÜœLò%éääD:::RÚßß—$%I¢0 E‘†‡‡Õl6•ÓäknNêéùîË÷Qd‘$EQ¤F£¡……U«UuuuI’êõºµ³³£‡‡‹EI’'IA ù>¾Ì<űڣÙljbbBóóóêëëÓÈȈÌL{{{šžžÖáá¡Â0T¥R‘$™$űdæ½qf9g///DQD©Tbss“§§'fff8>>fjjŠþþ~VWWi4`–ùåœuüf.H^__¹¿¿ÇÌpÎQ¯×13Z­µZ$ÇåøŽßìÔYšâr=ý/ZçܛΜsX»ÞéìC¦}¿Î1+àSkóS»Æ§ö³Oì´Ÿ¹†`îÿàIEND®B`‚routino-3.0/web/www/routino/icons/limit-25.5.png 644 233 144 1517 12573351605 14664 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”ÏK[YÇ¿yy46-H^V E)SpÓ…+u§Q±…@º¨l‹Ð¡øg´K©nt-H± ȸ°CJg!B,XÒn$h~Ió^îýÌÂÄÑͬß#$! Çq$ÑÖö;Ò¡Ð.±ܹcˆÅ ÚEZhÞ ÉiÖ µµµ…B<~܆ô×=afÞ½³”Jðó'”Jçç™pݤ×ÍüP³^"vˆDDgg7ÒwR)( ÐÀZÃe;?7( ©Hßéìì&á°#âq1>î"í17P,AAÖþç­X ÎÜH{Œ»ÄãÍ1¥7LNbÀêuŒïÁ…[k/Ôë¾O>““ ½iýÙ=\÷—-°`1¦9‘åí<ÏR(€ëþBº÷›¤—|`ûÇu]éééaccƒîînÆÆÆÈd2”J%Êå2žç111A&¦|vfX]ÅH_ݼù@CC*~ûæüùê•677ÕÑÑ¡ÅÅEA cŒFGG•H$$IÛÛÛ:>> ÑTJ^$âðð¡œ[·ˆÛ·©Vøçógz{{™%ŸÏ3==ÍÒÒžç±¾¾@>Ÿ'›Í²¼¼Œó×ÇP¯Óho7Ž ‚kgoOÃÃÃÊd2šŸŸ×á᡺ºº”Íf•H$T.—e­U±XT2™ÔÔÔ”<ÏS­V“¬Æ„sr²£­-m}ýj¾¯µµ5Åãqíïï+—Ë)ª¿¿_###P2™ÔÊÊŠnÇbúãþ}eÒi«÷ïuãôtGH <Î)4ª4ýìì ß÷©T*c°Örtt@½^§Z­¶xlðìH œQ(œss‰³k­fWâÆ`ÀÚKœ]Q€ßö\2W^Ù6­ŸG.)àZµy­[ãZ÷Ù5nÚ*°yæH¹ÓàIEND®B`‚routino-3.0/web/www/routino/icons/limit-23.png 644 233 144 1312 12573351601 14504 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”¿JcAÆ¿{4^Ôhš ‘ ‚>à…¤¶KJ‹<ƒU–i¬,lİÔB]CD-CÁ"ÄxïÌo‹Iü³înåÀ…93g¾{Îw¾s„$$áû>’$b±ŸH<ï–©)H$ SSày·H•Á½üÁ;¡!P,æ!yär1¤AÐ#Ÿ‡£#K«OOÐj9;Ÿ‡ è!•þÞà½ÄȈÏè¨H¥æ‘Éd ^7@„µ†ËÙõº!“é‘TjžÑQ12â‹dRllH÷‹}À††`íû7< ô)Aºgc# ™¤)•Éf^‰"ˆ"Œ1„aˆ1.¸OöÀx%›©<ä,Mtyxp4k-Öڷ솀ïÙZpg–‡‚.RZH €ˆ0|©ÕjìîîR«Õ¸»»£\.s}}ýèRŽ(@ªé.€~€ËËK&&&X__gqq‘ÃÃCfggÉf³ÌÌÌpqqá"vþ†ƒ~ùŠÇWµ¶&9ÍH’êõº¶··urr¢ññq]]]©T*)—Ë)™LªßïKN›’äkmMŠÇWÅô´¡Ó’ñÆÏÙÙËËËlmma­¥×ë±¹¹ÉÜÜ777.2Wèt`zÚˆxÜÒlºKÇÕj•±±1vvvØßßgee€¥¥%ööö__X³ ñ¸õÕíVuz*IÖ#I:??WE:>>V"‘ ……MNN*N+—ËI’~xž$YžJÝnõK5žŸŸi·Û4 ///ch·Û„Ú×j~ÖÙ‡?tõQ¼ÿÓÙ_;`(Üâ}Ûÿ³¾µ7¿uj|ë<ûÆIûÖº{„ÆâzIEND®B`‚routino-3.0/web/www/routino/icons/limit-184.png 644 233 144 1344 12573351603 14603 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“™IDAT8Ë­”¿JcQÆ¿{]“xu Š ÙJÄÂÂNÁÂÆ`a:mõ|ûØ[‚M@Á* ÖÑ[(.dRˆ…AWWÌÍ=çü¶ÈMLv·tàÀÌ9g>æÏ7#$! ß÷‘|$‘É|CÚÃ󮂯_-CCàyWH{É»üÄO¨ ”ÉxH…B©HüfsNN÷÷P¯Ãý}ËÞÜ„ øTLþ{‰¿D*å“N‹ÉÉR•|j5 œ³tKË6Ôj–|¤*““9Òi‘JùblL¬®HßÙÞˆGCƒs§}ˆØÞé;««ccIšÒ.kkMŒÁDÖ9¬µÄqŒµAÚ8ÆDQëÿÚH»íšM¿¸½p&Šp s®£wÛÎ9h;no!~!M i­-ãšMÎÏϹ»» CŠÅ"×××ÐjµÊéé)I¾†­-ö„tI©`±–££#úúú(—ËT*†‡‡Y__gbb‚J¥@.—cii –R ¤K_ƒƒ³ZX$ß<ÏS6›•$9ç400 ååe«ÑhhggGFC###JÊäkaAœõåû(•ê8 MOOëõõUõz]£££ÚßßW³ÙT¹\Öáá¡uqq¡Ÿ?~è‹$úû%ßÇ—sžšMu‹µV™LFÇÇÇš››ÓÙÙ™Òé´Â0Ôüü¼Â0T­VÓÍÍM+ˆ(’œózj7¬¬¬P*•x||dff†l6ËÆÆ///Ï爻jÖÓÍ„uŸ}â¦ýå…–mŽP™{IEND®B`‚routino-3.0/web/www/routino/icons/limit-47.png 644 233 144 1253 12573351602 14517 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“`IDAT8Ë­”±JcQ†ÿs#1{LVQ !¨U°²²ØÎV )+’È ,l©• )M•Îð!DQ $B$iDƒ Brï9ß÷ƨ[eàgÎÌ?gfþ! Ixž‡ä!‰Tj ©‚1W¤Óðó§%c®*ñ»¼ØOh”J$ÃÖV éß¡X„ÓSG§ÐéD÷b|ÿé ¶7±¿D2é1>.²ÙE¤&ù<´ZqÎ2,Ñ=¤Õ²äó 5Éfɤ'fgE¡à#Õ)—z€# À¹g ô(—AªS(øÌÎÆiJ‡lnô CC¬µ„aˆsŽ Þ ‚MŸÍM5ËáûÏ4QÄÈ9‡sŽo%²s4àûÏH¹Äoéöö~iw×* =É9'ÏóÔl6u{{+cŒªÕªêõºnnn411¡ÌÔ”cff¬îïèüðî žýw†>}9#Í‘n‘î³nÚ¿ÏÐÈÊã'IEND®B`‚routino-3.0/web/www/routino/icons/limit-0.9.png 644 233 144 1312 12573351603 14570 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”1K+A…Ï.¸ KB‚ 6BЗBmŒ`gaa£…b¡­¥þ€€àoÐF,òì,Düi£ ä!#¨èZˆÌîÎ|¯Øl4øÊ ,ÌÜ=çpçιWHB®ë"¹H"›ýƒTÃq®)atÔP,‚ã\#Õzÿ…äöxB©P6ë 9lme‘ðýOvvàôÔòøooðø˜œwvÀ÷?‘zx§Ç—ð<—LF”JSHY_‡vÛ1Ö~®äÓnÖ×AúK©4E&#<ÏããbcÃGº¥Zè–(‚(k¿¿4èR­‚tËÆ†ÏøxïšÒ!››!qŒ C¢(ÂZ;˜1†(Š0Qqœà77A:Lk6ƒï¿Ól&‰ã¾ˆµöÿ{À&b–f|ÿiFH5vwb†4›MŽiµZýŒGGGÜÝÝ%¢ >fw¤š.99Á‚xyy¡R©077Çôô4ApssC¹\fqq‘J¥Âëëkš¥áä¤KW…¼––d$W’...”Édtuu¥|>¯³³3IR½^×ØØ˜êõº<ÏÓùù¹$%¼¥%©P˜wåºÈó”®(Š”Ëå$Iù|^ÝnW’´²²¢N§£ÕÕU5 ŒŒô9ò<Éuqe­£0”Ó‹—J%=??ëááA÷÷÷*—ËúøøP§ÓÑì쬖——U,599)I / %k~ÍÓóÛÛÛär9ö÷÷ ‚€……Z­kkkLLL°··—x%Á÷k6𚩘1† 0Æ`Œéûëë‹§§§oÿ%ø×üå³Ô ƘŸõãÖ¦¦ýå³_Àã¦Bûæw µ7‡:5†:φ8iÿÒ‡kxP£iIEND®B`‚routino-3.0/web/www/routino/icons/limit-98.png 644 233 144 1273 12573351602 14527 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“pIDAT8Ë­”=O*A†ßb!ÛHÌML¼6Zag%‰¡"X[üÔþl¬¨,¥³ñXC0ñ#&~TjL,0B„eç¹Åê½Þ[q’IæÌœyç|¼çIHƒdD<þ ©Šã\’HÀôtH"Žs‰TÞ É ß €âqÉak+ŽTÁóÞ)•àøØòø¯¯ðøé¥xÞ;Rehï ßK¸®!‹‹KHwäóÐj…ÀkC¾J¤hµBòyîX\\"®kD2) é†r X‚‚¬ý\£3°@r¤ dr¦´O±Ðg0€Á€0 ‚€0Œœû¦m€>Å"Hû£œ­àymno£Ãk-ÖÚqt#ÀÏh-Dg–Û[ð¼6ÒŠªìî ‚1ÈÅÅ<<<p~~N¥Ráêêê0 yÀî.HU!5©Õ"ú}®¯¯Y^^f}} ŽŽŽ˜››c{{›……Fäq¯R«Ô4ššZS&#IÆ*’z½®™™ÕëuÅb1œœhvvVÙlV©TJÝnWЏ)IF™Œ45µfd r]I’‰.•ËåÔét”ÍfÕl6Õn·åû¾õòò"ß÷%IŽãD¿»®d FÖ:ê÷õUºÝ®VWWµ¹¹©T*¥³³3¥ÓižžÊó<5 I’µÃXú}ÉZç[Îl”PÞÞÞÈårÌÏϳ··Çýý=étß÷ÙÙÙ¡ÓéDEˆìÇ9û«š#ùøøàééiL‹^¯Çóó3Á›Ÿªù#ÏF £ýˆ2ãý?xöcŒ¹ô'Yá?0ÑÞœèÔ˜è<›à¤ý †Â…ÏhIuîIEND®B`‚routino-3.0/web/www/routino/icons/marker-23-red.png 644 233 144 2141 12573351600 15417 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“IDATHÇ•UMhYþÞßL2(ÈÝÃt̆ìÁ$ä¶(ˆƒëðç«&YÁ“¹9‡àž¼yr7e/*Ûô"(Ù“ƒ ²`4ÎzZM”9$›ôëן‡×=™‰,ë4Õ¯èþºê«ª¯-“]]]òùü¨1æHRÏö³1æY>Ÿ€ô=™‰Ô+À7Ƙ™8ŽÇI²§§G:tÆ$I)%¬µXXXÀêê*…BkZk/ø» §õ…~¥TK¥’­Õj®Ùl2I¶[’$l6›¬Õj®T*YLßëÏ*Î2”Ro°\.Gõz$霣µö‹Ë9G’¬×ë,—ËQ ü@àa¥„Öú&V*•(‹66˜DÇ™2Ž™D£x¥R‰Pk}SJ är¹ãk4$I»¹Ù ä™$þj3E$ÉF£Á ær¹ãÐZ/àìì¬k/^ׯ“ÙGœ#ççÉk×ÈÇ=°µ$ÉÙÙY—f»I±XLVVV|#Hòöm ‹EïOœð ÓÓþ¼{·÷/2Ë}ee…Åb1IGnllÌÓ•rÄrrÒß?}ênÝ"wí"/_öñ«W}¼ÙdÆúØØ8 @cˆ"`t˜œôsÑÕå}w7pç°g07„!pò$°s'à R nÿþý\__oÍ!IÏã•+d.Gž9³ÕçÏI­}–§O·F$Ëå28H)#îÆžx’\^&ɽ{É4Îɹ9òÓ'~ò„ß½K’üãÑ#H„”R?`oo¯m ýäÐùþ½ˆ"òõkŸ]­æc‹‹LòáC®‘Þ·/N—à7 cn`åØ1ËïØA*EæóÞä½{ä¥Kþ^J²»›îÜ9’äOgϺðO…LPJƘkí·Õóç“_N’öÕ+O¼RÀæ&pô(Ðß,,/_"„>x¿‡!œ˜J©’$ùžä_ @HyD AH‡÷ï{~·¯hÚ¬1ïÞ¾eod»_MÔ™ !´Ö°·TŠêËË`s“´vkE­¥K·n||ܦÚöõõA)ÕR(¯µ‚1&LÅÅzýèÌ6[Ë™™—¾k©S›ìa[ 0Æ4°Z­:ßü¨£ì¥¥% €RÊÓÛËÞnž_!ŽH) ð#õµ5ÛT<~B€ÁX¿AD™$’dµZÍÊ^P˜ššjÿ-ý»mç÷ðáÖ$Ã0$'¥¤âHÛÿí«¬Å¯Öº€ÉÈÈHVv5-[-`¿~B@œf8?00­µü¿€-~S?­”¢”ò€ï¶Uó…}HšÑ»öóÌIEND®B`‚routino-3.0/web/www/routino/icons/waypoint-left.png 644 233 144 244 12302414107 15720 0‰PNG  IHDR Vu\çbKGDÿÿÿ ½§“YIDAT(Ïc` üÿÿ/f``XÏÀÀ🠆™P…ÿñj€*|†¦S±k```è" ® ªŸ¬Pb``h ÊIX< ÓøJÿ!6X×£i$3âH–¥‹ŒCÄIEND®B`‚routino-3.0/web/www/routino/icons/marker-88-red.png 644 233 144 2072 12573351601 15436 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“ïIDATHÇ••OhIÆ¿ª®š sœ@V˜– Ù‹‰Ñƒ0Í$ë "ˆs4›\ö §V2‡½nî‚s™Ë@hªúÑõ«÷^Õ÷è™’N§/k­_ €ÈŽì×Z¿L§Ó—À®“ HØÑ`|§µ®„a8G’ÃÃÃbjj ZkDQ)%‚ Àúú:vvv(„J©z‹þîãtw8å8Ž€¹\.¨Õj¦Ýn3Š"ö[El·Û¬Õj&—Ëh×J2N"vÇi`¡PðIÒà Ž<Æ’d£Ñ`¡Pð-¸ À±RB)u‹Å¢ŸÀüƒF¾OÙ­1Œ|Ÿþþ~^,}TJÝ—R©Tê*º®k<Ï#IÈ9~,$± H’žçÑu]€©Tê*”R/°Z­’ |?^ñú5¹¼L>yBîíõHýþN‡A’$«Õª±Ñ¾€(›ÍFÛÛÛqP$Y¯“yìX<^¼<8쟞fÔé$·?}b6›ì•ƒ)•J$Ép?^|å yî\<õ*<NÞ¸Až9sØÿø1C›D©T"£H­5`o6`v¸y¸v øð8¸p!ž?|ØóçóÀôtW=–#%€¨Õj¡Óé@)ƒß¿¿j·Ý]Àóây³yÔÿåKWA[[[AJé0÷–—ãýü™Ôš¬Tz‡39I^¿Nž8AÞ¹ÓóŸ>Ípv–$ùçÚDB_ !~ —––B¯Ù„:~ÑÈðæM¼ý»w@«œ= ŒŒoßvýüøÎØöü|û¶ ¤”÷Éd µþ ‹33I†‘J‘Bć‘Ï“_¿’OŸ’ŽÓõ›|žÜÙáO·n«ª¿d’ç´ÖM,/.’ô re…\[#ûŰ¹I®¬0xöŒ$ùûêjd{Bˆñ¨@qIJIa}u5®¯½ØƒŠJäÙÚÜäI×M´_îç€B@)µ€']·×T|ÿˆöUÝÜÜ\`{k}ttŽãt;TŒWJŽCk]·Í%®oí€Þ+•бÀV·;õµ= 8\­µ€år9®¯,I{ccƒ™LÆ ”òÇÁ´íh}ëõCîîîrbb"°Íã®4¾a‡ê뺮Ÿ´D’,—ËIÚ2 ý¿¥·ÁúÎØû[¯× ÀH))„¸d?w¾ ¬¯RÊÀùùùhrr2I»lÓVÿx¨¾~B@h#ücll J)ùÝúÚñÇq(¥lø~ ›#öOl1èGjIEND®B`‚routino-3.0/web/www/routino/icons/marker-44-red.png 644 233 144 2002 12573351600 15416 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“·IDATHÇ•U¿kI}3;#9[ÄD*®Ð“øHaaȰÂaˆ!„„kâ8Å•wVqÿDàܨQÌ vT¤Iw‹4ÁIÀUI8ŸLÆ–²»3õÇï,Ã|ì¼yßÛïû8ƒœšš’Ïç—´Öo€u+‡÷Zë·ù|~ Ü9™ ·z €´ÖI’< Éb±(Â0„ÖÖZH)Ç1vvvpxxH!„PJ5ã8^ð×Ïé W=Ïk`©TІéõz´ÖrÖZöz=6 S*•btç®fgŠÏóö°R©D­V‹$iŒaÇ1†$ÙjµX©T"G¼ Hi¥„RêV«Õ(#‹¢(U™$ä9j£Á€&IH’Õj5@¥Ô3)%Ëå–0Ón·I’qÓIå¹pñØ‘¶ÛmA`0—Ë-C)õëõº9—ðÕ+ÒÙAk'âîmÖëuãÔ¾[(l·Û=MN·¶H€ÜÞN÷ƒÁDܺ˺Ý. …‚`%†a(ŠÅ"Œ1Öž¼{¬¯»Âs•—ÏOÄE(‹ÃP  µÖf„GGÀ½{Àò2àûÀñqJòíÛhüäÃp~LNO“ gñkט¼|I’üóõk°BˆÈ“R&$—vww“»÷ïË¢ïÃ~ú‘σðù3på †Àô4@Q|ù^¾ yû6N®_ÇÏw»]éyÞ&|߇ÖzËL’IVìGG©¢çÏÓ}Ä«Š_>4®«Þð3KZë}¬Õj†$£Á€ì÷ÓrúøñŒ4IÈ~ŸñÓ§äׯÜ~ñÂ:Â!Ä|F¨œÙ7¥”4›ÍÑΚh¨´:gff²Þ¯ ó€B@)µ€3Aµ\Ëšïß'zßXKZË++±›­ÍÙÙYxž'GjL)%çç硵nŽø›u—C¦~ccÃ8ÂÎét{ Zëöˆ¿îeiïííÑ÷}€RÊ•ñ´Çq¡¿ÇÇÇ,—˱¿¹Â׸#þAe#‘$kµZ–ömmmø·ôï÷wqq1&Éf³IFJI!ÄM÷ºw!ḿJ©6®®®Ú………,íšK[ýWÂü$„ €Ä)ücnnJ)ù Oýu믞çQJÙðãX6øFÛM¼0LÁcIEND®B`‚routino-3.0/web/www/routino/icons/limit-20.0.png 644 233 144 1464 12573351605 14653 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“éIDAT8Ë­”ÏK[YÇ¿ïÍ4 ¯±Únœ…"t' ‚B•ˆUa7J[wnÓî]vþƒ\¸ÈB\̪P,ØÒ•û2КéBL[°jT:P›æ½wïgù1q–^¸pÎ÷Þsîóý! I¸®‹ä"‰XìG¤"Žó–ž¸qÃÐÓŽó©ØZ’ÛŠj'ŠÅ$‡û÷cHñ¼ù<<{f9>†³38>núù‹1M ˆµö µµóyð¼H…”¶É$@ðïçÏ,..’ËåØÙÙaii‰ÝÝÝ&ˆ©?V(øëÓ'€À&“ ¥Hd³üý훉x###Äb1VWW¦¯¯žžNOOoÆb1Fãq¼{Ò†«{÷ú5:ªâׯî¯_kmmMZXXP4Õææ¦"‘ˆVVVÔ¹¹9]^^ê·‡%ÉåÉéþý~÷—–ìù¹&Ÿ=Óøø¸z{{588¨©©)U«UIR$ÑÙÙ™$)“ÉhyyYñx\ëëëÚ=<Ô¯‘ˆ¬„k}ßqC!ý³½­±±1MOO+•J©³³SÇÇÇÚßß×ÞÞžº»»U©T$IÊår*‹ÚÚÚ’Gã¨*mðñ#¾oZ\—¡¡!ÚÚÚÈf³ÌÌ̇™ŸŸ§\.ÓßßÏÉÉ ™L†ÄÓ§µœ½} Ò†Ò¼zÅ'pxxH¥RÁZK©Tƒ1†R©ÔäÝÅÅÿ}ÿðòe­š ž‘Ï×xS/ýu\ç\Sj¶[~td³`̤Ýä½l¢ê&Êd ’¡^Ï m¿X]…ïß=77p77±¿º Að i;‰7‰^"•²¤Óbdd©Éü<\]9 Â{Çk‹ýˆ«+ÇüŸÌ~eZ¥Ô:æ}ÿf©„á­‘5nŠ–––B·[ëÓÓÓð<¯¿¡b¼R²P(@k]wË%Öwd¡„î%ÛÛÛÆÛýí4°ö0âðµÖ-¬T*±¾.²$íF£ÁL&cPJùëhÚ£v[ßz}(««+ÎÎΆnyü!„ؾ¾ïÉJ$ÉJ¥’¤ÝY]]ü,ý»ê»àú·^¯Ç CJ !î¹ëÞ£ú*¥Z¸¼¼lçææ’´+.mõ_CúøEA‘‹ð`ffJ)ù}}ݹáy¥”m?dsËþΉ™U~ÙHIEND®B`‚routino-3.0/web/www/routino/icons/limit-34.5.png 644 233 144 1500 12573351606 14655 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“õIDAT8Ë­”ÏK[YÇ¿ïu0oBÛ¤ºHÈF0P\H7B±C¡ÈÐÍD%©¤`\èÒ…ÿÀ8.Û½+] tJé²›U™ "H‰ ¬YEÈ%f*æå½{?³0±¶ÌìÒߟ&==®H$ÄädéKK>` °ö‹vïÀ>KK }`r2J"ÑiSzB6‹vàû˜vû¼c a~U`àûí6´ÉfAzÒÙM¢ÑOvoïìGc:ÙsýO9ó³ìíA4ú éæ•_¤òù1gvÖüµ»ëþöô©<ÏS*•’ã8*—ËÚÝÝÕÀÀ€$) ýùö­JÅ¢óÃýû&R­~Ï»wWd¤"¯_³_¯›ÞXŒééiR©[[[¤ÓiÆÇÇÏ :<<$™L255ÅÌÇüÝj^¼ÀHÅïtíÚ-ݽ«°Ñp]YQ2•Òþþ¾Â0Ôòò²Z­–úúúÔ•íím5›Mú9“Q2q¹}[n,vKܸa8>àŸf“‰‰ FFFX\\$N333ÃÐÐår€ æææX__'™HðÇ›7àû„ׯ7l·]½ªß_¾Ôwî¨P(Èó<•J%iggG*•J:==U¥RÑàà òù¼’É¤ŽŽŽ$k…1ެTäùsš`~ºwx³³—€# ! Á¹ßãjpÉì,HûLLôö¶ž)åxõ ÍðòÛl¶“1Æ`íß b 6 1Ð$“)w…Ù‚à»;8ˆnl9:ç0Æàœã_qÎጉì ¾#=RÞe³fw—\.ÇææfÛqmm£££v«,K¥Ÿ>~0.›)/+m±²ÂçZÍöÄãLMM‘J¥X__guu•ŽŽ–––#¼°Ö244Äó§O¬)@Úº¥;wjtT¦^÷ß¼}«¾TJ‡‡‡:??—ïûJ&“rÎIR{ž››S£ÑнdR’|ž<‘âñ‡âî]Ë·oü8=err’666c~~¾ýìÅÅEúúú˜žžæþà _¾~…“lèñ£G*‹êîîÖöö¶$É#Ïó$I•JE€FFF´³³£r¹¬½½=É󄵞œ´Åò2§`_<{F"‘ “ÉP«Õ§P(0<;8/%#­4³;óìÎÎ3#$! ç’Cåò Ò&Að‰ xóÆ31Að i³8’+â„@år€P¯—‘>E¿Y^†¯_«+øù®®úöò2DÑo¤Ï…PÄK„¡clLLM½Eê$pyé3ÏséÛ9——ž$©ÃÔÔ[ÆÆD:19)"¤ï¬®¤€‘ee`öw öÀ€”ÕU¾³°19Y¤)}aq Gž“§)Þlø ï=yžõìé ëõúþ‹‹ }üÙ{¢èÇÇ–§)ö È̆öˆžçÇÇE¿Þ i“•€¼¸½½=NOO‡€N‡ÝÝ]ŽŽŽØØØàììŒ"ßœ•6…tÀÖ€Ç{¶·· Ãf³ @š¦ÌÌÌ0??Oš¦Ôj5jµÕj•›?¼5› 8ЧO’ä *•ŠIÒúúººÝ®¦§§µ³³£0 Õn·DZþkµúq?Jã㜜Ca(I23ÕëuU«U•J%µZ-5›MÍÍÍéððPûûûªT*’¤8ŽÕív%I”J’s8™êõô\ÌLÞ{9ç4;;«v»­““ÝßßëææFçç纸¸PõÝ;IRç’Y0ògÙÓI’Ðh4†h4$IÀÒÒq³¶¶}ºx¶¶@:©fAHîîîx||òêááÛÛÛ¡}}}÷~@à‘jŽð¬¸íE1³>à³ìEžý¯ìÀ"gÙ Å:àU{óU§Æ«Î³Wœ´å‹—?¼eâ‹IEND®B`‚routino-3.0/web/www/routino/icons/limit-170.png 644 233 144 1411 12573351603 14571 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“¾IDAT8Ë­”OK[iÆ÷Æ\373 šî„΢–è¢n†ÚqçJ šu¡ ]‹~€Y¶ûlIÁE7ý¡+Rˆ°; (X;1Zc̽ïyf‘Ä‘©K^ÎyÏyÞ?<ÏA€ù¾/ð(•úMP–çÕ”ÍJOž8e³’çÕåþ>¿ß‡¥RžÀS©”¼SþÐÊŠôñ£éäDúþ]:9éÅ++Rþ¼ë×{ý~PøFããÏ_µ° ;I±Ìœî[/Žu|ì´° ÁW?Óð0 åóhq1Ôµ¾.I·’LQ$E‘döŸr’IºÕúºu-.†ÊçûÏ„÷Z^–¤®âXñí­ÌLf¦(Šîü.×éȺÝ^ýò²ïöBaØÒá¡$Ùè!€õ c™d:<”°%x‘øþâíÛßyóÆ)Š|?¨V«$“I®®®ØÜܤ^¯spp@.—£Ùl²µµEþéS~Íf=årÎk4~ao/`O>H’“sÚÞÞV"‘ÐÎÎŽjµšfff477§d2©J¥¢ÙÙYMNNjbbBÿ|û&IÎ* ö|FF^òú5€ožç‘Ïç¹¼¼djjŠÝÝ]ŠÅ"kkk ÑétØßß'“Éð÷§O½¾W¯`dä¥ï‹ ÀÌ(•J ®¯¯8==¥\.³±±A·Û%NÉdh·Û(™ß—™G·Ë}33œsT*ÆÆÆ%—ËqvvF£Ñàè舉çÏðâÌ<ŸVë Õ*€a@:&èß¶Z­²´´Àüü<ÓÓÓ ŠÅ"ô¾ÇŸ?C«õAY««’÷ ©‹‹ ÝÜÜH’šÍ¦Úíö=œs:??—sn@àX««”â™âøA~ Vçz sQôÏT€Ý|ˆÀEêú?<ª6uj<ê<{ÄIû/[¨H¥ýàIEND®B`‚routino-3.0/web/www/routino/icons/limit-22.9.png 644 233 144 1530 12573351605 14660 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ IDAT8Ë­”?H\Y‡ó‚:¾| ™L266@:&™L2>>NPÎ"¹\Ž®®.R©u55ü¹¸aHÐÐ`d<ÏòíúD}4ÊÔÔÆ666p]—ééiNOO9??'ŸÏ³³³Ãèè(333ÄoÝbm}NN=Ϫ$ù¼Ï¯^™Ç¡§§‡D"A*•¢¥¥…îînš››™ŸŸg``€ÝÝ]iooç×2—†×¯Aò…4˳güáÁÞ{{{ Ž9<<$—Ë‘Ïç9;;ãèèk-ìïïcË<†<} Ò윑ɔÉþÐÍZ‹©pfÀRÅÙ• °P²A€ l ÕÀ†ØrBJ<|XU×Z›×Ú5®µŸ]c§ýèI”‹Ï¤ ]IEND®B`‚routino-3.0/web/www/routino/icons/limit-13.3.png 644 233 144 1446 12573351604 14657 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÛIDAT8Ë­”ÍK›YÆŸ÷M0™×Ú¤ F$ÒY7î„"ÅEÀ•ˆµY¶Ð…þþ£³l÷âNf¡àÚU‹+Sh±!ÁU‚HýÀªMîÇoI´:[\¸ç¹÷9÷žÃsŽ„$Â0D ‘D2ù'Ò Að•t2G: Aði¥s.¤°ÃêJ&¤€×¯“HŸÌÏÃÆ†çð~ü€Ãö??Qôé}ç~ÐáKôô„$"ŸŠTgz X¼wünmßÒh8¦§Aª“Ï?%‘==¡ÈfÅÌL„ôÅE€&à1ŒïoW4Y\é;33Ùl'Méss-ÛlâÚœscpîî]«…i6qÐâÕ+>tk6FS¯cÁûN ïý½ ý]¼ý€÷µDÑ9ÒXì/éo½{÷‚·o](…ÿîìÈZ«L&£ýý}•Ëe% år9yªÕª>–ËJÄãA®Pp4{{1!í±¾àþY_'³¹¹ÉÉÉ ©TŠR©Äðð0;;;Ôj52™ ¥R‰\6ËçjÕ±µ…•öâzüø¹^¾”— ÓÀÀ€¼÷²ÖjiiI###:88P³Ù”$Ykµ¼¼¬¡¡!Ôëjœ„šœ”=z.ž{¦k¡P ÖÓc(~lm5ÈH[d2üS*™–æfR©]]]ÌÏÏ“H$˜œœ$“ÍfÈf³„ÃaèŒÇùëÃÃË—øÒ–£pøŽ’IùŸ?;¿/,hbbBmmm*—Ër]WCCCjoo×éé©$iwwWÓÓÓZ__×µpX¹×¯ݽ+ššîˆë× ?ðïñ1£££ôôô033C?Éd’D"Áöööyþ666èííå·û÷1Ÿ>a£Q#¯©ÉR.“~þœŸoß ™L"‰¹¹9º»»Y^^¦Z­’Ífq]—ÅÅEŽŽðö÷!±N×/9­¬è×ñqûãjnnV<׿æ¦VWWÕÚÚª¾¾> jxxXkkk’¤L&£x{»V^½²zóFþñqNHKŽ•JŒss¸¶–îì¨þTƒiªiª!üÒ‘OƒúÓ… ×ÖçæÊkB×õuÕ¡Y¦Yfžç¦ijžÅåyn:v‰Q‡®¯+tGoöÁ$xyYœ˜e_Kžç†ðËt”,xy©I2> ì¹½­š™¦/Av»]ÏÎÎT½ºº²Ûíz~~^>_]9s{[aዽ^QÀp¨j¿ßwffÆ †ÇÇǶÛmÛí¶ÍfÓ›››¢âŸÛë)|yÇÔÔGZ-€˜8 Ë2vww©×ë<==qttD¿ßgyy™¥¥%jµÑØX×jÁÔÔǘ8–J€¸L¶°°ÀÖÖ§§§„ R86&„ˆá€<Ëèõz4›M™œœäúúšz½N§Ó¡^¯sww€Z$!„(f0øÊÉ @ˆ£€••fgg©V«ÌÏÏÓëõ¨Õj$IÂââ"›››ŒøÀÉ _ÿøÍ‘¤iêÃÃié˲ÌÇÇG³‚#пùšg%§~'ëH_8W,þʳ¿vÀ —^µfiÿ³Þ´7ßtj¼é<{ÃIû?èa»,$ûIEND®B`‚routino-3.0/web/www/routino/icons/limit-23.1.png 644 233 144 1457 12573351605 14661 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“äIDAT8Ë­”ÍK\YÅÏ{Ét;O%¶-*(Œd¡õ±]ŠÜ™lLvCð˜eg/ÉJÒ2ƒ‘þ.‚ AQC‚†Nv øÑd|}?~³ègOL¶^(¸U·NQ·8§„$$†!Rˆ$šš~Cš'ÞÓÖí펶6‚÷HóÉ»Â'tY¨©)@ Èç› DQ•ÙYxýÚst_¿ÂÑQÝŸ…(ª"’ü ÁK¤R!é´èí½ô‰ñq(—`ñÞñý©û–rÙ1>Ò'z{o“N‹T*Ù¬˜˜ˆ˜›ˆ1` xÿ¿]ÆÀ1ss 01‘Í&ß”žñàj&ŽqµÎ9Œ18wµA¬ÅƒƒSS =»œÙ]¢èÔ—Jxð$À xï¿«eñÖÖ;,• ŠN‘îÞøSú‹G~>tööÂ^½REêììÔþþ¾ŠÅ¢Òé´ºººH’Â0ÔúƆ\™;wåò¯ÁÎÎ Yi‡ÕU¶>v­QÄÈÈ,//ÓÓÓÃÔÔÝÝÝlnn6:\ZZ"•Jñ÷˗΋ í„ji¹§ÑQ•?~ ÿxúTkkkjiiÑöö¶ …‚òù¼²Ù¬â8–$Yk:::äƒ@’BÝ¿/ݺuOd2ÎU*l¬¯388ÈÌÌ Þ{ªÕ*“““ôõõ±»» @Çär9^<€ùò2zc‚0•ÒÞÁr¹œ¦§§µ°° ÅÅE keeEÍÍÍÚÚÚÒÙÙ™¬µ’$ï½”ÌPÆHÞ¡«V÷ôö­6ß½ó¶VÓêêªÚÛÛ¨¿¿_­­­ÒØØ˜FGGu~~.IŠ¢H¿Ü¼)I>xóF:=ÝÒ3:úß©”" ¤O¬­´GCƒs7y}h±¶Ò'Â0`` ûMé ¥@›$!iµ°ÎÇñtÎ' q³IÜnã M©Ò›ë™=!¾q| à’V ×%úcXÛyáñ1Á7¤'½’^éåËš˜°ÄqOO*¥Z­¦‘‘åóyíìì¨ÑhÈ÷}ÍĮ̀V«©^¯Ë÷}ý]*yMLX^¼xà½}ûJHûllX¬ekk‹ÞÞ^¶··‰ã˜þþ~Â0dqq‘ÃÃC†‡‡ Ãùùyþ­×¬{÷¤}£L橞=“$ã@žç)—Ë©¯¯O{{{º¼¼”µV³³³Š¢Hggg’¤B¡ ÁG„d¼çÏ¥Læ©‘1(•’$9çT.—555¥‹‹ år9ÍÍÍ©X,jeeE»»»ªV«šžžÖêêªþùðAž$ÛÓ#ƒ‘sžÚmÝ@ÆEQ¤|>¯J¥¢¡¡!h||\•JEƒƒƒ:ýò¥ÓÐnKÎywf7› 6779==ellŒL&Ãòò2GGGLNN’ÍfYXX iµ:3ÛØi_HëT«IWœŸŸsuu@³Ù¤Ñh`;R¸‹;õ Õ*Hë?éŒ$¹å÷CsÖZ¬µ7¸#Ú;:û¥Üo¯}änlõ?Ü«7ïukÜë>»ÇMûXUcB'z°IEND®B`‚routino-3.0/web/www/routino/icons/limit-37.5.png 644 233 144 1472 12573351606 14670 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ïIDAT8Ë­”ÏK›iÇ¿ovÕðÒ˜T„ät¡½ySº =ˆ'‰¾„mÁ ôÒ‹„‡ö u©7vKEdY ö¤W¶b—z%5H]‘¼?žç³‡Dë.잘ÃÌ3ó}f†ïŒ„$b±R IÄã?!-á8H¥ ­ÍJã|@Zj¼ )ÖȺŠÇ$‡‡ãHÏpÝ ff P°”ËP­B¹\·gfÀu/ž5âF¾DssŒ–‘Ív"}fxJ%DXk¸)u;¢T2 ƒô™l¶“–ÑÜé´Èç]¤"ss>` CC°ö»^ùÀ>ss Éç]ÒéF›Òs<Aèû˜ ÀZK†×j­½.0ô} „ÏéùÕÌr¸î7»¿_ÿјFG–ÿ•zœe\÷RîGIOyô¨Õ¹wÏ|úøñ‡ßß½ÓÐВɤÖÖÖ”H$ÔÔÔ¤þþ~uvv*mllèèèHͱ˜3þä‰ILL´òòåSi—ÕUþ¬VM[2‰çytuu1??Ïàà 8ŽÃææ&år™L&ÃÈÈ¿ŒsX«Þ¼ÁH»2‰„¥ZåÓ—/üúâ…BÞÞ^¶¶¶X\\dzzúº»õõu\×%ŸÏóÛÊJ}$_¿B2iÅÝ»†“þ:?gtt”l6ËÞÞtwwS,¯Á¶··™ššbyy™L:Íï߃ïµ¶šXŽîÜÑÊÛ·úùþ} ÅãqhuuUíííÊårªÕj:==U©TRGG‡&''•Édt||,Y+Œqd¥]^¿æÌàƒ¤R)òù<žç±°°Àáá!}}}ìììÐÓÓC*™dâñc"0¼z…•v…´Äì,@ÖjT*Â:19;;ãòò²ÁÃIc¾ïS©T0A1; ÒÒ?xf<3Æ\óìß|³ÖÖ}Æ`ÀÚ<û¾cc Cˆ¢ÿ°Q„­W06vcnu7oõjÜê=»ÅKû7Gœ©ˆZ„IEND®B`‚routino-3.0/web/www/routino/icons/marker-42-grey.png 644 233 144 2616 12573351600 15623 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“CIDATHÇ}•MhTYÇÿç~ø^^e‘š‚4¥:…1ž’5Î,Ä€ öª†Î®³±3¸˜†FÕM-f3Š+7C6¥¨ 5*bj2CA  JJc ?™)MÔʪ†÷qïéEW½Nìž9páÞ»øßóÿsï¥R©„N¥J¥’-—ËŸ0óŸ£(úy €ðC°ã8¤µ~HD_”J¥Ùr¹,â8 Ô•Ìl˜ù#­õù0 ?¢ˆÓé4e³Y!Ek-VVVÐl6YkM;vì¨DQô{"zCD€Q3ƒJ©j«ÕÌd2ñ‰'„ïûä8>Œ °´´ÄÕjÕ¼{÷îsÏó~aŒ9ÁÌ/‰HÈcÇŽ1€]J©†a8¸gÏžèÔ©S:—Ë‘”Ìü£¡”ÂÀÀŒŒˆµµµèíÛ·­õ¯¬µ×™ù?"•JAkýu»Ýþ8—ËEÅbQ÷õõÁZ›dFDB@"3#Žcôõõ¡X,ê\.µÛíµÖ_§R)ˆ0 ? Ãp2“ÉØ‰‰ Ìœpì u÷»(¥ÀÌ€‰‰ Édl†“a~*˜ù«(Š0>>Žt: k-„‰Àòò2šÍf’ñÚÚ>|ˆgÏž™a­E:Æøø8¢(3%â8K§Ó|àÀÑÍÌZ "£GpñâE¼|ùP¯×qáÂÜ»wÓÓÓ¨T*‰#ß÷E:æ8ŽÇDœÍf©§§ÖÚÄúëׯqóæMt˜fffÏçqîÜ9œ={õzOŸ>xž‡l6KA°ø>9±­(A R©`dd©T ƆïûH)áºî¶îÌ…’RÚÍÍME”R€[·n¡¿¿…B‹‹‹É~¡P€µóóó¸ÿ>òù<†‡‡þ­V B«\×5ÏŸ?G½^‡F£ÑÀÂÂQ©T@D˜…çyèïïÇôô4¢(B¡PÀèèhRØ/^`yy™]×5À—J)Q­VãÍÍMôööâСCèííEÇR‚ˆ@D¸zõ*˜gΜA>ŸG†IÏÞ¾}ÛÐ÷ñWºtéÞ¼yó·V«õë½{÷ÆÅbQuí„aˆ©©)LNNbÿþý˜ššJ8cÐn·qúôi¼zõÊÎÍ͉T*õ(Š¢_ÊŽ…o\×h4?3ÆØ¡¡!ŠãD„;wb÷îÝp]¾}û0<<Œ#GŽàýû÷<;;+zzzþËÌ'‰èßJ¡üËZ{Úó¼¿×j5Þµk|߇µLªëûþ¶›Õn·qçÎXJ©…SÖÚo(  ‰hNñ"’333ÑÆÆFb³{­µÉ€7nÄëëëÚqœË£££ ÄÝ&‹ˆH=zô¼ã8—›Í¦¾~ýzüáÝïö¤”óóóöÁƒ*•J­†aø§………äpyüøñ®%ZYYacÌ7®ë~Öh42]¾Æ˜ä=B`}}W®\a­5ø Í‘`@”ËåäQB(!ε¶èyjµ/--AJ™¼Q¡R©Äa )åy"º @w0¢\.Ct'ø¿| Z­ÚÕÕUå8ηAL™e¿ÜÙÑ/_¢wwúó§ÞÝ•ûͲ_§¿2°Ó4q|ëõwÂ×Ö´Ó jaŒÁßQî ;àÚšÂëõwŽcš&8;‹ëë™ðÝý}Õ'5šçšçãó3<Ó¨>¹¿¯ðÝõõÌÙÙAšðÙÍMÕ¾E¡EaÁ<Ï á9¸¢( 1jC§}77>ÿÙ{³¬ëÕUycÆ12+×EQŒÎžKþÕ•fYWxpäî®jaž ...<88ðòòrdßjµ¼¾¾]2ˆ®pwWá᫆jOOªž999éÊÊŠõzÝv»m³Ù´Z­Ú(¹æy>Œ.Øh(|M˜šúÀò2”š Óé°··ÇÉÉ œŸŸ“e333Ä¡ä',/ÃÔÔ‡7$‰¤i Z­cdccƒ¹¹9YZZb{{›4MYXX ×ëñi IbBŒú}b$IB»Ýfuu•­­-QFïè÷!ÆJB·ûV Æ8==¥( Ž™ŸŸ§ÙlP«Õ{vR¦iµ Ûýö¢šª½^Ïûû{onn¼½½µ×ë©úððàããã³<þPÍÿꬬÐßñ?:ûc Åú»PGëçe¼jo¾êÔxÕyöŠ“ö_9ËeN,†¦IEND®B`‚routino-3.0/web/www/routino/icons/limit-138.png 644 233 144 1434 12573351602 14601 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÑIDAT8Ë­”¿K[QÇ?ï)/éûB~Š”v±àR‹:9¸ˆƒ8:èà? tlqur²)8T‹…‚"‚;Z#JìË»ï~;$©ÒvôÀårî9çË9—ï÷ @€\׸”L>¬Ëq¾*•’ÒéX©”ä8_ë8·S‡è%“ŽÀQ¹œ¼•ïÿÔâ¢ôñ£Õù¹T¯KççmqQòýŸ‚·|§SòÆ\} ñ<üj =¿ø³.\÷Ä X°Ô 1Xk/uh»µŒÁ‚µ…¸î R×ߤßyòä—ÀãÇf7Ÿw^¼z¥p8¬x<®½½=e2™†o­•ã8ÚÝÝÕ‹—/ í÷îŠÅp`{û†jÒ6++üõ勉º.ÃÃÃtvv’Ífatt”ÁÁAö÷÷ØÚÚ"’L&éH$x÷õ«áÍjÒ¶£Hä¾’I?}r¦Ÿ>Õúúºâñ¸T*•ÔÚÚª¡¡!µµµI’ŠÅ¢¦§§µ¶¶¦H4ªüƆ£ÄÍ›÷ÅíÛÆ”ËlnlÐÕÕÅÌÌ ™L†îînÒé4‰D‚l6Ûø¿ÍÍMzzzøõÑ# À÷ïØXÌÈD"–?x÷ááPˆ¹¹9––– ··—t:çyär9\×e~~žÓ“|€ƒ¸uË:¦RÉ+—ÓŸ;;¶æyZYYQKK‹šššÔ××§`0¨þþ~¥R)¥R)­®®J’–——•¸sG¼}kµ³£Úéi^H‹LMñ7ÔÊ¥¥ºaŒáèè¨Éññ1•J…r¹L©TâàÛ7þSSXi±Á…Â9Ùuάµ XÿË\=xž‰³+ °àYßÇžKæ ¬WÀ­çØÿ)àZµy­SãZçÙ5NÚFÄŠ¸Æ>P=IEND®B`‚routino-3.0/web/www/routino/icons/limit-37.6.png 644 233 144 1515 12573351606 14667 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”OK[iÆŸ{K5‰išHD†: 1‹‚ %íTºPÜHðÚ ©"úüøpÑ.ܹp1Ë”‚ÉZnºÏÂ3XQ†L’j¬Ž¨¹÷¾ïo‰¶Sfv8‹óž?ï9‡ç22•ŠB¬5|+M;¤R1ŒŒ€ô‘Læ>íí¢­ÍÝÝ"Ÿ!•™›h– € k¿êÕX ÁÜHeòùÝÝ­1¥—xü ÑÀø>ÖZ‚ ¸Vkíuƒ& øxH/¯vÖK,vbwvš?ÓšÈò_b­múšqÖîì@,v‚Ô{ëižÉÉœóü¹ùãÃwåõk% ù¾¯•••Ëemoo++•JÉqíííé·W¯½}ÛùáÁC¥uJ¥[2R‰b‘Ý£#Óy÷.žçÑÓÓà à8ëëëÔj5r¹ÃÃÃ<~ø?ON kk©äêÎ>=y¢ðË÷×ùy«££CýýýÚØØçyšššÒÐÐ$issS»»»J§Óúy`@éhÔU.''‘è©”áógþ>=ett”L&ÃÖÖgggd³YÊåòõÎVWWÉf³,//óã½{l¾{——„‰„qCßwë÷µ5=~ôH…BA‘HDûûû*‹J§ÓêííÕÅÅ…êõº¢Ñ¨âñ¸¦§§ÕÕÕ¥¿>}’@ãÈJ%Þ¾åÌàÓ§$“Iòù<žç±¸¸@µZ¥¯¯z½ÎÄÄÑh”ɉ 0¼yƒ•JBZbv ./©V«M`r||Ìùùy[Æpxxˆµ–0 ©Õj„@Èì,HKÿ™iáÌs³ïñf­ÅÆ`¾ÃÙ× ðm@þo!ÂÛìÞglì› ¸ÑÛ¼QÖ¸Q>»A¦ýHN…,£€‚IEND®B`‚routino-3.0/web/www/routino/icons/limit-4.png 644 233 144 1066 12573351601 14431 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ëIDAT8Ë­”=JkQ…¿{›pƒ)ïÙXfA°:…d'¡}J±0cp "(˜FHa'"(hrÏù^‘D?ÏÆ·8û®½Ï:ûCB°Zý+ôͲ k5]Y‰ÖjšeBö!Ìüy j52wvªÂžEñh§£ÇÇÉÛ[½»ÓÛÛé¹ÓÑ¢xöfülææy°RÁFã0´ÝÖÑ(ª¥)Eßcz.¢í¶ÂÐFã• æyÀz·¶ áÊ^OõEMN&:™hJoßܦI}±×S¸rk«°^Ÿ=öÝÞV[–Z– ‚bŒ–ïmoœ±ÛÛ ûóœ­[^_Ooü(¥dJÉO˜ò’××ZÂ:BßnWµœ=aA‘êp8ôäää5ø+¦üÒnW¡pæ` ß«š;Å][[ssss&¨ü¨.:(œ–—›´Z˜#Ë2vwwy~~fuuõ•3ãZ-X^nB<ç=bŒrttÄÆÆ§§§ÜÜܰ´´´ Ï!)eŒÇ|…Íf“óósF£———¤”‰ã1¤”}›³i~§988°Ýn/ؾÊÙÕŒ1úôôäýýýçöø¢šÿí³oñMŸý8ŸúëÛ øÕÙüÕ­ñ«ûì7í?.k—ž˃ûIEND®B`‚routino-3.0/web/www/routino/icons/limit-38.1.png 644 233 144 1465 12573351606 14667 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“êIDAT8Ë­”ÏK›IÇ?ï¨Iöµ5®‰Ô€b¡X<õäa»z+B"âiíEÿÿY-^=y±¤ ´EzòhÙD‘@ ]ìÞr‚ÁF›Ì¼óÝC¢µíÕyžyžgžyø<È#0”H<¬(>¨½]êèˆÔÞ.ÁÁJãiø!®% ÐÔTBðLaøEssÒë×^ÒÙ™tpP—çæ¤0ü"xÖ°þ XÌ(G½½ý‚Ïš˜J¥H’“÷‘n¯ºìT*Eš˜à³z{û£XÌ LMN†‚OZX¤ª$/k%k%ï¿íkä%Uµ° Á'MN†Êdß„çÊåI5[­*ªÕ$IQÉZ«(ú>A9'g­"©¦|^‚ç×5{¤0,ûýýú‹ ÇxïoÅròÎÕí÷÷¥0, 5-Â’ž>ý=˜þýøÑ¬ Äc1zzz(‹ ÚÚÚÈd2HÀÃ?ïßU«Á¯F*•~ ööšˆ`OoÞ迳³¨#™T.—ÓÀÀ€Õ××§™™e³YíîîÞd¸¾¾®X,¦—kk’Ù/$Ø3Ü¿ÿ˜‘Üù¹ù{i‰ééiººº¸ºº" CÆÇÇéîî¦R©àœ#Òé4> ##L>6¦¹YxÏ@?ÍÎR(899ÁZK:fuu•ããc:;;ÄÔÔƒƒƒ\^^@K #ãjµ€{÷xùêår™ýÏŸb[*´&#Õøø?Ìðƒ,..’ÉdØÝÝ ›Í233ÓO¹\޹¹9^<{Æ—ëkÃæ&Fª èÞ½§zùRq³éüöö­e2ò}_qkuuU­VK###êíímù¾¯ÙÙYýôä‰F“IG¹œ÷ï?uœd­~ÌfõË›7򯯵VÕjU•JEÓÓÓÚÛÛÓññ±$) CŽŽjjjJ¿W*úóÓ'éáCY 'ÄR)ý±¹©ÏŸkkkK®ëêàà@¹\Nûûû:==U½^W†r]W©TJKKKÓéׯc²Rø Ìϯ^‘N§) AÀúú:ù|€ÉÉI®®®(‹$“I~-‰Àðþ=Vª iåe€8jµ8??'Š"¬µc¸¹¹¡ÙlbŒáòòk-qsqqAÜnÄ,/w~ó6ÎLgƘÿàë6ÎŒ1` æpÖa@¡Ú(‚!¾—¸_ ޱZ… ·p§Ü¼Ó­q§ûì7íß+¼–Û‘0²IEND®B`‚routino-3.0/web/www/routino/icons/limit-35.4.png 644 233 144 1476 12573351606 14671 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“óIDAT8Ë­”AH›YÇÿßW1ñ£ë"INŠ ‚⥞¶ÛÒ²ì¥ÕSZD½xïËzlO^¼¨‡m»P°Í%wÁ“—P­ØÅîv¡¨±[­ó½÷~{HŒ•eoÉ@©dƒs–葉J%K&ÒzzúˆDDk«/âq‘ÍHï™™8aaÎ]¬ó3pÀ33 ½'› ˆÇiJÏxô µðì [«†as9ç.~h 6 1Pcd¤gç5 ¾ºú‹Ö62rüŸ8çpÆÔíwv ¾" \ûUšãÉ“½ÇíŸ[[þï/_ª­­MÉdR+++Z]]Õææ¦úûû‰D䜓ïûúûãGm½}ëõÞ¾m)•Ú¼bñš¬TäÍþ:<´]±£££ôöö’ÏçI¥Rd2r¹{{{Í_YkI¥Rü|ÿ>€5/^€TlQ{û-Ý»'óå‹ÿÛÜœºãqU*­­­éääD€†‡‡•H$dŒQKK‹fggU­VõCw·$ùܽ+Åb·Ä–ÏŸ89>&›Í244Äüü<ÓÓÓ,..’H$( ,--‘H$ãf_ÿ|úGGØXÌú¦VótýºþXYÑOwî(ŸÏ«½½]…BAƒƒƒW2™Ôþþ¾Œ1rÎ)NkccC¥RIÛÛÛ’ç k=9©È«WƒýåÁ:::Èår¬¯¯300@,cbb‚ƒƒÒé4år€ååe2Ököü9HE!-05`Âj•r¹LX“jC·Ö✣R©4™;==å¨^ÃÔH —8³ Μscš¬»$u/qvÑ##5†P²çwAš{cÀÜ:àJ{óJ§Æ•γ+œ´ÿ,0vÍ‹ IEND®B`‚routino-3.0/web/www/routino/icons/limit-36.7.png 644 233 144 1512 12573351606 14664 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÿIDAT8Ë­”ÏK[YÇ¿ïY¢ ¶5’‚B†ÎÊâFI¥‹@³†ÐÆ}»‰kñÆe»VÜÉ`\µ7³é"¡”¶¨X£ˆPÁH´:­hÞ»÷3‹$V;[\¸çÞóãÞÃç! I¸®‹ä"‰¶¶ß‘fpœOtt@g§¡£çÒLã^HnÃO¨¨­ÍArkCzA(ô|^¿¶ìïCµ ûûu=Ÿ‡Pè;Ò‹†½Óð—\Z[E"qé ™ ìíÀÇZÃU©ë>{{†L¤/$÷hm€+b1‘͆֙œ¸,žžÖþ\Í3°À““ ­“͆ˆÅß”^òô)jÞŦVÀƒçyc®<ÎâŸãÕjxP³Ož€ô²Y³^B¡»¹YÏØp4Æ`­½äšÔí,›› õ¶ü)Mñüùγgfãóg÷ïBA@@ÝÝÝ*—Ëš››S0T<—$íììh~~^ëZûøÑiïï7áÓÓ ]]m‘‘Þóæ [Õªé¼{—±±1‰KKK¤ÓiÒé4###loo°²²ÂÐЩT GâŸÕUC±ˆ'½¿¥Û·ûõð¡üoßÜ¿¦¦Åttt¤b±¨r¹¬ÁÁA%“IÅb1IÒðð°J¥’¦§§õ["¡G¸öëWݺs§_„ÆÃCþ==%“É000ÀÄÄÉd’ÙÙYzzzX^^¾,W¥R¡¯¯õµµzù 6®_«9jo׫WÖâ⢂Á ¶¶¶F•ÏçÕÕÕ¥ÝÝ]U«UIR¡PP4Uïýû2’\ß—¬uÜ–?>èí[=ÎålW$¢p8¬x<®……E"ƒA%“IŽŽ*•J P©TR6›UC¬Þ½“NN>i†ñqß;?çàà¯&¾ïS©T.19<<ÄZËññ1gggàû>ãã Í\ãÌ483ÖbŒ¹„õWæl=Ð5Î~v@.P³ž×Ìø?X›{ëûͶª‘Ë]é€íÍ7:ÏnpÒþ9k™PYƒ8IEND®B`‚routino-3.0/web/www/routino/icons/marker-41-red.png 644 233 144 2020 12573351600 15413 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“ÅIDATHÇ••ÏkIÅ?U]5Ñ9äE¦CP÷” xwBbH0Ç×\< „Ìa¯»þ›K.Q¼HtþA‘ "xð"¸BNaÆÃàa%Bȯî©~{èîIf²‹»_hŠ*ª^½ï«÷ý6œ†½pá‚™÷ÞdŨ³sïýÇ‘‘‘y€âœ-L1F@.{ïW{½Þ]IªÕj¦Ñhà½'Ë2¬µ¤iÊû÷ïùþý»Œ1Æ9×JÓtøë Nÿ†«QuÕëõt}}=ìíí)Ë2,Ë´··§õõõP¯×S@Ź«eÆ%ã8Š¢/€¦§§“v»-I !(MÓs_A’Ôn·5==À_€8‡µçÜ3@sssI –$Iβד†ÙözJŽŠõ¹¹¹s*•Ê" 8ŽC§Ó‘$¥iª‚ªÎEýõr_§ÓQÇP¥RYÄ9÷ÐÚÚZøGÀW¯¤BŽþZ»-½}›'‰$imm-l?dcccÙÎÎNÿ!Ôëå‡76$ž?ÏçÒî®43#-,äû ;;;Ë€Ìj4¦V«BÀdD|ú++ù3fY>¾yðæž4†µZF£aYÀzïP ¸¿KK°¸Õ*œœä ·nÁö64°»{Z6޵@Öív9::Â9‡î߇©)xüáâÅüðè(\º”ÏKö€±¹5¿}ûa­M€ðôÉ“\øÏŸ%拏7¥;wrM¯]“^¾ 9iû”jµŠ÷~£0*I½Òìûû9Ó/òyÁJ Òì¬Jß»w/Uõ'P-ï®{ï¿j6›A’’ãcéè(·Óöö O77•¾~-Iz¾±‘€‡Æ˜É~2…5n[kôZ­Ö`e+ª¼Ûíj||¼¬ýæY<oŒÁ9·h<Ž“vQ²áää\í‡â²»ËËiÑ[[DQd‡´wvrrï}k@ß²ºŠ(Ù¯®®†°ÛïNgÚC ±÷¾3 oQßeÚ[[[ªV«µöçá´‡ã‡úhjj*-šÇï&·›ç1 oÇIÙ%©Ùl–ioÕÀéoéßcXß™™™T’Z­–€`­•1æv±=ú!ాι åååìÆeÚÍ"m÷_ôf1zÃ?®_¿ŽsÎþ_À¾¾ÅøKE²ÖvŸ†²9¤I·õ\÷IEND®B`‚routino-3.0/web/www/routino/icons/limit-15.3.png 644 233 144 1457 12573351604 14663 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“äIDAT8Ë­”ÏK[YÇ¿ï%˜ø”6‰BL6;`qa¡ n©uoPkÝ)v¡€ÿÀà,Û½;VE³påR:e.b±…ì‚BhQR1É{÷~f‘Äv~íÁõ5æþ}ãÊZGí¶zÈu]U«UŽŽjuuU©TJççç’¤MOO«P(hÀóT<9‘B!Ù p\]]}лw’d%ip`@€&&&´»»«x<®ÉÉIe³YMMMiffFétZ±XLãj9—³:8Pèúúƒ¶X_0†ËËKnnnh6›Ôj5Œ1Xk©×ëXk ‚€Z­†ßlvpëë m}×ÙÙYGÙAp«§ž¦zd½¾1ŒÁüCgÿr€õ}þ‹ðo‚ ºân³´ôƒîÔ›wº5îtŸÝá¦ý já¶tÔ IEND®B`‚routino-3.0/web/www/routino/icons/marker-89-red.png 644 233 144 2111 12573351601 15431 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“þIDATHÇ••ÏkIÇ¿U]5IÔ09ìa:ÍdBðæÁ$dDaŽº „½©ädæ°²ÿ€Š‡K`’=(› ¢‚ðƒ…=8pºa"Ì!¿º»ú»‡ªžL&»¸û ©¼þô{ߪ÷84ÙÝÝ- ««ë’Öú ˆÝÈöµÖúMWW×%pïÉ$Üè0¾ÓZ—¢(š ɾ¾>1:: ­5â8†”abeeÛÛÛB¥T% õqZ_8íy^ ³ÙlX.—M³ÙdÇl·8ŽÙl6Y.—M6› нw:É8‰Ø÷Μ±>Ù,ÀÚZ«zG*q½^—{{{èI¥@âãGëÕl»»À—/@Opçp÷.°¼ ¼ïÊG´*hkk bH)æ÷ùy{¢_¿’Z“¥Òááœ=KNMÙù½{äÕ«äýûdw7£/¬KK !xž÷ öû~XuWÊd³äÍ›òáyâùàyýúáþÇŒ{{Éf“;Êå"W¿!NCkýæÇÇC’Œž=#•"…°‡tþ<¹»K>n×yêÍÓ§$ÉŸ¦¦Œ®H'gµÖ›Xœ™1$T«ä£GäÒÙ^ äÜ÷oI’ ±î !r PY½ÅE)%D•ÅE«oýcE%åYÿô‰ýýýIíÛy …PJÍ8}›J«}ãªhbb"t½µ200ÏóZÊâ•’¹\ZëŠk.Vß$Ú¤ÞÃ$Y*•ŒÖ[Ý©­í¡cÃ×Z×°X,Z}]dIÚëëëL§Ó¥”?v¦ÝiÇõ­TŽD¸³³Ã¡¡¡Ð5_… ñ ;¢¯ïûAÒI²X,&i¯HOOO·ÿ–þÝ:õw÷·R©Ø†!%…»÷M`§¾J©NNNÆÃÃÃIÚE—¶ú¯À#úøAA‘‹ðÏÁÁA(¥äÿ¶ôuãÏžçQJYð}G6ÇìoÆw…õ ôˆIEND®B`‚routino-3.0/web/www/routino/icons/limit-no.png 644 233 144 700 12573351606 14661 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“uIDAT8Ë­”1Në@†¿Ý‰Ü$¢I‰WqZn¥WHc@ŸSpˆ´4HH¡Œ”t–hpœý(l ôŠÖó/m1»ÿü;³;3c¢€ÃáacÏŽÇzqqv<Öž…MsŽ?¤ƒ¼½ wæù»Ë¥><$G}{Óã±¶—KÍówá®á‡Æ̲è`€Óé¥ðêl¦ûýY­LéìwÔvå~v6Sxu:½t0À,‹8™à|ž /®×ªjòtÒÓISúZíž&õÃõZáÅùçýMÚOì*2›a'IEND®B`‚routino-3.0/web/www/routino/icons/limit-23.6.png 644 233 144 1532 12573351605 14660 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”ÁK[Y‡ïI“øŒbE‰£‚ÒA´‚aºJœ¡H³ÈF,³°±Ý Å` K»wᢅÚJÝ nÚÄ Š–T„!#B"]QLÞ»÷›…ÑiºöÂáÞsï9‡{/ßïIHÂu]$ID"?#-â8Ÿin†–Cs38Îg¤Åê¹ÜjžÐu¡HÄAr˜šŠ -ày%ææàý{ËÉ |û''WþÜx^ i¡ïTó%B!—pXtwßCúÊè(äó°Öðý¸òòyÃè(H_éî¾G8,B!WÄbblÌC:`~  X||¬ýß®÷ÀeæçA:`lÌ#«>SzÍÄ*~¹Œ©T0Æàû>ÆÔ^Ðø>~¹Œ  ½¾þ³ûxÞ™Íå°`©&þXÀZ{3[k©ÆY›Ëç!ݯûSzųg çéS³—ͺ½}+ÏóÔÞÞ®ýý}-//+«££CÖZ¹®«££#½I§UçŽóSVWWéêêbrr’ÎÎN¶¶¶(‹$ R©¿>|È?gg†wï0Ò®«hô?VþË÷—/µ¹¹©h4ªL&£……MMM)‹éââB’´±±¡ÃÃCµ¶¶ê·GÔZ_ï*‘ÓÔô@ܽkL¡Àߟ>188ÈÌÌ ÖZJ¥ãããôôô°³³@:f``€¥¥%º:;Ùüø./ ššŒk}ßqC!e”L&5==­t:­•• kmmM Êd2’¤H$¢h4ªÙÙYµµµéßãc „1ŽkJ¥¬¶·µ½·gƒJEëëëjii ÞÞ^566*+•JihhHÉdRýýýòÖZNOO±ÖÅb‘ \xþ¤ÅÎÈå®È®òe­½aÍSÙ1ŒÁüÀY,T¬ïc¯$SkÍ:®c*LN~§€[Õæ­v[íg·ØiÿJ4j¡óA6IEND®B`‚routino-3.0/web/www/routino/icons/limit-20.6.png 644 233 144 1532 12573351605 14655 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”ÁK[YÆ¿÷Äh¦Æ¢:ARiAj)Ú€.*‚­PDhAlwCñ(¸¬{—Óéf¤´®ñpDhÀEcTFâBˆ„¼÷îýÍ"Ñi§ÌÎ ι÷|ç^¾ïIHÂu]$I´¶þ„´Šã|!‡Û· ñ88ΤÕƽÜN芨µÕArxú´é-žWaq>}²œœÀù9œœÔóÅEð¼ ÒÛF½ÓÀKD".--¢¯ïÒSSP, ÄZ÷«ž‡‹†©)öèë»CK‹ˆD\‘Hˆéii—¥%€` °öß}u¨±´Ò.ÓÓ‰Dã™Ò 33ðƒZ ãûc‚kíw š ¨Õ0à33ÒÊÕŸÝÅó.l¡€‹1×DW$ÖÚãzµ…xÞÒݦ7Ò2/^dœçÏM~gÇýýÃE£QuwwkooOkkkJ$êèèµV®ëêàà@¿¾{§hs³Ó=4d(£Îöv“Bi›ÏŸùsßÄ<ññq’É$ŒŒŒ088H*•âüü€r¹L&“arr’Ÿ<ோ ÃÇiÛU[Û}=z¤âׯî/¯_kssS===Z^^V<W>ŸW,S.—“$­¯¯k_}øPѨ«LFέ[÷ݦæfl¥¢™Ç511¡¥ÓiÍÍÍÉ÷}IR,SµZ•$…aX'Õoïßë­-©£CVµAฑˆvvw•Íf5??¯••õööêôôTGGG:<ï!³¼ pX¢¢¬ý¹Úg`{–—A:&Ÿ÷l}SzËü<@#¾¿Ç4cˆ¢c̃ÇY¢z¨Ñ ‚†-@zÛæ,ƒçU9=%k[‰¬µXkÛw¬YÀrržWEÊtý)ý¥bqš×¯+¹ÿ–JŠãXétZ•JEÛÛÛ ‚@étZ’tvv¦ þ¬£OŸœÞlÖøß¿÷ØÃÃ.!}`k Àü½µEww7;;;„aÈÈÈÓÓÓLLLpyy ÀÞÞSSSär9‰ ïßI\õõeõâ…¬ä:]]POOJ¥’‰„vww%I“““*—Ë* *‹zùü¹k³Yu÷õe…ï¾~%jQ‘ËåX[[£V«1::ÊÌÌ Éd’õõõ]WWWŒq|tÔ¤ïËð}ãÊZG†Úf­•뺪ÕjÊd2Êårò}_CCC ÃP’´¹¹© ”yöLF’Ç’µŽ«jõ£ö÷%ÉJÒ½½’$ß÷U­Vµ²²¢……kvvV€Êå²òù|§¾ö÷¥jõ£VYZˆ1†ÛÛ[jµõz‹‹ ¬µc¸¾¾ÆZËÍÍ wwwÇMÜÒH«?uvrÒÔM3 “ -Þ_Í6ãþ§³ß:ÀFQ»b'é¯{Çí¶j0?ÿ µ7uj<ê<{ÄIûîg³ìxiQIEND®B`‚routino-3.0/web/www/routino/icons/marker-29-red.png 644 233 144 2077 12573351600 15435 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“ôIDATHÇ••ÁkIÆ¿ª®š ƒ`˜ö0=FÉ^œk¼dÈfQ/sÞe1¹9ÂÂþBÍe`‰MhЋ<VÈ!A–8§00§Õ 8„LWW{¨îq’¸¬û yÕE÷¯ßûê½×ÀW“²Ùì´ÖúˆÏþ{­õ»l6; É{2‰Ä{,€´ÖËQÍ’äÐИ˜˜€ÖqCJ c ¶··qpp@!„PJƘ»þîãô¾pÅó¼ ³²²b;ã8f¿ÅqÌN§Ã••[( &ï]I3N#ö=ÏÛÀr¹6›M’¤µ–Ƙs—µ–$Ùl6Y.—üÀwX)¡”z €•J%LaáÉ ã0$£èT¤´–q2<9éÁ+•J€J©§RJ “ÉÜ@ß÷m«Õ"Išn÷ˆqì|Ÿ™0$I¶Z-ú¾o0“ÉÜ€Rê ÖëuÛÿ ?| ="_½"û?Òh¸ý­-2Ž{Ï×ëu›Dûâ|>·Ûmw$¹¶Fd>ïüÍ›˜î:çÓcl·ÛÌçóqRr°Õj•$¥éŒ·n¹õÛ·ðü¹ÛŸŸwû¯_“™ ¹³ÃTõjµJVZk…˜žæç]]d³Î“Àá!pù²»/ܳ;;½îI8ìøø8{uHÒéøà‹fnÎíݻ碞™!‹E·¦ÇW.— ÀBJ°«««îDIrw—¼z•¼t‰|üøkY’KKNãû÷ÉF/_:567 B„ð<ï7,‹¦Wô×®‘¥ù铃}ùâüÌ ¹°àÖKKŒÉN‡GÝ.GK¥(i‚?Ëå µ^ÀÊõ놟?3ºpô<2›u 76ÈÍM·È‹i_¼ Iþrû¶M€È¥´Ö{X[X°ÜÚbøð!ùä ù왫Ë$‹´NÍû÷$Éõõõ8 !J)P€rJ AHNßo´hÚÆ$¹ÿñ#‹ÅbÚûµ~h!”Rw°X(„ÍÝ]èvIc\›’dÑ&]4;;k’Ù Ãó¼Þ„rx¥d©T‚Ö:H†‹qŒÓÑcH’ËËË6î÷¦SßØÃ™ _kÝÀZ­fI2L"KÓn4Ìår¥”?ŸMû¬9}…˜’R@Á©ŽŽ8::j’áñ»4þÃNéëû~˜ŽD’¬ÕjiÚ ¹ÅÅÅþßÒ¿ÛY}''' IAà†”BLõýß¾Ëzú*¥Z877¥i×’´Õ÷Oé à'!DI„ŽŒŒ@)%ÿ/°§oâõ…ô‘0üI¹ •Šãê ¾‡««–_.CþDúØ>ïµñ‰„O2)_!3308gy[[öÏ­-zzzØÞÞÆÃÈÈ£££ êõ:'''är9J¥ýù<}ûfÙÙÁHû¾2™7zûVNò½ P__ŸÒé´ööö”L&upp t:­ÝÝ]IR³ÙÔÊÊŠôûË—Šno}½{'½xñÆW DBNÒ|©¤b±¨F£!çœz{{%IétZ’¤B¡ ÅÅEmnnêöÇý–ÉHA /ð圧(RgŠ¢Hº¾¾Öåå¥ÎÏÏ544$k­666455¥J¥¢Þ0ÔþçÏRÈãùº¿ÿ¢jU’œ$e25 i||\ÅbQ¥RIšœœÔôô´úûû•Íf5üúµJ>8íì(øõëK7›€ÁZîîîh4ÝìÕëu¬µ]Û9‡1†››⇇ni©›Í–ÎŽŽZÊ6¦«§Ž¬µOtf­k±ÿ£³'àâ˜á‘>¶¡-¹Gð¬µù¬]ãYûÙ3vÚ`³kïðU£IEND®B`‚routino-3.0/web/www/routino/icons/limit-15.5.png 644 233 144 1440 12573351604 14655 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÕIDAT8Ë­”¿K\YÇ¿ïÌŒ/ëd& ó¦Q&KІ ؤ€µJ H$Z(iÒøg$uì¬dpA­Z¤P-§xã8ü‘ oÞ»÷³Å›1.»°Nq¾÷~¿œ{ùž#$! ×u‘\$‘ÍþŽ´Šã|%Ÿ‡{÷ ù<8ÎW¤Õî¹Ü.O¨'”Í:HÏŸg‘Þày?XZ‚÷ï-Aß¿C$õÒxÞ¤7ÝûN—/‘N»d2bdä>Ò• 4ˆ±Öp3’:¦Ñ0T* 12rŸLF¤Ó®(Åô´‡ô•€°DDXû+{X de¤oLO{‹ÝgJo™èÄaˆIDQtÖÚë£0$êtˆ Ã³g ½íýÙC<#b°¶+ô¿aLÒáá!xÞÒÃ>I¯õâEŽLJJí~ú¤ááa•ËemnnªÕj)N«Z­j``@QikkKÇÇÇJ»®S}õÊ ¼|™ãÝ»×BúL­`þ¬Õèëë£^¯ECCCÌÌÌ077G4›M|ßOðj•æÕ•¡^ÇHŸ]årõô©¬ä:©”Õß߯½½=]\\ÐÔÔ”J¥’$i_ççç ^©ÈÏd\ž<‘{÷îcQ(Úmz?511A­Vãàà€ùùyÖÖÖð}ŸíímvvvX\\Lðb‘¿>~„0$ÎåŒ+ku:ê ×uÊå²T*•Ôl6e­U£Ñ¸Æ}ß×Éɉd­0ÆquvöE»»’d%é·;whttTëëë* Óä䤯ÇÇU.—µ±±¡B>¯?=Ò\µjõáƒR?~Ò*ËË1ÆpzzÊåå%WWW´Z-Œ1Xki·Û„a˜àNÂ[^iõ—ÏßÄqwrìµQ{bÿÀÁ€µ7|ö¯ °QÄ öjÇtÍÝavöÆÜêlÞêÖ¸Õ}v‹›öoF“nÙݪÔIEND®B`‚routino-3.0/web/www/routino/icons/limit-111.png 644 233 144 1076 12573351602 14572 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“óIDAT8Ë­”1j2Q…Ïß ü„ <Ã!Hc!ÝÇYÆt:¥T*1™Lˆãø Ã8Ïaq ÒS­v©v[’œ‚ ÐÙÙ™IúŸžžÊÌT„S»-Õj—NΡ0”$™™úý¾Z­–ÞÞÞ$IWWW?bIRJÎád(Mµ{§þ +M%³ÀiµºW’H’© U«U•J¥÷?Ø”$ÒjuPͼ¼¼ðþþ¾«Þ?qnƒjø ïùUä¼/>ûÒöIpß´¹³ý¶­>uÀQ{ó¨Sã¨ó숓ö/MŸX†¡áÊßIEND®B`‚routino-3.0/web/www/routino/icons/limit-12.6.png 644 233 144 1467 12573351604 14664 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ìIDAT8Ë­”¿K\YÅÏ{ŒÎã!FF†­F²i† Ø„a mDŒ‚Å@--ü¶LJÁr“ƒ ‰ÄN° ! j`Š€¿`Ÿ"Šè@„ß½÷³ÅÌlÜ]v+¿pá~ïýžsp¾GHB¾ï#ùH¢³ó{¤e<¯Bw7ôôXº»Áó*HË­}!ù-œP›¨³ÓCò˜žîDzA~enÞ½sœœÀÅœœ4ó¹9ïH/Zõ^ /‘Jùttˆ\îÒããP­ZÀàœåv4sCµji\î"•òE6+&&B¤/,.4G’@’€sßF{ Ð`q¤/LL„d³­gJ/™š¸1¶ ÀZK’$Xû÷ Ú$!i4°pÓ' ½lÿÙC°ÆÞœk9çpÎý÷¼y€s»»†5¤‡ÁOÒÏzþ¼@©d}ÉÿíãGcÔÓÓ£J¥¢••EQ¤l6+k­|ß×áá¡~yõJé{÷¼ïòyKµšö¶·!mS.Ø_Ëe‚ `mmƒƒÒé4ÃÃÃär9vvv8??§P(066ÆóG­fyû+mûêêz¤bQNò½ P&“Q:::Ò‚666E‘¶¶¶$IëëëÚßßW&“ÑàÐ2é´¯BA^W×#_A€R)9IÓOŸ*ŸÏ+Žc ittTù|^*•J’$ I48¨×oÞè÷OŸ¤û÷å$|9çéæFí0Æ(Š"Åq¬‘‘ÍÌÌhiiIÆ]^^* CEQ¤ÙÙYõööê(Ž%Öz¾jµÏúðA’œ¤¿Š777eŒÑêêªúúúT.—599©b±¨þþ~…a¨òyÍ<{æôþ½‚ëëÏBZf~À`-WWWÔëuêõ:§§§ÄqÌññ1×××\\\àœÃÃÙÙ¦ÑhâæçAZþ¦³Ýݦ²áÿÂ9×±µØèì_à’„6a[ · €1´Ä}ÃÔÔ­¸ÓÞ¼S׸S?»C§ýã‚Hôÿ¾ÃIEND®B`‚routino-3.0/web/www/routino/icons/limit-16.8.png 644 233 144 1465 12573351604 14670 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“êIDAT8Ë­”ÏK[KÇ¿wRc¼½I/ AhÝÔnZžèÂ¥;](BÕE Eôð޲ݻ…×À íNåu• Å. jt‘…HBA¡Ñ&÷Î|Þ"I«ïm=0pΙù~gÎð=GHBÆ$ƒ$R©‡HkxÞWº»!“±twƒç}EZkí É´pBm¢TÊCò˜›K!½Á÷°´ïß;NOáûw8=mÆKKàû?Þ´Î{-¼D2ièì}}™ž†rÙ1ÎY®[3Ž)—-ÓÓ Ò×÷€ÎN‘L‘ˉ™é++uÀEEàÜïÕÎꬬ€ô™Ÿ\®U¦ô–ÙY€F\¯c›¬µDQ„µ7h ¢z ^¼émûÏáûƒs-"çιkº›ùæÎ€ï_ =J¬Jêõë^½²F2ÿ|þ¬8Ž•ÉdT*•´±±¡®®.õôôÈ9'cŒö÷÷õ×»wJß½ëå?¶”Ë]ÞÞ^BH{äóöï|žŽŽ¶¶¶frr’±±1ŽØÞÞ& Cèíé¡P*Y>| –öŒÒé§zöLN2^"¡L&£ ´³³£££#…a¨ññq…a(I²ÖÊ÷}MLLè~o¯®ªU£çÏ¥ xj”H dRNÒÜü¼tyy)çÜ/¢ÍÍM IR¥RQ6›Õúúº*•ŠÂ{÷$cä%9ç©ÑPÛ9ç‚ Ðâ⢲٬NNN$Iù|^CCCÚÝÝ•ïû*‹Ò;rqì]\|ѧO’ä$)N«V«ittTýýýò}_ƒƒƒšššÒÈȈVWWU,†¡þxòDó/_:}ü¨D­öEHk,/ÄXËùù9WWWÄqL¥RÁZ‹sŽjµ @½^çììŒèçÏ&ny¤µß:;8h*;Žé©-Ö6Ù ßZìtö¿pQD›ðºXoøqLKÜ fg¯uÀ­öæ­N[g·8iÿKäEÈ[+4IEND®B`‚routino-3.0/web/www/routino/icons/limit-8.5.png 644 233 144 1367 12573351604 14607 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“¬IDAT8Ë­”±KQÆ¿]“½Ë ºœÇÝ"‚˜@B°ºÂJÁREÁ€ ½B[Á 2éí¬ÄBØZˆ……(1EP»S8õ4E4ÍÝÛ÷~)n½ÄÄÒ7óf†™oFHB¾ï#ùH"›}…´‚ç}#Š —³DxÞ7¤•ô_H~š't_(›õ<Þ½Ë"}" ±°_¾8ªUøñªÕ¦½°aø éSï¥ùAà“ɈÞÞ—H§ŒÃÙ™œ³ü-M;áìÌ2>Ò)½½/ÉdDø¢X!Òw–—ê€Ã0œû£÷>p@åe¾31R,¦cJŸ™šh$ØFc Ö>lÌÓÔz×,Ú`j ¤Ï÷˜½% rrÒÄ܃ÉJ’4;<90ü‰ô¶íƒôQåò Þ¿·ã{ÏŸëèëW­­­©££CÅbQ’dŒÑææ¦vvvttt¤×oÞ(ù¼õÎÏ_èð°MH‡¬¯“€ØÚÚ"ŸÏ3;;KOOT«Uâ8frr’™™...HÁ³¬¯ƒt諳³¤áaIò%ÉZ«0 5::ªîînÝÝÝI’ö÷÷u{{+@cccŠãXX+Oò5<,uv–žÉ÷QxJåææF…BA«««ªÕj* ’¤\.§ééi iiiIQiddDVR[H¾/ç<5MKÚØØÐÀÀ€¶··ÕÞÞ®½½=ªT*êëëÓüü¼â8V­VÓ=éÕhHÎy-ÌlŠÙññ1¥R‰®®.Êå2•J…ÁÁAvwwéïï'Š"æææH’’äfBZaq I I½^çòò’$IpÎq}}Ýò_]]ýá_3>aq¤•ÿxfiqËZÛz;çúáÙ£@ÚÑ¿ÄmLcþ߀'ÝÍ'½OzÏžðÒþê f­•ºåIEND®B`‚routino-3.0/web/www/routino/icons/marker-70-red.png 644 233 144 2115 12573351601 15423 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“IDATHÇ••OhIÆ¿ª®Ê$caîaz0’ÝK‚g/³dÍiðàa#„½{sà^ÅÓO2/þaî‚Êîmz¸b¼ÈL ÑÃjT‚I&vuÕ·‡ªžLFÄÝÍ{Õ]ýë÷^½÷8988( —ËÕZ¯ 4{×Zëµ\.wÂ{2‰ #ÀZë¥4MçIrllLLOOCk 礔0Æ ÙlâÇB¥TÃsÀ?=œîNFQÔÀb±hêõºÝÙÙ¡s޽âœãÎÎëõº-‹Ã{'³ˆ3ã(Š6°\.'­V‹$i­¥1æ«ËZK’lµZ,—ËIoˆ=VJ(¥î`¥RIHÒ¦)“N‡.IHcü•yl-]’098èÂ+•J€J©»RJ````ã8¶ív›$iÂæ¯ÄÚC8I“$$Év»Í8Ž- ÌEBˆûιøÆõëüåÜ9‘îïC­¬ÏŸ/_¯^/^ÃÃ@¡à×äø8Rc066†\.ÇÕÕU!„ø \¡PpÛïßûƒøø‘%RJ2Ÿ÷öê*ùì™·³ç‹‹ÌüÞÞÞf¡Pp¡ä`«Õ*I2MSÞî.ùé“ß=?ONO{ûÌrfÆÛË˼±Á4€«Õ*X @j­$!€ÁA`txôxò¸wHS Ù.\ðõR­zýôi·{GJnkk NJ©C0\½ ,,ããÀî.à02âŸ)åu’t;èÝ»wà ¥LØ;wîø=8𱬬CCd¨Yîï“ÇŽ‘·nùõ›7$À´Ñ Iþõø18!D‚(Š~ÀR©dºEO’çÏ“år¨ãõÜyú´·oÜ "ß¾åž1œšœLCÜF>Ÿ‡Öú>Vfg I¦Ÿ?“ÃÃäÍ›ðå‹×kkäÈyü8)%íµk$Éßlþ Ÿå¸¨µÞÀÚ•+–$“åe24;,úÍM²^§i6I’€ˆ0??±±1¼{÷îSǬE6›e±XÌ*¥…ëº6N³p8 ­58ç¨ÕjH§Ó¸rå ´Öp'໲²‚‡"Œ1‡Ãèéé¡—/_öé ~ÈÌZ‹J¥‚k×®all `ŒassãããH§ÓˆF£Aúö ·|㜛f³ ß÷Á9h­‘ËåpñâE8p·nÝB³ÙD±Xľ}ûpáÂxž)e€Z­c†_­×ë´wï^J$PJ!•JáèÑ£èêêB?^¼xc fgg!„@µZE£ÑÀòò2vïÞ®®.Ôj5”J%ë8Žf~'„`?VÍfZkܸqÏŸ?ÌÏÏCkÞÞ^är9ìÚµ J©`ª6º©©)MŸôG~éÒ¥'›››}Íf3·²²¢™ïû(‹xúô)*• Nœ8ãÇ£¿¿GŽA&“A±XÄùóç‘Éd011aªÕ*…Bó¾ï_ä¹\ƘïC¡ÐÈòòò¥”9sæ >|ÄÐÐr¹\pEÛÚ¿?R©ªÕªžžf‘Hä?Ƙ³Dô/ÁþiŒùY$ùË“'Olww7²Ù,‰ˆ((|û@8çÈårh6›˜œœTŽãH"ºJD  H"úŽ1ök"âSSS~£ÑÁ˜}®ééiÕh4dGGÇíL&ó €jÔ'"vìØ±ëŽãÜn4òÞ½{j{]¶O‰Ïž=3³³³".yž÷Û¹¹¹?uêT»À´¸¸hµÖ߇B¡/———ãZkÓ××GZëàÞ3ưººŠ;wîX)%ø9=#"@+ AƘ`Œ-cF#‘fffl¹\çÆÇÇ•çyŒs~ˆn[Q(ÀÚ›-íà;99鯯¯},•JfiiI8޳àºîÕ³gÏb»!¶Àâ3ã|'&&¼~ý333ˆD"0ÆüR±ñèÑ#Ànçη?ü_Çq¾¬×ëñõõuûêÕ+Ýjµ¸”ò7Æ­µÇm¡°£+Û~Ù€²ÖžfŒ}纮Bp!Di```øÍ›7Lkm>7üÁø?‚¡Í÷¯ÖÚoB¡çœ/i­177­5þŸþ Ú´­À<½§jIEND®B`‚routino-3.0/web/www/routino/icons/limit-45.png 644 233 144 1250 12573351602 14512 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“]IDAT8Ë­”±JsA…Ï.’„Û$’4"˜FËŸ'“ɰ¼¼< ‹ì9ûµšÎ9^__yzz Óépww7¨tõ[5äÙ×.ò_ªì£Í<ûµú޾‘ø×øÓÞüÓ©ñ§óì'íwn˜yÛZèÈIEND®B`‚routino-3.0/web/www/routino/icons/limit-16.4.png 644 233 144 1366 12573351604 14664 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“«IDAT8Ë­”ÏJ[Æ¿nã86DF£K!qw™+' Ü:O í¾„³w7"‰ÂòfqqåFEl… 5†ð÷©ß]ôÌÜ ¹K œ:uê£þ|UB’ð}ÉGùü+¤e<ï3P(8Àó>#-·ìBò[~Bm |ÞCò˜Í#-WD|ühœœÀpr’éQAp…´Ôúïµü%r9Ÿ¾>1:ú)¦RfÓ)fŽß%ÓSšMG¥RÌèèKúúD.ç‹‘1= }aaà0’’Ìþ;í70àž…¾0=02ÒJSª13ðÞßã2œs$I‚sÝ’¦¸$!…ff@ªµköš øE“‚Y ÈÌ0³ß2ì¾[šfBüBz-¤eæç1H¶¶¶8>> Žcjµ{{{v”qóϧO©EHËBÚe}Àý½¾Noo/LLL055Åää$F£“ºsޱ±1þ*—\úáH»¾ž={£·oe’ïõô¨P(( CmnnêèèHCCC*•J”$ù¾¯ÅÅEÝÝÝiðÅ Iò)•¤çÏßøêéA¹œLÒlµªññqÝÜÜÈÌ:@«««ÚÞÞ–$Õëu­­­©\.kggG_¿}Ó“§Oe¾Ì<=<¨-€ÌLa* CÍÍÍixxXFCÎ9™™ŠÅ¢ö÷÷Õl6upp yžpÎëÔ,P©TXYY Z­ÒßßOEœžžR,9;; ^¯Sy÷.«Ùû÷ ívº ¤8Çåå%···-:¥œŸŸãœÃ̸¸¸ IÌŒëëk~~ÿžùÍÏwº™ñìð0ãMÆŸ.´Áº$³ýÁ³® °$¡ ødmOiŠý1:›º5uŸ=â¦ý`¹”}^]¬IEND®B`‚routino-3.0/web/www/routino/icons/limit-9.1.png 644 233 144 1271 12573351604 14576 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“nIDAT8Ë­”¿J\mÆç€Çå4jPÄF!ŸM´ÐÔ6k#îz^FÒlå,X¤ò «6HÀ …Âb`ãº9Þ_Š]÷s1¥/œ™ó¼3ï<3DZ X©ü'EßžÖwïJ§§5о ÇÃÿñðòLT©DBd­V>™¦¿=8Ð/_‚··úë—ÞÞüƒMÓß§!>Þ“$vr—–Þ ?ÝÙÑ››R- ¡ô¥ ü››Ò…Ÿ.-½wr“$ÆùyÜÝM…©þQƒy®y®!üžcÔ?)üpw7u~~X&|voO5³(,³Ì<Ï-ËñÄT‹¢°Ìs-Š~oOáóó›}0M»^^ Ésèª`aŒhäÈ‚——š¦]᱇‡ªEÈ2U[­–õzÝ«««W¤ÍfÓëëëA|€/<ÆÄ±$É€ ¨V«<>>²½½M«Õ"ITjµ«««ôz=Æ,I Ž !"ËFñ^¯ÇÊÊ [[[ÌḬ̀¸¸H»Ýe3Êê¥e„Åt»ßh6‰ ,,,Ðét¨×ëìïï³¶¶FµZåáá€4M™˜˜`È h6¡Ûý6ÖÍ¡ í÷ûÞÝÝB°,KïïïGšët:>== :2Àus\gEa9”Á¿DûBtÿÔÙ« ð¥8‡:ûb^OÀ›Îæ›n7Ýgo¸iÿ–hiI_4]IEND®B`‚routino-3.0/web/www/routino/icons/limit-99.png 644 233 144 1254 12573351602 14527 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“aIDAT8Ë­”±J+Q†ÿ=\7a›DAÒ(¢w µ2elR‰Û()ôÌ}m¬òé¬|ÔJ0*"V)b!J"šÝ=ß-6 7·ËÀÿ93ÿž™ùg„$$aŒA2H"›ýTÇqîÈçaf&&ŸǹCªî…dqB)Q6ë 9ìîf‘Žð¼.{{pzjétàõ:ïíçu‘ŽþÎ ^Âu ™ŒXXXBzd{Ú툰6æ§%8¢ÝŽÙÞé‘……%2áºF ¢RñþP«|–0„0k¿¿ô ,ðE­Ò*Ba¦tÌÎ@Ÿ(‚("ŽcÂ0$Ž“Ç ±µÇE‰ÿÎHÇiÍVð¼7Z­äqŒµkí0»”0ÉÔb!%³´ZàyoH+BªS­D„á¤ÙlrrrÂÓÓ···#ئiCDµ R]H74Éú}ð}ŸR©D©TâüüœååeÖ××Y[[ãåå%!Lüc nŒr¹¢ÊeI2V‰]__kvvVWWWšžžÖáá¡|ß×åå¥\×ÕÙÙ™$)NÜÊe)—+ƒ\795F’z½ž677uqq¡­­-u»]mll¨ÙljjjJ#溒1ü’µŽúý‘»­®®ªX,ªÕj©P(È÷}ù¾¯ûû{-..J’ÇIú}ÉZg¤f6)(ïïïAÀÜÜôz=‚ `~~žýýý´­i†5û§›©}~~òüü<”EŠJf\7Çê,%I5—’ 5÷€¡–FFÓ~€‰ÎæD·ÆD÷Ù7í_'‚EÁ|IEND®B`‚routino-3.0/web/www/routino/icons/limit-191.png 644 233 144 1307 12573351603 14600 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“|IDAT8Ë­”?K#QÅÏiúg“>IH“$›¿» Ò—ÁU ؛󽖙Ù?ÿÞûl,#7nn c¤ªN98ð–­F³Ùäîî€V«Åñññ0äïïïÉÏë98éTHßh4RÒ”³³3 …´ÛmY[[cuu•ççgÎÏÏ) 4²úÒh€ôÍifæ³j5Ir ‚@•JEÓÓÓº¾¾ÖÜÜœ®®®T*•tyy©(ŠT©TdfÊáT«I33ŸœCÅ¢$ÉÌT¯×µ²²¢§§'mmm©ÓéhssS­VKZ__×òò²:ކ(%çp2 ”$…™É9§n·«jµª EQ¤¥¥%ýI"™Nqü]ͦ$™ò­—ËeIÒìì¬â8ÖÉɉöööTË®CårY“““õÕlJqü}ì5sAòòòB·ÛàííÇÇÇ¡DÆò™<Æ^sLgx?âŠuT´™rýuöl„p@:{?°Õ_xWo¾k×x×~öŽö7¢X\ýRWóàIEND®B`‚routino-3.0/web/www/routino/icons/marker-31-red.png 644 233 144 2047 12573351600 15423 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“ÜIDATHÇ••±kIÆ¿™‘l‘¤°I®Ð|Mlܧ°°¢Ø`R¨1‹S¸JcÒD#÷'¤9_l®R%)l\Ä¥Hq…;K.„‹32ÆŸÅîÎ|W̬$+¹{°¼eæ·ï}ûÞ[ orddD@6›]ÐZ@Ö{®µÖ_³Ùìøs2 ïÀOZëõ$I‘äøø¸˜››ƒÖÖZH)Ç1ö÷÷qzzJ!„PJÕã8~à¯Nï ·ƒ h`>Ÿkµš9??§µ–ƒf­åùù9kµšÉçó1ús·ÓŒÓˆÃ ްP(DÍf“$iŒaÇß]Æ’d³Ùd¡Pˆ<ø@è°RB)õK¥R”¢n—6ŠÈ$á°Ù$aÔíÒø,J¥R€J©·RJ “É,`†¦Õj‘$ã(ºJñ‘õîý:Žc’d«Õb†3™Ì”R ¬V«¦·Ñrg‡|ó†üôiPPú¼É½½+T«Uã£m€³NÇ#ÉçÏI€¼yÓù/ìò’<;#ççÉÅE·ßGÛét866f}ÉÁ”Ëe’dB’ß¾9ÐË—ôê•[“ä‡äõën½¼ìž% ¯{¹\&£H­5€Ö™ °½ ܹã|½88`.—3(¥üe8íaû^ßzýJ„¾|b?<~B€Æ슾aFéH$ÉJ¥’¦} ·¶¶6ø[úwÖw~~>&Éz½NFJI!Ä=¿=ø!pX_¥T WVVìììlšvŧ­þ+ðŠ¾ŠBH|„;SSSPJÉÿ ìéëý¯APJÙðóP6ßÙ?+5•·)x^êIEND®B`‚routino-3.0/web/www/routino/icons/limit-34.2.png 644 233 144 1440 12573351606 14655 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÕIDAT8Ë­”¿K›kÇ¿ÉÛ›êB N¬·‹Ž‘.THšEìÝÒnü ´‹Ð€c&Ç;”bèÒÉ!CEPˆ3æ‚´A…ТFLò¾Ïó¹C~Ük]=px8çyÎ9ßóð=GHB~¿É$‚Ái¤">_•H&& ‘ø|U¤âà^HþAœÐ0Q0èCòñúuéŽÓ&—ƒËå%4›pyÙ·s9pœ6Ò‡Á{ß ^"ð36&b±8RÅE¨× àa­áÿÒ·=êuÃâ"H5b±8cc"ð‹hT,/;H'¬­t‹ë‚낵ÿéÐè²¶Ò ËËÑè M©@:žÛíbz½c žçÝhz=Ün=Òi Ã?Kà8Wöô´_јAGv¤÷;øŒÁ‚µ§§à8WH !m.àT« *•Ê(¸V«Q.—G(ŽÙÚÚ¢ztàÙ\¤¢ŒT¡TâŸfÓLÆ“*~…Ã/”LÊkµüïß+›Í*Êó<­¯¯«ÓéhrrRC©×ëÊçóÚÝÝÕoá°þþúÕ¯W¯D(ôB<}jøñ€›ëk–––˜%ŸÏÇYYYazzš³³³º½½=ffføóÍ ÀÏŸØHÄÈ …,wwüõé¿?Àüü< ¬®®’H$”J%nnn888Àq677¹¾ºÂ¸¸€ñq++Uøø‘k0¼|I$!“ÉÐl6ØÞÞ&NãyÉd’ ÇannŽñPˆrÙðå ®TR‘·o<·Ó¡Ñhàº.ÖZŒ1ÜÞÞÒjµ0ÆÐl6i·Û4 ÎÏϹøþ;ðx÷+ïñÌ xfŒyÀ¯Ò§‰åžõ' “èY×…_?L<:]·¯&àQgóQ·Æ£î³GÜ´ÿ… ½èÞË8 IEND®B`‚routino-3.0/web/www/routino/icons/marker-32-red.png 644 233 144 2124 12573351600 15420 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“ IDATHÇ••ÁkIÆ¿ª®šFð0Aö0³’ ˜˜Û/’ ‚4G‰ ²÷èAØ?A0ÆC`u=„uGrÉ)ž (ˆà‚Ù“39„2$H"™Mº¦êÛCu“„eÝÃëzLýú½¯^½¾™Ìd2Òéô­õàbÏöµÖúC:¾ñ>™€DìÀZëÙf³y‹$;::Äàà ´ÖpÎAJ c VWW±³³C!„PJUŒ1÷lµqZo8A óù¼)—Ëvww—Î9¶›sŽ»»»,—Ë6ŸÏŒ÷K*N2ƒ XÀB¡U«U’¤µ–Ƙ?k-I²Z­²P(D1x@è±RB)5€Åb1J`ÑÁ]‘Íæ‘Li-]1:8hÁ‹Åb€J©y)%J¥®`†¶V«‘$Mñ±%ÿ«Õj ÃÐ`*•º¥Ô;œ››³$iŒñ›——É'OÈ7o1½ÿô‰|ú”\Z"iâJææælœí;p¹\Îmooû½$95Eä™3ÞOMyàü¼_çrÞ_¿Þ:Èíímær9·ìèè(I²I’_¿ú xÐãÇ~½·G^¸@NLøøû÷>¾¸ÈDõÑÑQ° €ÔZèJ Àŋ޿| ܸáã##Àø¸ï—L&îð u{bŽ;00ÀF£áËONûãGR)ŸÍØØ·Ó9<$>$S)òöíVë‘d¡P )eÀþöì™?Ñz\X ¿|ñ·o=øÕ+²^'ÏŸ'Ïž%Ÿ?'­e3Nbee…œ"B¿`g>oª››äæ&-@–ËG¡++äÕ«^×zÝWµ·GF÷ öõõ5ãKð+²Ù,´Ö¿`qxØdóî] 2“!ïÜ!·¶ÈS§|,&¥ô/_\äÏ÷îÙø'€l2PòZëUcÌ¥RÉÍÌÌHóú5tµ \º\¾ ìïKK@£h:uú4þX_çÄô´„øÛ?‘ü !F¤”Ь¼xáõMÍÚoÍOÒÆÏõ:;{züÝWª'¨ZÝ „€Rê>v†aTýüÙÚ¯¬1dù˜s¼uó¦‰gk¥«« A´&”Ç+%{{{¡µ®ÄÃÅë{l cH’³³³6n´¦SÛØÃ±@¨µ®`©T²$ÅÙ&ý¸¶¶Æl6kPJ9v¼ìãvRßJåH†ûûûìëë3ñðx$„ÿ°#ú†a%#‘$K¥RRö€ìäädûgéßí¸¾CCC†$+• X)%…#mß·ï²–¾J©Ž»þþþ¤ìR\¶ú^à} ! g¸ÜÝÝ ¥”ü¿À–¾±Ÿ‚€RÊ =Ǫ9aÿ¨/›:cñ IEND®B`‚routino-3.0/web/www/routino/icons/marker-41-grey.png 644 233 144 2516 12573351600 15621 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“IDATHÇ}•OhTWÆ¿sÞ½oþ%—«8q"RA»‘âÊbÀ…˜nšE»(H+ÅLe–.¬à¾Ë2Šqc”qáÔ–€J&F’± ÄŽf:2Ñ÷î»÷vaæ™é ÷-Þ÷Îù}çœGù|kÁBäóyS(ŽZkRJ}êû¾@x6‹‘”òO":—Ïçï Ã К¨c­ÕÖÚO¤”—ƒ 8¥”²žçQ&“3GŠÆ,--¡ÑhX)%¹®[TJ}KDÿ‘@ l­Õv !Êív{W:9¹\Žb±> ß÷1??oËå²~ùòå©d2ù™Öúˆµö/"bçðáÃ@Ÿâ víÞ½[Ël6KŽãÀZ»é!°}ûvä••õâÅ‹´”òscÌ kí¿œJ¥ ¥¼¸ººÚŸÍfÕÄÄ„ìéé1&ÊŒˆÀÌÑ€0 ÑÓÓƒ‰‰ ™ÍfÕêêj¿”òb*•Ap,‚/Òé´“`­^ff½÷ÉZ BD÷±±1™N§M_ApŒ­µ”Rçy0Æ€™a­aaaF#$"4›M,..‚™¡µ†çyR ÖÚ †áAÏóìÐÐw23Æ€ˆ077‡+W®`qq1*Ù÷}LNNâîÝ»bÏól†Ù÷}›Éd(‘HÀ•þìÙ3ܼy©T*BQ«ÕpéÒ%Ôj5twwoh³D"L&C¾ï[~—o0Å÷}‹E "•JAk عs'Μ9ƒ¼yófS«­é0;ŽcZ­”RQ)SSSزe Ž?Ž  ¥¸®‹µn‰LZ Ýnƒ™ Çãq]«ÕLµZ¡^¯cff¯_¿F±X¡\.ãñãÇBlÊ®cÞ“'O°°°`ãñ¸f?!¸\.‡­V ]]]8p຺º†!ÇÙÐRëû¶sWJáöíÛšÞÅ/¼uëÖ]×ýõÕ«Wâúõëaww7Nž<‰ññqœ>}ívÃÃÃØ³gÖ–|ßÇÛ·o#ŽSSSæéÓ§ŽëºsJ©³ÎþýûaŒ¹ÇÇêõz¯ÖÚ P† "lÛ¶ ;vì@"‘ˆàyúûûÑÛÛ‹jµjïܹÃÉdò1f”ˆþÌ,<5Æ|™L&«T*¶¯¯¹\ÆìÛ·o“!ýýý "´Z-”J¥Ðu]IDç‰èÁB’ˆî1ówDäܺuK5›ÍhbÖ;½~TK¥RØh4¤ëºW÷îÝû3vT:tèr,»Úh4ä7ÂÍ~gŒ§§§ÍÌÌŒH¥RËA|?;;}Ìî|–––¬Öú~<?Q¯×Ó¾Zëh03ž?Žk×®Y)%øŠˆ¦‰HÐÀ…B!J‚™3/c&’É$*•ŠŸŸ‡ã8Ñ>PJ¡X,†A°ã8—‰è*¹†…Bܹ¬Åÿò€r¹l–——E,{äûþùÑÑQ¬ÄX| ¼‰ïääd<@¥RA2™„1æ!Äj©TrlpÒYÿð1¾±XìÄÊÊJºÙlÚjµªÛí¶#¥<  h­8®K çÀº_¶ZkG˜ùžïûZá!ʹ\îèÇYkm>ÜPþG0tøþn­=ÇÇq–µÖ_ÏÎÎFëðcñî—• ‹ºIEND®B`‚routino-3.0/web/www/routino/icons/limit-5.png 644 233 144 1146 12573351601 14431 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”¿J+AÆ¿™b¶É’&é"÷‚`ic›'pIÁR›¤±òZ  •>€……E – "ÝÝ™ß-v]¹¤ÊSœ9ßù7çÌ’„µÉ"‰jõ/Òcî‰"¨×QÆÜ# ½la'´pT­$ÃÞ^é„0|§×ƒËKÏl//0›år¯aøŽtRðMa/–JE´Zˆc˜Ná½ã'r9c:uÄ1H´Z¨TDXÑhˆN'D3|ž4…4ï¿Ïâ<ðÅ`Ò˜N'¤Ñ(Ê”Név² ²l™Lš¦Ëã½Ï/¿9 Ý.H§‹7Û" ߘLòˆ?­DÎóL&†oH[BÒïdE K$IÂÅÅgggœŸŸ3ŸÏ‹§ó‹´s»~¤¡•´£v[’ŒŒ‘$’¤××WéúúZ777úøøP 9ßö;VµÚv!XY+IòÞK’noo5ŸÏhwwWÍfS€L´à[µÛR­¶me- ‚_sr½^×þþ¾â8Öññ±®®®dŒ‘s®œaHÖbå½Q’”t‹2µ±±¡ÃÃC5›M=??—ôK$‰ä½Ò£€[tÒ¹|VÇã1›››DQÄÁÁY¡/8F#îVvàóó“§§§e€~usåœyï—Y8ç¾3Z1g+ÀO‡%Gÿýký›kÝkÝgkÜ´ÿÇ(bF D¾µIEND®B`‚routino-3.0/web/www/routino/icons/marker-53-red.png 644 233 144 2121 12573351600 15420 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“IDATHÇ•UMK\I=U¯ÊÖ†ÐfÑ/ˆ8B¢¸ue£iDò…ku3ì„,ìÀó„l"!œMˆi!! » $¸€Ð-(ZB/üà½WufQõÚV&s ¸¯ŠW§î=·î-ಽ½]@&“ÓZ@Ö[¶ÎµÖ_2™Ìø}2%Þ €ß´Ö I’L‘dWW—†ÖÖZH)Ç1*• ööö(„J©rdzþnáižÐA óù|¼´´d­µl…µ–FƒKKK&ŸÏÇè÷õ¤§‡Al`¡PˆªÕ*IÒÃ8ŽÏ c I²Z­²P(Džx@èh¥„Rê‹Åˆ$M’0:<¤"2ŽÝH‘$´QÄèè¨I^,#TJ=“Rmmm×0 CS«ÕH’q+I+@)`}ÝÃCÈž$I‚®®.d2®®® !DØ\.gëõ:i--I..’ÙÞîlg'™$äÜœ›_¼èìýûLÓX¯×™Ë嬿r0N®£#÷Ç­[äð0¹¿Oîí¹µFƒ‚|øÐÍ?vÄO<11AFZkÀßlŸ= R.\®\^¿ΟÊeàÆ àåËãïÎNÀ€ç‘`†††xppàî!IŽ‘7o’oߒׯ;·¶œ;_¿’J9/''›W$ …H)#æ¯åe—ÑÃCrg‡ô‡ðçORkòÉrm¬×ÝúÇ$ÀäÕ+’äúû÷`…‚ ˜ÀKaWwvÈFƒæÜ¹cíž>%;:È7oÈLÆ%‘$?}¢ÈÕU|9ñE°ˆl6 ­õs,ŽŽÆ$™la±Í+,;EÁ­Rjiá?ðð•»…¥V+–‚……¦à ·4¹‹¤X ¨™;óyÅM²îó•˜âÌœó9ßùž#$! ß÷‘|$‘Nÿ‰´‹ç}'“wï,™ xÞw¤ÝÞ¹ü^žP(ö<>N#}!:¬¯Ã·oŽV Úmhµ}‚ ƒô¥ïõò%††|R)Q(|@úÁâ"ÜÞZ Æ9ËsKü˜Û[Ëâ"H?(>J‰¡!_d³bi)@ª³µð8ŒcÀ¹_«¿xbk ¤:KKÙl¯Lé+++]ŒÁ<=aŒÁƒsnð0k-Æl· qœÄ¯¬€ôµÏÙG‚à'77ÉIÐ sÎ €àú/¼¹ ø‰ôñÍßÒ?ªTþR¹le­oœÓÑÑ‘NOOuuu¥b±¨T*%Ïót}}­ƒƒ ¿}«l>/Œñ¼÷ï­?tyùFH—ìïãÀDQD.—cyy™R©D†T«UFFF˜››£P(P«Õ’ÒÁ²¿Ò¥¯±±O𙑓|Iº¸¸Ðýý½-,,hbbB’Ôh4´¹¹©““ «V«IR’73#}ãã–»;ú8;;£R©°··G.—ãøøxÀÛùù9SSS”Ëe¬µþ¸»ƒñqëË9OÝn¢`IajrrR«««Êçój6›2ƨZ­j~~^¥RI;;;rÎI O’º]É9oÀ™íqV¯×)‹d2ÖÖÖhµZÌÎβ½½MLOO3::Êáá!ñ3΄´ËÆF²Ÿ|7DQ„µçív›N§CE4›MÂ0äáᡯµ˜ v_èÌ=jì-úMg/; ŽqqüÈ@¬=áº_mõŸxÕÞ|Õ©ñªóì'í¿¸6“¸6Ý´‹IEND®B`‚routino-3.0/web/www/routino/icons/marker-93-red.png 644 233 144 2101 12573351601 15423 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“öIDATHÇ••ÁkIÆ¿ª®š‰#¢$Ê ÓCìA¼æ”!ë(¢æœä²‚x0zÉ‹û¨xØ ¬£æ’4¨/B ‚‘ä ‡(9ˆÌÌiarÂÓÝÕߪzœIXÖ}мîGׯßûªÞkà»É¾¾> Ùlö¢ÖúHœg÷³ÖúC6›½nLAÂy€ð“Öz6ŽãI’cccÐZ#IH)EVWW±³³C!„PJQÍø»‹ÓùÂÏó˜Ïç£Z­fZ­“$a·%IÂV«ÅZ­fòù|€nÝ™´â4cßó¼-,‹a½^'IcEÑ¡ËC’¬×ë,‹¡oð-VJ(¥æ°T*…),Üßg†d÷dÊ8f† ¿}ëÀK¥R€J©y)%Éd. ïû¦Ñh$£ýý^[Üñ΢0$I6 ú¾o0“É\†Rj«Õªé~‘››äÓ§ä›7½Ð•òÉòí[ Ž"’dµZ5.ÛuHúûû“f³i7‚$H€$¯\!ïݳåÏÏ“ËˤӞkk$ÀøåK’ä_ËË!Bxž÷; …¨þå‹ýò… äÍ›vñƒäéÓä§O6»Çm|} @¾~Í6É‘³gc×"—ËAk½€¥ññˆ$ã °€<~œ|ñ‚nß¶1)É#Gh®_'IþzíšqÀ ¹´MóZë-¬ÌÌ’ ?~´çtc#mzëWWÉgϽ{G’\\ZJpO1œ!ÎK) ––¬¾i‹&‰½Ü†¤³ýõ+ ¾Ÿö~¥›Z¥Ô |ÿûPqÓÝûÆuÝäädäfk088Ïó:Êâ•’ÃÃÃÐZn¸X} ”´-gggnw¦S×ØÃ€¯µn`¥R±úºÌÒ²777™Ëå J)'–}Ðë=¶ÛmŽŒŒDnxü!„ÿ°}}ßÓ‘H’•J%-{@nzzºû·ôïvPßqw~ƒ #¥¤â|×ÿ퇬£¯Rª€SSSɹsçÒ²+®lõ£À}ü"„ €Øe¸244¥”ü¿À޾Îÿæy¥”Û~>PÍ!û|™®âô¼»÷IEND®B`‚routino-3.0/web/www/routino/icons/marker-53-grey.png 644 233 144 2734 12573351600 15626 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“‘IDATHÇu•MhTY†ßóW·rk‘”¥5Z“-*ˆå ¨4Q”B% E°Á΢³è^ô¦»$Ô@-ZzÓ.ܸ™•Bü›ˆ`ŒJ*΄±Œ­EH‰h*‰U]Zï½çg¦j¢v¿pá8<|ç9ßý.I§ÓX åœ#NëL&ÓeŒùÙ÷ýÝ®ëÿ±,‹!þCù1Nf2*¥ dÊŒ1Êó'!ÄÏó¾ð}ß„ÃaÒÚÚ Ji¨µÆÜÜJ¥’B@ 0èûþw„B 8jŒQ¶rγÕjuk$‘ÔqbY>ŽëºÈçó&›Íªååå/lÛÞ«”ê4ÆüJ¡,•JÍœóyž·5‘Hø'Ožñxœ0Æ`Œùäáœ#‹‘d2I‹Å¢¿´´BüEkýcÌo4 AñÓÊÊÊ–x<î÷÷÷‹ÆÆFH)aŒ©WG)­k0Æ@J‰¦¦&ô÷÷‹x<¬lBü …@=Ï;êyÞ—‘HD÷ôôˆ„s^­…ÕÖœsh­==="‰hÏó¾ô<ï(;xðà×u›?n‰€7oÞ P(`qq X^^ƺuë@)Åìì,fgg!¥D8†Ö¶mCaòù<B´q)eG86íííÔBž={†Ë—/#Ãu]X–…S§NattccchllD¹\Fgg'ºººŽãб±1S­V;¸ëº&™LÒ††(¥ÀÃÌÌ ’É$úúú ¥DCC\×Å;wÐÝÝT*…û÷ïãúõëH¥R°, ¶m£µµ•`0ˆîînlß¾}}}ˆF£˜žžF>Ÿ‡ã8°, µ®r(eŒéJ¥ß÷Á(¥°sçNôööbÓ¦M8þ<^¿~ Çq ”•+WP(>(¦Z­‚RªYWW×@±X$ëׯ'±X RJ$ ìÚµ ÑhÛ¶mÃää$Âá0¤”ˆD"8|ø0vìØk×®!‹!bffÙlÖX–¥(€¿qÎéè訬T*PJáìÙ³xðà`jj ”R455áܹsÈçóXÛvµj‡‡‡yŸ¿³'NL¼{÷®­R©ì|õê•ìèè ¾ïãÖ­[¸wï …öíÛ‡½{÷Â÷}ܾ}Èårؽ{7öïß¡¡!](X0œò}¿— ÀŸ…oß¾ÝrèÐ!}ìØ1úâÅ ,,, ‹aãÆõËxþü9–––°aô´´`jjÊ\¸p„B¡ÿj­?3Æ<å”Rà…Öú+Û¶Ç&&&Lss3ÚÛÛ‹Å@©1ؼy3ZZZ@A¥RÁÍ›7¥eYÀ!ä)NH‚r—Rú=!„ û¥R „h­AÈûqZ×>Ï‘‘Y*•D ¸è8Î/(YkPŸB÷ìÙsƲ¬‹¥RI ÉèãfŒarrR?|ø‡B¡yÏóþšËåêˆ8p ¶™ÌÍÍ¥Ô¿ƒÁàç/_¾Œ(¥t[[QJRZ(‹‹‹¸té’B_B& !€šÉdêCRÊ)¥óZë~Û¶1>>nòù<cu ¾ïcppPzžGcg!ˆUÈd2 µ—Õ|â÷Æ~¹\®¿l6«ççç¹eYO]×8räÖ±*?ñ{õêU Ož<Áøø8lÛ†Öú[ÎùÊÈÈ`Özgk¿çײ¬Ï‹Åb¤\.›Ç«jµÊ„?4ÆÔ=®) ^-€5¿l@cRJﺮ«8çŒsžu§kzzš*¥ôÇÀŽÿ;j~ÿiŒù1 2ÆØ¼Rê›\.¥þ(ÿÂΰ§ÝIEND®B`‚routino-3.0/web/www/routino/icons/limit-31.3.png 644 233 144 1464 12573351605 14660 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“éIDAT8Ë­”OK›KÆŸwÞ`ôõ_êÍõE¼‹„B®nµtãîŠ`tYÓ~¿ÀE—íÞ}¥®jÁ‚Ÿ@Š+-´Ð 7«,„ ¦)ÔhòÎÌï.­m·˜3óœ3Ïžs„$$aŒA2H¢·÷/¤-‚à™ ärŽL‚àÒV÷^H¦'t“¨·7@ XZêEzI}guvw=ggpqggu¢è;ÒË.>èÆKôôÒi1>>tÊüH`ÁÞã £è@¦4†q0øö­ Ïçó*¥I)T*u}ß7Õj•$îíðÎÂ0$IV«Uú¾o0•JƒRê5ÎÎÎ’ ƒÀF¬¬÷^YX¢í‡äƒä³gd£ÁÐU2;;k\¶¯ Îd2ñææ¦=’œŸ'òøqë¯]³À…{ô¨õ££Œ ’äæ×¯Ìd2±k9˜B¡@’Œâ˜ ²»›¼qÂ^¾$=üò…¼x‘²Ïß¿·à§O™¨^(À(Rk  @;;@o¯í‹l0xû¸r¸t ¸pøüFG›Óã8Rˆkµšl4èJ¥À®.ˆ›7éi`qøøÑFÀêªý]¯»»Àư½ ‘É666 †”2`æææì‰Cîìwï’çÏ“·o“GŽX=Oœ ïÝÛ?þS§]¾lUzñ‚b!DÏó~Àžžž°²ºj;çÌòúuxç™ÉÛÛd_ßþ¡}úÄøØ1òÖ-î’>ºÝZîíí…çyÍ eñJÉh­Ën¹X}ÛJ2ï333ÆkÍíÔ²öÐöÀ×ZW°X,Z}]fIÙ+++L§Ó¥”¿¶—Ýn‡õ-—d¸»»ËÁÁÁÐ-?„ ñ; ¯ïûA²I²X,&e¯HONN¶~–þÝÚõsý[.— ÀH))„8í^÷~l×W)UÀ‰‰‰xhh()»èÊVÿx@_¿! r.ö÷÷C)%ÿ/°©¯óÓžçQJYðs[5‡ì;Q²Œ³„íÈIEND®B`‚routino-3.0/web/www/routino/icons/limit-30.2.png 644 233 144 1530 12573351605 14650 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ IDAT8Ë­”ÏK[YÇ?ï©IL}ÔH™@"2"TÚUºéFL²Ñ…ÝØî\ø ã²Ý¹pçb 3.ÚÐd'n ])8–:è,ŒÁ ¶b¾¼ÜûEâhÇ­œsï=çþàó= ×u®E"? Öä8ÕÛ+õõõöJŽóQ°Ö^Gà¶ó—…"Gà(›^(=×â¢ôæÕɉT¯K''­xqQŠFÏ/Úûv>(r£T*-8Ðô´T©IMYkt}´â¦*£éi ”J¥£PÈEñ8𙉠>iyY’|IVA dí•]ÎIV’¯åe >if&ªx¼ýLx©ÙY©ø¾L£!I2Æ(Yk¿» i4ø¾ŒÔÐì¬//ÿì¾¢Ñ/v¿u¢1ÿº,b­½é#+Y»¿/E£_÷;~†=}úÈYX0–J^ …H&“°±±A<'‹a­Åu]J¥¿olÐ;ñáa£J¥ÛÙÝíÀÀ®òyýU¯›¾»w•Íf•J¥T(4>>®ááa ©V«I’¶··åyž&&&”êï×å²ÑÛ·j®‹çñø1ÍÏŸÝ_VVÈd2 ’Ïç‰D"”J%<Ï£X,P.—YZZbkk‹Ïcïý{—'OÐ;cng§°ÖJ§é_X`n~žÓÓSèîîÀó<|ß —Ë‘L&åÁÇ,ÌÏC½NGW—Üf£áÐÓÃo¯_óÓø8…B®®.jµgggrttD:æââ‚&''™››cuu àû8Ö:nÇׯ{‹Le2ö‡{÷ˆÅb$ Ö××I§ÓŒŒŒËåcjjŠÍÍMòù<ý‰Åwï,>Ð<;ÛC°¦gÏ$©|û¦jµª ¦Œ1ªÕj2ÆÈ£z½®óósU«Uëï£#ý#5õü¹,¬}Ç™isf®Ùÿ™»"×´¸¼ÆÙ•2IjØ šÍkr´7|-»¡€[Õæ­v[íg·ØiÿLJN7$Ô¯¼IEND®B`‚routino-3.0/web/www/routino/icons/marker-XXX-red.png 644 233 144 1756 12573351601 15676 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“£IDATHÇ••1hI†ÿ™‘ŒŠäâ ­p‚¯‰Œ»@ _D WJÛÜ;•U\r>݈*ÜÒC .Ò¤8‚ÓI.3r‚>;;;ó_±³ÒJ¾»ËìÎî|óÞ?ï½Æ&gff$äóù[Zë÷Àù‘Ùg­õû|> ü:™‚„ÀOZë8Ž×HrvvV,--Ak 礔0Æààà'''B¥Tdz௠g´ÃÕ zX*•L«Õ²ÃáÎ9fÍ9ÇápÈV«eK¥’@¿îjqêqÁV«Õ¨Ûí’$­µ4ß¾Ñ3qYkI’Ýn—Õj5òà#a‚•J©6Öjµ(…EQÄ‘’Þ;’‘µ#x­V‹P)Õ–R¹\nÃ0´½^$iâ˜tŽ|þœ|õ*¦2|ýJ¶ÛäÛ·4~Ÿ^¯Ç0 -ær¹(¥Þ`³Ù´$iŒ{vÿ> Ïž=½w/™{ù2qàüœ$Ùl6­÷ö¸b±èƒÁè ˜=œ¥%òÒ%òüœ|ý:>z4–Â; X,O9Øz½N’ŒãxB;’äǤä;d¥B^¿NFQš ëêõ:X @j­$3¥ 8®]?ž>¾|Úm@kÀ9@dÍs¤àúý>ÎÎΠ”š§Çð»ùü…×ÂÃÀAJ°»»»T6üWWÉ+WÈjõ_Cßßß''„ˆÁoX.—M6éGvãyù2yvF¾x‘l°½p½§§§\XXˆ}üŽB¡­õžO~C’qz\L©»w“¹7o˜n½±±a=ðO…T–’Öú[[–$£ÏŸÉ۷ɇ'åøô‰\Y¡ñóOööœþ-„¨¤@åž)¥$€¸ÓéŒ++£_zoýs¿ßg¹\Nk¿‘å€B@)µ€å0Œº¾dmzpY¨—gmmÍøÞÚ™››Cr"-”R²R©@kÝ™Ð7[™ìØÙÙ±Øu§LÛÃÔD¨µî`£ÑHôõž¥YqxxÈB¡`PJ¹:ö´}_ßÉô1¾ylûÄ×øMè†a”¶D’l4i؇ ›››Àø·ô}›ÖwyyÙd§ÓI†”BÜôŸ?Në«”êàúúº[\\LÃnø°ÕNè à!ÄÞÃ?æçç¡”’ÿ8Ò׿A@)eÀÏSÑ\°ãÿ—ëb‚IEND®B`‚routino-3.0/web/www/routino/icons/limit-91.png 644 233 144 1244 12573351602 14516 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“YIDAT8Ë­”¿J+AÆ¿5Y$‹"bôÚ˜F¬-‚Øh#)bm—<@Cm|ƒtН¬Ä?ˆàE›Ú($ Q³;ó»Åî&zõÞÊvæœóÍ93ß9B’0Æ $áû¿öñ¼KÂ&&,ažw‰´ŸÚ…dÒ8¡ŒÈ÷=$ÍMi› x¦VƒƒÇý=<=Áý}²®Õ ž‘¶S/—Èå ù¼(ç~³±í¶bœ³|D²Ži·- ý¦Xœ#Ÿ¹œÓÓ¢R ®i4ÞGAsÃ/Û¼Óh€tM¥0=–)íP­ô‰cˆc¬µDQ„µÃäâ8Æ:Öf¤}ªUv²;[ ºÜÜ$'Z‹sç\ZYòÇñ`/eNüon ºH BÚ§^ˆ‰¢AÀÅÅ»»»ÜÞÞâ[­wwwƒCÒìbêuö…tJ³ `m¿ÀÕÕóóó,//³¸¸Èãã#‡‡‡ŒŽŽÒL|‰¢(ËÎÒl‚tjT(,©\–$ã”àääDSSS:>>–ïû:::R†šœœ”s™—$c$ɨ\– …%#cP.—ÚŒ$immM///Z__×ùù¹FFF´²²¢R©¤^¯§/Èå$c0rÎS¿ÿÉÖëõT*•´ººª0 5;;«ÿ¢ß—œóŒºÝ3µZ’ä<$ÍĮ̀ÓéhooO[[[*'× ññq I’’Z-©Û=ûòšÞÞÞxxxø$‡N§ÃëëëPß¼æ·:ËÄúQ´Ÿð}Û-}jM7$J|þê€íÍ?:Ï~pÒþHX}é[¥—IEND®B`‚routino-3.0/web/www/routino/icons/limit-50.png 644 233 144 1264 12573351602 14513 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“iIDAT8Ë­”¿J+AÆ¿].›¸ ib!D¼ ±°°»¼AH¡ ’Ƥ–øÚ)ˆ/J+_ÂÆ&B "ø ÿ€"wwæw‹ÝhâµÌÀÀœ™ï|Ã9ç;GHB®ë"¹H"þ‹t„ã´Èf!—3d³à8-¤£ä]Hnâ'4 J§$‡õõ4Ò¾ÿN­§§–nžŸ¡ÛíZ |ÿi/Á;‰¿„繤R¢P˜Cº¢\†û{DXk^±qo(—Aº¢P˜#•žçŠ|^T*>R›Fà°„!„!Xû½w`O ÚT*>ù|¦´ÏÚ@@A†á×0Ɔ!ÖZ0¢(Ư­´?ÈÙ"¾ÿJ§ÿƒ~Dgc’á³11¾ÓßEZÒõ:@”„@œœœpxxÈññ1ý~Ÿëëk¸¹¹ù"Mðõ:HGBº Ù06èõzLOOS©T¨V«´Z-VVVXZZ¢X,òòòÆd†f¤ WSSË*•$ɵŠ×ùù¹ÞÞÞE‘677uyy)IjµZÊd2:;;“$Y$W¥’45µüG®‹<Ï‘$Çq$I¹\NZ]]ÕÎÎŽ433#IÊd2úøøÐ@£’$Ï“\WÖ: ‚‘LJ‡ÍÎÎj{{[¹\Nz||Ôíí­îîîT,5ü¹‚@²ÖÉ™IrÖn·™ŸŸ'›ÍR­VØÚÚbrr’ÝÝÝï2ÿÈÙ¯Õè÷ûôz=L,Œ1<==}ÙCd#ÕÕ™1#º2‰=Lja ÚÿtökØ–~ˆ—ѯ0ÖÞëÔë<ã¤ý&*…åõ·©1IEND®B`‚routino-3.0/web/www/routino/icons/limit-165.png 644 233 144 1447 12573351603 14606 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÜIDAT8Ë­”ÏK[YÇ¿ïŠI|5AˆÒ¢àˆÐ¬ìÊÅ ®²ð×Â@… q+ø ÌFhWn܉›».ãFŠ]ˆ ¥. Ö¬B±h)¨šä½w>³HÒ:YzàÂ9÷žïáÞËç! I8ç’H$~CZÇóŽéí…t:¢·<ïi½u.$×Ò µ %’G¡@zŽï§T‚ׯ³3øö ÎΚq©¾ÿéy+ßké%b1G<.†††‘>13•J„˜EܵfR©DÌÌ€ô‰¡¡aâq‹9‘Ɉ¹9é#++uÀ0û¹Ú{`@•>27ç“É´ž)½`~ AÖëDfDQDDQó’AÔj æçAzÑþ³Gø~•“ ëu¬UÈÌ~øíø‡5‹''àûU¤GJ©Xü]ÏžEs±˜ö÷÷†¡Òé´Êå²677åû¾´³³£½½=}8>Öèð°ø0¢RéòŽŽ:„tÄ«WQÄÖÖloo0>>N>Ÿgrr’ÃÃC™eaa/Ÿ?Döò%HGN==õä‰$9yž§t:­d2©ÝÝ]žž*•J)ŸÏ«\.ëòòR’4==­þ„ä¼\NêéyìäŠÅ$If¦B¡ l6«››™™úúú”Ëå´±±¡r¹¬b±¨©©)-//ëï7oäIŠ::$çp2óÔhè®23%“I%“I•J%e2httT‹‹‹êïï×ÅׯMA£!™yNÕê{½}+I&3IRww·®¯¯511¡‘‘uuu)›ÍjuuUkkkJ¥RÓOŸJ’¹wï¤jõ½ÖYZ[@ruuÅíí-arqqA†Ôj5ÎÏÏ›Ü5óC––@Zÿg´Dm®Ú°¶ý6kQÚqö¿`w þ «ö³­~é€{íÍ{÷:ÏîqÒþéÖIökÊüIEND®B`‚routino-3.0/web/www/routino/icons/marker-16-grey.png 644 233 144 2602 12573351600 15617 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“7IDATHÇ}U_hTÙþ~çœ;÷Îd¸5ÃP"Ñ@TX 2à¢ÊƧ€K"´Ù]Ê,ÓeÊ>X_úÚj"ÆêŸyé¸-aKŒcÌà‚‰£áNc¼÷Üs~}ØÌ4fe?8Üs÷~ç;ßïÏ¥J¥‚m¥*•Š­V«Ÿ2ó·ZëcQ1ÂÿÁ®ë’ã8ÿ!¢¯+•Ê?«ÕªH’,Ð6©dfÃÌŽã\‹ãxRkÍAP±X„¢Ïh­Åòò2Â0dÇq(•JMk­¿ ¢×D$@0³0¨”ªw»ÝÁ\.—œ:uJ”J%r]»E×ëu³¾¾>éûþ/Œ1§˜ù% 9::Ê~®”úwǃCCCúÂ… ÎHJ fþÑPJ¡P(ÐáÇE»ÝÖoß¾Í9ŽóKkímfÞgÏž€¿¼{÷nlhhHOMM9žç™AD "!ús`fcàû>Ž;&[­–^[[Ëyž÷³t:ýwÇñxÇŸçr9;11áô>êôž½}B@)k-`bbÂÉår6ŽãÏã8ÌüÖårAÀZÛWÕétÐjµ°ó 0 ñøñc¼xñDk-‚ @¹\†ÖÌüJ’ä“ xxxXôTc$ fggAD¸xñ"ˆívׯ_GÇèv»Æää$ T*‰p·ÛýDDQÄÅb‘Òé4Œ1€f³‰«W¯¢ÙlbÏž=ýëß¿…B—/_ÆÔÔ^¿~0 ¾ï£X,RE¬~'>ðoÿþý¸téfff°µµØÚÚÂÚÚ2™ ®\¹‚t:Ó§O#c ¥ìå³RJ»¹¹ ­u?É]×E&“ã8ýà€ÖQáܹsÀ­[·°±±)% ÛíBa…çy¦ÙlÚÅÅÅ~Å| ½œÃÑ£Gqþüy03šÍ&`ii KKKìyžþ¨”õz= ÃBˆ¾º^Ž@*•B¡PÀóçÏFÏç÷îÝ3ôþ*òùüŸR©ÔßÖ××ÕÜÜ\²»ß¿ß_£Õj¡R©àÎ;8yò$ …æææì«W¯d*•ZÔZ%GFF`­ýÞó¼‰ÕÕÕ½Æ{èÐ!€ 088ˆ½{÷‚™‘Íf122‚|>ÑÑQ?~‹‹‹\«Õ„ïû[ÖÚ3DôJ–ËeEDÇùÕË—/íÀÀ€Ø·o²Ù,r¹\ß f†çyÈçóÈf³ØÜÜÄ7k­”RþÀ?( àÑwBˆ/‰HÞ½{Ww:!>\¸·W«Õ’0 T*5säÈ‘?’^£ÔD$Nœ8qÍuÝ™0 Û·o'»k¿W®RJ<|øÐ>zôHe2™•8Ž·°°Ð°ë½LËËËlŒùÞó¼ÏVWWsÆ{ðàA2Æô³B7oÞàæÍ›ì8ø5=$"À€¨V«ý¦.„PBˆkí”ïû˜ŸŸçF£)e¿Ñh­1==Äq,¤”׈h€³m#ªÕ*Do²Ÿôêõº]YYQ®ëþ7Š¢?œ9s; ±m,vÿÈßÙÙÙž>}Šùùyø¾kío•RïjµšÀ;}—;ó×uÝÏÚív®Óéð“'OL·Û•Žã|`š™û>î…C `Ç/[H˜¹,„ø.Š"£”’J©z©TúôÙ³gÂcw~pýØÐó÷_ÌüµçyRJ¹bŒùÍÂÂB¿÷~ ÿëÿ¦ïFµëØIEND®B`‚routino-3.0/web/www/routino/icons/limit-12.png 644 233 144 1246 12573351601 14510 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“[IDAT8Ë­”=K+A†ßÝ…$. IDH#¼•……¿ Z†¹•…]RZäg(XXÄ_°KSXJ$…Ic‚`@0³óÜb7*è½·Éaç̾ï™sæ|IHÂu]$I¤R¿ê8N›L–—C2pœ6R=þ/$7æ Í ¥R’Ãïß)¤|ÿJÎÎ,ƒ¼¼À`é• øþÒAŒwb¾D"á’LŠ|~ ébz½0XòU"ÝÐë…‹ =ϯ‘LŠD¹œ(•|¤{j5€ `™Í`6k?×ü ,0¡VéžRÉ'—‹Ã”)—¦Æ`Œ! #çÂ0d6›Eú'fJ¹ ÒáüÍÖñýNtãCÖÚ8:û}]bétÀ÷GHëBªS­˜8„b³Ù¤ÛípwwÇÑÑívûá Õ*Hu!ÝÒh„sc§§§xžÇÅÅÝn—¥¥%¶¶¶Èçó´Z­(ôÉ$â5 ݺJ§7U(H’+Ï“$Ykå8ŽVVVäyžµ¿¿¯««+A V«á'â R:½)²Ùápžzf±‡ÛÛÛœœœp}}ÍÆÆ{{{I±ñ—á²ÙЕµŽ¦Sý$ÆA ~¿¯íîîêøøXÖZI’y&M§’µŽ«Ñ¨¥fS’¬bÐ\|ßWº¹¹‘1FçççZ]]Õåå¥$)Œœ°j6¥Ñ¨õc6çòúúÊx»’$‘$Õj5•Ëå0?‚ k-¾ï_444JRÇ —–”†¡EÙÕ¬8I”†¡Âåå|hh(äûþek-´µµAR¯×%IQþðg±î~E’¤z½® @mmm‡„Gàþ}èè€R ff`r^¼ÀöôCg©D¡PÐÔÔ”1Æ|–J¥ôÕü|ö!^¿–¶l‘@²V*³õÔ”tóf¶Þ´)ËJ—–$I¯æçU*•ÒüÈ‘ K’â8δûðAzó&ëqtTÚ³'[8 íÞ­<ÈÀׯ+Îåø€uÎ ŒövظnÝ‚;w`z:;###06‡ÃóçÐß-÷äktnnŽ¥¥%|ß_œ9ÇŽÁöíÙ¾VËr£‹‹P¯Ã»w-½|ù ÅZÉÅ‹³/º¼œõ29)mØ =}šíß¾•œ“ÆÇW>ÿΊGF$IÞ¾- 5Æ„xž÷3 îîî¨uè%éÈ©\^{¤º»¥ãdzõãÇJ7o–Ξբ¤¾;âÜ¿Q,qÎ]448IRüþ½ÔÑ!?Ÿ>}ÊòµkYµÆH ¤¿_ZXÐOccIü (65îrÎ=T9u*‘¤ðÂ)7ƒÒtÅQ³³Ò¥KŠnÜ$ý~õjš?cz›@À3h­W«ÕLß8^Û~=çfgÕMïWVóœ1ß÷Oê‚°öäÉÀjp†ùòÙZݺu+žçµ&T†÷}ÛÛÛ‹s®š—¨eˆñûøøx’çZÓiÕØcÝÀ9WT©T2}óÊšUÏĮ̀X,&€¬µ?®o{}|Yß¼ÂÅÅEõõõEù¨ûÕdFq|%ÖèA؉’T©TšmÏÅ'N¬þ[úr¬×wß¾}‘$U«U‰µVƘÁüqï«Àõúú¾_tôèÑt×®]Ͷ+yÛþ®ÑøÞ# Î+ücÛ¶mø¾oÿ/°¥ožO{ž'kíðíºn>‹–Hl{U übIEND®B`‚routino-3.0/web/www/routino/icons/marker-40-grey.png 644 233 144 2642 12573351600 15620 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“WIDATHÇ}•_hSYÇ¿¿ó§¹ùcIÐÆ]š¬JRˆŒúPi@Áy.VXp˜‡>ì>ìËî0Ì CfÈÃÀ¼ŒÂâ¾õAÅ*l¨K—ˆ—4VÑJÜh«$IõÞsÏ9ó0ͪ3ó… ÷^îýþ~çs~¿ó£b±ˆ 1!ŠÅ¢)•J‡­µß+¥>r]× ü" …HJù?"ú²X,þ»T*1ß÷Àm˜rk­¶Ön“Ržö<凜M$”N§Á 1XYYA»Ý¶RJ(+¥þND/ˆˆÐ³Öj;„•^¯·#™Lú‡bããã …ð¾\×ÅÒÒ’­T*úÕ«WŸD"‘ZëCÖÚÇDÄøÁƒ-€? !þãyÞŽ;wª“'OÊL&CœsXk?¸„ؾ};e³Y¶ººª^¾|™”RþÉsÉZû#‹F£R~·¾¾>šÉdÔÌÌŒŒÇã0Æ™c`Œˆ`­…ïûˆÇ㘙™‘™LF­¯¯J)¿‹F£`žç}ìyÞ§ÉdÒLOOK°ÖûFý÷ýBˆ ðôô´L&“Æó¼O=Ïû˜Yk¿UJ¡P( ‘HÀÆX`Ðh4Ðn·ƒŒ×ÖÖp÷î]<}úœsh­‘H$099 ¥¬µßò‰‰‰bjjŠI)ADq½^Ç™3g0::ŠT*…ååeœ={OžŸG.—ÃÍ›7qôèQìÞ½CCC¨V«¸}û6–——Q(°k×.\¾|Ù<|ø;ŽSWJý™ïÝ»Ƙ;ŽãL·Z­!­µ#ß÷ADH¥RA8Æàà òù<âñ8&&&ÏçQ¯×í7X$ycŒ9BDÿç…BAÑêRÊÏ?~l¶mÛÆ†‡‡ÃÃÇÃAG9ŽƒT*…x<Žn·‹sçÎùÆÎ9ÿ À‚ðH"šcŒýƒˆøµk×T§Óc ZkXkƒr³Ö%6;;ë·Ûm900p>—Ëý€ðûªˆˆíß¿ÿt(:ßn·å¥K—ü÷{¿Ÿ-çÕjÕ,,,ˆh4Úô<ï‹Z­ç“““ýieeÅj­ï8Žs¬Õj%û|µÖÁyÀÃÚÚ.\¸`¥”à/DT%"@+•JÁ¡ÎŒ±¦1f&‰`~~Þ.--sc ˆJ)”Ëeßó<Æ9?MDçÈ Œ(•J`ý› ý.ßF0ÍfS„B¡®ë~}äÈl6ÄX¼güß‹/úpïÞ=ÌÏÏ÷σ¿ !Öggg9»yÜðÍ¿Æ7 []]Mv:»¸¸¨{½—R~ l­ 8nJêÑ Ø4²ßZ[`ŒÍ¹®«…\Q?|ÿþ}¦µ6ï¾³ü_ÁÐç{ËZû¥ã8œsÞÔZÿµV«AkßÒOð ±–./;ñÚšäû_/»ùNJ&]y*hhyY:?7’bYkôÐ:q¬ós£åe *ÏCɤ‹r9T,ú‚cU«’t/É*Ф(’¬ý¾z{’•t¯jU‚c‹¾r¹î3á•VV$)Œïïe:cE‘¬µ.g}û¦( I¡-•$xÕû³)ù~K†bÉÚ.‘µ¶OòÐï›1žœH¾ßL%~‡?¨T~Õ‹Æ÷ï·o‰ã˜l6K£Ñ`{{›\.Çðð0§§§lllpüéÿ|øàü\(˜á/_~²‡‡ ï´µ%IæÏ­- hggGqkzzZ333šœœT³Ù”$íïïkaaA‹‹‹r@½y£Þ¹d2ž?Ç‚ë$ŒŒŒN§ÙÝÝÅó<ŽŽŽH§Óìíí0??O½^§T*Q©TøíÙ3× d2—DB$“X`µ\&ŸÏÖZH§Ó´Ûm<Ï£ÙlR«Õ¨V«ðä $r±Ö! é™$Â0dllŒëëk...8;;cbb‚««+677e*ŸÇnƒµŽK«õžƒ Éd‚€ÙÙYæææÈçó”Ëe …KKKH¢^¯S,{õ-Ðj½GPÓúº$Å2Fwww ‚ ¯³››cú¾µV···j·ÛRwpëëÔ¾ëì䤣›N‚¬µ2-ÉóƒÎl'ï?:û¡lõ*öIÿïÛ8îµU¨••ð¨½ù¨SãQçÙ#NÚ™(IçñkIEND®B`‚routino-3.0/web/www/routino/icons/limit-3.0.png 644 233 144 1310 12573351603 14560 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“}IDAT8Ë­”±J+A†ÿ].IXVÒL!x c¥‚­ØYJЍXYúú¶¦³È¤K¥`A,¹ˆb„`@QÜÝ™ï»ÉMÛe`˜33ÿ93çœÿ! I¸®‹ä"‰\î7RǹevŠEÃì,8Î-R#½’›ê år’Ãövé ÏûàðZ-K¿¯¯Ðï'ûÃC𼤳ï¤ú™ŒK6+æçþ°µ½žb¬5ŒdÓë¶¶@úÃüüÙ¬Èd\Q*‰jÕCêp| ð X¢¢¬ý7‡g`oŽAêP­z”J©›RZ $Ž1aHE3ù1c Qa£â8Á×j Õ‡1[ÂóÞèvGИgv´NÈ ÎÒí‚ç½!- ©ÁÑ@lÀN§C½^§Ýn~Ðív9??çáá!1šàcŽŽ@jéšfàîîŽb±ÈÎÎår™««+žŸŸYYYayy™J¥B¤Á34› ]»òýUmlH’+IqëôôT»»»*•Júúú’$]^^*›ÍêææF…BA’$#¹ÚØ|õ—\e2Ž+I ÅÅE•Ëeíïï+ù¾¯á#ù|^’T(ôùù©ÑÈd$×Å•µŽÂPF’GÍfSëëëjµZš™™Q»Ý–$ÍÍÍi0èééIªT*’$G’ÂP²ÖÅÌ‚ÁZÞßßÙÜÜÄ÷}ööö¸¿¿gmm 888 ŸÏsrr’¤:Éè(fÙL IE ƒ„SÖòòò‚1cÌHN?²9ɳ1²c&¸5qþžý¨âxddœ¸#9Åü¬€©ÖæT»ÆTûÙ;í_·=‡ ÓFcµIEND®B`‚routino-3.0/web/www/routino/icons/marker-7-grey.png 644 233 144 2402 12573351600 15535 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“·IDATHÇ}UMhTWþι÷Î{3£È0” JÜè Ȉ±I ¢fc1 AÐM³hÝ´¥¸‘©Ì¦tÓlºí²DÁØ…?£Ð‰-(”$F! 6 Úh˜48Ó¼wß½· çMg4öƒË}ïrÞwÎùÎ9÷Q©TB,¥D©T²årù„sî{­u1€ðœçy¤”úƒˆ.•J¥_Ëå2GQ¨M*œsÆ9÷±Rj2 ÃóZk—Éd(—Ë™;ŒÖZ¬®®¢Ñh8¥%‰)­õ—Dô F`眰OJYm6›û²Ùl422Âù|ž<Ïû‚KKK®Z­šó©Têc̈sîO"bqüøq _Jù{†ûô… ÔþýûIçÜ{KJ‰½{÷ÒÁƒy}}]¿~ý:«”úÔZ;íœû[ŒŽŽÀ­Vkh``@+ß÷᜙ADï-k-’É$ŠÅ¢XYYÑ/_¾Ìú¾ÿQ2™ü…Ã0<†áÅl6kÇÆÆ8ç:daö¬íímAf†s066¦²Ù¬ Ãðb†§¥sîŠÖÃÃÃÈd2°Öv ³½½ÉÉI´Z­Î™çyð<H§Ó0Æ “É`xxÓÓÓPJ]‘Q f2W(@O¥•REE´+• úúúN§Ñm_(xffÆ5›ÍA‚Àår9J&“°ÖöTYÇ£X,âÈ‘#ò3gÎ –©[ß\.GA8~ëŒñ!cÀÌh4¸wïNž<‰Ý»wÃZ "ê±mó0 !ìÖÖ´Ö؉<þ°Z­b×®](‹=iwÛ4›M0³eß÷ͳgÏìââbgb:óØî‚7oÞ`aaG3÷ØÄ?þOŸ>u¾ïð­”’«ÕjÔh4zZ%Þ———ÁÌ( =‘Åk­qûömCoñ÷õõ}—H$~ÞØØ7n܈vJýÁƒÈd2سgOÏyìôæÍ›vmmM$‰E­õ×\¯×¡µ¾”N§W–——åÝ»w-ÁƒxÏf³ì!ŠÓ^\\tsssœL&ÿ±Öžgæ–df `ÍZûY*•š©Õj®¿¿ù|ÖZ!pîܹžèc­·¶¶pçÎ(‘H("ºLDOHPDtŸ™¿""qëÖ-½¹¹ÙÑ×ZÛ‰°•J%j4*‘H\=tèÐ@÷…&">vìØ¤çyW†šžžîèßÝiÏÎÎÚ‡Êt:]Ãð›ùùùŽc144kE«««Î3çûþÙ/^d1öÀ@œö«W¯píÚ5§”"ŸÑ,I¸\.wZŽ™%3×­µã©T µZÍ---AщPk©©©( CBLÑUª-#Êå28~hãõmO–­×ëÒó¼'A\>uêº Ñï¿§ïõë×#xôèjµR©¬µ_H)[•JEè©¢è~ÙI_Ïóή¯¯g777Ý‚i6›B)õ5€)ç\GÇ® Ð{ÍèúeK‘sn˜™ïA`¤”BJYÍçó'?~ÌÆû.aOú;Èëû›sî’ïûBQ7ÆLÌÏÏÃá_ɥРèd>IEND®B`‚routino-3.0/web/www/routino/icons/limit-13.7.png 644 233 144 1453 12573351604 14661 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“àIDAT8Ë­”OK›KÆŸ÷5˜ÜX5‰DA‘HïÊ"‚‹néBãRB°n ]èð Tî²]+®ý]ÄMWA›M –bQÄ…P!†&¦”X3ïÌï.’´öºu``ÎÌyΙsxž#$! ß÷‘|$‰ü´Žç}&ƒD‹ç}FZo½ Éoá„Ú"ÉãùóÒk¢Ñ,-A.縼„oßàò²i/-A4úéuËßká%:;}Âa‘J=F:e~..,àœåîjÚ–ùyNI¥‹ÎN_ ˆL&ŠtÌÊ À-à0Œç~ïö8à–•ŽÉd¢ ´Ê”Þ°°Ðno±MÖZŒ1Xkï|Îa~þÄ4h¸l¤7ížÖ8=%çZœsÿ«ðO›fÇÉ D£5¤ÑŽWÒ?zùrŠ/¬/ù‡ïß+% ‹Emnn*kppP’t~~®­­-ù¢â§OÞ£‰ ÿþý/W(té;;öíΡPˆÝÝ]*• ½½½,..244Äáá!ûûûLNN233ƒ'ño¡`y÷#}©§gBÏžÉI¾×Ñ¡d2)眂 Ðêꪆ‡‡uvv¦ $ISSSÊçóZ[[ÓH*¥¹§O}÷õ«B=="·”˘V+Òé4T«U²Ù,###ýj×ÕÕccc‹Íö•J[_Îyj4Ô^ÆõõõiooOÓÓÓÊårêêêR¡PP¥R‘$moo+™LjôÉYI~HÎy¾jµ:8$'IÝÝݪ×ëJ§ÓêïïW,Óøø¸æææ4;;+@ù|^™L¦ßéà@ªÕ> iåe€k¹¾¾æææc ¥R c Î9Êå2Î9ªÕ*õz‚ ‰[^iý7ÏNNš¼i:àœûEVkí}Þ5ýþàÙ=8cÚ}vAЖUƒ……; xPm>èÔxÐyö€“ö?þÝs÷ê‚ÃIEND®B`‚routino-3.0/web/www/routino/icons/limit-33.3.png 644 233 144 1473 12573351606 14663 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ðIDAT8Ë­”ÁK[YÆ¿<%É<[’†ÒŒdE„`w %ºq3â«ËÒnôðâ²ÝŠ‹¡¯¸*-Ø¿Á.5P!!Îà"‹€K[›ä½{³H´Mgë… ÷|÷|÷žsøÎ’„ã8H’ˆÇGÚ%ùH2 ©”!™„Hä#Òîè^HΈ'týP<AŠðäIé®û xûÖÒnÃÅ´ÛC{c\÷Ò‹‘dÄ—ˆFb1‘ÏNY]…VË!Ö~^C;¤Õ2¬®‚tJ>_ Ѩ#ÒiQ.»Hu¶¶ú€% ÀÚû ôÙÚ©N¹ì’NÒ”^²¶†AÐïcŒ1A€1ãšÁ€ ßÇÀ€µ5^^×l×ýb›Íá#¢µö— í8>ô³¶Ù×ý‚4;ñ—´ÍóçDž=3“ÇßßW4U.—S½^—ïûŠÅbÊf³²ÖÊq5 ù¯_+69É‹†Vë·ÈÑÑ„ŒtÄ»wüsqaR‰žçQ(ð}Ÿééi<Ï#—Ëqxx@³Ù$•J±¾¾N6æC£a88 ”Ž&u÷î#=~¬ðóg§º½­t&£v»­««+U«U¹®«³³3õû}IR†ªV«Êd2ú÷ôTƒOŸ•JÒ;Ľ{†N€Ë¯_©T*äóyjµÆÊå2333ßÔìòò’J¥ÂL>ÏñÉ t»˜DÂ(˜š²|ÿÎþ›7Ì‹,..²´´Äòò2sssììì°··ÇüüüŸåïW¯ ×#˜š²ÎD·[Óû÷úÓóìƒû÷•L&•Édäû¾¢Ñ¨‰„ŠÅ¢VVV´°° R©¤l6«d2©Ù‡µþô©ÕÁ&ºÝšvÙ܃^óós‚¡0 ‚àÆ¶ÖÒét°Ö†áïõB67AÚÓ™éÌX‹1æF¬Æ˜1cÀÌ/:ûÑž0°Aaø?±ŽÃ;Œ~€çýÔ·Ú›·:5nužÝâ¤ýû,„’†´¡fIEND®B`‚routino-3.0/web/www/routino/icons/limit-22.4.png 644 233 144 1461 12573351605 14656 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“æIDAT8Ë­”ÁK[Y‡y´š>2˜VKÜ=°n*dQÝ#.ÄBÚ.Õ]ÚÝPñ/¡…,"f ÝvѺ(¥è,Z7#F ´%)Ì"Æ@,1-6¢yïÞoI;ev¸‹sï=çž{ÎwŽ„$ÇArD8| )C(”'…7 Ñ(„By¤Lû\HNÛN¨ã(!…xø0Œô×ýA*/_Z*¨Õ Ri驸íû¡¶½DW—Cw·ð¼¤"É$”J°ÖpQZz@©dH&A*âytw‹®.GÄbbjÊEúÄÜÀ`ñ}ð}°ößÕÙ œ17Ò'¦¦\b±ö7¥gÜ¿¦v†i60Æàû>Æü A€ñ}hòàHÏ:9»ë~·…,mˬµXkÖƒ a¡®ûé¶26•ör9Òé4{{{ìîî’N§ÉçóçN:‹Eþ|÷ °©HÒ6¯^ñ×—/æ7×%‘H044Äòò2±XŒ±±1<Ïcggç¼O<gff€ÍÍMâñ8³³³4ÛEÉf³ô÷÷3==Í­þ.—¡^Çôô™HÄR¯“ûø‘ká0‹‹‹cØÚÚÂu]–––8>>æää„jµJ6›err’x<ÎÕ+WX{û¾}#ˆD¬šÒ6oÞðÇë׿ªã022‚çyLLLÐ××Çðð0½½½¬¬¬0::J¥R`uu•ä½{­œ=Ò¶2<~L‚j¹L¹\¦R©pttÄáá!ûûûÐh4¨Õjø¾µ–F£AýëW€€GZÕìpF¡Ðâæ¿€þŸ´îýÂÙyXhZßÇú>ö¬`ÏÁ ì/p©½y©SãRçÙ%NÚ ç¹ øÀðIEND®B`‚routino-3.0/web/www/routino/icons/limit-167.png 644 233 144 1427 12573351603 14606 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÌIDAT8Ë­”ÏK[YÇ¿ï‰1}>4† K¡•BÜÅ‹«]ŒA&ë‚ýò ̲݊K …‚â®P7"®¥R˜€ÕU.„¢ÁÍ{÷ÞÏ,^’q:³ôÀ…{î=ç{ð9GHB¾ï#ùH"~´ç}#“lÖ’É€ç}CÚîî Éïæ õ„ÒiÉ£RI#½#~²±Ÿ>9./áǸ¼Lü ‚ŸHïºñ^7_"•ò““Ï‘¾³²ͦ ÎY[âšMËÊ Hß™œ|ÎÐH¥|11!J¥©Aµ Ðq q Îý3zkà€Õ*H J¥€‰‰î3¥÷”ËÆ`:¬sXk‰¢k-Î9â8&îtˆ£å2Hï{–'Zœ8ÓéàºBιþ¼ç÷ÍÚä†gg-¤üÀÒŸZ[ûMoÞXâØ÷S)Ë£l6«‹‹ íìì(“É(Š"íîîªÑhè¯FCa:í½|ii6Ÿy''B:áãG‹µìíí188H½^`vv–¥¥%ŠÅ"µZ……ñ$¾|þ `͇ ø-èÕ+IòÈóÿ iç¾S(@±˜R(€sß‘öûûB ú<¡£|Þ!967óHˆã[*h4Œ‹ øñ..2\©@ß"}èŸw}¾DŒ‰¹¹—HmÖÖàü<! Ic ’H&_!íãy%†‡áÅ Ëð0x^ i?>’‰ý„º’IÉ#ŸO"½Å÷±¹ ?:j5øñjµŽÞÜßÿ…ô6¶÷b‰DÂÐß/&&^"}cm ªU D8gy<::¢Zµ¬­ô‰‰—ô÷‹Dˆñq‘ËùHe¶¶Z€# ! Á¹?³»h±µR™\Îg|<¾¦ôŽ €6QDÔjaÀZK†Xkÿèf×nwì76@z×}³ ¾pqà¢V rÎ=¬ÿÖ.Špุß2BÚ§Pˆâl‹E®®®8==egg‡ËËKÎÏÏÙÝÝåúúšø¾…HûBú‡k988 ¯¯ÃÃCjµ“““ÌÏÏ3;;K¹\fnnŽ™™¦§§ùùý;€uï߃ôÅhhè%É8çyÕÀÀ€NNN466¦ããc¥Ói ¥Ói•J%¥R)}úü¹ã·° ½12%’$çœòù¼²Ù¬nooµººªz½®••Éó<ù¾/IJ¥Rª×ë’$ž?—ŒÁÈ9Oí¶県1j4Êd2Z^^Öàà –––T­VU©TT©T4ýúµ$É‹"É9Ï(¾ªX”$'ç²JÒÈȈ‚ ÐÞÞžr¹œ¶··555¥l6«õõu-užÇ=;:’‚àkÏoÆ@rO£Ñ Ùlrss󀄵–»»»wûžßìáŒ(ê᪠k—±xÃð¿œýSîQÀn †ÄIÿª€'­Í'íOÚÏž°Óþ=fÁ‚±UÊIEND®B`‚routino-3.0/web/www/routino/icons/limit-22.6.png 644 233 144 1531 12573351605 14656 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”AH[Y†ÿ¼¢&¯Ik tV ¤T¡„TºÐ¶ÛX7¶»¡¸q90 B»®`UŠ]u£‹vÜŒÆb‡¶¤" Q&˜"6´É{÷~³HœQ׸pÏ=÷î¹|ÿ’„ã8H’Fš&xO$W¯"Þ#M7âBryB'…‚ÁR€{÷‚HqݯŒÁË—–B¡P¨ûccàº_‘7îùÍÍ--"¿Žô™ÁAÈç àc­á´Õ}Ÿ|Þ08Ògâñë´´ˆæfGÄbbhÈEúÈø8@°xxXûÿ:9 Té#CC.±X£Mé ÃèyÕ*¦VÀƒçysöÆóðªU ÔéÉÉŸÝÀul.‡K#ñtk-ÖÚ³ûzÜÚ\\÷鯥ߥ?Mîß7¿{çÌ¿x!×uÕÞÞ®­­--,,(+‹É#Çq´³³£g³³ 55~¼yÓχÙì%ùR–W¯øk{Ûüàºôöö’H$˜™™!‹Ñ××G<gss€R©D*•b``€_nßæŸ£#Ãâ"FÊ: ‡;tçŽòŸ>9¿=z¤ÕÕUE"---ibbB+++ ‡ÃÚØØ$-//k{{[ÑhT¿öô( 9J¥hmíW®spÀŸoß’L&I§Ó¬­­‘L&¡Z­077G"‘ “ÉðÓµk¬¼y߿㷶™pØòå ›> ™œœÄÃúú:®ë255Åññ1•J…r¹Ìââ"ÝÝÝtܺÅìóçðíÞåËV5)Ëë×<]X0MŽCWWñxœþþ~¢Ñ(´µµ‘Édèéé¡T*‘N§ …BŒ¦Óx`˜ŸÇJY!Móð!ðööØÛÛ£P(P.—)‹ìî¿O¥Ráððk-¾ïS,ñë­ûèy³ÖÖ4s޳3 °P³ž‡õ<ì)@O €ïc벪q÷î)\¨6/tj\è<»ÀIû/”%´ÌM›IEND®B`‚routino-3.0/web/www/routino/icons/marker-76-red.png 644 233 144 2130 12573351601 15426 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“ IDATHÇ•UÏkI}UÝ53N<ÈD2=DMö`Bð–S†$ƒD zÛÉÁ½ç¤£,ìàâA6Ç$Å0'/‚†Ý[ àpÅxÑ™¨9­&Ê`“®®z{èêÉ$AÖý ùªšêWß{ßvMf2 étúŒRê9°Î³u¯”zžN§Ï€ûN&@Ây€С”šˆ¢¨L’íííb``J)Xk!¥„Ö‹‹‹X__§Bø¾_ÕZ_ðO Nó†žçÕ0ŸÏë©©)Óh4h­e«YkÙh4855eòù¼@÷݉„qqàyÞ ‹Å°V«‘$1ÔZxŒ1$ÉZ­Æb±:àA +%|ß¿€¥R)$IE ¿}£ CRëøI"6†6 no7ÁK¥R€¾ïß“R©TêA`êõ:IR»Ã̘]p’: I’õzAL¥Rç}Šñù3yä R’Ùl¼~ø\]%%Žß]ºÄ$îµµ5ær9ëJftt”$EQLocƒüò%>].“ñzd„¼p!^/,Ç“µ#<::JÆ •R’€@&Ó}ôXXž=vv€§OŽ ›¥¸u 8yÐP G€éïïçÖÖV³™$êôiòÊ•x½¾N¶µ‘ÇŽ‘33äùód*E¾{Ç$­Åb‘ ¤”!3==gt{;>17G:D¾}ï76ÈL†œœÜ½DFwï’$ÿzü˜¬"„çy¿`¡PÐÍ¢'É‹ÉbÑÕŽŽýÐЮ¦·oÓä“'Ü$Ù{êTäš`ÙlJ©ûXÖ$}ýgøæÍ`g'öKK»™h®]#Iþrù²q€È&mšWJ­`åúuC’á;¤kZ»[ôïß“33ÔKK$ÉÙÙYë·„=  Bˆa)%DÕj5f%Ų·£’ö\ýð…B!éýJ+(!|ß¿ €… koÞ4‡Ê~`ãÚ³\.k7[«ð<¯9¡bxß—===PJUÝpÑ͆h1í’611aàjs:µŒ=ì{(¥êX©Tb}]dIÔËËËÌf³¥”?什߾¯¯‹pss“½½½Úº?„ ð¶Gß Âd$’d¥RIh/ÈŽ·þ–¾oûõÔ$Y­V ÀH))„nù¿ý5õõ}¿€ccc¶¯¯/¡]q´ýÜ£/€!!D.Â?»ººàû¾ü¿€M}ÿÕóŸWOONNNtxx¨ƒƒõ÷÷ëôôTÎ9IjÜЋ"É9Ï·õú¶Þ¿×_¥’3a¨õõu¥R)c4>>®ÍÏÏ+“ÉhjjJµZM’b÷îI’óŠEéòr[H^¼à Ì?Õ*Õj•££#®¯¯qÎqvv†µkm›¸¸¸àºV0<Þ¨f«Ïh”¹ÝgιvàÏ=צ†íVŸµ'ÀAè¢×™6è-Þ˜–Ïÿ&àNgóN·Æî³;Ü´ÿfüvjJØIEND®B`‚routino-3.0/web/www/routino/icons/limit-23.5.png 644 233 144 1521 12573351605 14655 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”ÁK\W‡ï 3ö©Éèf*è¤Ø…Ò,CÅ…Dɦƒƒ Y]˜ìJð(tiöîDP¨D"ºêJ‰éCLS4L²RdÊ(YD&Õ7wîýºpÆj»õÂsî=çpïåû! Iø¾ä#‰ÆÆ¯‘æð¼w¤RÐÖfI¥ÀóÞ!ÍÕÎ…ä×ê„ê=$ññF¤Y‚ Ìô4¼zå(áÓ'(/âéi‚2Òl-ß«ÕK$>ɤè꺃ôl-PÅ9ËÕuW9<´d³ } «ëɤH$|‘N‹‘‘iŸ™€pÆ€sÿZ}33Ò>##étí™Ò FG±P1qŒ­T°ÖbŒÁÚë4qŒ©T0Pat¤õ?»G|v…µÂÿ6pÎ]‹kyŽB‚à3Ò½†¥Ÿ˜œüÎ{òÄþ¹»ëÿüò¥‚ P†ÚÛÛÓâ⢒ɤÚÛÛ%IÆ­­­é×ׯõÇÎŽ÷Í£G6Y,~E5¨*í°¾Îï?Ú– `pp»wï²²²Bgg'cccttt°µµ@±X$ Cr¹óyþ:?·¬¬`¥_ÍÍ÷õð¡ß¿÷xþ\jnnVEšÕøø¸Òé´ÎÎÎ$IÛÛÛ:== ï³Y…ɤσòoß¾/Z[­-•Øzó†ÞÞ^&&&pÎQ.—ÉårtwwE›››LMM1??O˜NóËÆÄ1Õ[·¬ïŒñüDB»ûûR>Ÿ×‚–––Ôß߯ÕÕU555)Š":88P&“Ñää¤Â0Ôññ±äœ°Öóm¹¼«ímýöö­«V*Z__W[[›õôô¨¥¥E}}}ÖÀÀ€2™Œ–——ÕšJéÛ¾>=ÎçÖÖÔðåË®æxöŒ¿¡Z::â¨fçççXk)•JcpÎqrr@Ç”J¥:Už>iî’3 … nj|9ç.Y³Ö^rvé[‹ç®pvM*ÎÜ…dþkÝwÕj=§ÂØØܨ6otjÜè<»ÁIûµNyt ÏíNIEND®B`‚routino-3.0/web/www/routino/icons/marker-74-grey.png 644 233 144 2621 12573351601 15625 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“FIDATHÇu•ÏkTYÅÏ÷{ï­÷ê•’”*!¶(¨$Z‰³6Øn”nÓ ' {1›™0ô¦©ZôЛñpv3$B¢TâÂ){Æ€Ð(clb,™.­˜T&±j|?î½³˜Ô›Dî[¼Ã¹Ÿóå^* ØK)Q(L±XüÌZû}†Ÿú¾oþ'ë8)¥Ñ7…Bá¯Åb‘£(´m*¬µÚZ{@)u9‚/Ã0´étšzzzÀ̱£1ËËËh4V)E‰Db2 Ã_Ñk"´ÀÖZ à”²Òl6e2™èÔ©S<00@Žãà}ù¾……[©TôÚÚÚ—žçýBk}ÊZû"bqâÄ  [Jù÷ år¹pllLe³YBÀZûÁ’R¢««‹òù<×ëõðÍ›7¥Ô9cÌ_¬µÿâT*¥Ôw­Vë“l6Ž«ŽŽDQkmœŽˆÀÌ1Š(ŠÐÑÑññq•ÍfÃV«õ‰Rê»T*‚àó ¾Êd2fttTµ ¤”± 3ƒˆv!RÆûÑÑQ•ÉdL_Að¹ù“ïûÝgΜ±¹\ŽÂ0ijgÏP«ÕP¯×Q¯×ñúõk8Ž×uaŒ3£Z­‚™‘L&‘L&¡”² ¤”:,£(N§Óvpp@k7n ÕjAX__Ç¥K—ÐÙÙ fÆüü<®\¹‚‹/"NÃZ‹ÁÁA¾sçŽm6›ÃÒ÷}›ÏçÙóxðàï‰ÄŸ×ÖÖäµk×"‚KKKèíí‹èììÄùóç166† .àíÛ·Aoo/J¥’©Õj"‘Ḣa8!†††`ŒùÑuÝÑZ­¶ÏcúúúhïÞ½èëëC2™Œ¹íä}àÀär9,--Ù™™ö<ï߯˜ÓDô³df àŸÆ˜_zžwçîÝ»¶«« G…1fWí£ !044„ÍÍM”ËåÈqEDßÑO$ˆ("ú™CDbzz:\__ÿ`Þ×ÌÌLÔh4T"‘˜êïïÿµ/ʈøøñã—Ç™j4êúõëÑÇŒŒ1 "Ü»wÏ{úô)k­Íû†»Žÿ m¾³Ö~㺮B¬h­¿ž››ƒÖúÿÎïR~˜Ô·kÒ¤IEND®B`‚routino-3.0/web/www/routino/icons/limit-14.4.png 644 233 144 1302 12573351604 14650 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“wIDAT8Ë­”½J,A…ÏŒ°.ø»¢™ &&‚>€¢˜ ‹ †¦ë¾„æfkà˜™ˆ È‚\ñ«¢â ºNw}7˜Ýñ›YÐAŸéSÝsêT IH" C¤IäóÃH›A…®.èéñtuAT6›ß…6yB­Dù|€°´”GZ'Š^(•ààÀ¸½…ÇG¸½M÷¥DÑ Òzó|ÐäKär!ííbpp©J±µšfžÏ‘§X©Êààíí"— E¿˜Ÿþ°º ÐŒ$$³ÕÂÀ€«« ýa~>¢¿¿ù›Ò‹‹ï®ÑÀ§¼÷8ç¾<çðI‚ƒwAÚhi6J=S­âÀìS"3ÃÌøf†¥EÏH£BÚdeprrÂÕÕUF¬V«gI¼÷øÑ€³R ¤M!²·à÷÷öÈårìîîÐh4avv€¤ùjï}ŠOOx·³Òi¨ŽŽqMMɤ0hkS¡P IZ[[ÓÛÛ›z{{%Iföï들ÉI©³s\tw{îïi)533Ãþþ>‡‡‡ –——æòò€r¹ÌÀÀ@Š ñ÷æžžð>”Y ÷wµÂÌä½W†š˜˜ÐÙÙ™®¯¯U©TDZÌ,ÃkµšÎÏÏ¥ Þ™f x€b±ÈÖÖVV€r¹ÌÂÂcccÜÝÝexqn.Õl{¤Ó¬š€Ã{êõ:¯¯¯™ÐqS¯×ñÞóðð@’$˜qótŸòVV²j¦>»¸H}óÝ ÿ‹Ô"?|ö¥,Iøž°eÜÌÀÎsØøÕÞüÕ©ñ«óì'í?œò¼ÀO‘€ÐIEND®B`‚routino-3.0/web/www/routino/icons/limit-188.png 644 233 144 1357 12573351603 14613 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“¤IDAT8Ë­”OK[MÆŸ;BŒWðOT´ TWEÜê6+júôøÄE²w—U)(tåÆ BSˆP°¸r¡" )¯¹¹3ó{¹‰±ï»ôÀÀ<3ç!òÞæ}¢Y‹Ïõ5„a 郎ØÛ°¾—jµÊÍÍ õzR©D£Ñx…¯®®HîkÙÛéHH?øòÀáÇÇÇŒŒŒpzzJ­Vczzšíím–––888 ŸÏ³³³Ãµïß{þü¤F““µ¾.Iƃ‚ P.—“$yï566¦B¡ ùùyµÛm«P(hnnNÿD‘$Ö×¥ÉÉFÆ Tj\,µ¼¼¬v»­f³©™™U*Ýßß+e³YU*=>>’©”d FÞêv5lÎ9¥ÓiœœhuuUÊd2:<<ÔÚÚšÎÏφ¡jµZïQ$yµZ?U­J’—÷’¤‰‰ u:•Ëe]^^*›ÍjqqQõz]gggÊårZYYQñÓ'Iò#ß¾I­ÖÏW¿™’§§'žŸŸˆ¢ˆ‡‡âdo€­k{qC¿ùJg‰Ã@WÚ³Ö°‹ãÿÕÙ*Àö‰^á—²ú«Þ´6ß´k¼i?{ÃNû/¸²iã èç*IEND®B`‚routino-3.0/web/www/routino/icons/marker-64-red.png 644 233 144 2107 12573351601 15427 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“üIDATHÇ••?hYÇ?óæ½M²j³³A¢VñDl¬ ê"Zù§°·8Í"×XÜY —&( *(Æ-‚`£B¸ëDHqH*³k±…žÆbc2³ó¾WÌLÜl8¼ûÁðvæÍï;ßï—÷ý-|/ÓÛÛkzzzŽ9çæ>[Õyïéé9õ™(ÈÖH€mι‰v»}N’¶nÝ:tçÞ{Œ1ÄqÌóçÏùôé“‚ ¬µµ8ŽÇ¿;pÖ¾0†aÐÀÀ@<55•´Z-yïÕYÞ{µZ-MMM%1 ¬o(Wœ3.‡aøÐÈÈHT¯×%II’(Žã W’$’¤z½®‘‘‘(~ ”SXc°ÖÞT©T"IJ¼W´º*ER»­îòÞ+ZYQ’íU*•µö¾1 …Â( r¹œ4 IRER§ì. ”13ÐF£¡r¹œ* £Xk_šœœL$)^]M¥éiééS)Ž7êÙ3©^W¾399™dl_øR©ä—––RR’ôúµ´}»´y³ÒéÓigþàAú|f&}ß{---©T*ùìÈ‘ŒI’Ú9ËãÇ¥S§ÒßssÒÐôæMz??/õ÷§ ¦}++’¤±±1‰ŒsRC Õ‚ùyèï‡bJ%¸qöìI÷ΜÑQxô–—é¬ ÇÀ7›M¾-/c³È°²’ܼ û÷ÃÅ‹ðþ=\¹ÃÃ0=öõ¥ Ò }øðÀcŒ‰€äÎíÛ©mŸ?K½½Ò­[©Ü¥¾>éÚ5iÛ6é§Ÿ¤'Rù»v©ýø±$éϹ9>‚ÈAð+`~»~½ÝX\ÄnÙ‚?xžV-ÁTONN÷ôôTÕååe766\]]õææ¦L=ËJÞñ±Â÷˜éé/¬¯ÄŒB Š"išrvvÆÕÕÍf“µµ5šÍ&Q‰Y_‡éé/1q,µo-„@«Õbqq‘ççgBÃ@GGGœŸŸqÔjÇÆ„‘eŒ2•iš’¦)»»»ÌÎÎrww7Ü Ë „(¦×ûA§œTÙÔÔOOO¬¬¬°°°Àää$KKKììì0E%¯Ó^ïÇÈߨãã£///C©<<<˜WÒQGþæH½¯¢ðN¼¡œŒÔÙ?+à­Pßùÿ¬€­ÍíÚÏ>°Óþócd6{ð|IEND®B`‚routino-3.0/web/www/routino/icons/marker-66-red.png 644 233 144 2072 12573351601 15432 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“ïIDATHÇ•UßkY=÷νI‰}1"3±j÷Å–â?ÐØDÄß¶}°ï}ë û?È1X£®¢lÍ (»OÖú°JAh“Ró´5#´ÛÎ;gf&MR–u?79ð|ß¹sÎû%ûúú$¤Óé ZëeÆ';k­—ÓéôˆûdB$âÓ` h­ç‚ ˜$É#GŽˆ±±1h­†!¤”0Æ`qq[[[B¥TÕ3 ௞ö?œr§€¹\ÎT*Ûjµ†!;+ C¶Z-V*›Ëå Æ}§’“‰]ÇqÖ°P(øµZ$i­¥1æÀÇZK’¬Õj, ~L¼Àh¥„Rê‹EŸ$mÒßÛcèûdtMJkú>ýÝÝ6y±XôP)õLJ ¤R©K躮­×ë$IãûdçÚq3­íÂï“$ëõ:]×µ˜J¥.A)õËå²%I³·u¬­‘/^Æì“uâA@c I²\.ÛxÚ÷f³Ù°ÙlFA’?’ÇŽ‘ýý$@^¿~øÐ߸Ádîf³Él6Æl©T"IÉ”/’×®Eß_½"Oœ ¿|!K%òÊ•}üäI²Vc¢z©T"«H­5 ´ZÀò2pô(ɇwîýýÀë×ÀÀ@„g³ÀíÛÀéÓ€1€Öˆy¤6 ü½³[»»ù½{ÀÙ³Àô4°º |ýÚol@ÄCmnn@)¥ÀþúèQt£ß¾‘}}äü|"©ùð!yü8y÷n„om‘B0xú”$ùÇË— !|8Žó3æóyS[]žœsçÈ«W£æû÷£Kùô)Òóòå6äÒ·IŽœ9Ä&˜G&“Öú7,NL’ Þ¼!ŠÈÒó"¢·o»p{ëIrúæMþ “Ø4§µ^@ovÖ’¤¿¶F>~L.-%¦Î òÉšwïH’ aL¸#„N!ÎK) ¨>é›X´ÇQ‰=Ÿ?3ŸÏ'Þ÷:ù@ ! ”šÀ¼ëî‡JlÅNË&Øä䤉³µ:88ÇqÚ Ñ+%‡‡‡¡µ®ÆáéÛ(‰-çæælLØh§SGì¡pµÖuôr‡RÊ€z¶9PÿöBŠKy‹Á–IEND®B`‚routino-3.0/web/www/routino/icons/marker-22-red.png 644 233 144 2055 12573351600 15422 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“âIDATHÇ•UAkIþªºj& èarØÃtt%^Lðä2¸FÜ”M6²w½èûÜä2°уģ"x[o9âaÁ,h˜ÉÁÓ†$0B²IUW}{¨êvf²‹îƒæu?º¾~ïûÞ{ |6922" \.Ïj­ß =ûŸµÖoËåò,Äs2Ñ'€o´Ö«Y–-äè記žž†ÖÞ{H)a­ÅÆÆööö(„J©¶µö>€¿úpŠ/œK’¤ €µZÍ®­­¹^¯Gï=ûÍ{Ï^¯Çµµ5W«Õ,ÆsçòŠóŒÓ$I¶°^¯›N§C’tÎÑZ{ârΑ$;ëõº‰ÀÛÒ+%”RO°Ñh˜ÌÑCfÙ@¦tŽÞ𣣼ÑhTJ=‘R¥RiÓ4uÝn—$iOÑûàûÌC’ìv»LÓÔ`©TšƒRê5¶Z-×ÿ"ß½#>$_¾$û?2·±’V«åb¶¯ÀW«U¿»»„ Éõu «Õà¯_€OŸÆoÜ(„ÜÝÝeµZõ±åàæççI’Y^Þø8¹´îß¼ ÏŸ“—.‘ ƒñgϘ³>??ONZk…Œfg¥¥ÐårðYâssáyd$vxRLOđদ¦xxxXô!ÉÀãƒd©DÞ¾ý™Ó‰ç]P¯× ÀAJi¸GEIrk‹¼p‘Æðàð“““Y‚_Q©T µ^ÀƵk–ûûÌN"“„,—I!‚ ++dš†ûr™”’. õÓ½{.þ ’/”šÖzÃZûmóî]ÿË͛Ҿ]*!¬¦¦€NØß„@æ=ÔéÓøm{›?./‹Dˆ¿=ðÉ?@€rF AH™µ_¼üh>`QÌ;;;>̾R͘ *ºA¥Ô}«ÕLgk+¡œ Þ:cHï¹pë–»µ}öìY$IRl¨¯”œ˜˜€Öº—‹%Y¨[Ì{ì„ÕÕU?Û©oía(j­»Øl6Iš¸ò~ÜÜÜd¥Rq(¥üa¸ìa ü 1#¥$€¬ÝndxppÀÉÉI—ÇŠ4¾`ü¦ijò•H’Íf3/{@åÎ;ý¿¥ÿ¶a~¯^½jI²Ýn€“RR1Ó÷û*+øUJupqqÑ_¼x1/»ËV_ 8À/€ï…Å ‡RJþ_À‚ßè—“$¡”ò#€óCÕœ°ÏÁ˜IÍs­¥IEND®B`‚routino-3.0/web/www/routino/icons/limit-19.3.png 644 233 144 1436 12573351604 14664 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÓIDAT8Ë­”OK›[ÆŸ÷$úÖÛ&I›M¤wQ‚ëNDjÉÆ•ˆµºëFˆÀoà¶ÙdåVP„.‚ˆŸ@ð"…«•,W."¡¶¬Ä¼ï9çwùsºtàÀy朙3gæ™’„ïûH>’èïÿiÏûJ2 é´%™ÏûŠ´Þ9’ß±ê:êï÷<Þ¿ïGúHü¦X„JÅQ«ÁÏŸP«µq±Aðécç¾×±—ˆÇ} ‘˽Dª2; 08g¹/ml¸¸°Ì΂T%—{I"!âq_d2bn.@:eu 8¢¢œûuuà€«« 27Ét¾)•XXM«…m`­%Š"¬}  C¢V !ïÞTêæ,O4¨V1à\Ç‘sçÜ÷—Úðì ‚ ”Ò:++80ûûûœŸŸprrB¹\îán„§§§”J%þýüÀ¸b¤u!±½ `?moÓ××ÇÎεZ‘‘&''£^¯P­VI§Ó,..’ÍdøçûwËî.F:òõôék½y#'ù^,¦¡¡! èððPÃÃÃ:88P<×ÞÞž$) C­­­iiiIÏ_¼Pøë—¯·o¥ÁÁ×"•²üøAÔIn¡P`ccƒf³Éèè(333$ 6770ÆpssÃüü<#¹Çß¾Áí-öÙ3ëË9Oa¨®8çäû¾šÍ¦òù¼ …‚R©”²Ù¬Œ1ÚÚÚÒÔÔ”*•ŠžŽŽ¥XLÎÏW£ñEûû’ä$é¯ÁAIR*•R£ÑP¹\Öòò²ÆÇÇ511¡ééie³Y%“Iå_½Òâ‡N»»ŠÝÞ~éU0XËõõ5Íf€»»;.//qÎa­åêê çÆêõ:ÑÝ]Ûne¥WÍ6ÏÎÎÚÌ6¦Ç§.î“¶§·ûž=èEt> éý½1tȲ°p¯µ7uj<ê<{ÄIûr¾‡ dŽoIEND®B`‚routino-3.0/web/www/routino/icons/marker-3-grey.png 644 233 144 2516 12573351600 15537 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“IDATHÇ}•OhgÆŸ÷û³;;C$ÛJ4°º$ˆf!Ó‹ˆñR6‡¢°½4‡öƒm)^d {z©GOÅKqŒ ¨{ÉÖ–-JŒ›à!‚ùcW—ÝDvãüû¾ÌLwÕö…f†™gÞç÷>ó åóyìB ŸÏ«B¡pJký“çy£Žãh„KÇãq’RþEDòùü\¡P`¾ï€ÚåZë@ký©”ò²ëºç<ÏÓÉd’R©c‘¢R kkkh4ZJI±X¬èyÞ·Dô7qÀ´Ö€ÃBˆr«Õ:lÛ¶?11Á2™ Åãq¼_Žã Z­êr¹Ôëõs¦i~Á„Öz•ˆ?qâ„Ð/„øÃuÝÃ^.—“étš8çÐZ°„8pà;vŒÕj5ïõë×¶”òs¥Ô¬Öz›Y–)å¥v»}(N{ÓÓÓ²··J©¨3ÆX´:1ôööbzzZ¦Ói¯Ýn’R^², ÌuÝÓ®ë~iÛ¶ššš’ µc DÆ|߇ã8ð}¿ëºÖ055%mÛV®ë~éºîi>>>þ«ã8ýgΜѤ”Š ",//ãêÕ«(—Ëxðà‰<½X)Ó4!¥ÔÕj•¤”ƒÌ÷ýãÉdR³Ðj(¸»»‹b±ˆ¾¾>är9ŒŽŽâÖ­[ØÜÜEÂ0<<̒ɤö}ÿ8sG§R)J$]àÍ›7Ø¿?ÆÇÇqäÈŒAkZ­†SÈ7‘H •J‘ã8Z¼kŽu‰½ËºmÛ˜™™A«Õµk×°²²‚T*…£GvÝ×9PŒqÎÕÎÎ<ÏÃûâŒ1pÎADPJaß¾}¨×ë¨×ëm¢Õj1¦˜aÁ³gÏÔââbd%´Õl6±´´˲Ëåpþüyôôô`nn.²¯”áùóçXYYцa ÀBV.—ýF£M666påʼxñàº.<σeY]n<ÏÃÝ»wzW¿ð³gÏþùöíÛÁííí‘Z­æŽŽ²Ð’mÛX]]E¥RÁË—/Q*•ÐjµÍfÑÓÓ¥äöíÛêéÓ§Ü0ŒEÏó¾à###PJ=4 cjkkë“ Ôàà AÎ9†††@D¨×ëH¥RÈf³èëëC˜çÅÅE]*•˜iš»J©I"ÚŒ1`C)õ•iš¿U*ÝßßL&¥,ËÂääd×`BÁÜ»wÏÅb’ˆ.Ñ2Áø$ÝgŒ}GDüÎ;^³ÙŒ>¥T´BËP*•üF£!c±Øõ¡¡¡Ÿ0~˜!ˆØØØØåx<~½ÑhÈÙÙY?dÛ¹¡„¢óóóêÑ£G²¬u×uXXXˆRÃOž<ƃÖÖÖt ÃÈnmmÙ|CAÆ^½z…7nh)%øšˆæ‰H€ …cL0ÆÖ•RÓ¦i¢R©èjµ Îy”GÏóP,}×uçü2] ÷0¢P(€…{õ¿| \.«õõuÇ—ǹ¸7D¿S'ú.;„?à{óæMžÆ7gkµšÝl6õãǃV«Å¥”ß(j­#ŽM¡{›ÐñË|­õ8cì¾ã8‚ !Ê™LæÔÒÒ ‚@½/Øeÿ#B¾¿k­/†Á9çëA|³°°€ ð_õ6µ*õaIEND®B`‚routino-3.0/web/www/routino/icons/limit-135.png 644 233 144 1451 12573351602 14575 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÞIDAT8Ë­”ÁK[Y‡ï)I|žF¢†ÔŒ T\Øu‘vãÒèÂe\*èVðe»sá ­Öl„2¸j·RF°`—¡XÒ1X4É»ï~³HRmg–^¸\Î9÷ü¸çò#$! ×u‘\$‘Hü†´ŽãÓÝ ©TDw78Î1Òz+.$·•'ÔJ$$‡ H ½Äó¾³°oßZÎΠR³³¦½°ž÷éeë¾ÓÊ—ˆÅ\âq18˜EúL.Åb¬¸»š¶¡XŒÈå@úÌà`–x\Äb®èï33Ò'–—ê€% ! ÁÚÛÝöê,/ƒô‰™þþV™Ò+fgƒ©×‰¬ Š"Â0$Šš ðV#l4°Ð`v¤Wí?{„çU9=°¦^Ƕ„Úçm•w즸åô<¯Šô¨ãOé/½xñDù|Dºn,¦ÃÃCc”J¥trr¢ uuu)“Éh{{[ûûûúçøX¿g³NüáÈb±Ë9:êÒoÞDD[[[tvv²³³ÃÅžïCCC FFFÈårÌÍÍñõˀȾ~ ÒQ§|ÿ±ž>•$ׂÇQ:–µVÆ­¬¬(“Éèüü\ººº ©©) HÕêG!­³¸`Z@ryyÉÍÍÍ®J¥a+V«Õ(•JMîš>Ãâ"Hëÿá c~⪠«µcÌÖ¢&´?qö¿`ïþ «ìm[ýÒ÷Ú›÷:5îužÝã¤ýPN*'ñg!IEND®B`‚routino-3.0/web/www/routino/icons/limit-8.6.png 644 233 144 1312 12573351604 14576 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”½J+Q…×L‘ÄQ0èh@Á[Y±M«M°ˆŠ˜Èc$½`c!ø)|.Æ4A$1…h“™9ç»ÅLæš+·óÀáü­µ9{ïµ·„$\×Er‘D.÷ éǹ#Ÿ‡©)C>Žs‡t”¼ ÉMxBCC¹œƒä°½CªãyŸÂù¹ååú}xy‰Ï‡‡àyŸHõï$|‰LÆ%› ‹H”ËÐé ÂZÃן#:C¹ Ò# ‹d³"“qE¡ ¶¶<¤ßÔjÀ††`íß9¼ ¨Õ@úÍÖ–G¡¸)5¨T¢„aˆ1£3ÆÄ÷AQã+Ø-áyï´Z±#aˆñ̦ëp`cc–V <ïiIHGT«‘ noo©×ëÜßßÅDÚí6Fƒ›››Ø`Œ¨VA:Ò5§§D`šÍ&¾ï³³³Ãüüÿ[ø0ð÷Ál6vtgg_ ?ÝØÐ››TM !õ±õqâÍMêÆ†ÂOgg_;:ŠÙlŒ33¸¹™~¸¿¯ÚQƒ½žözÂÃîiP;îï+üps3ïÌÌà™ðÑ­-Õ®IbÒ阆pŸP’$¦i?É4MíµÛ¦ÝnßkKáãðŸ-˜Ï7¼¼T I§cxF4Ä!„‡ï$1hðòRóù†°€päÞžjúѬV«^__ßV«U¯®®T=??÷ààÀ«ÁyÐĽ=…#„¯V*ª©iêññ±™LÆr¹¬j¥RqddÄ““kµšsss®¬¬¸¼¼ì¿õºjÊe…¯1““oxÿ JE‹ET¢(bzzš±±1ÎÎÎ(‹œžž’Ífùçóg€8}÷&'ßÄıd³„(•J,..Òl6ØÞÞfii‰ÛÛ[Ö××i6›¬­­qqqA&“€LâØ˜"º][áÇ1­V‹……VWW) ÌÏÏ÷³O!Ši4¾Q­$ãããQ‰‰ ¦¦¦h4²³³ÃÊÛ·á¯/_ Ñøö¤šAzwwg«Õº¯æcÜn·­×ë}‰ôýŸTó‰ÎLÿÏBâvÂ3ýÑáác«†^ÏAÐgð¢½ù¢SãEçÙ NÚÿ¨¹aÜʈÈIEND®B`‚routino-3.0/web/www/routino/icons/marker-92-red.png 644 233 144 2126 12573351601 15431 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“ IDATHÇ•UÁkSIþfÞLRr(’Ì‹]±Zêié©Á5JQ(9ÊÚEöäA½ØÂþBqí%°у–æ("Â<ô ¨‡E»IzèÉRÁZ“mÞ¼™o3IÓ”e݄ߛ!ï›ï÷ý~ó=`/äÐЀl6{Nký¸Ù¿ÖZ¿Íf³ç ¼'»@"ä€ðÖz!MÓK$922"¦¦¦ µ†sRJc°ººŠOŸ>Q!”RucÌ€}8½ŽFQÔÀB¡`íöö6sìç···¹¸¸h …‚ÀðÞÑnÅ]ÆqEëX*•’F£A’´ÖÒsàg­%I6 –J¥$¯ˆ=¬”PJ=Àr¹œtÁ’N‡.IÈ4ÝÇ”ÖÒ% “ÝÝx¹\NP)õPJ d2™óDZm6›$IÓéÚ—C˜$!I6›MÆql0“Éœ‡Rê%Öj5ÛÿG®­‘÷î‘/^x°®¶ïßûý§OÉN‡&TR«Õl`û\>Ÿw[[[¾$¹´Dä¡C>_¹â=òë|Þç™™^#·¶¶˜Ïç]9ØJ¥B’L#“„!¯_÷@++d6ëNL³³~ÿõküø1»ªW*° €ÔZ(¦ÀÎ0:êçâða ÓÞ¼ff€éi¿?4&<êÝž€#ÀNNN²Ýn“iêË¿yÓ³˜ž&‹Eÿ¼¼ìé´Ûä;d&C^¾Ü=’,•J`!¥LØû÷ïûŽZKîìóóä… äíÛàùsòãGòøqòÈòÁÒZ¦¡Q+++à„ ¢(ú‹Å¢i|øàO>{–¼zÕ3›Ÿ÷ ÛÝ%§¦È'ÈÍMßÔ/_È$a«Ýæøøx.ÁïÈårÐZ/`ùôiC’i½îKÈáaòÉòóg2—#•ò“’64ê—7lü@®k(­õª1æûêÜœûíî]iÞ½ƒ~õ ˜œN¾~ž=Z-@êÔð0–××ùó­["âoü@ò/P „8#¥$€´šÒl˜Š ëÍMÇÆüÝWªªÞ4! ”šÀb1{ÀÆIB›$¤s¼tñ¢ ÞZEE=‡òðJÉ“'OBk]æâõ0YXX°p£çN}¶‡XkÝÀjµjI2 ~Ðǵµ5ær9 €RÊŸËŒƒúÖëû¶Z-Ž›`w… ñ±Oß8Ž“®%’dµZí–½ wíÚµþÏÒ¿Ç ¾§ÃüÖëu°RJ !Îô}ß¾)zú*¥š8;;ë&&&ºeWCÙê[÷é àG!¤áÇŽƒRJþ_Àž¾!ߊ¢ˆRÊ cÕˆS˜›D^ÜIEND®B`‚routino-3.0/web/www/routino/icons/limit-30.8.png 644 233 144 1516 12573351605 14662 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”ÏK[YÇ¿ï©1¾˜iü¡£PKÝt¡ ãPÚÅàJ„$‹‚ÃèFÿWî†qÙîݹ&C mhpãÆ¥›–,l ƒ™‚˜…¨/b«4yïÞÏ,[Ûn½pàœ{ÏùÞs/ßï’„ëºH.’ˆFGÖqœ·$ÐÛkH$ÀqÞ"­·Î…ä¶ê„®¢QÉ!›"=Åó>±´/_Záô›ñÒxÞ'¤§­|§U/‰¸tvŠTj©Âì,T«±Öps5ãjÕ0; R…Tj˜ÎN‰¸"™ssÒ;VVê€% ÀÚ/v½¨³²Ò;ææ<’ÉÖ3¥g¤Óhõ:¦ÑÀCXk¿jÐ4õ:¤Ó =»þ³{xÞG»·×¼Ñ˜Ï@× ÖÚïýfžµ{{ày‘îµý.­±¸ø“³°`þ)—Ý?s9E" ªR©(ŸÏ+™Lª§§GÖZ¹®«ÝÝ]ý•Ëé‡XÌIÞ¿o¨V»œR©MF*Q(ðïé©é½s‡l6K*•¢X,2==Íøø8cccø¾ÀÖÖýýýÌÏÏ3t÷.¯ß¿7¼zE(•\Åãôð¡ÂÜ?ÖÖ”Éd4::ªB¡ h4ªr¹¬x<®ÍÍMIRò¯ÉÉImooËó<½~óFjo— CGV*ñü9ç`~yü˜D"A:æââ‚ÅÅEb±«««ø¾ÏÔÔ;;;LLLÐ××ǯOžðòy¬TÒ:ËËapuÅññ1A“˜c¨Õjc0Æàû>ÖZêõ:GGGWW!ËË ­Å3Ó♹aßrî³o æž}Q@&аAaxCŽö{? ±Íîd27p«Ú¼Õ©q«óì'íÿTácù W IEND®B`‚routino-3.0/web/www/routino/icons/limit-28.4.png 644 233 144 1467 12573351605 14672 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ìIDAT8Ë­”ÁK[YÆ¿÷fŒái "ÊtÜqQ5ÛbÀà¢4¶ݹH»Šàÿ,¸Á mÀM]uQȬ:ÈH2ZÑ’ˆV2Ö2ÌóÞ½¿Y$±v:K¸çÞsÎ=÷Üï;B’p]ÉEáðOH«8Î[¢QˆÅ Ñ(8Î[¤ÕÖ¹ÜVœP;Q8ì 9<|FZÂóÎÉdàÅ ËÉ |ú''M;“Ï;GZjù;­x‰PÈ¥³S ÞB*“NC¥b€k W¥iT*†t¤2ƒƒ·èì¡+z{Åô´‡tÀÂÀ`ñ}ð}°ö‹¶÷À,,€tÀô´Gooë™ÒSff0Ðð/.0Æ|ßǘ¯ $0¾O <éi»g·ñ¼Ï¶T‚¥øßÖÚ¯Ö6š–JàyŸ‘n iÕf2Án±Èòò2»»» –––ØÛÛ»LÒ¾¤\.óëë×Íd@ZU xù’ßß¿7ÝžG2™ddd„l6ËÀÀ³³³ô÷÷³½½}Y±1†¡¡!&“I<RÁU$rG““ª¼{çþüä‰òù¼"‘ˆŠÅ¢zzz455¥¾¾>Õj5I’ëºZ\\T½^WO<.I.wïJ7nÜùþ»Žìù¹3sÿ¾~¸ySÃÃÃJ&“J$:<<ÔÆÆ†NOO‹Å$IëëëÊårJ¥RúíÍýùáƒ~ìî–•p­ï;n(¤?”J¥477§••mnnj||\ù|^]]]ÚÚÚ’1FÆŽŽjggG•JEûûû’ãc5¤¯^ñK.g:\—D"A<'›Í211A4e~~ž££#ÆÆÆ¨V«¬­­‘¾w¯Ù³gÏ@*i•Çù‚¿Ž9ni½^Ç÷}ªÕ*A`­åìì ß÷±ÖR«ÕøûãG€€Gš¿ÙÆ¥R7WpÖÆÖÕõ¥4ý¾ÁÙ%,4¬ïc›”ù_°¶@`¿aÀµróZ§ÆµÎ³kœ´ÿ\DLZ¬dIEND®B`‚routino-3.0/web/www/routino/icons/limit-38.3.png 644 233 144 1505 12573351606 14664 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“úIDAT8Ë­”ÁK[YÆ¿÷çÙ&ÄÔ**ÎÆ ˆq3‹Ð.t!¤‚8EëBÿ·.D—í>È Ò–,¤´Ð?b Ah¡!Έ…¨A[‡¢IÞ»÷7‹$´v¶^¸Ü{Îý¾sϽ|çIHÂu]$IttüŠ”Çq>ÒÕ‰„¡« ç#R¾u.$·Åjêèpž>í@zç}cyÞ½³œœÀÅœœ4íåeð¼oH/Zx§Å—ˆD\¢Q188ŒtÈÌ T*°ÖðãhÚ•Šaf¤C‡‰FE$âŠdRd2ÒgVWê€Å÷Á÷ÁÚï³í ÔY]é3™ŒG2Ùz¦ô’l ¿^Ç4cð}cn'h üz ²Y^¶ÿ,…ç]Ùr¹yc‹øskí­µ…³¶\Ï»BJ…Ö¥Mž?ÿÍY\4¥OŸÜ×…‚¢‘ˆúúútpp B¡ X,¦d2)k­\×U©TÒë7o ‡‡cc†Jå§X ÉHEÞ¿çï‹ “ˆÇÉf³ŒŒŒ°¾¾ÎÐÐsssô÷÷³··@¹\&‘H0;;ËÃd’¿J%ÇR1¬û÷)Vðõ«»±¹©ž”Ïçuss#Ïó455¥££#]__K’‚ ÐÆÆ†z{{õÏá¡——®?–îÝ{vÃad­32<¬þÅEýñ왪ժ|ßWww·¶··u~~®žžIR*•ÒÀÀ€tùå‹â±˜ É …ßÙi¹¹¡ðö-ãcc¤Ói$±¶¶Àèè([[[ììì0>>Þô§RüùêÔjøVV*²»Ë¿`~ò„X,Æüü<ûûûLLLH$XZZ¢R©099Éññ1ÓÓÓÄãqr™ W`ØÝÅJE!åYYüZ³³3ü¦0©×뜞žÖZªÕ*ÖZ‚ hâj5€€•ò·tfZ:kÚš2-_[gÆ0ó“ξW@.а¾Að?±ÞÚ¶™}ƒ\î‡ ¸ÓÚ¼Ó®q§ýì;í•E{qõ4WIEND®B`‚routino-3.0/web/www/routino/icons/create-icons.pl 755 233 144 12504 12003023521 15360 0#!/usr/bin/perl # # Routino icons Perl script # # Part of the Routino routing software. # # This file Copyright 2008-2012 Andrew M. Bishop # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # use Graphics::Magick; # Markers for routing @names=("red","grey"); @borders=("black","grey"); @letters=("red","grey"); foreach $character (1..99,'home','XXX') { foreach $colour (0..$#names) { $image=Graphics::Magick->new; $image->Set(size => "63x75"); $image->ReadImage('xc:white'); $image->Transparent('white'); $image->Draw(primitive => polygon, points => '1,32 32,73 61,32 32,10', stroke => $borders[$colour], fill => 'white', strokewidth => 6, antialias => 'false'); $image->Draw(primitive => arc, points => '1,1 61,61 -180,0', stroke => $borders[$colour], fill => 'white', strokewidth => 6, antialias => 'false'); if($character eq 'home') { $home=Graphics::Magick->new; $home->ReadImage("home.png"); $home->Opaque(fill => $names[$colour], color => 'black'); $image->Composite(image => $home, compose => Over, x => 32-$home->Get('width')/2, y => 26-$home->Get('height')/2); } elsif($character eq 'XXX') { ($x_ppem, $y_ppem, $ascender, $descender, $width, $height, $max_advance) = $image->QueryFontMetrics(text => $character, font => 'Helvetica', pointsize => '36'); $image->Annotate(text => "X", font => 'Helvetica', pointsize => '36', stroke => $letters[$colour], fill => $letters[$colour], x => 32, y => 32-$descender, align => Center, antialias => 'false'); } elsif($character>=0 && $character<=9) { ($x_ppem, $y_ppem, $ascender, $descender, $width, $height, $max_advance) = $image->QueryFontMetrics(text => $character, font => 'Helvetica', pointsize => '36'); $image->Annotate(text => $character, font => 'Helvetica', pointsize => '36', stroke => $letters[$colour], fill => $letters[$colour], x => 32, y => 32-$descender, align => Center, antialias => 'false'); } else { ($x_ppem, $y_ppem, $ascender, $descender, $width, $height, $max_advance) = $image->QueryFontMetrics(text => $character, font => 'Helvetica', pointsize => '32'); $image->Annotate(text => $character, font => 'Helvetica', pointsize => '32', stroke => $letters[$colour], fill => $letters[$colour], x => 32, y => 32-$descender, align => Center, antialias => 'false'); } $image->Resize(width => 21, height => 25); $image->Write("marker-$character-$names[$colour].png"); undef $image; } } # Balls for visualiser descriptions @colours=("#FFFFFF", "#FF0000", "#FFFF00", "#00FF00", "#8B4513", "#00BFFF", "#FF69B4", "#000000", "#000000", "#000000"); foreach $colour (0..9) { $image=Graphics::Magick->new; $image->Set(size => "9x9"); $image->ReadImage('xc:white'); $image->Transparent('white'); $image->Draw(primitive => circle, points => '4,4 4,8', fill => $colours[$colour], stroke => $colours[$colour], antialias => 'false'); $image->Write("ball-$colour.png"); undef $image; } # Limit signs foreach $limit (1..200) { &draw_limit($limit); } foreach $limit (1..400) { &draw_limit(sprintf "%.1f",$limit/10); } &draw_limit("no"); unlink "limit-0.png"; link "limit-no.png","limit-0.png"; unlink "limit-0.0.png"; link "limit-no.png","limit-0.0.png"; sub draw_limit { ($limit)=@_; $image=Graphics::Magick->new; $image->Set(size => "57x57"); $image->ReadImage('xc:white'); $image->Transparent('white'); $image->Draw(primitive => circle, points => '28,28 28,55', stroke => 'red', fill => 'white', strokewidth => 3, antialias => 'false'); if($limit ne "no") { ($x_ppem, $y_ppem, $ascender, $descender, $width, $height, $max_advance) = $image->QueryFontMetrics(text => "$limit", font => 'Helvetica', pointsize => '22'); $image->Annotate(text => "$limit", font => 'Helvetica', pointsize => '22', stroke => 'black', fill => 'black', x => 28, y => 28-$descender, align => Center, antialias => 'false'); } $image->Resize(width => 19, height => 19); $image->Write("limit-$limit.png"); undef $image; } routino-3.0/web/www/routino/icons/limit-115.png 644 233 144 1364 12573351602 14576 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“©IDAT8Ë­”MK\I…Ÿ[j«­ V"˜õ,’?`£ (ã"˜…nÿÀÀ,“½@… Y‡YI4ÆEÀ,›Ðƒ~?úÞ[Ï,º5Æ™Ùy §ê­Ã[Å9/†„ `GÇOªIr`o¯>xÛÛ«Ir ¬6ÏBór-ÔÑ‘‰33ÂK‹Åo..ê›7ÑZM¿~ÕZ­ÁµXü&¼lÖ'Íû`¡loÇ¡¡á“•ŠV«¹šcîm4xfµš[©(|rhhÄöv, àädQøèÊŠê•MSMSñûºÞÓ¨^¹²¢ðÑÉÉ¢ÍgÂ+§§Uëf™ÙÕ•yŒ7 eYfž7šLÓÔôòÒ´^7jÝéi…W×öØbñÄÃCÕ˜]]ïÝæ7hˆGµX<·ü¿óâÅ/<ž›¦! ìîî’ç9¥R‰;;;¨”J%¶¶¶ØÞÞæÏƒ~IÚ=Ê­V;“ýý„}76TsóÜׯ_ÛÖÖæúúºª¶¶¶º¹¹iš¦öõõ955åüü¼}þ¬šÇõu…ý@OÏž>QI’„þþ~T’$¡\.ÓÙÙÉÞÞggg¨LLL0øð!BHž=ƒžž'¤P ÆÈÌÌ £££œŸŸ077Çèè(§§§”Ëefgg©T*,//óÇÛ·$@ÞÒ!ˆ1¡^ç6bŒ?p•µZááaäï/_õ:ĘNN>ðî@¤)ÒÕÕE[[ÛXww7*ccc¬­­Q*•ç×¹9€Þ¿‡““«.-©fMCz||ìÅÅÅ nóËËKŽŽ¾kÔg.-)¬þËgf™ÿ‡ãçò†iðÙ& Þ¼mÚ¨Æï±º“€{Íæ½N{g÷8iÿ$3Ev³˜3ÚIEND®B`‚routino-3.0/web/www/routino/icons/limit-23.7.png 644 233 144 1471 12573351605 14663 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“îIDAT8Ë­”OH[YÆ¿¤`ÒGlM6Š J‘â¬îœ•p)±M×¶°Ý n:‹ÁU ®D×*ˆµ]¤]u£”ŒPÕ¶C,iÁ…¤B”,©$ï½{³Hâ(ÝzàÀ=÷ÞóqÎáûŽ„$‚Á RI„ÿ!-|¦© b1CSŸ‘–jïB Öò„ê@áp)Àýûa¤g8N‰™xõÊrt…Uã™pœÒ³Úÿ@-_¢¡!H($::n!}er àc­á¢UcŸÃCÃä$H_éè¸E($‚¢¹YÄãÒ>³³Àâyày`íÿ^¿ T˜iŸxÜ¡¹¹Ö¦ôœ{÷0àz• Æu0ÆàyƘ ÅY¼rÏuñÀµwï‚ô¼>³Û8ΩÍf±`©%^¨ƒ\²ê»%›Ç9Eº}í/éo>ü=ðàùwo/¸þâ…ÇQKK‹2™ŒVWW …ÔÚÚ*I:88ÐÚÚšö¿|QæÓ§@äÎýñãºM§¯É—>L’þöÍ4:£££tww³¹¹I{{;‰D‚¶¶6R©[[[ 366F@âm:mxóOú ?±üüÉËׯùóéS†††˜››c}} ÙÞÞ R©°¸¸ÈU;ÎåàÆ +¢QcòyþI¥èëëczzk-¥R‰©©):;;ÙÝÝ=×ññ1½½½ìg2U°|¢Q#‰XŠEv3®‡ÃÌÏϰ²²ÂÀÀ===,//S(XXX`ddàûw¸yÓM©´§÷ïµóñ£õ]WÉdR±XL€ºººÔØØ¨þþ~MLLh||\€vvvÇU3«wï¤ÓÓ=!-ñä gàçs9r5/—ËcÈçóxž‡µ–““¬µ‹EÎÎÎÀ÷«Å=~ ÒÒ9ÏÈf«¼©ñËZ{Î5cÌ/<³U K<»¤ ®õ¯ÅÅE‹E­¯¯kzzZÔÇZ­ûˆv[rÎ3j6?éý{IrrN’444$@“““ÚÞÞV:V>Ÿ×ÎÎŽb±˜Òé´ …‚Ê/^H’øðAj6? iƒJ êÉÍÍ ÷÷÷´Z-ÖÚ>wF£Ë]uë*6þÅY/¡ÏÕ[ÖÚ¾Ø0ìrvvÖçì?àþ§a?öCV¿(àQµù¨[ãQ÷Ù#nÚ¿NÎH=öK{yIEND®B`‚routino-3.0/web/www/routino/icons/marker-16-red.png 644 233 144 2040 12573351600 15417 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“ÕIDATHÇ••OkIÆU]•ÄA=Œè Óƒÿöb‚ø4Dc"9h@rÙxл7GXØï ›KP#ˆ(+óAqõ"D„ÉIg$æ´’DFÈštO÷³‡îž?qwhªºèzúyŸzß·  ;44d'¼÷K€€4Õûî½_œÈ÷Ù‚Èäc$ÀÞû¹v»=+Iûöí3§OŸÆ{Oš¦Xk‰ã˜W¯^±¾¾.cŒqÎÕã8¾üÙÃÓùÑ š€*•J¼°°´Z-¥iª^¤iªV«¥………¤R©Ä€ò}GŠˆ ÅaŽŽFFC’”$‰â8þæI’D’Ôh44::åÄ€0£µçÜC@ãããQAűÒv[j·û”*I”F‘¢­­ùøøxÈ9÷ÐZ S€Â0LšÍ¦$)Žc)M¥|S/¡z숣H’Ôl6†ah``` çÜk@óóóIaŸôòe6/¿/ݽ+=y"µÛÙ÷’æçç“\ík€´\.§kkkÙAHÒö¶ôù³46&MNv•¾}+<(íÞ-té’ Ýkkk*—Ëižr$ÓÓÓ™˜ííì‹Ç¥½{³33]Òó祋³ù³gÒáÃR£¡Âõééi‰¬÷Ù<N‚wï`f66²µ XZ‚ýû¡T‚rnÞ„£G!ŽÁ{rktuu•¯_¿âœCìÙÀ®]¦ÝšÛÚ‚V nÝ‚“'áêUXYÁä¢>}úb­€äÞ½{Ý“ÏÍ×ÄDæ«$}ù" I·ogïëë’1j?x IúýéS©1&"‚_U«Õ¸“ôyªhjJ:w®ëé™3Ò… ÙüÎ¥ ½y£MI#Ç·ó"¸M©TÂ{ÿ[žüqßMNfD»'JnÜ$]½r%É ÿJ…[ïý@µZ-‘¤H’^¼ž?ï&¾$­¬H÷ï+^\”$=zô(Í ÿ2Æ „ÀsÖZ+ ]¯×»þþCEå¹úñ£ªÕjQûµ^>oŒÁ9wP5 £F^²{ˆ‹µÙÙÙ8ï­õC‡¥Î9;<<Œ÷¾ÞçR¨Ÿ››KrÂÕNwêi{ìX½÷Í>seEØËËË*•JIV/ö§aïÄwýÝÜÜÔÈÈHœ7_1žï Ïß0 £¢%JR­V+Â^J×®]ë½–þ;ý‹%©^¯ H¬µ2Æœí¹ßþ:þ:皀._¾œž8q¢»–‡íþ+aŸ¿ÀcŒ€v®ðù±cÇpÎÙÿKØñ7‚@ÖÚUàÇÑ|ƒ¿·w™[*ŠIEND®B`‚routino-3.0/web/www/routino/icons/limit-195.png 644 233 144 1450 12573351603 14603 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÝIDAT8Ë­”¿K\YÇ?ï*3ãÑ7ƒŽ0Å…… SظE‚…02…q-µ±l-¶L: ýP –a+ Fl”A¦¨ çÇ{÷~·˜c²[zàÂùÞ{Η{/ßïA€cF€R©ß[ò¼²úû¥tÚª¿_ò¼²`«}ŽÀ´û¢TÊx*•R‚çòýïZ^–^¿vªV¥oߤjµ…——%ßÿ.xÞ®÷Úý DÂ(™D##c‚Oš›“*+)–sVw£…cU*Vss|ÒÈȘ’I”H”Í¢bÑ|Ôúº$5$9E‘E’s?VgOr’Z_—࣊E_Ùlû™ðBóó’ÔT+n4d“$YkE‘¬m]2Š"Eõº¢fSNjj~^‚?ËË÷CŸK’‹ ¹6‘sî6ïàÛh‘;ŸK¾ ò]Áß<{öOŸZE‘1‰‡‡‡ÄqL:¦\.³»»Ëàà A°··ÇÁÁÊe~ó’XU*=Þéi‚S½z%IVÖjggGÝÝÝÚßßWµZÕè訦¦¦499©³³3 «X,jqqQŸ?K’u/_Jpjèë{È£GÆIxžG&“¡§§‡ããc8::"666ð<k-…B¡\ñ?†¾¾‡cD"€sŽR©Äøø8———ÌÎÎrssÃÌÌ '''d³YJ¥…Bµµ5þyó°]]`Œ Îy4›Ü çÆjµù|žééi2™ Éd’\.ÇÒÒCCC|ùúµÕÐl‚sž! ßóö-€Ã9z{{‚€0 ÙÜÜdaaÕÕU¶·· ‚€‰‰ þ|òÀ™wï ß#ØÒÊŠ$ÅmAêúúZµZM’T¯×uqqq«³z½®«««nÕÇZY‘`ë?:Sÿ¤«I'ïhͶDû“Îþ×îá¯bu’Ü[ýâ€{õæ½N{g÷8iÿ(DS< QÖIEND®B`‚routino-3.0/web/www/routino/icons/limit-30.7.png 644 233 144 1506 12573351605 14660 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ûIDAT8Ë­”ÁK[YÆ¿÷ÔDƒiÔ è@ £ E.Ü8™• nFBÝLAÛýüfÙ®ÊHv‚ƒfh iW³’.Ü¥´e3TQŠ"I†6ļwïoI¬víçÜ{Îwî¹|çIHÂu]$I´·ÿ€”ÆqÞÓÕÝ݆®.pœ÷H鯽ÜFžP¨½ÝAr˜mGzL(ô™ÅExþÜrrÅ"œœÔýÅE…>#=nÄ;|‰@À%±X)ÇÌ ÀÇZÃU©û>Çdž™rÄbq‚A¸"Édi—åe€ Àâyày`íWmž.X^i—d2D4ÚhSzÂýû¨y˜Z c žça­½ò8‹W­âÕjxP³÷îô¤ùgC„Bçv¿^јK &ˆµö`# ¿¿¡Ð9ÒPËoÒï<|ø£³°`ö>|pÿÜØP P__Ÿr¹œ677F‰D$IZ__×îÞžþ}÷Îé5‘r¹Ãîì´ÈHoxñ‚ÿŠEÓ}û6³³³Äb1²Ù,‰D‚ááaÉçólmm1>>ÎÄÄŽÄ?;;†W¯ð¤72á°¥XdïãGþxú”L&ÃÔÔóóóLNN066ÆÚÚÕj€••~}ô¨Þñ§Opë–mu[[‘µÎ`<®ïô˃*•JêïïWGG‡$)«R©H’‚Á òù¼Òé´þÎd$Ijk“ZZpýZÍQg§þzöL?%Êf³jkkS¡PP¹\Öáá¡ŽŽŽ400 ÓÓSI񮮠zzz4t÷®Œ$×÷%k·åË—·zùR?§Rö»;w‰DÔÛÛ«ÕÕUÅãqŒŒhnnN£££šžž íím%“I5Äêõkéüü­Ò,-ø^µÊÙÙ^˜c( c.mk-¥R‰J¥¾à³´RúÏLƒgæŠ~˹KòÖ®ñìë¤R5ëyÍŠ—„ýÖ¶¾ß«©Ô• ¸Ñټѭq£ûì7íÿ&ÆmÀ“æ\IEND®B`‚routino-3.0/web/www/routino/icons/limit-37.7.png 644 233 144 1452 12573351606 14670 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ßIDAT8Ë­”ÏK[YÇ¿ï š‰65!ŽË@g! nêÒé€ ¸yäǾ­ €ÿÀÀ,\´«:âZhºj¶ ÐEn„RÒ’'vˆ )B¬Á“о÷îýÌ"‰Vf˜•_8‹{î9ßsÏå{Ž„$\×Er‘D,öÒ*Žó‘áaH¥ ÃÃà8‘V»÷Br»yB=¢XÌAr(•bHψÇÛÌÏC¥b9<„V ;çùyˆÇÛHϺñN7_¢¿ße`@d2>3; ˆ°Öð=:爃Ãì,HŸÉd00 úû]1:*žgt´Û¦ôœBAxu… ¬µ„axmÖÚîã,áå%aB`óyž÷þ,K<~f÷ö:¹Nú_tâ,{{Ÿ!eû~“~çÉ“ŸÇÍî§OîÚË—J$ ‚@kkkò}_õz]ƒƒƒJ¥Rj4*—ËòwwU¯Õœ¡‡Mòüü»³Ó'#½§Zå¯Vˤîß§P(066ÆÒÒ333LMMá8lmm199Éôô4ŽÄŸ;;†·o ¥÷2÷îYZ-v þxñ‚J¥ÂÄÄ›››,//377@EDQÀÊÊ sOŸv:þò +’IÃׯü}~N>Ÿ'“ÉP«Õh·Ûär9|ß¿&8::b||¿^ï5›L7 GCCzõúµ~yôH•JE±XLûûûªV«J§ÓÊf³ ‚@FC’T.—522¢l.'#É"ÉZÇíûöíƒÞ¼Ñ¯Å¢ý1V2™T6›•çyZ__W>Ÿ—$žžªT*I’¶··åyžº°z÷N:;û ¤U¢ðò’f³IØ&'''\\\t•`8>>ÆZ{ãï´±°Òê-™®ÎŒ1·Dú_°¢[:»™€b °aØ«ø/¢ëQÔ«€bñ» ¸ÓÙ¼Ó­q§ûì7í?ØÅ™u° ¥eIEND®B`‚routino-3.0/web/www/routino/icons/limit-18.2.png 644 233 144 1472 12573351604 14662 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ïIDAT8Ë­”ÁK[[‡÷LŒMˆ!HߪPÁ.ÄÅ[‚Jp!BÛ•R¡ Û ÿoYw.ü Ìë*å ‚ˆÐb„ˆø”Š]5Á'J+h êͽç|o‘¤Fºu`àÌœ3Ùá›’„ëºH.’ˆD~CšÇq>“H@2iH$Àq>#Í7ï…ä6ã„Z‰"ÉáÅ‹Ò[¢ÑSSðþ½åäÎÏáä¤aOMA4ZCzÛ|ï4ã%::\Âa‘Ë=D:btªUXkh—†P­FGA:"—{H8,::\‘N‹±±(Òff<Àâûàû`í­¶|`™¾06%n–)Íòü9@=ðoÈd@:¡¯/I8,B!Wtw‹ééÒÖÖª€ÅóÀóÀÚ_ÙÄÀUÖÖ@úÁôtŒîîÆ3¥×ÌÎÔüjS'àyÞmZko4µ^µŠÏžôºùg‰Å.99ÁkBÿÖÚº°1X°öøb±K¤‡?¤?õòeŠÅEãJîç/_(k{{[»»»:::Òàà Âá°ÇQ.—ÓÛwïÔ;ƒƒ†|>ê„tÈÖ€y»µE0$›ÍâyÌḬ̀°°Àéé)¹\ŽR©¿?zÄ_¾oÈf1Ò¡«ëéSYÉu% E£Q¨T* P:Voo¯$i_]]]ÚÛÛS(Õ‡7o\¥Ó²­­](’•4÷ü¹†‡‡uuu¥D"¡ùùye2­®®jggG’411¡r¹¬ÉÉI}û¦––)”\WÖ:ªÕÔ @®ëªP(¨¿¿_KKKêééQ±XT¥RQ©TÒÐÐÆÇÇÕ+™LJå²p\]^~Õ§O’d%©­µU€FFF´¹¹©x<®ÑÑQMMMillLmmm*—ËZ__×â‹J=ybõñ£××_…´ÁÊ €1\\\pss@¥Ráìì c ÖZÎÏÏoñb±ˆ­Õ꼕6~ùìø¸îlßÿ§ŸàV¬‰›†Ï Xîøì_`=ÿlÖø> sט½3÷:›÷º5îuŸÝã¦ýH¤J‚<ÂwõIEND®B`‚routino-3.0/web/www/routino/icons/limit-36.9.png 644 233 144 1522 12573351606 14667 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”ÏK›IÇ¿ï[ÉÛ–&‘(¢Ȇ²•¶OV… Š`<ÊÚKü„=/ë±½{Õ…Xì/ý/º t±9TÄVHò¾3Ÿ=$Ze¯ 3ÏÌ<3Ï3|ž¯„$\×Er‘D8ü Ò Žó™hâqC4 Žói¥½/$·í'tuQ8ì 9ÌÍ…‘^áy?ÈåàÃËÑœÁÑQËÎåÀó~ ½jŸwÚþ¡KW—H&SH_™ž†JÅÖn¶–P©¦§AúJ2™¢«K„B®èí33Ò––€Å÷Á÷ÁÚŸýj ,Ð`i ¤/ÌÌxôö¶Ó”^3;‹¦ßh`šMŒ1ø¾1·4Í&~£&³³ ½¾ú³'xÞw»¿ßz±íhŒÁZ{#C{=ZkÁ,X»¿ž÷éɽ?¥e^¾v̿Ţûw>¯P(¤þþ~•J%­®®*‰¨¯¯OÖZ¹®«b±¨·o•ˆÅœøãdžJ%â ÷d¤?rpvfâ177G2™d{{›L&C&“add„ÃÃCŠÅ"étšááa~{ú”“ 0¼{‡‘ ®>|¦±1ß¾¹-/+›Í*NkkkK¥RIÝÝÝU<—$íîî*‘HhggG¡HD[oÞ¸šš’½ÿ™ëvt kõk*¥ß”Ïçu~~.Ïó‹Å466¦µµ5íííI’&&&T«Õ499©>}Rgg§ÔÑ!¹.nÐl:zð@ëïßkäùsmnn*‰èàà@‰DB¹\N===*—Ëj4º¼¼Ôàà ÆÇÇÅ”J¥¤ZM8²R .ÀL¼xA4%›ÍrqqÁüü<áp˜\.GµZehhˆr¹ÌÔÔüÑâÒ°¾RAH+,.~½Îññ1~ L‚ àäää“ÓÓSêõ:ÕjÛâ1`q¤•[œ™6gÆZŒ1×°ÞdÎZ‹isfÀrƒ³ŸÍ4­ïCüÖ[ó À¶¢o’ÍÞ¨€;­Í;U;Õ³;TÚÿêžaÉ–z¿IEND®B`‚routino-3.0/web/www/routino/icons/limit-74.png 644 233 144 1263 12573351602 14520 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“hIDAT8Ë­”?KcAÅÏ{¢É¾&Q1ü“*µ[j-"V"¤Hjñ ,l©• )m‚Øøìü‚ˆ $EŠH, ÿ%™™ßÉKÔu·òÂóæÜóæž9÷ IHÂ÷}$ID£)¤"žwM<SS–x<ï©88’?È ‰¢QÉcs3Š´O<‘ÏÃÙ™ãîàÏç!žöxo/11ቈùù%¤™ 408gyý½¡Ñ°d2 Õ˜Ÿ_"¾H&ÅÆF€Tao 8z=èõÀ¹Ñ ¿:ìíTac# ™”)Ít1×ëÑ{·œsXk1Æ€µ!i—l¤ƒP³4AðHµÚÿ£1|ι!)Àç¨V!‘Òc¿¤ßÊå~jgÇÒíúÞø¸êõºJ¥’*•ŠÊ岂 Ðôô´jµšnnn´°° @³ ±˜““–VkHêrO:¦ÙlrzzJ"‘`{{›T*E½^ïÃC}[-˜œ´¾œóÔí* k­$©T*)‘HhvvV¯¯¯Z^^ÖÕÕ•†Êå²$ÉA?©Û•œó>h†1Ã×××9<<àíí €ããc2™Ì¨Ì¿4“Š fàÚí6///CYky~~¦ÝnìÑÇ ŠÿõÙ_}Ž/|öe`Ì?‰œs0²Å§øÖÞüÖ©ñ­óì'íßÌz/äIEND®B`‚routino-3.0/web/www/routino/icons/limit-24.7.png 644 233 144 1457 12573351605 14670 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“äIDAT8Ë­”AH[Y†ÿ÷ÊÄÌ#´ ÑUDWF7u#8KãV¤Iq“EÛÛ•—ÅÀ€›v¡ âBp!Ú2Ú.Êì„Î* Å”´’…Æ@Ä¢-Ô÷Þ½ß,¢©™—sï=‡ÿþÿIHÂu]$ID£}H‹8Îíípû¶¡½giñò]HîežÐU¡hÔAr¸w/ŠôÏûÊÔ¼|i©VáÓ'¨VñÔxÞW¤§—ÿË|‰HÄ¥­M$“½H‡ƒ„Xk¸n8äàÀ0>Ò’É^ÚÚD$âŠDBLLxHEff.K@€µßýê,pÁÌ HE&&<‰Ë6¥gd2ðƒ‹ Œï7ÁcÃð8Kðíï€oïÞéÙÕÌúñ¼Ï¶T‚Ŭµ-þŸfLa©ž÷©ÿÖoÒïlt\©@tîG<˜$±ƒƒ8=ýF¸p}]¯® 57„Âß­íç^]®¯+\8=ýÆÁAL’''qc#~¸»«ú¨³L³LCøoucÔGww~¸±‘:9Ùy&|tsSµ•?>Z´Ea–eÅŸ šçæYf¡-77>vÿlÖ4­{qa®!tˆB†žìÛ\¹!ÏÛžŸkšÖ…Y„=wv š«V*///U===µ\.÷üßI+•ŠÿœŸ«æ¡TRØCøêþ¾jq°¿o¿‡‡‡V«Ugff\\\taaÁÛÛÛ^f&Iâþ§OªEöù³Âט—/ß±´D€8êëcllŒááaNNN˜˜˜àøø˜$I8:: ÕjEããã„(ˆYZ‚W¯ÞÅôõI’€­÷Ÿçææ†µµ5«««œ‘$ *[[[ÌÍÍÑh4``âØ˜"Z-ºB ŽcšÍ&³³³,//3::ÊÔÔ···„z÷Ð6(Ë „(¦^ÿF¥þzñ€ÑÑQêõ:år™íímÞ¾}ËÊÊ ÷÷÷¤iÊ@?@ˆ*¨×¿õª©æ…µZÍf³©êÃÃ××׆,ŠÂ»»»žæjµšÍûû6ng§WͶÎÚe¶õÓ#èŠ÷‰µcOtöG„,³KØ%}²Ïs;âþ_ëÔxÖyöŒ“ö_h–hîðÖEIEND®B`‚routino-3.0/web/www/routino/icons/marker-50-red.png 644 233 144 2125 12573351600 15421 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“ IDATHÇ••AhI†ÿª®š‰£BHÀ=L‡(ÙE˜“A™K6Ù»·Œ ¬GnnÊ`¼ˆažr0 ¬'ç ¢HAf‰ ¢2‡dBWWý{¨êÉ8AÜ}P<º¨úú½¿ß{ šÏç/j­ß <{ŸµÖoóùüE÷dÁG,€_´ÖKišÎ‘äð𰘜œ„ÖÎ9H)aŒA£ÑÀ—/_(„J©º1fÀ?=œîÎDQÔÀb±hjµšm·Ûtαלsl·Û¬Õj¶X, ÷ÎdgÇQmàÔÔTÒl6I’ÖZcŽ,k-I²Ùlrjj* àM±ÇJ ¥Ôc,—Ë IÚ4eÒéÐ% iŒ_™YK—$Lºðr¹œ Rê±”Èår—0ŽcÛjµH’¦ÒkÖ’=r˜$!I¶Z-Æql0—Ë]Ž„Oœsñââ"/]º$Rêóg`uxÿX_>|ÆÆ­ýÞê*Ðé@ž>Ô #ŸÏsmmM!~744ävwwIçèHòÁ ¼?y’LSòÅ RJrpÐïߺÅ,îÝÝ] ¹Pr°•J…$™øW¯’““äÞùõ롦ÓÓ~‘äǼ¹É4€+• X @j­PÙáë08œ= <{¤)ðò%0;ëÏT*Þ¿zÕížÀ‘€ÛÞÞF§ÓÊç=x¸rxú8w¸v ØØr9àÄ OPÊû$évÐÎÎ8H)öÑò²ÿ¢¹µEîïûœ¾}#•"="㘼wÏïüHLëu’ä‹çÏ À !DQô'ŽÄ±inm‘í6íñãäÝ»þòýû^»f“œ%ÏŸ÷û‹‹tÇŽ‘Ÿ>qÏŽ—Jih‚( ÐZ?ÀòÌŒ!ÉôömŠ"ïoÞô 7o|%œ:EJI{çIòë×m®(dµÖ›X]X°$™¼~M./“ïÞ>饩Õh ’äÊÊŠ À}!D)*B\R@Z_Yñú¦é÷@çHçhCWmomqdd$ëýj/´J©… ïáPéoYkiC{ÎÍÍ™0[룣£ˆ¢¨;¡B…(Y*• µ®‡áâõÍ¢Íú=¼diiÉàvw:õŒ=ômÄZëV«U¯oˆ,›J, ¥”¿÷§ÝoGõ u˜E¸··ÇññqFÝ_BÐø‰}§oÇI6I²Z­fio(ܸq£÷·ôcë×wzzÚd½^÷CJ !.„ãÑOýú*¥Z8??ï&&&²´«!mõ_ßé `FAiˆðï±±1(¥äÿvõ þVE”Rnøµ/›#ö/GEaÅáK?kIEND®B`‚routino-3.0/web/www/routino/icons/marker-7-red.png 644 233 144 1710 12573351600 15342 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“}IDATHÇ••?k[IÅ3oF2‚@°Š ‘„ ^\ØøÄÆ‘"•«k7nR¹‹Š…M•ÖÖ`qÀMØ 2_`ݹH“b 7É "5ØŽI¼ŽßÓ{g Í“õ‡àÝ Ãð†¹gÎ=sæ>¸;55eŠÅâCïý;@@f {ïߋŇ!Ïæ@&Ì?xï·{½Þš$•Ëe³´´„÷ž,˰֒$ ûûûœœœÈcœs­$Ižá N¸EQP¥RIvvvÒóóseY¦áȲLçççÚÙÙI+•J(äÝË+ÎW£(:´¼¼·ÛmIRš¦Jâxb¤i*Ij·ÛZ^^ŽðPíÃZ‹sî z½ç`qO°°•'ɼ^¯Ç€œs¯¬µP(ªV«i§Ó‘$%I’×*}ý*}ùr=ÎΤϟûûz=IR§ÓQµZM …G8çÞj6›é0gxv&ݾ-dŒEÒ­[R¥"÷¯®$IÍf3 lß ›žžæððДËe$aL0EC«ß¾µýÑh@½oÞ öŸœœ077§ÓÓSÒÕÕUIR/”3ùz³)•ËÒÇ 79’·ºº* u€õÞNˆ8†BÞ¿‡gÏ`k îÞ…4…(Ùp¬²n·Ëåå%ιIà<ñùs¸sž< nØq ×ññ1@†µ6ÒÝÝÝÑ›Ïo_’>}’¬•¶¶6 )Ó/}ooO@fŒ‰‰¢èW@µZ-6ýHòË—}|ø0¢eîã‹‹ -,,ôÂ#øR©„÷þ`þdpz– ’uÿ¾´°0Ê~èð4þ”rY*Þû#@F#•¤8øOWWÒãÇÒ‹#,s™^¿~ÀŒ1ó9  b?°Ö èµZ­ïë;İÛíªV«åo¿1Œà18çž}GšŠz½k)†@×ÖÖ’Ð[[333DQtm 真ŸÇ{ßšÐw(röÛÛÛiìºÓPÛcl¡ê½ïŒèÇ# T*•R@ÖÚŸÇËõ öIBóø-ßsCŒè[­Vã¼%JR£ÑÈË>J›››pý[ú~Œë»²²’HR«ÕZkeŒy?äÇõuÎu­¯¯g‹‹‹yÙP¶û¯€#ú?côÃ?gggqÎÙÿ 8Ð7Ì¿DQ$kmøq¬š‰ø‹»|FŒœ&IEND®B`‚routino-3.0/web/www/routino/icons/marker-85-grey.png 644 233 144 2750 12573351601 15632 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“IDATHÇm•_hS[Æ¿µ÷>ÉIâCÒp1é”v")bm@íPGDT¼àm_†[A½à…™_®Ãp_J¢ó2b™×y«´§óbÍ‹™:¶EkLm È“´MMíù³÷žÛÜúçƒ çlßYû·>Ö¦d2‰-1!’ɤJ¥Rßj­ÿê8Î!˲4Â/Ò^¯— Ãø/ýœL&¤R)æº.( -S®µ–Zë݆aÜ´mûÇqt(¢ŽŽ0ÆšŽJ)äóyT«Umy<žÇq~"¢qR`Zk &„È4X8vO:ź»»ÉëõâsY–…\.§3™Œ\]]ýÁï÷ÿVJyJký†ˆ?vì˜Ð&„ømÛ±x<î\¸pÁسgqΡµþb !ÐÚÚJ]]]¬\.;+++aÃ0~§”ú§Öz÷õõÀß766ŽÇãqçÒ¥K†išPJ5+cŒˆ>©VJ ŸÏ‡žž¾¼¼ì¼}û6lšæ7>Ÿï_̶íïlÛþ1«c›çŒ10ÆšQsOÑüÑÀÀ€‡•mÛ?Ú¶ý?qâİeYmýýý:“”œsT*,..b}}Á`œsÔëu,,, R© T*amm Á`@B=77G†at ×u{C¡N$ 8çÈårƒiš°, ííí¸|ù20::Š––X–ŸÏ‡«W¯Â0 $ 699©F¯°,Kwuu1ŸÏ×u!„ÀÌÌ vïÞ+W® \.ãÆX^^F¡PÀ¾}ûpñâEH)± ­5ü~?:::èùóçŠ}ìÃÇn3êííE¹\Æðð0îܹƒ½{÷¢½½›››X\\Äõë×144„ùùyQ³©[>ŒqÎU½^‡ã8MÓÕÕUh­aYlÛÆÚÚÞ½{­58€³gÏ"bxxÕjœs@£ÑcL Ó4åëׯ‘ÍfYOO>|ø€G¡¿¿GŽܺu étç΃R ±X ×®]Û7o …°´´„¥¥%mš¦dþ"„`™LÆ­Õjðù|(•J€••lll `hhOŸ>d³Yh­F’>êüüùóÓ›››ëëëJ¥’{èÐ!ÖÒÒ‚àáÇxòä "‘Μ9)%Òé4fff0??£GâàÁƒW Ü4ͬã8gipp~eÆôû÷ï}òäIÕ××ǪÕ*òùE¿9?0—¦Xdf/÷×Js[Ü8?‡(úôQH4›Îº]ŽŽŽ¸¼¼ ÝnÓjµ899yl·Û’×ëh6AÚÒW¶·<Þ³³³C¡P`ww€jµÊüü<µZ««+¦§§™››Àg{¤¯¡†‡?ivV’BA r¹¬8Župp ‹‹ U*Õëuk}}]išªR©(oS¨ÙYixøS¨0DÅ¢$ÉÌÔh4433£ÇÇG™™ÆÆÆT«Õ´¿¿¯ÕÕUííí©^¯ëøøX?üÐI RÊ,P·«·ÈÌDZâ8V³ÙÔè訮¯¯U­VuzzªN§£³³³^i*™=ËžŸH’„­­-–––ˆ¢ˆååežžžØÜÜ$I²7=øÍœÜßß¿:總½Å{™á½çáá»»»>~s€g87À©>Yû`/ÒóûgÿM€½ìƒˆsX/«&à]gó]·Æ»î³wÜ´ÆZ”ØD’´IEND®B`‚routino-3.0/web/www/routino/icons/marker-48-grey.png 644 233 144 2705 12573351600 15630 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“zIDATHÇ}•ÝkSÙÆŸõÕ½³wä¤4©LÔ‹4EuÔ 1`±‚¨ŒÂà€ã½8sáÍÌá0JFr1pnÆÀ¹Sê÷…Á´çÐCQªµÖOB™Ä¤m2‘tÜ_ë‹i2Õ™9lØ{³÷o=ëYë]/ËårX—R"—Ëé|>?@Dÿö<ï#ÇqÃï"Ã0˜Rj‚1öM.—»“Ïç¹ïû €-ADWJv]÷3Ïó(²d2 Îy›¨µÆÌÌ jµ)¥XGGǰçy_1ÆÞ0Æ€@àDè•R›Ífo,ówíÚÅ3™ 3 ÊqLMMQ±X æçç?³,k[»ˆè5cŒ‹;v€¿K)ÿëºnïš5k¼#GލT*Å„ ¢?\RJ¬\¹’¥Ói^©T¼¹¹¹˜Rê€Öú ýÌmÛ†RêûÅÅÅžT*å ©H$­uÛc œspÎÁÁ÷}D" ©T*å-..ö(¥¾·mÜuÝ=®ë~‹ÅôÁƒQ;Ǩõ¾5€”D8tèŠÅbÚuÝÏ]×ÝÉè”çyÈf³ˆF£ÐZƒsÞ¼zõ µZ­í¸Z­bbbÏž=ƒÖZkD"d³Yxž":%}ßÿ8R?o9k'''qæÌ;v Ñh“““¸téLÓ„ã8èééÁÑ£GÁ9G&“á###Ôl6?æŽãP2™d¡PZëöÔËå2®]»Û¶!„Œ#ãĉ8~ü8¦§§ñâÅ €eYH&“Ìqâ¿™ãï-Šã8F:†mÛð<°eËT*œ={/^ĺuëÐÛÛÛþw‰Ã¹B7 xž×^ëׯ£«« û÷ï‡ëºPJ@Dp®ëb~~Žã´¡Ífœs-NV*‹ÅتU«P*•põêUX–…çÏŸcaaÕj–eáÎ;ؽ{78€íÛ·cbbår™L/_¾ÄÈȆpßI)y±XôÂá06mÚ„p8 ß÷Û[Ç4M„Ãa”ËeÀÜÜÞ¾}‹ÎÎN@¡PØoúQ>|øïÞ½[Ûh46¼yóÆß¶mO§ÓX¿~=úúúpûömìÝ»}}}X±bFGG1::Š»w»ûöíC¡PÐÓÓÓÂ4ÍIÏó>6l€ÖúžišK¥Òß‚ Ðk×®e¾ïƒ1†îîn¬^½¡P]]]ظq#‰6oÞŒÁÁA<}ú”nÞ¼ÉmÛþEk=ÈûId³YÉûÀ¤Rê‹×¯_ëx<Ή ‘H  µ+Ê4MÄãqtvv¢Ñhàܹs> Îù·®€@1ÆF9ç_3ÆÄ7¼z½Î9‚ h—c«î[çB¡Pðëõºêèè8ßßßÿÀomP1Æ·nÝzÚ0ŒóµZM]¹rÅÿ°ö[n…×÷ïß—¶mϺ®û¯´;wîl}Ìfff(‚{¦i~R*•b­|ƒ hŸœsT«U\¸p”R À?cãŒ1 žÏçÛ‡:ç\rÎgµÖC–eallŒ¦¦¦ „€ÖŒ1xž‡ááaßu].„8Í;@-ň|>ÞºYÒÿÍŠÅ¢ž•†aL;ŽsrppËX €ÿïåË—}xüø1ÆÆÆ`Y´ÖÇ¥”‹·nÝhy»Ëþ,_Ã0>©T*±z½N= šÍ¦PJýÀ0µs\fê½Ö XÖ²%Ÿˆ²œóQÇq)¥R3™ÌÀ“'OxúCà{Óÿ“Zùþ‡ˆ¾1MS!fƒ øòáÇ‚¥_64À¬…IÎôIEND®B`‚routino-3.0/web/www/routino/icons/limit-12.2.png 644 233 144 1445 12573351604 14654 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÚIDAT8Ë­”ÏK[YÇ¿ï’øšØ4"D:«B]t=‹"(t%BÛm]غrá?P˜M ÝëZÄÉ,j]ºI1‚‹Ø”ÅEš‰´ã¯I|ïÞÏ,’T‡20 /¸ç{ï÷˽‡ï9B’p]ÉEÑèoHó8N…D’IC"ŽSAšï Éíñ„úBѨƒäðìYé žwÆô4¼{g98€?àà ›OOƒç!½éÝwz|‰pØ%éô=¤]&'¡V3@€µ†ë«›Ôj†ÉIvI§ï‰ˆpØ©”˜šò¾07Ð,¾¾Ö^E t˜›é SS©Tï›Ò[ž>¸ :L—€1ß÷1æß4——ø.yò¤·ýšÝÇóZì=!k-ÖÚÿÞƒkwvÀóZH÷C¯¥?ôâÅïd2Æ•ÜõbQA(™LªR©(—Ë)‹)•JÉZ+×uµ½½­?s9Å"'õà¡Vp¶¶BBÚbyÀüµ¼L(bee…½½='NS*•ØÜÜ$wñáa>U«†÷ï ¤-Wƒƒõ葬ä:¡††† …T¯×5;;«µµ5Åb1•ËeIRµZ½Âãq•××]=~,nÝz(îÜ1|û†ß+îÄÄ  FGGÉd2c~Ö­X,vñçÏ1ß¿c #nß¶4?ÅÆÆÆXZZ¢^¯‡Éf³œžžrqqA³Ù¤T*áyÙl–“V«Ëk4`pкjµÊúøQ’¬$yž§X,¦ A |>¯‘‘-..jffF«««’¤|>¯á»wõ¡P°úüYÁÉIYHó¼| ` ÇÇÇ´ÛmÚí6Íf“ýý}çççqvvÆááaÿú•¿!àÕ+¬4å³®³ƒ€ÿµºF¶\óÙ/`}Ÿ¾`ß × `}¿¿tÀöæNg78iÿy’úÞö“IEND®B`‚routino-3.0/web/www/routino/icons/marker-73-grey.png 644 233 144 2644 12573351601 15631 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“YIDATHÇu•_hSWÇ¿¿ó'÷zƒ˜» ƒb›¬rE©¸ J¨Ð‚>u¬ÃCX¶‡!8{YÉÃ`/ó]ð¹JýW°à¢›e(c2m…ne©5±ÌÜ{Ï9{X“Õ?ûÂ{àÞïùÞÏùýΡl6‹M1!²Ù¬Îår£Æ˜‚ l·Ûá?˲HJùˆ¾Éf³?år9†!h MSnŒQƘw¥”g|ßÿ$ãº.% 0ƺŽZk,//£^¯)%E"‘© NÑ_DÄ(€c€ÝBˆB³ÙÜÇÑ‘æyY–…×Õn·Q.—M¡PPëëëŸ8ŽóRjÄó;1žÉd €]Bˆ_|ßß½gÏžàøñã2™LçƘ7†===400ÀjµZðìÙ³¸”òC­õ%cÌ F!¥ü¾Õj½—L&ƒ‰‰ ¹cÇ„acL7u1c†!b±&&&d2™ Z­Ö{RÊï£Ñ(˜ïûG}ßÿ4ëññqÙ1B€1ÖDcLw.„€Ö0>>.ãñ¸ö}ÿSß÷ cÌd†ëº‚ ÃDÔMÖ×ׇX,†¥¥%4 ìܹ}}}ÐZÃu]>|—.]‚”rR„aø¾ëºfß¾} ”R˜™™A«Õç°¾¾Ž“'O¢T*!ŸÏ#‹¡Ñh`dd£££ÏóØÍ›7M³Ù|_´Ûm300ÀÇ1¶mãôéÓÐZömLOO£Õj!™LâìÙ³C&“Á½{÷033ƒL&˲à8‰=zôH3l뀔¶mcaaOŸ>ÅØØ8ç8qâR©*• Êå2<σeYÝï6}ãœë AÆØ+;~ãÆ ìß¿®ëB)Ï󠵯ôô4ªÕ*"‘È+õÛl6ÁÓ̶mµ´´¤K¥:L‰ÕjkkkH§ÓÝ‚¯T*ˆÅb˜œœÄ©S§ðàÁT*±¸¸hlÛV ÀwBV(Âz½!àáÇصk\×ø¾sçΡ\.w“ !ºigggý«süرcw^¾|ÙÿâÅ‹µZ-d¾ïãêÕ«8t艔RpZk\¿~wîÜA±XÄàà †††pùòe]­V¹mÛ¥ >æ€ÖúWÛ¶ÇWWWßÑZëT*EÛ·oG*•¶mÛ@D "ô÷÷cïÞ½èííÅÐÐÒé4J¥’™››cÑhôo­õ"úS0Æ€?´ÖŸ9ŽsóöíÛ¦§§ìvÌëMÐÛÛ "ÂÆÆæææB˲$€o‰è7‚H"ºÅûŠˆøììlðüùó7ª¡ÓªÅòù|X¯×e$9ïyÞ€°sPDÄÒéô˲Î×ëuyåÊ•o‘1œsܽ{Wß¿_D£Ñß÷¿.‹Ý|xx¸ó2-//¥Ô¯¶m´ººWJéþþ~RJuS3ư¶¶† .)%øœˆî‘ €år¹î¡ÎŒ±­õ„ã8˜ŸŸ7årœsh­AD‚SSS¡ïûŒs~†ˆÎ›‘ËåÀ:›zƒïµkׂF£Ñ=K …‚^YY–eýÖn·¿=rä¶b,^3~ƒïÅ‹Cxòä æçç;5û¥¢•Ïç9³•;ß:y_˲>ªÕjñF£a?~¬šÍ&—Rž0eŒérÜê•«°åÊBcÌaÆØ­v»­„\QðR¯„7õ:ù|žýý}êõ:qSÏæh·ÛT*VVVxüèß:ÀÛ·éc¤ÉɇzòD&E.—S¹\ IrΩT*ÉÌ4ˆƒƒ5›M•J%->}ªR±©R‘›œ|)—Cq,“´±¹©……]]]I’¶¶¶n`IòÞgB‹‹zõúµ>JwîÈ$"™9õzÃÅ£§`çœ$©Õj©X,jbbBÛÛÛ*—Ëúþã‡"©Óù¬FC’L’ÆÇÇ•Ïç‡bI’¨X,J’–——µ´´¤ùùy%I¢÷ïëÅóç¦÷ï•ûõëó0›€'.//¹¾¾>ø(nµZ˜Þ{...ðÝnÆÛÙf3óÙñqæì~úÿf–™8Â?|v£,M5íðß{úæî±¾>R·Z›·Ú5nµŸÝb§ý 4^øz€ IEND®B`‚routino-3.0/web/www/routino/icons/limit-152.png 644 233 144 1440 12573351603 14573 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÕIDAT8Ë­”¿KÛkÆŸï«Äø5õG"d¢½.%:‡ íàä R;Dœý.ܱÝü´ Ú!^G©ÔMŠh;Ìh5¨P0¦h’ï÷}?wHôz{{78ÃyŸó8/Ï9B’0Æ $þ†´‚ç}¡·âqKo/xÞ¤•/$ÓÒ Ý5ŠF=$\.ŠôßÿA¡ïß;ÊeøþÊåf^(€ïÿ@zÓª÷Zz‰HÄÐÑ!R©§H%289±@ˆs–‡hæ!''–L¤©ÔS::D$bD2)¦¦|¤¯,-ÔG@€sÿÄÝ8 ÎÒH_™šòI&[cJo™žh†„õ:Ö9‚ ¸k-A­†m4šõÓÓ ½½û³gø~…ãcÖë¸V£Ÿáœ»ç\âÀq| ¾_AzÖö‡ô§^¿þ]ù¼%Œ‰D´··'@}}}ÚÜÜÔîî®ŽŽŽ422¢R©¤µµ5ÅžÓÓ†?z XÂ[­¾Âôôµ ¸Ñټѭq£ûì7í¿žÕc™•ÔÖgIEND®B`‚routino-3.0/web/www/routino/icons/limit-21.0.png 644 233 144 1462 12573351605 14652 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“çIDAT8Ë­”ÏkSYÇ¿ïuÌKŸ©V)t€#L-ô‡P(Å•vgÈ]•n£»Aúg(t‘Eþƒ"‚Iv]u1 Cµ1‹JÔ2NšÒÖ¡bLÉ{ïÞÏ,òcœÎ,{àÂ=÷Üïáœ{¿ß#$! ×u‘\$ÿ„TÄqªŒŽÂõë†ÑQpœ*R±’Ûà õÅã’Ãq¤'ø~‹|^¼°ÂçÏpxØõóyðýÒ“Þ}§‡—ˆÅ\~ˆl>RQ‘ôš—/ùýÃ3âû¤ÓiR©•J…R©ÄÐÐëëëƒäGGGÌÎÎ233ÃÄÍ›ü†çÏ1ÒkW‰Äm¥Óª¿{çþúø±677•H$´½½-ß÷566&k­úV.—åyž*•ŠF®^UéÙ3W™ŒìåË·ºt Ûj9¹{÷ôãµkšžžÖÜÜœVVV‹Å455¥v»=HE‘‰„$iäʵ¿}“§„O–IEND®B`‚routino-3.0/web/www/routino/icons/marker-99-grey.png 644 233 144 2644 12573351601 15641 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“YIDATHÇu•MhTW†ßïüÌÜ\ct˜F&.4‘Š1‰AAg¡¦Y…¸©H»è¦-E0…ÙuS7Ýv'f«ALÆE§iIŠ"™˜ˆB´ &:?êäDZޟsN&×Dí îý¸¼ç»Ï÷Þs(•JaULT*¥ÓéôacÌOžçµ;ŽcÞÉ„Ãa’RÞ%¢s©Tê÷t:Í|ß ´jÊ1ʳ]JyÁuÝSžç™H$BñxŒ±ÀQk¹¹9T*#¥¤P(4èyÞ·DT$"@ Ì£4 !rÕjµ9ú‡b­­­‡ñ¾ÇÁÔÔ”ÉårêÅ‹§lÛÞ¯”:dŒù‡ˆ?pà€Ð$„øËuÝæD"áõ÷÷Ë;wçƘ.!vìØA»wïf¥RÉ{þüyTJyBký›1f‰'“Iøåõë×݉DÂ;s挴, Zë 3ƈDoÑc ”‚mÛhooç³³³^¡PˆZ–U_SSs¹®{ÔuÝÓÑhT÷õõÉ5nœs0ÆÀƒ1&0#"0Æ „îëë“ÑhT»®{ÚuÝ£üàÁƒÇiJ&“&‘HR œs”ËeŸ7—.]"Û¶ÿÕZfŒ¹/cÀ‚ÖúKÛ¶ÿ7MMMhkkCCCˆ(04Æ ¾¾Û¶mayyÙlÖ…B’ˆˆè>Áø$2ƾ#"><<ìU*´ÖÁ„׌×~Ïl6ëW* …2{öìùà¯Ô#"ÖÑÑq!g*•мzõª¿f´^ÆpÎqëÖ-}ûöm±iÓ¦y×u˜˜˜öÞÝݽö2ÍÍÍ¥Ôß–e}þìÙ³¨RJ·´´R*ˆc år—/_6RJðÝ""@K§ÓÁ¦ÎŒ±y­õÛ¶166f¦¦¦À90xž‡ÁÁAßu]Æ9¿@Dr#Òé4ØÚͪ>à{ãÆ oqq18Rr¹œžŸŸápø¾ã8GŽÁzC¬‚Å{Æð½råŠ÷îÝÃØØlÛ†Öú!Äël6˘õÜùú‡ñ ‡ÃŸ—J¥èââ¢ÉçóªZ­r)å÷1ÇuMaãh¬;²ßs16ê8ŽBp!D®µµõðôô4SJé÷ 7|þG0¬ñýÓsβ,Î9ŸWJ}=11¥þOÿ%ŒÀ`pY%-IEND®B`‚routino-3.0/web/www/routino/icons/limit-130.png 644 233 144 1363 12573351602 14572 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“¨IDAT8Ë­”¿K›ÇßÏSã#!Z‰‚K _°‚ÐÝÐ.®¢Ìnúø87›ƒ›[ Béä:J)T)Z„ ƒ MÔHÑ&Ÿ¯y‚æÛŽîîswÜÝûNHBa"…H"•úi‡ øÆÄ¼|阘€ ø†´Û…Æ~Bƒ@©T€P.§ÞE¿X_‡ZÍsy í6\^öåõuˆ¢_HïãÿAì/‘L†ŒŽŠ\.ôƒåe¸¸p€Å{ÇSêË–‹ Çò2H?ÈåòŒŽŠd233be%BúÎæ&@ðÆ€÷<кln‚ô••ˆ™™¸L©B©ÐÃZl·‹óçÆœsòïßø^¯ÿ¿T©2èÙk¢¨Ãé)€·Ý.>4xäœ{´Y‹Ïé)DQéµvØØ°q6gggS©T8<<àää„íímšÍ&q½– v„ô…α··ÇÈÈûûû\__“Éd(—Ëär9êõ:‹‹‹ æçç¹þùÀùj¤/¡2™7zûV’B ‚@ÙlVÞ{Ykµµµ¥R©¤¹¹9Õj5¥R))Nëã§O}¿bQÊdÞ„ C”LJ’¼÷*—Ë* j·ÛÊf³Z[[SµZÕÍÍÆÇÇ566&IJ§Óº¿¿—$‘HHaH(ïõzzJÆMMMéàà@ÅbQõz]‰DB­VKwwwj6›:??×ü«W’¤ÀZÉû T§óU†$yy?”uiiIÓÓÓšœœÔìì¬vww•Ïçµ°° ÕÕU½ë·Ç¿øüYêt¾M3$···<<<`Œáêê Ûœs´Z­>îúº¡iá kŸl뀜1ÿÄÙ_àŸüx½1ÄIÿ·Ϻ›Ïz5žõž=ã¥ý|™kÚÚj IEND®B`‚routino-3.0/web/www/routino/icons/limit-28.png 644 233 144 1330 12573351601 14511 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”?K3AÆŸ;_’x(‘(*"|+ k¹J«Ð4~ÅÊÂÏ`!,mSÙ ~!(1DA‰…Eˆ¢‚E@E½»ý½Å^üƒ¯ 3»³³ÏÌ<3B’p]ÉE©Ô_¤甞Èd"zzÀqN‘vâ{!¹ñ;¡¶£TÊAr(RHE<ï‘åeØÛ3ÜÜÀÃÜÜX}y<ï©Û;ñ{‰DÂ%™Ùì(Ò%¹4bLÄçeõF#"—é’lv”dR$®ù¼‡tÎú:À+`0æc·ÏÀ¯¬¯ƒtN>ï10‡)m±¸ðFBEAEÜ=¶ÞX\i«³1<¯E½nŒ"Œ1cÞ£k;üˆÖ€=3Ôëày-¤1!í°²ïNjµÛÛÛÔj5*• Åb‘³³³‡6ä•v„Taw×x}àèèˆîîn|ßgrr’ÍÍMFFFXZZbxx˜ããc‹ØÚGìî‚Tq•NOivV²œ‘$5 ­­­éàà@]]]:99Qoo¯æææ444¤ççgÉrS’\ÍÎJéôÔ¹.J$Iêèè1F ÔÄÄ„|ß×ÌÌŒ®®®T*•t¯¾¾>I’ã8’$%’ë"ÒiÃõµ…ms@µZ¥³³“ æççY]]`||œR©@ðöf+r} é´qÕjUU.K’1Q$I:<>fee…ÕÕU‰¾|0ɧO »{©×¯%ɵ Çq411¡ááaÕëuMNNª^¯+Š"µÛmÕj5mnnjçý{ýùö­¬ä¼y#½ù¼áê €8Š(‹”ËeºÝ. ¬­­áy•J…8Ž ‚€0 ÓÒ\]A>o\Yë(ŠôP¬µr]WÝnWA¨X,jttT‹‹‹:::ÒÔÔ”‚ I¹’E’µŽ«Nç«j5I²²V’422"IÊçóêt::88P©TÒüü¼NOOµµµ•f5&«Õ¤Nç«ÙÛH2Br}}M·ÛàîîŽËËË{Z´ÛmnooSz¤þ {{ þ‡g$Ƀ”O÷{ßžùýƳÿíûð>ø1Pê󨞴7Ÿtj<é<{ÂIûÅnS,9MIEND®B`‚routino-3.0/web/www/routino/icons/limit-96.png 644 233 144 1272 12573351602 14524 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“oIDAT8Ë­”?KkAÅÏ]á&Ü&1$¤’€ÏF A°4 · )bai“TV¿„i¬RÛ¤ócˆX(DäAb# Š‚…¢¢÷Ïþ^qoò”çë2°°³;³;sæÌIHƒdD6û ©‹ã\ÏC¡“σã\ uÓ{!™ÔOhôP6ë 9lme‘öñ¼WšM8:²ÜÝÁÓÜÝ%z³ ž÷Š´ŸÚ;©¿„ë2Q©Ì" ©Õàæ&"¬ù*‰qsS«4¤R™%“®kD¹,êué7í6À'` CC°öï>i·AúM½îQ.§iJ €€(‚("ŽcÂ0$Ž“àâ8& ‚DOm€€F¤Î³y<ï™Á ù1ޱÖb­g§gãlaô˜e0Ï{FšR—V " ÇNý~Ÿƒƒ®®®‡t:ÎÏÏSøì(åˆV ¤®Îèõ’‚€ËËKæææXYYayy™Á`Àúú:¾ï³ººÊõõuqbÓëtf”Ë-©Z•$c•ÈÉɉJ¥’ŽU,µ»»«‡‡MOOkmmMÅbQ’äLMI’Qµ*årKFÆ ×•$c$I¾ïëííM›››ê÷û’¤B¡ jµªÃÃCžžJ’¬M¿w]ÉŒ¬uú*ïïïZXXÐÆÆ†r¹œ庮Z­–J¥’noo%I@â’µÎ7Ìl(///ø¾ÏÌÌ {{{looãy;;;„©]j?ÆìŸjŽäããƒûûûqu£(âññ‘(¡D"?TóGžÈ:âÜWòÚdó#Ï~ì€1—¾µfªÿ·&Ú›gœ´6ƒgèH#tIEND®B`‚routino-3.0/web/www/routino/icons/marker-17-red.png 644 233 144 2040 12573351600 15420 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“ÕIDATHÇ••ËkTIÆU÷Vú!I³èTâl"þÚFc”¬‚ÍD÷îìÅàüâj²²ˆ(;A+Á• hÜHw½R"! ¶¹úfq«Ó8âÌKÕ½Uç;ç|çqa(¶Z­Z€J¥2ïœ{ ðaÕè»sîe¥R™zvdÂð‹sn%ÏóeIšœœ4§NÂ9‡÷k-Y–ñüùs>}ú$cŒ‰ã¸eÙ5àÃή…£Qu5luuµØÞÞ–÷^£â½×öö¶VWW‹F£‘ zG¹qã†.\¸`ò<'Ž"066àõk8rvvàþ}xõ Þ¾…wï°oÞW«LNOSqN?|hŒ1¿ø‰‰ ¿¹¹Y&B’vv¤­-ivVšŸ/ÝÚÜ”’@²Vª×%¿w¯<þðA>”Åââ¢$)ßÙ)<,––†|~þ\“¤åeéôéR/p»¸¸( ˆëœ@6TÃÉ“ðþ=,-ÁÖV¨hÕ*8ÁãÇðâEyæ=DÇÆ€ïõz¶ßïS«Õ„‡8†Z ²¬T”``ôúu¸|Žƒ<ÇD?~ðXkS X[[f>ËÊçç¥3gÊý(5µšj9OSIÒÓ§OxcLJEšššÊv‹>\Ô‚tî\¹ÿö­\/^”šÍ2©¡¤¾|ù¢ãÇç¡ þ¢^¯ãœ»Š?Û“°ó燞JÒ×¯Òø¸tófi<Ü»råJ_õA›6œs€Z­V!I©$={&=y2í÷¥[·¤nW ݽ{×À¯Æ˜™`\&לµÖ ÈÛíöß‘Aï÷z=MMM z¿5ŠàŒ1Äq| ÐT’¤Ð²»üŽôÿ ç———³0[Û‡&Š¢Ý UÂDZ™™Á9×ÞÃïè@ñ~ee¥€½Ýé42öØ÷!qÎu÷𼄽¾¾®z½^”ýbÛö~ù)¿¡|²0êþ4Æ8~"{øM’$ŒDIjµZƒ°×úÕ«WGK?–ýüÎÎÎf’Ôn·ÖZcΆëÑO÷óÇqÐ¥K—ü‰'a·BØñÜÃ/pÆ# >™žž&Žcûwù ëïQÉZÛŽí‹æ;ùL+zÕZz°ãIEND®B`‚routino-3.0/web/www/routino/icons/limit-15.7.png 644 233 144 1451 12573351604 14661 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÞIDAT8Ë­”ÁK[YÆ¿÷ÌÄø*SÁLº°è¢`7‚ ÌF ±X\H)è®ÿŒvWÐ+ ÚUA™•d‘……R(TQp#6CÐ`ј—{³x‰m™Ùxà,νçûï! I¸®‹ä"‰Xì¤Uç ðð¡¡£ç Òjã^Hn'Ô$ŠÅ$‡/bHoð¼ï,.Âû÷–BÊe(Âxq<ï;Ò›F¾ÓÀKD£.­­"‘D:"†“Ô±Öð³…q“C: Ò‰Ä ­­"uEOÈd<¤}–—nK@€µ?¼y¸ey¤}2žžÆ7¥·ÌÌÔê··˜@wn­mg ªU‚ZjöùsÞ6{6„çU8:¢Ö6ˆþ׌ +<<Ï« E$½ÖË—>™©%—Ïk``@ÉdR[[[*‹ŠF£š•ïû:>>Ööö¶ÚÛÛõ›ã8cé´|õÊ·ïÞ½Ò'²YóW6K$ass“ èêêbzzš¹¹9NOOØÝÝellŒT*…#ñ÷dž¤Oùþ={&+¹NK‹:;;ÕÖÖ¦½½=]]] ÐÔÔ”úûûeŒÑøø¸òù¼VVVô{"¡?Ÿ>uí·oŠøþJ%šš˜˜ ›ÍrppÀüü8]]Ií¶tu5ˆk5) Þ û½!¾ÆÇQ¡ðBðMËËÒ奕däœÕSÄF——VËË|S¡ðBãã(|43ƒVVBÁW­¯KRO’SKq,9÷補ä$õ´¾.ÁW­¬„š™® ﵺ*I}#ÓëÉ:'I²Ö*ŽcYkãŸ?eûýAÿêªïGöRaØÕù¹$9ÓëÉ Þ‘YksÆÈINççRv/Çþ‚¿yûö5ÕªUû~p||Œ1†©©)ÎÎÎØÙÙ!fggi6›lmm‘ Còù¼§lÖz­VŠÓÓ1§j4$ÉÊZíîî*‘HhooONGétZ•JE…BA‡‡‡*—Ë*—Ë*‹úçûwI²®^—à4A:ýŠR ÀwžçEÎ9Œ1lllÏçét:Ðl6Y\\daaé\À§T‚tú•ï‹ À9G¥RannŽv»MET«Uêõ:···„aH&“¡T*±½½ÍÉÉÉ—H€ïËÇ9~Ÿ§Ç1Ùl–££#ŠÅ"ûûû¤R)...ˆ¢ˆZ­FE´Z-ÔïƒsžO·û™Î011Áýý=KKKär92™ ù|žF£Áôô4a2??ÏŸoÞ¸±OŸ ÛýŒ`Skk’d†„ÔÝÝ$IqëúúZñ°fŒÑÍÍŒ1’1ÜÚš›¿ðlØðÏž’uä’dãøžýVîÉÀß‘×=Êê xVm>ëÕxÖ{öŒ—ö_‡çG—f¶IEND®B`‚routino-3.0/web/www/routino/icons/limit-7.0.png 644 233 144 1353 12573351603 14573 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ IDAT8Ë­”KK›A†ßù"1ýˆxÍFì&q£ Ú ¸”v]PÐà(tY·’ ¡{—æˆ °B© QÄA6óÍ<]äR¥íÎsnïÌ9¼çIH"¤I$ï‘òsD_ 8úúÀ˜#¤|Ë/¤ •'ÔJ$ ’áãÇÒWÂð•øöÍs~77p~ÞÔWV ¾¶âM+_"èî##£Hß™Ÿ‡rÙÞ;^JS(—óó }gdd”în"•¹\ˆTbm à౬ïÿœ¶ <ð‹µ5Jär!©T«LiÅE€†·ûüŒµk-ÞûÎÇœsM›µE AZo÷,CÖ89i¾Ø úK¼÷`ï=¾ç990¬!ebŸ¥/ZZúà?}rF ~üü©B¡ R©¤ããc%“Iõ÷÷Ë£ÓÓSíìì(•J©`@XkÌÐS¥òN1!°½M`Ÿééifgg1ư··ÀÅÅŒ“N§¹½½¥Õ<Çö6H¢·×S­¶k!j•¹±±Áòòr§ÌÍÍM²Ù,“““lmm`ªUèíõ] I‹Åtuu¥|>¯ÝÝ]µ%Š"%“IIROOêõzǧx\ ºä½Q£!IrΩ+T(488¨L&£§§'=>>jxxX———ªT*:;;S:–$Ij4$ïM ZíPÅ¢$yã½$©X,*—ËI’îïï577§©©)e³YiaaA333’sŠI^Å¢T« )Ïê*@Ô"$wwwÔëõ·®¯¯qνº7f›y«« åÿ˳—dmëmçÜ?yö×EíÀW@¯îQôŸ xÓÙ|Ó­ñ¦ûì 7ío3Ávb¾ÞÞ8IEND®B`‚routino-3.0/web/www/routino/icons/limit-21.2.png 644 233 144 1445 12573351605 14655 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÚIDAT8Ë­”ÁK[YÆ¿¼€I^_J,B U¡.ºž¥Yt%‚t%Ôv#î¤ø ÌFh÷‚îm)TÛ ¸qSˆEb*mI»i‰°TCP“¼{~³x‰Ó:ÌÎî¹ç;—sîý¾#$! Ïó<$‘Nÿ†´J"ñž\nÜpärH¼GZÆ…ä ó„F¥Ó ¤÷ï§‘žàû]àåKãð¾‡ÃÃØ_Xßï"=âÃ|‰±1TJ‹·>3= aè€3ÇÏûa蘞é3Åâ-R)16æ‰|^ÌÌøHY^èÆ`ƒ˜ý»Fg`@åe>23ã“ÏÛ”ž2;‹ƒþ ×ÃõûÅDQ„s¿èú}½úÌ΂ôtôf·ñýk400œÃÌ03¢(ÂÌ.uÇp³F|ÿévòéO=ú=ñð¡;¨Õ¼g/^(åóyyž§J¥"çœÆÇÇefòÖÓ§2''¡ß^½ÒÄÄ„¢Ñ¨ö÷÷577§ µ´´(“ÉH’<ÏÓ‚ªÕª:îß—¤OžH‘ÈcqïžåëWÎNO§§§‡2™ LMMQk4%NÓÕÕÅää$z{ù'Ÿ‡ãcl$bܽë¨Tøýý{~~ô€x<Îìì,Ñh”ÅÅEÎÎÎ8??§X,’N§appŸîÜáOŸàäÓÒâä¤MÞ½ãì¯ÏžÑÚÚÊôô4KKK„Ãaâñ8¬­­144D¡P`}}ÑçÏë5{ó¤M!¥˜™0AµJ±XÄC¥Ráèèˆ|>Ïáá!år™R©D8ç(—Ë×Ëc˜™©wó:ÏlƒgÖÚ¼ú_©SäžÕ' ‘¨¹ €:!¯Èz |À0÷ÃÜêlÞêÖ¸Õ}v‹›ö_vLºS*q=6IEND®B`‚routino-3.0/web/www/routino/icons/limit-17.7.png 644 233 144 1346 12573351604 14666 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“›IDAT8Ë­”½K[aÆŸ{Sc¸jЂ.‚’!ÅYÐU\C3v1 [ÿŒv+"î*XÈbAé 4P—B) (d‘6à&P´Þ{ßóëpóÑÒB¼Ãû¼çã=‡ç9B’ð}ÉG™Ì ÒžWctž?wŒŽ‚çÕ¶:ïBò;qBÝD™Œ‡äQ*e^?X[ƒJÅh6áöšÍä¾¶AðéuÇßëÄK¤Ó>ƒƒbjjéœB..cæøÝ’{ÌÅ…£P霩©iE:틉 Q,Hu66#Š ŠÀ¬ºðÈÆHuŠÅ€‰‰N›ÒVVÂøñ‹"ÌŒ(ŠzÇÌ:Ÿ3¢Ÿ?‰ÂB[^éMwfy‚ Íù91˜%•ÿoÎ%?<;ƒ h#åŸIz¥—/³är.%¥>~ú¤\.'IªT*ÑÀÀ€æçç533£F£¡ÃÃC kÀó¼…BÁM—ËY{ûö•¾°·àö÷öH¥RP«Õ˜››cqqÏó8::àøø˜………—øðù³ãý{"é‹ÈfïßqÀ»ý}&''ÙÙÙéu³¹¹I¹\ Žcâ8îã««IÇß¾A6kblÌq}MwRKKKlooÐl6™¥^¯÷’\]]%øéi’ìòÆÆœ/3Oa¨®™™œs’¤ÝÝ]+ŸÏ+ C5?ñ/ä$ùq,™y¾Úí¯ªV%É$ihhHétZ’T­VU,%I­VK¥RI’trrÒÃ%™ªU©Ýþ*¤-Ö×bœ£ÕjñððÀÝÝ÷÷÷&8nnn0³>ž´³¾ÒVŸggg o:sé+ÈþI3KüþàÙ_ °(êVü+QOqÜ•UÈÊÊo xRm>éÖxÒ}ö„›öt¤ª¼Z>8IEND®B`‚routino-3.0/web/www/routino/icons/limit-2.3.png 644 233 144 1341 12573351603 14566 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“–IDAT8Ë­”?KcQÅOނƇ’˜& E‚[ÜÚÂÆZ‚$ZÚ%¥…ßÀJ0`ice‘N¿€• b ¦$e0A‘ !FÈ{ïÞß/q7û§sàÂ{g†93gFHBŽã 9H"ýŽtB$R#‡DÂC$RC:ý Éù E£¤ù|é×}§P€ósK§Ý.t:¡^(€ë¾#ì##‰©)‡éi‘J-!5ÙÜ„VËÖ~—Phµ ›› 5I¥–˜žSSŽH&E6ë"ÕÙßßßkñX`Èþ>Hu²Y—drS*‘ËxÆóð}c&3Æ„ïžAÚçr •Æ5Ëàº=ˆïc?QY¬µŸ÷ Äa0K£®ÛCÊé„b °žÀãã#ÇÇÇÔjµÏŒêõ:¥R‰ûûû0`hP,‚t"¤ å2 ÀÝÝssslllJ¥¨T*4›M‰ÛÛÛ,..r{{K C¹ RÅQ,öCëëBr$©ÕjiooO———šUµZ•$yž§ƒƒíìì(™Lj8j$ŽÖ×¥X쇘Ÿ7¼¾†pÂ:p}}ÍÊÊ »»»Mè÷ûlmm‘N§yxx}^_a~ÞˆXÌÒn3v©V«ÌÌÌpxxH¿ßg0ðööÆÙÙ«««,//szz €ÐnC,fõzU]]ÉJV’nnn...”N§U.—•Ëå´¶¶¦……Åãqe2åóyIÒ7ÉêêJêõªÝ$øøøàåù™§§'Úí6ƒÁ€n·‹µ– xyyÁ‰;&ðD7'x6"ã_b­ý¬Ÿ1;ž„?x69¾õýÿÖZ²ÿŸð¥³ù¥[ãK÷ÙnÚŸù?ºF€Z÷úIEND®B`‚routino-3.0/web/www/routino/icons/limit-4.4.png 644 233 144 1176 12573351603 14577 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“3IDAT8Ë­”±N2A…ÏNd@ ìHÄÆÆ_€Æšˆ¥-<‰/¡=±¢ó|B¢ ˜X¬ ‰A£&n»;óýÅþ(vÜdŠ9sï™sϽB’0Æ $‘ËUºxÞBvv,…xÞ©»8’YÄ -år’ÇÙYéßÿ¢Õ‚›Çdoo0™¤ûV |ÿ éráï-â%2C6+Êå}¤1õ:œ³üoé>!,õ:HcÊå}²Y‘ÉQ*‰FÃGz Ó˜Ž8†8ç¾×Ìét@z Ñð)•ß”®h6"â¬ÅZK’$ü4k-É|éYD³ ÒÕ’³C|ÿ“Ñ(½ÑZœs8ç~%ZÃÓdŽÑ|ÿéPH]Úm€„8ÆÚ”¦ñxÌííí*ÉF<ŠÒ¸v¤®îè÷¬KùÀZËÁÁ'''ÄàÉ|`é÷Aº3Ê竪Õ$ÉxÆH’...4›Í´»»+IrÎmÄñ}µ$E‘䜷ÆI²â§×ëqzz ÀÑÑ///+¼^¯§\Îfkœm¬¦µ–0 ùøøÀZËëë+qãœ# CÞßßYTæW5×u¶A¨í­w@’,Wý)`÷íó£¶Ú›[[g[œ´ÿéÁ hò²IEND®B`‚routino-3.0/web/www/routino/icons/limit-15.4.png 644 233 144 1373 12573351604 14661 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“°IDAT8Ë­”±K[QÆ¿÷*ßPcµøœDãâhþ¥Ò­ì$ Æ?@ðŸhGAÌ¢DJpsëPWA+fp%šhÑjÅè»÷þ:¼$¶´tòÀν÷|œûï! Iø¾ä#‰D"…´Šç’L«W–d<ïiµ~/$¿ž'ÔJ$<$÷ïH‚Ÿd³°½í(—áûw(—ã8›… ø‰ô¡þÞ«çK´¶ú´µ‰¾¾¤"™ ”J08gùÝâØP*Y2Šôõ ÐÖ&Z[}ÑÓ#&'¤¯,-<Ž(‚(çž¼qx`i ¤¯LNôôÔ¿)}dzàÑ<<`ã¢(jºsî©Bc°Q„G¦§AúØàlˆ øA±ˆçê@ÿ3çΘ¸Â“‚HCBZeq`ww—ÓÓS …+++¬­­qss€µ1Åb‘/Ÿ?—Í‚´*¤}òyû)Ÿ§¥¥…B¡@Etww355ÅÌÌ gggͪ¬µ òöÍk67AÚ÷õòå°FGå$ß{ñB]]]joo×ÞÞžnoohbbBaÊ#Ïó´¼¼¬Z­¦®×¯%ÉgdDêè–‹ L‘Ïç9>>fnnŽ\.G†ììì°¾¾N†ÌÎÎ’àôÛ7¸ºÂvtX_Îyz|TÃù¾¯r¹¬þþ~ÍÏÏ«··Wççç2ÆÈ9§t:­ƒƒ•J%Iž'¬õšœE`&ÆÇÙÚÚ¢Z­’J¥H&“,,,P­VI§ÓT*r¹™wïbÎ66@Úov0XËõõ5÷÷÷Ôj5*• ÖZœs\^^65wwwÇÕÅEœ·¸Øìf¬³““X7±~b-Õ…ÚûÃb‰ü¥³?&ÀEÿlÄ ÀÜ_ð¬³ù¬[ãY÷Ù3nÚ_t³=ý4IÂIEND®B`‚routino-3.0/web/www/routino/icons/limit-25.0.png 644 233 144 1535 12573351605 14657 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”ÏK[YÇ¿ï9ÍsÒ¤ÕÉŠS+‚‚"8XW’˜ÁºÊ¦íÂv7ÿY¶KA÷.*J‘:\¸p3PDí€%uãD ØÒ´˜÷rïgIfé÷üäœË÷{„$$áº.’‹$¿GšÇqÞÑÔ·nššÀqÞ!Í×âBrkuBõF’ÃÔT#ÒsÂáÓÓðê•%Ÿ‡!Ÿ¯ÚÓÓ—ž×òZ½D(äây¢­­é©är¨`­á¢Tí ¹œ!•émmxž…\‹‰t:Œ´Ïì,@°Xû¯Ö}`2³³ í“N‡‰ÅjkJ/˜œÄ€”Ëß ‚sµÖžh|Ÿ \Æ‚Ïä$H/êv—pø“Íf±`1¦¶‘åÿÄZ[ƒk³Y‡?!ÝmøEú•G†œ‡ÍŸ;;îËåeE"Åb1­¬¬hkkK{{{êêê’çyrGz¹´¤ØíÛNsg§!—ûÖÙÞnPEÚæõkþ880Ñp˜ÑÑQ:;;ÙØØ ££ƒ‰‰ 2™ ù|€b±H?}}}tß¹Ãß`X^ÆHÛ®"‘{º_¹÷ïÝŸŸ=Óææ¦ZZZ´°°  dŒQ2™T<—$­¯¯Ëó<íîî*zó¦~[Zr•JÉ^¿~k×°¥’3™Lê»æfõööjddDSSSZ\\Ôàà fff‰D4>>®r¹¬H$"IŠÞ¸¡¯_¾Hž'¹.® Ç …´³¿¯±±1e2ÍÍÍéääDííízüø±âñ¸ …‚µ¶¶ªX,êèèHê‡înéóg9ฦTÚÑÛ·ú}w×V|_«««ŠÅb:<<ÔÚÚš¢Ñ¨‰„’ɤ‰„†‡‡500 žžý”NëÇ¡!«7oä–J;BšçéS¾B¥x|ÌqMÏÎÎð}ŸB¡€1k-§§§c0ÆTßå2@…'O@š?ÇÙlÙpVÇZ½YÝoŒc0ÿÁÙ%Xðm`«”¹Ôð+•zŽÏƒp¥Ü¼Ò«q¥÷ì /í?˜T{ŒøÚ)IEND®B`‚routino-3.0/web/www/routino/icons/marker-12-grey.png 644 233 144 2571 12573351600 15620 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“.IDATHÇ}UMhTY=÷»÷Ö{õBe1´øCaH1%¤coÄ€ ¶ :»fÒ#Ì#Ò-ƒMMS›¦AÛMogk£ƒu¡eÏPhD1&¶ –S…™‰VLª¨’÷î»÷ëE§j[úÀå}ïÁ;œï|?W ¬”R( ®X,~ÂÌßcö†aÈþö¢è‹t:íFGGuç§Aç¹þ;A)fŒŽŽêt:í¢(ú"Š¢O‰™¿1Æ`dd©T 鮪f³‰jµº°^¯ãÑ£Gxþü9˜Î9¤R)ŒŒŒÀfþFÅq<œJ¥xÏž=Dk-â8Æää$„8yò$„˜ÅÄÄz{{±ººŠÁÁAŒr¹Ý¿Ÿ[­Ö0…aÈ™LF$“IXk•J/^D¥RAooo7ý©©)äóyœ?§OŸÆÌÌ ž={‚™LF„aÈô«8ÚàßöíÛqæÌd³Y¼{÷`ŒA.—Ãðð0@J ß÷7ôðZLJJéVWWÉ­5Àó<´Ö]õRJ;v ÖZLOOãîÝ»ÈçóèúÝjµ@DNù¾o+• žT===óQýíÁƒÝËC‡uRµZ­µ?ù¾ÿÙÂÂBÚZë²Ù¬°Öv»‚ˆ°¸¸ˆ«W¯²ÖZø³bZ¡X b±ØÍŽˆÍ;çÆƒ @¹\æ¹¹9H)»‹Æƒ‰‰‰8Š"’R^B\ ×lD±Xu‚5ü®¿P*•Üüü¼ò<ïç0 ¿>räÖbÍX¼Gü'''c˜E¹\FpÎýU)Õ¾sçŽÀë§O®ù¿žç}V¯×ÓÍf“gffl«Õ’Zë³&˜¹ëã:Q®^Àº+[ˆ™y„ˆ~ ÃÐ*¥¤Rª”Ëå>yúô)YkÝû„Òÿ€ ÿÅÌç|ß—RÊykí_?~ÜÝ^Â/íij»šC<IEND®B`‚routino-3.0/web/www/routino/icons/marker-23-grey.png 644 233 144 2747 12573351600 15627 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“œIDATHÇuU_hSYþ~çOîÍ "!êBv4k‰>ĬÓ]°Tl íƒ¬SèÃ0Av…}™†y)¾ìËŠ°¾ˆ/…ú¿Õ Ý8.•Š kkSAm «1š&¦Æ{ï9g¦½SÙœs¾óï÷;ß¡\.‡U0!r¹œÎçóYcÌß=ÏÛÛn· Â/0–e‘”ò?DôC.—ûW>Ÿg¾ï€Z%åÆeŒù”ò”ëº_yžg¢Ñ(% 0ÆF­5J¥jµš‘RR(ó<ï"zMD€˜1FØ.„(4›Íí±XÌïííeétš,˧h·Û(‹¦P(¨jµú•ã8TJõc^ãÝÝÝÀgBˆ»®»=™LzGŽ‘Ä9‡1æWCxuƘ`Œ-i­;ŽƒééiS,Á9‡ÖDÏó066æ»®Ë8秈è<¹j#òù<ØÚd¿Œ±o‰ˆOLLxõz=H©B¡ —––„eYÛíöH__ÖbÕX|BøkYÖùZ­&/_¾ìÀüü<¦§§á8´ÖB|˜œœäÌúçÊ×/~Ë_˲¾¬T*±z½næææT³ÙäRÊïŒc׉úèë¬û²ßs€1öS»ÝVB.„(¤ÓéìÂÂSJéO ?ºþoذæïmc̶msÎù’R꯳³³PJáÿákN¿©Ú’ØIEND®B`‚routino-3.0/web/www/routino/icons/limit-163.png 644 233 144 1440 12573351603 14575 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÕIDAT8Ë­”=H\[Çÿ÷š½»^¯nDÙM!æ ºv©,"(h¡që@ÅÚZxð!éÅNØTX ÉBºM `À¯Æ€ q%jîÞsÏïû¡$)803gf8søÍIHÂu]$I¤Rÿ ­â8_éè€L&¦£ç+Òjý^Hn=O¨Q(•r …Òk|ÿ'óóðþ½åô~ü€ÓÓš=?¾ÿéu=Þ©çKxžK2)z{Ÿ"0= ''1`°6æ¾ÔlÃÉIÌô4Hôö>%™žçŠž13ã#}ci ,QQÖÞ†,²´Ò7ff|zzêmJo˜¨b & ‰­ Žc¢("Žã;û×/âjµ?; қƟåñý ûûÖ„!¶^ÈZÛÔvSŒÁ‚e|¿‚”oùWúO¯^=×Ë—1Q亞§R©$cŒ2™ŒŽŽŽ´¾¾®T*¥\.§½½=‹E%[[•Ëf?Žïß[U.·©Ì»w1qÌææ&‰D‚­­-†‡‡™œœdbb‚ÝÝ]²Ù,…B'¹Ÿ>~¬uþö-HåG ‚g•$ׂÇQ&“Q:ÖÎÎŽ555¥ÁÁAA ååeuwwëøøX¡1’ä2:*Á3W®‹Ï?ß¾Y>~ÄHèåË¢Þ¾•“|odD¹\N€$iuuUÝnWãããZÇZ[[ÓÄÄ„NÃP½Ÿ?}½{'½xQ¯^Y¾gÈÔìì,FƒÝÝ]r¹KKKLNNr~~žpvÏ ~ý 6“±¾œóÔë%™s²ÖÊ÷}MOOëøøXWWW:::RÇÚÚÚÒÌÌŒšÍ¦þ J##rÆx g1X€R©ÄææfÂÑÆÆ•J€b±ÈÅÅóóód2ªå2w`i4pÒARMÀ`-ív›‡‡‡¤zN‡v»µ–ÛÛ[œsc¸¹¹!îvû¸å多}œô•ýD OÍ9×—ˆµØÿÑÙoà☧‡BMk q÷¨VuÀ³öæ³NggÏ8iÿŸEµTV¤ïIEND®B`‚routino-3.0/web/www/routino/icons/limit-21.6.png 644 233 144 1500 12573351605 14651 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“õIDAT8Ë­”ÏK[YÇ¿ïeLÌãM1%’]¦ …FJˆ‹,*BÚE¡±Ý ÅÀa–íÎ…ËéÊÒbKvºt#ƒ©`Iƒ0d¢0†€BŒ$ïÝû™EL¦µ[\¸çžß—ï÷IHÂu]$I ÿ„´Šã|ddnÞ4ŒŒ€ã|DZ½´ ɽŒê'v=Fz‰çµX\„wï,ÇÇÐlÂñqO_\Ïk!½¼ôw.ã%¢Q—XL¤Ó·>33µšB¬5|)==¤V3ÌÌ€ô™tú±˜ˆF]‘J‰ÙY逥%€` °öÿÓ tXZé€ÙYTêrLéÅ"ºA§ƒévÍ„aˆ1_7h‚€ ÓÁ@—b¤Wý?»çÙJ c°Öb­% C¬µW&íÙè°¶RÏ;CºY–~çéÓ¬óä‰Ù/—Ý?ß¼‘ïûJ¥Rr]W[[[2Æ(‘HÈ#×uuxx¨?^¿V|hÈù1“1Ôjqgw7¢PÚåÃþªVÍ÷žG>Ÿ'N³··G©T"‰°¶¶6è¬Ùl’Íf) ürïŸÞ¾ÅH»®|ÿŽòyÕ>}r}ñB›››ò}_;;;ò]>ü‚×ÊÍkÝ׺ϮqÓþ7FJ1vÖÀ{IEND®B`‚routino-3.0/web/www/routino/icons/limit-20.3.png 644 233 144 1537 12573351605 14657 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”ÏK[YÇ¿ïÅj|Mjt“šM þhüA±àBœÕ®„Š`wµÝØî†â?0(¸i÷.fc§‹‘bÁ ‚ˆÛBp,•6DwA!U 阼÷îýtaìèÀì¼pá|ï=ç˹—ï÷IHÂu]$ID£mH 8Î' hi1$à8Ÿj÷BrkuBçDѨƒäðèQé%žWfzÞ½³Âׯpxx†§§ÁóÊH/kùN­^¢¾Þ¥¡A¤Ó·vƒbÑ!Ö.®3R,ÆÆ@Ú%¾ECƒ¨¯wE2)ÆÇ=¤/ÌÌTK@€µÿîó3°@•™¾0>î‘LÖž)½bb~P­b|c A`­½Ô ñ}‚j> ½:ÿ³.<ï›-°`1æ'Ñ9‰µöR\K8ƒ…xÞ7¤®ÈoÒOŸþâ9QÓR$"'A&³œœð÷çÏ4F£ÌÏϰ¶¶FOOÅb‘¶¶6Ö×× ÃÅÅEúúúèéêâ÷ׯ¡R!¸~ݺ¦\ÞÖ‡zÿñ£ }_+++jjjR†Vgg§²Ù¬úûû500 ¡¡!¥R)% uݾ­ìãÇV¹œ"ß¿o içÏù£ý}ö÷÷988àôôk-¥R c ÆJ¥ÖZÂ0äè舠Ryö ¤…Ÿ:£P8SvMgÖZÌÿhÎÆ`þ£³K°àÛ ÀžYæ²H/Æaxžãóðá\©7¯tj\é<»ÂIû5øcɼ5áßIEND®B`‚routino-3.0/web/www/routino/icons/limit-13.0.png 644 233 144 1444 12573351604 14652 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÙIDAT8Ë­”OK›YÆŸ÷U’ðFM¨Ä€.„Na¬ˆÚ…¸¨Rf!¸ ªqé.~?ëfçÂO ´…¸™ì\\¦TŠ"ÂtÄ€ J­!¹ï½¿YäÏÔ2K/\î9÷žçpÎ=Ï9B’ð}ÉG±ØoH{xÞ’IxöÌ’L‚ç}AÚë¾ Éïâ„zŽb1Éc}=†ôŽ ¸'Ÿ‡bÑquõ:\]uô|‚àé]×Þëâ%"ŸhTLN>G:#“‹ „8gùyuô‹ K&Ò““ωFE$â‹tZd³ÒW¶·Z€Ã0œûo÷îÀ-¶·AúJ6NwÓ” ¬­´ÃV Û`­Åƒµ´í6¦ÕÂA›·oA*ôþì%ApÇÙ!8×uäœû%C×?s`-œ«V!î^ i­-„år™óósNOO) T*•~¤Õj•ÝÝ]þîØ….ŸiOHŸ88°äððF£A"‘ —Ë111Áññ1×××ÌÏÏ377ÇÔ‹4Àòñ#Vúäkdä•Þ¼‘“|o`@©TJÎ9…a¨mll(N«ÙlJ’J¥’¢Ñ¨NNN4œHè¯÷ï}e2rñø+_(‘“´žËiffFõz]©TJ›››ÚßßW£ÑP"‘$…a¨¡¡!IÒðȈ~ü¢QÉ÷ñ圧v[½eŒÑèè¨ŽŽŽ´¼¼¬b±¨x<®J¥"IW­VÓåå¥þùöM¿OMIß¿ËÏ×ÝÝg•Ë’ä$ixxXZYYÑØØ˜’ɤfggµººª……---iqqQÓÓÓú3›Õ¯_;•Jòïï?÷« „XËíí-Ífc µZ c Î9nnn°Öb­íÈ­V·µÕ¯f‡gÕj‡ÙaØçS ÖÚG<³Ö‚µØÿáÙ£pÆÐsø+yûrÒ%w›µµŸ:àI{óI§Æ“γ'œ´ÿçSjú©M¨?IEND®B`‚routino-3.0/web/www/routino/icons/limit-32.9.png 644 233 144 1546 12573351606 14671 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”ÍK›Y‡ï+M4ÖH A#ŽªEì¢+;qãÆ4\TÛnÿa\¶›€}±S§­;tëJ—±øA;®¢F ´Õ ÉûÞûÌ"qª³öÀ…{î½çœ{ïyÎ’„ëºH.’¨¬ü)…ãlP[ uu†ÚZpœ ¤Ty_HnÙNèÂQe¥ƒäðøq%ÒsB¡S&'aqÑ’ÍB.ÙlIŸœ„Pèéyù¼S¶—\‚A· }a`2øXk¸,%Ý'“1 €ô…x¼…`P®ˆFÅÐPé333Àâyày`íq±(03Òg††BD£ågJ/Á@Ñ+0Å"Æ<ÏØ«4Å"^¡€"## ½¸ø³»„Bßìöv)bÙð²k-ÖÚ«sc°`íö6„BßîVü*ÍòìY·óô©ùksÓ}ùê•‚€b±˜Ö××µ°° p8¬h4*k­\×Õææ¦þxóFõ‘ˆSwçŽ!“©rÒé )Íû÷üË™º[·H$´µµ‘L&ihh §§‡x‚7nðra|¯ºÚ¸~±è(ÖïïÞé—‡µ¸¸¨h4ªT*¥ÁÁAinnN¾ï+›ÍêääDíííêííUm$¢––)Ÿ—Ž[‘ÏÒ‡êO$ìO·o«¦¦F]]]ŠÅb:>>ÖÒÒ’š››5??¯ññqåóy%“IM~TÅéé'!¥˜šð½ósŽŽŽð}Ÿ³³3ÙÛÛcŸ|>O.—ÃZËùù9Ø>SS ¥®pfÊœcþãêÿb­Å”93`¹ÄÙ H$ŠÖóÀ÷¯zX|[JH‘DâR\km^k׸Ö~vö_O m–¡O—IEND®B`‚routino-3.0/web/www/routino/icons/marker-92-grey.png 644 233 144 2715 12573351601 15631 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“‚IDATHÇu•_hTÛÆ¿ý/çÌ1ŠÃP N£3Ê$–›F ¼ó’r/Ì}©H+Ô‡¶”‹¦0o}©/}õ­˜ÖFq"j'iI‰8qü‡ Œhf4'ÍÙçì½ú`27êíöÞkýöÚk±l6‹Uq)%²Ù¬Íår½Dôç :}ß' ?ˆÇaJ©»Œ±ï³Ùì?s¹Ã,°USAD†ˆ¶*¥Îi­¿ ‚€¢Ñ(‹Çãàœ7­µ˜E­V#¥kjj ‚àwŒ±9Ƙ`$ND@«”²P¯×[c±XxäÈžL&™ã8ø\¾ï£T*Q¡P0ïÞ½ûÖó¼ŸcŽÑ Æ$-RÊk­[‰DÉdÔÎ;™DôÅ’RbÛ¶mlÏž=¼R©oß¾)¥~a­ý;½étþº¼¼|(‘H'NœP®ëÂZÛˆŒsÆûˆ–ˆ`Œçyèìì/_¾ Þ¼ys]÷'‘Hä\kýµÖú»X,fûûûÕ7!8çàœƒˆfŒ1pÎ!¥lÜ÷÷÷«X,fµÖßi­¿‡þ›ïû-étš‰3Æ@jµŠÇCkÍ›7c¨T*xòä –––FžçA)E¥R‰)¥Úd†_E£QÚ·o!¦§§144„ææf,--¡»»}}}û7bqqíííÈd2€d2ÉGGG©^¯Å}ß§x<Î"‘H£d®^½ŠàìÙ³8yò$¦¦¦P­VqóæM¤R)œ9s§OŸF±XÄ£GÑÆãqæû>ÉïðCc†a#µM›6! C”Ëe¤R)ìÚµ k¹®ûI ¯î¹BØÅÅE„PJ¡»»ÃÃØ™™ÁÜÜVVV „@oo/‚ Àää$nݺ…ŽŽìÞ½»ñ€õzœs+]×5ÏŸ?Çôô4ß¿?ˆ===hnnÆ‹/ÐÕÕ…±±1xž‡z½ŽóçÏ#ôõõ!•JÁZ Î9fffðìÙ3r]×p’RòB¡ÎÏσ1†ÁÁAÔj5d2pΡ”Bkk+.\¸"©S§ÐÑÑ­5ˆa"ŸÏöQçÅñãÇ'VVVÚÞ¿ŸªT*agg'B`ddccc(—Ë8vìš››1<< ­5nß¾ÑÑQܸq;vìÀÝ»wm±X‘Hd:‚_²Ø®”šøðáÃO{zzl:æsssxõê¶oߎ­[·Bk§OŸBk Ƭµp]óóó”Ïç™ã8ÿ%¢ŸÑCÉ9—^YkåyÞèÄĵ´´`ï޽زe c "455¡½½ý“Ÿµ¼¼Œ‘‘‘P¡8çÖÚ‡$PŒ±1Îùïc"ŸÏµZ­ÑÚŸ·Ö6\¹r%¬V«Êqœ¡T*õ@¸VdcŒwuusg¨V«©Ë—/‡k_ó³:„“““vjjJnذ¡¬µþã;w½@:th-%6;;KƘÿ¸®ûÍëׯcÆÛÖÖÆŒ1ÆÂ9GµZÅÅ‹I)Åüš16É“ ð\.×hêœsÉ9/[kOxž‡ññq*•JB40A€ÁÁÁPkÍ…çcCÔ*Fär9ðµÍª¾à{íÚµ`aa¡‘z¡P°årY:ŽóÐ÷ý£Gb½!VÁâ3ã/ø^ºt)€û÷ïc||žçÁZû[)åòõë×Z?nÄúÃñuç›J¥[XX b±hêõºPJýÀ 58® ê“Ñ X7²%€ˆsÎÇ|ß7RJ!¥,$“ÉÞpcŒýÜð“ôÃßÑ÷®ë !DÙó›{÷îÁƒÿ§ÿ'1ÖÞü»NIEND®B`‚routino-3.0/web/www/routino/icons/limit-21.1.png 644 233 144 1376 12573351605 14657 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“³IDAT8Ë­”±k[IÆ¿}¶žìEGœ`ðA®JaCÀ}¹Œ18ªŒ[%Ýüg$àÂ… w \TºRq‚ëT8(Á.„l8L@"BÆzûæwÅ“tw×y`agvføvæ›’DEH’˜™ù ©ŠsMææàÁƒ”¹9p®‰T½ )Å ÍÌ8$G¹<ƒô ïûT*ðîqy ß¿Ãåe¦W*à}éÕÈßâ%â8"ŸÅâC¤¯¬­A»³”K¦Ú픵5¾R,>$Ÿq‰…±¾î‘NÙÞ¸Œ$$³ÎØܰ½ Ò)ëëž……Ñ7¥×llÂ0¹¹!'`B¤é!IHaȳg ½×ìÞ÷¬ÕÂÀHSÌ 3#„€™q[BXÂV ¼ï!=RÕ*€ðççÏìììÐl6'õz³³³QÉl’¼^¯sÖj«T@ª*HŸxÿžß¾¥¿xO©T¢X,Òh4¨ÕjLMM±¿¿@’Õ‹ƒƒâ8fÿÍ€4yû¤O‘ …Ç*•Ôþò%úýåK©P(èøøXÞ{ÍÏÏËÌ$I€ÌLιÌîœ$EzòDºwïñôT.‡õûnãéSýzÿ¾–——µ²²¢­­-Åq¬¥¥% I’sNf¦r¹¬½½½‰]¹œED–$.ŠcœžjuuU›››ÚÝÝ0Aã2:??W𦒔¡ù(I$3¥ýþ‰>|І…áP‡‡‡Z\\T­V“$åóyÍÎÎJ’Êå²z½ž$É{¯Üô´$™«×¥^ïDHU^¼`á¯N‡N§ÃÅŃÁ€n·Ëõõ5WWWÎu»]®ü<žusÌ3²6· ú’ùýijÉ -I°ÆÜúéÂØçÖÜélÞéÖ¸Ó}v‡›öoñÊt—ØB.IEND®B`‚routino-3.0/web/www/routino/icons/limit-3.6.png 644 233 144 1325 12573351603 14574 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ŠIDAT8Ë­”¿JkAÆ¿s¸$ñ( ‹€·K+‰vŠX¨`£¢7°5½µ…éòöâŸÂ"  " ‚‘Šž³»¿[œ¯¹r»,,;;ûÍìÎì7#$! ß÷‘|$‘ËýF:Àó®„|Þ28žw…tž ÉOí„:Žr9Écu5‡´O¼³³µšãñÚmx|Lö;;ïHû)ÞKí%2ŸlV‹cH7,-Áý½ ÎY¾do¸¿·,-tC±8F6+2_ ‹åå©N¹ ð 8ââœû;;:pÀ'å2Hu–—†‡Ó0¥ ++Æ`£ˆ8ޱ¶ûaÖÚDE`L‚_Y©ÒÉÙAðÊõuHú™ûZ;2@Šs\_C¼"Mé€Ý]㢀z½N¥RáüüüëEFƒJ¥Âååeâ0ÁvwA:ÒÕ*,@³Ù$ŸÏ³¶¶Æèè('''´Z-fffX\\¤T*qww—\–j¤‹_ ÃIÍÍI’/IÆíííiddDÍfS’¤ããc5 -,,hjjJ…BA’äI¾ææ¤0œôåû(“I<ÆÇǵ¹¹©££#½¼¼( Cu.) šÕáá¡NOO%IN’2É÷ñ圧(’•$ÏSµZU©TR­VS¿ÎÎÎ$I¹\NÚÞÞÖÐÐÔ!½¢HrÎûÊ™‹s¼½½1??O†¬¯¯s{{Ëôô4ív› úúúØÚÚ"Žc°6±KsÖõ›)!‰ã˜§§'â8Æ9Çóó3Î9Œ1´Z-L‡> ¾ë7»yö¬ÖÚ.ž}éû/Ï~TÆtô_9Åü¬€žÖfO»FOûY;툴ˆ?BFzuIEND®B`‚routino-3.0/web/www/routino/icons/limit-7.3.png 644 233 144 1355 12573351604 14601 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“¢IDAT8Ë­”¿K[QÇ¿÷ &} &+˜A±SÀÉÑ¢‹¸JãZPÐ?À Ð±w nÙÝ4‹› &¤C)!‰Ekî»÷Óὤ‚íæ;œ{¾çÜû=|Ï’DH’H§ß!mcÌW2Èå™ ói;‰ )Hò„º…Òiƒd(•ÒHŸ Ã_¬­A¥â¹¸€Û[¸¸ˆýµ5Ã_HŸ¼Iò%úûR)166ô…8;s@„÷ŽçûggŽ…¾166A*%úû12"ŠÅ©ÎÆÀ౬ïÿžîxà‰ ê‹!## Mé KKo-ö÷o¬µXkñÞ÷>æœÃZ‹ët Š:,-ô¥Û³aØ¢ÙŒ_ŒA/ìyQã<Í&„a ©Ð÷Qú¤••÷þÃg¤àû*—˪×ë:==Õàà ²Ù¬Œ1j4ÚÙÙQ*•Òh>/¬5æí[§Ÿ?ßèø¸OHÇìí8<éçåå%6Á%øˆõu¶ÿ«³ºò¾×;ç¾; Ïtöbˆ¢® ÿ)Xï}¬þNÀ«Îæ«nWÝg¯¸iÿº  K?Y¡GIEND®B`‚routino-3.0/web/www/routino/icons/limit-131.png 644 233 144 1314 12573351602 14567 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”¿JkAÆ¿³j GÂñQAðVA@¬+±0¶vú>µé}ƒ€E쬬Neãõ‚ˆ ÄÆB°H0 GrÎîþnqNÔ\oéÀ²ìÎÌ·3³ßŒ„$Œ1HI”Ë¿N‚&'azÚ19 ApƒtRè…d ?¡P¹ Ôëe¤cÂðý}hµ<ÏÏÐéÀós~Þ߇0|C:.ìƒÂ_¢T2Œ‹ÅÅ%¤¶¶àéÉï_%?[žž[[ =°¸¸Äø¸(•Œ˜›ÛÛ!Ò‡‡}À“eeàýçÜú‚tÇövÈÜ\‘¦Ô`g ÅZl¿óçY–áÜg6MqišÛïì€ÔÔ¬Fö¸¿ð¶ßÇ@ƒý3Kµ6¿ÏÁ=÷÷†=¤šN88°>8Ži·ÛÜÞÞÒh4¸ººúã˜ÇÇGŠ|- é7Í&€Ã9NOOåììŒn·KEìîî2??Ïåå%çç猌ŒÐÌ}ÈÀÑl‚ô{TQ´ªõuI2ªÕª¼÷²ÖêèèH j·ÛJ’DƘ}!FëëR­ƒJ%I’÷^õz]+++êt:ªV«ÚÛÛS³ÙT·ÛU¥RÑææ¦–——•$‰>¤T’ŒÁÈû@iª¯’e™ffftqq¡µµ5µZ-MLLèúúZ’d­²WšJÞF½Þű$y¡W*%I¢ ÍÎÎjjjJµZMõz]’E‘ÆÆÆP^q,õz†~³ $¯¯¯¼¿¿çÎ2^^^È Ý>§ÇÐoñ k‡x5 «sn˜w¹Ý7ž}ëÿð¿äµvÐVÿtÀöæNg?8iÿ_f¤¸‘?IEND®B`‚routino-3.0/web/www/routino/icons/limit-8.0.png 644 233 144 1317 12573351604 14575 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“„IDAT8Ë­”1K+AÇÿwÅ%œ  ‚ øšXië´VÁB;+ýñ[ÄÎÂÎÒB°ÒÆÂ  ŠÂÃØˆB”¨ˆ"äîv¯¸Kžyòº,,;»;3Ìüç?#$! ×u‘\$‘NÿBÚÅq®…±1Ãè(8Î5Ònò/$7±ê9J§$‡••4Rßÿdc-­¼¼@«ß76À÷?‘ꉾ“ØKxžK*%¦¦¦‘î¨V¡Ù4@„µ†ï+¾G4›†j¤;¦¦¦I¥„ç¹¢PKK>Òoj5€.` CC°öïÔj ýfiɧPHÒ”¶Y^ˆ"L†!Æ fŒ! ClBÅúËË m÷0›Á÷ßi4âDÂ;™íŸrìÌÒh€ï¿#Íi—ÍM€È———ÔëunnnˆbC;;;ÜßßÇNcýˆÍMv…tÁþ>€““òù<«««LNNr~~@»ÝfnnŽÙÙYJ¥¯¯¯$àö÷Aºp•Ë•U©H’+IÆù¾¯ÅÅE‹E}||H’Ž•J¥tuu¥l6«££#I’‘\U*R.WvåºÈóÔ[NGÚÛÛÓóó³òù¼$)Š"e2IR6›Õ××WßFž'¹.®¬u1ƒ%haaA§§§ÑÙÙ™‹E===éññQ*•J’$G’‚@²ÖécfÌnoo)—ËŒ³¶¶F³Ùd~~ž··7Ö××Éd2lmm‘T¾a6PÍ„t»]Úí6Qa­¥Óé`ŒÁÓ—ª9À3†}>c¸ÕsbŒù/Ï~tIDÿ·/':?;`¨½9Ô©1Ôy6ÄIû†ˆý˜îÙIEND®B`‚routino-3.0/web/www/routino/icons/limit-128.png 644 233 144 1445 12573351602 14602 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÚIDAT8Ë­”½K\[Å÷Ž\ÇËðf…¤ ¢µ{…NãG#BœF‹@ --ü¯’¤l-b‹€þÁH qSD VÎE!à@xÜñžsÖ+füà%¥ œ}ÎÞ‹}kmïû_€Òéç‚y^MÙ¬”ËYe³’çÕ;{~§qG”N{O¥RZðNaøKkkÒ§ONWWÒÏŸÒÕU;^[“Âð—à]'ßëÔƒ‚ÀWw7y&ø¡ÅEéòÒJ2rÎê1Ú±Ñå¥Õâ¢?42òLÝÝ(|Ôß––BÁwmnJRK’S’HI"9÷°îÎ$'©¥ÍM ¾ki)Tç™ð^ËË’t+cdZ-Yç$IÖZ%I"kíCDz··íüåe ÞßýÙ …aSçç’äL«%×!rÎÝïïˆîaŒœät~.…aSð"õþáÍ›¿yýÚ*I|?8::ÂC.—£V«Q.— êÕ*{{{ü•ÍÒß×ç)Ÿ·^½ÞÃéi Á©>~”$+kµ¿¿¯T*¥ÃÃC]\\¨§§GÅbQcccÚÚÚÒðð°VVV444¤“¯_Û ø Á©OoïK¦§|'áy…BT*E½^gccƒJ¥B&“¡Z­’Ïç™››cpp[-_ÓÓÐÛûÒÇ÷Eàœ£T*1>>NEÌÌÌ0??Ïèè(,,,ÐÕÕÅîî.××× ¼ ß—s··<†1†L&CEÌÎβººÊöö6år™©©)*• arrrÒn¢Õç<ŸfóŸ?8œ C2™ ÇÇÇc888 ¯¯b±ÈÙÙ¹\ŽÉÉIJ¯^¸Ô—/Ðl~C°£õuI2AêææFq+Žc5 EQ¤(ŠDZ’$Q£ÑPbŒdL»n}]‚ßtÖIø#¬µ÷º³Iò›Îþè÷ˆðN¸Åëlõ?<©7Ÿtj<é<{ÂIû§*CܱÿIEND®B`‚routino-3.0/web/www/routino/icons/marker-47-grey.png 644 233 144 2612 12573351600 15624 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“?IDATHÇ}•ÏkTYÇ¿çþ¨zU/¢/O´üEÚBƒ”¥ÈÙHl°WŽpј¦Î,zÓÓ=‹¡º©E³ÿg9–bñµpŠÌš€&1‘ÒH vÙ‰¦Ò%•ñý¸÷Ì¢S¯»g¾páÞïûÎùœsÏ£J¥‚u ¥*•Š­V«0ó_¢(úU €ð“8N“Öú}Y©TþQ­VEÇ`€ÖM%3fÞ©µ¾†áÇQ±çy400!Dâh­ÅÂÂÚí6k­)•JÕ¢(úœˆ¾'" À(‚™ €ýJ©F·ÛÝïû~|òäIQ,)Nã]A€ÙÙYn4æõë×g³Ù_cN2ós"òĉ `¯Rê_aî?pà@4::ªóù•Ëe½mÛ6Xk“ȈhfFÇØºu+Êå²ÎçóÑÚÚÚ{Zëo\×…ÃðÃ0 ?ñ}ߎŒŒèÞK=!ˆ(Ù÷–R*y>22¢}ß·a~†á‡Š™¿Ž¢ÃÃÃð<ÖZ!ÀÌ "4›Mlß¾žçannƘČ™±gÏø¾R©„7n@kýµŠãø}ÏóøÈ‘#¢MÏxff—.]B¹\†çy¸yó&Þ¾} )%`eeçÏŸ‡ïû(‹b||œ»Ýîû*. "“ÉÀZ›ð{ùò%nݺ×u.\3ÃqŒ¡Óé X,ÂZ ×u100@>´âÇàĦ¢A€Z­†B¡×uE@)ÇqÐl61??3gÎ$zYBJi;¢(JXݾ};vìÀéÓ§†!´Ö›úôÞ½{8zô(úûûTÐív!„°ÂqóìÙ3;== "B«ÕÂää$Þ¼yƒZ­"B£ÑÀ“'O ¥ÄãDZ¼¼Œ¡¡¡$J"Âüü<ž>}ÊŽãà+¥”h4q§ÓA__Ž?޾¾>Äq )%ˆ(IñÁƒØ»w/<Ï3CJ‰(Šp÷î]C?êo"—Ëý9•Jý}eeE]»v-Þ²e Ξ=‹ÑÑQœ;wÝn¥R ‡B†h6›LæÀ:.ûâÅ ™J¥f¢(úB;v ÖÚoÇiµZýÆ{ðàAŠãD„]»vaß¾}Èd2`fô÷÷cpp™L¦×v\¯×E6›ýµö}'‡‡‡ý`FkýéóçÏíÎ;E.—är9d2™¤º¹\Žã€ˆÐétpùòåØZ+¥”p €bšˆÆ…¿'"yçÎhuuBcž½”{çz½·ÛmJ¥®>|ø¯€¸× ‰¡¡¡‹étúJ»ÝÖׯ_ß½ûÉ4÷ïß·“““ÊuÝÅ0 ÿ055•|L–J¥^kÐÂÂc¾uç£V«å÷øc’y „Àòò2®^½ÊZkð["ºOD €Q­V“Ì„J±h­-g³YLLLðìì,¤”ÉŽ¢µZ-ÃPH)/Ñz#ªÕ*Do³®ÿˆ]\\TétúßAüéÔ©SØhˆu°xÇøg|ÇÆÆbxôè&&&Ífa­ýL)µV¯×%ÞÈ\n<üßt:ýÑÒÒ’¿ººÊÓÓÓ¦ÛíJ­õjÌœpÜ6—À†_¶3ó°b<£”’J©F±Xü`nnNc컆›Òÿ =¾ÿdæ/Ç‘RÊEcÌ簾¦`ŒÁÿÒîØ¡T¬3IEND®B`‚routino-3.0/web/www/routino/icons/limit-68.png 644 233 144 1313 12573351602 14517 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“€IDAT8Ë­”?K\_†Ÿ{ósÕ« ÆÁ?ˆ‹”ÁJ-¶-d müëðc(X "ØÙ¥¬´^L JÀlg!²`±„Ý{ïyRÜ]ÿðK:œ9sæ™sÞŒãXˆ˜¢ŽŽêǹ££E?„î!îú!= HˆÜÚöL’ßÖjúõkðþ^õþ¾Ðk5M’ßÂ^÷~ÔõK¥Øþ~œý$ürcCïîr53„Ü×Rè™ww¹ ¿œýd?–J1NL`µš?ÝÝUm«Á4Õ4Õ^VïLƒÚvwWá§ÕjâÄD·LØwsSµcšjž›‡`Úé˜çEryž›¦i¡gY±´ãæ¦Â~ïÍ>›$-oo‹ˆynÁÂsu=À—jƒgÁÛ[M’–ðáÐÕÌ4}i4îïï{uu¥ê·oßÜÛÛóúúú°(9sgGááÊÓSÕ<F]YYquuÕõõuŽŽœššr{{Ûééiëõz‘q»­š{zªp32ò…J ΀óósãããT*ÆÆÆèëëcmmÉÉIžžž à&@L¥##_þ#Ž¥TŠx%Y–Q.—©T*°´´ÄÜÜÇÇÇ4›MÊå2QÔu+• Ž !¢ÓycfhhˆZ­ÆÌÌ ''',//sqqA’$ÔëuBX§!D1­Öw./‡nfÕj•……™ŸŸçææ†³³3Êå2‹‹‹lmm𡸼„Vëûÿ~³'Y–Ùl6Í >Ùn·}xx0}uço¿ùWžõ¸ÕÛ÷(ó¼ÿÏÞvÀ »ß÷þÏx×Þ|שñ®óì'í)Ô[Í‘DäIEND®B`‚routino-3.0/web/www/routino/icons/limit-102.png 644 233 144 1407 12573351602 14570 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“¼IDAT8Ë­”OK[[Å×½O’pý›:p"ÚQ‚j§GN$Näu¤À¹_ Aü¥ P°<Rȸm„¢EEE!Å„o“{Ïþu¨±oêgÿYû°ÎY{ IHÂ÷}$I¤R/Öñ¼*CCðì™ch<¯Š´Þ‰ Éïà„î ¥R’G©”BzCübq>|0./áǸ¼lÛ‹‹¿Þtò½^"‘ðI&E&óé;³³pvæ€3G÷jÛ1ggŽÙY¾“É<'™‰„/FFD± }cy  QQfûÎ4Y^éÅbÀÈH‡¦ô–¹9€qLÜlâÌpÎEÖmÿþkµÚùss ½½{³,AÐàèÀâfóhfÎÎ=°¶8ÆÀ8:‚ h e…´ÎÒ@líÛ¨T*pxxH¹\æää€ýý}VWW©V«tøÆ,-´.¤/¼àpŽ zzzØÜÜ$Žc&&&'ŸÏ³³³C:fzzšL&ÃÞçÏmæïÞôÅ×ààK½z%I¾<ÏÓðð°úûûµ½½­d2©ƒƒ¥Ói­­­ieeE»»»êëëÓÞׯm\¡ ¾ôåû(‘$™™J¥’r¹œÂ0”™©··W’äœS±XÔÌÌŒr¹œ¦¦¦ôïë×’¤R)É÷ñeæ©ÕR÷Ôjµ466¦««+žžªV«©^¯«P(haaAårYf&Iò¢H2ó|5{ªT$ÉÔ  ( CMNN*ŸÏ+›Íj~~^ÉdR777ÚÚÚÒèè¨þûøQ’Ì}ú$5{~³#Hêõ:aÞëªV«afÜÞÞr}}Íùù9„?¶q]¿ùHgÄqW÷Ÿ‡ã8FJI¡PhÔ÷ý?ÑqJ`Æ ]‘­V«í±X,8pàK&“‡ñ)\×ÅÜÜœÉf³jeeå+Û¶«”:`ŒyADŒïÝ»×hBüËó¼öx<î?~\vttçƘÿ;B´´´P"‘`¥RÉóæMLJù{­õ cÌ[Þ××][[ÛÇýÓ§OK˲ µ®WÆ}T­R ‘H©TŠ¿|ùÒýúu̲¬Ï"‘È-æy^¯çyßÄb1Ýßß/kºqÎÁc ÆÕÿ !êõ÷÷ËX,¦=ÏûÆó¼^¾ÿþ×u[ûúúL<'¥8ç(•JxöìÞ½{‡ÆÆF0ÆP©T°°°€ååe,--¡\.£±± B˜ùùy’RnA|FMww7Î9fgg1::ŠM›6¡R© ³³'NœÀÓ§O166†Í›7Ãu]D" BJ‰®®.699iªÕêçÂu]“H$X$1D„ññqôôô```¯^½Â… ÏçQ(ÐÙÙ‰“'OB)…Údc`Û6ÚÚÚèÑ£GZüäûÈ€d2‰îînÔ*‡ÃuçpþüyX–…C‡!‘H &Ù:cœs]©Tàû~݈Ç£µµÓÓÓF*•–-[P­V±sçN;v ÍÍÍã8àœªÕ*cZX–¥ž?Ž\.ÇR©ˆårW®\ëº8rävìØ­5Ž=Z3ííí8wî^¼xh4ŠÅÅE,..˲ð!Ëf³ã8€k×®Ak3gΠ§§J)¬­­áÒ¥K¸wï —ËÁƒææfÀ;wý„¿Ñðð0–––FÞ¿ÿu"‘ÄÙ³g …À9GøðáN:Çqpûömض °{÷nôööâæÍ›úþýû̶íœïû¿£¡¡!øµ”òßÕjuËž={tWW[YYçD„ ÐÑÑh4Šb±ˆb±ˆ¦¦&´´´ —˙˗/“mÛ´Ö¿1Æ<Œ1àG­õ)˲þñàÁ³mÛ6¤R©úˆÕ3o½Ý¦¦&*• îÞ½„B!IDCDô€`’ˆ&9çƒZk~ãÆ ¿\.ƒˆ ”‚Öºþ€Öºž ã82 ]ݾ}û @PPŸˆØ®]».Z–uõíÛ·òÖ­[A-L> Î9¦§§õÇECCCÁó¼?ÏÌÌÔ3‚ïÛ·¯Öåóy£”ºoYÖ—Åb1¦”Ò[·n%¥T=XcX^^ÆØØ˜‘R€o‰hšˆ,“ÉÔC1&c­õiÛ¶155eæææÀ9‡ÖDß÷1::xžÇ8ç‰è*¹.#2™ Xí²Žº¾Œ±A"âãããþêêj}¥d³Y](D8~âºîÐÁƒ±‘ëÂâ⺾ápøªã8òúõëÌÎÎbjj ¶mCký!ÄÚÄÄ`68ßøñsú†Ãá/K¥RluuÕ<~üXU«U.¥ü€QcL]Ç Eáã`ÃÊcÌ~ÆØ¤ëºJÁ…Ùd2ùÅüü>V.—“$mmm)›Í* «bQj4JBZáÑ#N!¨U«T£l6›4 NOO#%ŽŽŽ°ÖR¯×C<;àáCVÚ:#ÁFú9ç ë͆DtvÁ<ëûØÐ2µ]g¶ò¸wïœ.Õ›—º5.uŸ]â¦ý „˜µq0pTÄIEND®B`‚routino-3.0/web/www/routino/icons/limit-27.4.png 644 233 144 1465 12573351605 14667 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“êIDAT8Ë­”AH[Y†ÿ÷ÂÄô%ƒ¦tç`Ýâ"Bq1P¢›‚ˆmWbh]Øî†"¸˜e‹èfܩРnºèªˆ B»‘–$¤Î"ˆÔ"B•gÞ»÷›E¢­ã,=pçÞsçþÿ’„ëºH.’ˆÅn!­à8ïéê‚›7 ]]à8ï‘VÚÿBrÛuBçb1ÉáÁƒÒ3<ïssðê•åà¾~…ƒƒV<7ž÷ éY;ßi×KD£.¢¯¯é#P« ÄZÃÖŠCj5ÃÄHéëë§£CD£®èé““R™ùy€3À`íw? œ1?R™ÉIžžöšÒsîÝÃ@38;Ã4›Xk ‚à­µß' CLB“û÷Az~~³4žwl«U,XŒÁZ{¹ø?f­Å†akÂj<ï)ù]úƒG~u>4ŠEwcsSÝÝÝò}_kkkªT**•JJ$J&“2ÆÈu]ýýù³>‹Î/·ojµN¡Q(xýš¿>}2?{£££d2–––ÈårŒŒŒà8[[[í CŒ1 0áË— \%YårªU*îoOŸjggG€âñ¸¶··555¥ÙÙY+ CE"-,,È÷}u§R’ärçŽÔÙ™ɤ1õ:ïÞ¾epp|>@£Ñ “ÉP.—/îµ¾¾Noo/333ÜêïçŸý}8:Âtv×ãF£*–ËÓôô´–——%IJ¥RJ§Óò}_FC€†††´··§Z­¦R©$9Ž0ÆQS*ðæ nnšŸ\—ááaâñ8»»»äóy¨×ëd³Yêí-VWW™¸{·u³/@*i…'O8°¾¿Ï~Û}ßçøø˜ÓÓSŒ1^`îää„£/_B?iågT«-ÜsSÿk­¼K8»Ä MØe®4ºˆÃÂ{…×ÊÍkUkÕ³kTÚDדr¤O.²IEND®B`‚routino-3.0/web/www/routino/icons/limit-0.0.png 644 233 144 700 12573351606 14542 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“uIDAT8Ë­”1Në@†¿Ý‰Ü$¢I‰WqZn¥WHc@ŸSpˆ´4HH¡Œ”t–hpœý(l ôŠÖó/m1»ÿü;³;3c¢€ÃáacÏŽÇzqqv<Öž…MsŽ?¤ƒ¼½ wæù»Ë¥><$G}{Óã±¶—KÍówá®á‡Æ̲è`€Óé¥ðêl¦ûýY­LéìwÔvå~v6Sxu:½t0À,‹8™à|ž /®×ªjòtÒÓISúZíž&õÃõZáÅùçýMÚOì*2›a'IEND®B`‚routino-3.0/web/www/routino/icons/marker-43-grey.png 644 233 144 2666 12573351600 15631 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“kIDATHÇ}•_hSYÇ¿¿ó'7É-šl ¦u45Z…4¢Ø‡ U X±øeú°8ààCvæefY:’ò ÌËú( øjµŠÿJ¥aviq‰iºT(J¥nlTRézϽ÷œy˜ænuœýÂ…{/÷~Ïï÷9¿ßïP±XĆ˜ÅbQ—J¥acÌ®ërÇ üOƲ,’Rþ‹ˆÆ‹ÅâL©Tbžç€Ú0åÆß³MJyA)õ…ëº&S:c,pÔZcyyÍfÓH)) M¸®û ­à ÌãØ%„(·Ûí]‰DÂ;~ü8ËårdY>–ã8¨Õj¦\.ûoß¾ý"ö}ÿ¸1æ91~ôèQà3!Ä?•R»öìÙãž9sFf2âœÃó›KžžÊf³¬Ñh¸oÞ¼IH)ÿ¨µ¾aŒyÇlÛ†”òüúúzo&“qÇÆÆd,ƒÖ:ˆŒˆÀ 0càyb±ÆÆÆd&“q×××{¥”çmÛSJ(¥¾L$zttTv~ê0Æ@DØüž1!D°ðèè¨L$Z)õ¥Rj„c¾w]ù|ñxZk0Æ`Œaii Íf3ˆúÙ³gxüø1^¼xÎ9´ÖˆÇãÈçóp]Ƙïù‘#G~ܲe …“R‚ˆãjµŠ‹/¢··ÝÝݘžžÆ­[·ðòåKÌÍÍvïÞ ˆÇãT­Vã8Û™ã8&NS$Ö:HñÕ«W¸}û6lÛF§fff022‚ññq ÌÌÌÀq@4E:&Çq ûû`SÇÁÄIJÙ,lÛ†R pöìYìÛ· ¨ÕjÈår°, Ƙ€?Æ8çºÕjÁuÝ`Cîܹƒd2‰B¡¥„€ýû÷Ckk×®aqq¡Pèƒúm·Û`Œi><<|®ÑhP"‘ íÛ·£^¯crrÑhOŸ>E³ÙÄêê*Âá0Z­’É$Nœ8þþ~ܼy===H&“XZZB¹\6–eù Àß„¬\.{­V ]]]@WW<Ï JH)…K—.a~~>ˆLD{ïÞ=Ÿ~Õ%~úôé¹÷ïß÷µZ­ƒ«««ÞáÇY6›ÅÐßßééiœ:u PJáÁƒ˜››C¥RÁ¡C‡044„ÉÉI½¸¸ÈÃápÕuÝ?ñƒBkýs8­×ëð}_÷õõ‘çy "twwcçΈD"èëëÃÞ½{±cÇ appÕjÕÜ¿ŸÙ¶ý_­õI"úÏçó‚ˆÞ¨J)Ï>þ\oÛ¶¥R)@*•B$ RŽÅbH¥Rغu+Z­._¾ìi­9cì;·À ‰è'ÆØ·DÄï޽뮭­1ß÷ƒ’!"c‚öœššòšÍ¦ …BWr¹Üß0^§@]"bƒƒƒ,˺Òl6å7¼{¿Óÿœs<|øP?zôHض½¢”úk¥R çÇŽë|LËËËÆ÷ýŸÃáðçõz=Ñáëû~0cxýú5®^½j¤”àÏDôˆX©T †:cL0ÆV´ÖcÑh³³³¦V«ƒƒˆàº.&&&<¥ãœ_ ¢+äF”J%°Î͆þ/_(—ËzeeEX–õoÇqÎ~O¿q»¬,εIEND®B`‚routino-3.0/web/www/routino/icons/limit-2.7.png 644 233 144 1331 12573351603 14571 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ŽIDAT8Ë­”½KcAÅÏ{¢Æ‡_Ñ"eÄ­DýÜJ´–Z è`k±° `%vVAµ·Óˆp1` 5â*A‚¢3o~[¼Äïí¼0 óqgîœ{…$$áû>’$b±H«xÞ1ÝÝÐÓÒÝ žwŒ´Z?’_Ç 5ˆb1Écj*†´H<03[[Ž«+(—áê*ZÏÌ@< -Öï{u¼DK‹Ok«H&û‘ŠLLÀùyXœ yÑÚr~21R‘d²ŸÖVÑÒâ‹DB¤RR¹9€'Àa Î½ŽÆ8à‰¹9 ¤R‰Dý™Ò““ÏXKøüŒ1†0 ߈rc¢Q«á"Òg&'AZjäl€ ¨pzaŒÁ½!pÎñeX)<=… ¨ 4ý’~kzú§Òéc|¯¹Y޵±±¡ööv% IÒÙÙ™²Ù¬ …‚NNNÔÞÙ©x<îÑÛzm::jÒëë„ÐÑÑÁøø8Éd’ÃÃCvwwall ÏóØÙÙ‰BÈú:HG¢«ËQ*aëê777™ŸŸ`ppµµ5jµ+++d2B[G•JÐÕåD<r{ûîpŸááaÒéô»O¸¹¹ahhˆB¡ðžìöâñðEY’Ïçikkcaaûû{jµÅb€ååeFGGëù·‘]Þ(óU©äµ·''9IÊår²Öj{{[}}}Êf³Êd2²Ö*—Ë)•Jé%œ“$§½=©RÉ i•ÙÙ(—ÖR­Vù{}Íåå%¥R‰ÇÇGÊå2Î9îîî¨V«¯öˆ¼f™iõ“Ïhäá?ñâ»/|ö¹ŒÁóΰg¬m}¨€o­ÍoíßÚϾ±Óþ½ÊŸ\¿-IEND®B`‚routino-3.0/web/www/routino/icons/limit-12.7.png 644 233 144 1452 12573351604 14657 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ßIDAT8Ë­”½K\[Å×½÷¡ãå":(SŽäU-¦H3¯HáG)Ã`*‹´´ðxðʤôÅWDTA”—iÄ2 Á,tctB”qî¹ç÷Š;c )^ã‚çc¯½ÏÙgí-$! ×u‘\$‘HüŽ´ˆãTèéd2¢§§‚´Ø:’Ûâ µ%’ëW ¤×øþwffàí[ËÅÔjpq¯gfÀ÷¿#½nÙ;-¾DG‡Kg§H§Ÿ!21§§`°6â1âµáô4bb¤CÒégtvŠŽW¤R"—ó‘ö™Ÿ¸,aaÖþí=°À=óó í“Ëù¤R­gJo˜œhšû{¢˜@E„aHE.g  Âf“š6ŸéM;gƒø~ÃC XÛrd­ÅZûËüqËÁø~iÐûSúKÅâ ‘+¹ÿ¾/cŒ’ɤ*•ŠVWWR©”$éääD¥RIûŸ?kïÓ''Èd¢ÞoߺìÎŽ'¤¬¬D¯¬àyëëëÓÕÕÅèè(étšÝÝ]677Éf³ŒŒŒàHü³³ñî¡ôÁUwwF/_ÊJ®ãyêëë“çy:;;ÓÜÜœ666*•Š$)›Íª\.+ŸÏ«X,jüÅ ×f2ú­»;#z{#¾~%l¥bllŒ¥¥%¶¶¶¦P(üô WWW ±¿·§ïËèí\Yë¨ÙTÆA jµªññqMMMiaaAaêèèH’´¼¼¬þþ~ >®H’kŒd­ãª^ÿ¨ímI²’äû¾‚ P¹\–1FkkkP©TÒôô´Œ1*—ËÊåríøVÛÛR½þQH‹Ì΢ˆ››FƒËËKªÕ*çççÜÞÞR«Õ°Ör}}ÍÝÝófgAZü¡³ƒƒX7±ÁÿÂÆv?éì— °aØŽø ÖÇâ}p‹»Éää£ xÒÚ|Ò®ñ¤ýì ;í²vsd©7’IEND®B`‚routino-3.0/web/www/routino/icons/limit-36.2.png 644 233 144 1524 12573351606 14662 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ IDAT8Ë­”ÁKÛYÇ¿ù ‰ùÙ´ÑÈJj ÐõR¨eríEHnŒ×n{±½‰ø,õ"´w/² [(•¢^D„B=èÁµTèb7HTˆm º–6ùýÞûì!Ñêöêƒá1óÞÌ{3|f„$$á8’ƒ$Fš xC4 --†h7Hõs!9u?¡“@¤ƒƒHqÝc††àùsËþ>”˰¿_Ó‡†Àu‘×ïêþÁ C($’ÉkHïÈå X4€µ†³«¦û‹†\¤w$“×…D0舶6Ñßï"½et X<<¬ý.'6°@…ÑQÞÒßïÒÖVOSzÂÀª^¥‚©V0ÆàyÆœÿ ©Vñ* TéÉIͮ㺇v{»öbÝуµöL†öt·Ö‚1X°v{\÷ézÃïÒ÷ïwîÝ3om9ÌÌ( ª½½]…BAÓÓÓ ‡ÃŠÇã²ÖÊqmmméϧOu) ´Ý¸a(Ãiƒ¹9þ)—MË•+ ’L&Y\\$“ÉÉdèîîfgg€õõu"‘½½½$ þzÿÞðâ¾´á(¹¥Û·åþì<S>ŸWGG‡T(‹ÅÔÓÓ£X,&I*‹Öòò².E"Ú|õÊÑ;¢©é–hn6|üÀ¿GGär9R©###¤Ói&''I$¬¬¬œÖouu•ÎÎN~»{ðé65òšš,_¿2óì¿Ü¼ @WW}}}d³YR©SSST«UÖÖÖp]—ññqŽñööàòeë4|ù²©ùyýšÏÛŸZ[ÕÜܬx<®ÙÙYµ¶¶*+N+›Í*›ÍjiiI’477§ÄÕ«šùÒêõkùGG›BšàÁßûöR©„Wß÷9888Ť\.s||L©Tbww—½ø >b¥‰sœ™:gÆZŒ1§°þŸ¹º±Æåξw@>Pµž¾ÿ¬çÀõ¼šüÐÚ›:5.tž]à¤ýÚ·„ÐXIEND®B`‚routino-3.0/web/www/routino/icons/limit-18.5.png 644 233 144 1462 12573351604 14664 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“çIDAT8Ë­”ÁK[YÆ¿÷$ñ 1F›Ä ”ࢠÅE·Ù”j Œ¥cºâ?00ËvïÎ)µ7³±S° NÝÅEF£k 6yïÞß,’Øtfë ÷œ{¿ïÞsøÎ’„ëºH.’ˆÅ~BZÇq>‘H@2iH$Àq>!­wÏ…ävqB=¢XÌArX\Œ!½Ä÷¿²²ïÞYj5h4 Vëø++àû_‘^vï;]¼D$âЉ‰ûH'äópzj€k ýÖñCNO ù37ç“NwÓ”^±°Ð[-L€1† 0æÇ­A»Mmž<éU¯fðý/œœ‚µ]"k-ÖÚ¾ í„t°ƒïAzàý.ý¡bq†çÏ+¹{?* C%“IissSñx\étZ’¶··õׇú»Rq~ÎåL´V \ö„T¡T0oJ%<Ïcgg‡r¹Ìðð0KKKŒsxx@­V#“É0??Ï/…ÿ|ûfxû#U\Åãõø±¬ä:ž§ÑÑQI’µVÊårS³Ù”$èúúZ€fóye¢Q—Gä =tåy(‘•´øô©²Ù¬šÍ¦†R©”666T¯×•J¥$IÉdR…BAù|^¿½x¡?ß¿—sïž àÊZGí¶zfŒQ,ÓÖÖ–¦§§µ»»«ÁÁAíïï PµZÕä䤖——•ÉdT¯×%k…1ÎmÍ0³³³”J%.//™ššbdd„b±HµZeff†½½=²Ù,‰¡!~}öŒ ¯_c¥ŠÖY]1†««+nnnhµZœ†!ÖZ...nãççç˜v»ƒ[]iý»ÎŽ;º Ã[Áö´Õ¿·½½1°¶Ogÿëôÿ+Ö[Â0¤+î6 }p§½y§SãNçÙNÚ¥l|£ÐRIEND®B`‚routino-3.0/web/www/routino/icons/limit-49.png 644 233 144 1236 12573351602 14522 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“SIDAT8Ë­”;K3A†ßp¶I!•†ä«ì’Ú" ˆ•!Bü ÉäOhc•N°0•}*ñR VQb!"‚¢nvæùŠlâ½ËÀ2gæ\fÏyßs„$$aŒA2H"™ü‡ÔÂó.I§avÖ’Nƒç]"µb½Lì'4”LzH››I¤-‚à™Z ƒ<<À`0:×jÏH[±½ûKø¾!‘Ùl©G¹ ý¾"œ³|^£sD¿o)—Aê‘ÍæI$„ï‘ɈJ%@º¢ÑxÃ! ‡àÜÇ7¾¼Óh€tE¥ÉÄiJÛT«!QQ€µ–è“<±Îµc›j¤íqÍ ‚'ºÝÑ‹±³sçÜï2Œƒ9º]‚'¤E!µ¨×¢8¬•ª×ëÑét8??ggg‡ëëëIÐØ>¢^©%¤SÚmKMþÀZK>Ÿg}}››r¹KKK îïïGÃpä×nƒtj”JU*I’‘çÉóbc¤]!ýfŸ Àññ1ƒƒƒ¬®®R(¸¸¸ ^¯3>>Îìì,SSS¼¼¼t¢4ìïƒôÛU6[ÒÜœ$¹’dŒ‘ïûZXXÐÈȈZ­–$éììLCCC:==•çy:::’$ÉÕÜœ”Í–\¹.òŸgyy™T*E0¤P(pssÃÉÉ ®ë²··ÇÏëk<€V b1«TæÃþ.ÌÇaqq‘X,F¡Pààà€L&ƒïû,--±½½ëº,,, ‡9,• ïßãIe!åX_g~»Ù¤ÙlÒjµèõzôz=®®®0ÆÐétèv»´Ûí!îÛ7nÁg}+åÆ<£V2ÛL*è6ÄYþdz±, ¬ça‡’™ êÄ=ÂØßp¯Ú¼×­q¯ûì7í/Žô¼h‹šbIEND®B`‚routino-3.0/web/www/routino/icons/limit-35.png 644 233 144 1353 12573351602 14515 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ IDAT8Ë­”½K\AÅÏ›]v×êcÁ¸b¡&¢¬•©ƒØiåbáV‹D"h+øS&½½ÅV†mì+›-LQ¬”õ£PS˜}3óKñž›h°sà÷Î9wfîœ{…$$aŒA2H¢Px‡´Iü Š XtDÁ¤Ít_H&å =&*¤€jµ€ô•0üÅÊ |ÿî9?‡›8?Oü•Ã_H_S|ò%r9C>/††Þ"S©Àé©,Þ;þ]‰o9=uT* 34ô–|^ärFô÷‹ùùé'ëë¿OCƒ÷í1øÍú:H?™ŸéïOŸ)}ca µ`-Î9â8ƹärqw̧ ÍÂHßkV& o9:JN´Ï^÷<Âc2ÏÑ„á-R9óYú¢OŸ>èãG'k ™Œ‚ Ðáá¡¶¶¶ÔÕÕ¥mookwwWS¾PqoÞ8u©ÙÌ©I½à\» ÀÉÉ Åb‘jµÊðð0FƒÑÑQ*• µZ‹‹‹äÆ ÞQ¯ƒÔ̪·÷½¦§%ÉÈI’µVêëëÓõõµöööt/@sss*•Jd³ ozZêí}Ÿ•1(— $ɤɯÇÇ588¨ÅÅE]]]iddDÕjU“““Z[[SEš•³V™lVÊå$c0ò>P»-IrÖJ’êõº¦¦¦Ôh4ÔÝÝ­MLLhyyY¥RI———’$@’¤v[ò>xR3Ÿhˆ»»;fffèéé¡V«±¿¿O¹\&Š"–––°ÉO’â;5Ò&««6dGW­V‹8=<<Ðjµ:ºKA ou¤ÍÿuæÞûÉ{µ¶£5ç\¢Ãdÿ‰Î^ì€çbõÞÿõ_ì€WíÍW¯:Ï^qÒþ­“f·üc˜"IEND®B`‚routino-3.0/web/www/routino/icons/limit-4.2.png 644 233 144 1311 12573351603 14564 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“~IDAT8Ë­”?K+AÅÏn‘„EMÔ"vµ±°Hc›&X†€±±3¥…à°U°°°+;ý6VIL!˜Â"j@B@!¢îîÌï›?Æ÷^— Ã03÷Μ{æÜ+$! ×u‘\$‘H, à8uR)˜™1¤Rà8u¤“Þ¹Ü^œPÿ¢DÂArX_O ày]¶·áâÂÒjA§­V´ÞÞÏë"ôü^¼D,æ‹Lf©A¡Í¦B¬5ü´hÒl d2óÄã"sE:-ŠEéžÝ]€oÀ`ípô÷Àßìî‚tO±è‘N÷Ò”)•|‚ŒÁC†#ÀŒ1A€ñ}ˆÎ|J%ûœ-áyï<Ò££wˆF…ç¹bxXÌÎúH_Y]h– € kþX Íê*H_™õî=SzÍü<@'l·1]Æ‚ À˜ÿ&´Ûtxü¤×ý?Ëâû ÁÚ^ k-ÖÚßæ—Ö½À²¿¾ß@ÊFþ’þÖóç<{f\ÉýT*) C%“IU*mmm)•J)™LJ’‚ P±XÔû´·»ëüùð¡‰V«ƒ|þÒ.æŸ ØÞÞ¦Z­266ÆÄĹ\Žz½@­V#N377ÇÓBZ«exó#íººuëž<•\'ÑÐÐU.—•J¥T*•äyžvvv$IårYçççô(ŸW:u¹_îíÛ÷\E"Èód%-¤ßﳿ¿Ïáá!Üßß³··ÇÎÎA0 bÂoh4@jºJ§w•ÏK’k@’t{{«N§£µµ5éîîNKKKjµZJ¥Rº¹¹‘$Ùï*Ÿ—ÒéÝ?r]äyŽf,Š"mll(ŸÏëêêJAhssS’”J¥ôùù©±F%Iž'¹.®¬u4J’'æL&“ZYYQ¥RÑêêªÇÑ`0Ðóó³^^^Á^ád­3׳QC899Á÷}ÎÎÎ0ÆpzzJ2™äüü|*âo=ûq›c‹¢ˆ××W¢XOcx{{›èn†lî6ÕÙ¬Xøq¶_u6?Q4Î wΟb¾MÀBgs¡[c¡ûl›ö?Ua…3ç?šsIEND®B`‚routino-3.0/web/www/routino/icons/limit-59.png 644 233 144 1324 12573351602 14521 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“‰IDAT8Ë­”¿KcAÇ¿oÕgîúEm½B°lb …tB"úÖWjï 6‚`+X 6‚ZL%J"AD Í{»Ÿ+^OO;vv¾3»3û’„1É ‰Tê'Ò6žwAB:m Cð¼ ¤í¦]H¦é'Ô ”JyHKK)¤M‚à™ÕUØÛsÔjpµZ¢¯®B<#m6ñ^Ó_Â÷ ÝÝbhh©B.×׈qÎò¯$zÌõµ%—©ÂÐÐ(ÝÝÂ÷èëù|€Tf}àpDD8÷¶Zgà€WÖ×A*“Ïôõ5Ó”¶X\hÇÇDQÔ^ÖZ¢(Â:ÖB'øÅE¶Z5Ë\^&7& Ù9œso{hs\^B<"e;~KT,þÒò²Uuv*Š"íïïëèèHgggW¥RÑîî®2™ŒÒé´ð±èkº*®*D×…+¸©i…t›v÷(þ.RP\¼,w‚›J»*"âNÁbŒybIZ7ñ>CÁ‚Á&÷žóy‹üxúxK†ÃÌ™fÎù~GHB®ë"¹H¢«k)ƒãäé냇 }}à8y¤Lã^Hn#O¨Y¨«ËArxù² )ç]“JÁ‡–ósøñÎÏëv*žw”nÄ;|‰HÄ¥³SÄbÃHE¦§¡T2@ˆµ†ÛR·CJ%Ãô4HEb±a:;E$âŠÁA13ã!1; P,AAÖþ«MX Êì,HGÌÌx 6ƔޓH` T«˜Z­ÕŒ1†0 ï4hj5‚j5 Þ7ßì ž÷Ó X°ƒµöŽÞ´á3¦n ày?‘ž)cS)€ð ›e~~ž|>ßJ.‹lmmµºØßß'NóW.ÚT ¤ŒBiOŸØýöÍüæyø¾O,#›Í0<<Œïû­âëëëô÷÷“L&zôˆÝïß ?J{®zzžÊ÷UúúÕýãÝ;mll¨»»[‡‡‡š››ÓÍ͢ѨšbŒ‘çyšššÒã¡!ݔˮž=“zzž¶·ut`¯¯ÄóçúýÁŽŽÊ÷}…a¨ÅÅEù¾¯kddDårYZ^^Öåå¥ú£QÉuå´µáÚ pÜHDûGGšœœT2™Ô‚$illL:99Q.—“1F+++׿æ¦<ÏÓî—/R{»l:ªI{|þÌŸ««¦Ãu™˜˜ ··—µµ5–––H$Xk‰ÇãlooljF£¼~õŠ VW±Òž2¼}K¿OO9==åììŒJ¥@¥Ráêê c årk-Õj•‹‹ ‚_¿BÞ¼©ÿfg ud›» ú¯˜1ó?8k1ÀBͶN™;@½}†Í˜/^ÜbÀ½ró^·Æ½î³{Ü´ÿ“Œ^XûÝIEND®B`‚routino-3.0/web/www/routino/icons/marker-67-red.png 644 233 144 2120 12573351601 15425 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“IDATHÇ•UÏkIþªºkfq‚¬2=„8»—„à-§L ":7a“Kî¹Í ûˆ1Ç8àú ãàAô´Šnn‘€p‰ñ¢ÓrŠ$âcHÿ¨oU=3™°¬û ¨®ê~_½ï«÷^]“™LF@:>¯”Z@ÚÎì]+¥ÖÒéôy°~2vvÄ~RJ-DQ4C’b||J)h­!¥D†XYYÁîî.…ÂuÝF†UÛ=8†Çñ0ŸÏ‡õz=nµZÔZ³×´ÖlµZ¬×ëq>ŸÐú %Œ“ˆ=Çq6°T*Íf“$Ç1Ã0<4â8&I6›M–J¥Ào𠬔p]÷–Ëå€$c­ìïSEÝ0à Cê `°·Çؾ+—˺®û@J ¤R© èy^ìû¾ñ ²—vŸ3lľïÓó¼S©ÔGñPkí]»vÓÓÓ" ¸©àûÀ“'ÀçÏ@±Dðô)ðö-ðîðþ=äú:¢LÅ"ÒJñÏçÏ…âй\Nïì옠Hr}ø>Xûß¼Ú ˜™é€ñqh´ôLé-(ú…¦XÀƒïûsó‚¦XÄ/0Pdb¤·WvÏûfÓi,XJ‰ÿ/`­ý±ZkÁ,X›Nƒç}Cº[ö›ôšçÏœgÏÌþÎŽ»¼º*ÏóÔÜܬT*¥¥¥%ÕÖÖ*ÊZ+×uµ¿¿¯ßWWÕ‰8õwî2™jg{»L´Í‡üõå‹ùÉóˆÅbôôô0;;K[[“““´¶¶²µµÀÞÞ pÿÞ=΂ÀðîFÚv?УGʺ¿¾z¥d2©p8¬T*¥††Åãqµ´´(›ÍJ’666ÔØØ¨õõu…ª«õÇò²«ÑQÙššnYE6›ÕÄè¨FFFÔÝÝ­ÞÞ^% •——kqqQgggŠF£’¤D"¡\.§D"¡¿wwUQQ!•—K®‹k}ßqC!íhxxXSSSšŸŸ×ÊÊŠúúú”L&USS£ÍÍM ]\\¨««KCCCª‹DÔÑÑ!årrÀqM6»£OŸôçî® ŠE­­­©©©I±XL‡‡‡ŠD"êïïW<×àà Âá°r¹œæææôËÓ§xøÐêãG•e³;BZàåKþ…àŸ£#ŽJ3ŸÏãû>§§§A€µ–óósòù<'''ØK^¼iág¤Ó—d_ã슭붵SâÌ€åg7`¡h}{)™°Þ°ƒà*¦ÈãÇ×p«Ú¼Õ®q«ýì;íw'OÐ7äó,IEND®B`‚routino-3.0/web/www/routino/icons/limit-26.7.png 644 233 144 1477 12573351605 14674 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ôIDAT8Ë­”OH[[Æ¿{‹I¼ñUSP¡®RÝ]ùt¢ ABÿ,mŸØ®ué[<è²u).Üd¡<(¯ ÛUAJ+”@IÛ‡)iUDDHDÄ’J̽çüÞ"‰O»v`àÌ93gf¾! I¸®‹ä"‰H¤i ÇùB[ܸahkÇù‚´T’[jE"’Ãýû¤gx^™™xùÒrpGGppP³gfÀóÊHÏêþN=^"r ‡EOÏM¤oLLÀÞž¬5\”š°·g˜˜é==7 ‡E(äŠÎN‘JyHyææÎ‹ïƒïƒµÿkã,pÆÜHyR)ÎÎzšÒsîÞÅ@Õ?;ÃT«cð}cÌ…ÏYüJ¿ZŇª½s¤çšÅñ¼[(`ÁR4Æ`­½rIj~–B<ï)~í/é)þî}²Aµªµµ5µ¶¶ª©©I ‡ÃÔøø¸‰„mll(•J©.VoßJ''9!-ñä §÷÷Ù¯k¥RÁC©T:§Éáá!ÖZŽ9==… xü¤¥sžQ(ÔxS癵öœ¬¿rÀÖ€.ñìÒX¨ZßÇÖ;ö+Yg±ªrïÞ… ¸ÒÙ¼Ò­q¥ûì 7íCåŽð†*ß9IEND®B`‚routino-3.0/web/www/routino/icons/limit-12.9.png 644 233 144 1444 12573351604 14662 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÙIDAT8Ë­”ÍK›KÆŸ÷ ÍÇÛ´Ä¢¸Œ¤n*Un]¹èÂÜT„Ú•TwqéÂ?£ º¾ˆm)äÒ•fªY”¬LŒrK@Ñ@’wf~]$ñÚ ÷®<00gfžÃ™sžóIHÂ÷}$IÄãO‘6ð¼©O¹\àððµµ5J¥Òm¦GGGär9ÊÇÇÆe³ m©Èö6€ý¼½M$aww—r¹L"‘`rr’t:M±X T*1<<Ìøø8<Î߯X¾|ÁJE_¿Ð«Wr’ïE"êïïW$Q¥RÑÊÊŠööö”L&U,%I…BA:88P4‘Ð_?úzýZîáâ¯Ïòó'a·¸SSSlnn°¿¿Ïèè(KKK„ÝZV*ÆÆÆ˜™™!öà~úÆ>zd}9ç©ÝVÏŒ1J&“ªV«šžžÖ‚Ö××eŒQ­VÓõõµFFF411¡T_Ÿ2™ŒÔhÈÏ×ÕÕwåó’ä$)%“I c´³³£¡¡!mmmiqqQÑhTFC¹\NKïÞiüåK§oß¹¹ù~ÛMÀ`-———4›MšÍ&T«UÎÎÎh4Ôëuœs4›MÎÏÏqív·¼|ÛÍÏ:mvÃÿ™sÛå™Ç¿xöÛ¸0¤°Gл„Àºän3?gîu6ïU5îUÏîQiSÜ‘FÁ`YžIEND®B`‚routino-3.0/web/www/routino/icons/limit-82.png 644 233 144 1321 12573351602 14512 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“†IDAT8Ë­”±K#Q‡ûÈËË‹FGGutt¤ûû{U«UEQ¤™™ÍÍÍikkK’Ô××—:är’1ˆBÁÑhw:¬¬¬°»» Àüü<¥R‰b±Èþþ>oooÄi¯R\ (œQ…º¼”$g²Ì*•Š®®®444¤……MLLèùùY§§§*‹:;;KÛÑéH’Óå¥Eá§×ìJ»Ý¦Ùl’$ ­V‹f³Éãã#FƒV«•}ñšŸ8³k]Æ>2דÚOœ}9=–þÕ9÷Ÿ øÖÙüÖ­ñ­ûì7íoaŠcïìIEND®B`‚routino-3.0/web/www/routino/icons/limit-23.2.png 644 233 144 1502 12573351605 14651 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“÷IDAT8Ë­”ÏK›Y†ß|“~MJê&¢H‘b»žD(¢¨ÛÚnÄÿAÒµîuÑR©4³ ±*þ bKÚM¢¨%̘|¹ç™E¢­3[/.çÞ÷î=<çIHÂó<$ID"¿!- }$‡övG<¡ÐG¤åÖ½¼VœÐe¢H$„bj*‚”Á÷«ÌÌÀ›7ÆÉ œžÂÉIÓŸ™߯"eZúP+^¢­Í#©Ô}¤/ŒŽB©ä€fŽ_WÓoP*9FGAúB*uŸpX´µy"‘cc>Ò'æçj€`öÓ.ÏÀ€óó }blÌ'‘h}SzÁÄêA­†«×pÎÎ] «× j5Ô™˜éÅeÍàûgV(``´ÿ›ÀÌ®v3ç00+À÷ÏÜúCú“gÏ~=}ê÷÷½—¯_Ë÷}uttèèèH««« ‡Ãêìì”™Éó<êå«WŠ†Ã¡ÄÇŽRévhw÷–Ò.Ù,¾~u1ßghhˆÞÞ^ÖÖÖH&“LNNÒÕÕE.— ŸÏ‹ÅH§Ó¤’Iö¾}s¼}KCÚõ>R:­ÒçÏÞÜóçÚÚÚR4ÕÎÎŽ2™Œ¦¦¦”H$T«Õ$IÅbQsssÚÜÜT4Ó~.çéñcqçÎ#qïžs• Û¹ýýýLOOcfT«UÆÇÇéîîfooïª~ÛÛÛMÝ“'8€ïß±xÜÉE£Æìq;aaa€••èëëcii‰ Èçóø¾Ïââ"çggÇÇp÷®y®ZÝW>¯÷֨וÍfÕÞÞ.@===ŠÅbÐðð°FFF´±±!IZ__W²³S½{g:8Pãü|_HËÌÎò74*å2å–]\\àœ£R©fÆéé)Õj•J¥B¹\æ¸Xäh0;‹IËWœQ(4ÉnñefW¬9ç®8ûI®kêáìZÔ-°fË\ƒõ¸-ý¯n´7otjÜè<»ÁIû/Fq‘$Ofü‘IEND®B`‚routino-3.0/web/www/routino/icons/marker-88-grey.png 644 233 144 2664 12573351601 15641 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“iIDATHÇm•MhSYÇÿÏùèMnÒQ¨¥1’V„‚ uº•œv¡Œ®†qºÐÂÌÂͼ//.,Èn6ãfnfW­?6¶‚L:3T ~UÓàØ:ئ I£QïÇ9ç]ØÞitþpáÞ?—?çüžç<‡2™ 6Ä„Èd2:›Íc~òqâ„ÜäÆ9c Œ1c‚0"c BˆÀ?yò¤ŒÅbÚuÝo]×ý’>|xÂqœ®‘‘“L&I)Î9ÖÖÖðìÙ3¬¯¯£½½œsQ‹FápRJS(HJÙ#|ßïF£&N3àœ£P( —Ë! Áqtwwcll ˜œœD8†ã8ؽ{7FGGÁC*•b333¦Ùlö3ÇqL<§p8Œ^ÃÝ»w±sçNœ?gÏžE±XÄÒÒîß¿;v´øÏŸ?ضxÅàà Ž?Ž—/_âòåË-þèè(nß¾­çææ˜mÛ=Ï ññqØ%¥¼óæÍ›ÝGŽÑÃÃìV«¡T*aÛ¶mH$àœÖ××±¸¸Û¶ÑÛÛ‹Ç›‰‰ ŠD"ï´ÖŸcŠ‚1&ü­µ>mÛöÌ;wLWWÒé4ÚÛÛƒâmž¨íÛ·£¯¯D„F£©©)ß², `œˆŠàDô;cì?Dħ¦¦¼Z­"‚R*%"c‚¹0==í×ëuÙÖÖv%Nÿ €ð7¥GDìÀ,˺R«Õäõë×ý-½×²ZÎ9æææô½{÷D$Yv]÷> f?tèÐæÏT*•ŒRê¯P(ôÕ«W¯bJ)ÝÓÓCJ©`°0ư¶¶†\.g¤”à;"š#"@Ëf³ÁPgŒ ÆØ²ÖúŒmÛ˜5…Bœsh­ADð<“““¾ëºŒs~ˆ®‘ÍfÁ6_6ô ß›7ozõz=ÀÏçõòò²°,«è8ÎøÑ£G±5`ñQð'|¯^½êÀ“'O0;; Û¶¡µ>+„x{ëÖ-Àlåη~ü_˲¾*—˱z½næççU³ÙäRÊÿ˜4Æ·,ªåêl¹²ßs˜1ö»ã8JÁ…ùT*5´°°À”RúãÀ–íÿ †M¾cÎ…B!Î9_VJ}ÿèÑ£–þýXÿ'ϽÜ}-(IEND®B`‚routino-3.0/web/www/routino/icons/limit-9.png 644 233 144 1123 12573351601 14430 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”¿N*AÅÏNâB¶acb¨ Ák£•Ö6Ø |x^B*Þ€ÎÊW ¡²ÀŒÄB£ÙùÝ‚]„«—Š“l²3{¾³ß! Ic ’Èfÿ uð¼{Âvw-ažwÔI¾ É$vB©P6ë!y\^f‘®‚wêu¸¹qŒÇðòãñâ\¯C¼#]%|/±—ð}C&# …¤'*,ãœe‹sÌhd©T@z¢P8 “¾oD>/ªÕé‘fà pDD8÷ý¤wà€/šM©Vòù$LéšZ `NC/±ÖEÖ®8ùÍ™S«tæìˆ xe8\üqEÈ9‡sîÇûRÃ!Á+Ò‘:4qÂÒ`0Ðn·y~~^»Òc :Bº£Û°©WiHrvvÆÉÉ Óét]pÁ·t» Ýår§*•$ÉÈI’sN’Ôï÷µ··§^¯'ß÷u{{+I²ÖJ’¾Q©$år§FÆ ß×*L"Z.—õññ¡‹‹ íììèWø¾d FÎyšÏå|~~êøøXççç ÃPÅbQ’äyÞ:q>—œó~ÍYš“··7Êå2ûûû´Z-~àŸœý·š)f³“Éd½Šª¹±ÏÒÊ®5í†>Û8?zkãlu6·º5¶ºÏ¶¸iÿ`ñ†‚wÕðIEND®B`‚routino-3.0/web/www/routino/icons/limit-67.png 644 233 144 1325 12573351602 14521 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ŠIDAT8Ë­”?KcAÅÏŒ³/ãb)¸X¤´D+Aj)Â*úRÚ,l¹Û;1‚°X[úD (Ø(I!y¸ˆ¾÷f~[¼ÿ¬»n13çÞ¹sçÜ+$! k-’Eùü¤-Œ9£T‚ÏŸ¥s†´• Éf~B½@ù¼A2,-å‘~¿Y_‡_¿<t»Ðé¤ëõu‚ßH?2¾Éü%r9K¿Eºd~®¯à½ã5ÒuÂõµc~¤KFFFé﹜ÃâV ZÔëO€'Ž!ŽÁûë힨×AjQ« gÏ”~²¸ÇàÎ{¢(Â9‡÷ž8ŽŸÍÇ1$IÊ_\ég¯fU‚ äâ"½1söÞ¿zçÒ`ž‹ ‚©Ú÷Mú®¯_'´²â”$keŒÑÕÕ•¶··U*•E‘vvvÔjµt~~®b±¨Á¡!ÇÆT*N77Ÿt|Ü'¤cvwœOëA·Ûebb‚™™fggi6›LMM1==1†ÃÃÃ4¹§'Çî.HÇb`ÀÓnG{{{T*–——ÙÜÜ$ C«««8çÒOh·a`À[Y‹r9½F’$*—ËšœœT³ÙÔéé©Õh4T¯×õ¹œd-VÞE‘$É#I*‹* Z[[Óàà îïﵿ¿¯r¹¬jµ*眬µ/Á¢HòÞX…቎Ž$É÷egµZMccc* ×ÜÜœ´°°ð6#ï%ÉëèH Ã!m±±d‚Ì~>áöö–$•www<<<¼•GÊOØØië¿:sÎ=º§³7zû‡ÎÞw@’ôˆÿî ç¯øÐÞüЩñ¡óì'íJ’fÞ£eÉäIEND®B`‚routino-3.0/web/www/routino/icons/limit-56.png 644 233 144 1334 12573351602 14517 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“‘IDAT8Ë­”=K+A†ß%&Û¸ãG¥(ÖâGi£¤ˆ i¢‚¦ÿÀ…[joeac§ølµDHP+IPˆ`¡êîÎ<·Ø_÷ÞÎa83ï9Ã9<çIHƒdD6;‚´ƒç]Ï[‚<ïi'}’Iý„Ú²YÉcq1‹´…ï?³¾Ž»;xx€»»Ä^_ßFÚJõ^ê/‘ɺºÄàà0Ò5 ÐhX Æ9Ëç•Ø1†ea¤k‡éꙌ}}¢Xô‘êln¼Ž(‚(ç>vûðÆæ&HuŠEŸ¾¾4Mi›R $Ž!މ¢è}Xk Ãk-m R*´Ý®Ù¾ÿÈÕUòc"ú–Ã9÷aC;˜ãê |ÿi¬ã—ô[««“ªT¬âب³SQéèèHÇÇÇ:??×øø¸šÍ¦vww•Ëå400 >Ž\.‡N§ƒ÷a“‡YaÖ×ס”êi=Òüü}Š .`3–]Ï?~Œ‡ZÏó4øNJÉ•J%nµZ=jƒ ÀÞ½{áû>â8†¢gÍ’–•R¸zõª¦×øI;vì÷N§3¼¶¶6Úl6ã±±1NZÚ¶möìÙƒ|>ÑÑQÜ¿˜í Äå˗̓„çyKJ©OÅèè(Œ17=Ï›i4h­Íðð0i­ADÝh23ÖÖÖr¹\w3–––l¹\fß÷ÿ5ÆLÑß’™%€§Æ˜Ï|ßÿ¥Z­ÚÁÁAäóù¾ 4F-µBT¢M‚ÁB‚X´àìh†'8¶_¶1ö d’·½Ì—=º7¥F:’VŒsTÅJµ±h(Ì@glÚ¤õÞsÏ9{°ÍRuûÃs_þü¿ß÷ÝïP:Ʋ˜étZg2™AcÌRÊ®ë„elÛ&˲Ñ÷étúF&“a¾ï€Z6åÆeŒé²,ëœçyŸI)M8¦h4 ÆXËQkR©„Z­f,Ë¢ŽŽŽQ)å×D4OD€˜1FØ"„È7›Í-‘HÄ?pàK$dÛ6Þ•ëº( &ŸÏ«jµúY0üH)uÀó1¾wï^`“âÏó¶Äb1yìØ1këÖ­Ä9‡1æ½#„ÀÆ©··—U*¹¸¸±,ë­õ¯Æ˜?tèüüêÕ«}±XLžþüùsùòåˈã8ëÀoÌó¼=Ïû<‰è‘‘k…çŒ10ÆZ Û%„hÝGFF¬H$¢=ÏûÜó¼™1欔‡ÃPJsŽ……<|øOŸ>…Rª•Ð"Âìì, c``RJcÎ ß÷ûÃá°I&“ 8ç( Èf³p®ëbóæÍ8~ü88ç "<~üçϟlj'‡aŒA2™d7oÞ4Íf³Ÿ¹®k¢Ñ(,Ïîܹƒ®®.œ>}§NÂÌÌ ž={"‹/põêU„B¡­5¢Ñ(¹®kØÛ>¼Ã•ûûûQ©TpáÂ\¾|Û·oG,ƒ”Ùl½½½…BR¶¬4cœs½´´)eË´Z­Â×uáyªÕ*¤”ÈårX¿~=†††ày,ËZ¦Ùl‚1¦ùààà™J¥BëÖ­£žž¼~ý/^ÄáÇ144„Ý»wczz<@©T‚ÅbµZ årذafgg‘ÏçmÛŠøAÁòù¼_¯× …0??X\\D£Ñ@OOúúú°fÍø¾Îy{ÉWôV¿ð£GÞ~óæÍ¶F£‘šŸŸ÷wîÜÉÖ®]‹7nàÖ­[¸wﺻ»1<<ŒD";v ãúõë8räâñ8ÆÆÆt±XäŽã<–R~ÊS©´Ö:Ž3R.—×ú¾¯÷ìÙC©T ÝÝÝèïïÇþýûaÛöª¿¬«« ±X ÅbÑLLL°`0øZk}ˆ^Ƙð·Öú‹`0xóöíÛfÓ¦MH&“èììl5¡½TÎ9R©–––Ëå|Û¶-":CD3à°ˆèwÆØ7DÄÇÇÇe­VA)…ÿÒÄÄ„_«Õ¬ŽŽŽKñxü' €¿²(%±]»v³mûR­V³®\¹â·§kß§D„»wïêû÷ï‹P(4çyÞwSSS­yåûöí[`*•JF)õ§ã8Ãår9¢”ÒÛ¶m#¥Tk±0ư°°€l6k,Ë"_Ñ]"°L&Ó ÁŒ±9­õÉ`0ˆÉÉIS(À9o%”RbttÔ÷§”újjjêç÷à°xûmIEND®B`‚routino-3.0/web/www/routino/icons/marker-9-red.png 644 233 144 1745 12573351600 15354 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“šIDATHÇ••1hI†ÿ™‘ŒŠäâ ­0Á—ÆÆib!ºˆ€U©>»ˆ»ÜEÅ…ë’:pn‡ nBŒ "ý¹sa)®0„€Ö$Ù ŸÈŽfþ+vVÒê.—»Ëcvg¾yïŸ7o©É…… ù|þŽÖú pÞsv¬µ~“Ïçï€_'Sð>`|§µÞÇ›$¹¸¸(*• ´ÖpÎAJ c q~~N!„PJu1ü1Ùìp%‚K¥’ét:v8Ò9ÇYsÎq8²ÓéØR©dЯ»’fœFAp€Õj5îõz$Ik-14q<}Œ¡µ–$ÙëõX­Vc>&X)¡”z€õz=Naq'QŽÇd­;çÇñ^¯×cTJ=“R¹\®€aÚ(ŠH’Ƙ)„$G#r8$ã8ó>EÃ0´˜ËåPJ`»Ý¶ ‚/^Å" —.‘OŸf¾§óÛí¶õÑ€+‹n0Lb|÷ŽTŠÜØ _½"ïßOà¯_'ß½$9 X,/9Øf³éçŒé·O|·›@NO§Çý:yï^f^º®Ùl€•¤Ö@ÒW¯/ßË—ÿáCâÏÏ(NO³ó¼yŽ”\¿ßÇh4‚R*K_jÀú:P©píðñ#Ëe`ÂÃÏÎÎÀAJ°{{{ÿ|òŸ?““ëëä“'äÕ«äÝ»MÓÔÀ !bAð3–Ëe3)úTÛ÷ïÉ›7É££düöm¢ñ˗ɾ>€‹‹ ®®®Žý%ø…BZëç¾øMæÀHòÖ­¤ 2Ÿ'kµäBÌl¾½½m=ðw…T–’Öú[­–%ÉøË—úéùð!yãùèQ"ÇŒLûûûÎÿB¬¤@åž-¥$€q·Û.œk(tnr=ûý>Ëårz÷[³<ÐB(¥x}㌾ÆLŸèææ¦ñ½µ»´´„ d¦,”RreeZëîWõI{ww×z`ÒfÚæ^„Zë(£¯o$i„ÇÇÇ, ¥”?Χ=oÿ®ï´|Œo¿øÂ×ø†eô Ã0N["I¶Z­4íc…ÙßÒ×m^ßZ­f’þÒM†”BÜöÓƒoçõUJE¸µµåÖÖÖÒ´[>mõ_}ü „ €±ð·ååe(¥äÿNôõþ§ (¥ìø~.›¿Ù_ö–šcN™÷IEND®B`‚routino-3.0/web/www/routino/icons/limit-36.4.png 644 233 144 1442 12573351606 14663 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“×IDAT8Ë­”ÏK[KÇ¿÷"/£³ ø\´ËÁMmHy¼, Ah²”vuýô/x]6ûìÒæA¡-ˆîºèÒ…?AÁ(¼¨ëV*ÄÜ™ù¼EkißÎ9gæœ9gæsŽ„$|ßGò‘D,öRÏÛ!‡ÑQK<ž·ƒTîî ÉïÚ õÅb’G±CzE|' áý{ÇÑœÁÑQGC‚ïH¯ºç½®½D¿ÏÀ€H¥&jäóÐhXÀàœåöèȆFÒσT#•š``@ô÷û"™³³Ò ×€#Š ŠÀ¹³§\³°Ò³³Éd7M©Ä³gXhG×רvk-QaíÏb 6Š0ЦP©Ô{³Á7·¿ß¹±kh­Å9w+ß×ΘÎùý}‚oH„Tva`övv(•J¬¯¯P«Õ(•JlmmÝ8éEY«Õøôñ#€qaRYVÚäÃÎÎìèð0Åb‘T*Åêê*¹\Ž\.ÇÌÌ õzý&bk-“““ü™ÍXóæ H›}z¨LFæëWÿï—/•H&u~~®••jzzZSSS“$ù¾¯ÅÅEµZ-%’äóø±4<üÐ÷ûúsº?1¡ç/^¨Z­êââBAhddD™LFKKKZ[[“$U*U«Ue³YmllèßÏŸÕ74$'á›vÛÓ½{úçÝ;ÍÛÛÀî.äçψ2äÇÆVŠ¿{'„¿€ÉåræððÐ6‚$WVH€¼zÕŽ‘Ý.yåŠKIf³$@óêIòðà€¹\Î8É!®T*$ÉÈ2 É|ž|øÐr\_'S)rk‹4†<:²ëÕ*yó¦Ýçj[©T –¤R @!€(²”GF¬. K}{Èå€÷ï€åeûcG@|ãÆ žžž’Qdé?~liÎÌÅ¢ýýòe¿Cׯ“µZO‰ÄJ¥ÄR†âååå~GÉÅEòÞ=òÉ2“!×Ö,ÈÚyéé´…¡«Ò:!DÏóþÀb±¨[_¾XݾM>x`AÉk×ȯ_íüþ}²T²Mužœœpbb"r—à/d³Y(¥V°<=­I2j6-åD¯_[ÀoßÈ˗ɧOíáNÏsss±ÜM®iA)µ€õZ-&Épk‹|öŒÜÜìײÛ%Ÿ?'Ûmj·´ººjà©b<ô@qKJIQÓ5E'WtÈT’Æìïï³X,&w¿>ˆJß÷kX ‚¾©h}Z÷î|µZÕÎ[›###ð<¯çPÞ÷åøø8”RMg.zPØ}L{ÈÒÒRì÷{î4`{Z”Rm¬×ë¶¾N6 íf³Ù¥”¿ ÓŽ‹õm6Ïeèä£Õý)„…ïĹúA&–H’õz=¡½ ;???øYúï®ï´Óo³Ù´†!%…·¾o?½úú¾ßÀÙÙY399™Ð®;Úþž«/€_…¹ ÿƒïûòÿöêëÆß=Ï£”rÀÏCl.Ä¿&Ó˜HÁ_}êIEND®B`‚routino-3.0/web/www/routino/icons/limit-34.3.png 644 233 144 1432 12573351606 14657 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÏIDAT8Ë­”¿K›[Ç¿y{Ñð^KÒ8äš%—8u’ÌVJ‹tpÐ`R÷8:øhÇfÏäâpAhŠý œ*šˆRŒ"¢ HM‰Ú@ò¾çœO‡ü¨½÷Žx†çœç÷ù~! Ixž‡ä!‰ht©L$rH<‰„%‡Hä©Ü’×÷ŠF#H^¿Ž"½Å÷P,B¥â¸¼„f./{z±¾ÿémß>Ò÷—ñét©Áü<œŸ[Ààœåþéé†ósËüRi0³§øþ;:êe´¶ß‘ÊïºA–žzt¾ƒôTHeW,˜úá!¥R‰jµ:tn4ìî×ë”J%>ú`\±RYVªòþ=ÇͦMÄb,--‘J¥ØÛÛ “É0;;; ~rrB"‘èÙ%“|üúÕòáFªþ¡Ç³zþ\¦Õò6Þ¼Ñ_©”ŽeŒÑúúº:ŽÆÇÇ58ajccC:i4|ÿîéÅ il,+ž<±|ûÀÝí- LMM±ººJ&“ayy™ÉÉINOO‡3»»»cqq‘¿Óij_¾@»Å¬g‚ ¢±1ýóîfž=ÓÎÎŽ¢Ñ¨4==­Z­¦‹‹ íïï+ CmmmiffF•JEú¾ªµšô葜19©Êö6·`_½|I<§P(Ðl6ØÜÜ$ŸÏÍf9;;cnnŽX,F!—ã,ÛÛ8©*¤2++&ìt¸ºº" CœsXki·Û´Z-¬µ\__ãœÃÓ³ët ++½ß¼3ÛÇ™µö?øº3k-X‹ýœõP(. á_ˆ&0×£U@¡pÊÍݺÏpÓþ±Ó2©IEND®B`‚routino-3.0/web/www/routino/icons/limit-15.png 644 233 144 1240 12573351601 14505 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“UIDAT8Ë­”ÍJªQ…×Þ‰ÙG`IQDPWà$JP£&: ¼ŒBãBº€f5lAƒ  AZP}?û9ƒOÍ86sÁ†ýó®µÿÖû IHÂZ‹d‘D*õ©17ÌÍÁŸ?ss`Ì R£¿.$Ûç „R)ƒd¨TRHûxÞ;Õ*œž::xyN'W«àyïHûýxÓçK$“–éi‘Ï/!ÝS,B»!ÎEŒ"‡´ÛÅ"H÷äóKLO‹dÒŠlV”JÒ-õ:Ààpî» æÀ_Ôë ÝR*yd³ýkJ”Ë>aa@†DQ|¸ †Í}Çø”Ë  ÞlÏërwï8"äœãWÄqŽ»;ð¼.Ò²Ôjaÿ C‘óóshµZrttD¯×‹ã|?æÕj 5„tE³  ÄNNNH$´Z-‚ `aaÍÍMvvvx||‹h6Aº²J§×U(H’ÕÔ”$É9'cŒ2™Œffftyy©··7ÚØØP.— “HļBAJ§×­¬EɤFáœS¥RÑÊÊŠz½ž2™Œ¶¶¶T,µ··§³³3cEQLH&%k±rÎÈ÷5€¬µêt:Z\\Ôîî®r¹œžŸŸ‡ë’$ß—œ3VÝîµ..$Éɹb³³³´ººªããcÍÏÏkmmMÛÛÛ’¤)cbÞÅ…Ôí^ýÍ^__ùøøàóó“§§§¡ïúæûï7Çúìg¹¡]¢(Âű>û5FM;*ȯ0ÑÜœhÕ˜h=›`¥ý)ëh@õüêIEND®B`‚routino-3.0/web/www/routino/icons/limit-10.2.png 644 233 144 1443 12573351604 14650 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ØIDAT8Ë­”ÏK[[Ç¿÷Æ&!yW¤.„"ò66 }]w#’"´fco•vçÂ?£YøO¨Á…¸ièJ¡]ÁD}¢€–`¸¹÷œÏ[äÇ{mßÒ33g¾Ì9ó’„ëºH.’ˆÇGZÅqŽ€§O à8GH«¸ÜNžP(wâHïI$ ðñ£åúêu¸¾nÛ…$ ¤÷ûN'_"u‰ÅD*•F:en.. b­á¿Ò¶C.. ss ’J¥‰ÅD4ꊡ!1?Ÿ@úÆò2€X‚‚¬ýW»>°€Ïò2HߘŸO04Ôy¦ôׯZ¡ïcÚ c‚kíšV‹À÷1ÐâÕ+>tÿì9‰Ä=§§„`mÈZÛùß³1X°öä‰{¤çBZåí[,„¥R‰³³3Ž)‹œŸŸ÷*8<ŸW.—Óøø¸þxñB¾y#5Š>fllŒF£Áüü<©TŠ_Ÿ<0¬­a¥²–YXˆÂ¯_©×ë„-bE'''—49==Ń1¦e7› -_ã™ióÌX{ úžs¶ÃÌw<ûÖÅ"@`âèd½fG¶•}@±x¥n´7oT5nTÏnPiÿd§H;ØIEND®B`‚routino-3.0/web/www/routino/icons/limit-90.png 644 233 144 1263 12573351602 14516 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“hIDAT8Ë­”¿N2QÅÏÞÈ*˜ˆ•!ñ³@ ml°Ð„ŠP`i €ñ%´1¼•Ï`¬, †ˆ mÔD£Daïý}Ųà¿ÒI6¹³wæÌ™3#$! c ’A‰Ä?¤:ž×"†™K: ž×Bªî…dF~BP"á!yìì$ðýW*89qÜÝÁã#ÜÝ…z¥¾ÿŠt0²÷Fþ±˜!ÙìÒ5Å"ôzpÎòYB= ×³‹ ]“Í.‹Ẍ¹9Q*ùHmj5€À1ÂpÎM¾è8àƒZ ¤6¥’ÏÜÜ(Mér`@@`­e8bmø¸Hwε¡}¹ ÒaT³%|ÿ™N'Œh-ιÐiœÝDŸÃ ŽN|ÿiIHuªU€€(2Ðl69::âææ€««+޹½½ƒŽR¨VAª é‚F#Ìd0àòò’ÅÅE666X[[£Ýn³¾¾ÎÊÊ ¹\ާ§§0³4 ]¥R«Êç%É8…r~~®ÙÙY)“ɨZ­*“ɨÕj)™LêôôT’ä@’Œòy)•Z52Åb’$cŒ$©P(èííMÛÛÛj6›òtq¡àüÙ³i#777Y(¬—LµZ%I&Iâ¸ûð|ûÖÕ8>NŽŽº¸¿Ÿ¼pÁÅOŸ:àû÷™x:ªÕ*@j­$!€\èê=?žŸ7(¥üiÙûíëüú wvv888ûU÷»4þÃöð†aÔìPA­Vk—½ ?99ÙùYúºíçwtt4&Éz½NFJI!ÄXÇ÷í›,åW)ÕÀ‰‰ ;44Ô.»æËVß ¸‡_?! ñþÕßߥ”ü¿€)¿Þÿ¥”köUsÀ>Õ7’„ KçÃIEND®B`‚routino-3.0/web/www/routino/icons/marker-81-red.png 644 233 144 2064 12573351601 15430 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“éIDATHÇ••¿kYÅ?÷ν‰>Q0‚™ÄmŒˆ`!>‰B×XXØYyŶë_°iÒb¡¸¾ÆÆNa£…6‹D|/ÂA‰†Wä×ü:[ÌLÞË ‹»_¸Ü¹3÷ž9çÌ÷ûè†Ý·oŸœôÞ¿dŬ޵÷þíààà$@qΖ@¦˜ Žyïç’$¹!IGŽ1.\À{O–eXk‰ã˜×¯_óýûwcŒs®Çñ,ðµgç ǃ hŽÒN§£,ËÔY–©Óéhaa!Ž玗ŠKÆa+€ªÕjÔl6%Iiš*Žã=#MSIR³ÙTµZ à Ìa­Å9÷P­V‹J°h{[YIq,õ³ME[[J‹ûµZ-äœ{h­…Ë€Â0L[­–$)ÞÞVŸæ.pšæCRÇ’¤V«¥0 S@—qν4??ŸJREùá÷ï¥ÅEééSis³ ˜ë–^¾Tïþùùù´`û ÊVWWsR’ÔhH :”ÏÕª´µ•[±¶&KSSùþ‚íêꪆ††²"åH§§§%IÉÖVÎäÒ%éÌ™üúÝ»øÅ éÕ+éÀ|}õjþKRòä‰äœdLþQΟ—¾~í2š’&&T$˜nݺ•Uõ7P)ß=ì½_TŸM%)j6¥¤çÏ¥²Ê<]ZRüì™$éÏG²pÃ3¶#ÀsÑZ+ i<~œû[¤Ê®Š*ÊX’Úí¶FFFÊÚ¯÷âxc ιY@#aØm*Q´§öÓ"áoÌÌÄEomŒŽŽ¥7œsvll ï}£h.¹¿%Û"ÊzŸ››K ÀöNwêi{ôݽ÷-@õz=÷·¨ïRöòò²*•J ÈZûk¿ìþØëo£±‹áúúºN:Íãc €ç'±Ëß0 £²%JR½^/e/•;wîôþ–þ=úý/ò·ÑhH­µ2Æ\,¶?ì÷×9×433“>}º”]/d»ÿ ¸Ë_`Â# )þuâÄ œsöÿîø[Ì¿A kmø¥OÍžøâ"pm`IEND®B`‚routino-3.0/web/www/routino/icons/limit-28.6.png 644 233 144 1533 12573351605 14666 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”ÁK[Y‡爫>3¢5GD¡³±ˆ2•€”0Ò@ƒÉ¢"Ø.ª›Äv7ÿYI»\ŽS‘Ò‚]ºÉZ#TPR†Œˆ“Ð…Áä½{¿Y$v´k/\î9÷žs¸÷òýŽ„$\×Er‘DsóOHË8ÎgÚÛáÎC{;8Îg¤åú¹ÜzžÐU¡æfÉáéÓf¤7x^™ùyøøÑrr_¿ÂÉIÍŸŸÏ+#½©Ç;õ|‰PÈ%w‘¾09 …‚¬5\5? P0LN‚ô…»„Ã"rE,&¦¦<¤}*€Å÷Á÷ÁÚÿçÕX ÂÂHûLMyÄbõgJo™žÆ@Õ¯T0Õ*Æ|ßǘ›4¾_©` Êô4Ho¯þìžwfóy,Xê‰ß°Ö~[­µÔã¬ÍçÁóÎî5ü&ý΋ çùs³·»ëþõþ½<ÏSOOr¹œVWWÕÖÖ¦X,&cŒ\×ÕÑÑ‘þXYQKS“óãȈ¡PhqvvH;|úÄöá¡ùÁóH&“ ³¸¸H?333ôõõ±½½ @©T"‘HÉdøåÁþ>;3|ø€‘v\E"÷õè‘ _+›Í*‰(—Ë©³³SêííÕùù¹$iccC‡‡‡ŠF£øPÑ–W‰„œ¶¶ûnCS¶\ÖôãÇJ§ÓÒèè¨2™Œµ²²¢b±¨h4*I2ÆÔ ëÏwï´µ¹)utÈJ¸Ö÷7Òîþ¾R©”fggµ´´¤µµ5Åãqe³Yµ¶¶jkkK’‡‰D477§®®.ýs|,0ÆqM¹¼«ÍMmîíÙ ZÕúúºº»»•L&upp ŽŽ)N++•JippPžçéç‘Í>{fµ¾®†‹‹]!-óêü{|Ìq}^^^âû>§§§A€µ–R©„µ– (‹• @ÀË— -ãŒ|¾Fö5ήغn[kk ƒù޳ °Pµ¾­Iæ¬7ì ¸Š©òäÉ5ܪ6oµkÜj?»ÅNû"J¯B„HIEND®B`‚routino-3.0/web/www/routino/icons/limit-107.png 644 233 144 1422 12573351602 14572 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÇIDAT8Ë­”ÏK[YÇ¿ï*/™çDº‹ÐBÔ,ª‚‹‹]ºe]° @þY¶ûì)TŠ ±0ËàZ • ¸‰ .,I òÞ½÷3‹$NÚ™¥.œsïù~Ͻ—ï9B’0Æ $‘NÿŽT&¾0>Ù¬c|‚à R¹w.$Óà õ‰Òé) XL#½%о³³?znnàÛ7¸¹éÆ;;Eß‘Þöòƒ^" ©”˜ž~‚TcuêuX¼w Z7¶ÔëŽÕUjLO?!•ahÄÔ”X[‹ª”JÀ“$$àý¿«¿èP*Tem-bjª÷Lé[[1Öb;œ÷8çH’ï=Þ{’$!étHâ1[[ ½ëÿYž(jqy àm§ƒïõ ~ö{Uº7¼¼„(j!å‡þ”þÒöözýÚ‘$Æ„¡ÎÎÎd­U6›U­VÓÁÁr¹œšÍ¦ö÷÷U­VõµZÕ¯étðÛÓ§Žzý—àü|HHç|øàpŽÃÃC†‡‡9::ÂZK¡P`nnŽÅÅEŽY^^fee…@âïOŸœ}ÿ¤s£±±gzþ\’ŒA ‰‰ e2žž*•JéââBA¨Ñh¨R©h}}]ÛoÞèå«Wò’zñB{fd CI’÷^ÅbQ333j·ÛòÞkddD’”Éd䜠r¹¬R©¤ CÉŒ¼Ç4@q+—ËéööV××׺ººÒÒÒ’ööö499©|>/g­Œ$űä}`Ôj}V¥"I^ÞK’FGGÕn·5??¯……ÍÎÎjccC…BA'''ÚÜÜìVu®‹«T¤Vë³ÊìîØž i6›´ÛíÝÝÝáºR Ñhpß•G7ß²» Rù?:ÃÚîñ$ι4×ËûAgÿÛ~€ð<è[Û'û©µ7uj<ê<{ÄIûIìO²Ó¨IEND®B`‚routino-3.0/web/www/routino/icons/limit-37.2.png 644 233 144 1472 12573351606 14665 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ïIDAT8Ë­”OHÛYÇ¿¿Œû‹I/¹ÝCЭeñàeA$ˆG þÚk·E°½{õ°¸…ö µàiÚ.ÛRS{)^„^/fÁSìRhƒFBD7óûå½ÏÓî¿›æ0oÞ̼>3B’…BH!$ÑÝý-ÒŽó†xz{ ñ88Τ¥¶]H¡¶ŸÐy înÉáæÍn¤û¸n©)Èå,å2T«P.·ô©)pÝÒýö{§í/ÑÕ"©ÔU¤wŒC©d€&Ö¾>-½I©dé©ÔUÂaÑÕɤÈf]¤"ÓÓ À`í9¿ 4˜ž©H6ë’L¶Ë”àyðƒFãûXk ‚ #ÖÚÎï4ðñ<œ÷¬×=¶{{­ŒÆ´+²ü×±Ö¶lÆ`ÁÚ½=pÝc¤¾K?I?sçÎÎíÛæm¡Z~òD±XL¾ïkyyYÅbQ»»»êééQ"‘ã8* úíéSõ„ÃNòÚ5C©ô“Ï_’‘ò¼xÁÕªé½|ÏóH§ÓÌÍÍ166ÆÈÈŽã°¾¾ÀÖÖÑh”ÑÑQRW®ðû‡†—/iJy™hÔR­òöý{=|H.—cpp ™œœì”¹ººÊÌÌ ßõõñËãÇpvF‰X‘H>}àÏ“&&&H¥RìììP«Õèïï§X,Ðl6ØÜÜd``€oÝÂ|þŒÇ‚HÄR¯óëóç|ý:étšµµ5VVV ^¯sxxÈöö6®ë2??ÏÉñ1ÀÁÄbVVÊóì'`Æ2âñ8ÙlÏóXXX \.“Éd˜Åu]†††ˆE"ä^¿6¼zE å…´ÄÝ»ÍàìŒJ¥BГ££#NOO[lCµZ¥V«Q©TØßßçàãGêÐäÞ=¬´ô7ÎL›3cL‡³ÿã­Í£å+ξLÀ¾ h7úŸ: ‚ %ÿš€ Í ÝºÏ.pÓþòùÄCCµgIEND®B`‚routino-3.0/web/www/routino/icons/limit-29.4.png 644 233 144 1451 12573351605 14664 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÞIDAT8Ë­”±KÛ[Ç¿¿4 ?Z4}”èbÀ:5‚K¡q(¡-âhÚíQÿ„ÄA³ˆ"ÍÐ¥C]:yC‹CÁ6´$•‚!(¢E Äü~÷~ÞħøF/¸çÜ{¾÷Üs¾çIHÂu]$ID"÷‘²8Î7Z[áî]Ck+8Î7¤lã\HnÃO¨ ‰8HOŸF^âyÈdàí[Ëþ>üúûûu=“Ïûƒô²qßiøK„B.á°ˆÇ;‘ФÓP* ÀZÃåU×J%C: R‘x¼“pX„B®ˆÅÄØ˜‡´Ãô4À9`ñ}ð}°ö?iÚÀçLOƒ´ÃؘG,Öø¦ôŠÇ1PóÏÏ1µÆ|ßǘ«ß'€Ož€ôª™³ž÷Û X°4/Xk±Ö^Õƒ a¡ž÷)!¤¬Íd‚­/_˜››ckk €|>Ïüü<»»» ÍGŠÅ"ÿ|øØL¤¬i“wïøüㇹãy ÓÝÝM.—£··—¡¡!úûû9::ºØÕÕEêáCär mºº};©TJ¥ïßÝ¿_¼Ðúúºb±˜ÕÑÑ¡ …B!­­­©¹fffT­Võ×½{’äòàÔÒ’Ѩ1‡‡|úø‘žž¦¦¦ØÛÛ£¯¯ÑÑQÂá0+++,--ÑÖÖÆää$÷;;ùY.ÃÉ ¦¥Å¸Ö÷7Ò׌ŒhbbB ªT*J$J¥RŠF£ŠÇã:;;“$ (ŸÏ«T*i{{[raŒ£š´Éû÷,¾ycn¹.ƒƒƒD£QVWW§½½ÙÙYNOOI&“6~±¼¼LúÑ£zÎ^¿iSHYž?§Áa¹L¹!Õj•Z­ÆÁÁÁEÒñ}k-•J…“zQž=«W³É3 …:o¥¿Lƒk¤­ÿ—g`¡f}[o™ Ðkû € À^ë€íÍ7:ÏnpÒþ W yÍ.ù’IEND®B`‚routino-3.0/web/www/routino/icons/limit-88.png 644 233 144 1263 12573351602 14525 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“hIDAT8Ë­”=O*Q†ßÝÜY IÔ„Ä[iGŒ­´T„ Mì ü~ƒ±ÀžŽ’ÂÄ`¥=LŒÜ’‚#…ñ#Ýsž[삟÷VLrŠ™3óž33$\×Er‘D"ñ©…ãôI¥ 6¤Rà8}¤Vt/$7Šš%’Ãîn©‰ç½P«ÁÙ™e4‚ñF£P¯ÕÀó^š‘¿ÅKÄb.ñ¸ÈçבþP.Ãph€k %Ô†CC¹ Òòùuâq‹¹"—•ЇtK£0,¾¾Ö¾Ÿ™ ,0¡Ñé–JÅ#—‹Ò”N¨V¦Æ|ßǘðsŸôȘR­‚t2«Ùž÷Ä`¾h ÖZ¬µóìf€ïÙZm–Á<ï iCH-êu€ßŸƒ\__Ól6é÷ûôz=šÍ&777ï€aÊõ:H-!]Ñé˜`2àüüœl6ËÞÞ›››‘ÏçÙßßgmmn·þ8ô7t: ]¹J& *%É•ëJ’Œ1òºon@Ói?c¤GélL‘8"?žš(8¼ƒÂd1oñ6Îã‘…¡G7³7³t62%Nf£†H·I†ÀÐÆNl$‰ dŒ‰·ÓÚ™¾U5 Óý¢ÏùCÁ-êò¯S¿:ç%“I¬‹ !L&u*•úÆó'ß÷÷»®k~– ‡Ã$¥ü7õ%“Ét*•bA€Z7åÆeŒÙ.¥¼îy^ïû&‰P,c¬ê¨µÆÂÂÇ1RJ …B¾ï_&¢e"â”ÀŒ1 À!D¦T*í‰F£Á‰'X"‘ p8Œ/åº.r¹œÉd2êÝ»w=¶mÿZ)uÂó’ˆ?räˆÐ(„xìyÞžx<î_¼xQîÝ»—8ç0Æüb!ÐÐÐ@ûöíc+++þÛ·o£RÊßh­ÿnŒYå]]]ð—µµµŽx<î÷ööJ˲ ”Ñ'”Œ1QunŒR ¶mcÿþý|~~ÞýúuÔ²¬­555ÿ`žçuzž÷]4ÕÝÝݲÂMÆc0ÆTÍ*›! µtwwËh4ª=ÏûÎó¼N~ôèÑ¿¹®ÛxæÌÇIk Æ^¾|‰¹¹9A€ºº:c@DpÓÓÓ(•J¨¯¯‡1¶mCJir¹I)›Dí‘HÄ$ V‰âáÇxüø16mÚ„B¡€ãÇãäÉ“X^^ÆÍ›7áyJ¥ZZZÐÓÓH$ìÑ£G¦T*µ3×uM,#Û¶žç!N£³³}}}8wîÒé4`dd;wîÄ•+WÐÛÛ‹ååe8ްm±XŒ\×5âSp¬ÊŒsŽK—.aëÖ­˜ššB.—Ckk+Êå2^½z…ÚÚZ\»v 5558uê"‘”RàœWò™1ι.‹ð}DÆš››¡µÆàà ž?ŽP(Æ|ßG¹\ÆÙ³g±}ûv buuœs@©TcL3˲Ôì쬞œœ¬­­ajj uuu¸zõ*._¾Œ‰‰ äóy„Ãattt ­­ çÏŸ‡1³³³€™™ÌÌÌ˲ðG!K§ÓÁ‡ ”Â7Ëå šŸ‘H ÈçóP]ß±càþýûŠ>é¯üÂ… ãår¹©X,¶.--‡bJ)ŒŒŒ`||Ùl@{{;êëë1::ŠL&ƒ/^àðáÃhkkÃÐÐÎçóܲ¬Iß÷Kýýý°KJ9þñãÇ_;vLwuu±ùùy¼ÿÛ¶mî]»ªÕ´ººŠ¹¹9lÙ²»wïÆä䤹uëÙ¶ý_­õcÌ´`Œ ÿÑZÿζíGãã㦱±---ˆÅb ¢Ï*jóæÍhmm¡X,âÁƒA(’DÔODÓD4Êûñ{÷îùŽã€ˆ µ®FYÙ RžÃÃÃã82 Ýnnnþ3 ¨4JŸˆØÁƒ¯‡ÃáÛ…BA £ªäò“'OôÄÄ„¨­­]ô<ï§l6[=ïèè¨üL F)õ/˲¾]ZZŠ*¥tSS)¥ª…1†7oÞàÎ;FJI~ODOˆHPÀR©Tµ©3ÆclQkÝkÛ6ÆÆÆL.—缊Á÷} žç1Îùu"º @®cD*•«|¬ë«| …BõIÉd2zqqQ„Ãái×uûOŸ>†X‹/Œ?ãë8޼{÷nÏž=ÃØØlÛ†Öú!ÄÚðð0`6rç'_ㇿ]YY‰ óôéSU*•¸”òGƘ*Ç Aáó«°áÉcÌQÆØ¨ëºJÁ…™D"ñÍÔÔSJé/ ?;þW0TøþÓÓgYçœ/*¥¾Ïf³PJáÿééfÏ‚µ9Æ”IEND®B`‚routino-3.0/web/www/routino/icons/limit-34.1.png 644 233 144 1372 12573351606 14660 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“¯IDAT8Ë­”MK[Q†ßs)1\ZŒ`ÉFˆ«n”®mŠvç$uã>.]ø l—Í>´T -µøÄ»f!© Ë¥R­4æžsž.î5­¶Kfq>fæ™wFHBA H"›CªbLƒ\¹Ó@ª¦ïB R;¡kGÙ¬A2¼x‘EzMþ¤\† Ïé)´ZpzšœËeßH¯Óÿ&µ—ÈdúúÄèh©ÉÜ;Àâ½ãoIΖãcÇÜHMFG ôõ‰L&##ba!DÚguà ðÄ1Ä1xÿG¯ïÀW¬®‚´ÏÂBÈÈHš¦T¡XÄA7¾ºÂu»=0Î9¬µ7b-6ŽqÐ¥T©r]³G„ápDt.ÍÈ÷ô¶XkñIÏÁ„á¤GBªúrÀî7T*êõzϰÙl²µµu#Àöö6_Ö—Ë Uå¤:_¾pØj¹Áþ~ÉçóìììP(˜žžî!¨Õjd2>}øàâAªßÓƒ55%Ûn/_½ÒÃ|^‡‡‡²ÖjmmMNGCCC’$l12ÆhxxXÞI 45%õ÷?Žï߸8?g~~ž‰‰ VVV( ,--166ÆÑÑÝ´9333¼}ó€øÛ7pívîß×§ÏŸõôÉmnn*›ÍjooO“““ÚÝÝÕÉɉ†¢(’µ¶‡R IRKÞy©N­Æ9¸çÏž‘Ëå(•J´Z-Ö××)‹ŒE³³³¼÷ÀÙ´fBª²¼ `ãN‡(Šˆãï=Î9.//i·Û8ç8;;Ã¥Ôi·Ûüº¸°,/'Ýü›g.å™sî¿üº!‰Óx–L@©Ðõq ·í¸ÀZ|2V·&àNgóN·Æî³;Ü´¿ß¶ëúÝM<IEND®B`‚routino-3.0/web/www/routino/icons/ball-1.png 644 233 144 201 12573351601 14170 0‰PNG  IHDR à‘bKGDÿÿÿ ½§“6IDATÓ¥10¡ÿÿóu³­‹$½M F1 Â>¸dà5;à¥#1…¢Maèúâóð § ÝÛ-öiIEND®B`‚routino-3.0/web/www/routino/icons/limit-22.1.png 644 233 144 1467 12573351605 14661 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ìIDAT8Ë­”OH[YÆ¿÷Ú‰é%ƒ±Ï]ÄB…,ºžEQëV„¶[mlwCqãF¡ÝÛºleFY× E…2¢©Ú’7QS’*Ñ™$ïÝû›EbF ³óÀ]œsÏù8¾s„$$áû>’$âñŸfñ¼÷$“pýº%™Ï{4Ûü’ߌ:ŠÇ=$û÷ãHO1æ„ñqÈfÅ"”JP,6ôñq0æéiÓßkÆKÄb>mm"•êAúÌÐ ˆpÎr^zD¡`é3©Tmm"óEˆáaƒô‘‰ €àCCpî¿wfÔ˜˜é#ÃÆ h–)=ãî],ÔÃZ [¯`­% C¬½˜ QD†X¨sïHÏÎzvcŽ]>G3ð<€sçÜ9¬E óy0æéæ•_¥ßxøðgïÁûW.çÿ‘ÉÈ£®®.mookaaA‰DBA$ù¾¯Õµ5ÙZÍë¸qÃR(\ó67¯(’6yýš?¿|±?C__½½½ÌÍÍýýý¤R)¶¶¶ZY...‹ÅøýåK¾zÒ¦¯Dâ–îÜQáÓ'ÿ—'O´²²¢d2©¥¥%MNNjyyY‰DB¹\N’†¡<ÏSgg§œçI’¯Û·¥öö[¢£ÃÚƒÖVWI§ÓŒŒŒ°¾¾N:ftt´Õð1M™{ñ¢aûú::¬l"áøö­¸3==µ– Œ1ÌÌÌP©T¨V«ìììP­V`îùóX¡ííη''9½}«õwï\T¯+›Íª§§GSSS2Æ(“ɨ»»[óóóS¹\–$côÃÕ«’ä¼7o¤ããœfyü˜¿!:ØÛcoob±H¹\æððÝÝ]ö÷÷9==¥T*µÊ=::âŸJ âÑ#f[<#Ÿoðæ{‚þŸ4ü.ðìÂ8¨»0Ä…!îYÏÛ"náƒøn.u7/õj\ê=»ÄKû/Em‘²¤×éÏIEND®B`‚routino-3.0/web/www/routino/icons/limit-116.png 644 233 144 1311 12573351602 14567 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“~IDAT8Ë­”?KcQÅÏ»ë‹á塌–‚k³Ú¸•j±0ØVôø1Lom‘€Â~»€….l±`TX,„k4É}óÛâ=ct-¸Å¹3sîŸ93B’pÎ!9$‘ÏFÚ#~26ÅbÂØÁO¤½Ì/$—å =åóR@¹œGÚ%Šþ²µß¿··ðçÜÞ¦xk ¢è/Òndù¹œcxXLMM#5Y[ƒëëð˜% ZŠ=×× kk 5™ššfxXärNLNŠõõé;;Àèõ ×³—õ¼tØÙéëë““Ù3¥*]¼Çw:$fý yïI’ô’I’Ð{z"évÓø ªÏö…(jq~`¾ÓÁÞ=c3{ñyq~QÔBú"¤=¶·¼¥§Ñh4¸ººê6 .//h6›T«UÎÎÎÈÞëÙÞiOH§Ôë IÂÁÁaR«Õ¨×ë„aÈáá! ¬®®²´´ÄïôÀÄj5NFG¿jeE’œ‚ P©T I ‚@ÅbQqëèèH×òò²Æ'&$ÉieEýêäÊå$If¦r¹¬¹¹9µÛmIR¥RÑìì¬Úí¶Ì¬O´¿¿¯“““4ohHr'³@Ý®ÍÌ^a@f¦8ŽDZ677U*•tss“ú»]É,pjµ~¨Ñ$SFR(†aŸlddDZ\\ÔÌÌŒ …‚æççõ­R‘$ût|,µZ?^U3$÷÷÷<>>ö«9ˆ½÷ÜÝÝá½ïÓ¼j¾ÒYð®™Ù‹x{½wuö_ØÂAØK[½é€íÍ:Ï>pÒþȬde­WÜIEND®B`‚routino-3.0/web/www/routino/icons/limit-19.6.png 644 233 144 1440 12573351604 14662 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÕIDAT8Ë­”ÏK[YÇ¿ïEcò̈©—‘ÎÆ€³³„±ÝÄ…ÕB™¥ÿÿŒf“•ëéBh1;×Á¶ÐV»(h\ N‰R0ГwïýÌ"/¶efv¸pϹ÷û½?Î÷! Iø¾ä#‰DâW¤<ï#ããpïže|<ï#ÒN´.$? ˆ Éc}=ôœ øJ©¯^9 øò¾_*A|Ezí÷"¼D<î32"²ÙûH§¬¬Àù¹ ÎY~´¾o8?·¬¬€tJ6{Ÿ‘ûbjJ¬®HŸØÞèŽ0„0ç¾A Ðe{¤O¬®LMEϔʬ­ôL·‹í°Ö†!Öþ|A†„Ý.z>Öðð°$ÉÓ'ZXÐ/^èÍë×R:-'áË9O½ž朓ïûêt:ÊårZ\\T:V6›U¯×Óèè¨R©”677•Édô÷çÏk=_íöÕj’ä$é—TJ’”N§Õn·U©T´±±¡|>¯ùùy---iffFAhîÁýþì™SµªØ·on³ ¬åêêŠN§ÀÍÍ 8ç°ÖÒjµpÎaŒ¡ÙlbºÝ>nkë6›}œô•¥@0ï÷ŠŠâÖbÿCg?U€ C„ð¿æÆ‰»ÇÚÚp§µy§]ãNûÙvÚ—jfC˜÷{IEND®B`‚routino-3.0/web/www/routino/icons/limit-126.png 644 233 144 1441 12573351602 14574 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÖIDAT8Ë­”½K\MÅw6®»wV6ÙJˆU,Ä Ø?Pü¨ÄB!!DK ÿÞJk[-´H±½ÁXXH`‹€aÁ½ˆRÜÝ;3ç-vò&¥ Ì™yÎÎy @Æ L¦_°£ ¨¨«K*ºº¤ ¨vÚ÷L›‡¸ÊdA ¥¥Œà­Âð—ÖÖ¤½./¥Ÿ?¥ËË^[“Âð—àm»?hóAé´Qg'êë{*ø¦ùyéâÂI²òÞé~µ°ÕÅ…Óü¼ßÔ×÷T(6¨·-,„‚¯ÚÜ”¤†$¯$‘’DòþnÝžI^RC››|ÕÂB¨ÞÞö3á%©)ke 9ï%IÎ9%I"çÜŽc¹f³Õ¿¸(Á»Û?{¦0¬ëü\’¼m4äÛBÞûßû[¡ßØZyÉëü\ úàYêø—7o^ðúµS’“Ns||Œµ–b±H¥RaŸl6K©T¢Z­²»»K6 )•J?vA­–åì,…àL>H’“s:88P*•R¹\VµZU6›ÕÔÔ”úûûutt¤ééiÍÎÎjttT?¾—$çß¿—àÌP(OEÌḬ̀²²Âöö6¹\Ž\.Çêê*===Ôj5Ôl‚÷¡^ÿ§OïÃ|>ÏÉÉ ÖZÊå2…BŽŽ†‡‡Éd2 ñêåKŸúüêõ/v´¾.I¶mHÝÜÜ(ŽcÅq¬««+EQ¤(ŠDZœsº¾¾–µV²¶Å[_—`矵þZÞû;ó&É>ûkü=Á[ãÞ7¯¿‹Õÿð Ù|Щñ óì'íO7>Ô¼þO”IEND®B`‚routino-3.0/web/www/routino/icons/ball-6.png 644 233 144 206 12573351601 14202 0‰PNG  IHDR à‘bKGDÿÿÿ ½§“;IDATÓcüÿÿ?dmEp¦y3˜ŒÿÿÿG•DÓ¼™ˆŒÿ3·ü'¤ˆ(“ˆT„ä ND8>\åh¥âIEND®B`‚routino-3.0/web/www/routino/icons/marker-94-grey.png 644 233 144 2651 12573351601 15632 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“^IDATHÇu•_h”ËÆŸwþì·pqûÙ5¸¬¬D² .zaýG<^h8¹(ȹ©H{Ñ›¶”"ÛÃÞõ¦Þ„boBj%dW/ºMËJà@,çb žS7îj¾$°šï›ofzq’=Ñœ>00ÃÀÃ;¿÷™*‹ØB X,šR©4l­ý£Rê„ïûáYÇqHJù"úªX,þ£T*±0 Àm™rk­¶Öî—RÞ ‚à ¥”M¥R”ÉdÀë:c°´´Ï󬔒"‘ȸRê7Dô†ˆ8-0k­BT;NÖuÝðÂ… ¬¿¿ŸÇÁ§ò}óóó¶Z­êwïÞ}Ǧµ¾`­ýŽˆ?þ¼Ð#„øwÙ\.§ÆÆÆä‘#Gˆskí®!„ÀÁƒ©¯¯µZ-õöí[WJ9bŒù›µv_ºt þüþýûÁ\.§®]»&£Ñ(Œ1ÝÊc ¢î­5b±Nž<ÉÕÊÊŠF‹Åþ΂ ø,‚/]×5£££r›çŒ10Æ`­Ý…@ÑŽŽJ×uM_Að³Ö~­”Âàà R©´Öàœ£ÝnãéÓ§X\\üÈÌZ "ÂÂÂÖ×שT CCCPJÁZû5?wîÜ_’É$FFF˜”Œ1<{ö wîÜÁ«W¯033ƒ> ··ZëîþíÛ·‘ÍfqàÀXkáº.ÍÍÍYß÷1ß÷m&“¡X,ÖÌää$Μ9ƒ7nàúõë˜Å›7oÀ9G³ÙÄää$‰D1±X ™L†|ß·ìû>üC­5Â0D*•$“I(¥Ðn·wïÞE__‰”R]$Û ÀçÜlll0¥8çRâôéÓxøð!^¾|‰••lnn‚1†r¹Œt:+W® ^¯CJ ÝDt:0Æ ¾Ùjµhß¾}tèÐ!Xkqøða$“I¬­­!ŸÏcuu®ë¢V«!‰ ÑhÀó<4›MìÝ»ét ¨V«ÖqÍüAÁªÕj¸ºº "Âøø8<ÏÃØØX7V½½½8~ü8öìÙƒ0 Á9ßyd”ËeMßë¯üêÕ«O677®¯¯Z­VxâÄ Æ9G¥RÁôô4^¿~‘‘d³Y;v …Bù|?ÆåË—‘Ïç111aF£Ï”R?ç…BƘo¢Ñèh³ÙüI†æìÙ³400€žž !›Íîºû÷ïG.—C£Ñ°•J…ÅãñƘ‹DôZ0Æ€ÿc~ÇÿùäÉÛÓÓƒ¤ÓiQ7ðÛ áœ£P(`ccSSS¡ã8’ˆnÑ·D4Íû-ñr¹¬<ÏÁÓ5ûT•J%ôó}ß}ó˜†, òùüC­õ p~äì\k}’Ïç€ß'3ðcÀøIkÝJ’d‹$—––ÄÆÆ´ÖpÎAJ c ŽquuE!„PJu1{.f8“nA`¹\6NLJC:ç8Î9‡Cv:[.— ú}·³Œ3ÅaçX­Vã^¯G’´ÖÒCÇÓŸ1´Ö’${½«ÕjìÁçÂ+%”R¯°V«Å,ŽãTe’B?wÎ1Žã ¼V«Å¨”z%¥r¹Ü# ÃÐFQD’4ÆL!$9‘Ã!9Ï­gÏEQÄ0 -ær¹GPJ}Àv»m瀙º÷ïÉJ…Èb‘|ùrîÿìùv»m½ÚàJ¥’ “1Qh †ä½{äÛ·d£‘ÂON&àìE–J%çK¶^¯“$“$™O{8L!­V:ÿò%w»ÓCgöÕëu° €ÔZHúꀵÀÀóçÀÞðîðáp÷.ð䉯î³á9Rpý~ãñJ©L¦Hàâ¸yH’ô~øú^…×Þ¡ËËKpRÆìÁÁÁÔøÌ†7oÒ#>ž¾œ•òéSú¼'©€BÄRñ;¹¿¿ŸDQ¥œs©’\nNœK×üœ$‚ Àh4Âîî® ¤”(‹ÐZ¿öÅoH2ÉÊêÛ7òÎRkòñcòÖ-²P ?}J…Ç1IrggÇú[u  ˜y\ÖZŸ`³Ù´$ÿž‚¯®È/Èû÷ÉgÏÈÓÓÔ&<<€Ÿ²ù[ü(&·êàâIEND®B`‚routino-3.0/web/www/routino/icons/limit-11.8.png 644 233 144 1332 12573351604 14654 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”?K\AÅϼÍ>×1‰O%A’Jl¶b¥•Q‘`½~k?Á¦·³s%…”Ûf‘%6"®AÿäíÎÌ/ÅÛݬ!¤òÂÀœ;sîÜ™9÷ IH"Š"¤I ¯‘Ö1æ€þ~xþÜÓ߯ ­·Ö…µxBí@…‚A2,,JX{C±ÛÛÓSøùNO3\,‚µ7H¥Ö~ÓâKÄqDO}…tÄì,œœxÀ‚§Û2ì89ñÌ΂tÄèè+zzDGbxXÌÍY¤ï¬®¤@ Ù„fBø3Ú>@Êê*Hß™›³ ·®)}d~ áÒŸpÎáýÃ}£A3MñÐàý{>¶ßl k¯9:ÂA !üuÓù²B8<k¯‘Æ„´ÎÊ @¥Ráøø¸CîÆí kµ¥R‰oûû.‹ ­ irÀ*—ÉçólnnP.—‰ã˜r¶ÀÎÎI’°¼¼ÌÈ‹|ýñÃóù3NÚ‹ôìÙ[MN*H‘Éå488(@’dŒQ’$ !¨mÞ{Yk533£—##º¯×#MMIOŸ¾”Ë¡8V´°¸¨ññqÝÝÝI’–––`Iº¸¸ÐÐÐ666t~~®d`@Š"™\ŽH!5ÍÝY´±1F’tyy©­­-MLLhwwWÖZ}­V¥'Oœ3‘®¯kªT$)HR__Ÿòù|'˜µV½½½4==­µµ5U«U%I¢woÞhñÇ /_”»½­u~pxÏÕÕ÷÷÷ïÆõz€4M9;;£ùëWÆ[Yéüf¦³ÃÃLÙÎñ?óÞwtæÿ¡³šMºv‹¶3wŽ–¸ÌÏwUÀ£Öæ£vGígØi5pcÿÕ_¶9IEND®B`‚routino-3.0/web/www/routino/icons/limit-64.png 644 233 144 1254 12573351602 14517 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“aIDAT8Ë­”¿K²QÇ¿ÏíEå)Ð^#G)§Æ¦†D—–q°¥­Eÿ¡"ÇÀ­Ñ­ ¥-h("(P‡BÐ!ŠÐç¹÷ó>f¿ÞÍw¸çžó½çÇ÷! Ic ’H$rHM<ï–T þþµ¤Rày·HÍè]H&òš%’ÇÞ^éߥZ…ÓSÇ`Ã! “{µ ¾ÿŠtÙ{‘¿D,fˆÇE6»ŽÔ¡T‚^Ï!ÎY>ËäÒëYJ%:d³ëÄã"3"“å²tO½0AAÎÍÎTQ¯ƒtO¹ì“ÉDiJ *€1AÖb#±vœµ–0 ÁÚ)è˜J¤Æ´føþ íöäGkqÎáœû–á7]NìÛmðý¤ !5©ÕB‚àáÛíÒh4¸¾¾þðït:œŸŸ€GÑ…Ôj 5…tE«`Ýä‘ápÈöö6»»»äóyÈårìììD…Óè,­HWFÉ䦊EI2$Igggêv»J§Ó* Z]]Õáá¡F£‘Òé´$ Œ‘$£bQJ&7ÿÈ‹yú$ajeeEù|^ÇÇÇê÷ûº¸¸P¡PÐå奴¶¶&¬•·° Åb’19çi<–$yÞsiiI‹‹‹ªÕjZ^^V¿ß×ÖÖ–nnnÔëõtww'IrQ&%ç¼/5‹ Àþþ>¾ïsppÀûû;'''”J%‚ øQ³Ýœu>äéé QÅZËÛÛÏÏÏ3züÒÍ_y6%ëì‡ü‡g_'`Öò_Aœs|²ù6s͹n¹î³9nÚ¨6˜J\ YIEND®B`‚routino-3.0/web/www/routino/icons/limit-156.png 644 233 144 1423 12573351603 14600 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÈIDAT8Ë­”ÍK[[Å×=†˜Ü æÃD©uT$`ÇâÇЉ’Áâ š±ø:lçŽVSÿ©t’T )Z(…‚ÑB>î=ç÷‰Zê{37ìÁÙ{íû°Ö’„1É ‰Xli ÏûJ"©”%‘ÏûŠ´Õë Éôæ„îˆb1É£Pˆ!½Ã÷³¾?:êuøõ êõî{}|ÿ7Ò»ÞëÍKD£†þ~1:úé;KKpqaç,F÷rqaYZé;££ÏéïѨÃÃ"Ÿ÷‘¾±¹ ÐAAÎ=ä] Ðfs¤oäó>Ãý5¥÷,/tCÂvëAÜ'€uŽN«…ítºøåeÞßýÙ |¿Áù9€ Ûm\èïpÎ=ôÂŽósðýÒ‹¾7Ò[½~=­bÑÆD£:>> d2©r¹¬££#žž*—Ë©V«i{{[ñgÏ422â‘N[¯V‹ëä¤OH'ìíX¬eŸH$ÂÁÁA044D>Ÿ§X,R­V™ŸŸgaa™™~þøÑÝüÃNŒ_jnN’Œyž§t:­x<®J¥¢ÛÛ[Ykµººª³³3U«Ue2ÍÎÎj(›•$£¹9ipð¥‘1(•$9çT(499©››¥Ói­¬¬hqqQ:<<ÔÄÄ„¦§§µ³³£J¥Ò‹D$c0rÎS§£?1Fõz]ãããZ[[S6›U³ÙT"‘P©TR&“Q­Vëâ;É9Ï¨Ñø¢OŸ$ÉÉ9IÒÀÀ€år9íîî*™LjllLårY©TJ¾ïkjjJÿ¼z%I®ïóg©Ñø"¤-J%€°'H®¯¯i6›´Z-.//±ÖöruuE††Ý¹R ¤­G:ëéÊZ‹sîžÔÁ#ý§ÜÿÞ×lõ—žÔ›Oz5žôž=á¥ý)‹JG™Î&IEND®B`‚routino-3.0/web/www/routino/icons/limit-193.png 644 233 144 1365 12573351603 14606 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ªIDAT8Ë­”ÏJQ‡3•˜ŒˆNEva¨«àª;]H7®B æô|Œf¡ ¸,%øiÁÙ4*E þÛ¸ˆ„Rp@˜LfîýºÈ$j»õÀÀœ;çœËoÎwŽ„$\×Er‘D>¿€´ãüdzÞ¾5LOƒãüDÚϾ ÉÍò„†…òyÉ¡^Ï#}ÂóÙÜ„¯_-üùÎÀßÜÏ{Dú”Å;Y¾D.ç2>.æçß#]Q­ÂÝR¬5<·Ÿrwg¨VAºb~þ=ãã"—sE±(j5éÛÛ1`IH°öéžb¶·AúE­æQ,f2¥}Ò”4Ž1Ö`Œ!IŒ1O~¯‡é÷ñ 5†ÿ¬Œç…\^Ø4ޱY!kíè}è,M±`¹¼Ï ‘ÊBÚgk µƒÛhµZÜÜÜp~~Îîî.×××\\\Ðh4øÑn“éMÙÚi_Hm¾|0ÃÑÑccc4›M:¥R‰ååe–––‚€b±H½^çÝÜ'ß¾ ”þ R{LSST©H’kAŽãhffF…BAAhvvV'''ªT*j6›ÚÙّ뺺½½Uœ¦’äR©HSS„ï~ÿ Éd®­­qpp@E,..²¾¾N.—ãðð€jµJ©Tâ4“jº]ð}ãÊZGý¾ž›µV®ë*Š"•Ëe­®®jaaAAheeEÇÇÇš˜˜Ði»=ˆcÉZÇUž©Õ’$+k%I“““’$ß÷†¡öööT«ÕÔh4T(äû¾Êå²ê?J’}óý»†g/º™ÉÃÃQÐëõ¸¿¿a‘$ Ýn—$I MyϺù‚³,`ÄÕÖ!s#x“dÀÙÕÕ Îþ›û¬à°öi¬þ™€WÍWݯºÏ^qÓþú:ŠÐÔ¹UIEND®B`‚routino-3.0/web/www/routino/icons/limit-17.4.png 644 233 144 1441 12573351604 14657 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÖIDAT8Ë­”¿K\YǿO‰N–aìc3 E„Ø,$׉‘ S˜R)´ý¶LjÅnŠ(l‘Æ`a9é,D™e”$Å#L¡†Ññ×è»÷~¶˜Ý]—­üÂ)ν÷|ï9‡ï9B’ð}ÉG‰Ä#¤e<¯HO<|hééÏ+"-7ï…ä7ã„ZD‰„‡äñúuéApÆì,|üè¨TàǨTþì,ÁÒ»æ{¯/ûttˆ¾¾¤}¦¦ -`pÎòw4|CZ¦¦@Ú§¯o€Žû"¹\€Tfaà pDD8wk­3pÀ •ÉåÒéf™Ò{¦§®ÍÕ.ŠpÎEÑ9çn34E¸fz¤÷­že‚ö÷1à\ãçÿ…sgL#ý=‚¤Lì7éw½}û oÞX_ò Ÿ?«½½]§§§Êçó*—Ë*•JêêêR2™”µV¾ïëËׯúsgÇëòĆ?yÛÛ1!m³¶`ÿX[#‹±¾¾N±Xdtt”±±1<Ïcss³Y¡ÁZËàà ¿>`͇ m·éÁƒÇzöLNò½XLétZµZMÃÃÃÚÚÚÒÒÒ’úûû•ÍfeŒQ[[›U¯×õs*%I>OŸJÝÝE2i9<¤Õ©ññqVVV¨T* Q.—oú•Ïçéííeff†G|ûþªUlw·õ圧ëkµàœ“µV’´ººªT*¥L&£z½®ƒƒÑîî®Â0T©T’>æòò€jµÊÅÅÖZŽŽŽn4w~~Nõð°77Òò­ÎööºièçšúOX{Ggw&ÀE-ÂÝøÆ€1¸;p¯³y¯[ã^÷Ù=nÚ¿Vye|N/IEND®B`‚routino-3.0/web/www/routino/icons/limit-36.3.png 644 233 144 1503 12573351606 14660 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“øIDAT8Ë­”ÁK[K‡÷*1¹µ$ jHòè[uS¨D\¼†Ò.p‚FwB»‰kñxè²Ý‹;±´ Ô‚èÖå[ÆE…cPÈBQQjlÁÜ{g¾·H´úÞÖaæÌœ3sÎá;GHB®ë"¹H"ýiÇùF"ɤ!‘Çù†´Ø¹’Û±º~(u&'£Hïñ¼Ÿ”˰¶f9<„³3801?hµ0¾€1† 0殃Æ÷ Z- øLL€ôá:gOñ¼ »»Ûþ±chŒÁZ{+B{gíèY»» žwô´ëoiwïþrÞ¾5ÕwåÓ'E" ª^¯kyyY±XLétZÖZ¹®«jµª•ÕÓÝí<~öÌÐhÄœJ¥KFªðõ+{gg&399I&“ass“|>O>Ÿ'—˱¿¿@­V#™L255ÅãTŠªUÃú:¡TéÖÇÏõò¥Â?Üù…õ§R:??×ÆÆ†êõºFGG•ÍfÕ××'I2Æh~~^étZõZMþù¹«W¯¤ÞÞçâÑ#Ãé)—Í&…BááafggÉf³,--144ÄÖÖÖM.///çL†íøõ 7ô}G½½úüå‹r/^h}}]±XL{{{êïïW¹\ÖÀÀ€êõº$ieeE¹\NkkkzàyªloK]]²aèÈJVWi‚yóú5‰D‚R©D³Ùdzzšh4J¹\æè舑‘#S*¹Ãê*Vªi‘™€0¸ºâøø˜  &arrrrƒÉéé)ÖZÂ0lë]]„ÌÌ€´x‡3ÓáÌX‹1æÖÛÌÙÎÆ`þÃÙï (•|†ÿƒõÎ> ±mï}J¥[p¯µy¯]ã^ûÙ=vÚs€âW}HIEND®B`‚routino-3.0/web/www/routino/icons/limit-40.png 644 233 144 1236 12573351602 14511 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“SIDAT8Ë­”¿J+AÆ¿{Ù„…%AË ibÈK›"6>@ò_B; K±ÐÎÊÂÎ7Pˆ…˜ ø§H¥QÉîÌﻉQ¯]ÎÌ|çÛ=ç|çIHƒdD6[DÚÇó®ÈçaaÁ’σç]!í§ïB2©ŸÐ„(›õ<66²H;Á;Í&œœ8ú}x~†~?97›ïH;)ÞKý%|ßɈBa©G­ˆqÎ2»’sÌ㣥V©G¡°B&#|߈¥%Q¯H×´Û#ÀEEàÜçžÜF´Û ]S¯,-¥aJ»4cââk-ñŒEÎ9°v‚Óh€´;ÉÙ*AðJ·›|1uvÎ%Ž¿ÙÖ&øn‚àiUHû´Zq6Òëõ8??àææ†½½=îî)>¦Õi_HXâxúÖZŠÅ"ëëëŒF#Êå2år™R©Ä`0H2Ëñ1HF¹\EÕª$yž<Ï“$mook8jyyYgggò}_NGaêôôT’ä ñ«V¥\®òWÆ ß÷$É:§?ÆèððPGGGZ[[Óåå¥òù¼%Iaj8j¢QI’ïKÆ`䜧ñX³Ë£J¥¢N§£ÛÛ[½½½i0èþþ^*•J’4Bã±äœ÷#gQZˆƒƒjµ›››„aÈÖÖÖ§ˆ¿åì×jZkùøøàååez÷ôô4­ô Ù—jþWg_»ÈMI¬µ8˜ˆö‡Î~퀩ž¾ÛŸ˜o0×ÞœëÔ˜ë<›ã¤ýÐi’Ó͵ÆIEND®B`‚routino-3.0/web/www/routino/icons/marker-96-red.png 644 233 144 2121 12573351601 15430 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“IDATHÇ••OkIÆŸª®ÊÄQP&‡ˆÓCÔìÅ„àHÈ:FüAo›ÌMPñû<Ù\×(A”Ä|€€²‚‡ˆ"xˆ0' ãœ6LcÈÆtwõ㡪'“ ˺/ ÕStÿú}ŸzŸ·½ÝÝÝR©Ô˜Öú#ˆÝÊöÿZë©Tj Üs2 ·z €^­õ\E$ÙÓÓ#†‡‡¡µFÇR" C¬®®bss“B¡”*…a8 àï6Në §<Ï«`6› çççM³ÙdÇl8ŽÙl69??o²Ùl€î¹SIÅIƾçyë822T*’¤1†aøcH’•J…###¯ð-VJ(¥ž`>ŸX°»Ë8È(Ú—)a ¾oÁóù|€J©çRJ ««ëú¾oªÕ*I2ÜÝ=j­mr„A@’¬V«ô}ß`WW×%(¥Þ`±X4í7²\&ŸÛ'Nؽ• \H 2àÁàôi ­á8Rˆëõ:vvv ŒîÞff€‹ œM°³|û<|œ= LMµ„KjccbH)faaÁž¨1äÖ9;K^¾LÞ¿O>L./“½½d±hkÝÜ$…`ôì™UéåKˆ…<Ïûs¹\XùüÙvÎùóä­[öáÙYòèQ{=6F^½j¯=b >p›äà™3‘3ÁŸH§ÓÐZ/`~t4$ɨT²§›tÀò²½}»wòͽ{$É©7Œ®H'6Íj­×°0=mH2øôÉöéÚÚ~ÔjäÓ§ ß½#I.--Åøb *{✔’¢Ò‹VßÄ¢‰‹œ£{Ö¿~e.—K¼_hç€B@)5 €9ßß*Î1í–5Îu¡›­¥¾¾>xž×šP¯”€Öºä†‹Õ·c $¶œ››3XoM§¶±‡Ž _k]ÀB¡`õu™%e—Ëe¦Ói€RÊß:Ëú–Jû2ÜÞÞæàà`è†ÇBÐøØ§¯ïûA2I²P($e—¤oß¾ÝþYú÷èÔwÔõo©T"#¥¤â\Û÷í§¢¥¯Rª €“““ñÐÐPRvÁ•­~¸O_¿ ! rþÕßߥ”ü¿À–¾nñ|Säƒ*O¾ffž ¾¨Õ’®®¬¤LÎYýj9ÎtueÕjIðE33Ïåû¨RñÐÔZ_}õz’ôC’SšJi*9÷sŒc’“ôC½ž}­¯šš*® µ¹)I‰²LÊ2¥iú8œs¿ã‚#)Ñæ¦ÇoöRAðU——ùŽ9éÿ-ç9]^JAðUð² ¼¥Ý~F³iɲå2išr||Ìíí-¾ï³±±ÁÉÉ ×××ø¾OELNN¢45¦Ù´´ÛÏøôémé¼§×û‡W¯µÆ”J ‡CZ­I’0 XXX Ýn3ˆã˜••&&&À9L©ß¾ŽŽi×xÒ~ö„ö_¤ùI?SÒAJIEND®B`‚routino-3.0/web/www/routino/icons/limit-14.6.png 644 233 144 1371 12573351604 14660 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“®IDAT8Ë­”¿K[QÇ¿ï‰Ïä!¢5â(´ºu+¡ZÁÅ%ÑŽ‚Ä?@ðŸ0»›R!–B;º¸ˆ[[´H†‚‰BÑâ F"Tôý¸÷Óá%¯V:zàçÜûýÞ{Ïùž#$! ×u‘\$‘ɼ@ZÇqjô÷óg†þ~pœÒz{_Hn'Ô!Êd$‡ÅÅ Ò¾ÿ›r>¶\\@³ ‰_.ƒïÿFZkŸwÚx Ïséé##Ï‘ê pvf€k -ñcÎÎ …HuFFžÓÓ#<ÏÃÃb~ÞGúÁÊ @X¢¢¬ý»:1°@ÀÊ H?˜Ÿ÷nSª°°ÆA€IcˆãøŸš("  „‹ U:9Ç÷o¨×‰ÁÚDÖZ¬µ~ÚŽ“¸ÇÇàû7HãBZgy 1Àþþ>§§§)¸^¯³··—¾ ÑhP©Tøþí@lËeÖ…tÈö6€ù¸½çyT«U‚ `tt”ÙÙÙ”¼Ùl’Ïç™››ãõ«Wü¼¹1|ú„‘]õõ½Ôô´¬ä:]]Êår$I«««º¿¿×àà :¶»»«F£¡\.§©7o”Ëf]åórúú^ºêêBž'+iñí[©»»[;;;ªV«š™™ÑÁÁNNN$Ia&DSSz¿µ¥¯_¾H²®¬u†éÍÖZc亮&''utt¤óósÕj5…a¨L&£ÞÞ^---ihhHç¿~I ŒqÒœE` …›››iŽ666(‹LLLp}}M©T"›Íò®TJp>`¥Ã´š@Œ1´Z-îîîÒêÝÞÞÒjµ0Æpuu…µ–8޹¼¼$‚·¼œV3ÑÙñq¢ìG}lÖÚD"Æ`þ£³:ÀF ;ÂMǴŲ°ð ž´7Ÿtj<é<{ÂIû…[’î…²‹IEND®B`‚routino-3.0/web/www/routino/icons/limit-29.6.png 644 233 144 1525 12573351605 14670 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ IDAT8Ë­”ÁK[YÆ¿÷$QŸNQ1ÄÙè€Ä…AwJ¨‰ÁvQÜ´(¶»¡ø ̲źœN„ÐbºråVìˆH*XR†(Ê„t!$`Þ{÷þf‘ØÑ™YzáÀ9÷ÜïãÞË÷! I¸®‹ä"‰¶¶ŸÖpœÏtuAO¡« ç3ÒZ³/$·‰º&jksžSzÃì,ü ^Çø>Æ‚ À˜Û4A@P¯cÀgv¤7×6ˆç]Úb –&ð&µkíí¼Ñ·¶XÏ»DlùEú•çÏÓγgæðàÀÝÈåäyžúúúT(”Ëå‹ÅÔÓÓ#cŒ\×ÕÉɉ~{ûV푈óc*e(•Úýý…Ò>?òÇñ±ùÁ󘘘 ™L²¾¾N*•bllŒááaÊå2•J…t:ÍÔÔÆÆøóòÒðþ=FÚwÕÙ9¢LF¥/_ÜŸ_½Òöö¶âñ¸VWWÕß߯E£QåóyIÒÖÖ–ŽÕÛÛ«ñ‡ÕÛÞî*–sïÞˆÛ‰`«UÍ>z¤l6«¡¡! hccC§§§Êf³* ŠD"’¤0 DããúýÝ;}ÚÝ•º»e%\ŽêàèH“““š››ÓÊÊŠjµš•ÉdÔÝÝ­D"!ß÷ÕÑÑ¡ÎÎN-,,(‹éôìLaŒãšjõ@»»Ú=<´¡ïkssSñx\{{{´¼¼¬ùùyŒŒhttT™LFÉdRžçi8•ÒÜÓ§Vù¼Zjµ!­ñò%5ÿ:;ã¬WWWø¾ÏÅÅÖZŒ1T*¬µ„aH¹\&¬×B^¼ií»Î(Ênêëšàÿ4gŒc0ÿÒÙ-Xðm`–ùþO†×g|?¾á€;õæN;gw8iÿÛÂQÛI¢;¦IEND®B`‚routino-3.0/web/www/routino/icons/limit-48.png 644 233 144 1246 12573351602 14522 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“[IDAT8Ë­”1K#Q…ϼ]Æ0MBD º XX¤+« ­´M~@Àß Ä>¦ó/h«SZˆE#&3ï}[Ì$f×u«\¸wæœwçÝsï’„1É ‰LæRÏ»&—ƒ|Þ’Ëç]#5ÒïB2)OhpP&ã!ylldêÁ• ;àù’¸R xCª§x/åKø¾abB sHmJ%¸¿·@Œs–QKâ˜û{K©R›Baމ áûFLNеµé–Z  8¢¢œû|ïÀ=j5nY[ ˜œL¯)íQ.ô‰cˆc¬µÄ#~EXkÁô)—AÚÔl xåî.ɘ’s8ç¾øƒküÝÁ+Ò‚T«qz…$;Ðn·999àòò’z½ÎÍÍÍç >¦Z©!¤ šMKÿÀZËìì,ëë뜑ÏçÙÚÚbzzšV«•`z½„×l‚ta”͵¼,IFž'Ïó$I;;;úøøP†”Éd´ººª©©)½¿¿KIo&¼åe)›-þ”1È÷=I²Îé‡1:<<ÔÑÑ‘VVVt~~®ùùyÍÌÌh_NGaJÒ0±|_2#ç<õû5cŒŠÅ¢®®®Ôét´»»«¥¥%žž*µZ-I’s.!ôû’sÞ—šD©lnnòôôÄââ"a²½½M·ÛMDHpÚ}«¦µ–n·ËËË ½^ÇÇÇa¢4ë5ÿÙg£f­ýCåÿõÙ·0ì§¿ýo'`¬³9Ö­1Ö}6ÆMû'Ž}»€åIEND®B`‚routino-3.0/web/www/routino/icons/marker-63-red.png 644 233 144 2100 12573351601 15417 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“õIDATHÇ••ÁkSIÇ¿3o&©Q/)e•¼R¤+HK=öÔØD¤hÎm/+x+xh”Åý ¨Õj$Ic Ã0<6Œ1$ÉZ­Æ|>8ð.ßb¥„Rê% …€$M388`dÉ”QÄ8|ÿÞ† …•R/¥”@*•º€¾ï›z½N’ ƒ€ì”Çv8Ha$ëõ:}ß7˜J¥®A)µ€årÙdxp`OììOŸ’ËËdÒùA®®Úý·o-ØýW.—Ëvâl67 ›I~üHž9Cž:Ed±h¡wïÚu_ŸïÝc¢§Ñh0›ÍÆî•ƒ)ºCQ’åÕ«äö÷Ê yþ<¹µEöô÷ïÛýG,¸Ùdâz±X$£H­5` šM`sèë2 ›<.^^¼†‡W¯€j˜œNŸŒ<Ž#ÀŒŽŽò[«eåùBžNNN’©é"?| •²YNMµ_=’Ìçó` ¥ ˜ß­ñ_¿Z™ ‰Yòø±}HÎ{¾{GŒ^¿&Iþµ²B±"€çy¿`XûôÉÞ|éyýº=ü䉽äÍ2>¼lcƒ1@./³ErøÂ…ÈÁ2™ ´Ö`ab"$Éh}ÝZØqçŽݾm×R’'NÐܺE’üåæMã€[2I™æ´Ö»Xš›3$ììÏž‘ïß-‚µ5rq‘áú:IòÏ¥¥Ø¿ !† !Äe)%DÕ¥%ëoR¢]•<˜½ÏŸÙïûIí—:y …PJÍ`¿ï6WеŸìMOO‡®·Vày^»CY¼RrhhZëªk.Öß®†’”åüü¼qÀ½vwêh{èÚðµÖu,•JÖ_—Y"{{{›™LÆ ”rª[vw÷·Z=’a«ÕâððpèšÇC!hüGñ×÷ý i‰$Y*•ÙÛ2³³³Ÿ¥nÇÇÇC’¬V«`¤”B\îø¾ýP´ýUJÕpff&Id—œlõ£À#þ˜B@ä2\„RJþ_`Û_7ÿêy¥”{~îRs,þ¡ñ­p¿ùqIEND®B`‚routino-3.0/web/www/routino/icons/limit-38.4.png 644 233 144 1456 12573351606 14672 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ãIDAT8Ë­”ÍK›YÆŸ÷E4¼Ö¢EAq\ØeÕe'%¥ H!±ˆ¸˜â"þ‚k™. n³Rm mqßE]Š_ˆ¢`f1©D£L;4˜ä¾÷þf‘¤cgºôÂ…{Î=÷žó~øºT ¤Œ¬´Çû÷üq}m£$“IFFFXZZbpp™™úûûÙ©'°Öb­exx˜§ñ8€ _¿iÏW[ÛC=~¬ðógÿ·—/5==­ÞÞ^ÝÜÜ(MLL¨¯¯O¥RI’äû¾U.—Õuÿ¾$ùÄbRGÇCßojBÎidhH¿¾x¡l6«b±(cŒº»»µººªËËKE£QIÒúúº²Ù¬âñ¸vwwõç§Ojjk““ðÃjÕÓ½{úýí[ýüè‘666ÔÕÕ¥••Åb1mnnªµµU[[[²ÖÊZ«ÑÑQ(ŸÏëøøXòÛÛ–8înnn¨V«ÜÝÝõùFƒóóó~€$;Ëö6HûBº¦Vp¶ÓàììŒ\.Çææ&óóó\^^P(XYYI³½ìµH×FÙlQ¥’$#IrÎ) C­®®jnnNív[»»»j·Ûšžž–$JðF¥’”ÍŒA©”†íååE333:88PE:==ÕÑÑ‘–——uuu¥§§'MLLﻄTJ2#ïEÑ š¤ããc-..êââBétZõz]KKKª×ëj6›º¿¿—$ù¯(’¼¾ÕÌE‹Er¹[[[|||pxxH¹\ Žã‘šüfÏ:ÏÏÏXkñÞãœãëë‹···<~ù͹Dk=¡~Ó×tökôµôü÷ a~tÀX{s¬Sc¬ólŒ“öGÀšÒuzÙCIEND®B`‚routino-3.0/web/www/routino/icons/limit-121.png 644 233 144 1321 12573351602 14564 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“†IDAT8Ë­”½K+AÅÏî>׸,(@!à«,{± S‰mRZøg(XXXØ,D$¥ÕvŠ!… ÄFW± HL6³ó{Ån¢>›Wx`˜¯{ÏÜ™9÷ IHÂu]$I pœSSðûwÊÔ8N é ß’›û ‰ É¡R) íoT«p|lyz‚—xzÊæÕ*ÁÒNnïäþ¾ï2>.Êå¤[VWáþ> Ö¦|F67Üß§¬®‚tK¹<Ãø¸ð}W”Jbm-@ºf{ X ÀÚ6\ ôÙÞéšµµ€R)¿¦´Ëú:@‚1˜~ŸÔZÒ4e0¦Aš$!M’Ì~}¤Ýá›Ínn¬é÷±9‘µöÛØ“­eä–›‚Ò¬¨ÕŒÍN#Š"Úí6Íf“½½=Z­Ö(²(Џ»»#¿¯¡Vé@H—Ôë)iÊÑÑžçqzzJ»Ýfbb‚ååeÊå2Íf“F£çyÔ3R¯ƒtéjrrAKK’äZã8*‹ò m¶ö…ä´pBíD±X)“'1¤¸n\^¿¶œŸÃ—/p~Þôs9pÝ:Ò‹V|¤…—ˆFº»ÅÐÐ0Ò'ææàøØ!Ö¾M?äøØ07Ò'†††éîѨ#úûÅü¼‹´ÏÊ @°Xûßl¯¬¬€´Ïü¼Kë™Ò ðƒFãûc‚kíÿ.h|Ÿ ÑÀ€ÏÂHkí?{€ë~µ• ,Ætµ“Xk´Á‚µ• ¸îW¤BÚ´¹@¸÷þ=ëëë”J%ØØØàðð°sÀÞÞù|ž?+€Ðær m*”ÞQ(ðÇçÏ&îºd2’É$ÛÛÛLNN266Æèè(µZ €r¹L2™djjŠŸÇÆø; ¯^a¤wŽîÞ}¨Gtüñ£óëóçÚÙÙÑÀÀ€VWW•H$T.—ÇU($IÅbQ}}}*‹ŠÞ¹£ß^¾t4;+ÛÓóйÕÕ…­×µ0;«l6«T*¥‰‰ ---É÷}IR<W£Ñ$e³Yyž§™™í•Jêêê’nß–ÇAĉFµ»¿¯ééi-//kmmMƒƒƒªV«:99ÑÑÑ‘’ɤ.//åyžR©”2™Œ÷îixxXò‰Àƒ†Hç#ÒB7/¤@·Nè²Q(ä 9<~BzŽë6˜œ„W¯,ÇÇP­Âñq'žœ×m =ïân½DOO€`PÄã>12¥’|¬5ühاT2ŒŒ€ô‰xüÁ èé ˆhTŒŽºH¦§Z€ÅóÀóÀÚÿýò ,Ðbz¤££.ÑhwMécch{­¦ÝÆZ‹çyWn­½дÛx­ÚŒôâòÏpݺ-±`1kíµâë›vsÆ`ÁÚb\·Ž4pçwéž>ýÕyòÄär¿–—Õß߯f³©¥¥%*ŸÏ+«¯¯OŽãèàà@//+ :ÑDÂP*ÝuööîÈ—öxó†?6½®K*•"‘H077G:fhhÇqØÜÜ`gg‡ÞÞ^Òé4ñXŒ_¾^¿Æ—öä‡Ã–ïßYY_gæÙ3Y\\`~~ž‰‰‰«5WVV˜™™éàøóåKh6ñîݳ¢¯Ï˜J€íwïH&“d2NOOI$ |ßïà¶·I&“ü–É`¾}ÃF"F&¶Ôj|Èç¹ ‘Íf©ÕjÌÎÎ’J¥¸¸¸àää„ÝÝ]\×%›ÍrV¯ãÁýû6`œÞ¿×?ûûÖo·µ¶¶¦X,¦­­-år9 K’jµšÆÇǵ±±!IZ]]UìáC­¿}kµ¿/ÿì,'¤¦¦8¿R.Sîz³Ù¤^¯s~~Þá–1T«U•J…r¹ÌÑׯ\€ÏÔVZ¸âÅb‡ÙÆÜàÕO­ƒ³üÀ³k °Ð¶ž‡íHæF£Ëøco(àVµy«WãVïÙ-^Úÿƒ¬ºŽÆêUIEND®B`‚routino-3.0/web/www/routino/icons/limit-23.8.png 644 233 144 1531 12573351605 14661 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”MK\I†ß{{bw®íhLcm2ˆ8 q–ƒ‹HD7AEPH6&¸‚@ÁlÅ Dé•+Wn$#FLè$«FÄ4ÚÛ÷V=YØ:1k Š:§êœCUñ¼GHB®ë"¹H"û iÇyOM ÔÖjjÀqÞ#͔υä–ó„. Åb’Ãà` i Ï+22oÞXvvàðvvÎý‘ð¼"ÒT9Þ)çKTT¸D£¢©é.Ò'z{¡P0@ˆµ†ǹR(z{AúDSÓ]¢QQQáŠdRôõyHðK@€µÿÏ‹=°€ÏØHèëóH&ËÏ”^ÐßRàû˜R c A`ÌÕ šR‰À÷1P¢¿¤ÖŠç}³ù<,åÄŸ Xk/Wk-å8kóyð¼oH­‘qéž<ùÓyüØl®¯»ÿ¾~-ÏóT__¯­­-ÍÏÏ+ª¡¡AÖZ¹®« ½ZXЯ••N26 7µµˆBil–wŸ?›*Ï£³³“––I¥R ÐØØÈÊÊ KKK$ †††Hݹû/_ oßJk®âñ{zð@…Ý¿Ÿ?×òò²âñ¸r¹œ¦¦¦488¨d2)ß÷%IaÊó<õôô¨!•ÒéÁ«û÷¥xüÞ/‘7°Å¢Óÿð¡êoÝR&“Q{{»&''urr¢ááa©ººZ’txx¨ºº:ÍÎÎj_‰Û·%ו‰ [¾~å¿­-nÆbLLL077G[[étšééiºººà÷ÖV^.,Àé)Ae¥uM±¸®ÕU­nnÚ°TR6›Umm­577«ªªJ™LFÝÝÝêèèÐøø¸r¹œ‰„þhkÓ_Ye³Š¯ i†gÏ8†po{›íò<;;ÃÃÞÞA`­åààß÷ÙÝÝ%8;yú¤™KÎÈçÏÉ.óe­½dÍsÉÙ¥m æ'ή(ÀBÉö\2W`½b‡áEL‰p­Ú¼Ö®q­ýì;íw]jÓ­ßUIEND®B`‚routino-3.0/web/www/routino/icons/limit-28.7.png 644 233 144 1504 12573351605 14665 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ùIDAT8Ë­”OH[YÆ¿—Œ1}dRSĸ…Ϊ.TtVEÜTBm\µ°uí²³\H ®$+AA*-ØvÕàBBµí ’²TcK*Éûs³HÒ‰ÌÖî¹çžs.ßw„$$ …BH"ý)ƒe}¤¥nÜhiËúˆ”©å…ªÕ Õ¢Q ÉâÞ½(ÒSl»ÄÔ¼|i8:‚¯_áè¨OMm—žÖÞ[µz‰H$Ds³è꺉ô‰±18< c­ûŒô‰®®›47‹H$$’I‘NÛHûÌÌTƒçç1ÿyý Paf¤}Òi›d²6¦ôŒñqp½J…Àu‚Ïó‚ ¡9ƒW.ã¹.¸æÎžÕÿì¶}nr9 j…uKVÍr9°ís¤[á?¤?yðàWëþýàïÝÝÐ_kk²m[íííÚÙÙÑêêªâñ¸’ɤ$)ŸÏkeeEûÚûðÁŠõô‰oß®™íí°|é¯^±ýùsð³mã8ÝÝÝÌÍÍÑÙÙÉää$d³Y666dhhKâíövÀ›7xÒ;ù±˜áûw^¼~ÍïOž000ÀÄÄ===,//Ó××Çææ&•J€……~{ø°:q¡ñ¸ù)ÜÔ„)•¬ñÛ·ÕžH(•JÉqõöö*ŸÏkiiI'''jmm•$E"‹Ee2­=.IRS“£ 3œ±³·Çµh”ÙÙYFGG™žž •J±¸¸Èéé)óóó8Ž€ðå \¿nBA©´«lV[ïßßuµ¾¾®¶¶69Ž£ƒƒ% õ÷÷kddDÃÃôµµ¥t:­šmnJçç»BÊðø1àÿS(P¨y¹\Æó<Žñ}c Åbc ggg\\\€ïW›{ô¤Ìž‘ËUyÓÀ³:·Ï?xWºÄ³K 0àÏÃT%ó?²ÖÏÆ÷ë²r¹{·AWªÍ+ÝWºÏ®pÓþ ™úŽW[}qmIEND®B`‚routino-3.0/web/www/routino/icons/limit-28.8.png 644 233 144 1514 12573351605 14667 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”ÁK[YÆ¿÷2júÌHÚDc%(tVNpÑEVn Ț"Ø.*´.lu3ÿÁEh×7Ž‹ #…B»rçNBRìЖ´E0ˆd”P V“¼w﯋Ď–.½p¸çœûý—ï;B’p]ÉEáð/HK8Îk¢Q¸rÅ‚ã¼FZj ÉmÕ 6 ‡$‡Û·ÃHð¼#fgáÙ3Ëþ>T«°¿ßŒggÁó޵ðN«^¢½Ý¥£C \CzÏø8”˰Öpv5ã€rÙ0>Ò{®ÑÑ!ÚÛ]‘Hˆ‰ é- uÀâûàû`íÿvš ÔYXé-‰Dë™Òc&'1ÐðëuL£€1ß÷1æüM£_¯c Áä$HOÿlÏûlK%,XZ…ß7°Ö~Û­µ´pÖ–JàyŸ‘CHrïÞ°s÷®ù÷Õ+÷Ÿ§Oåyžz{{U,•ÏçÕÕÕ¥D"!k­\×Õöö¶þÎçÕÕÙé$R)C¹|É)B ¤/^ðòÃó³ç‘Éd"—ËÑßßÏÔÔÉd’­­-Ö×׉ÇãLOO“¼z•—?ž?' ®"‘ëºqCåwïÜß>ÔÆÆ†"‘ˆŠÅ¢b±˜ÆÆÆÔ××§ããcIRò}¢øæ —ÂaÈf³ÌÍÍJ¥X^^`tt”ùùy~ä¯|NNð;;­Rõuž¬­™6×%NÓÝÝM.—cdd„h4ÊÌÌ »»» ³¹¹I:&‹ñÛ;|ÃÚV*i‰øÁ{{쵬V«áû>•J… °Örxx@½^§R©à×j÷ôg”JMfŸáÙ)·~èƒùŽgç`¡a}Û”Ì9²žóƒàÓàÖ­3 ¸Pm^èÔ¸Ðyv“ö+ŸÅs€ ¨“IEND®B`‚routino-3.0/web/www/routino/icons/marker-74-red.png 644 233 144 2107 12573351601 15430 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“üIDATHÇ••ÏkIÇ¿U]5“ ùìazÆõ`‚ààdM¼=™¨°g½9ÈâþЧÍq‰!%q@/B$ݽ媸’x‘™s‰2ÄdBWW}÷P5É$np÷AQ]Ý]Ÿ~ï[ï½öMvttHÈf³´Ö¯€ 3Û×ZëWÙlö„}²aŽX?h­§Ò4$ÉÞÞ^qþüyh­áœƒ”Æ,//css“B¡”ªcnø»³÷…“QÕ0ŸÏ›ééiÛh4èœc»9çØh48==móù¼À°ïd+â–ÇqEkX,“jµJ’´ÖÒóͰ֒$«Õ*‹ÅbÀkb•J©GX*•’´iʤ٤KÒ?ÚÔ¥%àåK`fÆçH£\¾ Œ¹°³ƒv )¸z½Žf³ ¥Ô>îÜ®_NŸöë7€ÁAàÁììôÞ___)eÀÎÎÎú ¡paìì$ß¿÷ë•RkòÜ9rtÔ‡ßßÏôÙ3’äŸ/^€B$ˆ¢èW, f/éIòÒ%²XÜ×òÃòÊòâErx˜ÌdèúûÉçϹMrðÌ™4ÁïÈårÐZÏ`idÄdºµE;FÞ¿Ïp‚­¬÷óÖ ÐÎÏ“$¾vÍà_r-óZë5,ß¾mI2™™!C1Ð9?Œñh6i>$?~äüÓ§.w„-  bH) ­T**æÛ‚òU¯×Y(Zµ_nç€B@)u qœTÃÙ)Y<Ÿœ˜0¡·VúúúEÑ^‡òx¥äÀÀ´Ö•Ð\Ì^A´™1†$955e°¾×ÚÚ݈µÖ5,—Ë^ß$9àõêê*s¹œ@)åÄá°ÛÑú···988hB«û-$¾Æw쀾q'­–H’år¹ö*€ÜÍ›7ÛKGÛa}‡†† IV*ß0¤¤b$¼}xX_¥T ¯^½êΞ=Û »ÂVÿx@_ÃBHƒ‡œ:u J)ù{ú†ù—(Š(¥¬øñP4ߨ?Åýk£]PzCIEND®B`‚routino-3.0/web/www/routino/icons/limit-6.3.png 644 233 144 1320 12573351603 14567 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“…IDAT8Ë­”±J+A†ÿ]$‰a%E,/– V-E ±ˆ66À7°5½µ‚éò>€šâ“ `¡¨DØdwf¾[ì&×\oéÀ03gþù™sÎŽ„$|ßGò‘D.÷ é ÏûÍä$ –ÉIð¼ßHgé½üôЀ(—óÙ¬˜››Gj±½ OO08gù:’³áéɲ½ R‹¹¹y²Y‘ÉøbzZììHMŽú€#Ž!ŽÁ¹¿s`ô9>©ÉÎNÀôtê¦T¥\ˆ0ÇÄqŒµ£³Ö&ö(c|¹ Ru³E‚ Çý}âHãœûâ™Y‡ö„ÌqAÐCZÒGGÆEív›jµJ£Ñþ ÙlR­V¹½½M¼áè¤3!ÝQ«áÀt»]VWWÙÜܤT*ñðð@«Õ¢P(°··Çìì,×××$LXj5îÆ†KZ_—•ü1IWWWj·ÛÚØØÐòò²ŠÅ¢$ÉZ«““ÍĮ̀Óé¨ßï+¾Ö×¥0\òåû(“\È£b±¨µµ5ŸŸëææF’´°° ƒƒ]^^êããCaJ’Ÿ×áᡦ¦¦Ôét$I*•Jª×ëÊçój4’$'IQ$9ç cØ4Ýìïï3>>N¥Ráåå…••ÙÚÚ" CÊå2½^TpØd3$ÆÞÞÞ°ÖâœãýýçÆ^__‰S\ŠÉæ¨ÎŒJa@6ÐÙˆ}P ÿèì[`Ì…;ܧ˜ïð£µù£]ãGûÙvÚ?G×…Ejò§“IEND®B`‚routino-3.0/web/www/routino/icons/limit-6.2.png 644 233 144 1344 12573351603 14574 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“™IDAT8Ë­”±K\K‡¿{«\%Š6ÂBi„€¨ˆÛÈ›ÊÂF´´ðψ`aamc+µ²Œ‹³°Å¢‚‚ Ù{ï|)v×Ä—Ç«<0Ìœ™s~sÎÌïŒãXˆìíýGØ5Š®Ò÷ïs‡†4Š®„ÝÎ9BÜñCº@½½‘ùùs¯ðÅ$yrmM¿~ ÞÝi³©wwm}mM“äIøÒ±:þ`¡ÛÓƒÅâá‡KKÚhäjf¹J[Ïl4r—–~X,~°§ …ÇÆ°\N„ïnnªþTƒiªiª!üÝ= êO77¾[.'ŽuÒ„-+Õ–Yfž¦¦ijž¿,Ïóö~«¥YÖ¶¯T¶ºoöÑ$yôúºHšBø#³ð2¿¬ÕÐðúZ“äQøˆ°ëúºjZ-Ukµš[[[^\\¼D¤zyyéöö¶WWWmж}æúºÂ.Â7÷÷ š«6›M§§§-•JÎÌÌX¯×U=;;s``Àùùy‹Å¢Õjµ}‘æîï+|‹üÄÜ9ÄÇÇÇÔj5FFF˜exx€F£ÁÆÆ'''ô÷÷S­V37ƒƒŸbâX º’eÙ ÐÞÞçççT*™œœdjjŠ••Þ ÇÆ„ÑjuÀúûûéëëcuu•ÑÑQêõ:išrvvÆÂÂËËËìììBmûµZBóøXåô”wÈsÊå2$IÂÔÔ¥R‰R©ÄÑÑŒsxxQDÓSx|¬¾úÍ!Ͳ̇‡ó<7„`³ÙôééÉûû{onn¼½½õùù¹ËµW¿ùšgYöB….ØJè/žýUfÙÿ7ü.«UÀ›Öæ›v7ígoØi(ViDõìIEND®B`‚routino-3.0/web/www/routino/icons/marker-29-grey.png 644 233 144 2737 12573351600 15634 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“”IDATHÇu•Mh”ÛÇÿÏù˜yçՈè%öBš0º˜%¦dZQ xÁ›E¬7ťɦ"­ÐMo)w¦0¸é¦"t!HÂebÄ Hp@;MKJ jâdD!j‚SM&&'¾–÷ãœÓ…™÷F{û‡çlþçy~ç9ÏCù|ÛbBäóy](>7ÆüÁ÷ýc®ë„ïd¢Ñ(I)ÿEDßäóù¿ h mSnŒQƘH)/{ž÷•ïû&SGGc¡£ÖËËËh4FJI‘HdÌ÷ýßÑ*qJ`Æ SQv§3‘H§OŸf™L†¢Ñ(>•ëºXXX0årY­¯¯eÛöO”R§1/ˆˆñ“'OŸ !þîy^g2™ô‡‡‡eWWqÎaŒùŸ%„ÀÁƒ)•J±z½î¿yó&!¥ü™ÖzÂó–÷÷÷ÀŸÞ¿*™LúçÏŸ—–eAkFÆèZc ”R°mÇŽãKKKþÊÊJ²¬ý±Xì6ó<ï ÏóF‰„”-nœs0ÆÀƒ1&4#"0Æ „/”‰DB{ž7âyÞ¼¯¯ï[×u?ëïï7Éd’”Ràœ£^¯ãéÓ§ØÚÚB<£][[Ó'Oàyâñ8´Ö°mBS­VIJyHAÐÇÍ‘#GpÎQ©T066†¶¶64›M¤R)ŒŒŒ R© X,¢­­ [[[8~ü8Ùl–MMMÇqz…ëº&•J±X,¦799‰îîn áÕ«W¸rå ªÕ*îÝ»=þׯ_G.—Ã`Û6:::èáÇš}x‡ïêP)…L&ƒÞÞ^´"·, àû>öîÝ Ø³g|ßÇÊÊÊG € ιn6›Ì÷}H)ÁÃÀÀ”R˜™™Áýû÷‘Íf‘N§Q«ÕpçÎ,--auu®ë†Žã€1¦…eYêÙ³gxôèëééaccÅb®ëâìÙ³8zô( ¯¯»wïÆ‹/Ëå055)%`qq‹‹‹Æ²,Åü^ÁÊårÐh47oÞ„Ö/^Dww7<ÏŒ£Ñh`xxŒ1H)ÑÙÙ ¥îÞ½«èƒþLW¯^Åêêê·ïÞ½ûy*• †††Ä¥K—‰DÀ9‡R ŽãàÂ… BàÚµkàœÃ¶mœ;wétzvv–Åb±G¾ïÿ”FGGà‡RÊ8Žó£'Nèl6ËÖ××Á9!tuu!cmm /_¾D{{;ÚÛÛ1??oŠÅ"Ù¶ý­õ1cLø·Öú–eýõÁƒæðáÃèéé K,ìyÆ`ÿþýØ·oˆÍf¥R)ˆD"’ˆF‰è1Á$MqοÖZó‰‰ ccD¥´ÖáZëð{–J¥ ÑhÈH$r#Nÿ´ Ô'"–Ëå.[–uãíÛ·òöíÛA«öZ_´%Î9fffôìì¬ØµkWÍó¼ßÍÍÍ…=‚Ÿ:uª•-//¥Ô?-Ëúòõë× ¥”>tè)¥ÂÆÂÃÚÚÆÇÇ”’ü’ˆfˆHPÀ …BØÔc‚1VÓZŸ·mÓÓÓfaaœsh­ADð}cccçyŒs~™ˆnÛQ(ÀZ›m…|c_Ÿœœô777ÑR.—u­VÑhô±ëº£gΜÁNClƒÅ'Æ!ßh4z£ÑhÈ[·nP©T0== Û¶¡µþµâ}©TâÌÎqÃw¾o4ý²^¯'677Íüü¼r‡K) `ÌrÜÔG£°cd 1¦16庮Bp!D9“É|^­V™RJjøQú߃¡Å÷oƘo,ËâœóšRêWsssPJáÿé¿ÌÁlXÌaIEND®B`‚routino-3.0/web/www/routino/icons/limit-37.9.png 644 233 144 1477 12573351606 14701 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ôIDAT8Ë­”ÁK[Y‡/¥šy67B #•„"ƒØ±RAÜ(ÁØ}‹ €0ëY¸hR\È,œ©m“­ÿ…,Ò`Š*!êHj*É{ïÞo‰©fv^8‹sÏ=çžsøÎ’D(B !‰pø¤5ç=Ñ(ôô¢Qpœ÷Hk-»B-?¡«@á°ƒäðøqé®[ca²YK¥Õ*T*M}a\·†ô¬õÞiùKtt„èìñxé#33P. ÀZÃõÓÔÊeÃÌ H‰ÇtvŠŽŽèëé´‹Tbi  X||¬ý*Ww`KK •H§]úúZeJÏÉd0àùÆó°Öâû~[¬µíçá7ðÈd@z~Õ³$®ûÙîí54¦U‘忎µ¶i3 Öîíë~FJÞúUú§OÇœ'Ȯb1´ñꕺ»»åyž666T*•´»»«H$¢X,&ÇqT,µõæ¾Åœž{÷ åòwN>KFÊ“ËñWµjzîÞ%“É088Èòò2“““Œã8ÛÛÛ ãÇû÷ù; oßb¤¼LW—¥ZåçOüþâÙl–ááavvvX]]e~~¾]æúú:£££üôà¼| õ:þ;VÄb†ÓS.ÎÏ™%S(¨Õj¤R)J¥R;Øáá!CCCLMMÑyû6¾~ A€ßÕeBç9ŠD´ùî~~øPÙlVápXûûûÊårêííU2™T£ÑP¥RÑÅÅ…R©”&&&Å”H$¤/_ä€#+åÙÚâÌä£GD£QÒé4™L†••Žáàà€ééiúûûù¥É¥as¤¼ÖX\üz““ü&˜œqyyÙdËN[í¨×ëa= `q¤µo83-ÎŒ1mÎþÍ›µÓâÌ€åg_'`nÀ³¾Að¿l3{¹¹kp£³y£[ãF÷Ù nÚ6¨T”á.IEND®B`‚routino-3.0/web/www/routino/icons/limit-105.png 644 233 144 1431 12573351602 14570 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÎIDAT8Ë­”ÍK›YÆ÷*I|ýŠq‘Hƒ‚U«ËY´{‰da Ž‹BA]*¸t30ËvŸ¿ EÅ.¥ÌJŠÝJiE³3«S  IÞ÷½÷™EbêÌtéç¹÷œs?xžƒ²Ö ¬¥R¿Ê2¦¢tZÊdœÒiÉ˜Š ÜÙG`;uˆÛF©”•J)Á Áw­­IoÞx]\Hß¾Im¼¶&ÁwÁ‹N¾éÔƒ «dMLL ªZ\”j5')–÷Nw­cÕjN‹‹T511©d%e³¨X Ÿ´µ%I-I^Q$E‘äý¿]“¼¤–¶¶$ø¤b1P6Ûy&¼ÔÒ’$…ŠcÅ­–œ÷’$眢(’ïà(Š5›ŠÂP^ µ´$ÁËÛ?{¨ ¨ëôT’|Üju ½÷?;§´oxz*A]ð°çø“çÏãÙ3§(²6‘àèèˆ8ŽÉd2T«UvvvÈår¤Óiö÷÷9<<äc¥Â¯““&™Ï;Õj}æø¸Á±^¿–$'ç´»»«ÞÞ^ííí)ŽcÍÌÌtýääDù|^ÅbQ+++úòù³$9ÿê•Ç–ááG<~ `½„1†ÑÑQ988 ™LR©TÈf³loocŒÁ9G¡P ÷àkž<ááGkE"€÷žR©ÄÔÔFï=ýýýA@__ËËË 677ùëí[ àzzÀZY¼7„!wMa2>>Îåå%gggœŸŸ300ÀØØ«««är9þþúµ]†à½±Ôëx÷Àã=CCC4 æææ˜ŸŸgzzš……666(—ËŒŒŒ0;;ËïOŸxûþ=Ô딵¾.Iq‡º¹¹Q£ÑèòìúúZ®M5›M]]]µq;?ÖúºåÿñLq|G=¾ÛÄ9'ç\—k®MÚñì§ ðwÞ6íÆ’üYýG÷ªÍ{÷:ÏîqÒþ¡Gz4¾%bIEND®B`‚routino-3.0/web/www/routino/icons/limit-109.png 644 233 144 1373 12573351602 14601 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“°IDAT8Ë­”=K\[†Ÿs®ÎȈ:ÄBµ1еó&Øh'b¡þ;ÿBÒˆˆ¿ …TÓ‹X†¨EÐ`,f@…kÀÀŒ3çìç3~å¶.ذ߽×kï÷]DZ ØÒ2(lE'æóúêUj>¯Qt"l7îâFrŸ¨¥%"[„÷ær¿]YÑÏŸƒ——úë—^^ÖñÊŠær¿…÷ ÿ¨f2±Ù,öõ ?œ›ÓB!UCH}juœX(¤ÎÍ)ü°¯oÀl3™»ºp~>'|wmMõN ÖjZ«iëþLƒzçÚšÂwççsvu5Ú„.,¨VM“»;ÓTMÓÔZ­fxŠ+Ójµî¿° ðáþÍ^›Ë•<;S ÉÝÝC`áÙ>M»IbÐàÙ™ær%á5¶««ªI¨WsßóósUOOOÝÜÜôââBÕ££#766<ÿùÓF¿‰«« Û_ýôI55MÝÙÙ±©©ÉÝÝ]“$qttÔÑÑQÇÆÆ<88phhÈÉÉIß¼yã¿WWªiøøQákLGÇSSqP¢(¢³³“¶¶6öööÈf³œœœÐÝÝÍúú:ƒƒƒ’ÉdøçË€8}÷::ÆbâX2B,..2<>¦¹¹š›!Ž !¢Zå©©T«Uz{{¹¾¾¦P(P,éééa``€ééiòù<ýýýDI!D1¥Ò7ö÷!ÐÞÞN¹\f||œ‰‰ FFF˜eii‰b±ÈÖÖËËËüýö-@øëàJ¥oÏ~³AHooo-—˼º¹¹y E¥RñêêªN™ºÿ³ß|Æ3“ä‰z¹•¦é3Þ¥÷JøƒgÿS@x’ð>é3\«Ù(ú‡^T›/:5^tž½à¤ýô­k¥8×½ÄIEND®B`‚routino-3.0/web/www/routino/icons/limit-8.2.png 644 233 144 1336 12573351604 14600 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§““IDAT8Ë­”¿K#QÇ¿Ù;bx¨‘S ¨¸«Dbk“ÂBÄB­ÁB±²ð/°"X –vg/þÛ‹DmD1¢bŠ“ dwßû\±›x9¹ÎÇû53oæû¾3B’ð<ÉC¹Ü¤=2™*}}ð훥¯2™*Ò^z/$/µj9Êå2HrHŒi°º ?:îï¡^‡ûûd¿º Æ4*©~&µ—Èf=ººD±øéŠÙY¸½µ@Œs–¿%ÙÇÜÞZfgAº¢XüNW—Èf=Q(ˆ¹9ƒtÎæ&@pDD8÷>Zgà€&›› 37g(Ò4¥æçBâ†DQ„µYk“ó0„8NôççAÚia6Š1¿¹¼L‰"\Gf®=·×€kExy ÆüFÒkk± C‚  R©pvvÖŽàôô”ÝÝ]ªÕjâ4ÑY[iOH¿8<$ p||ÌÀÀKKKŒŒŒàû>¾ïÓÓÓC¹\¦X,AòXAúå)Ÿ/ijJ’ï¨ÕˆRÀgffX__`llŒýý}Â0Ä÷}Œ1looóòòBÔ¢ @­ù¼kcfSÌ...(•Jô÷÷³²²Âõõ5år™­­-Œ1LNNÒÛÛËÑÑ úï˜uüfJHšÍ&ÄqŒsŽz½N£Ñàññ‘»»;jµooo-®uüfÏlµùd­m¯?HâèÏ>TiDÿ#®{/«*àSkóS»Æ§ö³Oì´h¡Lùî9ÚIEND®B`‚routino-3.0/web/www/routino/icons/limit-6.0.png 644 233 144 1276 12573351603 14576 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“sIDAT8Ë­”?K+QÅÏn±‰ëõ! 6‚¯‰•ZÑÔ6ÁB[%ùñ[˜ÎÂÚÆÎJlü‚"BL¡FFŒ"ˆàî½÷÷ŠÝä|¯ó²sgÏvfÎŒ„$|ßGò‘D>ÿiÏ»bt~ý²ŒŽ‚ç]!ígß…äg<¡^ |ÞCòØØÈ#í†ïT*ptäh·¡Û…v;½W*†ïH»ÞËøAà“ˉéé¤Êehµ,`pÎòõ¤wC«e)—Aºazz†\N/&'ÅÚZˆtM­ð 8’’œûûô|à€Oj5®Y[ ™œÌҔ꬯ăM’$ÁÚÁ³Ö’$ .IÀ˜¿¾R½W³YÂðF#M$IpÎ}ÉÌõßvÌÑh@¾!Í iŸjÀ¸8 ÙlR¯×¹¸¸À¤D{{{ÜÞÞ¦AS¼¡Zi_HçâÀt»]–––X]]eyy¹Oìt:ÌÏÏ377G±Xäåå…¬x–ÃCÎ}Œ,¨T’•|I:==U³ÙÔøø¸VVV466&I:99Q.—Óåå¥ …‚Ž%)å•JÒÈÈ‚/ßGA Þ1ÆôèììL’DZ¢(’$ }||ô9 É÷ñ圧8–—ù£(Òðð°¶··511¡»»;šššR§ÓÑÃÃîïïU,%)åűäœ×¯`³v³¹¹ÉÐЕJ…ÇÇGy}}ekk‹(ŠØÙÙ!ëLÊËj6ÐÍLcxzzÂZ‹sŽççg¬µXkû6Ðð@7ufLÜ ÖÓÖ€ÿ?:û6óOáöí ó}~t6tküè>ûÁMûT5‡³”9»aIEND®B`‚routino-3.0/web/www/routino/icons/marker-52-grey.png 644 233 144 2740 12573351600 15622 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“•IDATHÇu•]h”Û†ßý—ï›OơԉÁ4a‚df‚“¤ÄÞˆx"˜’€â/Ž­Ð›¶”¦0Ò›æÂ^Ò+…¨X«âø&§%1¤ˆ?‰“1Z‰&3&“NœÔïgïÕ‹“ÌIôô…{ß¼¬õ¬µ×fétkâRJ¤Ói“Éd¾ ¢?ù¾ßâº.`øAdYSJ=fŒ}›N§ïg2`k¦‚ˆ4ýT)ÕçyÞW¾ïS8fµµµàœW1˜™™A±X$¥«ªªê÷}ÿ·Œ±Ƙ %ND@”r \.×E"‘àÀ<™L2˲ð©\×E.—£½¸¸ø•ã8¿ÐZ ¢3Ƹػw/¨‘RþÓó¼ºX,æ÷ôô¨úúz&„}RJTWW³x<Îóù¼ÿþýûˆRê—Æ˜¿ÑDGGüeuuu_,óOœ8¡,˂֌ý€’s^¹´Öp---âÍ›7þüü|ĶퟄB¡¿sÏó¾ô<ïëH$bº»»Õº‰”œóJ¬›1ÆÀ9‡”DèîîV‘HÄxž÷µçy_Šýû÷_t]·æÐ¡C‹Å¬¬¬`jj …B X\\ĶmÛÀ9G>ŸÇ‹/°²²‚p8 pJ)ÊårL)Õ ƒ h ‡ÃÔÔÔÄ×3yþü9®\¹‚p8 ×uaYN:…‰‰ \¼x[·nE©TB"‘@OO ™LòÁÁA*—ËmÒu]ŠÇã< Ak !¦§§ÇqüøqA€P(¸yó&ZZZpäȼ}û}}}hmmEcc#ÇAmm-{ò䉑ß÷€o"ÂÔÔΜ9Û¶qøða466"‘H`÷îÝ!lÛÞ4ÃkgÎ…¦T*Á÷}!Zk¤R)=zÑh.\ÀÒÒ:;;±cÇŒŒŒàܹshnnÆ®]»* +—ËàœiÛ¶~õêÆÇÇykk+‚ @WWÇ”uuu8}ú4æææ …pþüyø¾ÎÎN¤R)cÀ9Çëׯ1==M¶mkàRJ~ÿþý T*Ak³gÏbtt0>>ؾ};úûûAD8yò$š››áyˆA ›Íjö½þ*Ž;6üñãdžR©”šŸŸÚÚÚ¸ïû¸{÷.£###æÑ£GrË–-³žçýááÇ•Ñûöí[/‰ÍÌÌÖú_¶mw½{÷.¢µ6 Lk Î9ˆœs \¾|™”R À¯c#Œ1 @Ïd2•¥Î9—œóYcÌ Çq044D¹\Bˆ ß÷ÑßßxžÇ…}Œ±KÔFd2ðõÚ>ã{ëÖ-yy¹RúÀÀ€™•–eMº®Û{ðàAl4ÄX|büß«W¯ðìÙ3 Áqc~#¥\½sçŽ@w‡Øxù1¾–euåóùÈòò2ér¹,”R¿ÐODŽ’Úôõ6|Ù@@Dû9çß¹®«¥”BJ9L&¿˜˜˜àZkó©á¦òÃ:ßÑ·¶m !ĬÖú×OŸ>…ÖÿOÿ¬î̪:£!PIEND®B`‚routino-3.0/web/www/routino/icons/marker-90-grey.png 644 233 144 2661 12573351601 15627 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“fIDATHÇu•_hTéÆŸ÷û3çÌQŒÃ(2U&"ù#e(«Ä .ºsc³Š Ù›Š´½iKYa s×›õ¦·½r%ÜTD'7Æ’D)2 d´&8NÔ™‰ëùó}_/ÌœºûÀs‡ç{¿ßû¼ß¡l6‹1!²Ù¬ÎårŸcþâû~Êu]€ðƒŒeY$¥ü}“Ífÿ‘ËåX €vL¹1FcH)¯yž÷•ïû&‹Q"‘c,tÔZc}}õzÝH))‰Lú¾ÿ{"zAD€˜1F8"„(´Z­#ñx<8wî ˲ð±\×Åòò²) êÕ«W_9ŽsJ)uÎó_"büÌ™3@·â_žçI&“þØØ˜@(—Ë(—ËÆ¶mÅüYÁ …Bðúõk&''Q¯×166ƪ¿¿ÄÒÒ X,BD"c òù¼¢÷ú¿|ùòü»wïz›ÍæÏkµZJ¥çù|³³³ØØØÀÈȺººÐÙÙ‰……<|økkkH§Ó8v즧§õêê*·m»äûþ¯hbbK)ç···6<<¬3™ {ñâ666pøða8p ~³ÙD¹\Fgg'zzzP*•Ì7Èqœÿi­aŒy,cÀ†Öú׎ãüs~~Þtwwcpp]]] ¢ÐÐƒŽŽ¤R)¶¶¶ÏçƒH$"‰h‚ˆ @@Ñ,cìDÄïÝ»ç×ëu´ÖáÌ·Ûã933Ôëu‰D¦úûû¿Àí€úDÄNž&''ÏóçüM;‘ËåÀÚ7;ú„ïÝ»wýF£NP¡PЕJEX–õØu݉ .`·!vÀâ#ãOøÞºu+€GannŽã@ký;!ÄÛ™™ÀìæÎw?ü_˲¾¬ÕjñF£a–––T«ÕâRÊ?˜4Æ„w…[ `×/[Œ1iÆØ¬ëºJÁ……ÏWVV˜RJløÁöC›ï}cÌ7¶msÎyE)õÛb±¥~JÿdÞ¾§Ù,õÚIEND®B`‚routino-3.0/web/www/routino/icons/limit-2.9.png 644 233 144 1341 12573351603 14574 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“–IDAT8Ë­”¿K#AÇ¿»bÅx"6BгQP´±±°ˆ‚b¡•…–‚ÿ„",,;+KÛØM!(©¢FBüîìÌçŠÝä.Èu,̼yóÝ÷¾ïûž„$|ßGò‘D&óéÏ+“Í–l<¯ŒtÜ ÉOÞ 52Écu5ƒ´K¼²±''ŽZ  ¨ÕâóÆÁ+Ònâï%ï%R)ŸtZärÃH·,-Aµjç,ÿ®øQ­Z––@º%—&©”/Äòr€tÍö6À'à0Œçþ~M8à“ím®Y^HÒ”~±²EØ0ăµíYkc»1E±ÿÊ H¿šœÏÜÜĉƒkeåpÎ}Ý.sÜÜ@<# é€ÍM€È…!WWWìííQ.—[5íûûûT*•4öØÜé@H%ޱ`...èîîfnnŽ\.G©T \.322ÂÌÌ “““Ôëõf”–ãcJ¾zz¦4;+$_’ªÕª¶¶¶tvv¦®®.•J%IÒùù¹úûûU,•J¥tzz*I²’¯ÙY©§gJôöZ’¿Ø˜ŠÅ"ãã㬯¯câêqwwÇÄÄ ¤ÓiŽŽŽ0õ:ôöZ_Îy C9I~G‡.//5??¯µµ5 EQ¤Z­¦——)ŸÏ+›ÍjhhH’äIRJÎy-ÎLÂY¡P ³³“ééiúúú8<<$ŸÏS©TX\\dpp¸ÜqÔ-ÎÚªIñþþÎï§'îïïyxxàííF£sŽ[IÀÚªÙ¦³DŒ_–s®%ë\S´_tÖÞÆàŒù"ØA‰¢ÿtÀ·öæ·Nogß8iÿvή¯ÆGFâIEND®B`‚routino-3.0/web/www/routino/icons/limit-61.png 644 233 144 1242 12573351602 14511 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“WIDAT8Ë­”=K\[†Ÿs¢ã0#~įRÈE0©Nm#ƒ˜ÊVôø32½µÍtk»élb EÀ Na! 8”Ì9{?·˜O¯¹/ìbíõ®µ×Þû] Ó4RËå„3“ä‡ úþ}paA“ä‡p6ð#¤ƒ8d˜¨\N„ÄÏŸËÂ+•ßëׯÑû{ítôþ¾ok¥ò[ø2à'ƒx°TJ™ÁõõÂ/÷ö´ÝjaŒÁIôíÂv;¸·§ðËõõÎÌ`©”âÚÖjá§§§ªÔhžkžkŒã5ÜÓ¨þñôTá§µZŵµÁ5¡îÁjÏ<× 1š÷z†0.®( CŒÂ0iσ…úðÍ>Z©t½¹éŸ‚1FcŒ·‹EñbÏ¢èóon´Ré Î<9Q-ÌóQ@«Õ²^¯{}}=Šo6›ÞÞÞŽTWxr¢p†ðÍFC5ľÓN§ãöö¶»»»îììxwwçÅÅ…SSS6ú\ó<Vl4¾¥ÌÏ"ËÒ \^^ÒjµXZZ"Ë2 !°ººJŒ‘Ò %Ë`~þSJšJ©Ä$Š¢`yy™,Ë8??çêêŠýý}677yzzâJ%HSSbLèõH’€ÙÙYªÕ*GGG¬¬¬Ðn·^V5‰^bLRºÝï4›ñÝÀW«ÕØØØ Z­²µµÅáá!sssLOO“ô“GšMèv¿¿úÍIM=<ß:`®½9ש1×y6ÇIûËÁª²I ¿IEND®B`‚routino-3.0/web/www/routino/icons/limit-30.png 644 233 144 1266 12573351601 14512 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“kIDAT8Ë­”±JkA†ÿ³\c<ÒXX¼¢lì;Ë ˜TV6ÉèØšÎÂ7H§| ±QF„`Š€£æìîw‹sbŒÞÒ…)fw柙FHBÆ$ƒ$Òé¿H'Á¹äóŽ\‚à é$y’Iü„F@ét€P©¤‘ŽÃ7ªU8=õôzðø½^¬W«†oHG‰}øK¤R†éiQ(, ÝR*A·ë‹÷ޝ'Ö-Ý®£Té–Baéi‘J17'¶·C¤ûû€'Š ŠÀû±ŒîÀìïƒÔb{;dn.ISªS. ±¬Å9GE8n¤{ïÁ9°6¶/—Aªj¶B¾ÐnÇ­Å3yœs1ག§Ý†0|AZÒ µ€ehµZÔëu...¸¹¹áøø˜N§ó š¤l©Õ@:Ò%Füျ»;òù<•J…B¡@³Ùd}}ÕÕUŠÅ"OOO1` æh4@º4Êf×´¹)IFÆH’¬µ:<¹41š‰>¶ù6¿:›¿º5~uŸýâ¦ý·k‡Ê@—IEND®B`‚routino-3.0/web/www/routino/icons/limit-35.1.png 644 233 144 1470 12573351606 14660 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“íIDAT8Ë­”ÁKÛIÇ?ó‹&ú£!©¤sR³"[=¼mÅ(4¿“‡µzü=¶7Þ-­iÅ‹'©íUŠ-t±{ËÁ FˆÄº&¿ßÌw‰º.ìÍófæ}çÍðyäyžÀ žžŸ2æ‹Òi©¯Ï*–Œù"Øèì#ð:qˆk¡ž#0 ‚Á ùþ…¥·oŽ¥³3éø¸í/.J¾!xÑ9o:ñ xÜS"ò‚ï*¤JÅJŠäœÕ¿­íGªT¬  ¾k` ¯DÅãÊfÑì¬/ø¦•IjJr C) %çnÇõšä$5µ²"Á7ÍÎúÊf;Ï„—zöLVj…ͦl«%I Ãðf8çn3Œ"Ea(+µT,JðòúÏË÷ÏÝÑQûFk;/rú?‹¢H.ŠÚçŽ$ß?<ŽýkzþüW3?oÿüúÕÛ|ýšÞÞ^r¹¥R‰½½=!‘Hàœ#‹ññÓ'l³iŽŒXU*½æà †…½{§¿ÎÎl_*¥ 488¨r¹¬ááa ÍÍÍ©Z­Þd¶½½­x<®7››’dÃW¯$8è"™|ÂÄQ½î­®­ñ(›¥V«±¿¿O£Ñ@ÓÓÓô÷÷c­Åƒ1†L&ƒ3ÀcbR©'ž×Õ%œã—|žßççÙÚÚâôô”¡¡!‚ `ff†ååevww‰Åb„aHŒqyy ÝÝàyò¢VËðàoJ%~{ú”r¹L2™dgg‡ÑÑQÈårT«Uêõ:ÖZœs µÅœ3^ìÇϼÏt±è~ÊdH¥RäóyVWWY__'N3>>ÎÔÔ“““\\\àû>Ý]]Î|øççŸlhiI’¢ðêJ''' Û`êªã[kåœS­V“í S¯×õw£!I‘––$ظÙípæœk³ÔaíZ쎵Eïpv[Å¢$µ\Jm 圻#r3"¹vöÿ©€{­Í{í÷ÚÏî±ÓþœR!*눂IEND®B`‚routino-3.0/web/www/routino/icons/marker-10-grey.png 644 233 144 2553 12573351600 15616 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“ IDATHÇ}•_hTÙÇ?çÏ{se0ãPÿQ"‰ˆIˆø°öA™—¸>•O .}Ph Ò.e‹”Ùe^¬/}í‹P£S(b|èK@XÄ2ÆØ§ &266˜ÙàhîŸsÎ>lfšde¿p¹çîùžïùþþQ.—Ù„ÔZS.—m¥RùØ9w-I’“Q9@ð8ß÷…çyÿB|Y.—ÿY©Tdš¦@l’*çœqÎíó<ïFÇŸ%Iâr¹œ( H)»ŒÖZi6›Îó<‘ÉdÆ“$ùâB Hçœú´ÖÕv»Ý—ÏçÓ³gÏÊ¡¡!áû>;Esss®Z­šµµµÏÂ0ü…1æ¬sî¥Bª3gÎ8àçZëÅqÜ×ßߟ\¼xÑ;räˆPJáœûÑ£µæàÁƒâøñãryy9Y]]Í{ž÷Kkí]çÜwêüùóy÷î]±¿¿?¹té’Î9„!RvÇÎ9Œ1„aÈÉ“'ÕÂÂBòæÍ›|?ëééù»Œãø“8Ž?ÏçóvllÌë,êtÞ[祔h­±Ö066æåóyÇñçq"s_'IB©T"—Ëa­íªjµZ,,,l#\YYáéÓ§¼zõ ¥Ær¹Åb‘$IpÎ}­Ó4ý(—˹ááa ¥ÄCš¦LLL „àòåË!¨×ëܼyß÷yûö-¥R‰ÑÑQ†‡‡åôô´k·ÛÉ(Š\¡P===c¨×ë\¿~z½N6›ízzšB¡ÀÕ«W¹pá=¢Õj†!…BADQääâä6ÿ:Ä•+Wàýû÷lllÐh4àØ±ch­i4ÝM7y¤VJÙõõu™$ žçàû>RJ<Ïëªï$~'o;B6+ €v»”ÒÊ L½^·³³³Ý…Bg“ ’$@k Àüü<óóó.#¯´Ö²Z­¦Íf)%ι®E™L†Ã‡S«Õ¨Õjh­) 8ç¸ÿ¾?à¯rÿþýßd2™¿­­­éÉÉÉt«º(ŠºÊFGGY]]åÚµk<|øb±H6›errÒ¾~ýZe2™Ù$I¾P'NœÀZûmcKKK{Œ1öèÑ£ —ËÑ××Çž={pΑÍf¡··—Ó§O322Âìì¬{ðà Ãð½µöœ⿪T*i!ÄwÀ¬çy¿zùò¥Ý·oŸÜ»w/»wï&ŸÏw­pΠ··—õõunݺ•Zk•RêÀ?-ð„ÓRÊß !Ô½{÷’V«…”r[à:Ĺ©©©´Ùlz™LæöàààŸ ¤F™!ä©S§nø¾»ÙlzwïÞMwÖ~§\•R<~üØ>yòDïÚµ«ÇñjµZ7ÀªX,v~‹‹‹ÎómŸ.--å1v``@cºY!¥dee…;wî8Ïóðk!Äc!„ €¬T*ÝÜ–Rj)eÃZ{) CfffÜÜÜJ©n£I’„ñññ4Žc©”º!„¸ x›6R©TÁ&~Ò_€jµj†ö}ÿ?Qýéܹsl%dÓXvÿÈ߉‰‰àùóçÌÌ̆!ÖÚßj­ßMMM)Àmõ]mýø¿¾ïº¼¼œoµZîÙ³g¦Ýn+Ïó¾Æs]·ˆb{h-W¶Rç\IJ9E‘ÑZ+­uuhhèã/^HcŒÝI¸íø°¡ãï#çÜ—A(¥TÃó›Z­¶­{íÄ÷N²˜!Yô *IEND®B`‚routino-3.0/web/www/routino/icons/limit-33.1.png 644 233 144 1446 12573351606 14661 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÛIDAT8Ë­”AK[YÇÿïé¼dž-‰&Ä@"(t#t=Ühv#Á¾îÛ~€|A—í^:ËWZj…~ƒ2u#h ;à"‹©BLZ§/÷Ýû›EbZÛ­.Üsï9çžsø#$! ß÷‘|$‘ÍþŠ´‰ç½%Ÿ‡™K>ž÷isô.$d'té(›õ<îßÏ"=" ?±º ÛÛŽNÎΠÓÊ««†Ÿô½‘½Død2¢Z­!½gyÚm ¤8gùv å”vÛ²¼ Ò{ªÕ™Œ_‹¢Ñ‘i6Àa Î}Ý—wà€„f¤Cbq”¦ô˜{÷°00I‚ °ÖbŒÁÚ«’¦¤Æ`a@ôø²f· Ãswt4üqdèœû.C÷¯—¦Cý£#Ãs¤ÛJ<|ø›÷àýçÝ;?~öLA¨\.ëððPq+“ÉhvvV€$É÷}ýýæl’xÓ·nYÚ퟽ýý YiŸ—/ù÷ìÌÎärDQD­V#Žc*• QQ.—ÙÝÝG¸µµEiR7oÞÑ‚Òn×_ߨP±TR§ÓÑÅÅ…Ö×׆¡Ž•$‰$)MSyž§B¡ çy’äkaAÊåîˆéiËÇô{=VVV¨V«´Z-¬µ4 æææ888 I–––øëÉ̇0=mýt0ðt㆞¿x¡ßïÞÕöö¶*•ŠšÍ¦êõºvvv455¥½½=õz=¥i*IrÎI£ÊÉ9ÏŸøü¹¥W¯ôG¹_ åóy•J%Åq¬ ”Ëå4??¯z½®ÅÅEõû}IR†úirR’œ÷úµt~ÞÒ&kk©ùò…““ÌLŒ1cÙ9Çéé阹n·Ëý>@ÊÚH›W8³#άsXkdžÖÚ¸ñx…³¯Eg üÖñ9MqÃè¿ë€kíÍk×:Ï®qÒþ„×oÑT<§nIEND®B`‚routino-3.0/web/www/routino/icons/limit-69.png 644 233 144 1270 12573351602 14522 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“mIDAT8Ë­”?K+AÅϸ‰«`„T"ú*-D[-‚‘4’Bkÿ|€€_Â4b‘oÎJlì-jñ ®U %‚`¡»;ó{Åf£yÏ×yaŠ;sæÌÜ{ϽB’0Æ $‘ÏÿBjáy· P*Y ð¼[¤Öà\HfpO(#Êç=$<Ò1AðÆÁœ9 ß‡‡‡Ô?8€ xC:à½Á} ß7ärbvv鎭-èõ,àœå«¥~B¯gÙÚéŽÙÙyr9áûF”Ë¢^~Óh|Ž8†8ç>W¶ø Ñé7õz@¹<Sj²½ Ç`-Ö9â(ÂÚôsÖZâ8Æ:ÖB’¤øímšY΂WºÝôEkqÎáœF—¦‘:ddŽn‚àiAH-âxH†!Íf“N§Àõõ5'''ÜßßI!'‚ÔR‡vÀºô~¿ÏÚÚ›››T«U...X\\duu•ååežŸŸSÂ(°´Û uŒ¦¦VT©H’± Iº¼¼T†*•JªÕj ÃPÅbQWWWò}_ççç’$+I’Q¥"MM­ƒ|__-IMOOk}}]§§§*‹ò]]b`àÒwfgáì,f¥­;ÎÎ"fgAúÎÀÀ ººD2é‹Þ^17 }cm   aaf÷§ó4Y[éss½½qšR‘…€ÎášM"3¢(" C¢(º× ¬ÕjÛ/,€TìÔì%APçøÀ\³‰Å@föûÞúýçÆñ1A饶XYpq4J¥•J€r¹ÌÆÆår€££#677999!Î×±²Ò–>óþ=@D±½½M"‘`ww—J¥Bww7SSS ²··Çøø8### ñב½{Òg_Ùì+½y#I¾<ÏSOO‰„ªÕªVWWµ¿¿¯¾¾>­¯¯+—ËéððP™LF~üØö{ýZÊf_ùò}”LJ’ÌL…BA£££ªÕjš˜˜ÐÌÌŒ†‡‡566¦ÅÅEµZ-IR&“Ñíí­$‰gÏ$ßÇ—™§Ø #Î9¥ÓiÕj5MOOkiiIÅbQýýýº¼¼TµZÕé驆òyI’çœdæùª×¿¨T’$“™$)¥ÓiÈ9§e³Y9ç499©|>¯ùùyM´Ëc‰OŸ¤zýË£nÆ„äææ†F£A£ÑàêêŠZ­Æùù9www˜×××mÞµíuóÏpŽÿ3»'oþ'Ïþ5ö°C܇äµ0$ú xÒÙ|Ò­ñ¤ûì 7íß®¤k•KKIEND®B`‚routino-3.0/web/www/routino/icons/limit-31.0.png 644 233 144 1457 12573351605 14657 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“äIDAT8Ë­”MO[G†ß{AØ\ð¡BB¢‘ŠaY „’(ê†]-WØÞ–•ùüƒfïXø (гHÍ`ņÄÉiPSÌ—L|ïyºðGiÓ%#4ç̼gÞ3óž#$! ×u‘\$þ€TÂq„áaÃà 8ÎR©½/$·êŠF$‡\.ŠôÏ»¦P€rÙrz ——pzÚ² ð¼k¤—íóN/Ñ×版ÉÉ)¤¤Óp|l€k wGË9>6¤Ó }drrŠHDôõ¹btTd2Ò!ëëMÀ`í?³ã 4Y_éLÆct´¦Tde~Ðlb|¿K& CŒù7AãûÍ&|VV@*vÞ,…ç}±ÕjëÆ6ÐZK†Xkÿ“©mùŒÁ‚µÕ*xÞ¤”J¶P(‹ìîîvÁÛÛÛuYT«U666øóÓ'€Ð •d¤÷¼}Ë——fx`€|>Ïøø8;;;lmmÑÓÓÃææf7øÙÙóóóÌÍÍ1ýèW`xý#½w•H<Öóç ëu÷·/”Ïç566¦F£!×u522"k­:£R©(‰h_‰ýþê•«tZ6{Üëöö"ké©)M¬®ê×ÕU]]])‘HhaaA³³³j4Ý`a*K’ɤ77R$"¹.nèûŽâqm¾y£gOŸª\.+‹ioo¯ vG’T«Õ411¡Z­¦““ýõù³~œž–¾~•ŽÛssóAïÞéçlÖ>|ð@CCCJ¥RÊår’¤d2©þþ~IÒòò²–––´¸¸¨™™ý’Éè§'O¬*¹×ׄTbm ¾}£V«´„ @½^çöö€óósŒ1c¸¸¸À4›!kk­ß¼«3ÓÖ™1æ;}ÝÕ™1ŒÁüÎZÍø6 ­§ø»ub[ì}²Ù;p¯µy¯]ã^ûÙ=vÚ¿o|hÆ’AÞÐIEND®B`‚routino-3.0/web/www/routino/icons/limit-8.7.png 644 233 144 1362 12573351604 14604 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“§IDAT8Ë­”±K[QÆ¿wÓ>Óg‰ÚD³J;e3ƒ‹‚8‰CÜ!ƒþþ…Žíâb6§èèA7!‹` Íà`@ÄD(bòÞ½¿ïikëè;œ{Ïù8÷;ß9B’0Æ $‘NBªày?†,ÃÃày?‘*É»L’'ô”N{H++i¤¯Á/Ö×áûwÇå%t»pyûë뿾&ñ^’/áû†11ñ©ÅÒ\\X Â9Ëßû–¥%ZLL|d`@ø¾ù¼X^šlnôGB‚sÎã8 Çæ&HM–—òùä›Ò7J%€>Q„í÷ Ãkí_E9Â0ŒÏÃ.íS*ô푳ApÇÙYœ†¸g?s¼hQWxvAp‡TH}–¾¨\žÕÚš% ÷ö­~«Z­*“É(ŸÏK’ÎÏÏU­VÕl6urr¢÷™ŒFFF<²YëµÛïtt”Ò{{D`êõ:¹\ŽÕÕUÆÇÇi4033Ãüü<žçQ¯×ãÁ²·ÒÑ 57'IF’¬µ ‚@‹‹‹jµZêõz’¤ÙÙYj{{[“““ZXX³V©TÊhnN*¾‘1È÷=%vss£±±1íììèúúZ¹\N’äû¾:Ž*•Šjµšž™ïKÆ`䜧~?V°¤Z­¦ééiíïïkppPFCÝnW’´»»«ÑÑQ YkeŒ‰“ú}É9ï‰3›pvzzJ±X$›ÍR.—i·ÛLMMᜣT*±µµ•43zìègBª°±sk‡^¯ÇÕÕQᜣÓéàœãöö–ûûû?òˆã#66@ªü§3†OÚ²Öþ§³'ÿ½8$ý ð (ûg^u6_uk¼ê>{ÅMûâof^z~ÝIEND®B`‚routino-3.0/web/www/routino/icons/marker-79-grey.png 644 233 144 2700 12573351601 15630 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“uIDATHÇu•ÝkTIÆŸ·NÕ9'§1IokVb “&1• LÁOpu3¹ÈÜl.v/a7,sáÐ Ì07ã_à…0C"ºAmÁík 0šh2D=²¶é¤íl¤{9Uï^lº'~Ìç@ç¼õ{ªê¥t:M )%Òé´Éd2Ÿ0ó·a~èû> ü"v‡”RˆèËt:ýL&#¢(´ij1³fæß*¥ÎAðy†Ç©½½Bˆº£1KKK(—ˬ”"Û¶ÇÂ0ü3­‘@K‚™5€)e®R©t$‰èرc¢··—ÇÁÛò}sssœËåt©TúÜó¼µÖǘùg"ÖÁƒ@›”ò_Attvv†ÃÃÃ*™L’eY`æw†”­­­ÔÓÓ#ŠÅb¸¶¶–PJýÎówfþˆÅbPJ}]­V?H&“áÈȈjjjBE`æzuD!ˆÌŒ(ŠÐÜÜŒ‘‘•L&ÃjµúRêëX,Á§A|‘H$ÌÐЪH)!„¨šYÍ\J c `hhH% ÁA|j9rä{ß÷ÛNœ8Á†!žŸÇÅ‹‘J¥ÐÒÒÏóÐÞÞN>4€¨íÃZ0J)¸®‹gÏž!ŸÏcppÌŒ0 ÇÃ/_¾¬‡¹é#¤eYfccC„a¥Ô‰ß¹sûöíCss3```ÈçóXYYïû úå°U*!Œp]W?þÜ\›LKKK¬µþÑuÝÏ …BBkmºººHk]¯ZÕÕU\ºt‰•RàD4MD€‘Édê—ºB !–1#žçajjŠçææ`YŒ1 "„aˆ±±±(aYÖy" 61"“É@Ô6õß7n„ëëëõ–’ËåÌòò²tç'ß÷¿:~ü8¶b,Þ2~‡ï•+W"xüø1¦¦¦àyŒ1’RV³Ù¬€·r·¶¾¼¯ã8Ÿ‹ÅÄúú:ÏÎÎêJ¥b)¥FŒ1sã–¢Þh½€--[ˆ˜ùˆbÒ÷}-¥´¤”¹ÞÞÞOæçç…ÖÚ¼møÆò߃¡Æ÷.3麮eYÖ²Öú333ÐZã×ô?…»±ÅºøÓäIEND®B`‚routino-3.0/web/www/routino/icons/limit-108.png 644 233 144 1372 12573351602 14577 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“¯IDAT8Ë­”ÁK[KÆ¿;•$Ü•ªxQè[UŒPn]éR„š•{ýü3Ò WîJQ¡Á•«@Á…4ŠQÈB¢X0Pz{sgæ÷‰_ßÒsfÎwfÎÌ÷! Ic ’ÈåþAÚ!¾1< ¯_;†‡!¾!íôö…dz8¡‡D¹\€P.ç*„á/66àógÏõ5üü ××]cÂðR¥ôð™Œ!›ÓÓo~°²ͦ,Þ;ú­ë[šMÇÊ H?˜ž~C6+2#ÆÇÅêjˆô­-€ð¤)¤)xÿ4ÖÀ [[ }gu5d|¼W¦ôµ5€Öb“ç=Î9Ò4Å÷ûþà:nüÚHÞì-aØæüÀÛ$yzïŸÍë«ÚZ/IÊçój6›Š¢H»»»º½½Õèè¨$)Èd$c0ò>P§£~Ôét455¥V«¥««+ÝÜܨ^¯knnNÕjUaêôô´{‰$‘¼ŒÚíºªUIòò^’488¨8Ž5??¯R©¤b±¨¥¥%Õj5kllL¥RIå÷ï%É¿úòEj·ëÏ~³GHîïï‰ãø‘Wwww´H’„V«Ej-XÛÅõýæ3žõþâ–sçÜyÓôyö—|_‡¤Ïü'YýG/ªÍí/ÚÏ^°Óþ W¯nZcÓåìIEND®B`‚routino-3.0/web/www/routino/icons/limit-37.4.png 644 233 144 1443 12573351606 14665 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ØIDAT8Ë­”AK[YÇÿï4óHM"‚.„ V¸3ÐÕtÀ–ÁM!c;+¡EÐ/00 íBjÁ(•Bã^ð+„j%)vF"ÄB(ñ½wïo/Æ)¥;ÜŹ÷Üsïùó;GHB®ë"¹H"‘¸‡´†ã| †ÁAC: Žói­{.$·{Oè:Q"á 9‘ÍŽÑß/úú\1<,ŠE©N¹ pX¬½Y×{`+Êeê‹ÃÃÝ2¥—”J«+L`­% ÃÞ²ÖÞü0Š0aHss ½¼Ö,‡ç}µ‡‡ñ‹Æt+²üȬµØ(ŠãÁó¾"åîü!ýÉóç¿8Ïž™îæÖ–677U¯×U«Õ”L&•ÉddŒ‘ëºúçèHïß;?ß¿oðýŸœjõŽŒTe{›¿›M3˜JQ*•˜˜˜`yy™™™¦§§q‡n…ÆÆÇÇùíáCmmT•¹{×Òlòñèˆ×¯^Q©TÈçóìîî°ººÊÂÂa,>år™ÑÑQ~ú4Þ÷}H¥¬Èd _¾ðïù9³³³d³Yö÷÷i·ÛLNNR¯×{zmll022Âüü<÷ÆÆ8þüZ-L*eÜ(%“úëÝ;ýúà*•Љ„޵½½­¡¡!år9u:žž P>Ÿ×ÞÞž|ßW­V“GãÈJUÞ¾åÌÌ£G¤ÓiŠÅ"¥R‰••SSS4 Ö××)<~köæM¬ÒKKQØéÐh4zÚ´Z-.//0ÆpvvÖcîââ‚V,OÄÒHkßpfºœczœý·˜Ço8»é€¹9€À†!Ä@~—¨çGDö»¸ÕÞ¼Õ©q«óì'íe§¸)¨ùluIEND®B`‚routino-3.0/web/www/routino/icons/limit-13.6.png 644 233 144 1504 12573351604 14655 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ùIDAT8Ë­”ÏK›IÇ?ï›Ä×IÕ(«ˆÐ½X`÷ ” =ÉE„j ìA(¢€ÿÀJíÝãv+ UzÖSÙ ]D  þ‚%[# ÚH|g滇$¶u¯ 3ÏÌ|Ÿ™gø<È÷}/@ñøÏ‚yÞG%“RW—U2)yÞGÁJcßÐ!šŽâqOàiv6.x® ø¢…icÃéôT*•¤ÓÓº½° ÁÁóÆy¯¡E£¾b144tOp¨©)©P°’Œœ³ú¾Õm£BÁjjJ‚C ÝS,†¢Qõõ¡éé@ðIKK’T“ä†RJÎ}ëÍ5ÉIªiiI‚OšžÔ××^hfF’®L­&[ÈZ«0 eí´a¨°V“•®ôø±/šv_APÑᡌä\ÑsîF„îztÎIõ œ;8‚ "¸ù žñôiFssÖÿ¯wï0ÆÐÕÕÅþþ>«««Äb1úûûqÎáû>'''üþò%­wîx?¥ÓV…B«··A°§õuI²®¯«¥¥E›››*—ËJ$ÊçóÐÎÎŽ$©X,*“É(—ËiüáCýS©X½~- {-tv>àÑ#ø^$B*•Â9‡1†ååe9>>¦Z­°µµÅÑÑ“““ü2:JOk«O&ƒ×ÙùÀ'Ñ(˜Íç¡T*‘J¥˜››cmmr¹L"‘ÀCOOüñê¿wïâ@>Îy\]ÑlaÒÝÝÍöö6ãããlllÐÖÖÆîî.ñxœöövæççI¥Rüûù3HÈZϧRùÀÛ· ££ƒjµJ6›¥··—d2I:&—Ë166F6›exx˜ M§ùõÉÇ›7D¾~ý€`E‹‹’dd­...tyy)I ÃPggg ÃPÎ9ŸŸË9'cŒŠÅ¢L­V×-.J°ò³ƒƒ:ÙÆ\óÔ„ÕZûgÖZÉZÙœý/\ªéð&¼×scÔ€ûJ33ßeÀ­ææ­V[­g·Xiÿˆ“HRŽ>1±IEND®B`‚routino-3.0/web/www/routino/icons/waypoint-down.png 644 233 144 310 12002775154 15740 0‰PNG  IHDR Vu\çsRGB®ÎébKGDÿÿÿ ½§“pIDAT(Ï­‘Á €0 E_ŠwgîÙ œBp'ÝAâ¥Ø6¢` $ПÿÒ>†Ô¬oõ©ÛƒèÊM£ªF OÕœÓJ7ªåˆÜG€}@ÈÝ–¬@D´¡‹»ëí[òð<ÁS¼»¦`3 0óG\ÆW7;ƒ½©íIEND®B`‚routino-3.0/web/www/routino/icons/limit-103.png 644 233 144 1377 12573351602 14577 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“´IDAT8Ë­”ÁJA†ÿuwEW#($°BrZaÀè}@„8_@ÀÇÈ"‚_ ‚xð6B.›I `PQ¢`ÄÅÀdv¦ûËavÍšähAAWwUuW×ÿ—„$\×Er‘D¡ð iÇùÆÐ<{fÇù†´Ñ>’ÛŽê$*$‡ ( ½Åó~²´>X./áǸ¼Ìì¥%ð¼ŸHoÛþN;^"—sÉçÅøøK¤cææàâÂ)Öº%³S.. ss 3>þ’|^är®óóÒwVVbÀ’$$`ííìbVV@úÎü¼ÇØX»L©ÆÂ@‹4%cŒµcH’Ûmÿú…iµ2ÿ…j?«àyMŽŽlÇÖÚÿ®HS,XŽŽÀóšH!m°¼ Úì6êõ:'''²¾¾ÎÙÙÔj5>‡!ízS–—AÚRÈû÷cØÚÚ¢··—íímÒ4Å÷}|ßgrr’F£Áèè(Aðâùs>}ü˜UþîHa¯J¥×š™‘$ׂÇÑÈȈ´··§|>¯F£¡jµª­­­©§§G§§§ŠÓT’\ff¤Réµ+×E¹œ$ÉZ« 411¡(Šd­U±X”$õõõ©\.kqqQ›››º½½U©T’$9¹œäº¸²ÖQ«¥nÔjµT.—uuu¥óósÝßß+ CU«UíîîªX,êKfˆcÉZÇU³ùUõº$YY+ITEšššÒôô´|ß×ìì¬VWWÕß߯ááaU*oÞH’íÙß—šÍ¯ºÙ$wwwDQô€«››ŒÉÈ$ ×××$IišÅuuóÎÚØê$1Æ<(€I’ gÇÇpölWÂNÒGöZýÅ€'åæ“N'gO8iöÑmˆÿŒbIEND®B`‚routino-3.0/web/www/routino/icons/limit-39.8.png 644 233 144 1535 12573351606 14675 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”ÏK\WÇ¿ï©3öÅ©::J:Š0uÑÍDP”¦„¸"‚#CÀR³Ñ?À¥›R—ÉÞ…à¢Ô2‘DnÜ.d ³˜RL³AttP’bé̼wï'‹m·^¸p~Üï¹ç^¾ç+$! ×u‘\$ÑÜü-Ò Žó†¶6ˆF mmà8oVêy!¹uœÐe¡æfÉaf¦é žwÁü<¼xa9:‚³38:ªùóóàyHOêç:^"r ‡E__é=““P( ÀZÃÕUó Ãä$HïéëK‹PÈÝÝbjÊCzÇâ"@°ø>ø>Xûe_ÆÀAzÇÔ”Gwwý™ÒS¦§1Põ+Lµ €1ß÷1æzƒ¦ZůT0Pez¤§—vÏûd÷÷k7ÖW Xk±Ö^·kyk÷÷Áó>!ÝiøYZæñãï¹9óÇÛ·î¯ëë ‡ÃŠÇãÊçóÚØØP,S4•µV®ë*ŸÏë·õu}}ë–Ó}÷®¡PøÊÉåd¤››üyvf¢­­¤R)úûûY]]%™L222B2™¤X,°½½Mgg'³³³ôܾͫ /_H9W‘È==x àãG÷—åeÍÌÌ(‘HhwwW±XLÙlV¡PH[[[’$ß÷åyžÆÇÇõMOþ)•\=|(µ´ÜsÝÆFd­¾K$ôÓÜœ2™Œ”N§uqq¡±±1åóy555I’J¥’ººº´¶¶¦ÓÓSuvtH®+§¡7¨Vµ´è÷çÏõÃýûÚÜÜT$ÑÞÞž4::ªöövõööÊZ«L&£¡¡!íììÈó<½zýZjl” GVÊñ쥵µ•t:Íáá!Äãq–––8??gxx˜l6Ëàà üøèƒ!“ÁJ9!­°°øå2'''ø5bR.—9>>ÆZ‹1†R©„µ–J¥B±XÄ/—@Z¹Æ3S癩ƒ/¹u•sÿÆÁü‡g_& •¨Z߇ ¸FØÿÙA€­u_%•º27:›7ª7ªg7¨´ŸKÈ`h¾"D$IEND®B`‚routino-3.0/web/www/routino/icons/limit-97.png 644 233 144 1324 12573351602 14523 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“‰IDAT8Ë­”?K£AÆŸ}…˜{5'$‚à  QN±±A­ úüWj•Æ"…VÁBK Ë|üˆ¥A-D4(A³ïîïŠ7þ;µs``gwæ™ÝÙgFHBA H"™ü…´1GtvÂÏŸŽÎN0æi£y.¤ 'ô ”L$ÃÂBi0|`yvw=——ps——±½¼ aø€´Öô7Íx‰D" µUôöö!13ççˆðÞñVb;âüÜ13Ò½½}´¶ŠD"™Œ˜ ‘ʬ®<kÁZðþUŸ÷ÀO¬®‚Tfv6$“i>SZg~ AAáœÃZ‹÷ï=ÖÚõÖBÅþóó ­?×,KÖ¨TâŒÎ½Ä/{]¿“ÌS©@Ö²-¤¿Z\ü­\Î)Š‚@Æk{{[===º¿¿×ÖÖ–Êå²NOOÕÖÖ¦TW—°Ö˜tÚ©Zý¡ƒƒ!P,8×hprrB?£££Œ³³³ÃÄÄ“““cØßß/÷ôà(A:ž‹ l¬P(066ÀÈÈ…B€|>ÏÒÒqf ÀÅttx‘J9®¯c‡¸T«U†††˜žž&‘HP,±Ö’Íf)—ËÁ®¯!•r¼7j4ôVêõº555¥ööv kssSétZÙlVÎ9AðÐhHÞ›@µÚ¡J%Iò$IÝÝݺ»»S>ŸW.—ÓÀÀ€ööö477÷.©¼—$¯RIªÕ…´ÁÊ @Ô$$\]]½Ðâöö–z½þž±ÄÊ H_òÌ9÷Z›—nz÷OxöeüüèÓøÖÞüÖ©ñ­óì'í?ßž—‚Ñ2‰IEND®B`‚routino-3.0/web/www/routino/icons/limit-14.png 644 233 144 1166 12573351601 14513 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“+IDAT8Ë­”¿J+AÆ¿u¶IP!eÀk¡¥¾@¬—É+$ð%´O™* Kk±WA!¶H'*\Ñ$3ó»Ånþ(‘ÛäÀgæûÎ9sþ IHƒdD>ÿ©MÜS,Âæ¦£X„ ¸GjgïB2Ohj(Ÿêõ<Ò)Qô—F..<Ã!¼¼Àp˜êDÑ_¤Ó d|‰04är¢\ÞAÇ$°xïX”T·$‰#ŽAP.ïˉ04¢TÕj„ôH«0<“ L&àýüLïÀ#Z-©V#J¥ì›ÒµÀkÁZ¬µ87Î9‡µœ›S«t6ÍÙ>QôN¿Ÿz\0ä½_ø¡ÿ¦g8O¿QôŽ´/¤6Í&€Í¼ÍH×××<==ÍøƒÁ€«««9&Å[šMÚBº¥×pScççç„aH·Û`4±»»Ëñññ,ò,:G¯Ò­Q¡p JE’ŒÖÖ$IÞ{A íím’¤““}}}ikkK’Ò{cR^¥" FÆ 0Ô¢xïU¯×µ··§ ]^^ªÛíêèèH777z~~Öúúºð>%„¡d FÞµL¼÷rÎÉ£ÃÃCÝÝÝ)I=<<¤ïYÔ%ïƒï9Ë*9ÉrÇ1Ng–ÇN§CÇsÌœ-­æTÞÞÞøüüœõØÇǯ¯¯sÀ’j.í³ÿÊ/}öë|kÒ…æ]Àü˜€•ÎæJ·ÆJ÷Ù 7í?Ö‰›Ùcw.IEND®B`‚routino-3.0/web/www/routino/icons/limit-36.6.png 644 233 144 1511 12573351606 14662 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“þIDAT8Ë­”AK[YÇÿïÕÆ¼GÚ&b â"àl¦›ÒŠ %Õ@ nD0.u$~¿À0.۽ˉ‚S ¶ ºó t„lZh±‰(™"j0Vé¢yïÝû›…ÑêÌÖ —{ϹçÜ{ÎåwŽ„$\×Er‘D<þ ÒŽódºº É$8Τ¥ö¹Ü¶ŸÐåEñ¸ƒä09Gz‰ï§T‚·o-prr©¾ÿéeÛÞiûKÄb."›íGúÂØÔ눰Öp}\Èõºal ¤/d³ýtvŠXÌ™Œ÷‘>±°Ð,aaÖþœ—:°@‹…>1>î“É´Ó”^11 lµ0A€1†0 1æf€& [- LL€ôêòÏâûgvgçâŶ£1kíµ íÕj­¥mgíÎøþÒÃ;¿K‹ÌÎæœ™óùãGweuU±XL}}}ªÕj*—ËòÃÌ8ûYÅ"@`âè°ÞØGö"ú€bñZÜjmÞj׸Õ~v‹ö_äaµ5Žf¸IEND®B`‚routino-3.0/web/www/routino/icons/limit-143.png 644 233 144 1325 12573351602 14574 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ŠIDAT8Ë­”±K#QÆ¿]ŽÖÂUQbe©ÿ€ –ˆv¶úVö¦·ÓÆ)´²´¸êÖâ@!A,„D…HÜì¾÷»b×hî,XØy;3û¾™ï! I¸®‹ä"‰lviÇùƒïÃØ˜Á÷Áqþ í¥ß…ä¦yBï…²YÉae%‹´‹çuX_‡ãcËÃ<>ÂÃC⯯ƒçuvÓx'Í—Èd\††ÄÔT©I±÷÷ˆ±ÖðÙ?æþÞP,‚ÔdjªÀÐÈd\‘Ï‹RÉCºfs ,QQÖ~<ïg`ÍM®)•<òù¦T¥RèÇÄaˆ±¶!c q÷ߣ·7L¯—ÄW* Uß{6‹ç½ÐhØ8 ±Ÿ Ykûþçsâ –F<ïiVH{llÄ6ùçççÜÞÞöóšÍ&ggg\]]Q­Vù¤xc66@ÚRÀÑ€Áêõ:™L†Z­@† –——i·Ûø¾Ïêê*?'&øuq‘ ?<)ø¡‘‘9-,H’kAŽã(—Ë $mmm) CË£MNNêææFaK’Ë‚422'FG í6Q sqq‘z½Îéé)¹\޵µ5fff¸»»£ÛíR.—™žžæ2…jZ-5®¬uÔëé³YkeŒ‘뺚ŸŸWêt:ÚÞÞÖÒÒ’NNN4<<¬Ë HâÃP²ÖèYôö@±Xäàà ?€ýý}ÊårÿÖ¾ïS©Txy|0¶V)˜fJHžŸŸév»}^½¾¾òôô”´"ŠhµZDQ ÷¦9À³4àK³ÖbL¢0E Ϛ͞ý§ûEÁ"Èê|«6¿uk|ë>ûÆMûÌj·h£æ IEND®B`‚routino-3.0/web/www/routino/icons/limit-13.9.png 644 233 144 1505 12573351604 14661 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“úIDAT8Ë­”AK›K†ßïKLb¢5‰Ä€.¯*An]‰d! YT„j\•@úüWî²Ý¸òˆ–¶èæÒ•«rƒ‘öF,è2 Å+ *Ƙ|ßÌsI¬íÝz`˜93óæ Ï9B’p]ÉE‘ÈoHë8N‰x’IC<ŽSBZoŸ Émë„:"Éaa!‚ô–hô†¥%ØÞ¶œžB¥§§-i ¢Ñ¤·íûN[/ ¹„Ãbxxé„ÙY(— àc­á¡µ|ŸrÙ0; Ò ÃÃ#„Ã"rE:-ææ¢HßYYhÏÏkŒÎX ÁÊ Hß™›‹’N·Ó”Þ1?Ðô LK€1Ïó0æçšf¯ÑÀ@“W¯@z×ù³gD£Wœœàƒµí@ÖÚ_2´÷³µŒÁ‚µÇÇ^!= ü!ý©7o&(Œ+¹‹ò}_ÉdRGGGÚØØP8Öàà ¬µr]W‡‡‡úðñ£R‰„“|úÔP.w;!°µ`>lm ÙÙÙ¡Z­Ò××G>Ÿghhˆb±@©Tbtt”‰‰ ~Ïdø×÷ Ÿ>a¤WOž¯L&£J¥¢T*¥B¡ ÍÍMU«U% IR.—S­VS.—Ó?ß¾©««K %×Å•µŽšMuÌó<õ÷÷kwwW“““ÚÞÞV,Óþþ¾†®¯¯566¦©©)Å ŒŒHµšp\]]}Õ—/’d%©··W···šžžÖÀÀ€âñ¸ÆÇÇ533£l6«žžÕj5­­­©ðúµ&^¼°úüY››¯BZgyÀÇ.//©×ëxžÇùù9žça­åâ※»;ÎÎΰÍfK·¼ ÒúÎŽ[dûþ=OX1?qfÚœ°<àì`=NÀ_á½_û>m¸›ÌÏ?¨€G­ÍGíÚϱÓþ[Kbd¸ ­IEND®B`‚routino-3.0/web/www/routino/icons/limit-192.png 644 233 144 1375 12573351603 14606 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“²IDAT8Ë­”ÁKAÅß.Qãªh"âE‰´§à©G$OâÁÅ“úxö/hA‚ˆW¥CÑRð$…\ôPŠ6‡€Å“hĆB–7Éî̯‡Ý´±½úÁÀ¼™ùÞî›yß'$! ×u‘\$‘N?GÚÇqªŒA6kÇ©"í'ûBr“<¡.Q:í 9¼z•FzçýbcÞ¿·ÔëðãÔë1ÞØÏû…ô:9ï$ùýý."—{†ô¥%¸¾6@„µ†ÞˆqÄõµai ¤oärÏýý®˜œËËR­-€6` CC°öïè®ÚlmTcyÙcr2‘)½ae CµÛk0Ɔ!Ƙ¿¸ÕÂt:ñù•Þtï,çù\^Ø¨ÝÆ&DÖÚ?ó.ÑÅQ„Ëå%xž”Ò>››‘¿F¥Ráêê €‹‹ J¥Ò#¼³³CµZ%ѱ¹ Ò¾¾ðî€ÁÊå2©TŠÃÃCêõ:333ÌÍÍ1??Ïññ1Ùl–b±H.—ãüóçø‡ß¾é‹«ÑÑ*$ɵ Çq4>>®ÁÁAibbB§§§ÒÞÞž¶··urr¢ááaýç½|)޾™Œ¡Ñ Ld‹E‚€ÙÙYéëë£\.S«ÕÈçó¬­­a¢(–úý;d2Æ•µŽ:õ†µV®ë*åóy-,,hzzZFC…BA«««ÚÝÝ•µV’ä„¡d­ãÊ÷ÏU©H’U²922"IÊd2ò}_¥RIëëëJ¥Rj6›:::ÒÔÔ”>~ø IÖ|ú$ùþù£×L I³Ù$Z­www<<~tyôH[[[ÔÊÊŠ‚ 1F“““J¥R2ÆÈZ+Çq400 ë8’äêæMéêÕ"™4æô€ímÆÆÆXXX X,277Çêê*©TŠB¡@£Ñ —ËñûÓ§íªV!™4® ÇFUÚßW.—S>Ÿ×ÒÒ’ŽŽŽ422¢ÙÙY ©Z­ªV«É#I²ÖJ IRHÖ:®©×KzûVoÞ¿·a«¥ ù¾¯ƒƒmnnª¯¯Oãã㚘˜P6›U½^—$yž§®\‘$ë¼~-Ÿ—„´ÌÇü áéá!‡o4´Z-NNN0Æ`­åìì Ó¡N­V㟯_B<iù‚g”ËmÞ|dz.׺`=ÖÎëáY,´l`Û’éì!rvsþ£€KÕæ¥nKÝg—¸iÿ¦¤};˜`ö¨IEND®B`‚routino-3.0/web/www/routino/icons/limit-63.png 644 233 144 1313 12573351602 14512 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“€IDAT8Ë­”¿K\KÇ?÷&®rWX ¢ˆ…˜‡¨eê *XÉî еµ½íÅZ›€µ`ac¥‚Ìbc!((¬¤Ù½÷Î'ÅÝ}š÷|¯òÀÀœ9s~|g¾ç `ÇB,`_ß_ÂŽQôÝýð!w`@£è»°Ó±#Ä?¤¨¯/"kµ>á‹Iò˵5ýú5x{«z{[èkkš$¿„/ûQÇ,•b{{q|ü£ðÓåe½¹ÉÕÌr_J¡gÞÜä./+üt|ü£½½X*Å82‚Õj"üpsSµ¥ÓTÓTCx^Ý3 jËÍM…V«‰##˜PweEµmšjž›‡`Ún›çEqyž›¦i¡gY±´íÊŠB½ûf3&IÓ««"cžB0„ð]øÚ E’àÕ•&IS˜AØq}]53Mÿvl4ÖëuÏÏÏU½¼¼´^¯{vvö°€œ¹¾®°ƒpîþ¾j £~þüÙ¥¥%<>>vttÔZ­æØØ˜§§§ôVK5w_áü=•Ê'fgâ\yÑh4X\\dzzšJ¥ÂÖÖÃÃÃ\__Ójµ à&@Ìì,T*ŸbâXJ%^J–e 177Çîî.OOOlll°··Çãã#•J€(Š ‡R âØ˜"Úí?Œýýý”ËeVWW™ššb{{›ùùy)—Ë\\\B(‚µÛBÓl~ãä ¼ëTV­V™œœ$I&&&888 §§‡ÁÁAfff¨Õj¼+’NN Ùüö¯ßìJ–eÞßß›|2MSïîîL_Üyí7_åY—¬ÝýKòþÏþì€gv¿NÖ¢ìÿè€7íÍ7o:ÏÞpÒþ$ã_´2ËLêIEND®B`‚routino-3.0/web/www/routino/icons/limit-3.2.png 644 233 144 1332 12573351603 14566 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”½JsA†ßs %1…)"~•ˆ¢W`£•("þ”vZZxV‚;½í´±+Ñ"…LPl!E4 ÉžÝç+N¶.,»3;3;?$|ßGò‘D,öéÏË“H@2iI$ÀóòHG­w!ù-=¡¶¡XÌCòX]!íu67áôÔQ*Aµ ¥RDonBÔ‘ö[ò^K_¢§Ç§·W¤Ó£HO,.Âë«Bœ³|_òújY\é‰tz”Þ^ÑÓã‹TJ,-Hvv€Ã0œûÚm8 ÁÎH––R©V˜R†•€&aˆm61Æ`m·cÖÚˆßlBFò++ eÚ9#j<>FDBß"s³s\ÛÃÇG‚Ò˜ŽØÚ]³ @¡P “Ép{{ÛñàáჃòù|d4’ÙÚéHHwœœ`Á­™Iò%) Cíîîj}}]©TJFC’ôòò¢íím]^^ª¯¯O¹\N’ä$_33R<>-,•J;A|||°¼¼ÌÈÈ÷÷÷üÝÜÜ011ÁÆÆF'tP©ÀÀ€ñ¸£X¤öããc¦¦¦çððc Ùl– ØÛÛãýýÓ† @±ñ¸óU«åtu%_r-,,hppP‰DB“““š››Óüü¼...$IgggÖùù¹äy²’ÓÕ•T«åºªÙ$ÆÊå2ÆœsT«Uêõ:år™··7ŠÅ"ŸŸŸm¬uU³gßÀj­í`ë׊ ýÂÙ¯ »Œü®ûj«ð§½ù§SãOçÙNÚÿò¹TјºkIEND®B`‚routino-3.0/web/www/routino/icons/limit-30.0.png 644 233 144 1434 12573351605 14651 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÑIDAT8Ë­”ÏK[YÇ¿ïQM|É«Á!àT'A³ÏPèb–AH²žŠ×ÅÙ¸.›‹üJ[Ú`œ?CQÓ)¤*¼IkÚ±yïÝû™Eb'C]záÀ9çÞóãÞûý! I¸®‹ä"‰dò'¤:ŽsL&33†Lç©>Ú’;ŠºM”L:H•Jé%ž÷…jÞ½³\]AÀÕÕЮVÁó¾ ½wFñ““.‰„Èfç‘ÞS,ÂÅ…b¬5Œ¯¡sqa(AzO6;O"!&']1;+VW=¤S67€%Š ŠÀÚÿäÖ°¹ Ò)««³³£kJ5J% „Ñ`€ CŒ1DQ„µö š0$ °R*T»}³ÇxÞgÛj +ó=Ñmkíº1X°¶ÕÏûŒôXHu[­ħÇÇÔj58;;c{{›v»ý½@«Õú?|ˆmµ R]F:¤Ñ௠03ÓÓT*²Ù,Íf“B¡ÀÒÒ¹\Ž èt:¬¬¬°¼¼LîÑ#þÛ7éЕïçõä‰âOŸÜ?^¼P¹\Öâ⢆’ɤNNNäû¾ööö$IûûûJ$:::’?=­?_½rU,ʦRy×}ðY«Üü¼~{öL;;;êõzòkm! I¸®‹ä"‰dòÒ>Žó• €tÚà8_‘öG~!¹£<¡q¡dÒArØÚJ"½Å÷²½ õº¥Ó? ÓâímðýŸHoGñÎ(_Âó\ Q(‘.ØØ€«+ÄXk˜KK£6¥w„!À€8&î÷1Ö`Œ!Š"Œ1ø×/Ì`0ŒCÞgVÂ÷{œŸظßÇŽ ïÇ.'pcÁr~¾ßC*Mý#½Ñë×/ôê•!Š\×óÔh4DZÒé´ÎÎÎtxx(Ïó”ËåÔn·U«Õ”˜™Ñr6ëÉçÛ·5›SBjòá€ÁŽŽŽ˜žžæøø˜ëëkR©aR,©ÕjäóyÂ0$·¼ÌçOŸ†¿RsZ©Ôs­­I’kAŽãhaaAÖZÅq¬ÝÝ]år9u:ÝÝÝiooO¾ïëòòRý8–$—µ5)•z.æç ß¿ ‡J¹\æàà€››677) ´Z-Œ1T*VVVøÒl?¥Û…ùyãÊZGƒ&OEÊd2:==Õêêªêõºòù¼ªÕªÖ××urr¢ÙÙY}i6%I¶ß—¬u\õz-}ü(IVÖJ’æææt¯r¹¬ÅÅEA l6«Z­&ÏóJ¥’¶^¾”$;ÕhH½^KHûììÄ#Br{{ËÃÃðõ(¢Ûí|à8æí쀴ÿ?ž~ój’¬c0Q4äÙÅÅožýUv¢à_Éû(«ÿ(àIµù¤[ãI÷ÙnÚ²]n°tÌ|IEND®B`‚routino-3.0/web/www/routino/icons/limit-24.0.png 644 233 144 1455 12573351605 14657 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“âIDAT8Ë­”ÏK[YÇ¿ïuLÂ3¦¶.,n™ÀXµnüžË!íÎv7ˆó?¸hAÑ… ×-¥P¡ŒÐ… —€ bI˜N¢‚bGKM5yïÞÏ,ò£f˜¥÷ž{Ï9œsï÷{„$$áº.’‹$b±Ÿ‘Vqœýýpÿ¾¡¿§€´Úº’ÛŠj'ŠÅ$‡§OcH/ð¼Kr9x÷Îr| _¾ÀñqÓÎåÀó.‘^´üV¼D$âŠd2…T"“JÅ!ÖnJÓ©T ™ H%’ÉѨˆD\18(¦§=¤æçê€% ÀÚÚ> Ô™Ÿé€éiÁÁV›ÒK²Y 4‚zÓhtŠ1ƆaW¦Ñ ¨×±Ð ›éeûÍây_m±ˆ‹1Xk»´»ÓÖ™1X°¶XÏûŠôPH«6—÷òy) àR©ÄÖÖV§J€b±ÈÊÊ •Ë¡Íå@ZU(íðþ=|údú<ß÷I&“äóyR©¾ïw’Ÿžž2>>ÎØØÃé4ÿ€áí[Œ´ã*$ßWåãG÷×¹9mnnª··WûûûZXXÐÕÕ•Ô– E£Qíîîªïî]ýþæ«LF¶·÷ÑOwzz°——Nöñc=¸wO###ò}_ajyyY¾ïk{{[årYétZA(K’ú }¯Õ¤hTr]\މèσMMMiffFKKK’¤‰‰ ííí©Z­ªP(èúúZCCC:99QµZÕߟ?ë—áaéÛ79à¨!íðá+¯^™×err’D"Áúú:kkkd³YFGG9??gvv–x<Îoss†×¯±ÒŽVyþœïžrxxÈÑѵZ €Z­ÆÅÅÆÎÎÎ0ÆüØ×ë!Ïž5³3ŠÅ&²M7ƒþ+ÖÚ&DŒÁüÎ: °Ð°A€mR¦+ÁÍ•0lû4xòän•›·:5nužÝâ¤ý>c|ò ÐIEND®B`‚routino-3.0/web/www/routino/icons/limit-33.8.png 644 233 144 1513 12573351606 14663 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”ÏK[YÇ¿ï)‰óÒQ1hŠBf3VéB\ŒRqÐIÁaÒ‚[ÿA—íVÜ9&ÐRZºó7YØ‚Cœà"hð‘vè_Þ»÷3 £­­.÷œ{Ϲ÷œËç! I¸®‹ä"‰¶¶ï‘6pœ÷tt@g§¡£ç=ÒFó\HnÓOèú¢¶6ÉáéÓ6¤çxÞgáÍKµ µT«Wúâ"xÞg¤çM{§é/‰¸D£b` …´ÏÌ T*±Öðõ¸ÒC*ÃÌ Hû ¤ˆFE$âŠDBÌÎzH{¬¬ø€% ÀÚ/óz,à³²Ò³³‰D3Mé™ ïc Œ1A€1·4ïc A&Ò‹ë?Äó>ÙRéêŦ£µö› íÍj­¥igm©ž÷ i°å7igÏ~rr9óׇn¾PP$Q2™ÔÞÞžòù¼¢Ñ¨úúúd­•ëºÚÝÝÕ…‚Úc1'14d¨T¾sŠÅ©ÈÛ·ü]«™Îxœl6K*•"ŸÏÓßßO6›%™L²½½ ÀÖÖÝÝÝ,,,ð ·—?Ëeûw„R±U÷ï?ÒãÇ ?~tW×Ö”èíUµZÕÅÅ…VWWåyžäû¾$) Cyž§©©)í—JªŸ¹zòDºwïQ«ÛÚŠ¬u~H¥ô —Ó¯¹œŽŽŽ4::ªááae2ŸŸ+K’jµšzzz´¹¹©ÓÓSuwuI®+§¥±˜¥^§ðú5?0>>N:fbb€¡¡!Ö×טœœdyy€‡ƒƒü^(@½N‹YY©È«Wüæçtšx<ÎÜ܇‡‡LOOÓÞÞÎüü<år™±±1vvv¡««‹_æçù /_b¥¢6XZƒËKNNN®À$‚ÝZËÙÙ¾ïs||Lpy ²´ÒÆ-ÎL“3c-ƘX17œÝÈÆ`¾áìKd³ †ÿƒõ–†Ø«èd³_UÀÖæv;ígwØiÿÄ}{ĸOpIEND®B`‚routino-3.0/web/www/routino/icons/limit-73.png 644 233 144 1336 12573351602 14520 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§““IDAT8Ë­”?K£YÆïëj²±ÐF!†ÙÊ`3­+û b´˜B?€_`aË™Ví¬‚ßÁÚ™A§Pp@ðÏ AHÞ÷¾¿-’̺;;[yáϽϹ÷ž‡çŒãXˆÌçv¢ONNj©œœÔ(ú$ìÎâA2¼(Ÿ„Èõõ¼ðÞBá›zpys£_¿êÍMolh¡ðMx?àGƒ|pl,6—ÃÙÙ×Âg——õú:¨©Y|¾ú8õú:¸¼¬ðÙÙÙ׿r86ãô4®¬„s·¶T»jf’h’h–ýÃ=ÍÔ®[[ 箬œž” \[S홦fIbò,²,3„`ÒëBÐ4í‡ö\[Sø0ÔlÎB¡ãÅEÿÅ>é_Õe?âúü‹ -:ÂÜÈð'ïÞýÎÛ·Á^/ŽFG¹¼¼¤Ùlr~~Îéé)¥R‰‡‡öööÈår”Ëe¢"^½ |ùò+''#'î陼´ÛUõððÐ……—––ÌçóîììX©Tl4ÎÌÌx||¬jèóƒûû '¿01ñ†Z `qq‘££#¶··©V«ÔëuÒ4¥\.suuE·Û…¾7bj5˜˜xƒÅbðþ~(Æw}îîŸ÷ììLÕN§ãêꪕJÅv»ÝÿÙPßû{-CL–Eôz W€f³I©T¢Z­Òl6©Õj0>>N»Ý ˲~R¯YÅt:iµ2²Œ(ŠhµZ4 êõ:SSS‹EæææX__`¤ÏÍhµ Óùˆ°ëæ¦j:0¤ª>==}ÇI’x{{kòŒ3à§nn*ìþ¯Ï†ú M«Bø©Ïþ³LÓŒúóþ´^´7_tj¼è<{ÁIûM4n‡Þ¹WIEND®B`‚routino-3.0/web/www/routino/icons/marker-51-grey.png 644 233 144 2606 12573351600 15622 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“;IDATHÇu•OhTYÅÏ÷Ý{ë½zYUŠFŒD©€–)(Eb/…ˆ¶n†dm°]ŒÂÌb@z¤éMS µ‘Þ´ ³í•jÁPY{†¨ØÆ$–B¢cAºóÏP5%¥¾?÷Þ^tꙨsàÂûç~ïwÎ{ …ÖÅRJ S,Xk¿ Ãp¯ïûá¬ã8¤”ú}](î‹EŽ¢ к©°Öjkí¥Ô¥ >ÃЦR)êéé3ÇŽÆÔj5Ôëu«”¢D"1†á—D´LD€–ØZ«l—RN´Z­íét:äþþ~rïË÷}T*;11¡×ÖÖ>÷<ïS­õ µö¿DÄâàÁƒ@·”òßAlÏd2áéÓ§ÕŽ;HkíKJ‰®®.Êf³¼²²¾|ù2­”ú“1æGkíÿÄñãÇà¯_¿>”Éd³gÏ*Çq µÑ;”Ì "Нi­áyöîÝ+^¼x.--¥]×ý$™Lþ“ƒ ø,‚/Òé´Vm)%˜9^qJÖÆ÷ÛÇÃÃÃ*N› ¾‚à3qøð᫾ïwŸ8qÂf2€W¯^¡Z­buuËËËX[[Cggg¨Úº³Â4›M„a!Dœl>ŸÇÈȶnÝŠ«W¯¢^¯Ãó>Žû÷ïcnn@>Ÿ‡ÖÌŒ©©)„aˆ}ûöˆpëÖ-S­V…뺳aŽˆ|>cÌÏ®ë/..vFQdŽ=J»ví¶mÛ088ˆ|>OEDH¥RèííEgg'fffìøø8{ž÷ÆsŒˆ~“Ì,üjŒù³çywïÝ»g»»»‘ËåÐÕÕ"йµéíí¡Ùl¢\.G‰DBÑ7Dô É"Šˆ~bæ¿‘ ëõ:ˆƘM߀¯j¹\ŽêõºJ$×vïÞý=µ ïß¿ÿ’ã8×êõººyóf´±.‹ÎÌxðà™šš’ A|5==o&:ÔÞjµšÕZÿìºîÐââbZkmúúú¨µÌŒÕÕU\¿~Ý*¥À_ˆèI¸X,ÆC0³dæcÌYÏó099i+• „1†0 1::AÀBˆKDt €ZLjb±n¬ë¾·oßFÜˉ‰ ³°° ÇùÅ÷ýoŽ;††X‹÷Œ?à[*•"xüø1&''áyŒ1“R¾.—Ë€ÝÈ]l<ù_Çq†VVVÒFÃÎÌÌèV«%”RŒZkcŽ†ÂæhløeK‘µö03ÿäû¾–R )åDÿ‘'Ož°ÖÚ¼o¸éñ?‚¡Í÷_ÖÚ¯]×Bˆ­õ_§§§¡µÆÿÓïK ƒbâ¼IEND®B`‚routino-3.0/web/www/routino/icons/limit-33.7.png 644 233 144 1465 12573351606 14670 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“êIDAT8Ë­”OK[YÆŸ\K’¹6‰” 1`ÄY%Œ‹n)qW éí¾Ýèð ºlÁºº*í¢]ÍF(’PC[ŒØB‚‚ÕiSͽçüf‘Äêtë ÎsÎûŸç}…$$á8’ƒ$¢Ñ?‘Ö…>C¿!‡Pè#ÒZ÷_HN×N¨ç( !…xò$Šô×ýÆü<¼ze©Õ Ù„Z­ƒççÁu¿!=ïꇺöá°C$"2™a¤ÏÌÍÁᡬ5\•8<4ÌÍô™Lf˜HD„ÃŽH&E>ï"UX\¸,¾¾Öþ<½7°À‹‹ UÈç]’Én™Ò ?Æ@Û¿¸À´Ûcð}cÌ•ä,þù9~»m[(€ô¢×³û¸î©=8èDìZkÿWáuÜÕ³€ëž"Ýïû[ZæÙ³‰ÐÓ§fÿÓ'§¸¹©p8¬t:­J¥¢b±¨H$¢IRµZÕÆÆ†*ûûÚûð!ôûؘIœýfwvúd¤÷¼~Í—fÓôÇbxžÇðð0Åb‘ÁÁA<Ï#N³½½ ÀÖÖãããär9Bÿìì޾ŗÞßÒ;czøPÁׯÎÒò²’©”jµšZ­––––亮ªÕª‚ $MLL¨T*iuuUC™Œfî Ü&SìîÌìîÌoFHBÆ$ƒ$2™9¤&žwM.ù¼%—Ï»Fj&çB2‰ŸÐ0P&ã!ylnföñýWj58=uÜßÃ`÷÷ëZ |ÿi?±÷‰TÊN‹Rié7• ôzˆqÎò]>Ö1½ž¥Ré7¥Ò,é´H¥Œ(Dµê#uh4ÀEEàÜ—÷ÀHªUŸB!ù¦tÀÆ@HCEѧ:ç°ÖÇ1X; ²±ÒÁ0g øþ3ÝîÇqÌ(qÎ}HìÝ.øþ3Ò‚šÔëqrarrrÂáá!GGG<==Ðív9??ÿ žØÇÔë 5…Ô¦Õ°. è÷û‹EÖ××ÙÞÞæá္¹9VWW“‡ÅÃ×YZ-ÚFÙì¢ÊeI2Nrqq¡——Z[[S±XT£ÑPšœœ”$’1’dT.KÙìâ/ƒR)O’<Ï“$åóymmmiyyY{{{:;;S»ÝÖÊÊŠ.//u{{«™™a­¼‰ )•’ŒÁÈ9Oa¨!À’tww§ééiíîîjjjJƒÁ@KKKºººR¯×ÓÍÍ$É‘x„¡äœ÷#g6ÉY§Óa~~ž\.ÇÎÎAp||L¥R Š¢r6²šïïïôû}¬µ8ç°ÖòööÆããã#ªù“³Äù;¨?øúg#;À Y/_XüÕcíͱN±Î³1NÚ?˘užsÒxIEND®B`‚routino-3.0/web/www/routino/icons/limit-17.5.png 644 233 144 1446 12573351604 14665 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÛIDAT8Ë­”±K›kÆŸïKMBÄ4$Ù¢¹dh¹]„ºtqjˆÔB ªƒÒ¥‹F;G\ÜK ®KỈ”B†€ŽR5chÕïûò¾¿;$±r{á.8Ãyß÷<缇ç9B’p]ÉEÑèH«8N•D<0$à8U¤ÕÞ½Ü^žP(už?"½%ûÁҔ˖F¾‡F£/-A,öémï½ÓË—‡]"‘NgŽÈç¡^7@k ·­w¨× ù!ÝjùYú…¹¹œ‡ÍŸÛÛî¯ÏžÉó<Åb1 ­­­©££CÑhT’äû¾r¹œ~{õJlm9ßML˜`©ô5oÞ´¨.mñò%›>˜oŸW{{» …‚º»»•L&ÕÓÓ£³³3I񮮠NOOh2•R,t¹{Wngç¯ZnÜÀV*ÎÌä¤bá°”H$4<<¬½½=­®®ª\.+‰H’ººº”N§5::ªŸÔjbtTp­ï;n  í+“ÉhyyYÙlVCCCÊçójkkÓúúºíïï+knnN±XLårY²V㸦RÙÖë×úýí[[¯Õ”Ëå‰D”H$´»»«p8¬‘‘%“I)+›Í* éûÛ·•I§­r9µ|þ¼-¤?æo¨rذóós|ßçèèˆz½Žµ–““ªÕ*ÇÇÇMëŸ×ÙÙ™¾·¶Ê÷}‡Žã ßttÔ$¤#vv0`NOOéëëc||œááanoo888`llŒt:ã8ìïïG ‚ag¤#ÑÖf¹¾&¨e¿¾¾Îèè(###lllP©TX]]%›Í`¢RáúÚÚ¬ð}Ãý=õV ™˜˜ ‹±¹¹ùÖ¦»»;ÈçóÁîïÁ÷+kU«ªK¹\V¿Òé´|ßWww·ŠÅ¢$i{{[ÉdR©TJƹ®U«’µŽ«RéX¹œÉJRWW—žŸŸµ²²¢l6«¡¡!MNN Ðáá¡2™ÌÛDzV’¬r9©T:Ò Q/#îP©T¸¹¹ÁZ‹1†‡‡¬µ<==Q.—ßéù‡,,€´ö/ÏÂSãV#iÉû?ž}:„á²ÖÏ€"°¿&àKgóK·Æ—î³/Ü´P™§w–\ IEND®B`‚routino-3.0/web/www/routino/icons/limit-35.2.png 644 233 144 1516 12573351606 14662 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”¿K\YÇ¿ï}“'6þ  fE4¬ )Q$ÀZ d“B“B°ðX´’ÊB›©d¢1M@°ŒÅXL#d1Û$£30$ñèÌ{÷~¶˜Ñ(»¥Nqî¹çÜ{Ÿs„$$áº.’‹$jkAZÄq>‹ACƒ!Çùˆ´Xõ É­Æ 'ª­uÆÆj‘žãy'LLÀÊŠ%Ÿ‡bòùŠ=1žw‚ô¼zß©ÆKÔÔ¸„B¢µõÒgâqÈf `­á²Tì€lÖƒô™ÖÖ;„B¢¦Æ"‘ð>1= P,¾¾ÖþÔó3°@‰éi>‘Hx46VË”^02‚²_*aÊe|ß¿PkíÅM¹Œ_*a ÌÈH/Î{Ö…çÚ½½Ê‹ÆT+²üŸXk+>c°`íÞxÞ!R×ߥYž<¹ç<~lþÞÝuÿXZR]]š››µ¼¼¬ íì쨳³S¡PHŽãhwwW¾|©›¡ÓØÝmÈfëœL憌”áÍþ)MC}=ccc´µµ±ººJGGñxœd2I.—`{{›H$Âàà ­·oóáËÃÛ·RÆU$Ò«û÷üøáÎÌÎjttTíííÚÜÜÔññ± «¥¥E’´¿¿¯©©)­¯¯ëf$¢¿Þ¿wõð¡‡{Å­[†oß8>:"‘HÐÝÝÍüü<“““¤R)šššX[[»èÛÖÖ===üöèàûwl,fä‡Ã–ÓS–^¿æ×»wèïïghhˆ……z{{I¥R”ËeÒé4žç177ÇÑá!>@.Ѩ••2¼zŘ¡ˆF£$“IÒé4]]]Ô××3>>N>Ÿg``€™™<Ï£¯¯h8ÌÊÆ†áÝ;|)#¤Ež>ü³3 …~LΪ¶1k-Åb‘““ …ä¾~åž=ÃJ‹W83UάµApÁÚy²+RáÑr‰³Ÿ0: P¶¾ApÐKÀX߯è&àZgóZ·Æµî³kÜ´ÿ~šŽ/®JXIEND®B`‚routino-3.0/web/www/routino/icons/limit-29.1.png 644 233 144 1435 12573351605 14663 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÒIDAT8Ë­”ÏKYǿݛi‡&K4}! â þÈÑS@FèKD0sò(Lr[‚F‚âAçžÈЇ Á³‡9DÂJâL†IÜË(Ê”]íî÷>{˜ëÆ«Š÷ª^Õ—z¯¾UB’p]ÉEéôoHEç ½½ðð¡¡·ç R±}/$·'ÔJ§$‡|>ô ßoR(À»w–ãcøñŽ[z¡¾ßDzÕöwÚñžçÒÓ#!}czj5$Xk¸¹ZzB­f˜žéèéžçŠ 33>Ò> ×€%Ž!ŽÁÚÿ¤c \³°Ò>33>AÐ~¦ôšÙY Dñõ5&Š0ÆÇ1Æü?A’„$Ž1ñìH¯;–Å÷ÏmµŠK;ð&€µkí ¬›$­ «Uðýs¤¬Š¶PH*Ÿ?³´´D¥R \.³¼¼ÌÁÁÁ-ÐR©Ä_Õ*@b ŠJ¤O¼ÏŸß¿›_}ŸÉÉI†††X[[ctt”‰‰ ÆÇÇ©×ëÝÌ666ðÛàjµš›L&‹Ò¼ sÿáùò% /^¬@Cüd2a­VsœÀV«%êõ:¬µÂw9÷ƒðõ+Ç€µ(›ÖZÔëu´Z-€€ÔZ{—ÑQ4÷oÞŸ>77ø7ó)¸ñxŒ»»;(¥Šà|ÆåõR¶puuNJ)íùù¹KÓ`Ë%9‚/™µRJœžžâììŒB‹(Š~Àf³iòMŸ;Þ¹ßÛ#Ÿ<)T8¤ÛÛ[nmmÍü%øqCký‡o~3ß3[…>{Fîî á㇇‡Ö¿ˆC ­õ%v»]K’Y–ÛçÝ;òíÛE»…þ<99qøM±€Ê‹ýXJI³4MWoVÎB†ãñ˜Íf3ÜýnžZ¥Ôk¯o¶¢¯µ‹ Öö÷÷Ÿ­éúú:¢(’…STJÉÍÍMh­Óê›ËþøøØzàx1rc¥…Dk=ú'}C†ŒãØ ”òçrÙe»W_ß>óáñ›o|{¬ o’$Y‰$ÙívCÙ⣣#`ù·ôc+뻳³cH2MS°RJ !ûðè^`Y_¥ÔÜööv(»ëËVÿXÐÀ®‚f>Ã?766 ”’ÿ¸Ð×û_¢(¢”r àa©šû4×Iœ¢ÚIEND®B`‚routino-3.0/web/www/routino/icons/limit-86.png 644 233 144 1272 12573351602 14523 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“oIDAT8Ë­”½K+AÅÏŽã6Yt¥èÁ2…¥¦‹¤ˆ•ZØÄ?À?#é­,lR‚mJK Rø,$B? AìîÌï»É‹èë¼°ÌÜ™{fçž9÷ IHƒdD>ÿéÏë0=m ð¼ÒA¶/$“ᄆåó’Çæf©ïP¯Ãɉ£ß‡·7è÷S¿^ßÿ@jdñ^†—Èå ““b~~©ËÆôzHpÎ2n©ŸÐëY66@ê2?¿Èä¤È匘›ÕªtÍþ>ÀpÄ1Ä18÷ï®ìïƒtMµê37—¥)5©Õ"’’k-qcmz9k-q¥~DÔj 5‡œ-ãûïÜÝ¥´çιQv6[e ÃÃwwàûïHËB:`o !ŽG ««+N€n·K³Ùäòò2£Ï SNØÛé@H´Z6 h·Û„aÈÖÖ ´Ûm*• ëë묮®òððÞ8Š,­HF…BIå²$#I²ÖÊ÷}U*---éôôT÷÷÷š™™ÑÚÚšÂ0”$y)®\– …’‘1(—Ó¸½¾¾ªX,êððP/// ‚@A¨\.ëèèHççç’$ç\ Èå$c0rÎSI’IÒññ±VVVtvv¦|>¯››‹EÕëuÍÎÎêñññK¼¢HrÎûÂYÆ···”J%Â0dgg‡ÏÏO¶··™ššbww—8%—Ž#ξ½æÐƒOOO#`’$7ueW.ž1dÄ…B….’?ÀàÁ[¶{·Š´ ØÀ]±.\˜B«…‡BÑ@Õ&÷Μ.’¨ïù– Ìùæ|f8çC€cF€Òé?+ ‚/–¢ÈixX ‚/‚•î=ÓíCô„Òé@¨RI ÞÈÚŸªV¥¼NO¥?¤ÓÓ®V%k ÞtùA·”J  |þ©à›¤“')‘÷NwW':9qZXà›òù§@©”A££hqÑ ¾jyY’Z’¼âXŠcÉûÛÝ«I^RKËË|Õâ¢Õèh÷™ðVKK’ÔV’(iµä¼—$9çDZœs·ø×/¹v»Ã_Z’àmïÏžÉÚ¦%É'­–|WÈ{s¾‡“D^ò:<”¬m žõýóúõŸ¼zåÇÆ¤Rììì$ Qq||Ìêê*étšñññüØZÆÆÆe³.h4³¿ß‡`_ïßK’“sÚØØP¿677%I333*—Ë*•Jª×ë*•J*—Ë* úçûwIrþÝ; ö CCÏ)Œ—‚€(ŠÃíímŽŽŽÈd2ÌÏÏS¯×988 —Ë177GîÉC±CCÏ ÆˆT ï=•J…©©)®®®ðÞ“Ëå(‹¬¯¯³»»K>Ÿ§P(°¶¶ÆÞÞ^§ïÑ#0FïÚmî.Ixï Ã0 ©ÕjDQÄùù9™L†jµÊÈÈF£Ão·ÁûÀÐl~æãG÷ ryyÉìì,“““Xk™˜˜`kk‹l6‹µ–ééi^¾xàû>}‚fó3‚Õj’”t ©‹‹ ]__wèììLI’ÜÇZ¢ZM‚•{>ën|Õ3kÏc7æã{>ûßø;‚=¡áÛXý'šÍ:ÏpÒþˆ•EšÊì¿“IEND®B`‚routino-3.0/web/www/routino/icons/limit-35.5.png 644 233 144 1507 12573351606 14665 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“üIDAT8Ë­”ÏK[YÇ¿ïUŒ†Æ'Â4ŽÈ¨»¬ÍPèbÁ h@ƒ¨[‹ÿÀ0.Û½û¶”¦ ÷݈% [è`g—E¢F¡Õ.’÷Þ½ŸY$±vÓ•Îâœ{~^¾ß#$! ×u‘\$ÑÕõÒŽóÞ^èë3ôö‚ã|@Új½ Émå µ uu9HÙlÒS¢Ño¬®Â›7–J.. RiÚ««~CzÚŠwZù.‘ˆèïDúL&å²B¬5Ü”¦R.2>Óß?H$":;]‹™™(Ò'66€% ÀÚïÚöll€ô‰™™(ñxkMéssðƒFãûAp­ÖÚëƒFƒÀ÷ Àgn¤gí?!ýj›imdù©4ã,ÇÇ~E¹ó—´I>ÿÀYZ2ÿ~üèþóü¹º»»•L&U(´»»«££# +‰(mook÷Ý;•JÎð䤉T*ݼGF*ñö-ÿ]\˜>Ï#›Í200@±XdhhˆL&C.—£R©P­VI$ÌÎÎ’[X Z¯^¿ÆH¥Åb÷ôð¡Â/_Ü¿77õK<®óósíííéêêJ€¦§§•L&%I‡‡‡º¼¼lú3%"—û÷åzÞ½·£Yëü>8¨_—–´øø±jµšR©”²Ù¬ÆÇǵ¾¾®X,¦©©)yž§……¥Ói­?y"/×d:-¸¡ï;º{W/ ý‘N«X,*‹iggG£££Z^^V2™TµZ•µVårY©TJù|^‰DBggg’µÂGV*ñê—`þ|ôˆžžr¹ŒŒŒày+++œœœ011Áþþ>cccôzK‹‹„`xù+•„´ÅÚ@Ô뜞ž4I½ec°ÖR«Õh4M!kk mý€3Ó™µ–0 ¯±Ö.ÖÆŸµŒÁ€µ7pöóó¾ ï©Ù*†Øæô>óó7p«Ü¼Õ«q«÷ì/íÿm=Í/¼¼IEND®B`‚routino-3.0/web/www/routino/icons/limit-3.4.png 644 233 144 1276 12573351603 14577 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“sIDAT8Ë­”»JkQ†ÿ½=$a[äb¡b16– –’F,ƒH,lõô lMŸJËty;›(ˆ`ÀR¤EE¼Aöe­ï{Çc§sÁ‚5³þæòÏIHÂu]$Id2%¤:ŽsC.…‚!—ǹAª'ÿBr;¡¡£LÆArØÞÎ àyŸìïC³i¹¿‡—¸¿åý}ð¼O¤“ï$ö©”K:-ŠÅ¤• ôûˆ°ÖðóÄrD¿o¨T@êP,.N‹TÊÓÓbsÓCjsxà–0„0kÿÝ¡,àsxR›ÍMéé$M©Fµ E˜ CŒ ÀCäûE1¾Z©6¬Ùž÷ÆÝ]œH ú‘™yË1Îrwž÷†´$¤:‘ Úí6µZËËËo'Ã(;ççç±>ÆG€TÒ @·Û¥P(°³³ÃÜÜI ÆY__u¾`h4@ºú£lvYå²$¹’E‘Ž5;;«n·+ß÷%I:::Ò`0ÐÔÔ”$ ljíÊe)›]ù¼áéiX>>>ØÚÚb~~žV«Àéé)333ìííQ*•èõz ÛÊÓä󯕵ނ@F’GFCkkkj6›šœœT«Õ’1FÖZ­¬¬èúúZý~_···’$+IA Yë|×Ì‚ÁZÞßßÙØØ ›Í²»»K¯×cuu•‡‡ÎÎΨT*„ƒÁHÍFº™’0 y||$ C¬µN¦@Ÿ à­õfÇwIrbbB,..Bk 礔0Æ`§§§B¥TÃóÀŸ8½7\ ‚ €…BÁÔëu{vvFçÍ9dz³3Öëu[( ú¸+iÅiÆaGX,£f³I’´ÖÒóÕÇZK’l6›,‹‘>&°RB)õ K¥R”‚EÆÐÅ1ÇC™ÒZº(bôåK¼T*E¨”z&¥2™Ì †ah[­IÒC:Gú AÀA3QD’lµZ ÃÐ`&“YRê5nmmÙ!À¤>rooðÝ;òÉòåK²Û¥ñ•lmmYŸíkpù|ÞµÛí¤$Ùí’?’KKd¥ÒOmg‡È|>9oÝê5²Ýn3ŸÏ;/9ØjµJ’Œ»Ý$øÅ r|< ¼};ñÅ19=MÞ»—Üß¼I~þœ)ëÕj•¬ µÖJ¯†ë×ÃC`qøð!ñEP.$÷±1¯ð 7=G€]XXàùùyO‡4&yu¥B./û®x_·K>~Lf2äýû=é‘d±X$ )eÀnoo÷;Ÿ”Ë}P’<<$¯^%/_&Ÿ>%­eìµ»»KN!‚ŸprrÒôDï¥Â•²Têƒ^»FÎÎ’''IUŸ>‘QÄÎù9çææb?¿ —ËAk½ãÅo†V©7n$ßß¿'/]"•"³YRJZߨ>´ðw¹t¡´ÖûƘokµšÛØØ€ÞÛ¬Môù3ðêÐébç ÆÇñëÑX_9à;’€!ÄM)%ÄF£Ïï?˜õÚ<>9áäÌL2ûJÕ|‚ª§!”Rp2 £¦Ù¿©*¢(ñ9Ç»wî¿[SSS‚ ·¡x¥äìì,´Ö!~GJšýææ¦õ€Ç½í4°ö0âµÖ-¬Õj–$#ŸmªÇƒƒær9›Ì‹ü~´ìQ»ßN§Ã¹¹9ã—ÇÏBиÀ†ø Ã0JW"IÖjµ´ì¹µµµÁ¿¥·Q~—–– I6daHI!ÄMÿxp!à(¿J©®®®ºùùù´ìš/[ýWÀ!~, ! öþ6== ¥”ü¿€=~ý¹¥”ÇfFªùÊþͬ=‘#ÊøIEND®B`‚routino-3.0/web/www/routino/icons/limit-39.5.png 644 233 144 1513 12573351606 14666 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”ÁK[Y‡ïòlh „ŠŽÅMêî1 ‚CN0±0Ô…þ.Ý ã²Ý»DÚRÛŠº™UÑEÐEÉÂ:ØÙIHˆ¢´™.òòÞ½ß,ŒT‡YzáÂ=÷Þß¹ç¾s„$$áº.’‹$ºº~@ZÁq>ÐÝ ©”¡»çÒJç\HnG't騫ËAr˜šêBzJ<þùyxûÖR«ÁÙÔjöü<Äãßžvî;½D,æây¢¯oé3… ÂZÃÕqaG >Ó×7€ç‰XÌ™Œ˜˜ˆ#}bq ,aaÖ~Ÿ—{`€ÅE>11'“é|SzÆä$Úa`ÚmŒ1„aˆ1× ƒ€°Ý&„6““ =»ÌÙ=âñ¯öèèâÅŽðªk-ÖÚk;÷,GGEºwë7i™ÙÙ™ó×ÇîÏŸËó<år9jccCétZ©TJ’†¡¶¶¶´»·§ÃJÅzôÈxµÚmÞ¿¿%#UØÜäï³3“J&)•J ²ººJ>ŸÇ÷}òùÒáèÍ2x^—Fcñ“з6ÀY ð¼.R&ò[ú£½½_ÚÝ5 CW33亮|ß×ì쬞žžtrr¢z½®››ÍÏÏ+µ¸(‚Àq–—îî~¨Z©J¥`†ïÀùù9‘H„««+jµlnnâ8××׃äz½¯R©* K«5ú-Œ1\\\°²²Âééé[€££#ö÷÷ß0#<­$V¤R†NgL,f¸µµÅññ1ív›õõuêõúW±NR)ãÊZGý¾&™µVÆIÒÙÙ™–––”ÉddŒ‘ëºïÀ~_²ÖqÕíþ•ïK’•µcbsssŠF£’$ß÷µ½½ý9Ú€çûR·ûWHeŠE€ðã<>>òúú ÀÃÃ///ãå1À‡‹ •¿­³I6Vwêì¿ð‘üEhbLµ7§:5¦:Ϧ8iÿX°__.IEND®B`‚routino-3.0/web/www/routino/icons/limit-29.8.png 644 233 144 1532 12573351605 14670 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”OH[YÆ¿wm¢óê ÆÑÁ*t@”¢Ø…A™UE!›Š`‹h7¶»¡¸t30Ëv«îÁb -.ê&Û,,AÒKÚ®¢hÆP¡ Œy/÷þfat´³õÂsî9çãÜË÷! Ic ’¨«ûi Ïû@C46ZÀó> -UóB2Õ>¡s º:ÉãáÃ:¤øþ1³³ðúµc¾~…ýý³xv|ÿéEµÞ«öKD£†ÚZÑÕuéããP(X ‚s–Ëç,®P(XÆÇAúDW×mjkE4jD<.&&|¤ææÊ€# ! Á¹ÿìüPfn¤&&|âñê3¥—LNb!Ëel`­% C¬½:  Âr ““ ½<ÿ³^|ÿ›Ëçqà¨6^pÎ᜻êŸåËçÁ÷¿!õÖü!ýÉ“'¿zÛ¿¶·ÍÚúº|ßW[[›r¹œÖ××ÕÒ񢮮F9çdŒQ.—Óê«WúéæM/~玥PøÁËfkT‘²¼}ËÖçÏöGßgdd„žžVWWéïïgxx˜ŠÅ"›››477333CG{;[_¾XÞ¼¡"eêëïjtT…ÍïÏŸ+N+kqqQÊd2ŠF£ÚØØ$…a(ß÷•L&õsG‡þ)•ŒîÝ“êëïššHw|¬Éû÷•L&Õ××§îîn­­­iwwWÉdR¹\N‘HD’T*•ÔÚÚªååeª¹©I2F^M Æ…¡g¢QmïìhllLÓÓÓZXXÐÉɉz{{5::ªX,¦[·nÉ9§T*¥D"¡t:-ß÷µõþ½tã†\¥â)²¼{Çb*e#ÆH$ˆÅb¬¬¬055E{{;óóó144D&“app¦¦&~{ôˆ°¤R8)+¤%ž=ã*ïí±WµÓÓS‚ àààçÖZJ¥Î9Êå2Åb‘ðô ÂÓ§ -]ðŒ|þŒÙU~|Ï9kíÏìw<»¢ CÜ™d.@ÿçW*ç5\RÀµjóZ·Æµî³kÜ´ÿ w\æ‘2«2IEND®B`‚routino-3.0/web/www/routino/icons/marker-45-grey.png 644 233 144 2663 12573351600 15630 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“hIDATHÇ}•_hSWÇ¿¿ó'7¹)˜, M-VC ’¤šN˜B Çú œëÃö°—m _$ƒ<({™P|Ý‹UÔâÿˆ,s#«P„YcÿB@ ÝbS55êýsÎÙƒMVì î½Üó½ßó9¿ó;”Íf±*&„@6›Õ¹\nÀó£çy:Žcþ•±,‹¤”щl6ûK.—c¾ï€Z5åÆeŒÙ ¥<ãºîgžç™h4J]]]`ŒµµÖ˜ŸŸG­V3RJ #žç}CD‹DÄ(€c€-BˆB£ÑØ‹Åüýû÷³t:M–eá]9ŽƒÉÉIS(ÔóçÏ?³m{—Rj¿1æ 1¾{÷n Sñ»ëº[º»»½cÇŽÉD"Aœscþs !ÐÑÑAÉd’U«UïÙ³g1)å'Zë+Ƙ—,CJyjeees"‘ð†††d$Öº•ŒˆÀÑ´Æø¾uëÖahhH& oeee³”òT8s]÷c×u?ÅbzppP659®5kš3Æ „h½”±XL»®û¹ëºó½{÷žw§óàÁƒ¦»»›´Ö`ŒÁ"B¹\„B!¼|ùsssXZZÂââ"^¼xH$‚p8 !„™šš")eó}ÿ£h4jz{{Y3™ÖD„R©„ááaááaÌÌÌ€ˆZ‹ºêÃç\×ëuxž×ãÆ ¬_¿‡†ëº­DZkd29rñxçÏŸG­VçÐh4ÀÓ|``àdµZ¥X,F7nD¥RÁèè(lÛÆÜÜjµ*• "‘úûû‘N§±aÃlݺccchooG<G¹\F¡P0–e)à!+ ~½^G[[vìØ¶¶6ø¾Î98çpgÏžÅøø8 T*Áƒx<¸uë–¢7ú™=zôׯ_÷ÔëõÌâ⢿k×.–L&±}ûv¤R)ܹs‡B&“Á«W¯p÷î]ŒaffýýýèëëÃè訞åÁ`°äyÞžÉd µƒƒ•J奔îéé!ß÷ADˆÇãØ´iB¡‰R©:::°oß>ôõõ¡T*™|>ÏlÛ~¥µ>@D Ƙð—Öú Û¶-‹¦³³étZklÛ¶íßž·:Ýöövêõ:nß¾íID'‰h€`|’ˆî1ƾ%"~óæMoyyŒ1(¥`Œi•›1¦UBù|Þ¯Õj2\H¥R?`üfzDÄvîÜyƲ¬ µZM^¹rÅwï7ÓrÎqÿþ}ýàÁ‡\×ý~bb¢õs¾gÏžæÇ4??o”RãÁ`ðÓJ¥kòUJµúc KKK¸xñ¢‘R€/‰è> X.—k5uƘ`Œ-h­‡lÛF±X4“““àœ·¶°çyñ]×eœó3Dt€\ň\.Ö¼YÕÿò€B¡ „eYÓŽãœÏ˜µÇ _ûð>¾–e}Z­VcËËËæÑ£GªÑhp)åwFŒ1-ŽkB½uôÖÙ€oŒÙË»ç8ŽBp!D!NLMM1¥”~×ð­é¿C“ïoƘÁ`sΔR_MLL´šóûôÙÆ³óÇ|ŠIEND®B`‚routino-3.0/web/www/routino/icons/limit-31.8.png 644 233 144 1476 12573351605 14670 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“óIDAT8Ë­”ÍK›YÆŸ÷&˜Ì«Nã÷4g3ÅUq3J»(nÁT(8LºÑ?À`—íÞ‹Áj鯅 W‚BK[h‰ã* Qc4:Ñä½÷þf‘hk»õÀ…{>ïs.Ï9B’0Æ $‘LþŒ4G¼#•‚ÎNG*Aði®é’iæ ]J&¤€G’HO ÃÏLMÁÊŠgÊeØßoèSS†Ÿ‘ž6ãƒf¾DK‹!‘ýýH»ŒŽB±è‹÷ޝ¥¡[ŠEÇè(H»ô÷Hˆ–#úúÄØXˆô™€à‰"ˆ"ðþ˹°jÌÌ€ô±±¾¾f›Ò3ÆÇqPj5\½~ ÆZ‹sWºz¨VÃAñqž]üÙmÂð“//6½÷XkñÞÓ©oØqÞ †ŸnÇþ”fyòä× —sß¿7/.*‘H(NË£ 9çÔÑÑ!l1ÚÙÙÑÂâ¢~lm úÅâA>““ò¼zÅ?å²ë¼qƒ‰‰ Òé4[[[¬®®‹ÅXZZºD¶¶¶Fww7“““ܺy“7{{Ž×¯±R>®öö;ºwO¶R1ÍÎê§tZ{{{ªV«2ƨ§§GÞ{]ˆsNajxxX»…‚ÎJ%£û÷¥¶¶;q#ïƒ_t+—Ó¹œNNNÔÞÞ®L&£ÁÁAU«ÕËbÇÇÇêííÕüü¼ŽŽŽÔÝÕ%£ ÃØz=P[›–^¾ÔowïjeeE­­­ÚÞÞ–$Yk$éôôTËËËÒúúºÂ0Ô›·o¥x\ÞÚ@^Êóâÿ‚{øà©TŠl6K¹\`dd„……¼÷d2677Éd2tuuñûãÇüŽçÏñR^HsLOØèüœÃÃC¢1¨T*œP*•¨ÕjŸX¦§Aš»Â3×ä™sî;~]öÂçîž}™€l î£¬½BÒïîÖâèëd³_MÀµÎæµnkÝg׸iÿøËguHtŠIEND®B`‚routino-3.0/web/www/routino/icons/limit-22.png 644 233 144 1266 12573351601 14513 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“kIDAT8Ë­”½K+AÅÏ®_ë‚ BÊ_¥’楳ÓJC -ÑÎüi­EPØ2`‘2•ú?ÚD‚&… ¥`š`¡Xhvg~¯ØMž¢×80Å9sï¹gî½B’p]ÉEž÷ ©Šã´™ž†lÖ0= ŽÓFª¦÷BrÓwB}Gžç 9llxH‡øþ+»»pzjétàé :ÄÞÝßE:LñNú^btÔelLÁ,Ò=Å"<< ÆZÃÇ•Ø1†b¤{‚`–±11:êŠ\N”J>Ò-• À;`‰"ˆ"°öïîŸÞ©T@º¥TòÉåÒ4¥#Ö×zÄ1Ä1Æ¢(˜„Ü';Å=Ö×A:êk6‡ï?sw—D4k-ÖÚAv}‡I¦é]rf¹»ßFšR•r &ŠNZ­aÒjµ¸¹¹! CÚíöÀišrL¹ RUHMêõ„Àû;Fƒ‰‰ –––˜ŸŸçøø˜\.Çòò2Ap}}0Nð†z¤¦˜š²<>'‘899aoo€ÅÅEÖÖÖÀ……jµQ¯—äþøSSVd2†n·/È@Ÿ‹‹ òù<ÛÛÛ\^^’ÏçÙÙÙ`l_Ën2ó‰™I™5›MÆÇÇÙßßÇÃÕÕ¾ïsppÀËË QŠ£ÿIf4‹ÞÞ¨ÕjŒŒŒP(‚€••fff( LNNrvv–È’àš Kjèüü·67’$mmmiuuUQÉu]yž§8ŽÕëõä8Ž²Ù¬$i(Á£ósIj|­³¤ÿ¿Ü—:û¶úÅùÝþwühoþèÔøÑyöƒ“öxŽÍs¥ Ù IEND®B`‚routino-3.0/web/www/routino/icons/limit-161.png 644 233 144 1310 12573351603 14567 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“}IDAT8Ë­”½K#QÅÏ &†qð#~•‚k¡Vne˜ÚFDLe+úøglzk›€‚`m7ͺ°Å‚Q SX ÖH&ïÝß3ÉšµõÀÀ»ïÞ{Þ¼wϽB’Ã)D•ʤ‚à'ÓÓP­z¦§!~"~!…EžÐ€¨R êõ Ò7¢è‡‡pqa<=Áïßðô”Û‡‡E¾ñA‘/Q.‡Œ‹¥¥e¤ÛÛÐn{ÀaæyÜv´ÛžímZ,--3>.ÊåP,.ŠéÇÇ=Àè÷¡ß³ß` èq| Ò/vv"‹kJ öö2œÃõzx3¼÷ôû}¼ÿ÷“.ËðY–ÇïíÔ¼ÙQÔáöÀ\¯‡Df6\lç\¾—“··E¤5!ptà,?4M¹¿¿ ÕjÑh4¸¹¹’¦iÊÃÃÅ}GG é;Í&€Ç{ÎÎÎ(•JœŸŸ°¹¹ÉÖÖµZÇÇG.//£™çÐO³ Ò÷PSS_•$’(U«UÅq¬««+ÝÝÝivvVI’hffFÞ{-,,ÈÌT T’HSS_C…!*—%If¦z½®õõuu»]™™æææ”$‰NOOu}}­ÝÝ]­®®ªÛíjˆrY CB™Ê2½ 3SÇŠãXšŸŸW»Ý:‚,“Ì‚PÎ¥©$™Š ÉÉI½¾¾ªV«ieeEÚØØÐþþþÐ_*•T¦4•:#Õ,ÉËË ooo¹¦œãùùçܰšC.‘jŽèŒwIf6«÷~DsEÜ}è{G8 ±´Õð©½ù©SãSçÙ'NÚ¿“e‹‘%ÿ¦IEND®B`‚routino-3.0/web/www/routino/icons/limit-106.png 644 233 144 1370 12573351602 14573 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“­IDAT8Ë­”ÁK[KÆ¿{_H ­/U\(ô­*¬ºÕ‹;WâÂ@¡{³råŸÑ,®]´ Ð¥@À‹ZÈ¢hHƒ(ˆ F ·¹™™_¹±Iû–˜oæ|g8s¾s„$$áû>’$²Ùÿð¼ccðâ…el <¯†tÜ ÉOxBý@Ù¬‡äQ*e‘Þ?ØÞ†OŸ··ðý;ÜÞöðö6Á¤÷‰¿—ð%ÒiŸLFÌξBª³±××08g´6\_[66@ª3;ûŠLF¤Ó¾˜œ››ÒWvw:€£Û…nœû½úgà€»» }es3`r2ISª°µc ¦ÓÁ:€µ–n·‹Ä?bã¸ç¿µR¥ÿg¯ ‚6——Ît:ODçÜÐÞZû„1ŽËK‚6Òk!P.×{jµJ£Ñàââ‚ýý}šÍ&õzJ¥Âùù9I¾†r¤!}æãG‹µ‘J¥8>>ÆC±X¤X,2??O£Ñ CÖ××YYYáêÛ7ë>|鳯|þÂP’|òŸ×ã㣠…‚Â0Ôáá¡ÎÎÎz¼TJò}|9ç)Ž5h€â8ÖÌÌŒîîîtuu¥f³©ååe¥R)•Ëe ÝÜÜôüãXrÎóÕnQµ*INÎI’FGGE‘µ´´¤b±¨µµ5íííijjJ¹\N z÷ö­$¹NO¥vûËP5Aòðð@EOºº¿¿ÇZ›(ÂÐjµ0Æ€1=Þ@5‡t–8 i«tw»ÿ«³¿:À ì¿ÛêxÖÞ|Ö©ñ¬óì'í/ ¸iU²ZmýIEND®B`‚routino-3.0/web/www/routino/icons/marker-32-grey.png 644 233 144 2715 12573351600 15622 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“‚IDATHÇu•_hÓYÇ¿÷Ü{ýýú+Š!ê@¶•Á¤bD¦3þ mE\¦oÃtTØƇÝe)BÉB^d^Æ—yPpßjÕí"MÛ•– fL•"Ô:XSm2ÉòûsïÝÛß¶Žó… ÷܇/ç|8÷–Íf±"B ›Íê\.×cŒùÖ÷ý}®ë ÿ—±,‹I)bŒ f³ÙB.—£ @[1åÆeŒùDJyÉó¼/}ß7‘H„ÅãqQ訵F¥RA­V3RJ¶aÆaß÷ÿÂ{Íã”@Æ`‡b¬ÙlîˆF£Á‘#G(•J1˲ð¡\×E©T2cccêíÛ·_:Žó™Rêˆ1æ%cŒø €!ÄCÏóv$ ``@îܹ“qÎaŒùÍB ‹±Ý»wSµZõß¼y•RþQký/c̯¼¯¯¾oµZ‡‰„æÌiÛ6”R`ì=J"c,Œ1PJÁqìÛ·—Ëeaa!jÛöÖ¶¶¶“çy½žç}Fu¿\å&„ˆ`Œ Íc "!Â÷þþ~Fµçy_{ž×Ë>üƒëºÇ7‰D‚i­ADxùò%æææ6oÞV«UÌÎ΢Ñh ‰ǔҔJ%&¥ìA|‰DL*•¢ÕRïß¿‡bÓ¦M¨×ëÈd28zô(ŠÅ"FFF°qãF,//#™Lb``J¥h||Ü4›ÍOÉu]Ç™ã8ÏóP(ÐÛÛ‹ÁÁAœ}årYOLLP{{ûϾïΆ††àRÊ©wïÞmÏd2º¯¯Êå2–––°mÛ6tttÀ÷}ÌÎÎÂ÷}0Æ µ†mÛXZZ2ù|žY–õ_cÌ~cÌ3ADÀ/ZëÓŽãŒOMM™ŽŽtuu!ƒ1c ¤”H¥Rë~V«ÕÂ;wι$¢!­õ3‚$cl‚ˆþÊã·oßökµZ˜ÑêŸ×Z‡nݺ,..J˲®íÝ»÷; Xm2Ÿ1FÝÝÝ—,˺V¯×åèèh 4\Ó‡àœczzZ?~üX´··Ï{ž÷÷G…³€:thµ$V©TŒRêGÛ¶¿xõêUT)¥;;;™R*,D„ÅÅEŒŒŒ)%ð'ÆØ4cLP@¹\.êD$ˆh^k}ÆqLNNšR©ÎyˆÁ÷} žççüc칂¹\´zYÑGùÖëõ°ô±±1=??/,ËzæºîбcǰÖ+`ññ:¾µZMÞ¼y3€§OŸbrrŽã@ký¢u÷î]À¬]7|mð1¾–e}Q­V£õzÝ‹EÕl6¹”òo†1!Ç5I­[½€5+[Œ1‡‰hÂu]%„àBˆ±T*Õ333CJ)ý¡áºò?‚a•ïŒ1ƒ¶msÎù¼RêÏOžZ Æ9Ë×–Œc-å2Hw”JSd³"“ñÅø¸X[ nÙÙècÀpîoïÏzìì€tËÚZÀøxúLiJ "ޱQ„1çÜ·‹Yk1Æ`£â8ÁW* íõ5›%^iµ’‡Äñ€Ä9÷ßÀ%dŽV ‚àiVHu¶·bE´Z-ö÷÷¹¿¿Üàòò’Z­ÆÍÍMB˜àc¶·Aª é‚F Ûí2??ÏÜÜ333„aÀéé)Åb‘ &''i6›ÉA`i4@ºð54´ •YÉ—¤““e³Y]]]©P(èøøX’dŒQZ]]ÕÄÄ„>>>”ÊäkeEZðåû(“Q¿c”Ïç%I…BAŸŸŸ’¤0 566¦ƒƒu»]‹EI’'I™ŒäûørÎS%“’J¥’:Žžžžôðð ééi:<<ÔÒÒ’ÎÎΚͦ$ÉIRIÎyÍ›zˆ­­-òù<»»»„aÈòò2ççç,..2::Êææ&ïïïà\¢uªÙ·ßì“Yky~~ÆZ‹µ–0 qÎÑëõèt:˜—â¿ýæŸõ­`­xëGÜÏ„|ö#øbܾa¿Å)ægüjnþjÕøÕzö‹•öÆK‰õ}HÓ¦IEND®B`‚routino-3.0/web/www/routino/icons/marker-62-red.png 644 233 144 2135 12573351601 15426 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“IDATHÇ•UÏkSY=÷¾{“ÅEŠŒ’W;EEht7vcã("R»”±C™}W6‹Âø78í¦PªŽ‚ ¸qe2n¤‚ ]ˆv6šTèjJ ¦Nûnî=³¸71MÆùàñ½wážûs¿ï<àkÈL&# N_ÑZ¯ 2»¿µÖ+étú „}² $BŽXßi­g[­Ö-’ìëë###ÐZÃ9)%Œ1X^^Æææ&…B)U1ÆLø« §sÂ`E5ÌçófaaÁ6 :çØÎ96 .,,Ø|>o0ìl3nWGQ´€Åb1©V«$Ik-1ûk-I²Z­²X,&x @ìa¥„Rê1–J¥„$­sLvwé’„lµöTJké’„ÉÎN¼T*%¨”z,¥R©Ô5ŒãØÖj5’¤I²›vØÜÉ!L’$kµã8¶˜J¥®A)õçææ,IšÝ]¿ãÓ'òÞ=ri‰4æ+Ò‡äýûäóçäî.M`277gCµoÀår9W¯×ýEäû÷ä‘#äÁƒ$@ŽyÀ'Oüw.çóèhç"ëõ:s¹œ -;6µÚU^½JÞ¸áß_¼ ÉZ,Èñq¿þö­~öŒmÕÇÆÆÀ*Rk xA€FXY²Y —ff€ÁAàÜ9`bÂ÷K&:<êLOÀ‘`‡‡‡¹Ýlzú_¾G’‘ׯ“©ùù³/gg‡¼{ׯMLtZ$‹Å"XH)ö·ünm‘™ 9?ïA67=ͧOÉz¤ °»kç,ש³»k)@úH>ßG2) _¤Ó¢X 6(—"Àa Î}Ýggà€ˆr¤ ŠÅ€tº•¦ôŒÑQ,4Ma›M¬µc°ör€&Š0Í&šŒŽ‚ôì¬f· ‚ÏnsóôÇ–£sî?^Ö[vŽÍM‚ÏH·¯ý"Í29ùƒ71aÿüðÁ¯<®D"¡l6« U*%“IuwwK’Œ1ZZZÒïïÞéZÍûþÁ› Ão©V¯ÉJ5Þ¼á¯ÃCÛ•JQ*•èëë£R©Ëå(•Jd³YVWWÃL&Ãðð0??zÄß''–W¯°RíݸqG÷î)þôÉŸ™UúÖ-…a¨££#ÍÌÌ(mooëøøX’´¶¶¦F£!@? Ê$“>wïÊO¥îˆ›7-üÓh022B>Ÿg}}k-Åb‘žžªÕ*ËËË“É@>o€ Ö.Ÿ³¸B>oÈd@úL}ý=";ÂóDg§‹´Íà @°XûÃÎïÀeAÚ¦³ÓÅóªß”žÓÕ…?(—1¾€1† 0æjƒÆ÷ Êe øtuôü|f÷qÝc›ËaÁR-¼ `­ÅZ{Õ7 ÖæràºÇH÷oü.ýÁÓ§¿†ž<1[ëë΋©)¹®«T*¥ÍÍMMMM©¦¦FÉdRÖZ9Ž£­­-½xùR±H$ä56òù›¡µµªHk¼yÃß_¾˜¸ëÒÖÖFCC“““455ÑÚÚJKK ‡‡‡d³Yâñ8íííÔ×ÖòþëWÃë×T¤5G±Øµ·+ÿé“3ðì™äyžÆÆÆTWW§••…ÃaÍÎÎJ’vvv400 ùùyÅâq­/-9zøPܺõ@ܹcL±ÀòÒôöö²»»Kss3D"&&&.f¸¼¼L:æ·Ç1ß¾a #‹Y¾çýÇÜŒFÂ÷}¶··éîîfdd„T*Åââ"¥R‰l6‹ëº sr|L°··o[Ç”Jëz÷NmlØŠïkffFžçiuuU€FGGÕÓÓ£t:­L&£¹¹9IÒôô´jïÞÕŸoßZml¨rr².¤qúûù*ÅBBÕNOOñ}Ÿƒƒ¬µc8::¢T*Q,) ìíîò/TèïÇJã<#—;cv•_ç?sîsÍYþ%ž]Q€ßöL2 ?ûç9ö ¸Vm^ëÖ¸Ö}v›ö?Éy•³6ðIEND®B`‚routino-3.0/web/www/routino/icons/limit-29.7.png 644 233 144 1475 12573351605 14675 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“òIDAT8Ë­”OH[YÆ¿÷ ‰ópŠ „¸RèlL Æn3 Á?ˆ úg妭h»wÙY ̲Å]pçÆÈ€´HÛUWR:BQеƒ)iAP$±ˆE%¾÷îýÍ"‰£®=pàž{Ïù¸çð}GHB®ë"¹H¢©é7¤ç --ZZÀq¾ ÍÔß…äÖë„@MM’ÃMHÏñ¼c&'áÕ+K¹ ?~@¹\‹''Á󎑞×óz½D$âŠöö[Hß…ím„Xk¸hµ8d{Û0: Ò7ÚÛoŠHÄɤÈå<¤"SSg€% ÀÚÿ½q8cj ¤"¹œG2YoSzÁ½{ðƒ³3Œï`Œ!Œ1>g ªUß'ßÞ½ Ò‹ÆÌRxÞ‘-•°`©^°Ö^긞g)•ÀóŽR7þ”þâѣ߇Í¿kkîß òñú5+ß¿›_=¾¾>:::( tvvÒÓÓCWW{{{,--‘ÍféïïÇ‘x·²bxû–@ú¤°¹ÙrrÂË7oøãÙ3z{{Éf³ŒŒŒÐÝÝÍìì,Õj€|>ÏøãǵŽwvàæM+b1c*þùðt:ÍÄÄ[[[d2†††ˆF£ÌÍÍkŸt:Mqc£V©@,f\މh­XÔàà ÆÆÆ”Ïçurr¢T*¥Åb1µµµ©\.K’æçç•H$”º}[F’†’µŽkŽ×ôñ£–?¶¡ïkqqQÉdR«««4==­ññqe2  Ðòò²r¹œêfõþ½tt´&¤ž>åÂÊÎ;u¯V«ø¾Ïîî.ÖZŒ1`­åððÓÓSC€'O@š9ç¥R7u~5®rîœ{5 K<»¤ ¾ lM2ç WÏ6 ²ò¹ÿ‚®U›×º5®uŸ]ã¦ý8È”Õ]þP:IEND®B`‚routino-3.0/web/www/routino/icons/marker-9-grey.png 644 233 144 2513 12573351600 15542 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“IDATHÇ}UMhSYþÎ}÷&¯/›f²¤±¡þ$RŠè ˆ…j+¢ íbP¨›É¢.f33 n$Y³—®ZÅ.kNÆ2J`¨5êPé44Õ¾¦’ŒïçÞ; ›˜ÔÎ|pàýÜû½ó}çœw)—ËaŒsŽ\.§òùü)­õžç 9Ž£>@ƒABüIDWr¹Ü/ù|žù¾ h‡ÔÐZK­õ§Bˆë®ë^ôX«Õü¡¡!Öª¾iš(—Ëxøð!Ö××177‡D"ÑÑÑvõ‰÷îÝSÏž=3LÓ\ò<ï cppJ©Ó4'ªÕê'RJ•J¥¨Õè‡c 8räÎ;Î9Zý¼´´¤ …³,ë¥Ô­qÆð·RêK˲~-•J:‹!NC)…@ €Ó§OøïíÌ?c ÛÛÛxðà]%¢§8àDôˆ1ö ÷ïß÷¶¶¶Úƒ ”jG' …‚oÛ¶3‡úà·Ô#"vìØ±ëÁ`pƶm1;;ëw£-çççU¹\æ¡PhÕuÝïÛÃ`œŽ•æ®xF&Saö5žÕ¸V»a•:Ë5žÝP€…À†!¶"™€×‰\«±ÿQÀ­jóV¯Æ­Þ³[¼´ÿÅù“Ÿ½ÑXèIEND®B`‚routino-3.0/web/www/routino/icons/marker-89-grey.png 644 233 144 2735 12573351601 15641 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“’IDATHÇm•_hSYÇ¿¿ó'¹¹ñ_Œ"qJ3‘AXÊÒQ±à´PÊôap ó2Uf|Y—e@Kò6/ã˾Λ´V¬Äl][ÅEYZ›ŠŠ+6IK’Ö¨÷ÞœsöÁ6Óê|áÀ½pùÞïùü~çw(•JaMLT*¥Óét·1æÏó:Ç1Èøý~’Rþˆ~J¥RwÒé4k4 €ÖL¹1FcöH)Ï»®ûçy& Q4c¬é¨µF¡P@¥R1RJòù|£žçýˆŠDÄ(€c€˜"[¯×cáp¸qìØ1ÖÞÞN~¿ŸÊqär9“ÍfÕòòòw¶m¥”:fŒyADŒ:tÈhBüÇuÝX<÷å¾}ûˆscÌgK½{÷ÒX©Tò–––ÂRÊ~­õïÆ˜ïé逽{÷îp<÷†††¤eYÐZ7“1Æ@D úˆÖ¥lÛFGGùò¥·¸¸¶,kw ¸Æ\×ýÚuÝïÃá°ëÜ8ç`Œ1cLÓŒˆÀƒ¢ùㇵëºß»®û5?räÈÇqZz{{M<'¥8ç(—ËÈçó¨Õj…BÍ´årÏž=ƒëº…BÐZöm!ÌÜÜI)ÛD£Ñè …B&‘H0àœ#—Ëall –eÁq´¶¶âäÉ“˜ÅÈȶnÝŠÕÕU$“Iôõõ‰›˜˜0õz½“9Žc¢Ñ(¬õîß¿={öàܹs8}ú4òùˆ´†ãœLÂë׆dçi­}/$·m'Ôq;HÓÓq¤e<¯A¡;;–ëk¨Õàúº% ày ¤åö{§m/‹¹tu‰tz©B.ÕªB¬5üI-9¤Z5är UH§è걘+úúÄ䤇tÊ€X‚‚¬ýÍXÀga¤S&'=úúÚß”>25Ð }Ó2ÀC†%hšMßÇ@“|¤š ãy?©TÁÚ?Yk±Ö>ùi[g ¬=;Ïû‰4,¤5ææ°ìïïs~~W*ŠÅb”%Àññ1+++œ„¶PiMH‡lm˜í­-b±›››ø¾ÏÐÐÙl6r^*•H$d³YÒýý}ûføô‰P:tÕÓóF™Œ¬ä:/^(•J $-..êññQ½½½êPµZÕüü¼öööô2‘Ð×/_\½}+º»ßˆW¯ ··t*5>>Îöö6»»»¤R)fggäââ"Êîàà€‘‘Þ¿{‡¸»Ã&“Æ•µŽšÍ(²µVƹ®«ÑÑQ•Ëe]^^ª\.«Ñh¨T*ibbB333Z]]••$ß—c­Õ, $—˱±±e±¾¾N>Ÿ' C2™ KKKxžÇØØ=ÝÝ싆ϟ ¤Ã¨›@ˆ1Ôëu¢îÝßßS¯×1ÆP«Õh4ÜÜÜpuuÅïßy€°ín¶pvvÖBö€þ—Z0±<ÁÙ_`ƒ€§;ÀÎ hñ?ð¬³ù¬[ãY÷Ù3nÚ_ϲ“ÛžìIEND®B`‚routino-3.0/web/www/routino/icons/limit-12.4.png 644 233 144 1401 12573351604 14646 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“¶IDAT8Ë­”±K[QÆ¿÷¡ÚjÑ-`]:8ÔÁ±µ .à “ˆ[ÿ‰\D‡±ƒ s†ê †€‚!tˆ1ˆ´ÐÀ3ïÞûëð’´Å¡‹.Üsï=çœû}GHB¾ï#ùH"™|ƒ´çéëƒW¯,}}àyE¤Ö½üVœP(™ô<ææ’HŸ‚_är°¿ï¨Õ ^‡Z-ös9‚_HŸZï½V¼DW—Ow·H§‡‘Jd³P©XÀàœåo‹}C¥bÉfA*‘NÓÝ-ºº|18(ff¤ VVGAsVû ðÈÊ HÌÌ ¶Ê”>3; Ð4Ø8k-Qaí¿ b 6Š0Ðdv¤Ïíž½%~R*aÀ¹sçÜ“}Ç7&Îðò‚à'Ò[!m°´„p||L¹\ P(°¶¶F±X쀴³,•J|ÏçŒËå@ÚÒ »»öÛî.‰D‚ÃÃCÊå2===LNN’N§9;;ë”n­edd„ɬùú¤_/^¼Ó‡r’ï%P"‘ÐÕÕ•–——•Ïç•J¥tzz*IòëÔxÖyöŒ“ö7c½¬â¯tDIEND®B`‚routino-3.0/web/www/routino/icons/limit-21.8.png 644 233 144 1510 12573351605 14654 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ýIDAT8Ë­”?HœIÆŸoÖìêdïÐdq/ÇÂB® AI8±¹* hL®ˆ IcÒÁZ8¸2é,ì¬. `d++ñjÃ&©O X×ì~ßÌïŠ]÷¯õ…yçý?<Ï+$! c ’A¿ Mïhn†k×ÍÍï&jv!™ZœÐy¢ÆÆ)àáÃF¤X[ddÞ¼ñìíÁçϰ·WÕGFÀÚ"Ò‹šP‹—ˆÇ ‰„Èfo"} ¯ DxïøVªzD¡àèëéÙìM ‘N‹þ~‹´Íè(@ð„!„!xÿß9”i›þ~K:]SzÉÀ*a¹Œ«TêÍDQ„sß7è*Âr@zyþg·°ö‹Ïçñàqï=Þ{¢(Â{aÒªjïóy°ö Ò­ØŸÒ_>.@’(IÒññ±¦§§ÕÙÙ©……Ykµ¼²"54ÈGQ`\±¸®¥%-mmù¨RÑÌÌŒ2™Œr¹œ$)‘H¨©©I€zzz466¦••¥R)ýzçŽ~ôÈkvV±ÓÓu!Mðì§ý³³ÃÎλ»»”J%NNN8;;àðð€r¹Ìþþ>áׯOŸ‚4QÇù|ÙzQ\ ‡8‡»€³ïà¡âÃ_¥L¤ÿ»GѹO…¾aÀ¥róR·Æ¥î³KÜ´ÿ6>PŸâûIIEND®B`‚routino-3.0/web/www/routino/icons/limit-175.png 644 233 144 1421 12573351603 14577 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÆIDAT8Ë­”±K[]ÆŸ{SnÂÕVSDŠ)*,‚këàh0‚ÔtÑEºøg´»ØÁESpÈâP:è"R  ÆÉÒZ))ï½çü¾!Ië×~ð-¾ðï9ç}8çð{^! I¸®‹ä"‰Dâ!Ò:ŽSepîß7 ‚ãT‘Ö»ûBr»}B=¡DÂArxö,ôßÿÉò2”Ë–f~ü€f³S//ƒïÿDzÝ=ïtû%<Ï%££¤ù<Ô눰Öp3:uD½nÈçAª1:š!žçŠTJÌÍùH_X[¸,aaÖþÎÞXàšµ5¾07ç“JuŸ)½¡Xˆ"¢ëk¬µXk ÃðWcˆ¢ˆ°Ý& ,‹ ½éýÙ#|¿Åá!€í ýoÓ¹áá!ø~ éÑI¯ôòå=Â0ó<ííí)›ÍJ’Êå²úûû•H$499©Z­¦ããcÅãqÍ‹Îݱ1Ë÷œ·o_ éïÞŒagg‡X,Æîî.Õj•©©)¦§§ñ<­­-²Ù,ù|ž……¾6Æ–J }r50ðXOžH’kAŽã(•JéââB¹\Nûûû* Z]]Õðð°†\×Õìì¬ÒÉuž>•‹dÒpz @ÌḬ̀±±@³Ùd||œz½ÎÁÁ‹‹‹lnn’N§ùðþ=Ñ·oLWÖ: Ý k­Œ1’¤R©¤¡¡!ŒŒèèèH™LFKKKJ§Óú~zÚiÉZÇU«õY•Š$YY+Iêëë“çy’¤J¥¢B¡ IÊårÚÞÞV2™ÔÄÄ„žÏÏK’u?~”Z­ÏBZge êÉùù9WWWœqyyù‹ˆv»ÍÉÉ Æ˜À++ ­ÿÅQôR=îz ˜´ÿâì?`oþ °ìo[ýá€[õæ­N[g·8iÿjã`†WéÏÓIEND®B`‚routino-3.0/web/www/routino/icons/limit-181.png 644 233 144 1317 12573351603 14600 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“„IDAT8Ë­”?K#QÅϼÁ§0Œ‚‚[-©±¶M%ÆÊZ?€#éí, VÚZL'Äua…m,D„€!‹:3ï½ß3ÉšÝ-½ðàÝwï9ïß¹WHBÆ$ƒ$ÊåOHÁwff ZuÌÌ@|G:(âB2NhHT.HÍf©EýbwNN<ÐëÁÃCîïîBýBjùA—(• ““byyé'pï‹÷Ž÷–û–û{ÇÆH?Y^^arR”JF,,ˆÍÍéûû àÉ2È2ðþÏ®ö÷AúÁæfÄÂBqM©ÍÖ@еØ$Áy€sŽ,ËpîÏ!mšâÒ4ÏßÚ©=|³ÏDQŸ›o“_yïGó¡o­Í×rrÏÍ DQé³ØÛ°>ß8޹½½àêêŠV«Åõõõˆ4Žcîîî(îkÙÛé@H_étÎqttD†œžžÒív™egg‡¥¥%.//9;;# C:9† H_*•/Z_—$ãAAhnnN’ä½×ÔÔ”†5 †¡jµš¼÷*Ìh}]ªT¾ƒJ¥¸Ùlª^¯k0¨×ëi~~^‡‡‡zzzRµZU£ÑP½^×ËË‹FV*IÆ`ä} 4Õ{sΩ\.ëøøXkkk:??WEêv»’$kíX¾ÒTò>0ê÷¿)Ž%É«8úôô´ÞÞÞÔn·uqq¡Z­¦ÕÕUmooK’*•Š&&&†T^q,õû߯~³$ÏÏϼ¾¾$ dEl,žËcì7Çt†µ#sn¤³÷ó\¹ö¿:û§ü;¡XÇ|k‡eõW|hm~h×øÐ~öö72ÜdÂ8,”MIEND®B`‚routino-3.0/web/www/routino/icons/limit-8.8.png 644 233 144 1237 12573351604 14606 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“TIDAT8Ë­”1K+A…Ïn± k‘`‚¾Ê2El,ÒZ…±ÓÆ"ùù±Ogg ÁZ,RŠBAAŒ)‚¨)²»3ß+v“gÔ×e`™;gÎÌÞ{çÜ+$! ×u‘\$‘NÿAêà87d³°¼lÈfÁqn:ɾÜäœÐô¢tÚArØÙI#µñýw 89±ŒF0Ãh¯ ðýw¤vÂw’óžç’J‰bqéj†CDXkø:âuÄph¨VAz X\'•žçŠBAÔj>Ò­À°„!„!Xûï›b` ­HwÔj>…B¦t@½E˜ CŒ™wÌãAQóëu¦9ÛÀ÷ß â@Â;™ÍSÀÆ—Yðý7¤ !uh6"\__Ón·¹½½yôžð#šM:Bº¢Û%pvvF>Ÿgww—µµ5.//8==Ãûý~ü#0t» ]¹ÊdJªT$É•$cŒ|ß×öö¶VWWõùù)IŠ¢èWÉU¥"e2%W®‹B|Á—h'Žœé()—ÒÑű‚…¤HÁpQP¸RH¤Áœ“³÷ï’œk3vÁ¬µ÷·öúó­%$! c ’AéôH;xÞw2xûÖ’É€ç}GÚéß ÉôqBG鴇䱾žFúDü¢\†oß··ðó'ÜÞöôr‚àÒ§þ{¯—ð}Ã記žÎ"5(áúÚ1ÎYžJO¹¾¶‹ 5˜žÎ2:*|߈ÉI±º ý`s Ý.t»àÜÿg`„ln‚ôƒÕÕ€ÉÉ~šÒgÖÖ¢8 ±=ÖZâ8þ-@Età ¥HŸ5{G´h4ˆÁ¹'Žœs8ç†2íÛ¬Åsçç-¤wBÚac1Àáá! ¸ÑhpppD P¯×ÙÞÞæŸós€Ø•Ë íé”jÀþU­âû>•J€0 Éår,--%ÎÏÎÎÈårÌÏÏóçû÷üÇ–¯_±Ò©Ñë×y}ø 'odDããã$I[[[êt:Ó@Ž511¡££#ù/_êï/_Œ ¹W¯òF##È÷å$­ü¨™™¥R)íïï«R©haaA'''º¼¼”$-//«ÝnkeeEõZM©TJzñB2#ç>&Ýk·Û4›M¬µÜßßÐét¸»»ÃEQ·±‘t³Ç³^›Cç¶Ï3 Ž!žý6®ÛeØá€¸ ã˜>¹#ÖÖžLÀ³Îæ³ngÝgϸiÿž,‘©¨zú¹IEND®B`‚routino-3.0/web/www/routino/icons/marker-69-red.png 644 233 144 2115 12573351601 15433 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“IDATHÇ••ÏK[YÇ¿÷¾{cH µJ™B^Ñ•Vè Õ†þ„Vº…2˶0ÿ@ ]Œ]H­µÓE;6…nº*SèÂB)XÄ"ÔD¨+EtÌ{¹÷;‹{_Œ‘¡3'÷’ûÉ9ßw¿'ÀaÈt:- ­­í’Öz XŸÙ¼ÖZ/µµµ]N& ásÀøIk=U¯×ÇH²³³S Bk k-¤”ˆã‹‹‹ØÙÙ¡B(¥Jql6q¿ÐA³Ùl<;;kªÕ*­µlk-«Õ*gggM6›ПëN:N*ƒ XÀ¡¡¡¨\.“$1ŒãøØcŒ!I–Ëe E¼ tX)¡”z€ù|>"Ic-£Z6ŠÈzýH¥4†6Š4àù|>@¥Ô )%J¥®`†¦R©$ã("›Ûö‡ÙGE$ÉJ¥Â0 ¦R©kPJ}ÀééiC’q­æN¬­‘OŸ’ïÞ‘q|HZY!çæÈHkàééiã«ý¶££Ãnoo»A’ËËäÙ³äÉ“$@ŽŽ:àË—nÝÞîòÝ»LúÙÞÞfGG‡õWfÔª'U^¹BÞ¼é>/,==äê*™Í’÷î¹ý÷ïÉTŠ\^f¢úèè(@j­'P­KKÀ™3@&œ> ”· üñcàüy`l ØÝ&'Ýsõ*pù²·h8hkk ,¤”óû³gîîî’é493ãzÚÙqú½zåÖ÷ï“ׯ“é4ëoß:5À !"Að+ær¹¸üí›»9.7n8È“'ººJÞºEÞ¹ãö>¤mo'«UîÕjìïë«{Ì “É@kýæGFb’¬üHž8á`Y(8Ðëׇ{§NѼyC’üåömãÈ$6Íj­×°X(’ŒÖÖÈçÏÉÏŸÓ»üõ+97ÇøË’äüü¼õÀ}!D_TNoqQJIõ’×/N,Úâ¨Äžß¿3—Ë%Þ/6ó@ ! ”*`. ‡ŠwL³e“½±±±ØÏÖRWW‚ hL(‡WJöõõAk]òÃÅéÛ2PboÙ©©)ãéÔ4öвj­+X,¾¾²¤í••f2€RÊŸ[Ûnãú–JG*ÜÛÛcì‡ÇoBÐøAÑ7 Ã(‰$Y,“¶Wd&&&šÿ–þ=ZõŽI²T*€‘RRqÑ=ø!°U_¥TÇÇÇíÀÀ@ÒvÑ·­þ+ðˆ¾F„P÷þÙÓÓ¥”ü¿À†¾>OA@)å€Þ–nŽÅ? ˈ!ƒþ ˆIEND®B`‚routino-3.0/web/www/routino/icons/marker-43-red.png 644 233 144 2054 12573351600 15424 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“áIDATHÇ••¿kTYÇ?÷¾{3f@‹Y$OD\›Á?À5‹°Ùh±‚…b%S,v»–6„4‰ÚĘ`)ˆàVFL#²B*É‹•¤äýúnñÞKfÆ]Ü=ð¸ï<æ~æ|Ï»ßóà ì¡C‡,@¥R¹à½ ÈŠUí¹÷þu¥R¹Pì³%Èk¤ÀwÞû™$I&%©¿¿ßœ;wï=Y–a­%ŽcVVVØÚÚ’1Æ8çêqOµqöÿád @ñÜÜ\Úl6•e™Ú#Ë25›MÍÍÍ¥1 bßÉRqYqÁ{@ÃÃÃÑúúº$)MSÅqüÕ•¦©$i}}]ÃÃÃQ~„9ÖZœs €FGG£EQ^e’HD’”$Ê¢HÑîî>|tt4äœ[°ÖBOOÏ 0 ÓF£!IŠãXE©Ò»ó8Š$IFCa¦€zzzÆpέšMÿøô©T´CI"=.ÍÏK/^t0;;›Õ®d}}}Ùæææþ‹P’äÅE ¤‡ó|z:ÏÍ×[·T¾ÆÍÍMõõõeÅ‘#/ I€oÞl^^ΟtçN~÷nž7›*vh||\@jë½@YAÛÛ01ccÐÛ ;;ùYZ‚K—`yêõüþðaHS ޵@¶±±A«ÕÂ9‡nÜ€¡!˜Ÿ‡V *•:9™®^…ÕU8rŒÁ˜ÜCŸ>}ȰÖF@úàÞ½¼ñoßJÞKgÏJ/æOŸ–¤'O¤­­\ë«W(yüX’ôdzg2cLd1¿ö·Û·“ÆÇ¸þ~²‰ 8v ööÀûüÚÙË—séÆ ¨Vùü|óf kíªÕ*ÞûÅâðÇ’””ÖÜÞÎ+]\Ìó©©<·VêíUzýº$é§k×ÒÂUÕÒ¦Þû÷€jµZ*IÑî®ÔjIIïޜݕéþ}Å/_J’--eð‹1f°º\9o­ÔëõNgu9ª´çƇ:†¥÷kí<oŒÁ97 èxFë…eÓ½=©}R%‰Òž“““q1[ë'Nœ ‚ý •㳃ƒƒxïëý-ÍPú½¨~ff&-€ûÓ©mìÑõ ôÞ7:ú[TVÊ^[[SµZMYkì–ÝßìïçÏŸ544Ãã÷âà{¾ý Ã0*G¢$ÕjµRöPššjÿ,ý{t÷wdd$–¤z½ž keŒ9_ü<ø&°»¿Î¹ +W®dgΜ)e× Ùî¿;ú ü`Œ>?uêÎ9ûûý-Ö_‚ µvø¾KÍWñ7œÌl®´Ò–IEND®B`‚routino-3.0/web/www/routino/icons/marker-58-red.png 644 233 144 2131 12573351600 15426 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“IDATHÇ••ÏKIÇ¿U]åÈ„ü`<ä0DtÁ(’CÀ“šdHðW/{HNÞœÃÂú!°Þ"‚{HH2’@„ÀîÍS@‚“˜Æ$°F… Œ#Ý]õÝCUOÆ‘%»š×]ôûô{ߪ÷øn²³³S@&“¹®µÞ@Ö{¶>k­72™Ìuðq2 ïÀy­õB’$S$ÙÕÕ%FFF µ†µRJÄqŒõõuìïïS!”R¥8ŽgüÝÂi~¡'‚ æóùxiiÉÔj5ZkÙjÖZÖj5.--™|> ëI+N3ƒ ØÀÑÑѨ\.“$1ŒãøÄeŒ!I–ËeŽŽŽF¼ tX)¡”z€…B!"I“$Œ Ú("ãØ]©CEŒŽŽšðB¡ Rê‘”èè踀ašJ¥B’Œ[!­æ!©¥ïU*†ah°££ãF „xl­ ççç9>>.êËàùsàý{`søøèë”Þ½^¼>}‚ìéA"ºr9d2®­­ !ÄO`s¹œÝÛÛ#­¥%ÉÅE ;;?}šLreÅ=Ÿ9ãüØm£A’Üûú•¹\Îú#311A’LŽŽ\]·n‘##d½NQäÖÇÇÉK—ÜýÛ·¼ºÊÄË111AFZkÀŸl¿{Àú:pîÐ߬®ºõÛ·7o““Àð006ÖìÏ‘€ÝÙÙA£Ñ€ÊdøðЮ¬—/;Àî.ðù³‹®Õ€z¨T€oßš´»» RÊ€ùcyÙíh£AV«äá¡«éà€ÔÚé|þyúÔzà¡b *B\“R@RzòÄé›$ÇÞ§í¹S­òB¦½_lå€B@)5ëõý>TÚ[Ön§¦¦b?[KÝÝÝ‚ 9¡^)900­uɧošm[¿/,,ÜiN§–±‡¶…Pk]Àb±èôõ™¥eomm1›Í”RþÜ^v»Ô·T:–a½^çàà`ìGÝïBÐøÓ7 Ã(‰$Y,Ó²·dgffZKÿníú^¹r%&ÉR©ä†”B\ó¯?¶ë«”ªàôô´JË.ú²ÕÓÀU!$>Ã?{{{¡”’ÿØÔ×û_ƒ  ”r@_[5'ì[‘b½²MIEND®B`‚routino-3.0/web/www/routino/icons/limit-174.png 644 233 144 1354 12573351603 14603 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“¡IDAT8Ë­”½K[aÆŸ{S“ô.~p‰Ö)ƒƒ.ü˜äâ`G)t0»ù ÛÉA]º¸9::$4ìb†–«Õ˜Üû¾¿7iµêæ3œ÷|¼ç<<çIHÂu]$I$“cH8N‰2 €ã”6º~!¹Ý<¡^¡dÒArxó&‰ôÏûÍÊ |þli4àçOh4"{e<ï7ÒÇn¼ÓÍ—ˆÇ] ‘;BªáûP¯ ÄZÃ]‰ìzÝàû ÕÈf_‘HˆxÜ™ŒX\ô* mÀ`í?í½Ú UX\ôÈdºcJŸXZ膄í6ÖZ¬µAðW­µ˜ l·£ø¥%>õ0Ëáy¿¨Vl¯ÐSÒûc¢«Uð¼_H¹Ø{éƒÞ½{­·o Aàºñ¸ŽÕ××§««+íìì¨R©¨\.Ëó<¥R)Õj5})—522âJçÛ·—*cB*²·`0†ƒƒb±‡‡‡”J%¦¦¦˜™™AGGGŒŽŽ2;; @†½=Š/Ôß?¡éiIr-Èqe2]^^j||\'''Z__W6›Õüü¼VWWR©”º0¹šž–úû'Äà áÇ‚N€¹¹9677h4är9ÎÏÏÙßß'N³¼¼ÌØØ_ÏÎ"¿‡ÁAãÊZGŽîеVÆIÒîî®Òé´†‡‡Õjµ499©ÓÓSÕëu•Ëå(¾Ý–¬uîaÜÞàû>[[[,,,°¶¶Àm׿½½ïûÑ4w0Òù|„eDH...hµZ4›Mnnn"~ƒ1†ëëkšÍfÀ!ùÊ­ÅÝãÙ£`ï|ªºúožu7Ÿõj<ë={ÆKûL,—]iœžwIEND®B`‚routino-3.0/web/www/routino/icons/limit-4.5.png 644 233 144 1301 12573351603 14566 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“vIDAT8Ë­”½K3AÆŸ»Â„k’háuâG#Vilml c%‚ZèðŸÐRX«TÚÛ‰`c!¨…`!~Aƒ¢¹»Ýß[Ü%yß·r`Xvwfvö™gFHB®ë"¹H"žDªà8×d³0«««LNNr{{ Àéé)T«U|ßçøø8† Ý†\θ²ÖQô3p]Wù|^———º»»ÓÕÕ•>>>Ôl65>>®õõuù¾¯§§'õH¯ ¬u0#ŠܪÕ*KKKXk™åì쌙™²Ù,kkk1m¢h³¿VÓÃûû;///ch·Ût»]ûO>&À0°ìî‚ô[d³ŽÛ[âä$ö÷÷Y[[`bb‚±±1fffa{{€(Áí-d³ÎÈ”NK’R©”œsšŸŸW±XÔàà úûûµ··§››‹EA ŽŽ}é´d FÎy CI’³VÆU«UMOOkqqQ[[[zyyQ¡PÐÔÔ”r¹œz{{%Ižç%°0”œóŒ3I’sÖJ’ŽDZ•Ïçuzz*@årYKKK—@©ått$5g_^àõõ•‡‡êõ:õz··7Â0äþþþ“d¾{ÍÏ:KôóO¹Oâå?:û¶ZÂýIû»éóµ~´6´küh?ûÁNû Ø––Ä_¦íIEND®B`‚routino-3.0/web/www/routino/icons/marker-86-grey.png 644 233 144 2725 12573351601 15635 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“ŠIDATHÇm•OhTKÆ¿SU·ûö m;$f”žH\;`ÂDøÐ] /Â`Àl^/fnfdx›ÐóhܸynÞvp£Ä ³±c¢85ÆVMglÈC“N¸ÝÁÖÜ?Ug¦{¢¾ ª øêœ_Õ9E™LëJ)d2“Íf¿aæ At{žÇÿG£Q²,ë ýÉdîd³Y†! uSÉÌš™›-˺èûþ@Ç)™LBÑp4Æ T*Áu]¶,‹"‘Èp%¢E"’´ ˜YhSJåjµZ["‘=*R©E£Q|)ÏóÏç9—Ëé•••Çqþ µ>ÊÌÿ%"!<Èv(¥þíû~[{{{pæÌk×®]$¥35”Rhmm¥ŽŽ±´´,//',Ëú£1æ_Ì\•}}}ðó‡···étÚ²mƘFdBˆ>¡efh­á8º»»å›7o‚wïÞ%lÛþM,»!|ßÿÖ÷ýÁD"aúûû­:7)%„B€™fõC”Rƒûûû­D"a|ßô}ÿ[ÁÌ?A€ÞÞ^Äãqh­!¥D¹\Æ“'OP( µ\×ÅãÇñúõkŒ1ˆÇãèííE`æU†=ñxœ;;;H)‘Ïç122Û¶áy’É$Òé4Êå2.]º„ P«ÕÐÙÙ‰@*•wïÞåZ­Ö£<Ï㎎‹Å†!”Rxðàš››qöìY,--áÂ… ˜ŸŸÇôô4¶oߎÁÁA‹Eܼy®ë"Ãq$“Izúô©QŸ‰FzÐÓÓƒ7nàòå˨T*سgâñ8J¥b±Ο?X,†cÇŽ}†lÝG)¥Y]]E Ó••03<σçyXYYçyÐZcmm 'OžDss3®]»†jµ )% V«Aa„mÛºX,šÙÙY!ðñãGÜ¿'Nœ@:ƹsç‹ÅËå‰DpèÐ!tuuáÔ©S`f‹EÀÜÜæææØ¶m-üC)%r¹\X©T‹ÅÐÔÔ„ÅÅEÀòò2ªÕ*’É$ZZZP(ù|ÐÒÒÓôIÿ”§OŸžZ[[Û]­V÷-..†ÝÝÝbëÖ­¸sçîÝ»‡G¡µµµ‘òÄÄr¹^½z… «« £££¦P(HÛ¶gƒ ø Ào-ËšzÿþýïŽ9búúú„ëº(•JØ´iÚÚÚܪÕ*æçç±mÛ6ìܹ³³³|åÊrç£1æ÷ÌüR !€_Œ1ß;ŽswjjŠwìØÎÎNlÙ²¥qyõŠÚ¼y3öíÛ"Âêê*nß¾F"‹ˆ†ˆè%%„,"šBüˆäØØXàº.ˆ¨QMõ'ÇÌò]×µ"‘ÈÕ½{÷þ@ë2 "±ÿþ‹ÑhôªëºÖèèhX¯óbfH)ñðáC3==­ššš|ßÿûÌÌL£7ÈÇ×7S©Tb­õlÛþîíÛ· ­µÙ½{7i­Er¹Œ‘‘¶,‹ü™ˆ‘ @d³ÙFSB(!Ä‚1&í8&''9ŸÏCJ c ˆA`xx8ô}_H)/ÑUÖ:Fd³Yˆúd]_ñ½uëVP©Tr¹œYXXPÑhô¥çyCÇÇFC¬ƒÅÆ_ñ½~ýzÏŸ?Çää$Ç1æ¬RêÃøø¸À¹Ë‹_ãF¿[ZZJT*~öì™®ÕjÒ²¬s†™¹ÁqCPŸ}½€ _¶2s¯bÂó<­”’J©\*•úæÅ‹Bkm¾4ü,ý_ÁPç{™°m[J)´Ö™™™ùìý~©ÿسÓk®Á’+IEND®B`‚routino-3.0/web/www/routino/icons/marker-47-red.png 644 233 144 2070 12573351600 15426 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“íIDATHÇ••ÏkIÇ¿U]5“id‚ìa:ì%!à1q/ƒa' 9 ¹9‡Åý‚§Íq% ’8ˆ§\Ö€›[®"QãEfr=$$è’1ý£¾{¨êd2²ëºª»>ýÞ«÷} œšÍf¯k­_ ãFöε֯²Ùìupûd nô$~ÒZ/Æq\%ÉÁÁA111­5Œ1R"Š"lll`ŸB¡”jDQtÀNçä —<Ïk`¡PˆêõzÒéthŒa¯cØétX¯×“B¡ Ûw)8õ8ðXèÑùø1ÙjÑɃ+++Æ„£)PÙ3פ”7³Êê³Tûív›CCC©ök½<ÐB(¥î¹ü†M'ÙäøøTûNÿ©æ«Õjäzkcxxžçt(‹WJŽŽŽBkÝ8“ßT 'Lëýââbâ€í“îÔÓöзh­[gòëÊ& {kk‹¾ï'(¥ü¥?ì~ûa~]ùD®Õý.¬ 4~`gòA˜¶D’¬ÕjiØ[üùùùÞßÒ?[~'''#’l4¶aHI!Ä5÷º÷C`~•R-œ5ãããiØ5¶ú¯À3ù0%„ €ØyøW±X„RJþ_àI~Ýø«çy”R¶ŒôEóý G@m{9Ý#IEND®B`‚routino-3.0/web/www/routino/icons/limit-18.9.png 644 233 144 1451 12573351604 14666 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÞIDAT8Ë­”½K£[ÆŸ÷Í“W]¢¯Íê»…Xna¡)V„Õ­\nÿÿŒ¤Iegér]¶’--ñYw° XY¨(‚ æMÞ3¿[$ñê­803ç<ÃÌ™gFHB¾ï#ùH"‘ø i Ï+ÒÙ ¯_;:;ÁóŠHK{!ù œP3P"á!yÌÍ%rA‰l¾7ÎÎàúÎÎêv6 APBÊ5Þ{ ¼D<îÓÚ*úûŽ™ž†ÓSD˜9žJÝŽ8=uLOƒtLÿ­­"÷E:-ff¤?,.„€Q«A­fÿ¦ Y\é33ét£L)Ïì,@5 C\€sŽZ­†sÏtÕ*µ0ÄA•OŸ@Ê7ÿì ApËñ1˜5™fö¤B{îw³£#‚[¤7BZbaƒ`ccƒ““ö÷÷Éår>f ppp@¡Pàäè ²l¤%!ýdeÀý³²B,cmm½½=ººº˜ŸŸ§¯¯ÝÝ]ŠÅ"ƒƒƒŒñîí[.£ÈñíNúé«£ã½>|I¾‹)•JI’ÌLÉdRSSSêííU©T’$mmm©»»[›››Š'“ZûúÕ×Dz¶¶÷¾b1Ë$Í}þ¬ááaÝßßëúúZ===Z^^Öåå¥Òé´$)“ɨ\.+“Éèà÷oµ´´H¯^I¾/3OÕªšâœS"‘ÐêêªFFF´¾¾®¶¶6moo+ CÝÝÝihhHêìêÒÀÀ€T.ËÏ×íí/mlH’IRGG‡*•Šòù¼vvv”J¥4::ªÉÉI«½½]årY…BAù¢±‘ÓŠ•J¿» D8ÇÍÍ „aÈÅÅQaf\]]P©T8??ǪÕ:naá±›užÕÛlDÑ# šÜzª›®Á3Æÿxöl¬V£ð)YŸéQDƒÜUfgŸLÀ‹Îæ‹nÝg/¸iÿ™mIFèa/IEND®B`‚routino-3.0/web/www/routino/icons/limit-75.png 644 233 144 1303 12573351602 14514 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“xIDAT8Ë­”¿KcAÇ¿/w¼Ä'j$i$À¶vvþ1…‚ ؘÎBÿ -ÄFll±¹R°°°Á‚#&ˆ"úÞî~®xI.ÇýjXØÙýÎÌÎwvFHB‰D)$R©oHÛxÞé4ŒŒXÒið¼ ¤íö½m;¡Ž£TÊCò˜ŸO!­¯,/Ã÷ïŽFžž Ñˆõåe‚W¤õ6ÞkÛKø~‚dRäry¤Å"Ôë08gé•X7Ôë–b¤¹\ždRø~Bd2¢T ®X[øQQÎý\3pÀkk ]Q*d2í4¥ ææBŒÁEQϲÖbŒéêÎ0&ÆÏÍ´Ñál‚ xáú:Žƒþ/1Îq} Að‚4ñUÒŠÊåA –0üâù¾nooutt¤þþ~¥R)MMM©V«éîîNÉdR Qäy…‚U¹<¨!sp`Íǧ§§LOO333ƒïûìíí1>>N±Xdqq‘‡‡‡¸a`98é\ 9îï;Õjg§ºµµÅêê*'''ôõõQ*•8<ð~à´Ïö6HµÁ›-bm—ûûäFï !Bø’]À97¶‡s ÿþ¬í"- ©ÎÁ€#އ­V‹jµÊíííоÙlòðð0¼ ÎqpR]H×4Þõzœ1==ÍÞÞsss\]]qzzJ&“¡‘p‰ãx§ÑéÚ¨PXÑúº$#IòÞËZ« ÍÎÎêííM™LFårY! ‘ðÖ×¥Baå—ŒAÙl¤/x~~ÖÌÌŒŽŽŽôôô¤R©¤ååe---éããCßÍJÆ`B¤~_’H’޵¶¶¦óósYkuyy)IrÎéGôûR‘Q·ÛR³)IÁ¤gµZM*—ËZ]]Õîî®$©P(hjjjä$I9¨Ù”ºÝÖ·ß ×ëñøø˜??Gòøá7¿ȩ́ZÆæcøÎ~¬€¡–ÆJ3Œ%œ*`¢µ9Ñ®1Ñ~6ÁNûë\Ùƒæ˜çIEND®B`‚routino-3.0/web/www/routino/icons/limit-51.png 644 233 144 1307 12573351602 14512 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“|IDAT8Ë­”1K\A…¿™èº>DÝ…¸vŠÁÂFL“&‚­b¡"Xˆ»…° 2öboØ? ²VZ„ …`Jƒ‚‚èJpÍ{3sR¼·jؤÛSœ™{Ïν k­À P>ÿN°#cN58(‹^ƒƒ’1§‚ìÍò-¡|ÞŒ––ò‚/Š¢_*—¥¯_ƒ®®¤Û[éê*åå²E¿_²x“åƒr9«ž422&ø¡ùyéâÂKr Áë5Rîtqá5?/ÁŒŒ©§år•Jha!œ©Z•¤ß’‚’DJ)„—ÕÚ“‚¤ßªV%8ÓÂB¤R){&lkqQ’b9'9§$IžWA’䜓Aò¾%kqQ‚íÖŸM(Š:?O+:§Á9÷,šm¤ñççR5o>Ág66>²¶æqÎÒÕE’$Ôj5899a||œÞÞ^ !P(1ï oßz~þìåÛ·7øÀÌ €‘ÀÝÝ›››ìïïS¯×i6›Ôj5fgg9>>À{Ƙ,ÿƒe`à}Fl ÅÑÑHbnnŽR©DÇ B+ °À23ï»°Väri‰´Åb‘••¦§§ÙÚÚ¢¯¯ååevwwy||¤ ¹X+K†8¦e`€ËËKFGGY__gxx˜››€¿oõq !K£ñz ˜ìÏ&''ÙÛÛ£P(055Åêê*ýýýtww¿ˆ¤âzïvT©H’˼#IzzzÒõõµ¼i‚ûû{5›Í{¤ñN•Š;í>ó^!„gOùŒÿÃxm>ûo©Mä™g1íÐÑÞìèÔèè<ëà¤ý—¦°“>uÒIEND®B`‚routino-3.0/web/www/routino/icons/limit-1.7.png 644 233 144 1265 12573351603 14576 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“jIDAT8Ë­”ÏJ#AÆ¿!&Ãbœ xÜSÀ'pâUr0gAAÀXØ£^%à9|oŠxA0 ˆ‡Hr0ˆÄ?3ÝýÛÃLü·âÉ‚†®êª¯«Š¯JHBA H"Ÿÿ…T؆‡áçOÇð0s‚TËÞ…dqB} |Þ ªÕ<Ò*axÏÒììx:¸¹N'Õ—– ï‘V3“ÅKärƒƒb||éœÙYhµ`ñÞñVRÝÒj9fgA:g||‚ÁA‘Ë¢T•JˆÔdeàð$ $ xÿzú6ðÀ3++ 5©TBJ¥¬Li¹9€˜$ç°Öâœ{“”'I’ô<=áSИ¹9Öú=+†=ÎÎÒ­ÅZ‹÷ž/ÅÚÔÿì °‡Tø#ýÕÂÂoÍÏ;Y00  tpp 眢(’$]^^ª^¯«ÙlêôôT?††E‘adÄ™««‚ŽŽ„tD£à²~°µµE.—£‘ÚØÛÛcjjŠééiŒ1ìîî¦ ‚£ÑéH‹žv»ßœsloo366F½^ ŽclZëëë,..à2í6‹^D‘£Û}K²ìfffØØØx¸¾¾frr’f³ù¬Û…(r¼7Šc}l1’¤‹‹ IÒææ¦FGGU.—åœS©sKÞ›@½Þ±ö÷%ÉËû°0 U($IÕjU’txx¨J¥òöÇ4n_êõŽ…Tcy9íeV"ÀÝÝY]¼÷ÜÞÞòðððJÔß²¼ RíSž}%/üû„gÿO€µð´ýû; ìÃ|ël~ëÖøÖ}ö›öcœ!`߀-IEND®B`‚routino-3.0/web/www/routino/icons/limit-38.0.png 644 233 144 1523 12573351606 14661 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”ÏK[YÇ¿ïUç%F' £ 8-“®´èn:ºp„XDœ‚UÐuqþ—-n]¹б¥-Âø¸5”:X7’øclÇvìË{÷~f‘Øjgë…Ë=çÞsÎ=÷ò9GHB®ë"¹H¢¹ù;¤Eç%mmLÚÚÀq^"-6Î…ä6ü„Î57;H÷î5#=Âó>0= ÏŸ[ö÷áøö÷ëúô4xÞ¤G {§á/‰¸D£¢««é ù<”˱ÖpqÔõrÙσô†®®¢Q‰¸"“ÃÃÒkfg|À`í—y¾ð™é5ÃÙLã™Òc  ÔßÇÔjc‚c.'hj5ßÇBB¤ÇçvÏ{owvê76¿`­ý¼ZkÁ,X»³ž÷éæµ9iž~p&&ÌŸ¯^¹¿-/+‰¨££C[[[Z^^V"‘P&“‘1F®ëjwwW¿¯®*“J9ßÞ¸a(—¿qJ¥k2R‰/Ø=>6ÉÖV …¹\޹¹9º»»£³³“b±@¥R¡¯¯ÞÞ^rׯó7ž>ÅH%W--·tçŽÂwïÜ_çç5::ªöövÉó< )›ÍêôôT’´¾¾®h4ªíímµ´¶êÕUWù¼l,v«ÉmjBÖ:¹žuNLèçû÷uxx¨ ”N§µ´´¤ƒƒ¥ÓiIR†ŠÇã’¤–DBÿ~ü(E£’ë↵š£x\+ÏžéÇÛ·µ¶¶¦T*¥…… jccC±XL›››”ÍfU­Vµ··§¿Þ¾Õ÷¹œtz*Y©Ä“'üæ§»wI$ŒS, ™L299I¹\¦¿¿Ÿ““¦¦¦ˆÇãüòð!€ae+•„´ÈÌ @|úDµZ%¨ƒ‰ïûT*Â0ÄZËÑÑÆŒ1uÙ÷Bff@Z¼Ä™ipf­ýàœ¹‹œcÀÌWœ}©€‘€š ÃÿÁzICl=û##*àJkóJ»Æ•ö³+ì´ÿûe3”jIEND®B`‚routino-3.0/web/www/routino/icons/limit-187.png 644 233 144 1432 12573351603 14604 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÏIDAT8Ë­”ÍK[[Å×=›k¨_!Fp"ôA!8ªâ¨ƒJÁE!fà¨`Aÿ€üÞ°™g¦ƒJA¡(…'8'‚H¥PÅ:Ë@t4¤oî=ç÷ùxy}oè†{ï³×:¬½…$$aŒA2H"~C*ãyß‚tÚ24ž÷ ©ÜÞ’iã„:DAà!y ÒR©Ÿ¬®ÂçÏŽëk¨Váúº¯®B*õéC»Þkã%|ßLŠññçH?XX€JÅ1ÎYz­ÇT*–…~0>þœdRø¾££bq1…tN±Ž(‚(çþY8 ¤XéœÅÅ££ígJ%––šÄ1qbÀZKEXkqÎEQ5›8h²´R©óg9R©——.C\›È9×õ;q׬mÝðòR©R.ñ‡ô§VV^éÝ;Kãû:::RÇJ§Ó:;;Óææ¦²Ù¬†666tqq¡ïççzÞð‹–J¥Ï;=Mé”OŸ,Ö²µµE"‘`oo““†‡‡Y^^&—ËQ*•˜effOâ¯/_lüñ#H§Fƒƒ/õúµ$ò>ÖÈȈ¦¦¦4??¯ÝÝ]åóùΩ-Üá¡T«}R™µ5€¸-Hîïïi4„aÈÍÍ Q{ïî‡‡–à[¬”PJ=ÀJ¥$°`0`dqÒâ(b0Ð8•J%@¥ÔS)%ÉdVÐ÷}ÓívI’áp8N1†LÒ`Œ½H†aH’ìv»ô}ß`&“Y…Rê6 C’aØÃ?’‘/^ÉCŒùú5Ó÷7 ã¢}q>Ÿ{½ž•F’ÛÛ$@æóÖ߸aaÃ!y|L..’++ö~m¯×c>Ÿ]ËÁÔj5’d”D23CÞ¾m?¿oÁ¯^‘oß’çÎÙï7oÚÿ£ˆ‘Ë{­V##H­5€BAT«ÀÝ»¶/¦¦¬ÿú¸zh·…àøøllH€ãH0óóó<==õáHêƒd&CÞ¹CWëWVÈ¥¥Q¤I‹•Ëe0RÌÖÖ–=G’í6yù2yñ"ùøñY[%E¬VGÐh0 Iîîî@,„àyÞoX,ÃQÓ_¹B–Jä§Oòå‹&ðÕUòÚ5[Ô(âÉÉ ggg#7 —ËAk½ €•ë×C~þÌèüyÒóÈlÖz€ÜÙ9ë['ß••ëëëÆÿKR]ÐZ`ýÞ=Ã7o<|H>yB>{fûÕ †ÓÊðåK’äÎöv쀧BˆRT ¤\–BRF­çÏm~ÿeD“1&ÉÃÃC‹Ådöëih!”R÷°X(vÛ†C[õÔ¶2® n­­…n·¶¦§§áyžDÚ”R²T*AkÝrË%´u6™÷ÍÍM〇£í”Z{˜øÁ×Zw°^¯ÛIÁ˜ìýý}ær9€RÊ_&eOšÍ¯ËRJˆZ­ÖX„®}B·<~B€ÆÿØX~}ߺ©Ê×ëõDö>€ÜÆÆFúµôß6™ßÅÅÅ$[­–]RR±œz¿}—ò«”êàÚÚZ<77—È®;Ùê{cù°$„ €ÈEøçÌÌ ”RòG£ü:ÿ«çy”RøyBÍ7öÐÀŒUBÙ‚IEND®B`‚routino-3.0/web/www/routino/icons/limit-19.8.png 644 233 144 1446 12573351604 14672 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÛIDAT8Ë­”ÍK›KÆŸ÷MŒñÅÓD¥Eé]\$\p“E)nÔ…UÅÿÿ÷é&+w.Å.Š-nܸBCIì…‚’•‹ ­ùxß™ß]䣖öî<00gfžgÎÌyÎ’„ëºH.’ˆFÿFÚÃq¾06ÏžÆÆÀq¾ íõö…äöpB}¢hÔArX_"åð¼ïd³ðþ½¥Z…oß ZíúÙ,xÞw¤\ï¼ÓÃKD".ÃÃbfæÒ++p}m€k ­ë\_VV@ºbfæÃÃ"qÅä¤X]õ¾²³Ð,¾¾Öþý5°@›¾²ºê19Ù{¦ô–µ5€NÐncºŒ1ø¾1¿h:üv^¿émÿÏ’x^ƒ«+°¶Gd­ÅZûÿóîÖ^^‚ç5’BÚc{ @¡P R©P.—Éçó¿a©T"—Ëño¹ Øl¤=!}æàÀ¼;8 sttDµZevv–L&C*•¢V«prrB"‘`ss“©çÏùT©>| >»zú4­—/e%× …Ç522¢óósëììL‘HDÇÇÇ’$ß÷åyžõ×Ô”šõº«W¯¤ÑÑ´«PE"²’Ö76477§Z­¦ååeÝßßkiiI’$ÕëuMLLh_···JÄã’ëÊ …pe­£NG}³ÖÊu]5›M%“I-,,(‹izzZÖZj~~^§§§ò}Â>éoó  'îkk*àQkóQ»Æ£ö³Gì´ÿæÔhD¸8\ÓIEND®B`‚routino-3.0/web/www/routino/icons/limit-15.6.png 644 233 144 1466 12573351604 14666 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ëIDAT8Ë­”¿K\Yǿ÷"âdFd*1 b%A›0¬Ica1ƒ‹`mÿÀ–Io™laqi¬,$›&LP–ÙððWÀÑ}¾wïg‹™1Ù_Nñ=÷~¿œ{ùž#$! ×u‘\$‘Nÿ„´€ã|¤µnÜ0´¶‚ã|DZ¨Ÿ É­ó„Bé´ƒä0>žFz†ïef^¿¶|ùAPÃ33àû_‘žÕï;u¾D2é’J‰ŽŽ›HÛ”JP© ÆZÃQÃ1•Š¡Ti›ŽŽ›¤R"™tE{»ñ‘>1?–(‚(k¿g£™Ÿé##>ííõgJϸˆÃS#EÑeZk/4QD†¸àÁž7þì¾_e{›¬­ ý_XkkÂÆÔàÖø~éVâ©ô‹ž<)ðø±q%÷÷wï(“ɨ\.kmmM›››êêêR*•’ã8ÚÝÝÕ‹—/å]»æäûú •Šçll$„´ÁÒ€ùmi‰¦¦&–——‰¢ˆ\.Çèè(“““AÀÑÑ…Bááa~¾{—?ªUC¹Œ‘6\µ´Üѽ{²’ë$Êf³ò/IZ]]ÕÎÎŽr¹œïßWÎó\ rZZî¸J$P2)+iüáCõôôèääDÙlV*•Jš››ÓÊÊŠ$) ÚÐà ~}õJëïßK™Œ¬„+k]\¨€\×UêììÔÔÔ”òù¼ööö$Ižç©¹¹YÓÓÓjkkÓŸŸ?K Œq\U«ôö­$YIj¾~]€z{{µ¸¸¨L&£‹Eõ÷÷khhHÝÝÝò}_·ûú4ùè‘Õ›7J|ûöAH ÌÎÄÃññ1gggœŸŸ³¿¿1k-‡‡‡Xk‰ã˜ƒƒâ0¬ñfgAZøî³­­š³ãøï~‚K±FÝÆ`þá³M€"þK°ˆcêæ¾`lì‡ ¸ÒÙ¼Ò­q¥ûì 7í_=ëE_m^Û]IEND®B`‚routino-3.0/web/www/routino/icons/limit-30.1.png 644 233 144 1415 12573351605 14651 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÂIDAT8Ë­”OK[KÆŸs®‰ñÐàÂÜrQ,ê"û—®*BOܶ«øü·Ëfç";-„6ú ²–RPíåt!ˆQ£im=gf~]œ˜jÝúÂ03ï¼óÌ33Ïû IHÂ÷}$Id2ÿ Õð¼FF`lÌ22ž·ƒTë­ ÉïíºÊd<$r9ƒô† øF¥?:Žáì Ž“y¥Að éM/Þëí—H§}E>_@úÊâ"YÀàœå®%sÃÑ‘eq¤¯äóE:í‹ñq±´ í±º p8ââœûÝn}à€VWAÚci)`|¼wM©Ê‹Xˆâ›l`­%Žcœs÷b &ޱ† Uoßì)Apé’­íÝ‚8çîcpÆ$ñ—HO…Ts• €ÙÛÙ¡Z­²½½ Àþþ>kkk´Z­ Íf“ÿÆU* Õd¥ÏÔëüwvfdž‡)—Ëäóy¥R‰ÙÙY¦§§9??ï3ÛÜÜ$Nóþí[¿{Òg_ÙlQóó2Žÿïë× ÃPSSSª×ëÊd2ÚÝÝU6›ÕÖÖ–$)Š"yž§\.'çy’äk~^.úþÀrNÓ…‚^¾z¥ ]\\( I’²Ù¬®¯¯%I€Êå²fffú>¥R’ïã›(òôä‰Þø g¥’†R©”Úí¶®®®Ôjµtxx¨ÉÉIžžÊ9'II XKÎyþ_ß¿ѧOz†îï\N£££š˜˜Ðúúº …‚æææ´¼¼¬b±¨……u»]IRJ H’óšMéòò‹j¬¬˜øçONNNˆab­¥Ýnc­½7èt:üèv ++ÉoÞÕ™íéÌÞij®oÉÚ%†‘‹cHÙ×Öƒ±1¸„ýð¨¹ù¨UãQëÙ#VÚ_unÅî´ÅÁIEND®B`‚routino-3.0/web/www/routino/icons/limit-31.png 644 233 144 1245 12573351602 14511 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ZIDAT8Ë­”¿N*QÆ¿=*5$QŒ$ÞÂ+ KÃH,ÀÖÀ7°•ž7 £ô¨lü“X`°¡ ±ÐHb0²çœß-vA¯z;¿d‹Ùùæ;3çÌŒ„$Œ1HId2ZÁ¹äóŽ\‚à©•ø…d’8¡™P& Ôj¤sÂð•z:ÏhOO0Åv½aøŠtžðƒ$^"•2¤Ó¢XÜFº§RáÐïŸÛ–áÐQ©€tO±¸M:-R)# qt"õ8=x’³Öâ¼çf¢SªUš³;+†cúýøDkñð¥:µï?y¬ùý>„á©$¤€%Šæ½^f³ÉÕÕÕ<¾Ûíòðð0? ÉÎÒh€ÔÒ5í6€sÓ)ƒÁ€|>Ïññ1›››\^^rqqÁÂÂí˜KE³ìí6H׋Êf÷T.K’‘1’$k­ÎÎδ±±¡Á` Éd"cŒÖÖÖä½×1ߨ\–²Ù½EƒR© öÅb;;;ÚÚÚÒÉɉžŸŸµ²²¢ýý}íîîj2™èR)ÉŒ¼4J’œµ’¤v»­ƒƒu:-//ëææfžñ˜N%ï£ñøVÝ®$y’¤ÃÃC­¯¯kuuU¥RIµZM’”Ífµ´´ô!—ìÕíJãñí·×œ!Š"ã‹NðòòÂÛÛŸHß^óß>sïý¼Y]bÃúìÇ ˜÷Ò—æ Åœ/ð«³ù«[ãW÷Ù/nÚ¿SZJa;qIEND®B`‚routino-3.0/web/www/routino/icons/marker-69-grey.png 644 233 144 2726 12573351601 15637 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“‹IDATHÇm•_hSYÇ¿¿ó§¹¹E%ÄV ÙJú¢iYË2,¥ŠDÊTXé¼(²ó0/»Ë2 % Á—}_æu@q1 ®}Ñäe³Ù¥EX”¥­i‰Rƒ³‰Mb5Ú{oÎ9û`s·£~áÀ½pùÞßù|çw(•Ja[LT*¥Óéô„1æ/žç ;Žcþ/HJù"ú>•Jý=N³v» hÛ”c”1fŸ”òŠëº_{žgB¡Åb10Æ|G­5Êå2†‘RRWWWÆó¼ßщˆP3Æ(ýBˆ|«Õê‡ÃíãdzD"A@Ëq‹E“ÏçÕÆÆÆ×¶m©”:nŒù™ˆ3ú„ÿr]·?{333òÀÄ9‡1æ“%„@4¥ƒ²jµê½zõ*,¥œÒZÿÍóš'“IøñÝ»wãñxÜ;þ¼´, Zk¿2ƈDÐc ”‚mÛæÏž=ó*•Jز¬ž`08Ç\×t]÷›p8¬§§§e‡çŒ10Æ`Œñ͈Œ1!üOOOËp8¬]×ýÆuÝI~ôèÑ¿:ŽÓ—L&M<'¥8ç¨×ëX]]E«ÕB(ò+­Õj(•Jp]¡PZkض !„YYY!)å€h·Û_„B!344Ä€sŽjµŠk×®Áu]´Z-$ œ={ËËËÈd2صkÞ¼yƒ#GŽàÔ©S€ÁÁAV(L«Õú‚9Žcb±ƒA(¥ÙlÑh—.]¹sçP«Õ°±±l6‹ÑÑQ\¼x.\ÀÇQ­V¶m#‹‘ã8F|ÈáCrαµµ…J¥‚îîn\¾|Á`“““…Bxÿþ=B¡`÷îÝð<•J½½½~ ãœëÍÍMxžç§íyÇÁÉ“'±oß>d2¸®‹±±1ÌÍÍáúõë¸zõ*Çñ;Z­cšY–¥ž>}ª———Dc ÆÇÇqøðaœ>}D„R©„‰‰ LMMˆ022‚={ö@J X[[ÃÚÚš±,K1B°|>ß®×ëˆF£(•J€b±c úúúÉdÐl6133Ƥ”èïï‡R ÙlVÑýÄÏœ9³°µµ5ðúõë_W«Õöðð0ëééA¡P@>ŸÇ“'O0::Š¡¡!²Ù, …^¼x©©)D"ÌÍÍéÇs˲–=Ïû-ÍÎÎÀ~)åÂÛ·ouìØ1L&Y½^G¹\Foo/öïßï7~­VÃóçωD‰D°´´dnܸA¶m¿×ZÿƳ*cÀ ­õ9Û¶ÿ±°°`úúú088è7}ÇЃžžìÝ»D„ÍÍMär¹vWW—$¢Y"Z €6IDÆØˆˆß»wÏk4 "h­ý„;Æã™ËåÚFCvuuÝ2þ„ïíÛ·ÛðèÑ#ÌÏÏömh­¿B¼Ëår€ÙÉï|ùß@ ðUµZ 7›M³´´¤Z­—Rþ@ÆãsÜQ~-€W¶Ð6ÆeŒÇQB.„È'‰‰••¦”ÒþbûŸÁÐáûOcÌ÷–eqÎùºRêÛÅÅEö~Nÿ+tÇ*úIEND®B`‚routino-3.0/web/www/routino/icons/limit-15.8.png 644 233 144 1456 12573351604 14667 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ãIDAT8Ë­”ÍK[[Å×½ I¼-{ƒ!OA¬ ”Œ:PJgjPª•¢bA þÞ°;sôûÐBGâD„¶d JGAB>(XíÃ$÷žó{ƒ$¶}37l8뜳çlÖÞB’p]ÉE‰ÄÒŽó‘dnÝ2$“à8‘6:çBr;<¡®P"á 9ÌÍ%žãyßXYׯ-å2|ùår¯¬€ç}CzÞ¹ïtø±˜K<.††n#ËA©d€k ?F‡”J†\¤††n‹XÌé´˜žö>±¾Ð,AAÖ~ÏîX Éú:HŸ˜žöH§;ß”^0; Ð ›ML›@Wi­½z iµšM ´xô¤ÝšÝÁó¾rrBÖv„þ/¬µmacÚðø<ï+ÒÈoÒïzöìOŸWrß¾{'@}}}ÚÙÙÑÁÁŠÅ¢FGGÇå8ŽŠÅ¢þxùR½7n8élÖP*õ8…BDHòyóg>O4e{{› H¥RÌḬ̀°°Àéé){{{¤R)Ìdxÿù³áÍB©àª·÷®îß—•\'‘ïûêééÑÑÑ‘...hjjJ’$k­<ÏÓää¤~Ôe½îêÁéæÍ»®"‹ÉJš{üXÙlVçççò}_óóóÊårZ[[Óîî®$©Z­ª¿¿_›››ªÕjJù¾äºr"\Yë¨ÕR7¹®«r¹¬ááa---)“ɨ\.K’òù¼ÆÇǵ¿¿/ÏóôþÃ)• Cçªf€©‡ÙÚÚ¢V«122B2™dyy™J¥ÂÄ懇Œáû>¿>yÂ_`xõ +„´Áê*@ˆ1œqyy @£Ñ Z­bŒÁZK½^ ÙlR©T6ou¤ï>;>n;; ö\‰ý´6óŸý«lð_‚] @Ò1w‹ÙÙ:àZ{óZ§ÆµÎ³kœ´qM`ižwœâIEND®B`‚routino-3.0/web/www/routino/icons/marker-30-red.png 644 233 144 2074 12573351600 15422 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“ñIDATHÇ••¿K\YÇ¿÷׌$%YÈ<‘àVŠ]Jf’"¤˜*!«!l‘NÒd@aÛ4šBX&ºMX™à?.DD ‹-L•ÁÉ+JWywîûnqï›Ç]²{`8ï]îù¼s¾œsøÛdOO€l6{Ó³ €’àÙùnŒÙÎf³7 ÄÉ$‚W€ïŒ1 ­VkŠ$ûûûÅØØŒ1H’RJXk±¾¾ŽÃÃC !„Öºb­} àNû W”R5Ìçó¶\.»f³É$IØiI’°Ùl²\.»|>o0Ä]I+N3Ž”R»8>>W«U’¤sŽÖÚ3?çI²Z­r||<à]‘ÇJ ­õK, q ‹ON˜Ä1ÙjÊ”Î1‰cÆ''mx¡PˆPkýRJ d2™[E‘«Õj$IÇg@mß!Gz¯V«1Š"€™Læ´Ö›¸¸¸èHÒZëƒ×ÖÈ/È÷ïS1½ÿð\Z"××O]Èv’¾¾¾äààÀÇ’äì, /z?;ë¯_“J‘.øó¹9¦y°¯¯/ -W,I’-’üòÅ<{æo?îßIòÆ òÚ5ÿ¼´äÏww™ª^, ÀIÒ`’™ °º ܾí}¥‹ÀׯÀ»wÀ;¾_ŠEï77ÛÓ8RHêõ:Ž¡¥•îÞœîß¶¶€óç¥ký3hí}·'hH)cî—åe/üþ>¹ºJ~þìkÚØðe¾zE^¾LÎÏûóOŸH€­J…$ùÛ›7!b(¥~À|ÞV ²Ñ ÈrÙonzèÆyïyõª?ú”Io/ÙhðÈZŽ ·ÂüŒ\.c̯X˜œ´$Ùzôȃ”"{{ɇ=h{›æ°X4­3>>N4ecc€x<ÎðððuCkkk 044„#ñÏæ¦áË|ië¾>ì×óç J%÷¯¹9=‰Fuxx¨ 4;;«J¥¢¶¶6I’ïûJ$Z__ׂ:c1½|ö̵߾éþ£Gý"1|ÿÀ¿å2£££ôõõ1==M<gbb‚®®.r¹Üuw§§§ôöö²·»[_¡‘ˆqƒjÕQK‹V>~Ô‰„VWWåyž2™Œµ½½­““íìì(ŸÏK’Òé´ÚÛÛÕýô©Œ$7$kYi‹(ƒyùâáp˜T*E±X`ii‰d2 @OO©TŠùùy0¬¬€´%¤E¦¦¿R¡P(àû>ÖZŒ1\\\P*•0Æpvv†µ–óós.//¡†¿€©)oáÌÔqfŒù|5À[Kt g¿JT­ï7*ÞBý­3´ª’JÝ`ÀróN·Æî³;Ü´ÿpj”åù¸qIEND®B`‚routino-3.0/web/www/routino/icons/marker-98-grey.png 644 233 144 2733 12573351601 15637 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“IDATHÇu•]h“YÇÿÏùHÞ¼mH·R-ÄJ[AR]Ê0ÝD‹N?Fap ãÅÙ½ðf]–-ÈÝÞ¬7s»wVq]½Ø´+-âRY5Áo-´j“Ö$Mãú~œsöÂ&SuæÞ÷ååÏy~Ïÿ<‡‰ÖÄ„H$:™L~eŒù«çy½Žã„Ÿe‚Á I)ÿKD?$‰%“Iæû>h 5SnŒQƘÍRÊó®ë~çyž ‡ÃFÁk8j­177‡R©d¤”F=Ïû- fŒQ:„™Z­Ö‰Düýû÷³X,FÁ`ŸÊqär9“ÉdÔòòòw¶mÿN)µßó‚ˆß³gÐ.„¸éºnGgg§744$·oßNœsc>[BlÙ²…vîÜÉ …‚·´´‘RÑZÿÃSáñx~z÷îÝÞÎÎNoxxXZ–­ucgŒ1ˆ> 5Æ@)Û¶ÑÛÛË_¾|é½yó&bYÖoB¡Ð?™ëº_»®û}$ÑÇŽ“unœs0ÆÀƒ1¦aFD`ŒAÑø~üøq‰D´ëºß»®û5ß·o_Êqœöx|×uÑÜÜ "‹E5–e)àG!Ëd2þÛ·oADE©TÂÐÐcàœcÇŽ( €¥¥%T«U´´´Òé´¢ú;?qâÄôû÷ï»*•Êo …‚ßÛÛË8çH§Ó˜œœÄÂÂŽ9‚¶¶6477cbb“““¸}û6ÚÚÚpèÐ!¤ÓiÏç¹eYYÏ󾥑‘Ø*¥œ^]]Ý688¨ãñ8[\\ĶnÝŠÍ›77‚_©TðâŠضîînd³Y“J¥¨©©éZë/Œ1yÁ´Ö¿·m{bzzÚ´··£§§­­­ ¢†¡1›6mÂîÝ»ADXYYÁøø¸ %€"Ê €@Ñ$cì ñññq¯T*ˆ µnœùºq}.¤Ói¿\.Ë@ 0ÖÓÓó7 €_¨GD¬¯¯ï|0+•JòòåË~Ýh½Œ1àœãÖ­[úÎ;¢©©iÞuݿܽ{·1 øÞ½{ë?ÓÜÜœQJýDz¬o^¿~QJé®®.RJ5âÆC±XÄ… Œ”’üˆn‘ €%“ÉÆPgŒ ÆØ¼ÖzضmLMM™\.Îyƒçyõ]×eœóóD4@®aD2™«?¬é3¾×®]óÊårãJÉd2z~~^ƒÁ¼ã8#ÀzC¬Å'ÆŸñ½té’³³³˜šš‚mÛÐZŸB¼»~ý:`Ösçë_~‰o0ü¦P(DÊå²¹ÿ¾ªÕj\Jùg£Æ˜Çu›ÂÇ­°îÊ|cÌ>ÆØ¤ã8JÁ…™X,öÕƒ˜RJjøQù¿€¡Î÷߯˜,Ëâœóy¥ÔïÝ»¥~Mÿ ŠÐ£´%¼ÇIEND®B`‚routino-3.0/web/www/routino/icons/limit-39.6.png 644 233 144 1520 12573351606 14665 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”ÁK[YÆ¿÷Zµj0ÈE ãbº)Ѥµ% ALÈÎQý\ºÆe»wáb:B§VlpçÖ…Hg‘EZè`ELP Qëà¼÷îýÍ"‘j»õÂ…sî¹ß9ç^¾ó IHÂu]$I´·ÿŒ´‚ã|¤§b1CO8ÎG¤•V\Hn 't“¨½ÝArÈçÛ‘^^1?ïß[Žáì Ž›þü39¥¿¿õLéSSðüFãycð}cî6h|¿ÑÀ€ÇÔH¯nþì1Ñè¥ÝßoVlo'°Öb­½k7ãÖîïC4z‰ôøÁoÒ2³³gfÆüóé“»öæÂá°‰„Êå²666Ç‹ÅdŒ‘ëº:<<Ô¯_+ÒÖæüô䉡R‰8¥Ò©D±ÈÁÙ™‰uw“Ëå`uu•t:Íðð0étšZ­@½^'“É066ƳáaŽ./ ››©äª«kPÏŸ+øúÕý}yYù|^©TJ;;;ŠÇãÚÛÛS(ÒÖÖ–$i{{[êëëÓÈ‹ê‹D\e2r=t݇‘µú%•Ò¯33Z__×ÑÑ‘ …‚®®®4::ªr¹¬¶¶6IRÍD##úsmMø õöÊJ¸ç9êìÔ_››zöô©ŠÅ¢ººº´»»«¡¡!e³Yõöö*™LÊó*• <Ïkí¯×ëBá8Ž~õê•yüø1šL‰ÏŸ?G¹\ÆÐÐ`ii ·o߯¾}ûN§qâÄ ¸®‹7nŠÅ"^¾|ÉŽãhàORJQ(Âjµ )%àÁƒظq#¢Ñ(Àq¬^½oß¾ÌÏÏãýû÷­[äóyM¿ê¯ÖáÇÿ±´´Ô·°°°­T*…;vì¾ïãÊ•+D<‡ÖB¬]»…Bããã¸wï:;;±ÿ~äóy3==m9Žó8‚ßYÛ¶mƒ1æÇqÎÍÍ­5Ƙþþ~Z³f úûû±jÕªV½®_¿Û·odž °k×.ŒŒŒàÙ³gœËåD$ù1f„ˆþ-…À¿Œ1¿w]÷Ö;w¸«« ;wî„1¦õD›ÕÑÞÞŽ­[·‚ˆ°¸¸ˆ\.Ú¶­üHDÓ¤PD4.„8ADV.— Þ½{÷I54Ÿjó°|>Öj5ÕÖÖv~``à/€°ùQD$†††NÛ¶}¾Z­ªË—/‡øŒ˜–eáîÝ»æþýû2‰Ìú¾ÿýääd+kxx¸¹™fffXký‹ã8_ÏÍÍÅ´Ö¦¯¯š‰bf!P.—qáÂVJ€?Ñ]"’4ˆl6ÛúÔ…R1kŒI»®‹‰‰ žšš‚eY0Æ€ˆFGGCß÷…eY§‰è<µŒÙl¢9YÖ'|¯]»ÔjµVK) fvvVÚ¶=íyÞ###Xiˆe°øÈø¾ccc!}*´Öæcîÿ M¾gæDZ,ËšÕZÿñáÇÐZãÿé¿o=·Yµ´™¤IEND®B`‚routino-3.0/web/www/routino/icons/limit-27.0.png 644 233 144 1512 12573351605 14654 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÿIDAT8Ë­”OH[YÆ¿÷œ&ÎkZLEœE@è´ŒÿPA† nÔ’!íÊM‹b»wÙY ̲]¨AA™…(2EZºpëb  HJ•4›NELB¢&yïÞß,míÌÒî¹ç|‡{.ßw„$$áº.’‹$êë¿GšÇqÞÓÐwîÀqÞ#Í×òBrk8¡‹Fõõ’ÃÇõHÏñ¼"SSðò¥åð>}‚ÃÃj<5žWDz^«wjx‰PÈ%--w‘>06Ù¬¬5|iÕ8 ›5Œô––»„Ã"rEs³H$<¤]¦§Ê€Å÷Á÷ÁÚÏ~q(3= Ò.‰„GssmLéÉ$*~¹Œ©T°Öâûþ¥[k/h*ür ’I^\üYž—·é4,Æ`­½¾:i-g ¬M§ÁóòHmu¿H¿òøq¿óè‘ù+•rWÖÖÔØØ¨R©¤ååeíííiggG‘HDÑhTŽã(“ÉhumMÍNôþ}C6û­³½]§@ÚæÕ+þÌdÌ-ÏcppÎÎNfffb``ÇqØÜÜàè舞žº»»i½wÀ°¾Ž‘¶D"–ÓS~ýšŸŸ= ££ƒÅÅEæææ˜˜˜¸sii‰x<À½½ü¶º ¥þÍ›ö›º7°Å¢“ÕwѨºººÔÛÛ«ÉÉIœœhaaAëë뺰 ‰D$I·nßÖÙé©K®‹k}ßqC!¥vw5<<¬ññqÍÎÎJ’VVVÔÔÔ¤¶¶6ŸŸ+—Ë)‹éøøXûûûúûãGýÐÚ* rÀqM±˜ÒÛ·úãÝ;T*ÚØØP,ÓÖÖ–R©”FGG%I…BA###êëëS<W{{»~J$4ØßoõæÜb1%¤yž>å ‚ãƒj^*•ÈçóœU¹e ¹\cÌçs¹ ðä Hó—<#®2Û˜ÿðêëØÆ`¾âÙX¨XßÇV%ó¿‚‹š |¡€kÕæµnkÝg׸iÿú~vbeú5IEND®B`‚routino-3.0/web/www/routino/icons/limit-37.png 644 233 144 1322 12573351602 14513 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“‡IDAT8Ë­”=KcQ†ßsš½ˆ1Qbp ‰¥í"XÙ‚‰µ  ?À?°°……v ÖiÒE°lü".ˆ…’€ˆH0Þ{Ïy¶¸IvýØ.SÌç™™óÎIHÂó<$I$“ß‘ö1æ7ccÉXÆÆÀ˜ßHû]»¼nœP/Q2i ËËI¤m|¿Ãú:ÔjŽV žž ÕŠåõuðýÒv×ßtã%††<†‡E.7…tM¡wwˆpÎò/ÅrÄÝ¥Péš\nŠáa14ä‰ÉIQ,úHu67ÞGB‚s¹§¼±¹ RbÑgr²Û¦´C¹ EEXk ƒk-Î9Â0ì³ Cˆ¢Ø¿\i§7³<¾ß¦Ñˆ_Œ"|è^2G£¾ßFÊ'~J¿´ºúC++VQä‘HÈ£ËËKU*ŽŽ*U*Õëu]\\hddDéñq†Æd³V÷÷ßtzšÒ)Õ*€µAÀÍÍ ™L†R©Äôô4[[[,,,0??1†£££¸¸·7Kµ Ò©H¥Í&6.««+ööö¨ÕjÌÎÎr|| Àîî.kkk±¯µñ§4›J9‘N[{Ãéäåå…¥¥%r¹çççt:fff¨×럓=>B:m=9g’$E’¤jµª¹¹9Õj5%“IÝÞÞêàà@Êçó²ÖÊó<õ)$猧vûL''’ä>ftt”••òù<{{{LOO3??ÏÌÌ OOO1`§`ÙßéÂ(.¨X”$#c$IÖZA R©¤|>¯““e³YŸŸË÷}Å~RW,JétÁÈäûú*ÏÏÏÊf³ÚÝÝU£ÑÐêêªÞÞÞT*•t}}­oþò}ÉŒœóÔéH’IÒÁÁææætzzª¡¡!ivvV Êd2š˜˜$yžƒu:’sÞ·šÙ¸ÜÞÞR(ammV«Åââ"ãããlnn&mMЫÙn&Òn·iµZ„]ÛÇÇß(ó[7ðÌv¹–pì_ÿðì× èqéÛhºO _' ¯³Ù×­Ñ×}ÖÇMûÆÞ¦—Þ®ÌIEND®B`‚routino-3.0/web/www/routino/icons/limit-142.png 644 233 144 1364 12573351602 14576 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“©IDAT8Ë­”¿K[QÇ¿ï 1<Ä_té ‚Ký*ˆ‹ ‰ƒ]qÓMÁ‚ƒƒ›S-dèê"B £ˆ¿2p°%’ЪyyïÞO‡÷Lµ-tñÀ…{î=çÜû=ç{Ž„$\×Er‘D2ùiÇ)30CC†pœ2Òn|/$7öz ”L:Hïß'‘¶ð¼Ÿ¬¬ÀçÏ–z ¨×#}e<ï'ÒVlïÄþ‰„KOH§3HU²Y¸¾6@ˆµ†çé!×׆l¤*ét†ž‘H¸bxXÌÏ{H_ÙØðK@€µ¿×ÓXÀgc¤¯ÌÏ{ Ç0¥,,tCBßÇXÛý1†0 »û ÝÆt:‘ýÂHžr6Žçµ¨TlèûØg¬µ]ýÅ> ±`©TÀóZHãBÚeu ´Ñk”J%®®®º«Õ*Åb€‹‹ ¶··)—ËÄxCVWAÚÒ)Ÿ>Œ!ŸÏ“H$ØßßÀ÷}2™ ¹\ŽJ¥‚çyÌÌÌN§9?9‰üÒ©«þþ·šš’$ׂÇQ*• IÚÜÜT»ÝÖÈȈêõºÖÖÖttt¤ÞÞ^_^F~ïÞIýýoÅà áûw‚æôô4ù|žƒƒR©KKKd2jµÇÇÇLLL°¼¼Œ‰‹b¿}ƒÁAãÊZGŽž‹µVƹ®«ÉÉIéîîN{{{š››Óââ¢vvvd­•$9A Yë¸jµÎU*I’U|Ù××'ß÷5;;«ÃÃC­¯¯+—ËillLFC…BA£££úR(H’5Å¢Ôj¿¨fLHšÍ&]^ÝßßÓl6yxxàöö–››jµ?~D~Ϫù‚gÄyø¯ÙÿÁ³¿:Àþ#à â6BñG¼jo¾êÔxÕyöŠ“ö}Ç›•Ë"IEND®B`‚routino-3.0/web/www/routino/icons/marker-11-red.png 644 233 144 1706 12573351600 15422 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“{IDATHÇ••1oSI…¿™7“KPÄ…_!¶ âà(‰Ÿ°¤¡§@ÂŶË/Ø4iRlƒXù/ A(‰b‹TȦpµ((JA oÞÌÙÂó’Øb÷JÖÈG¾gÎ=sï5œ…½té’˜ŸŸ¿ë½ÿHùÔùïÞûóóówržmˆL> W½÷[u]ß—¤v»mºÝ.Þ{RJXk !ðöí[¾|ù"cŒqÎõCÎñœÞp­(Š! N§vvvâÑÑ‘RJ:)%igg'v:(ç]k*n—EQ|´ººZ IRŒQ!„™OŒQ’4 ´ººZeâO@9¦µçÜS@ëëëUCV… T×R]k:R]«úþ]1W±¾¾^rÎ=µÖÂÜÜÜ=@eYÆáp(I !H)IYÑDÄxЇ$IÃáPeYF@sss÷pν´½½'ÇõI¯_7f^ˆ‡ª’$mooǬö@Z\\Lã\I:9‘¥µ5iccLT×â)«=88Ðââb’ÔívM»Ý&VÕ¸Ç^¼€åexó®\ÉMW\ˆcˆ1Òn·év»¬÷ÙÜ ·nÁÇÐíÂááÙxü—È<Öi4Ùoß¾±°°€$ÌåËà,,@ãÄá"0YÌçÏŸ’µÖÆ÷ïß§~¿Ÿs㌂™8‡ÇºÆZËîî.{{{2ÆDkŒù°Ož<©‡Ã!Î9R“äÜØËéȸ€Â9ŽyôèQ‹¶ÒjµðÞ?ËÍ$©>9¿øÆ†tûöÙëç—nð¦‹ÖFÅYk ‚ ÒÃ0:Ðgg¤òðÍæñý.F”ÑZœs8ç>»FlÑ£Ñßï"Í ©Âá!@H|‚4›MÊå2Õj€ûû{NNN¨×럠ƒ–CAª©Êù9€u‘‘N§ÃÊÊ ëëëlllpqqA*•"ŸÏ“Éd¨ÕjQÅ–ósªF‹Z]•$cA’tss£f³©ééiåóy½¿¿ëèèH···J&“ªÕj’$çy’d´º*ML,ƒb1J†J¥RZ[[Óéé©r¹œ¶··µ°° ¥¥%íïïK’ÆÆÆ¢€XL2#ç<õû’$/ʤd2©ññq(›ÍêòòR›››ÚÛÛÓÙÙ™œsßüÕïKÎyFÝnMww’äyT(477§x<®ååee³YµÛm]]]iffF×××’$átw'u»µ~s(aÒn·±ÖÒëõx}}åéé‰ççgz½^äôÃoþȳQ²Žrn$Û<û>_ìþ2$«sî?ð«³ù«[ãW÷Ù/nÚ¿ÿ`:¿¨ªóIEND®B`‚routino-3.0/web/www/routino/icons/limit-9.3.png 644 233 144 1333 12573351604 14577 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”?K+AÅÏn± k±€ Â{jå; ›h!QK;ý–v¶¦±ò ¨]*¿‚h£BD ±Pþ!ò³;3¿Wì&ïåÙ:00sçÌ™{ïœ{…$$áû>’$òùŸHûxÞýýP(XúûÁó®ö³s!ùÙ=¡Q>ï!y¬¬ä‘v Ãßll@µêxx€çgxxH÷†¿‘v3¼—Ý—Ÿ\NŒŽþ@j°´÷÷08gùw¤{Ãý½ei ¤££?ÈåDø¢XËË!R­-€6àHHpîïìØÀm¶¶@ª³¼R,faJÊe€c°qL’$XÛ똵6µÇ1“âËe*œM†-nnÒ@’×Êáœë®{"NÉ77†-¤ !í³¹ `\P«ÕØÛÛãöö¶ë@½^§R©p~~ž¦xÃæ&HûBºàè àúúš±±1fff˜šš¢ÙlÐh4( ¬®®2<<Ìéé))–£#.|EÑ/ÍÍÉI¾$ippP''' ‚@ÇÇÇ’¤8޵³³£µµ5‹EµÛmeÃ×ÜœE¿|ù> ‚”IR©TÒûû»T«Õ”Ëå$IãããZ__×áá¡^^^E‘$É“¤ |_ÎyŠãÎ+úøøÐä䤿çç500 ¡¡!ctpp ÙÙYU«UõõõéòòR’äR·%ç¼nÎ\–³··7J¥###looóúúÊôô4www,..Eår™V«E&¸nÎz~3$ŸŸŸ<>>âœÃZËÓÓÎ9Œ14›M’ —á{~³WgÆ`3Mý+ÚqÇî:•ðŸÎ¾TÆôˆôË:Ã|­€o­ÍoíßÚϾ±Óþ “†c9IEND®B`‚routino-3.0/web/www/routino/icons/limit-25.4.png 644 233 144 1500 12573351605 14653 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“õIDAT8Ë­”=HœY†ßï ;3û1‹&Ë8c¥LTV˜j!Ô*øIªAHMÀb ‚õÂb•”²Úh“À†HŠ€ ‹lµ0¨ &Ùl1ø3ƒ"ŒóÝ{Ÿó“ȲNqî=çåœÃû! Iø¾ä#‰Xì2Ò<ž÷šÖV¸tÉÒÚ ž÷i¾þ/$¿^'ÔŠÅ<$Û·cH ‚/LNÂó玽=øô ööjñä$Á¤‡õ|¯^/‰øD£¢£#ôŽ¡!(•,`pÎò½ÕbC©déi¢Q‰ø"™##Ò6ÓÓ§€# ! Á¹oÞxœ2= Ò6##Éd}Lé7ob¡žžb«UÂ0lºsî[‡Æ`ÃUnÝéQcgW‚Ï®XÄÃÚúDŽÿ3çΘZ‡Å"Ág¤+~“~çîÝ_¼;wì›õuÿÏgÏÇ•L&µ¼¼¬|>¯ÍÍMõôô(Ê9'ß÷õχz³¾îuf³–RéG¯P¸ #xñ‚¿ß¿·?}}}tww³ººJ:fxx˜\.Çþþ~³+k-]]]ô_¿`Í“' |ÅãWÕ߯ÒÛ·þ¯hmmM‰DB ÃPÖZ *•JÉ#Ïó433£J¥¢Ÿ Iò¹vMji¹*.^´öà€¿^½¢··—©©)òù<ããã,..’J¥XYYhÆ£££\N§ùwgޱ--Öwaèù‘ˆÖ··500 \.§¹¹9íî³ScccjooW¹\–1FÎ9e2mll¨T*ikkKònH§Áq> í ÷…äã„n%’ÃÚZé9ž÷…ÍMx÷ÎrvWWpv6ð77Áó¾ =žw†ññ¸Ëè¨ÈåòH'¬¬@«e€k wÇÀhµ ++ Ëåñ¸+²Y±ºê!}d{ X¬ýj·k`ÛÛ }duÕ#›>SzA¹Œ~Øëaú}Œ1„aˆµö›M¿OØëa O¹ Ò‹Û?{Œç}¶Çǃù/Ñmkí÷sc°`íñ1xÞg¤Ç~“vÙØ˜sÖ×Í_¾ï¾¬VÇ599©““(›Í*“ÉÈZ+×uåû¾_¿ÖD&㌋†V+é4d¤GGü}ueÆ=bmm\.G­Vc~~žR©Äôô4Aàû>…B¹¹9~,•ø'Š oÞ`¤†«Tꉞ>Uôé“ûûî®*•ŠŠÅ¢ŽŽŽ”H$äû¾R©”jµš$©^¯kbbBõz]ñdR¼zåjyYvlì‰ëŽŒ k5Ïë—õuU«U]__Ëó<%“IIR*•R¯×“$-..ªÓéhiiI¾¯X,&ŒH®‹õûŽ>ÔþÛ·úi~^µZM±XLAèææFÍfS§§§* j·Ûêt:š™™Ñ‚ҙŒòù¼ÔéÈGVjpxÈ ˜ŸŸ=#NS.—i·Ûlll066ÆÎÎA0;;K³Ùdyy™©©)~piØß©!¤=¶¶¢°Ûåââ‚p&Æ‚ Àƒ1†ËËKºÝ.çççØ[[ í}ÙrfîØÿ1g†œ°Üáì«*€¾ Cˆ¢;r´ßÏ£;¨¾O¥rG÷ªÍ{í÷ÚÏî±Óþ ¸ûd8vvŠ—IEND®B`‚routino-3.0/web/www/routino/icons/limit-118.png 644 233 144 1314 12573351602 14574 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”?KkAÅÏ]IŒWðFA„€¯’T"Ö¶V!  ký~Œ¤·³Ò€‚•µE@P*år™Ž©V«Œ³±±Áìì,Õ³³Næ{{ ]Ž.hyY’ŒA t:-@’&''%IÞ{ ieeE333z"I2,/K££ FÆ d². Êf³z—$­¯¯+›ÍêõõUõz]SSSÚÝÝÕóósï’ ™”ŒÁÈû@­–úÍ{ÿÅwÎ)•JéððPKKK:99Q†ªV«|IÞFÆ•*IòŠI†‡‡•H$zd###j6›*•J:??W:Öâ⢠««’äNO¥FãêK5cAòòòÂÇÇG¯šý~E<==Ѷ¬íÄõUó‹ÎbÀæœëé̵Û?êì¿ðßûE à?Ûê[üjoþêÔøÕyö‹“öÞwfÈ›ó´«IEND®B`‚routino-3.0/web/www/routino/icons/limit-16.6.png 644 233 144 1431 12573351604 14657 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÎIDAT8Ë­”ÍK[[Å×½!1÷r &ø#¡u`È+ R¢¶N‚P-” Eôðxð†íÜá‹•:ÖQi­ … ~¡¤Å¡` Q’{ÏþuÄ÷¦8pö:g­söaí-$! ß÷‘|$‘ÍÞEZÅó¾ÑÝ …‚£»<ïÒj{_H~›'ÔÊf=$……,ÒKÂð7KKðîqr¿~ÁÉI+^Z‚0üô²}Þkó%2Ÿ®.18xiR *$˜9®VœP©8J%ö¼CW—Èd|Ñß/ææB¤ï¬¬4#Ž!ŽÁìjv00 ÁÊ Hß™› éïo§)½b~ ™4¸çqãÜͺ8&n4pÐäñc^uþìaXcoÌÚBf†™]ËÐnâ­ Ìvw! kH÷RKÿèÅ‹"ÏŸ;_ò?~ú¤$IT(tpp r¹¬ 400 çœ|ß×áá¡þ-—¤ÓÞÀ訣R ¼”vX_poÖ×I§Ólll011Áìì,SSSP­V)‹-üÁŽk5ÇÛ·8iÇW.w_Ê$ßK¥T(E‘677µ¿¿¯žžMOO+ŸÏK’¶¶¶®ðGÔ¾ŠEy¹Ü}_©Êdd’ž<ÑÈȈÎÏÏef—BkkkÚÞÞ–$5›Í+üõk}ùüYÊçe¾Ì<5›ê @f¦(ŠE‘Õ××§ããcIR—xoo¯~üü)pÎóU«}Õ‡’d’”ËåT¯×599©¡¡!…a¨ññq•J%iffFÃÃà ÃPŽêÙÓ§¦÷׿ i•åe€ç8;;ãââ€$I8==Å9‡™Q­V1³K>®ŽŽI’µVžçittT‡™Œþ)]=x 54Ü ¹¡²Öù¡§G·ggõøÉ‹Euww+‘HhppPKKKŠD"S¡PP{{»ÖÖÖt||¬¶ÖVÉuåÔÔàå²£†mlnê§{÷”L&‰D´µµ¥ÍÍÍ)‹)—ËI’6664<<¬yž§·ïÞI¡l8²RŠ—/ù ÌÏÒØØÈôô4ô÷÷ÓÔÔÄüü<ù|ž‘‘ö÷÷¢µµ•Çñ7^¼ÀJ)!­²¸øçç ü 19¯bc ÖZŠÅ"¥R‰|>~°¸Òê5ž™*ϬµApɵ‹d×ÎÆ`þóo05P¶¾Ap W @`+Õ—™šº27:›7º5ntŸÝà¦ýüa0SóEIEND®B`‚routino-3.0/web/www/routino/icons/limit-21.9.png 644 233 144 1454 12573351605 14664 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“áIDAT8Ë­”ÍK›YÆŸ÷•æãm-Š!qS©2]tåÒn*Û•wiwCñÏhA‚‹€ËYØB)RBW®¤–ÁÖÄ’vÜĨ8R°˜¨É{ïýÍ"Óq¶¸pÏ=<çžç! Iø¾ä#‰Xì¤<žW¢¯îܱôõç•òm»üvœP'Q,æ!y<~CzAÔÈfáí[ÇÑ|ÿGG-=›… ¨!½hû{íx‰HÄ'Éd é+33P©XÀàœågié†JÅ23ÒW’ÉѨˆD|14$2™i…€àCCpîßÓy4XXiL&`h¨]¦ô’ÙY,4ÃFÛlvÁc°ö¿m³IØh`¡Éì,H/;v— øáÊe8¬Å9‡sc ιk•¶lX‹çÊe‚Hw…”wÙ,€Ùùü™ÅÅEJ¥R7x}}ýýý¢6Âr¹•ËÆe³ åe¤O¼{ÇŸß¾ÙÞ N“L&)‹ zzzXYYé&ßÝÝedd„‰‰ ~½w¿±¼yƒ•>ùJ$î+VåËÿ·çϵ¶¶¦D"¡­­-A 9çÔ‘ÍÍM jccC‘x\…W¯|=|(wûö}ÑßoíÉ >066Æüü~ÔÅ¢3ͦVWW5<<¬B¡ IŠF£ŠÇã’¤L&£ T¯×•Ëå4ÿä‰&M=úint6otkÜè>»ÁMûD “?p„añIEND®B`‚routino-3.0/web/www/routino/icons/marker-40-red.png 644 233 144 2045 12573351600 15421 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“ÚIDATHÇ••1hI†ÿ™‘lABI®Ð'øÒHR¤‹…ˆÓˆ8•wQa¸6EÊS#8q±Q“6„À]ç€S„p§ ’Á²‹3r!ŒOÎîÎüWì¬,ÉwøîÁòvg5ß¾÷Ï{OÀ™É‰‰ étúžÖú#°ÎsøYký1Nß·O& á¼ÀøNk]¢h™$§¦¦Äüü<´Ö°ÖBJ‰0 ±µµ…££# !„Rª†ásq_¸áy^s¹\X¯×M¯×£µ–Ãf­e¯×c½^7¹\.@·ïF’q±ïyÞ.‹Å Õj‘$1 ÃðÜeŒ!I¶Z-‹ÅÀwø1VJ(¥Ö°T* ,‚8Ê("‡£5†6œžà¥R)@¥Ôº”H¥RKèû¾i·Û$É0 €3fäa$Ûí6}ß7˜J¥– ”ÚÀZ­fþøö-éä I~ùB6äÖÖ¸V«í6Øl6k»Ýîà E1`cƒÈõõøùÍÒóÈ+Wâõµ5&qw»]f³YëJ¦\.“$£(:~úD^½oÞØˆ×îÜ!âûF#~·»K·ƒår™Œ µÖZ xp| <|,-““@Å5òþ=ðøq|_.Ç~{{Ð=Ž#%ÛétÐï÷¡”àÙ3 P^½ú} “9ë»Ë—c¯Tìƒ`ÐA‡‡‡`!¥ ˜_XøÏŸI­É[·Èû÷ãoÞ$_¿Žå¨Vã\÷÷I€Q³I’üýÝ;°Bˆžçý€Ó¾¶ö÷Ƀš'OÈÈÅE2•"¯_OûÑ#òöíúò%íä$ypÀ“0d!Ÿ\ü‚L&­õ†+þ$£¤GêÃòÒ%òÚ5RJš/H’?>}jð­rZë]¬T*†$ƒÓS²ß'77ɯ_Ïêto¬×º:ÝÜÜ´ø—"Ÿ!îJ) j:p6MHki\&½=NOO'½_æ€B@)õÜé´\ËšoßÎõ¾q]´¼¼ºÙÚœ™™çyæ”’ù|Zëæˆ¾I3$ýV«Æ;ƒé44ö0¶àk­Û#úºÈ’©´³³ÃL&cPJùÃxÚãv¡¾''', ¡? !@ãÑ×÷ý ‰$Y©T’´wdVWW‡ÿ–þÝÆõ]XXI²ÙlÆCJ !{ÇõUJµpeeÅÎÍÍ%iW\Úê¿Gô°(„ €ÈEøÛìì,”Ròÿú:¿æy¥”ßesÎþ–‡M ã ÈIEND®B`‚routino-3.0/web/www/routino/icons/limit-18.8.png 644 233 144 1423 12573351604 14664 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÈIDAT8Ë­”ÁK[[Æ¿{n‰ñ¦M‚¡úV%¸è"n\”îÜ(BµP°²Ð?ÀàÁ[¶{w®^BŸP(¸p•U+JC@»((ݘ…ˆ1`±Õ&÷œó{‹$V_ßÒ3ß93sføf„$$aŒA2H"™üi øÌÈd2Ž‘‚ÏHký{!™¾ŸÐ P2 ,.&‘^EßY^†wï<ÇÇÐnÃñqÏ^^†(úŽôºÿ>èûK$†¡!11ñé¹9h6`ñÞqSz¶¥ÙtÌÍtÈÄÄC††D"aD>/æç#¤/¬®tOCƒ÷¿ÎtX]é óóù|¿Lé ]Ûéàz8çˆãçnÐu»Äº<{Ò›AÏEß8<Ä‚÷ý@Þ{¼÷7*ô·ñ^ï о!= ÿ”þR¹<Í«WÎHæÃDzÖ*“ÉhooO•JEétZù|^Þ{c´¿¿¯¿+¥S© _,:šÍá Ñ…Ô ZpÿT«„aÈææ&õzÑÑQ–––( ìîî°µµE.—ëáðéëWÇû÷X©a”N?Ö“'ò’ ÂP¹\N’ä½×ðð°fff4>>®ËËKI’µVQõðBAW­–ÑÓ§ÒýûÂ%ò’Ÿ?W±XÔÅÅ…Úí¶ÆÆÆ´¾¾®ÓÓÓë$¿áÙ¬dŒ‚0ÄÈû@Ý®âœS2™ÔÆÆ†J¥’jµšR©”vvv$I•JESSSªÕjŠ¢HŸêuéÞ=ykƒëžÅàfgg©V«œ199I6›¥\.sttÄôô4ÛÛÛ”J%²Ù,/_¼à8Þ¾ÅK !­±²`qŽóós®®®èt:œœœ`­Å{O«Õº…Ç?öüVV@Zûųƒƒ³­½&ì€[ÿ«;‡ûÏ~›Ç Þ$ë-ÝZúäî²°pcît6ïtkÜé>»ÃMû/í*_œB²úBIEND®B`‚routino-3.0/web/www/routino/icons/limit-18.png 644 233 144 1232 12573351601 14511 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“OIDAT8Ë­”1K+Q…Ïn Y·0ñ¡Dø*±±Nk%)²uòò3’>e@ÁÊÚ"°¨  D¬REMvïý^±›˜±Ë…{î3sgïÌIHÂu]$IxÞ_¤6ŽsO¡þ pœ{¤vz.$7Õ MyžƒäRßÿ Vƒ‹ Ë`Ã!  ¯ÕÀ÷?𩽓ê%²Y—\N”J;HOC¿o€k óHxL¿o8>é‰Ri‡\Nd³®(E¥â#=ÒhŒKAµ?ßt,0¦Ñé‘JŧXLÓ”ZT«ââ€8Ž1&¹œ1†(Šþc3¡Z©5ýg»øþˆ^/‰8çÈZ›fggë)' béõÀ÷GH»BjS¯Äi 3a·Ûåùù€ÛÛ[šÍ&?6‰}L½R[H7t:fê àììŒL&Ãåå%a²¶¶ÆÉÉ ÛÛÛ„a˜¤>'ºN¤Wùü¾ÊeIr•ÉH’¬µrGëëë3¾²²¢££#mmméóóSJj3Ñ•ËR>¿ïÊuQ6«yXköööôþþ®áp¨ÍÍMžžêõõuÄqœDÍJ®‹+kM&ZcŒ<ÏÓùù¹uuu%ß÷†á,¨$i2‘¬u\Fwêv%Éjz˜buuUßßßjµZº¾¾ÖÆÆ†$)“Ü̪ەF£»…¯9ÅÛÛ___ŒÇc^^^ˆæm¼æÂ:›‡1fV.³õ/uökÌêü×Xjo.uj,už-qÒþ‘.dj  kÕIEND®B`‚routino-3.0/web/www/routino/icons/limit-18.0.png 644 233 144 1435 12573351604 14657 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÒIDAT8Ë­”OK›[ÆŸ÷ $1±©– ¡·p­.´‹E‘rwY…\ª]¹ŽÀ‘ì\¸s)½BWfë";ÿP+ áö*HS”Øê›¼g~w‘Äá.803ç’$âñßÖ𼯌ŒÀ‹Ž‘ð¼¯Hk½}!ù=œP?P<î!y,.Æ‘Ê$·”Jðé“q~Í&œŸwíR ‰[¤rï¼×ÃKD£>±˜˜œ|‰tL¡§§1s J×9=u 39ù’XLD£¾Åbé++`t:Ðé€Ù«ïVV@úF±˜`|¼—¦Taa ® À9G§ÓÁ¹Çtí6 À Íû÷ UúöšDâ†ãcB0ë23Ìl C{ìw³z‰¤×BZcyƒ V«qrrÀÁÁår™££#Â0 ^¯³ººÊßÝs¡•J ­ é3î¯ "‘[[[ìïï3::ÊÒÒìííÐh4˜››cvv–©W¯øŽÍMœôÙW*õFïÞÉ$ß‹D”N§%If¦¡¡!åóye2µZ-IRµZU,Óáᡞ=®­} ²dò¯HE£2I‹>hffF­VKÍfScccZ__×åååÃ%ajxxX’ô,•Ò¯Ÿ?¥XLò}|™yj·Õçœâñ¸677•Ífµ½½­d2©ÝÝ]Êd2º¸¸ÐÙÙ™þùþ]¿OMI­–<ð|ÝÜ|Q­&I&I©TJ÷÷÷ªT*ÚÙÙQ:V.—S>ŸW6›Õüü¼r¹œ¦§§õg±¨?Þ¾5U«òoo¿ÒùÛ,, tÀ“öæ“N'gO8iÿ]smµfAìIEND®B`‚routino-3.0/web/www/routino/icons/limit-37.8.png 644 233 144 1510 12573351606 14664 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ýIDAT8Ë­”½K\iÆŸ{tö:Ñ,Â,ÙB4UÀd³ÄXˆ62xMq!±Ð?À ¬…ERØY+fM Jª [‹„)&ÁYtƒÅ~ b2ºêÜ{ß÷·ÅŒ“lHé§8ïùxÏ9<çIHÂu]$IÄb¿"-à8H$ µÕH€ã|@Z¨Ù…äÖâ„®Åb’ãG1¤çxÞSS°ºjÙÛƒãcØÛ«êSSàygHÏkþN-^¢¡Á¥±Q¤ÓwvRÉÖ¾EU(• ## íNß¡±Q44¸¢½]d³R‘™€ ` CC°ö«\½*ÌÌ€T$›õho¯µ)½À÷1„• &°Ö†a]¬µõMV*ð}^\ͬ Ïûb··«?SëÈò#Xk«¶ªŸµÛÛày_ºn<“fyúô7çÉó÷Çîâò²š››U,µµµ¥x<®d2)ÇqT(´üò¥š›šœö»w ¥ÒON>CFʳ¶Æ?ÇǦµ¥ß÷éììdnnŽÁÁAúûûq‡\.@.—#•J111AÇíÛ¼ûôÉðö-‘”wuëÖ==x èóg÷ÏÙY«©©I™LFëëëò}_“““Ö<ÏÓÐÐ~îèÐÅÑ‘«‡¥xüžH& GGœ–ËŒŽŽ’N§) œÑÝÝM±X¬Ïlii‰žžø%fkgNO1--Æ‚ÀQ<®¿Þ¼Ñï÷ïkuuU±XL»»»Z[[S*•RWW—...T.—µ²²¢ÞÞ^mllÈó<½{ÿ^ºyS6ŠY)Ïë×”Á  H$Èf³ø¾Ïüü<ûûûôõõ±¹¹I&“¡­­??æ_0¼z…•òBZ`z //9<<$¬“““ÎÏÏ«Ü2†£Ú8*• „——ÓÓ -üg¦Æ3cLgßó­n3óϾnÀØ@`â臉êza«ÕŒ}³׺›×z5®õž]ã¥ýrä`¢P¥IEND®B`‚routino-3.0/web/www/routino/icons/limit-2.6.png 644 233 144 1351 12573351603 14572 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“žIDAT8Ë­”¿K\]†Ÿ½Â*E +–+ùÓˆ;Ñm´QSY؈–þlk›íb-XÙ©£³¬?H‘…l‘½÷žç+võ‹_HçÀ3sfÞsæÌ;ƒ€€Q ‘€ÿ[ærçöôè›7™==šË [­s„¨‡<ut䄜>tãŸ./ë§OÁÛ[}xÐÛÛ¦¾¼¬qüSøØòϵâÁ|>²½‹Å·Â7§§µZÍÔÔ2—¦žZ­fNO+|³X|k{;æóöõáÌL,|umMõ—LM á¿õdÓ þrmMá«33±}}­4aÝùyÕ†ijÖh˜$‰YöòaY–5톦iÓ~^aýéÏÞÇ5/.š‰$‰á9«`á½jh‚/.4ŽkÂ;„-WVTÓÐh¨zvvæÆÆ†çç窦Í@+•Šëëëžœœ4›þ©++ [Ÿ-—Í4S=::²««Ëññq‹Åâsàýý½###NMM9::êååe3uÍ,—>Gtw¿§TBˆªÕ*«««ìííÑÙÙÉññ1»»»T* …ccc rQ*Aw÷ûˆ(’|ž6 dsssLNN288Èðð0‹‹‹¨Ï@ÛÛÛòyˆ"#BÈÑh€¨­ÓÓS&&&XXX`ss“4My||$Žc:;;YZZ¢··—««+žHO£!ä"jµ/ìïZ—¦);;;ô÷÷S.—™¥T*100@Ç ±°°!Ðý}¨Õ¾¼¨¦ij½^÷Ç÷ï^__{ssc½^÷ááÁ‚išzww÷\Ý_TóÏ|rüŸ„žIœ…ðWž½ì€$1$É„ýÔ4ýK¼jo¾êÔxÕyöŠ“ö_ ÞoAiBhÍIEND®B`‚routino-3.0/web/www/routino/icons/limit-36.8.png 644 233 144 1524 12573351606 14670 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ IDAT8Ë­”ÏK[YÇ¿ï)1yµÓ¨1!8p6Sº*øœJhW"eì&þþøl÷îD‡‰´Ð–Š.ܸt“’…-tˆFYMP[é0&ïÝû™…Ñjgë…Ë=çÞsî=çò9GHB®ë"¹H"þ iÇù@4 Ý݆hçÒbë\HnËOèò¢pØAr˜š #=Çó¾’ËÁ›7–jŽ¡Z½Ðs9ð¼¯HÏ[öNË_"réè©T?Ò.ããP© ÀZÃõq¡T*†ñqvI¥úéè¡+ 11á!}b~ X||¬ý6/÷À æçAúÄÄ„G"ÑJSzÁä$š~£i60Æàû>ÆÜ Ð4›øšLN‚ôâòÏîãy_l©tñbËуµöZ†öjµÖÒ²³¶TÏû‚t¿íwigÏ~qfgÍß?ºæó …BêëëS¹\Öòò²"‘ˆ’ɤ¬µr]W;;;ú+Ÿ×wî8‰ •JÄ)Ûd¤"oß²w|lºïÝcjjŠT*ÅÆÆ™L†L&Ãèè(ûûûlnn‹Å˜žžæÇd’B¹lx÷Ž@*¶ëî݇J§|þìþ±° ÞDB'''Z__W¹\Öðð°‹Å$IÆyž§±±1í–Jú·^wõø±ÔÙùÐuÛÛ‘µú¹¿_¿ÍÎ*ŸÏëôôTžç©««KétZ+++* ’¤Z­¦x<®¥¥%Õj5Åzz$וÓÖ†4›Ž:;µúúµF=ÒÚÚš"‘ˆöööÔÛÛ«\.§x<®ƒƒIÒêꪆ††´µµ%ÏóTxÿ^jo— GV*òêg`~}ò„h4J6›åì쌙™Âá0¹\ŽjµÊÈÈÛÛÛ ÒÓÓÃÌÓ§ü†—/±RQH‹ÌÍþù9GGGø`µZí “z½@£Ñàððÿü `n¤Åœ™gÆZŒ1W°^gîJ6ógß* ›hZ߇ ø¬7ä À^Dß$›½V·Z›·Ú5nµŸÝb§ýí:aåò±ä\IEND®B`‚routino-3.0/web/www/routino/icons/limit-32.7.png 644 233 144 1501 12573351606 14656 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“öIDAT8Ë­”ÍK›YÆŸDˆö­õ‹2A‚F:¸(‘bnœUt=Òtm[AâÊ``ÜH bqç¢DK ¶«Ù]¸k±õ3Ô…¨Cµš×¼ï½¿.’´ÚÙzàr9÷žóœžs„$$ ‘‚H¢¦æw¤iÏ44@S“¡¡ÏHÓå!Ë~B ššR€Çkžã8ß„7o,ÏÃÁAIÇù†ô¼l(ûK„BAª«E4z)C_ìîÀÇZÃU)é>»»†¾>2D£÷¨®¡PP„Ã"‘p6¸,žžÖþ<•7°À%££ m’H8„Ãå2¥ÏÖׯüóò%óóóôôô022Âøø8±XŒ™™\×`jjŠgÏJïíA]†\€³ÓS’É$­­­¬¯¯³ººJ,£¿¿ÿZŽŽèèè`sc£–ÍBc£‘wû¶¥P`öõk:< ««‹ááaZZZãìì ×uÉd2LLLÇðö÷¡¾Þ«ÎÏ?éÝ;ý™JÙßîÞU]]:;;‰D”Ëå´°° ¶¶6¥Ói È÷}---)‘H¨,V>H''Ÿ„4ÍЀï¹.Ùlß÷) ²··Çþþ>çççäóy¬µsqq¾_Jnh¤ék<3ežcþÏ«_Ä–€®ñìç¤REëy•ˆ?ÈZþqû~e¬Š¤RW&àFgóF·Æî³Ü´ß]Ô°•×ЀzIEND®B`‚routino-3.0/web/www/routino/icons/limit-173.png 644 233 144 1412 12573351603 14575 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“¿IDAT8Ë­”1KcYÇÿïe}ɼš &Sf«-¦±Ù"XØ£õÀúü [δ*6b,Òø 2 ™ maôé “Üwïo‹$Ž»kéSœsÏ9p¿ÿ’„ïûH>’H¥~GÚÂóZLL@6k™˜Ïk!m ß…äû„FƒR)Éce%…ôŽ0üÁê*ÔëŽN¾‡Ng¯®Bþ@z7¬÷†ýAà“LŠ©©WH§,,Àù¹bœ³<´As~nYX锩©W$“"|‘ˉÅÅ©Íú:@pÆ€s¿|”ôX_©ÍâbH.7ü¦ôžåe€>qLÜëáœÃ9‡1æÞsXk1?bûýAýò2HïG;+†''n4è1ûW>Žqà890ŒŠ‰?¥¿ôöízóÆbŒï†ÆÆÆtss£ÝÝ]µÛm)›ÍêââB;;;J†¡ò/^x<n½¯_Ÿ©ÙL©É‡kÙßß'‘Hppp@«Õbvv–¹¹9R©››› ªÕ*/óyþþøÀÚZ ¤æo­rY’|òÓÙ wî„tv‚e}FZlý ÉnÕ µb1 ÉâÑ£Ò 猙xýÚpxõ:6ã™pœ3¤­|«U/‰ØD£¢¯oé+°¿Æ„\µf°¿21ÒWúúˆFE$b ×™ŒƒTbnà0ø>ø>óŸ·ßÀÌÍT"“qpÝÖ˜ÒK< Ï¿¸ ô<|ß¿tcL«9ƒßhà{>xæþ}^¶w6ˆãœšr†0¼,ú_kæÊepœS¤Á[¿I¿óäÉ/ÖãÇá?Å¢ýÇ«WŠÇãr]W+++ÊçóÚÞÞV2™T4Õîî®r¹œJ_¾hg{ÛŠß»&¾ÿÉ ·Hyó†Â·oa‡ãN§I&“lll000Àää$Ùl–J¥Àææ&©TŠt:%ñW¡òö-¾ôQA|ÐÖ§O&ð<­®®Êu]íííimmMÑØØ˜Òé´mmm)“ɨeFïÞI§§E!-òìçÔ**-o4xžGµZ% CŒ1cŒáää„óóshî/àéS/yF¹ÜäÍžµ¹Ö»¦¬&Ð5ž]S€Ïø>¦)™k€W‰l‚ -+‡¯(àFµy£WãFïÙ ^ÚŽ ™Í¿*—`IEND®B`‚routino-3.0/web/www/routino/icons/limit-7.png 644 233 144 1147 12573351601 14434 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”ÍJ#A…O•’d!‰² 8«€Oà,݇q-($˜¥n%/²óÜ™‚`C\¸ˆ$ ƒH@“®úfÑÝþëÌ"Цúž{êVÝ! IXk‘,’Èå~"u0æ‚BÖ×…sÔIìB²‰ŸP*”Ë$Ãîné x Ù„“Ïdww0™Äûf‚àé0á›Ä_"“±d³¢RÙ@º¢VƒÑÈÞ;^#ÞGŒFŽZ ¤+*• ²Y‘ÉXQ.‹z=@ i·žÏb‹xÿ²Òà'ÚmBêõ€r9¹¦tD£0'Š Š’@<‹Åâyyïã_8s ŽÒ7«3†ÃøÄD蟈yžá‚`†T]ù-ýÑþþ/íí9E‘Õêªð^Æ]__«Ûí* C]^^jmmMÅbQ€ŒµR•JN77?4¬i@¯àÒ¨¢ä{vvÆÖÖÛÛÛc8==}cOøŽ^¤Èç=ãqš­w7‰Ž988À¹W Nùã1äó^‹ŽéôƒXúØ···lnn†á×bÓ)‹ÎÊ{£ù\ïᜓ$u»]•J%U«U9çd­ýÀÕ|.yo¬f³sõû’äåý³Ý#Iê÷ûÚÙÙѧˆù^ý¾4› ©C«%ù÷÷÷<>>~^1?¢Õ©ó_uæß%æ«:û¶¾ú´–Ú›KKgKœ´}ަ››îIkIEND®B`‚routino-3.0/web/www/routino/icons/limit-26.4.png 644 233 144 1452 12573351605 14662 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ßIDAT8Ë­”ÏK[YÇ¿ïÁÄðÒQ©?@Œ›àªY¸3P4¸(¡íNwòZWCü¤³p!ŠÐvY°«‚UfÑY ˜É´$…!„ j-R¨CÌ{÷~f‘ÇvºôÂ{νçp~|¿GHB®ë"¹H"O!­á8ïéî†dÒÐÝ Žói-z’ù µÅã’ãGq¤gxÞW|^½²ÁçÏptÔÒ}<ï+Ò³è¿ùKÄb.bhh©B>µšB¬5\?-=¤V3äó U¦£CÄb®èëÓÓÒ!‹‹—€% ÀÚÿ¤m \²¸Ò!ÓÓ}}Q™R0Ð ./1Í&Æ‚ À˜o$ 1A@M>©ÐîYÏûbËe,X"Gc ÖÚk~{·aØÊ°\Ïû‚”Òšõ}€ð¯b‘ÕÕUJ¥•J…B¡@±X¼ ÒβR©ðÛÛ·¡õ}ÖJû¼~Í?šŸ=‰‰ R©{{{är9¦¦¦§Z­^elŒadd„É{÷LøâHû®nݺ«ÉIÕ>|pyúT»»»Ðòò²êõº’ɤ²Ù¬zzz$I®ëjiiIFC=wîH’K6+uuÝ·osrÀïïÞ‘N§YXX`kk‹ÑÑQÖ××dgg€ úûû™%5<Ìßõ:œŸcººŒkƒÀqc1ýyx¨\.§™™­¬¬(‘H(‘HhnnN½½½ªV«2ÆÈZ«L&£R©¤Z­¦ƒƒÉq„1ŽšÒ>oÞðëË—æ'×ellŒÎÎN¶··™ŸŸ'‹áû>ÇÇÇd2N¢*677Éß¿ßêÙóç í i'Oø“zz$Fc §§§W09;;#¬µ\\\pþé@ÈãÇ­i¶qF¹ÜÂM4úë0øs‘ñ‡8»b€…¦ l‹2?k›„!ö ¸QnÞèÖ¸Ñ}vƒ›ö_5%£5s/êIEND®B`‚routino-3.0/web/www/routino/icons/limit-32.5.png 644 233 144 1541 12573351606 14660 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”ÍK›YÅO^!±!Õ(eÞHÔhŠPì²L‡â®›Æ¯T”"Vºü†qÙn!;ƒ­E»™UâJ(±ØJ;®üÈ5Ð: š¼ï½¿Y[Ùzáryî}ι_çÐÝÆu+×”žÐׇ²W*aÊeŒ1xž‡1è•Jxå2”éëéÉÙ›Ý þl76Nw¬ÏXk±Ö^ ¬äY66 þŒt£êgiŠ‘‘™?ß¿w~}úT¡`Pñx\kkkÊd2ŠD"r]W’äyžôÇë×ZËf?Ü»gB¹ÜÞ¼©’‘²¼xÁ_…‚©¯­%•JÑÖÖÆôô4 tvv’H$Èf³är9b±===<àï“óg)ëèêÕ[º{Wþ§OÎ/SSêïïWSS“677511¡¥¥%E"e³YIÒÊÊŠŽŽŽè~2©X(äpû¶œÚÚ[¢®ÎppÀ?GGôööÒÜÜÌúú:«««´··3<êõ:W*óæÍ›/’Éä§Æ˜Qfþ•ˆ„•JAA0Á—ÙlÖNLLèÞ$"ŠMã 1ÇæJ©x቉ Ífm_A0.˜y: CŒŒŒ “ÉÀZ "¡ÓéàÅ‹»x>þOž<ÁË—/!¥„µ™L###ÃÌ<­¢(ú$“Éð±cÇ!`ŒAE˜áÂ… €{÷îáÁƒØ»w/:FGG166ð‹?‚»øår9\¼xÅbïÞ½H)qþüy>|FõzžçÁq03z» „”Ònll Ã8»Žã`»*vM8zô(¬µ¸qã–——‘H$vñîv»BXẮi6›vii)>1’ïûh4H§Ó˜žžÆ¥K—ðøñc4 VVV°²²Â®ëà;¥”¨T*Q»Ý†"Ž®W=Ó«W¯¢^¯Ç )¥âhïܹcè]•gÏž}¸µµU|ûöíñV« Š^=..." Cœ8q}}}°ÖâîÝ»xøð!jµ1<<Œ[·nÙååeéºîR†ŸËãÇÃZû³ëºëëëûŒ1v``€ “É ¿¿ûöí3£X,b``¹\ÃÃÃÂÒÒÏÍ͉T*õÎZ{šˆþ§„ À­µO&“÷«Õ*8pžçag‡""03<ˆ\."ÂÆÆæææ"Çq4€o‰èJˆh"úQñO"’·oß;„»×3î}›ŸŸÚí¶N$×<Ïû7 ê5ʈÄÐÐÐÇq®µÛm}óæÍèý³ß;ÿRJ}ú?¶®ëjð­”’‹ÅbP©TÂhµÛ …Ö¯_žžtwwcbb·nÝ ñ03”R¸r劦eýÈ7nü.‰ü477'/\¸ÔW{íÚ5LNN¢¯¯RJlݺmmmÈçó(—Ë!®K—.™—/_ŠH$2¦”:*vîÜ cÌm×u{gff>‚À477ÓÒÒîÝ»‡]»v!“É„ÕoÞ¼oß¾Ehhh@©T²W¯^åx<¾dŒé"¢?(›ÍJ} ॔îïïét:ŒW£Öu"ÂÂÂNŸ>­ªÕªã8ÎQcÌ k­d‡ˆn0óWD$._¾¬æççÁÌ«6¬¾9044T*'‰œÝ¾}û ¨Í""Þ½{÷Éh4z¶R©8…B!¨—ú¥B`ddÄܽ{W®[·nÚ÷ý¯GGGâ½½½v˜Êå²ÕZßv]·gff&©µ6[¶l!­uˆ¡6fçγŽã€Ïˆh„ˆ$ œËåÂTÌ,™yÚs$cxxØŽ£ö]%"(¥000ø¾ÏBˆ“Dt€³‚¹\\{YÑÿò€b±h¦§§e4ô<ï›®®.Ôb,Öÿ‹ïùóç¸ÿ>†‡‡ÇaŒùBJ¹844$¬ú¬Zä÷ñF£=³³³Éùùy[*•tµZŽã0`­ 9Ö…Õ­P÷Ë–km3ßðõªÿGJ 6IEND®B`‚routino-3.0/web/www/routino/icons/marker-52-red.png 644 233 144 2156 12573351600 15427 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“#IDATHÇ•UÏkI}U]53Œ(29ìaZ]E1‚‹§ êD1ä(««ìQðdæØü‚àš›!àzÝA/FzYo¹þÈ ÊL ‚¸aGœLèêªç¡jÆqÂâîÅG7Õ¯¾÷¾¯^_Cær9 ÙlvTký¸Ùÿ¬µ~’ÍfG |'»@"ä€ðƒÖz:MÓÓ$944$FFF µ†sRJc0??÷ïßS!”R5cÌ€úpz'l¢¨€ÅbÑÌÎÎÚV«EçûÃ9ÇV«ÅÙÙY[, †ï¶ww+Ž£(ZÀr¹œÔëu’¤µ–ƘuËZK’¬×ë,—ËI^{X)¡”º €•J%!I›¦L:º$!ñ«ÖÒ% “µµx¥RIP)uSJ d2™ãDZm4$IÓÒ¤&IH’Fƒq[Ìd2Ç#!Ä-ç\|éÒ%;vL¤ÔÛ·ÀýûÀË—ÀÓ§À«W@©h ¼x|(„»À ×l6IçèHrf†È\ÎçÉ4%ïÜñÏ…‚Ïcc½F6›M Fv||œ$™®­y^ccäÈÙn“>ÎùU*‘gÏú= øÞ=¦AŽññq°€ÔZa²C÷€ùy`óf`Ï`n¨T€óçýž\.LxÔ»=G€=xð WWWý’äè(yò$97Gž8A A¾~íËétÈ+WÈL†Ÿ‡ÖúV6$™NMùê¢Èç©)ß°|Þ¿ËfI)iC£~½xÑÀ§ò]C)j­ç1?V'&ÜïW¯J³°ýìpà°?ðù3ðèÐnRç 6mŸKKüerRDBtðÉ¿@€∔’ÒÚíÛ^ß ×àM²a6߬¬pËÎþî+U ªÞ4! ”šú~5•þ+k ™$´IB:ÇÓ§N™à­µmÛ¶!Š¢žCyx¥äÞ½{¡µ®sñúv«íáúC¦§§m|Ós§>ÛÃÀ‹XkÝÀjµjI2 ÆÑÇÅÅEæóy €RÊŸiÆz}kµo*l·Û6Áê® !@ã;ñ¾q']K$ÉjµÚ¥½ áÂ…þßÒ¿Ç ¾‡2$Y«Õ¼aHI!Ä‘°=ú.à ¾J©ž9sÆíÛ·¯K»h«ÿ ø¾ ! þU*• ”’ÿ°§oÈ“QQJùÀÎ6ëâ ˜rqV!lIEND®B`‚routino-3.0/web/www/routino/icons/limit-4.9.png 644 233 144 1303 12573351603 14574 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“xIDAT8Ë­”±J+A†ÿp¶1(’F½i´2µE±Pã+ÄòÚXÙ ¦³òlWä‚AD"ÄB#bvg¾[l61^K¦˜3çüçÌ?ÿ9B’0Æ $‘ÍþA:ÀónÈå`lÌ’ËçÝ ôî…dzqB)P6ë!ylme‘v ‚*89q4›ðú Ífr®T >v{þ^/^Â÷ ™Œ˜ššAª³¾†bœ³|]É9¦Ñ°¬¯ƒTgjj†LFø¾ù¼ØØþ²³ð 8¢¢œìÔødg¤¿lläó½gJ{”Ë]¢¬ÅZKÇC…Yk‰¢EÜu)—AÚK9›%ZÜÝ%­Å9‡sîÛ 6¸ÌqwAÐBšÒÛÛ1Q„µ Mõz³³³~Ea²¿¿Ïýý}Úí&qÛÛ éŠZ Àº„¬µ –——û•ÝÞÞR(XXX`~~ž———´JK­Ò•ÑèhQ¥’$ÏIRµZU§ÓÑøø¸Òuqq¡‰‰ ŸŸË÷}žžJ’¬dT*I££E#cïËJ’1:::Òññ±uyy©‡‡IÒÊÊŠÚí¶VWW†¡FFFú‰äû’19ç©ÛíÛ1*‹º¾¾ÖÓÓ“Â0T«ÕÒûû»æææ´´´¤\.§ééiI’'IÝ®äœ7ÄqLÔãíððÍÍMŠÅ"¬­­199IµZMˆL|ûœýø›ÖZÚí6oooXkûdw:žŸŸ²IÀ†~sXgß„úUg©D¬s©hÿÓÙpÄqê8é»èÇøÕÞüÕ©ñ«óì'í?§š7ãIEND®B`‚routino-3.0/web/www/routino/icons/limit-199.png 644 233 144 1367 12573351603 14616 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“¬IDAT8Ë­”?K\[Å÷>u@œÉ Sªy ¦_B AP,ÁÆN?€_!iDÄO@Š`ñ µÔ*DS ¦…GÀqÔ¹÷ü^áŒQÓºáÀYçÏ:ì³×ÚDZ ØÚú·°n}3—ÓgÏRs9¢oÂz}!®ßCD­­‘93Ó*¼1›½paA?~ –Ëúë—–Ë·xaA³Ù áMý|T¿f2±--ØÕõ\øá䤧jb©÷ã'§NN*ü°«ë¹--˜ÉÄX,âÔTVøîҒ구մVÓ~ÆšõÚ¥%…ïNMe-ëiÂ[§§UoL“ëkÓTMÓÔZ­fš¦¿ñÕ•éÍÍíùéi…·?ë7›­xx¨’ëkC(„p7oÝeœ$ j6[úÖ]\TMÂíknmmytt¤êþþ¾+++âŸ?­ç›¸¸¨°ŽðÅ÷ïUSÓÔ>ØÔÔ䯯†årÙîînK¥’¥RÉÍÍMûúúrppÐÿNOUÓðî—˜ŽŽ¼~ %Š" …mmmìííÑÙÙÉîî.ù|žååez{{ÙÙÙ!“Éðï§Oqúêtt¼ˆ‰cÉd!033ÃÀÀgggŒsyyÉØØÛÛÛLLLpqqÁèè(477@s3ı1!DÜÜp?BÄqLµZ¥¿¿Ÿááa …Åb‘ÞÞ^FFFÈårôôô% „ÅT*_ÙÚ„@{{;ù|žJ¥Âêê*sssÌÎÎrrrÂÚÚóóóüóò%@øëóg¨T¾>¨f]žŸŸ[­VU½ººòôôôN "~TÍ:3Iî¹'Ü‘44âm8á‘Îþp@¸GØ z€k5ë>rÀ“zóI»Æ“ö³'ì´ÿÆ¥ej1¹¸IEND®B`‚routino-3.0/web/www/routino/icons/marker-87-grey.png 644 233 144 2702 12573351601 15631 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“wIDATHÇm•ßk“YÇ¿ç9ç$oÞ\Øô½k!ÓX{QS ‚é"HEY§Èâ€s³w/¼Y‡a¼²C.Ö‹õ/˜;¡V:ÅA3u¬Šƒ°­5VAíRìniÒ˜Mìû㜳m²­Î¼çæû>Ïçûð–Íf±!B ›Íê\.÷¹1æ¾ïïs]×`ø¿L8fRÊ1ƾËf³·s¹A؆)7Æ(cÌv)åEÏó¾ò}ßÄb1ÇADG­5Q«ÕŒ”’…B¡1ß÷ÿÆ[aŒqJ cŒÐ'„(6›Í>Çq‚#GŽP2™dápËu]”J%S,UµZýʶí?(¥ŽcþÍ#~ðàA Wñ«çy}ýýýþéÓ§e"‘`œsc>9Bôôô°ÁÁA*—Ëþêêª#¥ü£ÖúgcÌ[ŠF£RþØjµ>K$~&“‘]]]PJÁ³›h c ‚ À¶mÛÉdd"‘ð[­ÖgRÊ£Ñ(Èó¼/<ÏûÚq=::*ÛÜ8ç³v…í;AÆÖó•ŽãhÏó¾ö<ï aŒùÁ÷}:t±X J)pÎQ©Tðúõkضþþ~ž={† :fÆìܹŽã`ddù|RÊDéX,f†††8ç(•J‡eYX[[î]»pòäI\»v ïß¿‡ðæÍœ9sŽã ™LÒÔÔ”i6›iẮ¤H$‚  „Àýû÷±}ûvœ={år.\@:ÆùóçÑjµ`Û6&&&Ðh4L&¡µF4E<g333šÖsX¡ÝV:F¹\Æ¥K—påÊ  ¯¯`Û6^¼x……œ8q¢ƒ¡("ιn4ð}¿cZ­VaŒëºð<Õj®ëvÒ¿uëöîÝ‹îînh­;“Ñl6ADš,ËR¯^½Òsss "|øðwïÞűcÇÉdpîÜ9ض›7oæççQ©T0<<Ü©’1†……¼|ùÒX–¥Àß…T,ƒz½ŽH$‚h4Š••Àêê*Þ½{Çq333èííE,ƒ1œsø¾ÉÉIÅÖõ?uêÔ½µµµÝoß¾M­¬¬ûöí£îînܾ}wîÜÁÇÑÓÓƒãǃsŽ|>ýû÷#wZ¿zõª~þü9·,kÎ÷ý?ñT*­õo–e.//wA 8ÀR©vìØt:Ç# A)Çq000€H$"ÂÜÜœ) dÛö­õQÆØ ÿÑZÿÙ¶í_îÝ»gz{{144„®®®Nx „@*•ê¤Ýh4pãÆ  IÆØ÷Œ±y‚$clŠˆÎ1Æøää¤_«ÕÀƒRjˆÒZwL …BP«Õd(º¼gÏž A{KøŒ1¾‡/×j5™ÏçƒM³·ED„èG‰h4ºäyÞ·³³³Ÿñ‘‘‘öh°ÅÅE£”úͲ¬/———¥”Þ½{7SJu ¡R©`||ÜH)€¿0Æ0Æ”Ëå:‘ ¢%­uƶmLOO›R©Î9´Ö`ŒÁ÷}Œžççü"cì2¹¹\ÔþØÐ'|¯_¿î×ëõ†b±¨—––D8žw]÷û£Gb³!6Àâ#ãOøNLLðäÉLOOömh­Ï !Z…B0›™óÍ—ßㇿ,—ËN½^7?VÍf“K)¿0fŒépÜTÔ–§°éÉcÌ!"šr]W !¸¢˜L&?úô))¥ôdž[Úÿ m¾wŒ1ßY–Å9çKJ©¿ÎÎÎ~2¿›õ?r¥¸óVGIEND®B`‚routino-3.0/web/www/routino/icons/limit-2.4.png 644 233 144 1320 12573351603 14564 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“…IDAT8Ë­”1K+A…Ï®¨aQLL¡]@m,,´°Elƒ…V"vZZþ !h—Î_`ac%¨1 ‹ŸDp!ÙÝ™ï»ñ™B^ãÀwæÎ{Î=÷ IHÂu]$Id2ÓH§N6 ãã†l§ŽTIï…ä¦ï„z2Éam-ƒ´ç}²µgg–V Úmhµ{k <ïi?õwÒ÷CC.ÃâP˜BjR.ƒï ÆZÃ÷•Ø1¾o(—AjR(L1<,††\11!VV<¤vwº€%Š ŠÀÚ»wè²» Ò++)Lé€ÕU€8Æ„!QaLbÆânâ8ñ_]é ÇÙ,ž÷A£‘‰"ì*‹µöÊovÌÒh€ç} Í ©Âö6@lÀ»»;©×ë_AzY6›M...’óÄ?f{¤Š®©V1`®®®¥T*Q(¸½½ý‚gŒaff†R©”$×íªU®]Í«X’+I¾ïkggGçççÑÍÍ$Éqííí©Óé(ŸÏK’pIrU,Jccó"—3¼½%¿'ÎúªI^^xzzâùù™ h·ÛDQ„µ– xO䑸¯š}:KõóÿõƒÎú; аi=~.€ã:àW{óW§Æ¯Î³_œ´ÇŸ¸†$øÛÐIEND®B`‚routino-3.0/web/www/routino/icons/limit-21.7.png 644 233 144 1446 12573351605 14663 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÛIDAT8Ë­”AH[Y†ÿ÷‰>2Åäm„@geÕE·ÎÒ¸•Ð6+¶°Ý»ì,fÙîDq(S¤Íj‚%#”@IÚÁ”´âB¢¥¨ÅjóÞ½÷›EbƳèÂî¹÷žÿžsøÿ#$! ß÷‘|$Ñ×÷#Ò"ž÷ޏ~Ý20ž÷i±{/$¿'tÔ×ç!y }HO‚SfgáùsÇþ>|úûûv‚àéI÷½×—H&}R)‘ÍÞ@úÀÔìîZÀàœå²u|Ãî®ej ¤d³7H¥D2é‹0ù|€Tgn  8ââœûw]œÚÌÍT'ŸÃn™ÒSîÜÁB·ÛØ(ê%cŒÁZ{)9Güõ+qCänßééEφ ‚×hàÀa-Î9œscpÎñ¿ÖùÀÑh@œ '~•~ãþýŸ¼{÷ìßÕªÿû³gJ§Ó ÃP¾ï«\.ËZ«L&#IÚÙÙQ±XTýý{m½}ë¥oݲ™ÏŸû]¥’‘Þðâ•íA@.—#›ÍR«Õ(•J$ VWW{ mll0>>ÎÄĞ𕊥T"–ÞȤӎ/_øãåK~yü€‘‘–——Y__' CŠÅ"QaŒ`aaŸ<èTÜlµkNd2Ö¶ZüU.366ÆÌÌ ív€\.ÇÒÒR ààà€ÑÑQê[[°V 2ë»8öüdRÕz]“““šžžÖüü¼I Ïó$IÛÛÛ’¤•• jøæMYI¾1’sžoOO«zýZ›µš3Q¤µµ5 ©T*I’R©”úûû%I…BA’´¹¹©|>¯®9½z%œT…´È£Gœi5›4›Mööö8;;àøø˜óósqÎqttÔ¹ïôÏðð!H‹=žÑhtxc-ßc®ô ϾQ€ƒÈÅ1®#™ãÿ»wÆ\È*âîÝK ¸Rm^éÔ¸Òyv…“öÚ÷—ÌE]‡ÃIEND®B`‚routino-3.0/web/www/routino/icons/waypoint-add.png 644 233 144 261 12002775154 15526 0‰PNG  IHDR Vu\çsRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEÜ ׋'À1IDAT(Ïc` 02000üÿÿU‘ñ?TœMœ‰Th¯æÆÿĪg‰¡D2Î ‡Z„ßIEND®B`‚routino-3.0/web/www/routino/icons/marker-93-grey.png 644 233 144 2726 12573351601 15634 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“‹IDATHÇu•Mh“[ÇÿÏùÈ›¾•jˆFéW¦%E°Q†0ÜNQiÅf“áv1x¡w3Efwsg R2ÝlÆÍ€«Ù ­èTÛ¢;Ú" Âk*]Hµ«Iª‰­qú~œsfa“[õÎ^Þ^þç9¿çãP:ƶ˜étZg2™AcÌ_=ÏK8Žc~’±,‹¤”ÿ!¢±t:}'“É0ß÷@m›rcŒ2Æì—R^p]÷;ÏóL(¢h4 ÆXÃQkÕÕUT*#¥¤@ 0áyÞDT$"@ Ì£t !²µZ­+û,“eYøRŽã ŸÏ›l6«Þ¾}ûmÛ¿VJ cžãÇ7Ú…÷\×íŠÅbÞÈȈìîî&Î9Œ1_]B´¶¶Ò¡C‡X©TòÖ××ÃRÊßh­ÿiŒyÏ“É$üýãÇ'b±˜7::*ƒÁ ´ÖÈc "Œ1¥lÛF"‘à/^¼ðÞ¼yƒûššš®1×u‡\×ý>ëááaYçÆ9c Œ±†‘1¦ñMÑXxxxX†Ãaíºî÷®ëñ“'O^r§=™LšX,FJ)pÎQ.—±¼¼ ×u±gÏ}*€çÏŸcee¾ï# Ak Û¶!¥4ù|ž¤”=Â÷ýoB¡9räÎ9199‰]»vassýýýH¥R¸}û6îÝ»‡Ý»w£Z­b``ƒƒƒ€x<ÎîÞ½kjµÚ7ÌqF©©©©Q27nÜÀÑ£Gqþüyœ;w=B¡PÀýû÷144„±±1¤R)ܹsŽãlÛF4%ÇqŒø”‡ŸêP)ÕØ´´´Àu]”ËeŒŽŽÂ¶m,--!ŸÏ#ò,c@Dõzf‚s®766˜çyàœCJ‰þþ~\¿~+++(‹ØÚÚc ÝÝÝX[[Õ+W°¹¹‰¾¾¾Ïê·V«1¦ùàààx©T¢½{÷R[[Œ1èììDKK ªÕ*z{{Q,qðàAÔj5D"œ>}½½½¸víZ[[‰DðìÙ3d³YcY–bþ"„`ÙlÖ÷T*Á²,8p/^D>ŸoD&„@ LOO+ú¤ð³gÏ.lmmõ¼ÿþ—¥RÉO$ŒsŽ™™ÌÍÍamm ©T ]]]ð}·nÝÂÂÂr¹‰Ž;†©©)½¼¼ÌƒÁà¢çy¿¥ññqh“R.|øðá§NÒÉd’‹E¼zõ mmmØ¿#/_¾Äúú:öíÛ‡ŽŽ,..šK—.QssóµÖ¿2Æ<Œ1à•Öúw¶mß]XX0ííí8|ø0"‘H£5ë÷ÎÎNttt€ˆ°±±™™ß², `œˆž €@ÑcìDħ§§½J¥"‚ÖºÑMuãz{ÎÎÎú•JEÉx<þ7 €_/PˆX__ß˲&+•ŠœššòëF;eŒç<Ð>ÍÍÍ×uÿœËå3‚Ÿ8q¢þ3­®®¥Ô¿ƒÁà·¯_¿+¥tOO)¥ƒ…1†r¹ŒË—/)%ø== "@Ëd2¡ÎŒ±‚ÖzÔ¶mÌÏÏ›|>Îyƒçy˜˜˜ð]×eœó D4 @ncD&“«?lë+¾7oÞôªÕjãHÉf³ºP(˲ž:Ž3~æÌì4Ä6X|aüß«W¯úðäÉÌÏÏömh­B|œåÌNî|çËÏñµ,ëÛR©®V«æñãǪV«q)åŸLcw…ÏS `Ç‘-øÆ˜“Œ±9Çq”‚ !²ñx|pii‰)¥ô—†Ÿmÿg0ÔùþË3 9ç¼ ”úC.—ƒR ÿOÿrïÅÇ16ÐÝIEND®B`‚routino-3.0/web/www/routino/icons/marker-18-red.png 644 233 144 2035 12573351600 15425 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“ÒIDATHÇ••¿kTYÇ¿÷¾{gâ€)Fp…y$Û˜ìÒ˜I∠¤±È&Í6V)VœbÛÍ_°iÒ ˜BÙu* !«M ‹ QDç6&†â˜wß½ß-Þ}ó+,Ù=0œû~œÏ;ç{ï9tL HÈçó3Zë×ÀyÏîk­õë|>?>Nf á}ÀøAk½’$ÉIž;wNLLL@k 礔0Æ`ccB¥TÝsÀß]œö.A`©T2µZÍ6›M:çØmÎ96›MÖj5[*• ú¸KYÅYÆaÛX.—ãF£A’´ÖÒsâg­%I6 –ËåØƒ·„)VJ(¥`¥R‰3Xl ]’IÒ“)­¥‹cÆß¿·á•J%@¥Ô)%Ëån`†6Š"’¤1†tŽôAÝÀn3Æ$£(b†s¹Ü (¥^àêêªí¦õ‘/_öß¾%ïÝ#Ÿ!Æ7¿Ü¹c)å …´ÖøÃoz6lv–œžîdöèQš­$@;>NðçÛ·­ïªM…L­’Öz«Õª%ɘ$_¼ ××{ÏéÎyÿ>ͳg$É?>tøM1’!®I) ©×ë=ÓßQY{îîìðbf½_íæ€B@)u/†aÜð-kãø8»·°°`ül­ !‚ö„ò{¢äÈÈ´Öõ}ûJ–ýÊÊŠõÀÝötê{è»j­£}}fYÙ[[[, 6íùSÙývª¾GGG5~xü.„S¬Gß0 ãl$’dµZÍÊÞPXZZêþ[úwë×wjjʤCªž ))„¸æ_Nöë«”ŠpqqÑeeW}Ùê¿{ô0-„ €Äg¸><< ¥”ü¿À¶¾Þÿ¥”»~ì«æ„ýó}p4sYIEND®B`‚routino-3.0/web/www/routino/icons/limit-26.1.png 644 233 144 1462 12573351605 14660 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“çIDAT8Ë­”ÏK[YÇ?ïÚüð¥Cœ(JVB…BuU7ƒbƒ‚T›¸hAlwCñèJZ×nµ…,t‘½.Êt ’ÒKZ!aÄ‚¡Á1yïÞï,òÌØvë…÷œ{¾‡s.ßïA€cF€’É!Á†<ïƒzz¤Lƪ§Gò¼‚è‰pˆ‹Bɤ'ðT($Ïäû ­¬H¯_;I_¾HGGmeEòý†àY”ïExPœçîÜtú¶éŠÅä îÝcff†ááaÆÇÇY\\ÄC.—ckk‹½½½N±B¡ÀÈÈggg‹12.<S:8 ŸÏ³´´Äúú:©TŠT*Åòò2ýýýT*êõ:aàœƒè pÎ3¶Ñ(ñî½ïÂV‹b±H:&‹1::J"‘`llŒÙÙYr¹Fß÷‰]»à¼7o ^/!ØÐãÇ:“Âj5Õ";??—µVÇÇÇšœœœt8wzzª¿~•¤PI°Ñá™Êå6o¢dç\ø=ç¢à<ûFNj¹ kKæ²vîax‘ó®T›Wº5®tŸ]á¦ý©1J²×X IEND®B`‚routino-3.0/web/www/routino/icons/limit-15.0.png 644 233 144 1461 12573351604 14653 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“æIDAT8Ë­”OK›YÆŸ÷FòÆWkM#„àBì´ŽUD "¥ !R­ Å.t+øfÙîýâ8Õ®¦YKÛ• ©vQP7Á€ÔØÑ7oîýÍ"‰íüÛyàÀ}νÏý—ç! Ic ’H$~@ZÁó>ÒÝ wîXº»Áó>"­4÷…dš<¡–P"á!yÌÌ$^,,Àë׎r¾|r¹ .^4Ï{M¾D±¼ Ž(‚(ç¾e«Y^é…B@:Ý|¦ô’éi€Z= ± Q]§sîú‚¶V# CÔxò¤—­?{@œqp@œk ý_8çÂÖâÀ¹ý}‚3¤±Ÿ¤ŸõüùÏžY#™wïß P2™Ôææ¦¶¶¶´··§ù¾/Ïótxx¨_ÖוN¥¼äýû–R©ÝÛÙ‰ i‡µ5ûëÚmmmlllE===LMM177G¹\ R©066Æèè(ƒ÷îñX^½ÂJ;F]]õ葜d¼XL©TJíííÚÞÞVµZ \.§L&#I*‹ò}_»»»ºuû¶~[_7Êçå::Åb(—“4óô©†‡‡u~~®T*¥ÙÙYåóy---©X,J’Â0Tgg§$éVW—þüúUò}ÉŒœóT«©€Œ1*—Ëêïï×üü¼2™ŒŽ¨··W•JEGGGúýógý88(U«òÀ3:;û ·o%ÉIRgG‡ŒŒhuuUÉdRÙlV¹\NÙlV“““×ÐЦ =ž˜pzóFæââƒVX\¨c-§§§\^^puuE¥RÁZ‹sŽ““¬µXkë0lðAZùæ³ýý†³ëõ¿û ®ÅZuk-X‹ý‡ÏþÕ.Šø/Á ^§iîÓÓßuÀöæNg78iÿÖÝJß#×§ IEND®B`‚routino-3.0/web/www/routino/icons/limit-134.png 644 233 144 1326 12573351602 14575 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“‹IDAT8Ë­”½KcQÅÏ{ˆ†×$D!«­dkA´4Zdmìµ´ð/°Þôbca!X¬Ø[ˆ]âÇ)®Ä(¬˜—ûñÛ⽨Y·ôÂp™{çî™93B’Ã)D™Ì8Ò&Að“\††¹ÁO¤Íô^HaúN¨ ”ÉHß¾e¾EXY?<4›Ðh$þÊ DѤïi|¾—èï…BéŠR êuX¼w¼_‰o©×¥HW ED(FFÄâb„tÉú:@ xŒcÀû7ëžbÖ×Aºdq1bd$¥)U(—:X‹cœ÷8ç0ÆàÜÛ'1Ø8NâËe*Ýœ}!Šž¨Õ¼c| ÔÝßXúW#÷ÔjEOH_„´Éê*€õÇÇÇÜÜÜp~~N¥R¡Z­¾‚^Õj‘òµ¬®‚´)¤*»»çØÛÛ£¯¯ýý}Èf³,--1::ÊÉÉ Åb‘ÙÙY,8vwAªö)›ýªéiI =( Ë{/k­666466¦ëëëW¿Ýn+ŸÏ+MS¨éi)›ý*÷÷˜”æÜÜ[[[´Z-˜˜˜`mmb±Èòò2ãããüº½M¨þþ ƒƒ.”÷:½_ÆåóyjjjJÊd2:;;Óää¤NOOU¯×uqq!Iòq,yôäÌ´ÛÌÏϳ³³ÀÌÌ ¹\Žr¹L³Ù`{{›R©”°y—³žj¦‚äññ‘———$Øîîî0Æà½Ç9Çóó3­V«+àžjöè k{tÕ«s®WwIÜ}èÿðâÅZ|ò«:àS{óS§Æ§Î³Oœ´bÓ·¯¨‘s·IEND®B`‚routino-3.0/web/www/routino/icons/limit-39.7.png 644 233 144 1500 12573351606 14664 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“õIDAT8Ë­”ÁK›YÅÏ—‚q‚iL ¸(tD°ˆ¤.„8M$®D´Mqá¦í€þ.Ý Ì²ÝX*.£"mv5+7®iQ±C]HˆÆ´™"1ß÷ÞoI¬víƒï¾wϹï^νB’ðù|H>$ÑÚú+Ò"Žó‘övˆD ííà8‘ïBò5pBM¢ÖVÉáÙ³V¤Wß™ž†÷ï-Å"”ËP,Öíéi¾#½jø; ¼DK‹¿_tu=@úÌØÀÃZÃÍU·=ŽŽ cc }¦«ë~¿hiñ‰Ž1>@Úcvà °¸.¸.Xûc7ïÀWÌ΂´Çøx€ŽŽFšÒkž>Å@ͽºÂÔjcp]cÌÏYÜj·VÃ…š}ò¤×Íšõ|³õˆ àÏÖÚ[7ü,|Cê½÷§ô/^üæ<nö?}òýÉÈï÷+‹)ŸÏk}}]ÑhT‘HD’txx¨ÕÕUííïk7ŸwÚ=2áJ廽}OFÚ!—ãßrÙDB!Òé4ÝÝÝ,--ÇI$ÄãqNNNØÜÜdhhˆááa‰¶· >àJ;2Á ¥\fÿËÞ¾yC6›edd„©©)R©ƒƒƒ,//P­VXXXà—/ë pÿ¾á°áëWþ«T˜˜˜ §§‡ ‰©T ¿ßÏÊÊÊu¹NOOéëëcow·NV*A8l|^­æ¨­MkïÞé÷Ç•Ëå µµµ¥%“I…ÃauvvªX,J’2™Œ¢Ñ¨z>”‘äó<ÉZGVÚ!›¥f$™$ 199I¡P`tt”X,ÆÜÜô÷÷c­%N3??€†µ5v„´ÈÌ €çV«”J%ܺ0©V«c­ÅÃÙÙÖZÎÏϹ¼¼Ï«óÍÌ€´xKg¦¡3Ó7µuSs×Ú«ÝÒÙH§jÖu›¯ûóÙz^³­j¤Ó7:àN{óN§ÆÎ³;œ´ÿ­ã£l>…¬rIEND®B`‚routino-3.0/web/www/routino/icons/limit-80.png 644 233 144 1265 12573351602 14517 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“jIDAT8Ë­”±J+Q†ÿ=`C‚S½Í 6)¬,ì,C ­´°J ¾Eì,RÙZ¬ÁÒ!‚èmÔA4 ŠˆIöœï»£ÞÒ…93ÿœ™óÏIHƒdD&ó©…çuÈçav֒σçuZñ¹L'”e2’ÇÆF©‰ï¿Q«Áᡣ׃§'èõ"½VßCjÆþ^/‘JÒiQ*- ý¥Rn×!ÎY&%ÒCº]K¥Ò_J¥Òi‘JQ,ŠjÕGº¤ÑŽÑF#pîóKlà€H—T«>Åb\¦´Ëú:À0„0ÄZËh4ÂÚèr‰îœk! #ÿõuv“ž-âû/\_G­Å9Åbc[T©ûÇõ5øþ Ò¢ZÔë!Ifàüüœf³I§Óàêꊽ½=nnnÆ qÉ!õ:H-!qp`ÃÁ€““ …›››ÌÏÏs||ÌÊÊ KKKAÀóósY@:3ÊåÊZ]•$#c$IÖZù¾¯µµ5A v»­ééi]\\(›ÍêèèH’ä Š[]•r¹²‘1(•Ò¤ôû}ÍÍÍi_ÊçóÊd2’¤l6«÷÷w%•$¥R’19çi8Œ£Lj·ÛZ^^Öé驦¦¦ôðð ××WÝÞÞêîîNAH’<Ï‹À†CÉ9ïKÏìp8nv¹\¦P(°µµÅÇÇÛÛÛÌḬ̀³³óIâo=ûñš‰ îïïÅ6k-ý~Ì» °/¯ùƒg“¼Jþ'Éë !ížýwÆ\ú2š±þéóm~u6uküê>ûÅMû;ˆhÓ•yƒIEND®B`‚routino-3.0/web/www/routino/icons/limit-5.5.png 644 233 144 1327 12573351603 14577 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ŒIDAT8Ë­”±K[mÆ÷Z¢„¦¹¸˜Lj?§.DÈ(Šƒ…,‚ÔEŠàŸÑîÒÀ­PÜÄE ]:v ¨Q©(˜Ü{ß_‡$ýü†oð…w8Ï9ç9ïyyÎA@À8Ž…XÀ±±„]£è‡I¢ãã¹I¢QôCØíûâ~2 ‹„È÷ïÇ„‹÷nlè—/Áós½¹Ñóóž½±¡Åâ½ð±õóÁB!vt''_ ?]ZÒV+W3CÈýûôìÌV+wiIá§““¯ÅB!Ɖ \^. 'îì¨vÔ`šjšjÿÞ¦Aí¸³£pâòrщ‰~›ðɕծijÚ阦©išBøó°–v:†iו…Oƒ?{c±øËÓÓ^Å,ó^\ðôT‹Å_›ÀVW_Q«åäùHû_¿Òn·) 4 J¥iš²¿¿?Œ¿|Y«åÑêê+>þï¨×"FF¸½½ekk‹ƒƒ¹¿¿àææfxx€(ˆ¨×ÞÅ”Ëo©× sww‡Êââ"Õj€oß¾ á•Jóœbêu(—ß¾ Ž¥PèÕÆÇÇi4ÌÍͱ½½M©Tbaar¹<„'IÂüü<90R(@BD·ÛS0pvvÆÔÔÍf“jµÊÅÅ!Z­ÓÓÓ4›M*• WWW DO· !DßÝÛ3×\õääÄZ­f’$®¯¯Ûn·õèèÈ™™“$qmmÍ,Ë4Ë š»·§ða×ÍMÕ¬/H½¼¼4ÏsC^__«Úétþà}áõò67vŸè,ü%ÔYφñÿÐÙÓ È2C– )ÿ a¿Å§ð¬³ù¬[ãY÷Ù3nÚß*K…‚?mð Ú´D$¹÷œÏ[$i•n˜Å̙ΠŸ! I¸®‹ä"‰hô¤Yçñ8$†xçÒlí]Hn-O¨^(už<‰"½ÄóJLN›7–£#(áè¨jON‚ç•^ÖâZ¾DS“K$"ÒéÛH{ŒŒ@¡`€k —¥j‡ †‘öH§o‰ˆ¦&W$“btÔCúÌô4@°XûKë>°@™éi>3:ê‘LÖÚ”^ñø1@%,—1ÕŒ1A€1W?h*‚r=éU}fwð¼3ööÁÚZ!k-ÖÚKÚ«~c°`íî.xÞÒ†?¥¿ôìÙ}ÆÇ+¹›Ù¬Â0T"‘ÐÁÁæççÕÜÜ¬ŽŽYk庮vvvô÷ë×ò#'y÷®¡Phv¶¶„´Å€ùgaÆÆFèíí%“ÉÐßßO>Ÿ —Ë‹Å"Jñï—/†·o ¥-W--÷ôà¬ä: J$ò}_kkkÚßßW[[›ÔÚÚ*I* šššÒúúºüXLÛ››®>7nÜ7o¾}#¨Ífpp¥¥%VVVèêêbnnŽT*ÅÆÆÆÏùe³Yº»»úðý;67®¬uT©¨.€¬µò}_¾ïkbbBíííÊçó ‚@¹\NÃÃÃÓÌÌŒ¬$•Ër¬u\mëÃIUKK‹ÎÏÏÕ××§ÎÎNyž§žže2e2­®®J’–——•ºuKïÞ¿·úøQáÛBšåùs€c8==åââ€0 999Áƒµ–b±H©Tâøø˜ÃÃCþûú• yñ+Íþâlw·Jvþä©k½ØUrM5þg¿m€ ê/ÃzÜ ¨êop­»y­WãZïÙ5^Úÿ"m}• ÄÍIEND®B`‚routino-3.0/web/www/routino/icons/limit-132.png 644 233 144 1444 12573351602 14574 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÙIDAT8Ë­”ÁK[[Æ¿{+IÞE&h¨>\7v]lq‘­Š¤.ܺЭà?PyËv#.‚kKÑE„ð–B ¸,*)Z°¸²*ÚP5´˜&÷žóëâ&Ôö½¥‡ÃÌ™ïãÌðÍIHÂu]$IÄb#pœôô@"aèéÇù€Th½ Émá„ÚD±˜ƒäðüy éž÷ùy(-ççðõ+œŸ‡þü²´Ð,¾¾Öþ:íX ÁÒH™žöH¥ZeJ¯ÉåšA£±c ¾ïcŒùåÿøi6Ãü\¤×íž=ÂójØ ÑÀ¶ˆÚwÛÚ„ab€ËÑx^ éу—Ò?zñâ‰òyƒï»n$¢A D"¡ÃÃC­¯¯+*N«R©hccC]]J¥Rɤq>þK»»„´ËÛ·cØÜܤ££ƒ­­-®®®ˆÇãär9FFFXYYa``€‰‰ 2™ ûï߇~ó¤]Wñøc={&I®9Ž£¾¾>Yk–——5;;«¡¡!kqqQårYÚ¯TBÜÓ§R<þXôöªUü°©d³YÖÖÖ¸¾¾fff†ááaØÛÛctt”|> ‚°_¾@o¯qe­£fSwÍ÷}%“Imook||\ÅbQ©TJ…BASSSš››Óêꪬµ’$Ç÷%kWµÚ¾Þ½“$«ÖcWW—noo•ÍfÕß߯îîn)N«Z­ªT*ippPÿ–J’dM¹,ÕjûB*°°´ÉÍÍ õz=,Ý÷¹¼¼$êõ:œžžrvvFýÛ··°Rá?:£Õ‡¶ÎîŠõ7Ý…ñßtö¿`ïþ)^k-Ö÷±aLÀ½Îæ½n{Ýg÷¸iÙÌpplvÝR+ ÅÁÙ¡ |’V tpHEt¨-˜›{ß÷ù†$*_¿ÑÞç}Ïsà¼<ÏA€¹®+p(•¬Êq¾+›•r9£lVrœï‚ÕÎ;·ÃCt¥RŽÀQ©”¼—ïÿÖ‚ôé“Õù¹ôë—t~ÞÆ ’ïÿ¼ïÔ;>Èó\%“hdä•àD³³R½n$ŲÖèq´q¬zÝhvV‚Œ¼R2‰<ÏE…š›ó?´¼,I¡$«(’¢H²ö!»w’•jyY‚š›óU(tÆ„²‚@’ZŠcÅa(c­$É£(ŠdŒyÀͦL«Õ® ÊÝ?+Ê÷:>–$‡¡l§‘µöþÜÅ÷Dz’Õñ±äû A1ñ7¬ðîÝ_¼}kE®ëyT«Uâ8&—ËqxxÈÆÆ½½½ ŽŽŽ¨T*$Ói_¼pôü¹q~þLS«%Ôôñ£$£­­-% íîîêàà@ýýýšŸŸ×ØØ˜6775<<¬ ôrpPÿ|ùÒžüà jÏÈd^35àZ ÇqÈçóXkI§ÓÌÌÌpvvÆÍÍ +++ø¾Ïéé)a¸šš‚Læõ3\WxžÓ%—J%ÖÖÖ¸½½%‘H000Àúú:õzÉÉIÆÇÇ ‚€««+2™ ŽçëÊÅZ‡V‹ÇaŒ!•J±½½ÍÄÄ{{{ ±´´Äôô4;;;ôôôðµVkO†`­ãÒh|ãóg‹µôõõÑl6)—Ëìïï“Ïç¥R©àyÙl–b±HéÍ›¨V¡Ñø†`U‹‹’w©ëëkÝÝÝI’Â0ÔÅÅ…¢Î[Eº¼¼lã8nó%XýCg‚{ÚGâí¦$™(jëìää^gÿëû¨áb•dlõ<©7Ÿtk<é>{ÂMû/„ëGò8þ&IEND®B`‚routino-3.0/web/www/routino/icons/marker-83-red.png 644 233 144 2113 12573351601 15425 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“IDATHÇ••ÍkIÆŸª®ÊÄœ 9LKä ‰Á£‚²*~@À“›ˆ¬ð[FXÝÀãap™ »i/^„@Ö‹sñ°BôâLÄ9m˜sÈWwW?{¨êd2aY÷…¦ºŠ®_¿ïÓõ¼ „ìîî–Éd.i­ß €ÄlŸk­ßg2™KàöÉ$Üè0úµÖsqO’d__ŸƒÖI’@J‰(а²²‚ÍÍM !„R*ˆ¢hÀßmœý7œò<¯€ù|>ªT*¦Õj1I¶G’$lµZ¬T*&ŸÏGèöJ+N3ö=Ï[ÀB¡Öj5’¤1†Q¹Œ1$ÉZ­ÆB¡:ð:ßb¥„Rj‹Åb˜Â½=&aHFÙžm3 C†»»ûðb± RjAJ tuu]@ß÷M½^'IF{{ì¨ùàj‹( I’õz¾ïìêêº ¥Ô*–ËeÓþ ?~$«UòåKr{›Nry™|ú”|óÆ‚£ˆ$Y.—Ëv’\.—4›M›I ½½v¼pÁB<°ó'ìøð!ÓÜ›Í&s¹\âŽÌÄÄ„•kw×>qå yö¬½ÿðÁÈãÇÉGìúãÇv½ÕbìÀ`©µÜÉܺLO7n_¾çÏ—/óóÀÐðü9Àõë@O` àyp)$F;;;PJYðçÏÞj[[v¾½ ܼ Ä1pû6°º ôöB@ë¡ H ¥ ˜ùjÕ ÿí©597wð™Ïœ!¯]#_¿&ö|÷Ž¿xA’üsi‰!DÏó~À“¾ÕÜ‘2ù;ü†l6 ­õïXHÚ·+E a?ƹsd«EÞ¿oçR’ÇŽÑLO“$º{×8à_²é§Ék­×°4;kH2¬ÕÈgÏÈ¥%25C’++dµÊèí[’ä‹‹‰n !†S !ÄE)%ÄÁâ¢Õ7Ž;ÊÙ2µgãëWžôýÔû¥vh!”R³N߃¦†G¼oœë&''#×[ƒxž·ß¡,^)9<< ­uàš‹Õ7Í6õ»³åÜÜœqÀÆ~wjk{èXðµÖu,•JV_—YZöÚÚ³Ù¬@)åewÆQ}ƒàP†[[[‰\óøÕ|ÿˆCúú¾¦-‘$K¥RZö€ìÌÌLûoéߣSßqw~ƒ #¥¤âbÛÿí»b__¥T§¦¦’ÑÑÑ´ì’+[}/ð¾~B@ì2\„RJþ_྾nüÙó†ur9øüÙS.C¥årkŸËAÖ‘>Æþ&~/ÑÕÐÝ-ÒéWHçLMÁå¥"¼w<¶Ö>âòÒ15Ò9éô+º»EWW R)‘É„HE~kÁZðþ×jŸ~°°R‘L&$•ŠeJŸ˜žhzk±ß¿c­ÅZ‹÷¾S˜sk-®Ù„(h2= Ò§öŸ½! kœµ2¶œþ2ï}'°|»Â³3ÃÒ›gï¥z÷î­Ïf‘‚¯Z__W±XÔéé©zzz”L&eŒÑÉɉ677Õóâ…RƒƒÂZc^¾túöí¹ŽŸ é˜ "pûûûŒ1111†½½=éííerr’t:M¡PhIÇÆHÇ¢¯ÏS*µµÅ2WVV˜››ëÈÜÚÚbqq€ááaÖÖÖ°¥ôõy‘L:îîZ±\‹„ÛÛ[FFF(‹ŒŽŽ’Ífq±¯¸»ƒdÒýV™m6X^^f||€F£Áõõ5GGG„aÈÒÒ÷÷÷Ø66* T«”ÏK’7ÞK’òù¼2™Œ$©Z­jvvV»»»’¤íím iggG2FNòÊç¥Z­ ¤Uæç¢HªÕ*¶*• õz››®®®(•J46kóó ­þ—³Ç°þÓZ~¿qöWEø?ÀíÀƒëµÕð¤½ù¤SãIçÙNÚŸüYÇtc-¯$IEND®B`‚routino-3.0/web/www/routino/icons/marker-65-grey.png 644 233 144 2723 12573351601 15630 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“ˆIDATHÇu•_hSYÇ¿ç_îÍ ˆ1Ømc¡«¤ i«[ê¢HGœ °L‘àPa}Ø}˜—qYæ¥d!2/«ûº‚R•nÁ¶>l¶»´ "¬5¦1J‹º¤¦šÔ`ÜÜ{sÎol²Ug¿pàÞ{.ßó;ŸßïüK¥RØ—R"•J™t:ý%ýèûþ>×u ÃÿD–e1¥Ô¿c?¤R©¿¥ÓiÞl6ÀÛ0D¤‰ègJ©Ëžç}ãû>…ÃaÖÓÓÎyÛуb±ˆjµJJ)Æ}ßÿž1öŠ1&h €‘°SJ™©×ë;#‘Hóرc¼¿¿ŸY–…Oåº.r¹e2ýæÍ›oÇù¥Öú½`ŒqqøðaÐ-¥ü§çy;c±˜öìYµk×.&„}6¤”ˆF£,ór¹ì¿~ý:¢”ú•1æ/DôV$ øÓû÷ï‡c±˜þüyeÛ6Œ1íÈ8ç`Œ}­ÖÁ`û÷ï/_¾ôWWW#¶moƒåžç}åyÞ·‘HÄŒŒŒ¨7!8çàœƒˆŒ±ö7)e{¡‘‘‰DŒçyßzž÷•8räÈ5×u»‰Åb1¦µ†•Jù|õzápŒ1Ôj5 ¬­­áÕ«W¨T*غu+B¡¤”´¸¸È”R½²Ùl…ÃaÚ³g!Êå2®^½ ÏóP¯×Ñ×ׇÑÑQäóyܺu Û¶mƒëºƒ¸pá”Rà³³³T¯×‡¤ëºÇy0D+ÊééiD£QŒŽŽbyy·o߆ëº(‹ˆÇã8wî´ÖhUÁqôôô°Gù!êPF£ÕÕU„B!\¼xÁ`LJeYð<Ïž=Ã¥K—`Û6N:…x<ÞfÇs!„©Õjð}¿Yß÷áº.Nž<‰ŽŽLLL V«s޽{÷"™L¢«« ×®]CµZ…P¯×Á97ܶm½¼¼l²Ùl;ÃD„ááa âôéÓ€¥¥%$“I$“IìÞ½ÉdRJ¼xñ¢=¿´´D¶mkàRJžÉdš•J–e!¢P(r¹8çØ²e ®\¹‚²Ù,ˆ]]]€©©)Í>èÏâÌ™3óF£÷íÛ·¿(—ËÍ}ûöñíÛ·cvv™LÏŸ?ÇÁƒ144„F£»wïâÞ½{xúô):„ÁÁALNNšB¡ lÛÎú¾Ÿdccc°C)5ÿîÝ»Ÿ=zÔ$ ^©TP,ÑÑÑ;v€ˆÀC©TB©TBgg'¢Ñ(²Ù,]¿~9ŽócÌD”—œs à߯˜_;Žó÷ùùyêîîÆÀÀ@»è[†­ívvv¶Ãôôt3(ÆØc,@rMŠ16Ë9¿ÀSSS~µZc Ƙöql·úÂÌÌL³Z­ª@ p£¯¯ï8€f«QúŒ1~àÀË–eݨV«jrr²Ù2Ú,"‚÷ïß7>”¡PhÅó¼ß/,,´{„nýÌŠÅ"i­ضýu©TŠh­Moo/ÓZ· çkkk¸yó&)¥€ß0Æî3Æ$ 5ühû?¡Å÷DôƒmÛB±¢µþíÂÂ´Öøú/·ÎÃð:¨›IEND®B`‚routino-3.0/web/www/routino/icons/marker-27-red.png 644 233 144 2124 12573351600 15424 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“ IDATHÇ•UAkSY=÷¾w“4¸t1‹¼X$3 [Š;Ý4vJuºœ”J×v×,æ2])Ô‚¶D7 FÁ)¸(¸ÁAã¦$ºj‹Dhµï¾ûÎ,î}iÆùàñå¾—{îwÎ;ß÷€“™LF@:žTJ½@±Ëì]+¥^¦ÓéIpûd$\ö?(¥–¢(ª’äàà ƒR qCJ ­5¶¶¶ppp@!„ð}¿¡µ^°×ƒÓ=á¼çymÌçóº^¯›N§Ã8ŽÙq³Óé°^¯›|>¯Ðí;Ÿ0N*<ÏÛÀR©¶Z-’¤1†Zëo.c I²Õj±T*…x@`a¥„ïûw°\.‡ Xøõ+ã0$£è¤L­I­‡!Ã/_hܳr¹ ïûw¤”@*•º€A˜v»m÷Ÿ¢LcÈ>HR»ŠÛí6ƒ 0˜J¥®yBˆµ8ŽƒÅÅENMM‰Hkø©ÐlÀû÷@±ÀƒÀ«WÀ›7ÀÛ·¯_#Êd0X,"­ÿ|üX!~€8—ËÅûûûöEäÚ ¹œÍÓÓä§OäÙ³v-%™Í’ãû÷I’û{{Ìår±³L¥R!IFŽ‹ErvÖþ~ñÂ=|h×îpV«ä•+vŸÓ¶R©€ñH¥€BaLN³³Ö™Œs²góà ðä ðô)ðü¹½Ç€çÁáH0—.]âÑÑQׇ$ÉãcòÖ-2•"¯_?ya$yñ"¹°ÐuDb±R©DRÊ€YYY±ÿ!ÉímòÂòÜ9òömk«ÄZ‘¤ór†$ÉÍÍMˆ…!<Ïû …‚îšþòerx˜üðÁ}þL:&œž&K%ËÊUxxxÈ‘‘‘È5ÁÈf³PJ­`ùêUÍ9Cz™NÛ ÷îYÐòæM{¸óóÜÜœq€È&mšWJí`íÆ ÃgÏ./“««äÝ»äò2ùîÕtu•l·­L$×××cx$„N}RNH!)£ÆÆ†Õ··EO5˜¥½»»ËB¡ô~­”¾ï/`!Ÿ[ÛÛ'µ>iS­»=_­Vµ›­¡¡!xž×PÞ÷åðð0”R 7\t¯±OfŠ%¾´´dànw:õŒ=ôÝ”Rm¬Õj†$Cg›„v³Ùd6›5(¥ü¥ŸvX}…˜R@Ôh4NUèì£Ý¨û] ÿ§ô ‚ LF"IÖjµ„v@v~~¾÷³ôïÑ¯ïøø¸&ÉF£AFJI!ÄDÏ÷í»¢«¯ïûmœ™™‰GGGÚ5GÛÿ^ÀSúøYA‘«ð¯b±ß÷åÿìêëò¯žçQJ¹ àÇ>6ßÄ?½Ÿ–:¯YÕIEND®B`‚routino-3.0/web/www/routino/icons/limit-33.0.png 644 233 144 1514 12573351606 14654 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”ÁK›I‡ßWÉg?£qí!4Y"d[Ö^Ô‚ÔÃv)ô xKRÁËnŠ ç’þ‹Û»÷@][šzXÿÌ¥…,VݨÁ€†vÛj“ï›yöhµ{u`˜÷™ßÌ;Ãó¾B’p]ÉEÝÝ?!-ã8oèï‡C?8Τåκ܎Nèô înÉááÃn¤§øþgæç¡X´ÔjptµZÛŸŸßÿŒô´³ßéè%"σƒi¤wLMAµj€k ç[Û©V SS ½cp0ç‰HÄñ¸˜žö‘ÊäóMÀ`í·~:h’σTfzÚ'ï>Öââ¢|ßW¥RÑÉɉ$i}}]žçissSwÆÆô×êªûÛƒ²==·»Ü®.d­3”NëÇ\N¿çrÚßß×øø¸†‡‡•ÉdÔh4‹Å$Ia*J’zûútüå‹äy’ë↭–£hT+¯^é×»wU,•J¥”Ïç511¡µµ5õôôhkkK’”H$T¯×µ»»«Þ¿×ÏCCÒ§OrÀ‘•J¼xÁ¿`&îß'‹133ÃÞÞ“““ôõõ1;;K¥RallŒF£ÁÜÜÑh”'VV°RIHË,,„ÁׯÔëu‚6˜Apæ[k9<<ă1¦m7›! -_àÌt83Öž‰Ná=Ï™1ŒÁ|ÇÙ· ÈfZ6 ÿë; ±íè[d³ç2àRsóR«Æ¥Ö³K¬´ÿ6dô<ÅxIEND®B`‚routino-3.0/web/www/routino/icons/limit-25.9.png 644 233 144 1540 12573351605 14664 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”ÍK›Y‡ï+M4M@…u£dT¨-2»ܤ‚ ¿ÀvÊ´ ¶àb(þ³l7‚ 7³±£©CÅ…‹@±6`I» Á颇ä}sï3 Ga–8‹óÉ=—ç! I¸®‹ä"‰úúpœO46Bs³¡±çÒB5.$·Z'TkT_ï 9<~\ôŠP¨Èô4¼}k9:‚oßàèèžž†P¨ˆôªšïTë%—`P´·Ç‘¾0: ¹œ*Xk¸*v…\Î0: ÒÚÛãƒ"pE,&ÆÇCHÌΔ‹ïƒïƒµÿiÍ(3; Òãã!b±ê˜Òk&&0àùå2Æóð}ÿR­µ—4ž‡_.cÀcb¤×µ?»C(ôÝf2X°SÈòb­½ˆƒk3…¾#Ý©ûEú•gÏú§OMzoÏ]^YQ8V,ÓêêªR©”ö÷÷ÕÝÝ­`0(Çq”N§õûÊŠ¢MMNsw·!—kpvwëT‘vy÷Ž¿¾~5‘PˆD"AWW›››ÄãqÆÆÆH&“äóyÒé4ô÷÷óã½{ü]©VW1Ò®«pø¾>Tîóg÷ç—/µµµ¥h4ªÅÅEù¾/cŒFFFÔÖÖ&IÚÙÙQ4Õöö¶ úcyÙÕȈìíÛ÷ES“1''løÀÝ»w™™™!•J155ÅÒÒ---lllÍféííehhˆà­[üöæ T*ø‘ˆq­ï;n  ½ƒ *™Lj~~^ù|^šœœTkk« …‚J¥’ÎÎÎÔÓÓ£D"¡Æ¦&Åãqéü\8®)÷´³£??~´ÏÓÚÚšb±˜²Ù¬Ö×׉DÔ××§ááa (ëüü\sssúéÉõ?x`õþ½êŠÅ=!-ðâÿ@åäðê–J%<Ïãøøc ÖZNOO(•J ìž?iá’32™ ²¯pVc­Ö¬æ7UÎ X®pvm,xÖ÷±+s­á5+•ZŽÇ£GW6àFwóF¯ÆÞ³¼´ÿK-rQ/»]üIEND®B`‚routino-3.0/web/www/routino/icons/limit-5.1.png 644 233 144 1341 12573351603 14567 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“–IDAT8Ë­”1K\A…¿7‹o7¯Q7¢k¥$ AØ¥°°‹` mÿ@ eÒûdÁ"`k%bc#Á‚–Š. veÑuçÍ=)Þcç…¹3çž¹3sîE€9çN€ …÷‚ EÑoõõIÅbP_ŸE¿Ý}®‡¸'*"A¤J¥ ø®$iieEúùÓty)ýù#]^fþÊŠ”$-Á÷.>êÆƒâØ)ŸG##ï§*—¥³³ )•YÐcËüTggAå²§y§|űCCChn.k}]’î$™¼—¼—ÌÆýšd’î´¾.Á±ææ u¯ ?´° Iy/w'ï½¼÷2³'É¥iªà½”¦~aA‚÷oöAIÒÔÉIvbú¯¥iú@žáL''R’4r_á_¾|âóç@Λ±½½Íîî.GGGŒ‘Ïç13r¹ûûû„èûyEƒƒóó7æªZ•IA’êõºJ¥’æççµ´´¤Z­ö/³­­-Åq¬jµ*Iòí¶$U«:z{?25…888àúúIÌÎÎR*•!`fDQÄÀÀfÎ8¦¦ ·÷£Ã9ÇDÙ6Åb‘ÅÅEÊå2kkkìììËåðÞS©Tçææ†'ÇàœfN¦`àââ‚ÑÑQ–——¦V«Ñh4!b|<£)}`a ‹s¸NoÖ»sïÓKzïIÚm|·›Æ/,€ôááÍÞE-ÎÏÌu:Ø3 ßÌþÎÃÀ8?‡(j!½Ò««ÎÒÓ¨V«\\\ô«Õ*õz€³³3666¨Õjd|«« m é å2€Ç{ö÷÷ÉçóìííP.—ÉårT*êõ:ÌÌÌP,9ýü9e¾» Ò—PCCoõî$… ‚@ccc$IAhttT¹\NWWWZ[[ÓÑÑ‘â8ÖéׯiÞô´44ôVŒŒx~ü Éh–J%vvvz4K¥ÛÛÛ355Åòò2Þ¹”êÝŒŒøPfº]=63{â;çDZ†fggµ´´¤ÍÍÍ^\$’YªÕ:Uµ*I¦lsppPù|¾E‘â8ÖÉɉœs:<<ÔÄÄ„>V*’dþÓ'©Õ:}ò›™ i6›Üßß÷h6›MÚí6ív›ÛÛ[×××Üÿú•æ=úÍ':#{‡ÿZ*âtöOØ3ÀÇ"63,I°”ų xÑÚ|Ñ®ñ¢ýì;íü »_?BAIEND®B`‚routino-3.0/web/www/routino/icons/limit-154.png 644 233 144 1327 12573351603 14601 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ŒIDAT8Ë­”;K#a†ßùЧ1ì(Ú‰¦«m,µ±Sƒ‚AÐÆBôäØk)–Š„íìµ\A!YHQÆf2ó}Ï3ººîv8Źr.ï9B’0Æ $‘Íæ‘¶ñ¼sr9øöÍ’Ëç#m§v!™4Nè5Q6ë!y‹Y¤ |ÿ‰ÕUøñÃQ¯C£õz"¯®‚ï?!m¤þ^/‘ɺºÄàà0Ò…ÔjˆqÎòž9¦V³ ]188LW—ÈdŒèï³³>Ò%¥@8¢¢œûï:p@H©Ò%³³>ýýi›Ò&óómâ˜8 ±ÎEÑ»Tg£ˆ8 ÿùy6_g6‚ïßS©¸8 ß‚þEιÄnmRa¥¾4"¤mÖÖb×np||LµZ \.³µµÅÎÎÍf€J¥ÂÑÑi¿1kk m é'{{k988 ££ƒr¹LEôöö277ÇÒÒ×××äóy&''ˆÁ²·ÒO£žžïš˜$ã@žç)uwwëääD4==­•J%…a¨ ”ŽÉhbBêéùnd Êd$IÎ9‹EŽŽêááAAhaaASSSZ__×ââ¢5>>®ÓÓSýªVÕ!‰ÎNÉŒœóÔnë=2ƨ^¯khhH+++êëëS£ÑÐØØ˜ÎÎÎT«Õtqq‘†’sÞ‡™E­333ìïïs{{K>Ÿ'—˱¼¼L˜ÀÝÝ] …Bw3û°Í4›M^^^hµZÜÜÜ`­Å9‡µ–ççgîîî^üa›pFƼ%{£ÄïÎ>]€ûOÂ÷‰\RÕ_ð¥·ù¥_ãKÿÙ~Úß “©3©êIEND®B`‚routino-3.0/web/www/routino/icons/limit-28.3.png 644 233 144 1530 12573351605 14660 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ IDAT8Ë­”ÏK[YÇ¿ïÅjúšq¢BbƒDè,J»,fc  .*‚­‚‹Únl] Å`pp!í^dÚ)2P(˜À]¡K‡6¤AÄT)¤’¼÷îýt‘8£]{ápÏ9÷{÷^¾ß#$! ×u‘\$þ‚´„ã¼'‡ÎNC<Žói©y.$·Y'tÖ(uîß"=ÃóªÌÌÀë×–½=øòööñÌ x^éYï4ë%Z[]ÚÚDoï ¤OŒŽB¥b€k çW#©T ££ }¢·÷mm¢µÕɤó>27P,AAÖþog9°@¹9>26æ‘L6Ÿ)=g|~P¯c|c A`ÌÅ ß'¨×1à3>Òó³?Ëày_m¹ŒK³ðÇÖÚ {gm¹ ž÷)ù]úƒG~u>4ÿno»¿z%ÏóÔÝÝ­b±¨µµ5µ··+™LÊZ+×uU*•ô×Ë—jkiqR·n*•«ÎÖVD¡´E¡À?Ÿ?›Ÿ<|>O__‹‹‹¤Ói¦¦¦èééass€r¹Lgg'¤’IÞ”J†BPÚr‹ÝÖ;ª”JîoOŸjccC±XLÅbQ]]]R*•Òéé©$) CÍÏÏkrrRÝׯË?>v•ÏK±Øí–È•+ØjÕ¿{WÝÊf³ÊçóÐÎÎŽVWWuxx¨D"!IÊd2J§ÓšžžÖñɉ~no—"9‘2±˜åä„â‡\FYXX`xx˜ÙÙY²Ù,ËËˬ¬¬ÐßßßÈg2üùâÔj×®Y×T«ÛzûVoÞ½³¡ïk}}]‰DBù|^¥RIÊårQ.—Óàà R©”âñ¸27ojâÁ«BA‘oß¶…´Ä“'œBx°»ËnÓjµA°¿¿O†Xk9::ÂZK†Ôj!ƒ´ôÏ(—Ì>dz3N÷­µ ƒùg`Á·A€mHæ"IÏûax†ñ¹wïœ.U›—:5.už]â¤ýçúd%ÚŒIEND®B`‚routino-3.0/web/www/routino/icons/marker-22-grey.png 644 233 144 2615 12573351600 15620 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“BIDATHÇuUMhTYþι÷ú^*¸(ŠFP¡F© ”e¬2M;³ v@: ¡™d£‹i¡]t7M#„j(Üô¦ÝÌÂÍìÄRÉ(B¢ ­d† ÁAŒUþ: ¤Q+IUŒVÉ{÷Ý{{aêub;\¸ïƒwøÎwι‡ŠÅ"VÁRJ‹E[*•:ç~ÒZï ‚À üçy)¥þKD?‹Å[¥R‰£( ´T8çŒsn“Rêl†_j­]2™¤t: fŽ#Zk177‡f³é”R´aƲÖú"zED€‘Ø9gl“RVZ­Ö¶T*8p€s¹yž‡jµš«T*fiiéËD"ñGcÌçÜÿˆˆE¿°UJù¯0 ·e2=44¤¶oßNB8ç~w¤”ؼy3e³Y®×ëzqq1¥”ú³µöι×b``þÖn·÷e2}âÄ åû>¬µ±2fè½µÎ9cH$°gÏ1;;«_¾|™ò}ÿ“®®®«†áça§R);88¨:¾ !ÀÌ`f8çâ`Df†”2æU*•²a‡aø¹Ø¿ÿù ¶ ¸L&CÆ!P¯×ñäɼyóÉd2Vû!‰DJ)W«ÕH)Õ#£(ú,™LºÞÞ^!ªÕ*Êå26n܈••d³Y ÿŽß¹s'†††¹\Ž'&&\«ÕúŒƒ pétšºººâtÆÆÆP(púôiœ:u Õj?Æ­[·Ïçc~ff=ŠÕ¦Ói ‚ÀÉ÷uø­1ÈårèííEGy§p¹\===ëøµÿ®ÞY !ìÊÊ k­¡”3ãÈ‘#0Æ`zz7oÞD>ŸG6›E6›]Ç ìØ±#.`«Õ3[éû¾yöìîß¿Ï}}} "4 \¸pAàèѣؽ{7`ii år9æóù<¬µ`f<þOŸ>u¾ï𣔒+•JÔl6—/_†µ'OžD¡P€Ö0::ºŽÃÎ9DQ„ññqCïñw:wî^½zuþíÛ·Éf³Ñ±cÇä™3g ”‚QAkÇcbbZkH)aŒA»ÝÆñãÇ1;;k'''¹»»û¾ÖúO422[”RÿnµZèïï·»víâÅÅE!@D0Æ`Ë–-h6›x÷îˆÖZø¾F£áÆÇÇÉó¼wιOs%3K¿Xkû¾?qûöm—ÉdÐ×× ƒM›6­›¬v»ëׯGBÅÌ#ÖÚ‡$ˆ("šB| @\¹rE7X¥µÎ9Xkã×®]‹”çyóùüÏ@Ôi2MD¼wïÞ³žç]|ýúµºzõjÔé½ÎˆvzRééi{÷î]ÙÝÝ=†á÷wî܉‡GìÛ·¯“ÍÍÍ9cÌ|ßÿâÅ‹)cŒíéé!cLü°03péÒ%§”"%¢i"’ p©TŠuf–̸÷»çü¾sߣ\.‡`Bär9íºî cÌAô{žgÞ…±,‹¤”ÑÅ\.÷›ëº, CÐ@;¢Ü£Œ1íRÊ˾À$ êêêc,RÔZcaaµZÍH))‹MAð - fŒQ! õzý@2™ Y&“!˲°;<ÏC¹\6…BA­¬¬œwç¥Ô 1æo"büرc@§âß÷¤R©àÂ… òàÁƒÄ9‡1æ½!„À¾}û¨§§‡U«Õ`yy9)¥üTk=eŒYãÃÃÃðóÆÆF6•JcccÒ¶mc@D ÚÆÉ‹æ`ŒA<G?õêUðæÍ›¤mÛÇãñ_™ïû'}ßÿ<™Lê‘‘ÙØÐ,ƒïûÃ0:ˆ1c `ddD&“Iíûþç¾ïŸäãžçuž:uʤR)ÒZ·cŒÁôô4&&&P,aYöï߬µ†ã8Ršr¹LRÊn†á‘D"az{{Y#«†Ëp÷î]ܹs£££Èf³ÇóçÏADhN ··—% †ááyžéééañx¼eQãùàÁd³YôõõAk ß÷Dx´ÖˆÇãèêꢇj±½Ÿµ´LäÍÍMÔëuÌÏÏÃu]c0<<Œt:Ý"Ýžm&8çz}}A)å{‹cð<§OŸÆòò2&&&`Y:UÖ¯×ë`ŒifÛ¶zùò¥ž››‹JiÎÀó<?~‡ÆÐÐÒé4J¥RË #"ÌÏÏãÅ‹ƶmÅü „`…B!¬Õj-­bY‰–––[[[XYYÁž={Zª ‚·nÝR´¿ðsçÎý¹µµÕ½¶¶ÖW­VÃþþ~ÖÌÕ¶mܸq•J333¨×ë8{ö,ÚÚÚ¢5ׯ_×Ïž=ã¶mÏAðßqõžmÛ#‹‹‹)¥twwwÔ¯{÷îEGG^¿~ŽŽŒŽŽ¢½½J)pÎ177gòù³¸¸˜lðUJE‚Œ1¼}ûW¯^5RJð%Í‘ €¹®µcL0Æ*Zë1ÇqP,M¹\ç<â&''Cß÷çü2] w0Âu]°Æd'þ—o¡PЕJEX–õÔó¼KCCChÄXì~ïµk×Bxüø1ŠÅ"ÇÖúk!ÄF>ŸçÞ¹€7¿|ˆ¯eYgªÕjruuÕ÷žνÏs„$$áº.’‹$r¹vqœo ðìYB¡Žó i7½’›Æ õår’C¥’Czƒïÿfm >|°\]Á¯_puÕÃkkàû¿‘Þ¤þN/áy.btô9Òáò2 Ö&<´6\^&,.‚ôƒÑÑç ÏsEˆ¥%é;››ÀÇÇ`íýêŸ:ln‚ô¥%Ÿ HÛ”Þ²¼ ÐÅL§Cb-I’Ç1I’Üã("év{þËË ½í¿Yßosq`M§ƒMYkïöýDwƒËÅø~©(¤]Ö׌íU£V«Ñh48??§Z­R¯×ïðÖÖŸ?Iû5¬¯ƒ´+¤/¼$Éd8::¢Ñh088ÈÜÜìííQ*•˜žžfjjŠ[-€Ä¾{ÒWCC/ôúµ$¹ä8ކ‡‡•ÉdÔl6µ±±¡ããcA ŒŒèôôTžçéã§O’ä&33ÒÐÐ W®‹q’ׯ1iÑ?ð¤Ú|Ò©ñ¤óì 'íU%j4eEi÷IEND®B`‚routino-3.0/web/www/routino/icons/limit-20.7.png 644 233 144 1516 12573351605 14660 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”AH[Y†ÿ÷}h5ɸ¡cDƒnRta$P µu'´°Ý»ì,fY·’µ Œ ¶]Õt!¡ØvK,j4 IK5ïÝûu‘èè0K\¸çÜs~ιüÿ’„ëºH.’hhø)ƒã|¢µnÞ4´¶‚ã|BÊÔÞ…äÖê„Î$‡û÷žáy%¦¦àÅ Ëá!|ý ‡‡Uj <¯„ô¬–ïÔê%B!—pXtvÞBÚfl öö `­á²Uý€½=ÃØHÛtvÞ"¡+¢Q‘N{H[LOœßßkÿ=ç1°ÀÓÓ m‘N{D£µ1¥ÆÇ1PñÏÎ0• Æ|ßÇZ{©9‹zŠ_©àCÅÞ½ ÒÌùŸõâyÇ6›Å‚Ř  skíÀZBµÃl<ï©·îwé>¼íŸ×þþ¾vww‹Å”Ïç%I jkkSo<.#É ÉZÇ5¥Ò¦Þ½Óú‡6¨T´²²¢––A ááauwwkbbBýýý õõu¥ÓiÕÌêí[éøxSHž<¡ Á?¹¹\ŽƒƒNNN°ÖR,1Æ`Œ¡X,b­åèèˆr¹ Aðø1H™ ž‘ÍVyS㙵ó?œ» oè Ï®(ÀBÅú>¶*™ ÐÿÞmœËªÂ½{—p­Ú¼Ö­q­ûì7íA^s9ÆK­æIEND®B`‚routino-3.0/web/www/routino/icons/limit-76.png 644 233 144 1362 12573351602 14522 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“§IDAT8Ë­”?KœYÆï¸ãŸDƒ d´3–®"Xˆ•(L*‹@ý~…-“ÎÂbZÑ"ä#Na§‚¦Q 2ßyßûÛâu\v·òÂ)ž{Ïyî=ç>ç `.—rvwÿ.lE_íï×W¯Rûû5о [ç¹Ç8¤MÔÝ ‘oßv ,~¸¶¦Ÿ?¯®ôûw½ºÊðÚš ?„þÑc<ØÙ™³« +•×Â7õâ"UCH}¾2œxq‘º¸¨ðÍJåµ]]ØÙ™Ãr—– ‰ªj°ÕÒVKCøÇÚ{Ô76N\Z*X.?¦ ­VUc“ÄÐjÙzf!CÆqlš¦š$™ilµªð±]³q …¦§§Ù™Ó/ÙedOXÛdÁÓS-šÂxÇŸðïßÿÁ»w©qœ‹òyÎÎÎØÞÞæää„ããc¹»»£V«ÑÓÓÃðð0FQšF”J)——=u ¹³£š&ªîïï;55åÜÜœù|ÞÝÝ]œŸŸwffÆóósUÓ8VMÝÙQ8ú¾¾7ÌÎä:òy¦§§988`ss“ÉÉIŠÅ"‡‡‡,,,P©T êèÈ1; }}op` õæ¦]œ§Ú4 ÇÇǽ¾¾öÓ§OŽY«ÕqooOÕ$ûY½¹Ñ4GqL{¥i Àöö6¥R‰r¹LEôöö²ººJ©Tâòò5 Šc!ÊÑl~¡^„@EÔëuªÕ*ËËËŒŽŽR,™˜˜`ee€ŽÌ7P¯C³ùaËõuÕÄö³ÕÛÛ[ïïïŸp’$6 “çÒÉü××¶þWgíú…2±ªišf:ËðO:û×0I~é¯äÿÝ/Ú›/:5^tž½à¤ýŠcÐåþŽ”IEND®B`‚routino-3.0/web/www/routino/icons/limit-32.6.png 644 233 144 1544 12573351606 14664 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”ÏK›Y†ß|R|¦©•0A2é X… Ef¬K#S¡ÌÂv£ 7‚ÿÀ0ºk7®\¸¡¶Ô®ÜŒ‹®Õb+¬ ƒ¨¨!RkCL¾ïÞ§‹Ä©ví… ÷ÜsϹ÷\ž÷IHÂq$ITVþ‚4E 𞚨­5ÔÔ@ ðiªä’SŠºLTY@ ðèQ%Ò3\÷+CCðò¥åð28<,ÚCCàº_‘ž•ÎJñåå"»‡ô‰Þ^ØÛ3€µ†«£hûìíz{AúD,vŠ Q^îˆHDôõ¹HÈÏÏk¿ÏË=°@ž±1>Ò×牔ʔžÓß‚—Ïc Œ1xž‡1×h</ŸÇ@þ~ž_þÙ}\÷Ìnmo,^M`­ÅZ{}]ô[»µ®{†t¿ìOiœ§O;Ož˜?|pfçæTQ^®h4ª -,,( *‰È#Çq´»»«¿gfTuëV .7ìíUÖÖÊd¤5^½b;“1µwîJ¥hjjbrr’ºº:º»»‰Åb¬¯¯N§éì줧§‡_<࿳3Ãâ"FZstûv›ººäþìü5>®Õ××kggG£££ZYYQ0Ôêêª$iyyYÛÛÛ ‡ÃúíáC…«ªuv* µ‰»w é4ç_¾L&ihh`ss“õõuZ[[$ŸÏ0;;KKK ÓÓÓüòÏÛ·pq yÕÕ–\޹/HÄã´··322B}}=œŸŸ“Íf9==eqq‘ŽŽÚ fæç!—ë®¶NY6ûNoÞè÷TÊþ+ )‘H(*NkiiIšŸŸW2™TWW—š››åº®ñ¸þxüØêõk•e³ï„4Åð0€ï]\p||Œïûär9ŽŽŽØßßçàà€l6K&“ÁZ‹ïûœœœàK÷iêg¦Ä™1æ®~ÖÚ"ƒÆ`~àì»R)€‚õ<ðýk€^ßÇeU •º¢€Õævíg7Øi¿Ô¾ÄmeJ IEND®B`‚routino-3.0/web/www/routino/icons/marker-51-red.png 644 233 144 2071 12573351600 15422 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“îIDATHÇ••ËkTIÆU÷V:¶ ! Î"7ˆQ\¹c"%AÆlÜ»Kƒã ¸™,C ³‘H/\‰ .Æ]VB,‚ tÒ ŒDM/ò ïã›EÕM:qg‡*n}u¾ï<.šíïï·•JeÒ9· (‚WïÞ9·Z©T&Â=[™à# ~rÎÍgYvO’jµšÁ9GQXkIÓ”••¾|ù"cŒ‰ã¸‘¦éðWÎÁ g£(jJóN§£¢(ÔkEQ¨Óéhqq1J…{gKÆeÄIE€FGG»ÍfS’”ç¹Ò4ýnåy.Ij6›íà ñ°ÖÇñS@]IʳLݽ=Ý®”¦~õF›eêîï+,&&&º€â8~j­…¾¾¾i@I’ä­VK’”9byîWÏw­VKI’ä€úúú¦#cÌrQÉãÇuóæM“ñ§Oðâ¼kkðá\¸QÆÀƬ­aÏ#KSjµ•JE¯^½2ƘŸŠÁÁÁbkkK* ’´° ÔßïýÀ€´½í#üúU“¦¦¼!Ú­­- ¡äÈgff$IÙþ¾§xû¶42"íìxnן¿|):åºsÇŸe™²,“$ÍÌÌÈ-`s*;dVV``.^ôR\»?ÂÈ|ûvØ6ò7޵@Ñn·ÙÛÛ#®T<ðî.ܺÏŸÃÕ«p÷.4›P«ÁéÓpâŦ±¾4?þ P`­íùKK>£{{Òæ¦´»ëémoKÆHÏžVÀä¤4>~D²7oÞ(Œ1]¢(ú Ðp’¤ÍÍM©ÓQ~ò¤ôä‰XX¬•VWA§§¥7|R³L;;;º|ùrš`jµŠsnÐÄøx*IÙ£G>QäýǬLØÔ”4>®<¼qÿþý<®ÕR–!çÜ úÜ\.IÝ·o¥¥%éÝ»²éýò\•¾~-Iz¶¼\À]cÌ¥00Æ\·Ö ÈA¿4”JÙA‡Må÷ív[ÃÃÃeï×{ñœ1†8Žç‚¾‡CåZ¶<»7;›†ÙÚ8sæ QL(ÇöÒ¥K8ça¸x}Ëhƒ•ý>??ŸÀöÁtê{;Hœs-@õzÝëTÒ^__WµZÍYk9Nû¸}¯o£q$ÂP>iu¿c?°#ú&IÒ-G¢$Õëõ’ö:P}ðàAïoéßí¸¾ccc©$5 ?0¬•1æzø<ú!àq}ã8nš-®\¹RÒ®Úñ<¢/0nŒ…ÿ<þ´}©EîK˜Â¼H_š—¾_”D±©ˆI:MK¢P5Žù˜‡ÄL2£™ëùØ{÷áf¦QoÿpàìÃá¿×ú­µ×¦t: 1!Òé´Îd2_cþàûþ!×u Âÿd,Ë")忉è‡t:ý·L& ´aÊ1ʳCJÙçyÞw¾ï›h4JÍÍÍ`ŒÕµÖXXX@¹\6RJ …Bý¾ïÿ–ˆVˆˆP3Æ(»…ÙJ¥²;‹¬µµ•,ËÂçr]SSS&›Íª7oÞ|ç8N»RªÓóœˆ?yò¤Ð$„ø§çy»ãñ¸ßÓÓ#÷ìÙCœsc¾x„hll¤D"ÁŠÅ¢ÿúõ똔2¥µþ‹1æ-O&“ð§>œŠÇãþ¥K—¤mÛÐZ×"cŒˆ>‰V)…p8ŒÃ‡ó/^øËËË1Û¶‡ÿÊ<ÏûÆó¼ïc±˜îîî–Unœs0ÆÀƒ1@DµoBˆÚFÝÝÝ2‹iÏó¾÷<ï~úôéë®ë6%“IÇI)Î9J¥òù<<ÏC$a}}ù|¥R +++X]]E$A]]„fzzš¤”-"‚¯¢Ñ¨Ù¿?Î9r¹°e˼{÷íííH¥R˜™™Á­[·°mÛ6¸®‹p8ŒË—/CJ‰¶¶66::j*•ÊWÂu]“H$X8®µÌÝ»wqüøqtuua~~×®]Cgg'^¾|‰D"‹/B)…jgcà8š››éñãÇZüXöI‚ @4lݺ¾ïcii œsÌÎÎâêÕ«°m]]]H$¨"Ûða‚s®×××™ïûàœCJ‰cÇŽáÎ;˜ŸŸÇòò2|߇çyPJáÀ8rä&&&pýúu\¹r¥@¥RcL3Û¶Õ³gÏt.—«Uº££gÏž¡½½‘Hœs¤R)œ?{÷îŹsç „ÀóçÏsss˜››3¶m+à÷B–ÍfƒÕÕUúûûQ.—ÑÓÓ"‚eYhhh@__=zÈår0Æ ¡¡044¤èGý™_¸paüãÇ-oß¾=P,ƒC‡1Î9†‡‡1::Š¥¥%¤R)ìÚµ ®ëâþýûxðàfggqâÄ úûûÏó缈È ŒÈd2`Õ— }Á÷Þ½{þÚÚZíJÉf³zqqQX–5ãºnï™3g°Ù`ñ™ñ|oß¾ÀÓ§O166Çq µþâÃÈÈ`6sç›?Åײ¬o‹ÅblmmÍø>Xûpª1°@‰™öõho¯|Sš#•(¥&,ÀCuà,~±ˆ_.ãCÙŽ4WY7ž÷“£#°¶®‘µk-ÿ4cB„‡‡ày?‘ºÞKôîÝ+&'+¹_¾~•1F±XLŽãèøøX»»»êèè$år9­¬¬hÿà@{ß¾9OûúLìúú‰ÝÚjÒ6™ €YÍdˆD"¤ÓiJ¥]]]ŒŒŒÔmll000Àðð0ŽÄç­-çOøÒv£š›ûôúµ¬ä: ŠÇã$I³³³*‹jmm•$ù¾¯ÁÁAmnnjaaA‰„Þ¼|éÚ³3567÷‰XÌðý;ÕI ±ººÊúú:ñxœ‰‰ :;;Éår5tôöö²¿·Žïüb1ãÊZG岪f­•1F®ëª¿¿_;;;:==U6›U>Ÿ—$¥Óiµµµ©ûÅ InHÖ:µ™ù`’É$ËËË5KKKŒÐÓÓ@*•b~~€ ™ HÛBZdz:ŒC¡Pàþþ¾Æ±ÛÛ[ …Æ.//±ÖruuÅÝÝ„ü ˜žiñg‡‡!oêú?³aÞo<ûKÖ÷ù³a•¸µ;ª²*“JÕ)àQµù¨[ãQ÷Ù#nÚ_]?˜‰L©&½IEND®B`‚routino-3.0/web/www/routino/icons/limit-10.6.png 644 233 144 1430 12573351604 14650 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÍIDAT8Ë­”ÏK[KÇ¿÷F’ôê ¶*îú\¤ë«"RBm7.܈P ”·•øøg4;®Û…ð¤…lÄuv}…¾JE`Õ"" h¹$wf>]äG+íÒçÌÌ÷Ë™9ßs„$$áû>’$Òé¿¶ð¼O ½{–ÁAð¼OH[s!ùœP—(öÒKKpvfƒs–_­ÎÎ,KK 1>~ŸTJ$“¾ËËÒg66š€#Ž!ŽÁ¹Ÿ«»h²±Òg–—FG;Ï”J¬¬´L³‰m°ÖÇ1ι Ú8&n6±ÐâùsJÝ?{@48:€s"ç\ä¾µíðð‚ ô@H[¬¯ãÀT*Ž888`ss““““^¦Õj•R©ÄÿïßW,‚´%¤loØ··éëëcggc “““LMM‘Íf©×ëÔj5òù<‹‹‹}r\]Á÷ïpuÕö——!~ ½ïà½N¼D:íÓÓ#ÆÆž }£T‚FÃç,­í K©Ò7ÆÆžÐÓ#Òi_ŒŒˆÙÙ©ÎÚ@ p$ $ 8÷ïêžZ¬­Tgv6`d¤óMéóó1Æ`Z-¬sXkI’k-Î9’$!iµHâ1óó }èÖ¬@49?p¦ÕÂuˆœsÜw²´_x~AÐD*¤ÞIkié/½ycIßO§u||,cŒòù¼jµšÊå²E‘¶··uvv¦¯õº²™Œ—{öÌÒhôz§§)!R.X¬eww—T*Åþþ>ôöö299I±Xd}}©©)&&&ð$¾|þ `ÍÇ úêï®/$Éw Ïó444¤T*¥ËËK­®®êððP€úúútpp ¹¹9-½}«™W¯ä$?õò¥Ôßÿ\är–Û[’8`zzš­­-ŽŽŽgqq€››ŠÅ"õz½]:€Û[Èå¬/ç<űš1FÙlVajffF ÚØØ$íììhxxX…BAÖù’Ç’sž¯f³ªJE’œœ“$A l6«““c´··§ÑÑQU*U«U•J¥vVkÛq•ŠÔlV…´ÉÊ €é’»»;¢("Š"®¯¯ Ã0 ‰¢ˆf³Éýý}[m¼ae¤Íßt†1üŸ9 ƒûÎþØîaW¬ÿˆ·KÔÆüÒÚ›:5už=â¤ý —×tB()K—IEND®B`‚routino-3.0/web/www/routino/icons/limit-31.2.png 644 233 144 1476 12573351605 14662 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“óIDAT8Ë­”ÁKÛIÇ¿¿ ˜M¤n$‘î)P=o—éeEÔäè¶Û›ÿe=¶7‚ÇBÝšP½x)(hi ‹ÝK\!V!uSmòûÍ|öØÖzõÁÀ¼7ófÞ›ù¼'$! c ’A‘ÈÏHKxÞâqèï·Äãàyo–:ëB2?¡óƒ"É#› =&m0; …‚ãàŽáà ­ÏÎB4Ú@zÜÙïuü%ºº á°H§o ½cbªU 8gù^Úz@µj™˜ééô ÂaÑÕeD2)&'£Ho™Ÿhßßç¾s8 ÉüÁHœ;ßoKp¥µy¥]ãJûÙvÚÿWrŠ]gûIEND®B`‚routino-3.0/web/www/routino/icons/limit-24.4.png 644 233 144 1421 12573351605 14654 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÆIDAT8Ë­”ÁK[[Æ¿{¡1\ûÔVDwÄM]ÍÆ]¡p]‚»‹Û´+Kü\´ ðYÙ´]V誋,\ô­˜jPKè"FAjÑBïSsÏ9¿·HLõ•·s`8Ìœ™93s¾! Iø¾ä#‰d2ƒTÂójŒŒÀýû–‘ð¼R©w/$¿ç't(™ô<ž>M"½"~R,Âû÷Ž£#øþŽŽºr±AðéUÏÞëùK$>"•J#5Èå Õ²€Á9ËuêʆVË’ËÔ •J30  _Œ‹¹¹iŸ¥%€KÀÇÇàÜ/¾Ò.YZiŸ¹¹€ññ^™Òkòy,tâËKl§ÓOÆZ‹1æF‚ƒc t˜ŸéõUÏ?\½Ž‡µ8çnðÉ9‡ë>à¨×!~ =RÉ‹f§Zeuu•Z­Öwl4lnnöƒXké+ãŠEJ2Ò>ðw³iÿÂ0$•JQ­VH§Ó„a@ÜíÖZ&'' ?°æí[¶|ݽûPa¨Ö—/þ‹—/U©T488¨ÝÝ]­¬¬èüü\£££’$çœ$iyyY“$ŸG¤áá‡âÞ=køëÓ'¦¦¦X\\¤\.311A¡P “ÉÐl6úú……2é4_Ûm8=Å[ßűç'ú¼¿¯ÙÙY ­­­I’²Ù¬vvvtpp Z­¦(ŠäœS6›Õöö¶Z­–ööö$ÏÖzêH[|üÈŸïÞÙ;¾ÏÌÌ CCClll°¾¾N>Ÿ`zzšã^år™Ü“'Ýž½yÒ–J<Î?`ŽÛmÚí6‡‡‡DQ@Eœa­åää„8ŽqÎE§ß¾ž=ëþæΨ׻¸±7'è©k÷Îúà ãâ׃Àu^?1ŒÁý6·:›·º5nuŸÝâ¦ýq²ó[*IEND®B`‚routino-3.0/web/www/routino/icons/marker-13-red.png 644 233 144 2026 12573351600 15420 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“ËIDATHÇ•UAkSYþî}÷&mÀ.Rty¥Hg¡-ý6tZ(.²P„i]Œà® Á€ƒóÜLCÄndÆÅ ]X1³èJÁ¬¦¤„,:µï½{¿YÜûÒ$2èxÎåïó½ïœ œ™œ˜˜ÏçWµÖï€õžÃ±Öú}>Ÿ_Ÿ'3 á}ÀøNk½¦éINOO‹¥¥%h­a­…”I’`GGGB¥T”$É]á ¾p1‚6–J¥¤Ñh˜~¿Ok-‡ÍZË~¿ÏF£aJ¥R€>ïbÖqVqÁG,—Ëq«Õ"Ic˜$É1†$ÙjµX.—cü@è`¥„Rê V*•8‹“„6MÉ4©”iJÇŒ?€W*••RO¤”@.—[À0 M»Ý&I&IBZKú¤ÅI“$Ûí6Ã04˜ËåÖ¡”j`½^7#€®?òõëŒLº·G>zD¾ysVÉz½n|µM°ÅbÑv»]—K’§§d¯G./“kkg¥Ý»GäùóÎß¿Ïì7v»]‹Eë%S­V]§§îçÏÉ©)—xíš;ëõ\üà‹>tq¿ÏŒõjµJFZk¥WÕ+À‡Àõë@¯çÎòy`w¸|Ùù(®^ÎŒ‚GJ¶ÓéàääJ)t/^¸LN¤U ¸qÃܼ 4›ÀÔ „p3txxRÊ€ÙÙÙ9#Þ“ÏÕUÇ+I’»»Ž’|÷Ž˜>{F’üóåK°BˆAü€333É@ô^*\_'WVèuã8l4\ÜlÒä‹<&¹péRê‡à7 h­÷âOF~ØÚÚY¥$y玖’œœ¤¹}›$ùÓ­[Æþ iIkýkµš!ɘ$_½rºÌtj-¹¿O>~Ìäí[’äOŸZøb>T „X‘R@Eш°Ç'*ÏΧOœ ÃlökÃx …PJÝÀ™0Œ[~düÍ~v¶±±‘øÝÍÎÎ"‚Á†òŠQr~~Zëh„ß±…’U¿½½m<`g°†ÖÆB­u{„__YÖöÁÁ …‚qó"o{ܾÊïññ1¿<~õÂ×øŠð†aœ­D’¬ÕjYÛ [[[Ã×ÒÛ8¿ËËË IFQDFJI!ÄÊÐýöM6àW)ÕÀÍÍM»¸¸˜µ]óm«oáÀBH}…{sssPJÉÿ 8à×ûŸƒ  ”²àû±n¾°‡Ù•¯ƒ"É×IEND®B`‚routino-3.0/web/www/routino/icons/limit-12.3.png 644 233 144 1461 12573351604 14653 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“æIDAT8Ë­”ÏKIÇ¿ÝüÑÛ$“A˜Í\F²‡àÁ@Î"! EÌDB„ôèÁ`qÉQÐó ƒ{P˜³ÃÆã(L âàiE †3ÐÓ]UŸ=Ì I6Ëž|PP¯ª¾ïU½ú¾¯„$|ßGò‘ÄÀÀoHx^•L²YK&žWEÚèî Éïâ„z<$W¯Þ†_YZ‚ÇÅ\_ÃÅEÇ_Z‚0üŠô¶{Þëâ%úú|úûE¡ð©Æô4Ôë08gùÞ:¾¡^·LOƒT£PxL¿èëóE.'ffB¤O¬®´GšBš‚sßFo Ðfu¤OÌÌ„ärÝgJï(Ónc;¬µ¤iе?^Ð& i»…„—/Az׫ÙaxC­†纜s8çþsÞÍÔqON oF‚ߥ?ôæÍ‹‹Ö—ü¿?|1FÙlVÕjUÛÛÛŠ¢H¹\NÎ9ù¾¯ããcý¹µ¥þ{÷¼üÓ§–z}ЫT!U(•ì_¥AP.—9==epp‰‰ …•J€Z­F6›ennŽ|.ÇÁñ±¥\ÆH_÷ï?Óóçr’†ÎÎδ²²¢½½=EQ¤££#IR’$Z[[Óüü¼~}ôHÉ—/¾^¼¢è™xøÐòù3i·¸“““lnn°¿¿Ïèè(‹‹‹?|Âíí-³³³  ~ü­öÁëË9OI¢žcE‘†¦¦¦´°° õõuÅq¬f³©­­-kggG¿„¡*‡‡RÈãùº¹9Òû÷’ä$) CEQ¤ƒƒc´»»«ááa•J%‹E)ŸÏ+“ÉhäÉͽ~íT.+hµŽ„´Áò2€ÁZšÍ&qÇ1———4 ÎÏÏiµZ\__ãœÃÃÕÕiwpËË m|ãÙÉI‡ÙÆðæœëÔÏZì¿xöS¸4¥°GÖŸk ]r'‹ßuÀöæªÆêÙ*í?{'p–˜ %IEND®B`‚routino-3.0/web/www/routino/icons/limit-20.2.png 644 233 144 1520 12573351605 14646 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”OH[YÆ¿÷M|5U»ÉX¡þÁ¸qÐ…º (BhV]ظwYÚ½«qÓEµX±‚‹¸êf °J¥…ØMAH(J›¼wïoIl;¥.œsïw>ν|ß’„ëºH.’‡»Öpœw´´À;†–pœwHkÕ{!¹Õ:¡Q8ì 9Ü¿Fz‚çYX€—/-§§P(Àéi%_XÏ+"=©âj½DCƒK($:;ï!0; ™Œ¬5|¿*y@&c˜é„ÎÎ{„B¢¡ÁѨ˜›ó>°´P,¾¾Ö~Ûµ3°@‰¥%>07çVŸ)=%Ç@Ù/•0å2Æ|ßÇZûCƒ¦\Æ/•0P&éiíÏúñ¼s›NcÁbÌ5QÄZûsl ¬M§ÁóΑúëþóðáïÎü¼9>òù<©TŠH$Âôô4¼ýôɰ³C (hj²\^²µ»Ëò£GLLL0>>N,`tt”õõu677Y^^`°¿Ÿ?Ÿ=ƒ¯_ñoݲ¿ÔÕ×c‹E'>3£_[[500 X,¦žžmmmI’"‘ˆJ¥’$)‘H¨½½]ÃÃÃúmtTóH…‚êêë‘ij²|ùÂÛ÷ïi ‡YYY`ooÁÁA2™ ]]]$“I.//I¥RxžÇêê*ççø¹ܾm]S,êÍýutdƒrY;;;jnnVšœœToo¯‰„FFF433£d2)IÚÞÞVÇÝ»Ú}ýÚêèHÁÅÅ¡ÖX\äβY²Ù,¹\Ž««+¬µäóyŒ1c( ‹EÎÎÎ*¸ÏŸ¹‚€ÅE¬´v­3Ò銲«:³ÖbþGsß”k*øïtöƒ,”­ïc+–¹&ýo\ÃØŸp£Þ¼Ñ©q£óì'í¿ãJˆ€·a!&IEND®B`‚routino-3.0/web/www/routino/icons/marker-85-red.png 644 233 144 2147 12573351601 15436 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“IDATHÇ•UAhI}U]5æ !÷0DÉ.hBðàÁ Y ¢›º âÞDr˽丹¹ dãV»ÉÁƒA‚„t&è²1‰Ž2‰éê®·‡ªN& ˺šßõ¡^½ÿêÿ_À®É–– ÙlöœÖzXïÙ¼ÖZ/d³Ùsà÷ÉHxH|§µžŠãx”$ÛÛÛÅÀÀ´Ö°ÖBJ c æçç±¾¾N!„PJ•1þnÂÙ9áXUÌçó¦T*%õzÖZ6›µ–õz¥R)Éçóý¾ciÆ)ã0‚Œ*• I2Ic|I’$+• #¼ t°RB)u …B”‚EÛÛ´QDC¦l­%¡"F[[Lâ˜$Y("TJÝ•R™Læ<†a˜T«U’¤ÙÞæ¾œw›ÌxÆÕj•a&˜ÉdÎBˆ{ÖÚprr’ÃÃÃ"6*“–—Çwï€ÎN “j5[^!_½B|ô(ÚA6“áOž!Ä`ÛÚÚìÚÚš#E’å2 ‡9挣V*¹uK‹ó­­´?’$×>|`[[›õ%‡ddd„$ýê6“'Oºÿ—/ÀÓ§äÕ«d?ÙhN’$aìµ!€DZkÀW6àÊ`q¸xÑýŸ:ô÷››À³g@k+pü8ðè %`-ÀãH ÀÖj5lmmA)å€_¿vàõ:ÐhoÞïßÛÛÀ… Àƒî K—€J“Z]] )e ù}zÚÝèÆ©595µ{Í==äåË.í/_\ìÓ'RÆ33$É¿ææÀ !"Að v„¡©ø’Jòyòúu·yy™<|˜¼qƒìì$'']üÎZ!È…6Höž8û&ø ¹\Zë{X2$?|H*E á.éôiòógòöm·`ró&Iòçk׸ —^M^k½€Å‰‰„$£J…œ™!çæÈæfxñ‚œž¦yþœ$9;;k=ঢ'T „8+¥$€¸|ÿ¾Ó×—ÊNGùJ{¿öö-;::ÒÞ/6ã€B@)5áõÝ*Q´·EãØÅHŽŽŽ?[Ë]]]‚`gB9x¥dOO´Öe?\œ¾)Û´ß!INMM%°¶3šÆöB­u‹Å¢Ó×3KÓ^ZZb.—KPJùÓþ´÷ÛA}Ëå= {{{u¿ !@ã?l¾aFéH$Éb±˜¦½ 7>>Þü,ý»í×wÈ×o¹\vCJ !Î6½oßd;ú*¥ª866fûúúÒ´‹>mõ­€{ôð£‚bÏðÏîîn(¥äÿÜÑ×û[APJYðý¾lØ?,h—XÍIEND®B`‚routino-3.0/web/www/routino/icons/limit-11.1.png 644 233 144 1217 12573351604 14647 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“DIDAT8Ë­”ÁJ\K†¿>fŽã ŠK!w\å |qáŸ`|#Ù»OpÀEâ<@dPÐ… 7˜!AÑÓ§¾»83ãè]Ü ýWwýTwýUX…PØïÿ#›ÒO×ÖôíÛÖµ5Mé§p<=G(¦qÈŒ¨ßOBr0è Ÿ¬ª¿‡úí[x}­¿ëõu‡‡C­ª¿Â§éý4˲py·¶Þ çîîêÕU«f#Z­ÃÙ««ÖÝ]…s·¶Þ¹¼ŒeYàæ&îíUÂ/ŽTïÕ°i´i4âqÍ|ê½GG ¿ÜÛ«ÜÜœ>>»¿¯úïïm»UsζíÓÍÙÜ4¶úàþ¾ÂçÙŸ½·ª&žŸ›5âQDøÜrÎFÎ]†ggZUá=±‡‡†fÕº®½¸¸˜.∘“×uíÅÙ™jŽáPáợ‘j{:Ùëõ<99Qu4Y–¥£îÜfšõééiçÿòEµm¾~Uø^ðúõvv(ÒÒ¨¤”X__'"P‰ˆGJ;;ðæÍ‡‚¥%)K|üÈöö6···<Á)%"‚Á`ðÄO¯EaADâá™Í²XĩˀËËKÚ¶}¼7}M©`2ùA]Àêê*½^oNVU+++ &“ÉÜß{õ R]Ãdòc^M5Û¶ŽÇcïîîæÕ\Ä777sÍÇcïþüéâçÕìtÖ•9ìôóÿÖ‘þGgO: šÆEÂEÑÎ÷9;÷³xÑÞ|Ñ©ñ¢óì'í¿5·d Ê‹IEND®B`‚routino-3.0/web/www/routino/icons/limit-157.png 644 233 144 1416 12573351603 14603 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÃIDAT8Ë­”¿K[]Ç¿÷b¼H45’MI^"ˆdéÐ%$à u)YZÁÅl]ü3ÚY¡ƒK%´¸^œ288”B‡ˆ‚"EƒE“{ï9Ÿw¸W_ûöÇäœçœçûœs¾ßGHB®ë"¹H"•ú iÇùÂä$¯ÕÕUMOOË÷}µÛme³Y‹E™0”+I¾/Yë¸ê÷?«Ó‘$+k%Iããã´°° ííme2•J%---i_õz=ºÕ˜×éHýþg!mÒl„1!¹ººâöö€Á`Àùù9&¢———ÜÜÜ“0Â5› mþÄ3Âðzì=çŒ1÷kk-qÞ<û¥ìo þP(ÊùŸU›:5už=â¤ýŽdœù»uIEND®B`‚routino-3.0/web/www/routino/icons/limit-30.3.png 644 233 144 1503 12573351605 14651 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“øIDAT8Ë­”ÁK[YÆ¿÷“ø4MÌ&Ó:tDRBÁÝ(¥]ÌÂ…u1u£€+wƒ.Û½ûÖ…*ÿ†Y¦‹ Æ…š… <µjÉ{ïÞß,[™¥œïÞsÎ=÷ò}GHB®ë"¹H"•ú iÇùB6 ¹œ!›Çù‚´Ñ=’Ûͺ-”J9H33)¤7xÞw––`gÇrz ççpzÚÁKKàyß‘Þtãn¾D"á’LŠBa©Áô44›ˆ°ÖpwupD³i˜ž©A¡0L2) Wäó¢Tò¾²²Ð,aaÖþ´Û=°@›•¾R*yäóÝgJo)—1„í6&0Ɔ!ÖÚ{ š l·1P.ƒôööÏžâyWöà s£1? ݱÖÞó»xpžw…ô4ö—´Îââï΂©ïï»ï>|P"‘Ðàà †¶¶¶”Ïç500 k­\×U½^×»÷Ç'ÏžšÍ^§V‹ÉH5vw9~ú¤É‰ U«UõôôÈ÷}]__ëèèH'''’1F›››šœœÔÎÎŽú>fjjŠL&C¥Tâ ÛÛX©&¤ –—¢°Õâì쌰CLŒ1ø¾1æ‡o­%Š¢N\«±¼ ÒÆ=ž™.ÏÌû?ÎcÀÌ¿xöS• @`âèŽíý(Âvº¨Tî(àAµù SãAçÙNÚ ØbWXÕ—xIEND®B`‚routino-3.0/web/www/routino/icons/ball-9.png 644 233 144 202 12573351601 14201 0‰PNG  IHDR à‘bKGDÿÿÿ ½§“7IDATÓ¥A ÃVÿÿçz’¨Iìm!0Ô,€TJWóFe¤I|…Z›z¡ý‹¿Ã;=M]†“ÏóIEND®B`‚routino-3.0/web/www/routino/icons/limit-9.9.png 644 233 144 1233 12573351604 14604 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“PIDAT8Ë­”¿J+AÆ¿]p¶I$M0èµÑJÁÎ"…M, )â+$°ñ´±Ê¤³_!`e!AH¡ˆˆŒèîÎün±›5Ao—™ïœùæü’„ëºH.’Èfÿ µqœ+òyXX0äóà8WHíD.$7y'4&Êf$‡ýý,Ò¾ÿN£§§–‡xy‡‡øÞh€ï¿#%úNò^Âó\2Q*­ ý¥Z…ÁÀÖ&W| Õ*H)•VÈd„ç¹¢PµštK«ðX¬ýÞc ,ðE«Ò-µšO¡¸)S¯D&Ãc¦ 3ÆÄxBÅúõ:HÇ㘭áûoôû±#aˆM½²Xkž“Yú}ðý7¤5!µi6"ôz=NNN¸»»K-ú Oô#šMÚBº¤ÓÁ€¸¹¹auu•íím666xzzàúúz ~~[ièt@ºt•Ëmª\–•\Iº¸¸Ðâ⢺ݮ<ÏÓÙÙ™$©ÛíNáççç’$#¹*—¥\nÓ•ë"Ï‹™$U*F#íîîª×ë)“ÉüŠÏÍÍ)]ž'¹.®¬u)þññ¡õõuíììh~~^KKK‡F)žÏçµ¼¼,Ir$)$k4f6‰Ùp8¤R©P,9<<äõõ•­­-îïïÙÛÛ£X,rpp§;®¹4fSÙL„|~~òøøˆµcLìI|‚l*›ÓuE˜Dy²hÇÄ@,ÿOýè¢èû÷„hêœèü쀙öæL§ÆLçÙ 'í?«ŒƒÖÀ(~cIEND®B`‚routino-3.0/web/www/routino/icons/limit-5.3.png 644 233 144 1374 12573351603 14577 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“±IDAT8Ë­”±K[Æ¿ÃÎf,fÙ"º® $02…ÕSlEP6"X,ÔVðxøÊ¤·ßÂnÁÿÀNlL±â"Ɖ°’ÂÝ;÷þR̬1ÈëH'oEŸ4;+'ùC’Žõðð @ “$Ykµ»»«J¥¢ËËKõz=åækvVŠ¢Ooäû¨Pð¼ü¤\.kuuUÓÓÓÚÞÞVEš››SÇW½^×ýý½¢(’$y’T(H¾/ç<õû™‚%u:MNNj}}]•JE777’¤F£¡™™5›M ëôôT’ä$©ß—œóž8³9g­V‹8Ž)•Jlll$ SSS\]]1??OEÔj5ºÝ.¹àž8Ò[[—™ y||$I¬µ8縻»Ã9Gš¦$I‚Éq9>ek ¤½:sÏ„:(6ЙµöO|Ð Ïtö²Ò—¦‰ôÅ>Mÿ§^µ7_uj¼ê<{ÅIû_!bY·¥?lIEND®B`‚routino-3.0/web/www/routino/icons/limit-33.6.png 644 233 144 1526 12573351606 14665 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ IDAT8Ë­”ÁK[Y‡ï9MâÓj*:3$âl¬‹`»JZºRÉb$èë¢Ì¦Ñ? ÿ@Ñe»wáb$ÐY™Zºº)¸Q$ЂƒeÈ”€¡vj0yïÞoF[;[/\î9÷žsï9—ï! I¸®‹ä"‰XìW¤%ç=ñ8ôôâqpœ÷HK­s!¹-?¡‹‹b1ÉáÑ£Òs<ï+ssP*YªU8>†jõ\Ÿ›ÏûŠô¼eï´ü%"—hT¤ÓCH™š‚JÅ!Ö¾çzH¥b˜šé#éôѨˆD\Ñß/òyi‡B X‚‚¬ý6/öÀ vÈç=úû[iJ/˜™Á@3h40Í&Æ‚ À˜«š h40Ðdf¤vÏ;±»»ç/¶­µ?dh/Wk--;kwwÁóNn·=“yú4ëŸgppÍÍMVVVayy™_’IÞ¾{gg„]]Æ ›MGúsuUîßW©TR*•R¡PÐÄÄ„ÖÖÖÔÑÑ¡­­-IR,Sgg§fggÕ××§>}’@ã¸m§§e½y£ß|ßþÜÛ«x<®D"¡b±¨H$¢îîne2år9i||\ÃÃÃò:;«Zijúý»išš¦©!„§‡åynš¦æõºf™jÝÙY…­œ ™$·6nl€~±³À¡ j’Ü CmÁß¼?Þ½Ë#ˆÿ9>fccƒƒƒö÷÷éì줧§‡(Š8::bmmb±È¯_cšFQ__Îéi‘½½6„=77Í4WÝÙÙqddÄÉÉI£(r{{[Õ‹‹ GGGžžvllÌãããuÍÝÜTØÃ®®àÙY‹‹Y“æêêª O´¶¶¶ìëës~~Þ••ïïïmý„ggÚÕbâX TÚÚÚ¸¼¼¤Z­R©ThY–eôöö2>>Îúú:»»»€BâØ˜"êuò<`ccƒR©ÄÐÐ\__S,éììdqq‘R©Äéé)-ÑS¯CQÌíígj5€…@­V£\.pwwÇÔÔ ’$ ÃÃÃÌÍÍA´A VƒÛÛÏU——U³¦ ½¹¹ñáááI[WWW†f>/..žòÚÄg./+T«³Ÿ5Õòó¼Q]yÿ«³_*À,kŸz6ϲßTÀ‹Öæ‹víg/Øiÿ]†t—mŒŸ­IEND®B`‚routino-3.0/web/www/routino/icons/limit-17.8.png 644 233 144 1456 12573351604 14671 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ãIDAT8Ë­”¿K[kÇ?çÞ“ ÚFC¡ ôNA„– YîPŠK\$Pu(B¡ƒþ™…ÂÛÙlâÐ(w(´ÙÒÍŠ"2¨‹&VÓäœ÷ýÞ!1•–»ù…gø¾ïó|ß|Ÿ亮À ÁÁ?99NIÃÃÒ½{FÃÒ㔹î>·[‡¸tŽæçoäûßµ´$½out$}û&uøÒ’äûßoºùN·‰¸@ã㇚•ªU#)”µF·ÑᡪU£ÙY 5>þH(qQ"2_PV6+I-IVA díϸY“¬¤–²Y ÊÊd|%ÝgÂ[ÍÍIR;lµdƒ@ÖZAÐ kmÝVÐjÉHm=.ÁÛ›?KÊ÷ë:Å‚ëx‰D‚F£ÁÔÔ;;;¬®®211ÁÌÌ 7ð}Ÿt:Ía¥B³Vsyö b±'.ž'",0¿°Àää$WWW“ËåÈf³=¡³³3ÆÆÆX[[ãôô”øýûàº8ž'kÚí^²µc ù|žÑÑQ’É$Íf“F£Áææ&©TŠíím|ßçóî.ôõaÃÐq©×¿P,X€h4J$ X,’Éd¨×ë¤ÓiVVVØÝÝ%ó×ãÇ,¼xaùøïêê ‚œ–—%)”1º¸¸P³Ù”$ŸŸëúúºã-cT«Õ$I­VK''' ~üèÔ-/Kûé³J¥ãì0üÍW·aŒéùÌüâ³ß:Ànêñ0T×ÜmÍÍÝê€;íÍ;w:ÏîpÒþÍ`Gi.œF›IEND®B`‚routino-3.0/web/www/routino/icons/limit-18.3.png 644 233 144 1477 12573351604 14670 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ôIDAT8Ë­”ÏK[YÇ?ï=‰ñYÞÄQè,J6….$‹Ajwº¡š•TèBÿÿÁYÖ½Ó`‹Â.ĵ‹R Ф•.* ³ÊBüA­b«IÞ½÷;‹$SÙzàrϹ÷žsï¹|ÎA€ù¾/ð(™üU°$Ïû¬TJJ§­R)Éó> –Zûü–¢(™ôž¦¦’‚W Ãïš•66œŽŽ¤¯_¥££¦=;+…áwÁ«Öy¯åJ$|uv¢ÁÁ‡‚ŠÆÇ¥jÕJ2rÎê¶4m£jÕj|\‚Šª³%>ÊåÐÄD(ø¢ùyIªKrŠc)Ž%ç~Žöšä$Õ5?/ÁML„ÊåZi¢&'%©aêuÙ¦ƒ¬µŠãXÖÞ} m4×ë²RCÏŸK°Øþ³¼ÂðR•ŠŒä\+sNι[º;³š8W.Kax)ȿü|ù›ff¬þûŒ1¤ÓiX]]%Š"r¹Î9|ßçðð7oßÒÙÑáõ=~lU­vy¥R€ ¤µ5I²­­)mmmi_===šžžV¿ööö$IårYétZÅbQ}¹œ>ZmnÊ@©ƒ(zÂÓ§8ð½ “Éàœ£««‹ÑÑQ*• ×××cXXX ··—¿+çç>ÏžÁƒO:‘Hx˜*ùóõk®®®‚€l6Ëòò2§§§d³Yòù<ÌÌÌpþí¿D^ÈÇ9Fƒ¶XkI&“¬¯¯344Äöö6ÝÝÝììì°²²Âðð0t‡!¥!pÆx>——Ÿx÷ÀDQD­Vcqq‘ÝÝ]2™ …B±±1 …###ôõõ‘J¥È?zDñÅ Çæ&ÁŸ,inN’Œ¬ÕÅÅ…nnn$Iõz]ÇÇÇ2ÆÈ9§³³39çdŒÑÉɉâZ­é77'ÁÒOÎÊå&ÙÆü l›©Ûºs® ±µ²ÿáìàâXí€w ½­£Ü MNÞª€{­Í{í÷ÚÏî±ÓþÜäF9•š/IEND®B`‚routino-3.0/web/www/routino/icons/marker-34-grey.png 644 233 144 2660 12573351600 15623 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“eIDATHÇu•]h“YÇÿÏùÈûæM3q*fÄÐ’Á ŽP±bÁ*´ËôbqÀAX/v/æffYz#Ù!ws³Þ ƒsÝŠ…ÒVÅd>h :4š‹k¥nܨ$FÒíûqÎÙ Ûl«îœsñþyžßóñR.—ú˜¹\NçóùAcÌ·¾ït]× üOƲ,’RþFDc¹\®ÏçY €ÖM¹1FcvJ)/zž÷¹ïû&R"‘c¬ã¨µÆòò2†‘RR(÷}ÿ+"ú7qJ`Æ GQl·Û=±X,8qâËd2dYޕ뺨T*¦X,ªW¯^}î8ΧJ©ƘãG5v !~õ<¯'™LúgÏž•½½½Ä9‡1æ½#„@<§T*Åêõºÿòå˘”òZë1¯ù©S§à»ÕÕÕcÉdÒ?þ¼´mJ)½EÉu(¥‡Ñ××ÇŸ}Ú‰Œ1 ",--áõë×€h4Šø¾cÌ7¼¿¿ÿûmÛ¶axx˜I)AD¸}û6®_¿ŽgÏž¡T*z{{¡”c ÷ïßÇ¥K—ÐÓÓƒ]»vÁƒX,FårÙ¸®û s]×$ rày …†††066†‘‘ ¬­­sŽZ­†©©)D"‘­5Âá0‰¹®kØÛ:°Njœsœ;wû÷ïÇââ"*• 2™ lÛ†çy˜˜˜@*•B$ïûï6 €1ιnµZð}DÆÒé4´Ö¸zõ*>|ˆP(˜ššBww7FFFày¤”ÐaÞn·ÁÓ|ppðB½^§;vP<Çêê*=z„x<ŽÁÁA¤R)ÌÌÌ€sŽùùy!P­VÑh4P«Õ°}ûvtwwcii ÅbÑX–¥€¿ !X¡PÞ¼y¥._¾ŒJ¥Ò©8ç]]]èëëCWW‚ ç|sʘ™™QôV?ð3gΔÖÖÖö¶Z­l­V Ž9”R¸uëJ¥Êå2<ˆãÇcß¾}Èf³H§Ó¸yó&†‡‡‘N§199©«Õ*·mû¾ïûäÙlZëyÛ¶GkµÚGAèÓ§OS2™Äž={ÐßßC‡ˆ¶ ÁÎ;‘L&Q­VÍìì,sç?Zë“Dô/Áži­ÿä8ÎO¥RÉìÞ½@"‘Øb¶‘*çÙl­V ÓÓÓeY’ˆ.ÑïDô3cìk"âÓÓÓ~£ÑAk½e¢6kvv6h42 M¤Óé`‚Eé;|øðE˲&šÍ¦¼víZ°¹]6ïS"Â;wôÝ»wE$Yñ<ïo Œø±cÇ6˜–——RjÞ¶íÏjµZL)¥÷îÝKãiŒc /^¼À•+WŒ”’ü™ˆî‘ €åóùNŒ1Á[ÑZŸwsss¦R©€sÞ‰Ð÷}Œžç1ÎùE"š ×1"ŸÏƒm\ÖõA¾Íf³S¤b±¨WVV„eY¿»®{áäÉ“Ølˆu°xÇx ßF£!'''xðàæææà8´Ö_ !VoܸÁlY¸|óãC|-Ëú¬^¯ÇšÍ¦)—˪Ýns)å_Œc:7…÷zeÓ/[Œ1Œ±Ÿ]×UB.„(f2™ÁÅÅE¦”ÒïnIÿ6øþbŒ³m›sÎW”RYXX€R ÿOÿø¥"Ëj·gIEND®B`‚routino-3.0/web/www/routino/icons/limit-33.4.png 644 233 144 1433 12573351606 14660 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÐIDAT8Ë­”AK[YÇÿï9hx¶>ëPbIÝtYÁ]§¥e¤‚}\¸ ~»löYé–BS?@³sE"˜,BJ[§JÌ{÷þfñ^œvœ¥.œsï9÷Þsîï! I¸®‹ä"‰Tê!RÇÙgtÆÆ ££à8ûH•d_Hnâ'Ô?(•r^¿N!½Åó¾S,Bµjétàô:X/Áó¾#½MìÄ_bpÐehHd³9¤ù<´Zˆ°ÖðãˆõˆVËÏƒÔ ›Í14$]‘N‹BÁC: T¸,aaÖþ;ûk`+J%(<Òé$L©Ì«Wè…WW˜^c abÌÏ$Š0aH=‚¤r?gð¼oöð0¾1q´Öþ'Bû“l£(¶?<Ïû†ôHH[,Dûû”Ëejµõzr¹Ìöööõ!ýW6 þüü ²Å"Hi‡OŸøëôÔŒù>AËåØØØ “Élmm%Fc˜ššâ÷çÏLôþ=H;¿èîÝÇzöLÑׯîê›7J?x N§£ËËK­®®Êó<5›Mu»]IÒÀÀ€VVVÔívõëýû’äòô©äûŽ{†/_øûüœùùy²Ù,»»»c( LNN^‡¾¶¶Æøø8KKK<Ìåh¶Ûpv†ñ}ãF½ž£;wôÇÇúíÉU«Ue2•J%ÍÎÎjssSÃÃêÕj2ÆÈZ«ééiííí©Õj©^¯KŽ#Œqd¥>|àÌì‹ø¾ÏÂÂív›¹¹9FFFX\\¤Ùl233ÃÑÑëëëä_¾ŒsöîH;Bª°¼ …Ý.ÇÇÇ„1˜„ax­[k999¹–/..8‹Ó±¼ÿ朙„3“ ÐÇÀsƒ»„ÇœÅ=†ù¿°ö+€(ÂÞ¨€[­Í[í·ÚÏn±Óþ»Ê®ƒÃfl IEND®B`‚routino-3.0/web/www/routino/icons/limit-34.8.png 644 233 144 1455 12573351606 14671 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“âIDAT8Ë­”ÍK[YÆŸ{4\, Ft BÜL—]ÄJŠ ®DH*ºŠ€Óe²w¥;‡špåBÜi‰F„ĺQ5ÒRirï=ç7‹|Œ™¥ÞÅûž÷óœçy…$$áº.’‹$¢Ñ)¤uç˜X FG ±8Î1Òzï^Hn/N¨Ÿ(u^½Š"åñ¼ïärP,Z./¡Ù„ËË®žËç}GÊ÷ü^¼ÄÐË𰘜L"Õ™Ÿ‡ós„Xk¸{ºzÈù¹a~¤:““I†‡ÅÐ+&&Ä‚‡tÂê*@°Xûôm`«« °°à11ÑS*É`À:Œïš1ƆáO ß'èt0à“É€Tè¿ÙS<ï«­ÕºéMdòó¤=[×ÏÚZ <ï+ÒS!­Û\ <9>¦P(P©TÁõz½½½A—‡‡‡äóyþªVB›Ë´.#Uøø‘ÓfÓŒ>zÄââ"‰D‚r¹ @2™dvvv|gg‡±±1–––xòø1Ÿ¾|1”J„R%¢‡ŸéÅ …­–ûÇÛ·ú%‘Ðéé©Â0ÔÚÚšÚí¶âñ¸úÇ#Ïó477§z­¦†«tZyq#d­ók2©'oÞhiyYÖZ‹Emoo+Nk_gggšššR£ÑÐøø¸677uss£±x\r]9à†¾ïhdD~ø ßž?W©TR4ÕÑÑ‘ffftpp ‹‹ U«Uc´µµ¥ééiíîîÊó<}úüYŠDdÃБ•*¼Ï70¿¿|I,#›ÍÒl6ØØØ “É`­%•JQ.—I¥RÄãq–_¿æ ïÞa¥ŠÖYYƒv›ëëk‚ ÀZ‹1†ÛÛ[Z­ÆÖZ:WWWí6@ÈÊJ÷7ïâÌôpfŒù¾î‚¸3ó?8ë2 ›ðmÀ¿ßO<(†Ø.­|²Ù; ¸WnÞëÖ¸×}v›öon4–„û+NÂIEND®B`‚routino-3.0/web/www/routino/icons/limit-7.8.png 644 233 144 1355 12573351604 14606 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“¢IDAT8Ë­”=K\A†ß¹ÖÍEü\w-D!©ö¸ )íÕÂtJ@A€ Ò4²ÕEAH{;A›Å€ ¦Áà®A"~íÎyRì^£„t˜3óž3óÞs„$$R€$r¹·HŒùJOôõ9zzÀ˜¯H•ö½‚vœPš(—3H†÷ïsH+„á ‹‹ðå‹çô~ý‚ÓÓ–¿¸axƒ´ÒÆ›v¼D6ÐÑ!FFÞ }crŽà½ã©µü„ãcÇä$HßyCG‡ÈfQ,Šé驯ò2@ðX Ö‚÷Wzh°¼ Rééb±MSúÌÌ @Ó[‹}xÀZ‹µïýãÇœsXkqÍ&$ @“™>§5+†¿9:j½ØýcÞûg‰} ç9:‚0üTÊ|”>i~þÿðÁ)øþ㇢(R­VÓáá¡:;;ÕÛÛ+cŒE‘ºººTÖS(8ýüùZûû!í³±A`gg‡ññq&&&0ÆÇ1q“Ïç™ehhˆjµÚ¢Ž öEw·çä$åBÒ¦¹¶¶ÆÂÂÂ#­8Ž&Š"Êå2»»»$''ÐÝí_)P6k$ P&“Q½^W¥RÑÖÖ–R»¼¼T¡PÐúúº...”Ïç%IF’²Y)ä½Q³)IrÎI’¢(ÒÀÀ€J¥’îïïu}}­ÍÍM•Ëemoo+ CU«UI’—¤fSòÞ<Ö pÉÃSSS¬®®pvvÆØØ{{{ŒŽŽÒßßÏÜÜ···à=þYͤ KK-ú-AruuÅÝÝÝ£¶êõ:Fƒóóslׯ',-Tù¯Îžj*Mšž9çði'<ÑÙ?@’¤‚|&Øgû$ùO¼ho¾èÔxÑyö‚“öïZ”åøÖIEND®B`‚routino-3.0/web/www/routino/icons/limit-26.6.png 644 233 144 1521 12573351605 14661 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”ÏK[YÇ¿ïIóâT þ +¡n¬ ™J0mP ‚í¢Ž‹‚ín(þ³’ÖµË‰Ý ”êZÝ;‚,©Š’ Â$t!D0ï½{?³0ftÖ^8Ü{Î=çpÏåsŽ„$\×Er‘D{û Ò*Žó•®.H& ]]à8_‘V›÷Br›qB׉ÚÛ$‡çÏÛ‘ÞáyuáógËÙüøggWúâ"x^é]ÓßiÆKD£.±˜¸ô|Êe„Xk¸¹®ôrÙσôûÄb"uE¿˜õXZh– € kÿ“kX ÁÒHÌÎzô÷7Ë”Þ37‡?h40¾€1† 0æöM4ð™›éýõŸ=ÀóÎm©„K3ЃµöF…¶µ[kiúY[*ç#=hûMúW¯2ÎË—foÏýóãGÅãq¥R)©X,¶tcŒ\×Õññ±þ(DœÔȈ¡\Ž;»»m ¥]Ö×Ù9<4?y“““ ²µµE.—cjjŠññqNNN¨Õjd2fffôˆÓósçOi×UGÇC=y¢ò·oî¯oßjssS©TJËË˪T*J&“Êf³êîî–$mllèððP===Ê>~¬žxÜU&#çÞ½‡n[$‚­×5÷ô©¦§§5<<¬±±1ÍÏÏËu]MLLhmmM;;;’$ß÷¯e³ZûðAmoKÝݲ® ÇFµwp \.§……­¬¬(‘H(‘H¨P(¨¯¯O§§§’¤x<®ŽŽ õööêïJEaŒãšz}OÛÛÚÞß·¡ïk}}]ŠD"J§ÓŠÅbU>ŸW:V.—ÓÐÐ<ÏÓÏ##úåÅ «/_Ôvq±'¤UÞ¼áÂ**M¹¼¼ÄCµZmaR«Õ°Ö†!Õj•°Ñyý¤Õg”JWd79³Ö¶`½É\Ën æœÝê ¾ ìUËÜ‚õÖ9 ¯}|ž=»ÑwÚ›w:5îtžÝá¤ý©ÇE«¬£ •IEND®B`‚routino-3.0/web/www/routino/icons/marker-18-grey.png 644 233 144 2610 12573351600 15620 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“=IDATHÇ}U]hYþΩ[©êŠ¢m+‰´-IÜþ qAÄ€Ô§aÔ‡ma÷AU†ypèúeØÇ—yÝ7!¶DÁD¶AŒ?mµ™²ÆtÒtOB«õsI÷t2²uëÖ­s¾sÎW”Íf±VJ!›Íš\.÷‰ˆü+ Ã]¾ï ÂÇqȶí‡DôU6›ýo.—ã(ŠÀ-‘Z"¢Ed£mÛƒ ø< C‰Çã”L&ÁÌ-Fc ¦¦¦P«ÕĶmêèèÃðŸD4KD­°ˆh)¥T¡Ñh¤‰DtàÀN§Óä8VÂ÷}”J%) ºZ­~îyÞ_µÖDä"bkß¾} [)õs©žžžðøñãöÖ­[ɲ,ˆÈŸ.¥6mÚDÛ¶mãJ¥ÎÏÏ'lÛþÌsUD~µ<?¼{÷nOOO˜Édl×u!" "˜¹µÖžça×®]ÖäädøöíÛ„ëºb±Ø8‚Oƒ 8‘H$ÌÑ£GíæGM‚æ½}Ÿ™¡”‚ˆŽ;f' Á‰ >eù6 C "ÃÓŠª^¯crrráÜÜ>|ˆ/^Àc Ö®]‹ÁÁA„aùVEQ4Ç¥¿¿Ÿ€™¡µFEáÔ©S "”J%äóy¸® ß÷±eËœ‰‰ ¼|ùày’É$ù¾/ü{p¼L¿Í›7ãÌ™3èííÅû÷ï[¤¨T*¸té®\¹‚¾¾>¤R©Öû%V–e™……ömÇ3öíVôP­V!"ð}A`qq¾ï#‹˜Ù°ëºº\.›'Ož´&æcøðáîܹƒC‡!“ÉàìÙ³ð<·nݼzõ ¯_¿×u5øF)Å…B!ªÕj`æV«´÷¦ã8XµjfggóóóX\\Äúõëcccš~Ç¿UWW×w³³³©V«_\»v-Êd2ª}›é>Œ|>ññqcÐÝݽ{÷âúõëæÍ›7–çyOÂ0/¶m€¿Ñ="R4p.—k™:3+fž6Æd<ÏC±X”R©˲ZF†!†‡‡£ ز¬‹Dt€½$#r¹¸¹XÂÿÕ …‚™žžVŽãLø¾ÿõÐÐÚ ±$,VÿIß‘‘‘ž>}Šb±Ïó`Œ9­”zwóæM €´ënµ?|L_ÇqŽT*•D½^—ÇëF£aÙ¶}À°ˆ´tl ËK  í—­D"2ÈÌ?ú¾¯•R–RªN§?yöìk­ÍJÂeéD†¦¾?‰ÈW®ëZ–eMk­ÿñèÑ£e˯‡Æ¯e¼IEND®B`‚routino-3.0/web/www/routino/icons/limit-27.8.png 644 233 144 1503 12573351605 14664 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“øIDAT8Ë­”ÍK›YÆŸ÷-£é›ÌTA::+§qQPDfc$ ³ÑvQpBëÂ7Cñ˜Ð¢®êR²)´›t!ˆÐÁE!SìClWAü¤Hh“¼¹÷7‹|Œ¶[œÅsÏ÷žçIHÂu]$I?#-ã8ïèè€ë× à8ï–q!¹:¡f£@ÀAr¸{7€ôÏûÌÌ <nÙ߇a¿ŽgfÀó>#=iä;z‰¶6—öv‰ÜDÚel Ô°ÖpÞê¸F¡`i—Hä&íí¢­ÍÝÝb|ÜCÚan X||¬ýß›o` ss í0>îÑÝÝSzÊä$ª~¥‚©V±Öâû~Ë­µ­šj¿RÁ@•ÉIž6wÖ‹çm>‹1Xk/_œ´3¦óyð¼"Rï•?¤?yðàWçþ}óïÛ·îZ*¥p8¬r¹¬••år9e³Y…B!uvvÊqmoo믵5ý :Ý·n …«N&sE5)ÃË—¼yÿÞ|ïyÄb1¢Ñ(KKKÄãq†‡‡q‡t: @:¦««‹©©)znÜà͇†/¨IW¡ÐmÅã*ärîïkccC€‚Á Ö××511¡ééi% 5Íó<ŽŽêÇžœ¸ŠÅ¤Pè¶èì4æè€¿_¿¦¯¯d2 Àññ1Ñh”ÖÎVWWéïïgdd„Ÿ"²»»ðéæÚ5# YNOù'›åj Àüü<§§§,..‹Å(•J‹E‰³³³üÒÛËÊÚœáƒVU)ëW>®™™­­­ÉZ+Iò}ÉZÇUµZÒþ¾ÉJRww·^^^T(477§\.§|>¯ÝÝ]IÒöö¶2™Lßqd$«ý}©Z-5U³NH>>>xxxÀZ‹1†J¥B­Vãéé‰ÛÛ[îîîx¹ÖTÍfž…!¦Î§Ÿ¤m’(Ð/žýê°AИ°ß‰k¿ÚêGüioþéÔøÓyö‡“ö?À–ÒxNqIEND®B`‚routino-3.0/web/www/routino/icons/limit-9.4.png 644 233 144 1306 12573351604 14600 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“{IDAT8Ë­”½JkA…×®'á4þ!i„€7VÆÖBD‹Ø„ñâ6>‚6Vvé´³ñl#*$BŠˆ¨øƒ Éù™ïç$×སØ3{Öì½fí-$! c ’Aéôo¤}犱1˜˜ˆǹBÚOÎ…d’{B} tÚArX_O#íàyŸT*ptdiµàåZ­Ø¯TÀó>‘v’x'¹/ẆTJd³3H ŠEh6# ÄÚˆ¯û!ÍfD±Rƒlv†TJ¸®™Œ(•<¤[67z€% ÀÚ¿«¿è±¹ Ò-¥’G&“”)íR.ø„!‘ïQ4œ@E„½„a_.ƒ´ÛçlÏ{§^ ì *‹µöK•_üÌR¯ƒç½#Í iŸ €Ðú>µZ½½=îîî ý,'''ñ~²±Ò¾.8<$‚àúúš\.Çââ"óóó<== ær9VWWãäz=€ˆÃC.ŒFGóZZ’•Œ$ijjJ§§§r]WÇÇÇêÛÖÖ–ºÝ®&''%I8Ž$--I££y#cëÆH’ …‚Úí¶ÖÖÖT«ÕdL|R­Vupp ååeŸŸëþþ^¿FFb±º®d FÖ:òýÁëNGsssZYYÑøø¸²Ù¬:Ž$iaaA———j6›º¹¹‘$YIò}ÉZgÀ™M8ûøø P(0==Íöö6oooäóy¨V«‹E‚nwˆ³¡ßLI·Ûåááa@úóó3A`­¥ÝnóúúË#ŽúÍa…!Q¢¥‰v`ÿÑÙ· ¿‰u¨E“˜ïð£½ù£SãGçÙNÚ?û{åk¨ã£IEND®B`‚routino-3.0/web/www/routino/icons/limit-9.0.png 644 233 144 1316 12573351604 14575 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ƒIDAT8Ë­”¿J+QÆ¿]p–ÿ€Ø^‹hcR[¤°‰XèúÚùÚˆEÞ …ú ‚•`D„\QAYPƒ¢!îî9¿[ì&×à½],Ì™ù8óÍ7#$! ×u‘\$‘ÍþBªã8—ŒÁÄ„al 穞þ’›æ õ€²YÉam-‹´‹ï°±‡‡–ÇGxyÇÇä¾±¾ÿ´›Æ;i¾„ç¹d2¢XœFúÍò2Üß ÆZÃ÷“Ücîï ËË ý¦Xœ&“žçŠ©)±²â#]³µðX¢¢¬ýûõ|`/¶¶@ºfeÅgj*-SÚcu $Ž1aHE3ø0c Qa£â8‰_]i¯ÇÙ,¾ÿF«•EØ~Ukí¿íÌÒjï¿!Í ©Îæ&@lÀf³Éþþ>777ÄI"­V‹ƒƒnooÐ$>fs¤ºÎi40`®®®˜™™aaar¹LA@¹\f~~žR©Äëë+)y†F¤sW££U«²’+IgggšœœÔéé©<ÏÓÑÑ‘$éøøX™LFÊçó:99‘$ÉUµ*ŽV\¹.ò¼IR­VÓçç§–––Ôl6522"IŠãX¹\N’”ÏçÕétÔ?ž'¹.®¬u†}§ÓÑÜÜœ5>>®b±¨n·«B¡  ôðð »»;•J%I’#Ia(Yëô9³)gïïïÔj5 …;;;´Ûm*• ív›õõur¹ÛÛÛ¤oœ t3$Ýn—§§'¬µcx~~Æ3`=tsPgqŒIõô]´=àžÿ:û1Äq_ = ;ù9CÍ¡n¡î³!nÚ?¬§‡…UºÚIEND®B`‚routino-3.0/web/www/routino/icons/limit-11.9.png 644 233 144 1335 12573351604 14660 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“’IDAT8Ë­”¿N[IÆ÷:6öEŠœ‹ÉKH±)RQ¤ "ÈR ¢‰¶3Àc$+žG«(Õ*€„D%D(hi\€´( ؾw~[øÏŠ­8ÒHóÍÌwæÌœïŒãXˆ,¶Œ¢–Ëúôif¹¬QôCØì#Ä2tT,FBäÚZQxo’\Y¯ëçÏÁ“ýõKONú¸^×$¹ÞÎG>X(ÄNLàÌLU8reE[­LM !sÜú8µÕÊ\YQ8rf¦êÄ 1NOc­–?ÝÜTí¨Á^O{= á¿1\Ó vÜÜTøi­–8==x&|puUµ›v:f}‚ªiššew̺]{Ž™v}óFáÃðÏž™$™j÷…î½4ôײ̠!j’\Ï¶ÜØ0hªº³³ãñññˆ<އîïïÛh4üûðP5 õºÂÂW›MÕìÏfÓ|>ïöö¶ªÍfÓB¡`³¿¯êÁÁ³³³.,,øûóçþ“¦™Ÿ>™ÁטÇ_ðêâ(—£R© ESSS„ÚÞÞ•J…ÝÝ] ¥}üóú5aròEL.'…X{û–ùùy®¯¯X__¿ƒ–––h·Û,//³ÿý;ù|=‚86&„ˆnwtx<Š!Ž¢€V«Ååå%sss,..R~ò„jµ í6‘F1ߨÙ“““ýÛ–$ ¥R €Z­F’$´Ûm¼{ÇÂË—/_È]]}eSMÍ2ÏÏϽ¹¹}ø8>;;SõööÖÓÓSC·ÛçmlŒ²Ù×Y?ÍÁ4õÿ,„`6ÐY¦Á{:»S¡×sÜá¸hGó4u «cð µù ]ãAûÙvÚÝ©a1=ÄióIEND®B`‚routino-3.0/web/www/routino/icons/limit-7.9.png 644 233 144 1355 12573351604 14607 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“¢IDAT8Ë­”=KcA†ß¹‚É^wÕRܵ‰ˆX š2•¦Ð:  ?À?°°ånc!‚A°ØÚÖüY\1à‹Œ` ~dî̳ErãŠØ900gæÌ;sÏ9B’‚)@Éä¤-ŒùM*ŽT Œù´Õ9Rй' %“ɰ´”DúN>°º ?zªU¸¹jµm¯®B> }ïø›Î}‰ÞÞ€DBŒŒ|FúÃü<\\8 Â{Çÿ£mG\\8æçAúÃÈÈg ÑÛˆáa‘χHeÖך€ÇZ°¼žñx Éú:HeòùááN˜ÒZÞZl£µk-ÞûîÇœsXkqÖB´X\éGœ³ aXçì¬ýbÛéÕðÞw…=àÛ~ž³3Ã:R¦ç«ôMËËY_(8#ÏÏU,U.—uzzª¾¾>¥Óictrr¢ýý} ~ú¤…µÆ 9U*ttÔ#¤#ööˆÀ2;;K.—ÃÃÁÁÇÇÇŒ‘Íf™šš¢V«Å¿tìít$úû=——q,D0777YYY醹½½ÍÌÌ ÓÓÓììì`./¡¿ß‹tÚ¿âÚ$\__311A¹\îŠU*&''™››#‘H°»»û,V«A:íyoÔjI’œs’¤b±¨ÁÁAe25›MU«UÝßßk||\¹\N©TJ£££’$#I­–ä½ T¯ÿR©$IÞx/I*•JÊç󒤻»;-,,( C=>>jccC…BAÙlVŠ"õH^¥’T¯ÿÒkkQHnooyzzê²'»ÑhpuuõÌ^Û?bm ¤­79ûÖØvœ:ïch_pöªˆ¢ÈB/ÖQôF¼km¾k×x×~öŽö>žj¬Š£IEND®B`‚routino-3.0/web/www/routino/icons/limit-94.png 644 233 144 1261 12573351602 14520 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“fIDAT8Ë­”¿J+AÆ¿]/$QQ+›ˆ(ViV° )´ðÌ| m¬,íì¬-m+ ƒ h%ADÑ »;ó»Åîšxõv90ìÌìùæüûÎ’„ëºH.’Èd H8N\ÆÇ ¹8Né ù/$7Á ¥e2’ÃæfiÏ{c{Ž-í6<=A»Ÿ··ÁóÞv}'ÁK »ŒŒˆÙÙ:` ½9Щ1Ðy6ÀIû0¹xF²ð*IEND®B`‚routino-3.0/web/www/routino/icons/limit-34.0.png 644 233 144 1443 12573351606 14656 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ØIDAT8Ë­”ÏK[YÇ¿ïQ|á5Ö ‹@6B¦0v£vm‡b‘Y!i¶Sâº8ÿ€Óe³s‘•iKS„qïΕÍBH&0BČ鴒÷Þ½ŸYäGíÌ,½pàžsïùuï÷{„$$áº.’‹$b±ïJ8N•D¦§ ‰8N©4<’;ôŠÅ$‡çÏcH¯ñý/ P.[./¡Ý†ËË^(€ïAz=¼ï ý%&&\Éä°M©H6‹ ì÷1A0.ÆCEßh‚€°ßÇB@6 RqôfðýO¶Vd4fؑ˷mÆ`ÁÚZ |ÿÒ#!•l¡W«‹E*•ÊØ¹^¯sxx8® V«±µµÅï@d J2R…ø­Ý6ÓSSäóyR©GGG¤ÓiVVVÆÁ¯®®X\\daa¹‡ù ïÞa¤Š«ÉÉÇzúTQ§ãþòê•òù¼’ɤ¢(Òææ¦z½žfff4Zòïß[ŽŽàË8:ºˆÇÇÁó²HoŠùN±^"v)- wv„tÚÖ~\q@:mi—††;”–ŠpØñ¸òv˜˜ÈßßkÿÝ—g`< í04äŸ)M3<Œ‚ŸÏc Œ1ø¾µö§M¡€ŸÏc Àð0HÓ—vÏûjS),XŒ¹"º$±ÖþŠ/ò¬M¥Àó¾"Ý ý)MñâE·óü¹Inm¹¿{§òòrÕÔÔhwwW‰DBñx\UUU²ÖÊu]moo믷oõÛÍ›NüÞ=C:]îln†H›,,°þ铉x½½½455±¼¼LWWííí´¶¶’ÉdXZZ"‹1::J]M ëŸ?æç ¤MWôè‘Ò?º¼~­••ÕÖÖjjjJÑhTÉdR‘HD‹‹‹’$ß÷åyžúûûU[W§\&ãêáC©¢âAIèÆ l6ë ?~¬ß«ªÔÖÖ¦577knnN’‰D”Ëå$I™LFÕÕÕšÕéé©b·oK®+'µ¾ï¸á°¶vvÔ××§±±1MOO«¾¾^ÇÇÇÚßß×ÞÞž(‘H¨³³S«««òöìÙðÜD"ÐZömH)M¹\&)e/?vìØwïÞóçÏ3)%ˆ?Æôô4ÖÖÖP(`ŒAOO=z„;wî`mm ÅbÐÓÓˆD"4??oÇédŽã˜D"A¶m\×E.—ÃÐÐÆÆÆpñâEÌÎÎbss³³³ÄØØ.\¸€\.Çq¶m#‘Hã8F|Ú0ãœãÊ•+ˆÅbX\\D¹\F*•‚mÛE{{{O§Ó°, ÆQ«žãœëz½Ïó‚©T Zkܺu KKKR‚sŽT*cL…B;ê·Ñh€1¦ùÀÀÀx¥R¡öövŠÇãh6›xþü9âñ8Ð×ׇ»wïbïÞ½h6›ˆÅb8{ö,R©¦§§ÇÑÑÑ/^ ŸÏ˲ð[!Ëårþææ&”R˜˜˜@¹\2…BÐZcbb A\d{ÿþ}EŸô'~éÒ¥âÇ{ëõúWëëëþ‘#G˜R >D±XÄÜÜ:„Ó§OÃó¼ ^*•ÐßߣGbjjJ/--ñp8<ïyÞ74>>RÊâ‡~~êÔ)=<<Ì–——ñþý{ttt ³³3è®×¯_ccc±X ÝÝݘŸŸ7ׯ_§¶¶¶k­aŒy&cÀšÖúW¶mÿ¥X,š®®.twwƒˆP¯×ñàÁß², `œˆž €@Ñ,cìG"â÷îÝóªÕ*ˆZë ËÖZí933ãW«U …n¤Óéß`üÖ ôˆˆ>|øšeY7jµšœššò[FÛÕªå'Ožè§OŸŠ¶¶¶U×u*•JÁŠø‰'ZÓÊÊŠQJý=½¾¾UJéÞÞ^RJƒ…1†·oßâæÍ›FJI¾#¢'D$(`Ùl6êŒ1Á[ÕZ_µm…BÁ”ËepÎ žçarrÒw]—qίÑ r #²Ù,XëfK_ä[«Õ‚#%ŸÏëÕÕUaYÖ3ÇqƱÝ[`ñ™ñ¾ÕjUÞ¾}Û€…… ض ­õ¯…Í™™Àlçη?|‰¯eY_W*•h­V3sssªÑhp)åoLcŽÛ’Âέ°íÈ|cÌIÆØ¬ã8JÁ…ùt:=°¸¸È”RúsÃËÿ†ß¿cÆÂá0眯*¥¾/•JPJáÿé?ØÅSá(4‰IEND®B`‚routino-3.0/web/www/routino/icons/limit-22.3.png 644 233 144 1521 12573351605 14652 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”1H\Y†ÿyÉêäå-NTx&Í[²•.Œ–[©)ÄB5ÚiÒ˜tK°I\!é¶´Š!¬ ¤‹TÚdmV&b$Æ`3êÀ*2™Åyoîý¶˜1«në ÷¿÷ü‡{ÿ„$$á8’ƒ$âñŸ‘fˆÅ>‘H@c£!‘€XìÒLí^HN'tZ(!Ÿ?Žô×ýÆø8¼{gÉçáàòù*×ý†ô¼–«ñ%êêêëEÜFÚ¢¿r9T°Öp6ª¸B.gèïi‹ ¸M}½¨«s„ï‹TÊEúÂÄ@°DDXûß:= ”™˜é ©”‹ï×¾)½`paT.cÂc QaÌùš0$*—128Ò‹ÓžµâºÇ6›Å‚¥F<[ÀZ‹µöû¾–P…Ù,¸î1Rë•gÒï<|økìÁ³¹¾îüùö­\×UKK‹666´°° Ïóäû¾¬µrG™LFó¯^©þêÕØ­;w ¹ÜµX:}E)Íâ"ýj~t]ºººhkkcvvß÷éîî&Òé4[[[4662<<Ì-ßg5“1,.R‘ÒŽ<ï®îÝS.“q~{òD+++J$ZZZÒÓ§Oµ¼¼,Ïó´¾¾.I ÃP“““QËÍ› uuIžwWܸaL¡À_>L&`uu•d2ÉØØØ¹‹Eø)ø¸¹ ¥¦¡ÁÈxžå舟?s-gjj c kkk¸®Ëôô4Åb‘R©ÄÑÑóóó´··ðKk+s/_ÂÉ ÑõëV¡”æý{þxýÚüà8tvv½½½477ÓÑÑASSsssôôô°½½M__ ¥Rƒáͬ”Ò óT »»ìîî’Ïç9< ”Ëy¤aøÌÚìíynoáé noS}m Âð©–áƒÌ_"—3ôôˆááQ¤Kæçáú:Þ'ü.©î¸¾N˜Ÿé’ááQzzD.gD¿XX‘šT«mÀc-X ÞœŽ <ЦZ©ÉÂBHÖ¦Tgi à çÀ9’$ÁZK’¤Å}Ò3 ðÆÒHõΛM†-..ÒŒÎáù,€ÝzHmž‹ ÃÒ„¶¨TÖ¦@ ÙlR¯×9>>àôô”Z­ÆùùùGÀ´eG¥Ò–Nh4ÒÞÞ¸ºº¢P(°¸¸Èøø8ŒŒŒ°²²B±Xäèè(­¸ÝHh4@:1Š¢i•J’ddŒ$É9§ÍÍM-//k``@¯¯¯ ÃP³³³ÔËË‹”r3õ+•¤(šþ.cP.H’É‚ihhH«««z||”µVqk{{[ŠãX’$I¹œd "Š<77¸¬ÍÝÝ]¦¦¦(•JHb}}€ÉÉIvvv°ž›ˆ"oÔjýÔÁ$y“eš››S__Ÿ¢(R±XÔáá¡ö÷÷DZfffT.—%IßR¼×ÁÔjýüò›±ÖrÍlív›»»»w=}ùÍÏï!ðý_,-ÁÖ–åúj5¸¾nñKKàû¿ ±½ûK$“.bh(‹tÊì,\] ÂZÃkjñWW†ÙYNÊÒÙ)’IW й9é++` CC°öÏkËÀ++ ý`nÎgp0.S*²°Ð$Šˆ‚c-ÆÂ0Äó‡o4°ÍfË~a¤b»g£ø~“6d­}ù·½è¢ –“ðý:Ò¨ÖX^ˆâl”ËeÎÎÎ888 P(P©T8>>fuu•óósâz#–—AZÒ>_¿Œass“ŽŽ¶··ÙÛÛ£§§‡ÅÅE†‡‡ÙÙÙajjŠññqr¹?«Uc¿|ißUw÷GMOK’kAŽã¨¯¯O’d­U*•ÒÌÌŒr¹œJ¥’R©”ŽŽŽ”N§µýí[ËïÓ'©»û£+×EÉä‹s>Ÿ×ØØ˜U«Õ400 õõuU«Ue2yž'IJ§Ózzz’$‘HH®‹+k5›zMÆyž§R©¤ÉÉI•Ëe% ÝÞÞêááAº¼¼TîÃI’E’µŽ«zýPå²$YY+IêêêR£ÑP±XÔîî®úûû522¢ e³YMLLh~~^Ÿ[í±ß¿Kõúá›iÆ€äþþžççg‚ àææ†0Öc¸»»ká®%{3Í78#Šþ‹«öÿ¼aø_œý³öUÀ6xßðaHœô¯ x×Ý|׫ñ®÷ì/íoi†k˜iÂ8PIEND®B`‚routino-3.0/web/www/routino/icons/limit-30.4.png 644 233 144 1433 12573351605 14654 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÐIDAT8Ë­”ÏK[YÇ¿ïáøìÃàP\ nâ:mIfSB’õÔMüÁítÙì\d—M›B.»˜?@QÍ,‚ ¡‰¶¦bÌ{÷~f‘£ãÖνçÜï¹÷Üï9B’p]ÉE‘ȯHç€h¦§ Ñ(8ÎR¡ï’Û?'4ŠD$‡l6‚ôÏûI.Ÿ?[ÎϡՂóóÞ:—Ïû‰ô®ïôÏKŒ¹Œ‹Xl©J*õºB¬5Ü•Þ:¤^7¤R U‰Åfcc®˜™++Ò1ëë·€% ÀÚÿt°¸e}¤cVVéy"¡J¥¢ÑÑQ5›M]]]©V«éììLóó󺹹‘$-//k_õz]GGG’ãcYi¹óû«WD£QÒé4ív›ÕÕU&''ÙÜܤÕjÇi4‹ER¯_÷jöþ=H{B*°¶Fƒ GLŒ14›MŒ1C{À»ëëk.¿}Y[ëýæ]ž™>ÏÌý?ç†Òó=àY¯2€® èrH…vBbtÀ£öæ£NGg8iÿ)˜é}½IEND®B`‚routino-3.0/web/www/routino/icons/limit-66.png 644 233 144 1272 12573351602 14521 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“oIDAT8Ë­”1KcM†Ÿ{…®‚&F,#»XlçÖCº€ )ÜÊ>ùþŒMo-‚•ûì,,,’…-V4(XAÛlrï<_q“U¿u; Ì;3çœygÞs0Žc!°Xü(E?\^Ör9syY£è‡p8ÝGˆ§~È,P± ‘_¾…¯&É/Ûmýö-øð Ã¡><ä¸ÝÖ$ù%|ž¦þ`¡;?ÕêáÆÝ]½»ËÔÔ2_ZŽSïî2wwn¬V?8?…BŒkkØj%ÂOT«ÁÉD' áyÌÖ4¨¿=8Pøi«•¸¶6¥ ]÷öTÇN&šef!8ͲürY–=ã4͇ŽÝÛSèÎÞì“I2òú:Ϙe† !¼`÷?¬³`ÁëkM’‘ð áÐNG5u2ùã4 ìv»öz=Uonnìv»öûý? ¦”S;…C„ž''ªYÈ7‡nmmÙl6m4öû}†ÍfÓZ­æíímN}˜e©• Îͽ¾»±¡A-1ø'úréÅEpcCá»sso­T0ËRœ™ÁÍÍ\øæÞžê/5ZZãï5ÔiT¹·§ðÍÍÍÜ™™A˜ðÑímÕžE¡!X–¥!<}XÁ¢(ŒE¡eÙ·ßÞVø8ÌÙ;ó¼k»Ý¿±,-ËÒã³ãHc4öEÛmÍó®ðáÀÝ]ÕÒ¢Z­–§§§ª–}¢ívÛýý}ÏÎÎúN{½>owWáá³Í¦jäÃÃÃC³,³Ù׫z}}íÒÒ’‹‹‹Öëuïîî$/Øl*|N™œ|Ïê*@ÊØ1F’$azzš#CS©T899¡V«qtt@€”ÕU˜œ|Ÿ’¦’e#RŒ‘F£ÁÂÂ#}Y–LLLP«Õžœ‘e¦¦Ä˜ÐëñÃt:fggét:\^^r~~N½^ èõ Æ$¥ÛýB«ù#¬<Ï`}}••–——™ŸŸgkk‹µµ51ˆ´ZÐí~yñ›CÜßßûøø¨êÍÍ!CÞÞÞþ®¿¾ý“ß|QgCŒqä$„ðÏ:{Úe©ÏŠöÅ~`ó²^µ7_uj¼ê<{ÅIû?@$e? ÂuIEND®B`‚routino-3.0/web/www/routino/icons/limit-32.2.png 644 233 144 1530 12573351605 14652 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ IDAT8Ë­”ÏKÛYÅO¾Bâ|Ml*e‚1ÒÁE±»p5‹"¸èfD4uYÛ­¸PðFB»qå^J¥êRB]¸ˆ¦Vé`Ç… * V©?Óä›÷>³Hœ*Ãì¼páÝûÞ½ï½Ã9WHBŽã 9H¢²ò¤ |¾„ÃPSc‡Áçûˆ4QÞ’S®ºhTYéCòñøq%ÒK\÷”¾>x󯲷°·WŠûúÀuO‘^–ÏûÊõ~¿C âñ;HŸéè€tÚE¬5\¶R\$6tt€ô™xü€ðû‰ˆÎNéÃÃyÀâyày`í¿Èò ƒô‰ÎN—H¤üMéÝÝ(xù<¦PÀƒçysõ¦PÀËç1P »¤W˜ÝÅuìæféÆráåÖZ¬µWׯ`ÁÚÍMpÝ#¤»¿K#<{ö«ïéSó×úº395¥€ß¯h4ªµµ5MOO+ *‰ÈZ+Çq´¾¾®?§§ |‘{÷ éôO¾•• i…™þ>8057nH$hlld||œÚÚZÚÚÚˆÇã$“I–—— …B´··¯«cu{Ûðö-EiÅQ(ô@ªøí›óÇȈzzz‹Å´µµ¥¡¡!-..* *•JI’¶··588¨……C!¥Þ¿wô葨ªz nÞ4ìïpr|LWWõõõlll°ººJSS½½½cþÅmii‰ææfzŸ<Á|ýŠ ‡¼ª*K.ÇÔë×´Ü¿@kk+Äb1FGG999áüüœL&C2™Äu]ÆÆÆ8>:ÂØÝ…êjëTœ¥47§ß ûó­[ª®®VKK‹¢Ñ¨ö÷÷5;;«††MNNª¿¿_óó󒤙™Õݾ­¹wï¬>|Pñø8%¤ ž?(zß¿“Íf)‹är92™ ;;;ìîîrvvÆáá!§§§d³ÙRþËrPäÅ ¬4q…g¦Ì³Ëøü¯•xh¹Ä³ H$ Öó X¼BÐË„°žWòÿ(àZµy­SãZçÙ5NÚ±Ž7´'{1IEND®B`‚routino-3.0/web/www/routino/icons/marker-11-grey.png 644 233 144 2331 12573351600 15611 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“ŽIDATHÇ•UAhWþþÿ½73;âa²”ŠD6‘ăn@rÐ^$ÑS17A/Í¡=¤•âE¶²—ÒƒõÒk% ‰=¨¬‡lmYˆP’=¹6¤±Ñ°ÛÀ&™yóÞë!Ùé&¦…~0Ì?¼ïÿß÷¿ÿ •J%ì‚¥”(•J¶\.ŸwÎ}«µŒãØ üçû>)¥~#¢¥Riº\.sš¦`€vE…sÎ8ç>TJÝI’ä²ÖÚEQD…BÌœ)Zk±´´„F£á”RäyÞ„Öú "ú“ˆ#°sÎè•RV[­Vo>ŸOGFF¸X,’ïûØ8ޱ°°àªÕªY__¿†áGƘçÜïDÄâܹs@·”ò×$Izûúúô•+WÔñãÇIçÜ{”G¥“'OòÚÚš~÷î]^)õ±µvÊ9÷—¸xñ"|¿¹¹9Ô××§ÇÇÇUpΈ@D`æ,&ڱ׃0 188(õ›7oòA|Ëå~â$I.$Ir5ŸÏÛ±±1 ½³.9RfñØØ˜Êçó6I’«I’\`çÜ-­5†‡‡E¬µYEÍf‹‹‹™X;Y›gfcE†‡‡¡µ†sî§iz&Š"700ÀÀ̰Ö"ŽcLNNbzzzOç÷óí pE.MÓ3DZ+ ”Ëå`ŒÔëuܾ}õz‡ÎÄ·“år9 ŠãØñNq¼'ë±cÇpíÚ5ô÷÷ckk+[üo|6=;:,…vccƒµÖPJ|ß3C)•Uo­=ï,¦Õj™-A`êõºŸŸÏÿ´›÷úõk¼zõÊA`À×RJ®V«i£Ñ3gG¥}F÷£“'"h­ñèÑ#C;ø9òçy?®¯¯Ëû÷ï§ûÇq{{ûÀ1mó̌ؕ•áyÞ¼Öúº8}ú4¬µOƒ []]í2ÆØ'NDQ„ÞÞ^tuueU¢(BOOººº077ç?~ÌanYkG‰èÉÌÀеö“0 ®Õj®»»Åb7Tçdõôô€ˆ°±±J¥’zž§ˆè&½ @ @Ñfþ’ˆÄÇu³ÙÌá æ@¥RI†ò<ïî©S§¾ÀÒv4ñÙ³gïø¾·Ñh¨©©©ô Ù·Ö‚™133cŸ={&:´œ$ÉW³³³Y2144ÔÎNKKKÎó4‚K«««ycŒíïï'cLv*˜o߾Ž{÷œRŠ|JD3D$àr¹œÁÌ’™—­µãa¢V«¹……!²‹Fk‰‰‰4IBÜ!¢»Ô®(—Ëàv°‹ÿôªÕª]^^–¾ï¿Œãøæèè(:±k,ö ¿çïääd ÏŸ?G­VC†°Ö~.¥Ü¬T*€ëô]t~ä¯ïû—ÖÖÖòÍfÓÍÍÍ™V«%”R×L8ç2;ŠÂÞÖèøeK©sn˜™ŸÄql¤”BJY-‹ç_¼xÁÆ»_pÏö°¡íï/ιA!IJ1æ³ÙÙÙ=·Ô~ü ùR{”öü¬IEND®B`‚routino-3.0/web/www/routino/icons/marker-91-red.png 644 233 144 2046 12573351601 15431 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“ÛIDATHÇ••¿kTYÇ?÷¾wgÌB“b‘y!ˆ[Eü¢©Òجil5b‘)„í¬SlšÀì$ú*{‹DE°P‚2#8ÕJ$ âÆ¼_ß-Þ}ÉdÂâîáÎ{sïçó}ßsŽÂž:uÊÔëõ+ι7€€Â¯¼vν©×ëWü9[Œ_ ~qέeYvM’ÆÇÇÍôô4Î9Š¢ÀZKš¦¼xñ‚¯_¿ÊcÂ0ŒÓ4]þà>á\]@Íf3ÝØØÈûý¾Š¢Ð`E¡~¿¯¼Ùl¦€ü¹sUÅUÆQŸÍÌÌ$NG’”ç¹Ò4=ñÉó\’Ôét433“xð' *±Ö†á}@­V+©`ÉÁŠ$‘²LÃQd™’?”û*Z­V( ÃûÖZ¨Õj €¢(ʻݮ$)=88Nñ™~÷×išJ’ºÝ®¢(ÊÕjµÂ0|h}}=—¤4IÊÃ;;Ò½{Ò³gGÐJßNGzúTƒû×××sŸí+€bll¬ØÝÝ-ÏIÒæ¦ÒéÓåzãF Ûß—öö¤ÙYi~¾Üï³ÝÝÝÕØØXá-G¾¸¸(IÊŠBJi|\ºu«moKA }þ,mmI££åƒ®^-Ï2e^÷ÅÅE¹¬sYß¾Áädé‹fò^¾„¹9øð¦§aoï¨m$<dž@Ñëõìþþ>#µÁܾ wîÀÖ¼_,Šr={FF M™Æ–Öüòå @a­µùëׯ‹8Ž!È‹îÞ…ÕUX^†zFGOdgÖZžõ÷®--¥~¶Æ“““A`Œ0 íÔÔιØ—Rß¡RõûÚÚZî½Ãé40öº9纀Úív©¯ïïªì5µö·á²‡ã¤¾q|,CoŸÔ?Œ1ŽŸÄ1}£(Jª‘(Iív»*{h,//þ-ý{ ë;ëýÇq90¬•1æ²ßü8¬o†]@KKKÅÅ‹«²Û¾ìð¿é \2ÆÈ|†[çÏŸ' Cû‡úúõN²Öö€_‡ª9ÿ xsÐ|-/IEND®B`‚routino-3.0/web/www/routino/icons/marker-71-grey.png 644 233 144 2516 12573351601 15625 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“IDATHÇm•ÏkTWÇ¿ç¼{g^Þ ÎË,*AÍ8ù!ZÁt#"Ä]Iv‚n!]¤ ÅLe–nê_Ðe‰ÂD #؉­€1‰QÔhJ ihb2ÉÀLœwß½· 3ÓLâÜ»¸ßsÎçœ{¥Óil‹…H§Ó&“Éœ³Öþ¢”ú²R©X„ÿe£Ñ(I)'‰èj:þ#“Ép†`€¶Mk­¶Ö~!¥¼Á¥”õ}Ÿš››ÁÌ5Gc P(¬”’"‘ȰRê{"ú—ˆZ`k­pD‘/•JG‰DØÓÓÃF±[•J³³³6ŸÏëµµµ žç}¥µî±ÖþMDìœ9sÆ8(„ø+‚#GU/^”©TŠǵvÏ'„@SSµµµñÊÊŠúðáCBJùµ1fÄZ»É±X RÊår9™J¥ÔÀÀ€Ü¿?Â0„µ¶–™k(Â0D<ÇÀÀ€L¥Rª\.'¥”7b±8‚óA\J$¦¿¿_V „5fѧ^U !jëþþ~™H$L—‚ 8/¬µ×•Rèîî†ïûPJannaÖ>|ñxD„B¡€ÍÍM$“Ih­áû>Ξ=‹‘‘H)¯‹0 Oû¾o;;;´Ö¸wïÊå2Ǭ¯¯cppñx[[[Èf³ "\¾|¹¸³³“ÇÆÆl©T:-*•ŠmkkcÏó`­…뺂1®ë"›Íbssíííxóæ FFFP,qòäɺ1khh@ss3=þÜ0®Â¯2’RÂu]ÌÍÍa~~}}}€C‡áÊ•+hiiÁÖÖÖžQÛöaá8Ž)‹¬”‚”²®ã=ÂñãÇÑØØXËœ™!¥„Öºn2 T*™ »®«ß¿offfPeJDxýú5VWWÑÕÕUwp·¬µ "ÌÏÏãÝ»wÖu]Í~Bp>Ÿ …„€ÉÉIÃÃÃaì8ÎM"º@ncD&“WÛÚÃ÷Áƒjcc£6—ù|Þ,..Šh4úªR©\ëííÅNClƒÅ.ã=|³Ùl/^¼Àøø8<σ1æ;!D9—Ë9êºéìÜ|Žo4í[YYIlllØééi]*•)å€akm㎤°çBïøe ¡µö,3?®T*Zá!òç^¾|ÉZk³Û°®üÏ`¨òýÓZ{Õu]ÇqœE­õ·SSSu¯Ôný3ÆŒ¤;õıIEND®B`‚routino-3.0/web/www/routino/icons/limit-33.2.png 644 233 144 1505 12573351606 14656 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“úIDAT8Ë­”ÍKÛIÇ¿ù¹$îϵI¥lˆ#î©õ…õ¼HÁ—“¬×n{±½yðXÌEhÏzÈJ¥xóVÐC.šÒ€Å¤ m fSm2™ùì!ÑÖõêÀÃðÌÌwfž‡ÏóIHÂó<$Itvþ†´N ð–Hzz,‘o‘ÖÛûBòÚ:¡‹‹:;H:‘žâû5áåKG©• ”J-q|¿†ô´}>ÐÖKƒ¡H$‘Þ3; Å¢š8gùq´ü&Å¢ev¤÷$ƒ„B"ôD4*’Ié€åe€:à0Œç¾ÛÅ8 Îò2H$“>Ñh;LéóóXh˜zÛh`­ÅƒµW?h L½Ž…óó =»ÈÙ]|ÿÔ¶^l sÿ‹Ð]ÎÎ9°Î‚ïŸ"Ýíø[Jóèчí»|ÞËll( *ëàà@™LF¡PH½½½rÎÉó<åóyýóü¹~ …ÑáaK±øs`o¯CVÚcs“•Ší ‡I¥R ’Édèïï'•JÇÙÙÙ ›ÍÒÝÝÍÔÔ‰¾>ö?~´¼zESÚûIÝÝcº_Í/_¼•tZÑXL¥RIgggZYY‘ïû:::R½^—$ ---)NkøÞ=åvv¼±…ÑÕ5&nß¶|úÀ¿Õ*sss$ r¹ÖZ’É$ìïï_æoww—‘‘þzð ðù3.±2]]Žós6^¼à÷ÑQÆÇÇ™˜˜`rr€¡¡!ÖÖÖ0ÆÍfñ}ŸÕÕUª§§€“¸uËy_¿æ´µ¥?S)÷ë;ŠD"ŠÅbÊd2 ƒ ‡ÃÕôô´fff´½½-IÚÜÜT_o¯¶^¿vzóFÍj5'¤u?hšoß(—˘˜c.}ç•J…Z­F¹\æøø˜“Bshòä NZ¿Â™msfÃZ{ «µöwm?pö½R)€†3šÍk°^ט–]«€­Íí7ÚÏn°ÓþõéŠ•Ž ÝXIEND®B`‚routino-3.0/web/www/routino/icons/limit-72.png 644 233 144 1320 12573351602 14510 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“…IDAT8Ë­”¿J+QÆ¿]ÑÄ1$ BÀ[‰úÞB}h¡uÀB Õ…‹ (6v"v [#ر°P£¨ˆD$âîžó»Åf½z+ çß73ç›33B’p]ÉEÉä¤ ç„T ÒiC*Žs‚´Ñº’ÛÒŠ %“’ÃìliÏ{b~þü±\]Áý=\]Eûùyð¼'¤•ÞiéKtt¸$"›D:%—ƒós„Xkx;¢}Èù¹!—é”lvDBtt¸"“ÓÓR•Bà°XûOâ3°À …HU¦§=2™Mi•™Ÿ0ÄÁ±ÖbŒ!ð}Œ1†‘€ÏÌ H«q̆ð¼µZä1ýÇÎb­}¿6&Â×jày ¤¡¶_ÒoÍÍýT>oð}×io×ÙÙ™¶··U­VU©T”N§u}}­­­-uww+“ÉIŽ1ŽúúŒ..:U*µ ©Ä΀ _^888`llŒ‰‰ ºººXZZ¢¿¿ŸÉÉI²Ù,årá ;; •DO¥^ù¶¨®¯¯S(Øßßgqq€ááa677|?ҫס§ÇŠÞ^ÃÝÝ«±86···ŒŒŒP©T8<}`[3wwÐÛk>¼,ˆ¾žµµ5ÆÇÇ8>>¦³³“ååe_11“øe®²ŠEI²²VŽãH’ŠÅ¢¦¦¦$IGGG ÃP»»»ÐÞÞž$Éø~¤W,JFYH,,„懚Í&Íf“››.//©×ëv7².÷ž{Ï9<çÜç! I„aˆ"‰dò6Rž (107oz JHùö»Â¶ŸP'P2 <~œDzN}'—ƒ×¯z¾~…z½¥çrEß‘ž·íƒ¶¿D"ÒÛ+Òé¤ Ù,T«p˜yþ--ÝQ­z²Y*¤Ó#ôöŠD"CCbf&BÚga q q fÿ¬ÎÐ`a¤}ff"††ÚiJ/xø͸ÑÀ7›]0Î9¼ÿ/@œÃÇ1šPSÚåí[~{õÊÿ†LNNÒ××Çææ&ÓÓÓ¬¯¯0>>ÎQ;‹ÕÕU²´jöò%H»BÊóô)gàŽj5jµ‡‡‡œŸŸpzzÊÅÅÇÇÇÄqŒ™qvvÆÉ—/Ž'OZ¿Ùáår‹7?ôÿ¤ew…gÝ0hZcm t¸uåì8‡]é€kíÍk×:Ï®qÒþ áæ³?‰«ÇIEND®B`‚routino-3.0/web/www/routino/icons/limit-11.2.png 644 233 144 1324 12573351604 14647 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“‰IDAT8Ë­”±K[QÆ¿ûJb|i$E(B :8ô/pQé$‚v ´[ÚÍÁ?£ÁÝ@‡Štpq1ÔIˆVAAhƒ´)h HÞ{÷ü:¼$MíÒÁîwî=çžsïwŽ„$‚ @ D.÷içŽ(axØS,‚sGH«}!?¡n \Î!9^¾Ì!½# [T*ðñ£qq?ÂÅEŠ+ÃÒ»Îy×ñ—ÈfD©ôé”ÙYh4<`æé—'4žÙYN)•ž00 ²Ù@Œ‰¹¹阥%€6`Ä1Ä1˜ýÑ® h³´Ò1ss!cc2¥÷,,DI»OH’ïÿNÐGq»‡ˆùyÞwßìaxÃé) ˜Ý dfw*µÔæ=f''†7HÏ„´Ê›7$µZ³³³žs?îfxxxÈòò2Gûû‰U* ­ ©Nµ à?T«d2Ö×רV«d³Yªé>{{{ ¦¦¦(³ÿõ«gs“Dªz®ÉI™¸4::*@’äœÓÈȈÌL]i4Z\\Ôöö¶ :øü9Ћ"Ÿ.=òüøA÷¥¦§§Y[[ëeÒ£(`ww—‰‰ ^¿z…h6±bÑ2sŠ¢ÞÍýYt±sN’tuu¥z½®™™•Ëe­¬¬È$©Ý–3snnT«IJíù|^™L¦, C Ê{¯r¹¬­­-I񮮠Æ?Ö§Ó—/J~ý:èý&à=×××ÜÞÞöÊìÇÍf“V«Ååå%ççç|ÿö[Hxûëüfʳ““”ÙIÂIJãÏþê‹cúö“¶»¶8NõŸ¸×޼שq¯óì'ío3%ý„ŸQhIEND®B`‚routino-3.0/web/www/routino/icons/limit-7.1.png 644 233 144 1330 12573351604 14570 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”1K\YÇïÍ:ºA'ÑX*ÙJ°Ië ¢¥L1©)ôø¶LjëaÀ"ÀÎA,%pÀ‹°Pƒ3ÔÌ{÷þ¶x£q·óÀ-î=ÿû¿çœû?Ó4RGFþ¶L’OŽë³gÁñqM’OÂÖÀî!wD##‰øúõˆðÎ,ûæÚš~ø=;Ó¯_õì¬Ü¯­i–}Þ ðÉà>X­¦ãôôKᳫ«zzÔƒ­ÜžžWW>;=ýÒáa¬VSœšÂz=:nl¨~W£y®y®1þXwgÕïnl(t¬×3§¦iÂ{ Õ~ÌsóÛ[ó<7ÏscŒÿ ®( CžkQ¨öm4ÞßÕlÖ,ëy|\¾X‚µ¢(~—¸èñ±fYO˜­üóöíŸñÍ›@úÏÉ Íf“N§ÃÑÑ£££Ôj5BT*ö÷÷ !P{þóª¼üE———ÝÞÞ.#ë÷Ëú]\h­RbLè÷!Ðl6™œœdvv–~¿ÏÉÉɽï>ª‡ÖïCŒIJ¯÷‘v &`»Ý¦^¯Ðívi4ôz=²,chhˆ3@¤Ý†^ï#–ëëªÅ@^]]y}}}Ÿâåå¥aP‚n·ëÍÍM™^‰/\_WØú_ý,ÖGD÷‹Î~é‹Âø“pÇK¢G;àI{óI§Æ“γ'œ´ÿ´ez¹´ÛˆÑIEND®B`‚routino-3.0/web/www/routino/icons/limit-10.9.png 644 233 144 1437 12573351604 14662 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÔIDAT8Ë­”ÏJ[[Æ¿s“ô„„´"Îr3°¡béÈAA':¨ÕÌÊÅð1ÚIpàX®¥¹ä™–Æ EET®)(zˆ9çìýë ZÛ;tÁ†µöÞßÇÚ{}k IHÂu]$I¤R!mà8_ÉåàÉC.Žói£w.$·‡ê¥R’ÃÊJ éžwK¥Ÿ>YÎÎàûw8;ëÆ• xÞ-Ò»Þ}§‡—H$\’I1>žG:`qNN a­áWëÆ''†ÅEÏ“LŠD££biÉCúÆÚ@°„!„!Xûsõ÷ÀÖÖ@úÆÒ’Çèhï™Ò{–—‚¨ÓÁtcÃkí½Mv:xó¤÷ý?{Šç]sp@Ööˆ¬µ’ÿõÁ‚µûûày×HO…´Áê*"€z½Îáá!{{{¬¯¯stt4È`gg‡jµÊáþ>@d+6„ô™ÍMóÏæ&ñxœ­­-¢(brr’©©)&&&hµZìîîR(˜™™áù³güE†1ÒgWÙì ½z%+¹N,¦ááae2Õj5%“I5›Me2mooK’†FFFÔh4”xôHÿ~øàêõkÙtú…«X %²’VÊe‹EµÛmYk•N§%I™LFNG’4??/ß÷µ°° fSCCCR<.¹.®¬uê  466¦‹‹ žžêøøX…BA777ò}_ÅbQsssÊ=~¬|>/ù¾p\]_Q½.IV’²Ù¬Úí¶J¥’¦§§U,U.—U*•4;;«t:-ß÷U­Võ÷Û·šyùÒªVSìööË š@„1\]]Ñn·ÕkµZc0Æpyy ÀÝÝçççØ èâVWÕìê¬[fK ôÔ—‚1æžÎLOg,¿éì^Ø0¤OØÿáG=q,/ÿÒÚ›:5tž=à¤ý5n±¯¾º÷IEND®B`‚routino-3.0/web/www/routino/icons/limit-92.png 644 233 144 1304 12573351602 14514 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“yIDAT8Ë­”=K+Q†ß]üÛä£A xm¢`,D„`K±2ùù !X¤, Aìó.Ñ ˆU4 BM6{ž[ì&W¯áVœbΙygæ=3#$! Û¶‘l$ ýB*bY"ˆÅ<"°¬ R1x’ø B! Ébw7„tˆã¼‘ÉÀÅ…¡Ù„×Wh6}=“ÇyC: ì­À_bjÊfzZÄã H÷¤RP¯{Àc<>‹¯¨×=R)î‰Ç˜žSS¶˜™;;R•\ \\Œù{†w`€¹HUvvff‚2¥#Òi€>ƒ xž‡ëºxžŸÜ=°ú¤Ó  9Kà8j5?¢çaŒÁ3ªnèW¼ùw†Z §ƒ”R‘l`€ëŽ@noo) <<<pssC>Ÿ§R©Œ@ƒ’d³ …ô›³3?~€»»;I&“¬®®r}}M,cccƒxÀòò2§§§_ìi4 6"õhµüH>©<>>²²²ÂÖÖ“““œŸŸS­VI$ìïï84C.[-ˆF=[ÆXê÷õYºÝ®–––´¾¾®ùùyµZ-­­­iooOÇÇÇ2ÆH’,Ëòú}ÉËV§SV©$IÆIÒìì¬Úí¶ …‚411¡v»­ËËKÍÍÍéêêJ’äùI•JR§Sþö›Cùøøàùù€n·ËËË OOO4 Þßß}£1¿9¶Ï>7ëXñùýÖgc'`ÔKÿ4«1æ?ð£³ù£[ãG÷ÙnÚ?v½Pc$RIEND®B`‚routino-3.0/web/www/routino/icons/limit-198.png 644 233 144 1373 12573351603 14612 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“°IDAT8Ë­”?KcAÅÏ›•$>ÿ%¨APv«€…bc¥`‘ÂBMe¯À‘mÁÊn]°X[«€4Ä•ÅÊ"AðÁbòòÞ›ßy‰º»¥æÌÜ{fî̹WHBÆ$ƒ$R©/H{8Î/`h(b`çÒ^¼/$Ç uˆR)É¡PH!qÝßln–Z žž VkãÍMpÝßHŨ߉ã% C2)&&>#ݲ¼ ÷÷bmÄ[kãûûˆåen™˜øL2) #FFÄÊŠ‹tÍö6€X‚‚¬}5°€Ïö6H׬¬¸ŒŒÄiJ_Y_h†„¾Od-QQ½âf“¨Õjû¯¯ƒôµóf9\×ãæÀ†¾‰¬µÝy‡¨kaˆËÍ ¸®‡”Ò[[¡mŸF©Tâîî€ËËKvvvºøââ‚b±ÈÕÕq¾![[ í ©Ê÷ïQÄáá!===Q«Õ˜œœdnnŽùùycccƒññq*årûÂß¾T5êïŸÑ‚$ rGÃÃÃêííU¹\V&“Q¹\V2™Ôññ±FGG•Ïç•Ífõâû’dXXúûgŒŒA‰„$ÉZ«B¡ ©©)Õëu---éååEù|^ÕjUžç)Nk_J§Ó’$'‘ŒÁÈZG­–ÞšµVÆ5 år9-..*›ÍêììLÓÓÓ*•Jr]W•J¥íïû’µŽ‘çýT©$IVÖJ’úúú$Iƒƒƒò¹\Ž Èd2ø¾O:¦R©°¹¹Éðð0…BîÝãï(2¼}‹‘Ö¿Qw÷}Ž*úüÙ›ŸWÿÀ€jµšNOO577'Ïó´»»«³³3IÒÊÊŠúúúT©TôãÇúãÕ+÷×éiÙ®®û"•2ðÏñ1“““d³Y6660ÆP*•bmm €½½=òù<ãããÄoÝ"xý¢ˆ°»Û¸Q³é(‘ÐoïÞé§G´´´¤L&£r¹¬b±¨ååeuuuiuuUFCÇÇÇÑØØ˜’©”r¹œT¯ËÇí¨×7ôáƒ~ö}ûÝíÛJ&“PŠÅbêééQ>ŸW±XÔè訉„êõºôËãÇ*FÒhãÁÂ'¬B4EÀ`e1 p 8fæœýKqfŒsñÞÊÎÚçû¾½×^0„ +•„C“ä›Õª¾{WX­j’|ûÿBŸ‡ „*•DHl4*ÂG³ì—;;úùs´ÕÒŸ?µÕ*ýͲ_ÂÇ>>éóÁ4 Žãüü{á‡zsS¨¹1¾´ÒϽ¹)ÜØPøáüü{ÇÇ1MÎÍáæf&|woOõ·íõ´×Óÿ®ÁžFõ·{{ ßÝÜÌœ›ë‡ ŸÜÚRíšçšçªæynQ”—+ŠÂ^¯g£ÅÓukKáÓàÍjfYÛ««òÄB1Æ~tqø»”ø«+Ͳ¶PC8twW5ï‡ðLl6›^__«zqqáþþþ³akîî®Â!ÂŽT‹˜êññ±£££žœœØjµ\XX°^¯»¼¼ìýý})Øí–¼£#…/©©¬¬FFˆ1’$ 333LLLp~~Îìì,ggg¤iÊéé)”¼•˜šúAÒ”—c¤Ñh°´´ÄÝÝëëë<>>²¶¶Æåå%cccCxÒB0cB·Ëkc$„@§Ó¡V«±ººJµZeqq€$IJ`· 1&vû+Í&@$Æ!±ÉÉI¦§§i·Û°½½M½^e¤&Í&´Û__ÍæÀìt:ª>==y{{ûœiõÕl¾ZgÃ]‡Š×ÿ©³ÿ쀡[¼ôÿbþÕoÚ›o:5Þtž½á¤ýx^åR–£IEND®B`‚routino-3.0/web/www/routino/icons/limit-6.6.png 644 233 144 1236 12573351603 14600 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“SIDAT8Ë­”±J+A†ÿÝ"É®ÄK4eÀ[Yj+šÚ&XÄÆBBòy Ó§¶Iç è(ha!ĆA wgæ»Åîæ¼·ËÀ23ÿüç°çœÿ! Iø¾ä#‰Bá7RÏ{ \†_¿,å2xÞR?}’ŸÚ eŽ Éãø¸€tN~ÒnÃå¥c:…ù¦ÓäÞnC~"§|/µ—Èå|òyQ«m!=ÑhÀdbƒs–ï+¹&K£ÒµÚù¼Èå|Q­Š££é‘nà pÄ1Ä18÷÷Ë0pÀÝ.H…T«i˜Rf ÂlÇ1Ö.ÿ˜µ6Á£ŒIøÍ&H½,gÛ„áÃaHãœû™[ìKxâÌ1B~ m ©O§`\0èõzÜßß`ÃxÊ7t: õ…tÇ`€ 0ŸÏÙÛÛãððýý}žŸŸ˜ÍfKøxx årH’Þ¾•¦§¥û÷¥8îürr2ɳ}V*•tii©sŠã 03#tçNv?7'õ÷K[·fÏOŸV‘÷ÒÒ’*•Jš·ÉØØ˜$)Žã àÜœ´}{¶yfF¹xÒÉ“ÙïG¤;¥fSù H`½÷(MÁ{XYS§`tî݃8ÎzäÕ+èï‡r*¸rvï†(ïÉ9Öéââ"kkk8çÀ… 04ÓÓ°¶–AÖס݆k×à‡àüyXXÀäI}úô ÅZÉo7nd'úúµä½tà€tìXVþÞ½ÒÝ»R¥"]½šÕº¼,£øÖ-IÒ H1!Aü h V‹š>H?*9sF:~\:|X*•2í?–NœÈ.Iº~])H/^hUÒо}qn‚_)—Ëxïgòæ$).zqe¥÷ ž<Ù8yPrù²$éü¹sIü(6­zïߪ×ë‰$…ëëÒÚš4;+½y³Ñ§ ÒÍ›Šž=“$ÍÎΦ9ðocÌ`tƘ#ÖZq£ÑèuÖ&Gö\|ÿ^…÷ëÝ<oŒÁ9w)×7læ–M>þÂûInÏñññ(Ÿ­;vAgBexçìàà ÞûF¾… ¿çÙOLL$9p±3ºÆ›Ô¼÷­}óÌŠ²çççU.—@ÖÚ7—½9¾ªïêꪆ††¢|xübŒð|%zô­Õja1%©^¯eÏå‹/v–þ;6ë{èСH’†€ÄZ+cÌ‘®ïÛ7EG_ç\ ÐÙ³gÓýû÷e×ó²Ý·{ôcÄy†¿ïÙ³çœý¿À޾ùúS²Ö.ßoªæ‹øØ ½ 2€¶IEND®B`‚routino-3.0/web/www/routino/icons/marker-35-red.png 644 233 144 2136 12573351600 15426 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“IDATHÇ•UMhI}U]5ç&è¦c”ì‚&äš‹G‰0xLrp/ž‚G]Xðð²Áƒ.Ùƒ’0Dô²"lôÁ 9f&`Ìa5þŒ2‰twÕÛCuÇÉ„eÝšúšzý½Wõ½¾…lkk“N§j­€3›×Zë…t:}â}2qö?h­'£(%ÉŽŽ100­5¬µR" CÌÏÏãýû÷B¥T% ÃóþnÂÙúÂ~Ïój˜ËåÂr¹lêõ:­µlk-ëõ:Ëå²Éår!Æûö'Œ“Ž}ÏóV0ŸÏÕj•$iŒa†;c I²Z­2ŸÏ1ð ßÁJ ¥ÔM, A|ýJd5·I†!m0ØÜ¤‰ß …•R7¥”@*•:€¾ï›Z­F’ ƒ`eƵF×kµ}ß7˜J¥Ž{Bˆik­?11ÁááaE”çssÀæ&°w/ ðæ p÷.ðò%°¸ùê¢}ûбgÒ©ÿ¼wO!~›ÍfíúúºcH’—.‘¹{·Ë/ºÖ®]së¶6—ÛÛi?~$I®¿{Çl6kã+S,I’I~ùâ6\¹â€®^uk’<}šORÊ€ùcjÊèÛ·äì,kÅÇð­[äçÏN’üô‰‚Ñ$ɹû÷ À !xž÷+væraum\[£ÈrÙm~òÄu4=MæräÄ„«_¿N+¹°ÀÉÞƒ£x~G&“Öz CC!IFçιî<ܵ‹<{Ö]¾ü­Ð\¸@’üùÌ.È$cšÓZ¯`©T2$<|HNM‘OŸºËŸxÀóçäÔÃgÏH’3336ÜBô$€ „‡¥”Uffœ¾É¡% ñ%³¿úú5;;;“Ù/5ã€B@)u;}?¨./;€Ö‘¢­Úèèh{k¥«« žçm9”ƒWJöôô@k]‰ÍÅéÛl($Ã0$INNNšpuËšl-_k]Û¦oÜYB{ii‰™LÆ ”r¤•vkìÔ·RÙÖa£Ñ`ooo[ÝoBÐøØ¦¯ïûAb‰$Y*•ÚK2ãããÍ¿¥V}C’¬T*Î0¤¤âpÓÿí»bK_¥T ÇÆÆl___B»ÓVß ¸M_CBˆâÿêîî†RJþ_À-}ãü‹çy”R®ø±…ÍŽøQŽb¶$ÝIEND®B`‚routino-3.0/web/www/routino/icons/limit-10.png 644 233 144 1236 12573351601 14505 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“SIDAT8Ë­”AJA†¿nefhi•¸p§l&ŠHôzQp® ðÉÎ…7²0‘,‚ATF6éé®/‹ž6J&;Ô«úß_õªþ÷0Žc!°Õz'ìEßœœÔ7oJ''5о {ƒ}„x‡ÔD­V$Dv:-á£IòË­-ýü9xs£?êÍMåomi’ü>ðÑ l4b›Mœ}+üpmM¯®Jµ0„ÒçVù…WW¥kk ?œ}k³‰FŒÓÓ¸¾žßÝÙQý­û}í÷5„¿£^Ó þvgGá»ëë‰ÓÓƒ4á“››ª¹E¡E¡jQ–eu¹²,í÷û†´,kLîæ¦Â§úÍÞ›$=ÏΪŸ…Ù…çÕ!Á³3M’žðaÏímÕbÂS`·Ûõüü\ÕÓÓSwww½¸¸ø‹©ð…ÛÛ {_ÜßW-k2ÕƒƒGGG=<<´( \\\´Ýn{_VøÒý}…/1XYˆ „@ELMM‘¦)ÇÇÇ4›MNNNHÓ”£££ §UÜÊ LL|ˆ‰ci4xn!:sssdYF±±1Ò4åññ‘Z£4ÇÆ„‘ç 3•<Ï™™™áöö–ëëk.//i·ÛDQTóBˆbz½¯t»^“eKKK,//3??ÏÆÆ«««Œ ¡Û…^ïëÐ߬íááÁ,Ëžtvww÷¤;uèoÕÙË* /Ä*!ÕÙ+ ÖÛsRk¢¡ðªµùª]ãUûÙ+vÚ? eá,¶÷IEND®B`‚routino-3.0/web/www/routino/icons/marker-56-grey.png 644 233 144 2734 12573351600 15631 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“‘IDATHÇu•[hTÛÇÿë6³g+Èd¬c$U& ã $RbÁ;ôDÁ’ѠLJúpÎC_ÚRò¦0Ò—ú`_ëSC¼5}01>8K¢X„㘌2c Œä2 “ŒŽÍ¾¬õõádæD=ý½`ïß^û·¿o-–N§±.¥D:6™Læ+"ú“çy{Ç! ?†‚Á SJý›1Ö—N§ïg2îû>`kPADšˆ¶*¥®¸®Ûëy…ÃaÖÒÒÎyƒhŒÁÌÌ *• )¥X ô<ï·Œ±yƘ %NDÀ)e¶V«íˆD"þÑ£Gy2™dÁ`ŸÇqär9Êf³zii©×¶í_j­Ñc\8p€4K)ÿéºîŽx<î?^íܹ“ !@D_ )%b±K$|aaÁ[\\Œ(¥~eŒù;­ˆÎÎNøËÇÅãqïâÅ‹* Bk Æ~TÉ9ỏZkض={öˆ·oßzsss˲~ …þÁ]×ýÚuÝo"‘ˆéîîVuˆ”œóƨÃê/RÂèîîV‘Hĸ®ûëº_‹Ã‡ÿÍqœæ'NP<gðþý{äóy”ËeÌÏÏcii ápBT*LMM¡V«¡©© DÛ¶¡”¢\.Ç”R­Ò÷ýŽp8L©TŠc˜žžÆÍ›7‡á8,ËB__qíÚ5xž‡Z­†T*…ÞÞ^@2™ä< Z­Ö!Ç¡D"ÁC¡´ÖB P( ‘HàÂ… ÐZ#€sŽááalÛ¶ çÎC±XÄ;wP©T‡aÛ6ZZZسgÏŒüAÿ¤dˆù|—/_†eY8uêâñ8fgg±qãF\ºt ¡PÇŽC8n,fùÂT«Uxž!@k¶¶6ôôô b``år°ººŠ“'ObëÖ­¸uëVVVÏÕj5pÎ ·,K‹E399 ð}]]]8sæ víÚ…žžpÎQ*• ”ÂÁƒÑÞÞŽÓ§OƒˆP,…B…B,ËÒÀ¥”üþýû~µZ…ÖW¯^Å“'O/^¼€Öñx[¶lÁ«W¯¹\F###šý¿Š³gÏŽ¯®®¶V«Õ¶¹¹9¿££ƒ{ž‡{÷îáÑ£G˜žžÆþýû‘J¥ÐÔÔ„‡"›Íâõëר·oÚÛÛ144dòù¼°,kÒó¼ÖßßÛ”Rã>|øù‘#GLgg'÷îæçç‹ÅFQ/·••¼yó›7oÆöíÛ199I̶íÿc~ADS’s.¼3ÆüÚ¶íãããÔÜÜŒT*…X,ÆXHDØ´iÚÚÚÀCµZÅÝ»wý@  cýŒ±)’ð(ÆØ÷œóß1ÆÄÈȈW©TÀƒ1¦Ñóup½=GGGýJ¥¢ÀõÝ»wÿà× ÔcŒñ½{÷^ ƒ×+•Šòë ÏkXÇ›§OŸÊ 6”\×ýÃÄÄDco‡ªßÌfffHký/˲ºfgg#ZkÓÚÚÊ´ÖàœƒˆÀ9G¹\Æ7H)Å|Ë{Ì“4ðL&ÓØÔ9ç’s^2Æ\´mccc”Ëå „hhð<ƒƒƒ¾ëº\q…1v€ZÓˆL&^¿XË~‡‡‡½åååÆö—ÍfM©T’Á`pÊqœþãÇc=kbñø ¿·oßöë066Û¶aŒù”òãèè¨@뽋õ“Ÿò »"ËËËôüùs]«Õ„Rê÷‰¨áqÝ¢ð鯰îÈ–|":Ì9ÿÞq-¥RÊl2™üêåË—\km>~òù?¡¡î÷!õY–%„%­õwÐZãÿåMÎÊh-IEND®B`‚routino-3.0/web/www/routino/icons/limit-4.0.png 644 233 144 1273 12573351603 14571 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“pIDAT8Ë­”½JkA…×™" ‡ƒ‚MÀk5Ok Ÿ@ˆ øÚYØ ¦³ÒÞP)„AL  ø *1sf¾[œ$&ro—™=³×ìY{í-$! c ’A©Ô¤#‚ N6 ÓÓŽl‚ ŽtÔ?’éû €R©)`s3…´O~P©ÀÙ™§Óçgètâ}¥aø´ß¿ôý% C2)r¹y¤&ëëÐj9 Â{Çèˆ÷­–c}¤&¹Ü<ɤH$Œ˜¥RˆtÃÎÀ7౬ïæÀøfg¤J¥ÙÙþ7¥Êe€Ö‚s8爢h,0çÖZ¼µŸõ(—A:p¶H¾ÓhÄ/:‡÷ïý¯þؼ÷øÌÓh@¾#- éˆím€kq.¦©Ùlryy9Œ ÑhpxxÈÝÝ] ÚëÅ~ÛÛ  éšjÀù˜œs,,,°¶¶6Œìññ‘••–——Éçó¼¼¼Ð'ÏQ­‚tm45UP±(I&0F’´··§n·«™™ ÆÅÅ…’ɤjµš2™ŒÎÏÏ%IN2*¥©©‚‘1(‘“$ctrr¢ÓÓS­®®êêêJ···’$k­Òé´$)“Éèëëkø ÉŒ¼Ôë íÆ Õj5µÛmÕëuu»]ÍÍÍéááAív[÷÷÷Êçó’¤@’z=Éû`Œ3¢Ûçíøø˜ –––x}}ekk‹t:ÍîînLdœÑ!gÿ̦sŽÏÏOÞÞÞpÎñôô4´ÖÀ@ÀcÙ×Ù/¡Žêlâœû¯ÎÆ+ Šá‰ttäί ˜hmN´kL´ŸM°Óþ!0’м¯93IEND®B`‚routino-3.0/web/www/routino/icons/marker-26-red.png 644 233 144 2120 12573351600 15417 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“IDATHÇ••MkY†ß{«nwh³j"ÝíWf“·º±qÒü@nd"Áwº³…ùa² 8‰H0(½s!((#¸%‹BìŽ(£ $!©¯gUÕéÄÆ9PœªKÝçžóÖ9§¤m³}}}V’ŠÅâ¨snA’’ÌÓûìœ[(‹£’”í³9ÈdÞ“KÚçœ›Š¢h`ïÞ½æÄ‰rÎ)IYk†¡ž={¦ÕÕUŒ1Æ÷ýV†×$ýÕÃéžpØó¼Ž$*•J833¯­­‘$ ½–$ kkkÌÌÌÄ•J%”D¶ïpžqqÕó¼eIÔëõ ÝnÇ1a~sÅq @»Ý¦^¯xYR5ÅZ+ß÷ç%Ñh4‚ln’DÑŽH‰c’ ØÜìÂF ß÷ç­µR¡P8-‰jµw:­­o@$Éö•Yt:ªÕj,‰B¡pZ¾ï¿ÄôôtÜû"¯_ÃÍ›ðàôòö-ÌÎÂÇE„aÀôôtœEûB’’r¹œ¬¬¬¤àΠ\NýÙ³ÛíÛýýéúùóäq¯¬¬P.—“¬äe10éý«W)àɸpΜI×?†C‡ Ý&W}ll I±/É:ç$I#4:*ML¤uQ,JÆH?J ’µR©$•ËÒä¤t䈆’sÊ8V’âcÇŽ±±±Ñ­C ÕqrœƒË—áëWسö¹T’BÞ½#Ëz½Ž¤XÖÚ@R|ëÖ­ô‹,-Áà 8Ù:Ð×7n¤Ï««` ÑíÛ ¤Ó@&Ü¿œ= h Ç‘@T¯×±··¥T ÞØˆáÍ&Ðjµ°»on6G€ñq`nØÚ‚pAmoo@)eÀþ¶´Ÿè·o¤Öd±xx8çÏ“ÓÓd6K>|ûvvH!./“$×VW Bð<ïð}Su%e³YòÎxó—/äÉ“ä½{18ÑôñcFùþ=[$GÏ ]üŠt: ­õœ4$¾xA*E Ò… äî.ùá™NÇ>€öî]’äÜ­[ÖÿNŽ&«µÞÀ‚%É Z%——ÉÕUòàà°è·¶È§OiÞ¾%I®¬¬Dø·b$*B\’R@X~þ<Ö7 v”µdµÛ³þõ+’Þ/tò@ ! ”Zpú• 8ÖûÖuÝÌÌŒq³µ<88ÏóÚ*Æ+%GFF µ.»áë›D›ô»kËb±h°ÞžNc]_k]ÀB¡ëë"KÒ®T*L§Ó¥”?u§ÝmÇõ-—DØjµ8::jÜðx „ÿ°#úú¾$#‘$ …B’v@z~~¾ó·ôï֭狼ßr¹LVJI!Ä¥ŽÿÛwY[_¥T ggg£±±±$í‚K[}/ðˆ¾~B@è"ücxxJ)ùm}Ýú³çy”RÖüЕÍ1û­#Š]Á¨õ™IEND®B`‚routino-3.0/web/www/routino/icons/limit-23.4.png 644 233 144 1453 12573351605 14660 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“àIDAT8Ë­”ÁK[YÆ¿÷dbxfÐt(+H.*èJ ]‚Òt!îÒî†"øOp7Y)J³(H…®º(2‹v´¨%)¸A µH!BÌ{÷þf‘§N»ôÂ…sνçÜ{Îù¾#$! ×u‘\$ÞCÊá8Ÿèê‚;w ]]à8Ÿrá¹ÜÐO¨(uÒé(Ò2žW#“W¯,§§ð휞6õL<¯†´ÞwB‰HÄ¥½]ôõ •H&¡\6@€µ†WS(— É$H%úúho‘ˆ+ 1=í!³¸pX||¬ýo·l`+A:fzÚ#‘Ó”²ÆÜü A€ñ}hJ”mÕì>ž÷Ý‹X°„Žÿ`­½!Û hþ°XÏûŽt_H9›É?²²²ÂÁÁ‡‡‡d³Yvww¯ƒ´)•Jüýö-@`3r ¤=^¿æÃ—/æwÏcbb‚¡¡!677éíí%•JÑÓÓÃÎÎN˜a€1†ÁÁA&=0A>Òž«Xì&'UþüÙýóùsmoo+‹©P(hyyYétZ‰DBõz]’ÔÖÖ¦¥¥%Õëuýq÷®$¹<|(uv>ñ¸1Õ*ïß½cxx˜……¬µÔj5fffèïï§P(°ººJww7óóóÜà¤R‹ Lg§q­ï;n$¢Ž555¥ÙÙY­¯¯+ŸÏk||\[[[êèèP¡P1FÖZŒŒh_årYGGG’ãc5¤=޼ᯗ/Ío®ËØØñxœ Òé4±XŒ¹¹9NNNåìì €µµ5’7köâH{BÊñì—T+*á®×ëc¨V«ø¾µ–óóókùòò’‹¯_ž>mv³…3ŠÅ&nÂÖÿcÌ œ…Æ_âìšÖ÷±MÊü¬-ØŸp«Ü¼Õ©q«óì'í¿J•©¬UßÈ‚IEND®B`‚routino-3.0/web/www/routino/icons/limit-65.png 644 233 144 1335 12573351602 14520 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“’IDAT8Ë­”?KcAÅÏÌJòö)E6±QØ…ˆ¥µ…b•Â…Ûh¡‰Ø ~…-µ·ÓÎJ?€6¶"X˜Bp Š úÞ›ùmñ^².bç…¹3sîÌ=sî’„µÉ"‰ ø†´ƒ1u èïw `Li'Û’ÍpBí@A` ß¿H[„áµzîî Õ‚»»Ô¯Õ Ÿ¶²ó&ÃKär–|^ EúÅì,ÜÞ: Á{ÇkKý„Û[Çì,H¿þJ>/r9+ŠE1?"]²¹ ðxââ¼ÿ7Úkà67Aºd~>¤XÌÒ”¶YXˆˆcpç=qá\ú¸8Ž;Ã' $Iz~a¤í6g£„á®®ÒÃ{÷þUvž7–ó\]AþAýôCú©ju\ËËNIb±VÆÝÜÜhooOajppP:99ÑÅÅ…Êå²òA âØ˜/_œ~ÿþ¬óóOB:gÀù”Z­ãããT*¦¦¦8;;chhˆ¹¹9–––¸¿¿O_EŽý}έz{Ç41!IÖ$éøøX×××êëëS¥RQ£ÑÐãã£$iffF¥RI€LW—$YMLH½½cVÖ¢\N¯-I hrrR»»»j4ªV«šžžÖÆÆ†ŽŽŽdŒ‘s.är’µXyoE’$cŒ$©§§GÝÝݪÕj*‹:==U¹\ÖêêªJ¥’šÍ¦$‰,E‘ä½ù³LC,..ëëëÔëuFFF( ¬¬¬¤?IÆq‡3!í°¶¼–$ Íf³|~~æáá¡£»L|)nm ¤wuÖµçm­9çðéäÎÞVÀ?u¿nÇ·>´6?´k|h?ûÀNû¾ðf&\øÖ;IEND®B`‚routino-3.0/web/www/routino/icons/limit-31.9.png 644 233 144 1456 12573351605 14667 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ãIDAT8Ë­”1O[I…Ï{Ï1±Q¼ $/Å)6E*²JAc %lwQR™À?Ø”¡qåà‰Sd倄䆀Ù¥qbÈØ`{f¾-žaIÒ2ÒHsï̹÷Ì̹WHB¾ï#ùHbxøW¤2ž·K"cc–D>Æ…z4¬®†¿yWg¶¯3kíOúº«3Û×™Ç: + —èº^ŒùüÓÚ\ȾK.w§îµ6ïµkÜk?»ÇNûái¬Jf¦áIEND®B`‚routino-3.0/web/www/routino/icons/marker-95-red.png 644 233 144 2147 12573351601 15437 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“IDATHÇ••ÍkTIÅUï½Nì1Ì¢_Œâ h‚+wbpŒ_q“]`âÂÙ¸Qq‘„ñðk1YéÔ…íE@q3"Œ;qe”ÑEèFãGÚ÷QgïuìD†q.<ŠºEºç¼º§àkØööv ÐÖÖv ‚i@€ËGµÎƒ ˜nkk;ï³M “?A0ž$ɨ$uuu™={öÎ9¬µÄqÌãÇùð჌1Æ÷ýJÇcÀß-8«'lõ<¯¨T*Åi½^—sN­áœS½^×ÄÄDZ*•b@ù¾­MÆÍŠCÏóæ DÕjU’”¦©â8þæKÓT’T­V500åÀó@˜ÁZ‹ïû· FM°heE.Ф$i-SŠc¹(R´¼¬4_Œù¾ËZ …BaP†i­V“$Å++k(+¯l}Äy¾V«) ÃP¡PòŒ1“ιðüùó:tèIâ¿P€—/áþ}XZ‚Í›ÁZxó&˽z33ع9’-[èêPПcÌO®³³Ó-..f %irR©£#ÏJ»r%›··¯®»OŸ$I‹ïß«³³ÓåWŽtxxX’”8'E‘ÔÕ%:•=z$yžôö­42"íÞ-5ÒÇ™Æiª$×vxxX@j2’$£Üۛ݋R Òž=ƒbž<ŽؾîÞÍdq€ÇZÀ-,,°¼¼ŒŸ¦hÃ8}Ξ…ÇáàÁ ¼Ñ€/_`h¦¦`×.j“õîÝ;‡µ6Ò7n|ý£KKÒåËÒ‘#Ò… ™†÷îIõz¶&IŸ?KÆ(¹y3SéáCÎáyÞo€zzzâêÜ\vƒöï—NœÈ6_º$uwKóóÒ¦MÒÅ‹YþêU9c¤éi5$õïØ‘äMðÅb‘ & îÝKRR©d¤¥©© èܹ,çy(=sF’ôë±ci8›mZ ‚`Pyl,•¤èÅ éÚ5iffm<.]¿®øéSIÒíÛ·]øÅÓ×ôŒ1û¬µ’Ê;™¾ÍmšJÜìý…ׯÕÓÓÓìýr+@`ŒÁ÷ý1@=aøÕTâxmo&‰Ò(’$ŽŽÆ¹·Vz{{ñÐÃñiÏ@Õ*©¨  >®4¨Z HdŽÞúâ‡Äeñ¥¥Šno€%ˆA…‚Q‹¸°(hP irß½¿.^âŸÖ¥îÜ;s˜9œ! IA€ ‰dòÒ2Æü •‚LÆ‘J1?–ëÿB êyB  dÒ ¾|I"͆¿™™BÁsq××pqû33†¿‘æëñ¦ž/ÑÔHˆ®®¤ŸŒÁÙ™"¼w<µØ8;sŒô“®® ÑÔˆöv‘Ë…H%ææª€ÇZ°¼<7ð@•¹9Jär!ííõ6¥&&jD®VÃZ‹sîIQkm|þüÁÇ 5&&@Zhp–% +Ç9QôOgž-ŽóCV²o¾IßõõëgMM9¬ ÌÛ·:<<ÔÊÊŠ‰„:::$I§§§Z]]U©TÒÁÁÞø t:møøÑ™_¿Þiw÷vÉçqàNNNÈd2LNNÒÙÙÉÖÖ 044„1†õõõ¸@päó 튖Ïù9 vŽŽŽX\\¤P(ÐßßÏææ&Õj€¥¥%¦§§p JÎÏ¡¥Å‹tÚQ.7àîîŽññqº»»ÙÛÛ{ éêêŠÞÞ^J¥Òs°rÒiÈ{£ZMN’ŒQ>Ÿ×àà  …‚š››µ³³£››IÒÚÚšZ[[•ÍfåœS’$Õj’÷&P¥²¯bQäU[[›R©”úúú422¢ááaÚÞÞV.—Óƒy/I^Å¢T©ì i™ÙÙ˜ËX;Xk¹¼¼ÄZ‹÷žr¹Œ÷žÛÛ[îïïåÇGÌ΂´ü¿ÎžˆÕ9÷ŸÎütöâEÏ@÷g@1Ø?ðª³ùª[ãU÷Ù+nÚ¿=yŸûo7IEND®B`‚routino-3.0/web/www/routino/icons/limit-11.7.png 644 233 144 1341 12573351604 14653 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“–IDAT8Ë­”¿K\YÇ?ï™Çç"Np°œ%[l,Ò¸B 1¥ Á©)ôðXØ2©¬-R¥ÚN1Ó!$ A !B‚Nç½w?[ŒcfÀ6¸p¿÷žïùÅ9ã8bK¥_„u£èƒããzÿ~îø¸FÑaýæ!¾á!}C¥R$DÖë%á…IòÍåe}õ*xzª_¾èéi//k’|^ÜèG7|°XŒÆjõpè⢞œäjf¹ƒÒÙ''¹‹‹ ‡V«Æb1ÆÉI¬ÕaßÕUÕk5˜¦š¦ÂÓÓ ^»ºª°o­–89y“&¼tiIµ›]_›÷ªfYfžçÁÓïßM»]S톧O^ök6e’t<<4Óþa(„àJÏAðà@“¤#L ý¿óüù¯>{–Çï¼yCžç”Ëeâ8fggç³¹¹ÉþÇì½ý43“—¿~ »»Com6Uó?šM …‚FCÕf³i±X´ÙûWukkËÙÙYçççÀ?wws_¿6…·÷›áñcÄÑЕJ€(Š˜˜˜ „@š¦ÌÍÍÑjµX[[ãçj•'ÅáÓ'îÍ`¹œÛnÛ¯Ô‚·‘ ân·«êÙÙ™ÓÓÓîïíõÊ÷ù³–ËyLÝ.}éG1ˆ£(àèè€F£A¥RaêáCr Î2!ŠétÞ±½ FGG) ·Æ’$add€z½@«Õ¢V«Ýúc{:w뮬¨fæ¹^]]ݦ9ˆÛí¶!ÏÏϽ¼¼Ô,ëñVVÖôÙÁA¯oz ÿ+¡§÷·>ûׄ4uÐà`Óöï!ËúcÕuii`ît6ïtkÜé>»ÃMûôi%fs;IEND®B`‚routino-3.0/web/www/routino/icons/limit-57.png 644 233 144 1306 12573351602 14517 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“{IDAT8Ë­”?K+QÅÏ®’„-’(J°ŠäA 6v)lü²…–)TH±ÉÇÐJIcT°ÐJ°ÄÒÆ" ¥E‚A$îWìÆ§Ï÷§ÉÀsï™™;wÎŒ„$\×Er‘D&óiǹ!Ÿ‡ÉIC>Žsƒ´—Ü ÉMü„†2Éae%ƒ´…ç½R¯Ãñ±åសáá!¶ëuð¼W¤­ï$þ©”K:-ŠÅÒKKpo€k Ÿ%¶#îï KK ÝQ,–H§E*åŠBAø¾‡Ô¡Ùx,aaÖþÒáXàf¤¾ïQ($eJÛ,/DDa~¨1æ‹mâ(Æ//ƒ´=ü³ ž÷Âímœ1ý_bœåö<ï©2.iSµZVå²Qi|\aêôôTÊf³šŸŸ×ÕÕ•2™ŒR©”T*•D:N¹lT«eÕjmŽKªjqQ’@ޤ~¿¯ U«UÍÌÌ(NëèèH®ëêââBggg*•J² 1ÉÑâ¢ÔjUE.gévã—'''xž‡ïû|T¶»»Ëúú:Ƙ¸)Ý.ärVLLz½wŠËËKÖÖÖØßß§P(p~~Î`0`nnŽN§ó=X¯Æ•µŽ‚@CKR·ÛÕìì¬VWW5==­ txx¨©©)U*c亮>$$k!]ÓnÇÉ’2;år™|>O­VÀ÷}vvv’FFŸ;jh·AºÒ@”€Á`ÀÓÓS\Ðï÷y{{ûJÑh€´÷gÆ`­Å&ÿa;ž&ûOžýuìoÎßýqF:›#Ý#Ýg#Ü´?G4™zƒÅ}IEND®B`‚routino-3.0/web/www/routino/icons/limit-149.png 644 233 144 1331 12573351603 14600 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ŽIDAT8Ë­”?K›QÆŸ÷B^ûJ “JÒÅnÑUJA'ƒ‚ù ú„| ]œÜtŠàЩØ1 ¸(ˆ†‚¡.*f(E •äMÞ{~òšÛÑî¹çß½÷<Ï’„sÉ!‰lö=Ò6ApI.ïÞyr9‚K¤íÔ.$—Æ ='Êf¤€j5‹´Aýfu>6îïáçO¸¿ïë««E¿‘6Rÿ —CÇȈ˜˜(!5©TàæÆ fž—Ò×nn<• HM&&JŒŒˆ0t¢PKKÒ7Ö×bÀèõ ×³¿ëù ˆY_éKK…BúLi“•€.IBÇx³Á…¼÷$I2Ø÷:|·Û÷_YióùÏ>E¿¸º°$ޱ‰Ìl í“ãê ¢èÒ!m³¶X¿‡‡‡\__6›Mçççlmmñ=µ$¬­´-¤Söö<Þ³¿¿O†Ôëuâ8¦T*±¸¸Èíí-Åb‘™™Êå2?Z-oõ:H§N££SúôI’œ‚ P>Ÿ IªÕjj·Û×ññ±òù¼ŽŽŽ†¡¾|ý*IÎü(ŽN99‡ÂP’dfªV«šœœT&“ÑÁÁêõºæææÔh4T(dfZXXÐÅÅ…2™Œ$I™ŒäNfº]½3“÷^Î9MOOëììLwww:99Q¹\Öìì¬r¹œŠÅ¢$)HÉ,ú³^§@¥RawwwЀ–——˜ŸŸgllŒZ­6@{{ u3$´Ûí®žžžxxx ÓéÐjµúéûusg¤àüŸ˜Þ÷柙ð gÿ0Àþ“pȽiÑW xSn¾éÔxÓyö†“öùb¿à¸rIEND®B`‚routino-3.0/web/www/routino/icons/marker-56-red.png 644 233 144 2143 12573351600 15427 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“IDATHÇ••MkY†Ÿ{«n:tD¤³˜ ~ÄY˜ .Ü&¨ABð#àB˜¸Ð½»´00óA& !’AC/Ä…A™Ù…ˆˆ‹Pº% C/’õõ΢ª“NdçÀåtê>uÎ{ï9»fÛÛÛ-@¡P¸àœ{Hs¯Öÿι÷…Bá@¾Ï6A&÷]ι‰8ŽÇ$©³³Ó àœ#MS¬µDQÄÜÜëëë2Æß÷+Q·pvÞpÌó¼ îîîhjj*©×ëJÓT­–¦©êõº¦¦¦’îîîP¾ïX³âfÆçy_ †ÕjU’”$‰¢(ún%I"IªV« sð ȰÖâûþ@CCC¡$%q¬°ÑP†Re«iI¢4 noïÀ‡††B@¾ï?±ÖB[[Û  ’Z­&IŠZ!­–$R‹QJ’jµš‚ HµµµxƘ§išwîÜÑðð°‰ÿëWxñáãGøô z{Á9¨ÕàùsX]Åž8Aœ¦tvvR(ôòåKcŒù -•JéÚÚš”¦J%éÁ ¤ööÌ<(5Òâ¢ÔÕ%8ů^U3ïµµ5•J¥4¿r$£££’¤x{;{âòei`@ÚÜ”¾}ÛÕtxXºr%ûýúµtô¨T­*ÎÁ£££°Î9Èov~z07‡ekzFFàÝ;èê‚bJ%¸wއ(çÈ9ÖéÊÊ F¿PÈÀ[[pé<{gÎÀµk°°=¾±““pú4ܼ KK˜<©ÕÕU€km$ÌÌd'ÚhHËËÒÖVVÓÆ†äœ4=->,Ý¿ŸÅ××%c?~,IúëÕ+©1&Äó¼_õAT]^–êu%ÒÝ»ÙæÉÉìP>–.^Ì–$=|¨¤ùymJê?y2ΛàÅbçÜS@CçÎE’ÿö[ò¼Ìß¾Þ¼‘::²(Éã7oÜHràG Ø<šnçÜ@åññD’ÂùyifFúða÷âKÒÒ’ôè‘¢·o%I³³³iÜ2Æô5>€1æ¼µV@\™Íôã½À¼£ší¹²¼¬žžžfï—[y΃ïûã¹¾»CeË&‰’¼=ÇÆÆ¢|¶VŽ9‚çy;*Ãû¾íëëÃ9WɇK¦o3Ûf¿ç/™˜˜HràÊÎtj{ì ι r¹œé›gÖ,{aaAÅb1d­ýyÙûí{}+•=nnnª¿¿?ÊGÝïÆÇØ}ƒ ›#Q’Êår³ì xëÖ­ÖÏÒ¿Û~}Ïž=IR¥RXkeŒ9ßò}û!ÛÑ×÷ý ëׯ§§Nj–]ÎËö¸G_àœ1F@œgøgoo/¾ïÛÿ ÜÑ7÷¿xž'kí pb_5ßÙ?Æce+ÊG,{IEND®B`‚routino-3.0/web/www/routino/icons/marker-76-grey.png 644 233 144 2667 12573351601 15641 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“lIDATHÇu•ÏkTYÇ¿çþxõòJMÞÔ¢ˆ¤-ÄŠÄ ´‚„l4àbè¸ Ú›ÎÂY¸™ Cošš¦f3þ2àfˆbŒHŒY8eÏAc,›`Rh c1‰•JUC½÷î=³0UÌ.Ü —ï=÷sϹ‡òù<¶%”RÈçó¶P(|ÅÌÃð×Íf“þ'ŽÅb¤µ~JDßåóù¿ EX mSÉ̆™÷j­¯A0†!û¾O===B´­µX^^F­Vc­59Ž3†áïˆèßD$@0³°_)U¬×ëû‰Dtúôi‘Íf)‹ác5›M”J%.‹¦Z­ŽxžwÂsš™_‘ƒƒƒ  [)õÏ öÖ××ñúõkìÙ³€µ¾ïãÔ©S¸}û6´Ö?¨(оô}Ÿûúúcp÷î]4 H)Õj—/_†”×®]CE¨×ëèëëÃÈÈ ›ÍЇr½^ÿR5›Mîíížç™áº.ÆÆÆ`­…뺘˜˜Àææ&2™ ®_¿Žîîn\¸pårSSS¨Õjð}žç¡§§‡ž={fÕ{D¢}M"‚ÖD„ÅÅE”Ëe\ºt Q¡R©`×®]¸rå :::pæÌø¾c ¤”­|BJi·¶¶†!„¼øƒpôèQtuu!DQ„f³‰sçÎaïÞ½¸uë677Û˜êõ:„V¸®kÊ岟ŸG‹)aaakkk8qâ@)fF.—ñcÇpþüy03Êå2`ii KKK캮þ¨”Åb1ªÕjPJž>}Šîînø¾k-ÇA*• T*’É$`zzÚÐ{ýU$“É?9Žó·jµª&''#‚¯^½ÂáÇ۬`hhoÞ¼A>ŸÇÔÔNž<‰T*…ÉÉIûöí[é8Î|†c²¿¿ÖÚŸ]×®T*¿²ÖÚL&C»wïF&“AGGG;_;;;Ñßßd2‰ÁÁA `~~žgff„çyÿ±Öž%¢·J¡üËZû­çy=zÄ©T íŠÙY-c"ÂÖÖîß¿9Ž£‰è{"ú€"šˆ~Büžˆäôôt¸¾¾þI6´JµuØÌÌLT«Õ´ã87Ž9ò@Ôú(C"Ç¿‹ÅnÔj5}çΟ3CJ‰ÇÛ'Ož¨x<¾ÁæææÚÈ\.×ÚLËËËlŒùÙuݯ+•JÂc:DƘvÔB¬­­áæÍ›¬µ&—ˆè1)D¡PhêB%„X±ÖŽzž‡ÙÙY.•JRÂZ "B†‚ RÊ«Dt€ÞƈB¡Ñšlë¾÷îÝ 766Ú-¥X,Ú••‹Å~i6›ßŸ={; ± Âwbb"€/^`vvžçÁZ{Y)Õ˜™™‘x'w¹sñ9¾±XìëÕÕÕÄÆÆ?þÜÔëu©µ0ÎÌmŽ;‚ú õv´l bæSBˆŸšÍ¦QJI¥T1›Í~õòåKaŒ±~pýÏ`hñý3纮”R®c~;77c þŸþ ɤ¶i;M²ÑIEND®B`‚routino-3.0/web/www/routino/icons/marker-72-grey.png 644 233 144 2663 12573351601 15631 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“hIDATHÇuUÏkTY=÷»÷Ö{y¥Ä7µ‰JÚÒ¢4Ub2…q6! ö*c\„Io¬Å´Ð3aèMSÓÔ¢e@&[£•€ÑE,{Æ@ ÇFŒ±-¬1X•ªÊ$T ïǽwzm´çÀ÷nÎ;ç|‡wY¡PÀ&HB¡ ‹Åâ§Æ˜¿Að;Ïó †_`,ËbRÊŒ±¯ …Âíb±Ha€¶IÊ1Êó[)å¤ïûcA×uYoo/ˆ(bÔZ£\.£Ùl)%‹ÅbSAü™1öŽ1Æ(€Œ1 À^!D©ÕjíM$áðð0e³YfY>„çyX\\4¥RIÕëõ1Çq~¯”6ÆüÄ#~ìØ1`·â_¾ïïÝ¿0>>.“É$ãœÃóÑ!ÐÓÓÃúúú¨Z­««« )å´ÖW1ÿ¡x<)åwívû“d2äóyÙÝÝ0 aŒ‰Ô1Æ@D`ŒÁƒ0 ±cÇäóy™L&ƒv»ý‰”ò»x<ò}ÿ3ß÷¿H$zttTv„ ¢h:dr!DôÑÑÑQ™H$´ïû_ø¾ÿ™0Æ|†††àº.‚ ÀÒÒÂ0c?/݃={öÀu]T«UT*lÛ¶ ûöíƒÖ®ëâøñã¸zõ*¤”ߊ0 ]×5‡"PJaffívœs@½^ÇÙ³g±ººŠ . »»ëëëÈd2d³YºsçŽiµZƒÂó<Ó××GŽãÀÛ¶111­5lÛÆôô4666J¥pîÜ9är9œ:u oß¾Åää$r¹<ÇqÐÛÛË>|¨ uzØÉHJ Û¶±´´„ååeœ/|ßÇ‹/0<<ccår±X çÏŸ‡R ív§OŸÆëׯõ›7ox<Áß´ðƒmÛ£+++¿ÑZët:Ͷoߎt:®®®ˆx×®]H¥R8pàÒé4Ž9‚F£anß¾M]]]ÿ5Æœ`Œ½D$ü[k}Úqœ;wïÞ5===ÈårÐZGK‹ÅbÈd2QKch·Û¸yófÈ9—DôÖúG‚„$cì{"ú cŒÏÎÎFD´¥ Zëh`ff&¬ÕjÒ²¬Kýýýÿ@ÂNÉÆ=ztÒ²¬KÍfS^¿~=üð—×é$ç úþýû"W|ßÿë½{÷"|hh¨c‰•Ëe£”úÁ¶íÏWVVJ)J¥˜R*RMD¨Õj¸|ù²‘R2bŒ-0ÆT,#wD$ˆ¨¢µÎ;Žƒùùy³¸¸Î9´Ö`Œ!LMM…¾ïç|’1v €ÜŒÅbÔ9lâ£|oܸ¬­­EÖK¥’®T*²¬=ÏûæÄ‰xŸ›ÁââòžžàéÓ§˜ŸŸ‡ã8ÐZ%„hߺu‹øe›øû—_Ëײ¬Ï«ÕjbmmÍ<~üXµZ-.¥œ0eŒ‰r|OÔ–§ðÞ“-„ƘãDô½çyJÁ…¥l6ûé³gÏH)¥?$ÜbÿWbèäûOcÌ×¶msÎyE)õå£G ”ÂÿÃÿGÀŽÓòȪIEND®B`‚routino-3.0/web/www/routino/icons/marker-8-grey.png 644 233 144 2473 12573351600 15546 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“ðIDATHÇ…•ßkSgÇ¿Ïû#99Qh–‹a)DC‹P½Ð"ˆ… o††‚õ¢½Ø.v³•ád a7ó/Þ Z¡½Zƒ°ÌŒŠˆ£ÖT«k¡[³XIHÖóã}ß]Øs–XǾðÂ9ïûžïyžÏó¼çP¡PÀ¾˜…BA‹ÅsƘo=ÏqÇ ü+FIJù]/ ?‹Eæû>h }SnŒQƘ¥”·\×½âyžI$”J¥À µÖØÜÜD£Ñ0RJŠD"³žç}ID fŒQŽ !ÊívûX2™ôÇÇÇY&“¡h4Š÷å8ªÕª)—ËêíÛ·WlÛUJc~'"ÆÏœ9c !~q]÷Øàà wõêU™N§‰scÌ!„@? ³z½îíìì$¥”Ÿh­Œ1MÇ!¥¼ÙétަÓiozzZöõõAkFFD`ŒÀÐ×ׇééi™N§½N§sTJy3ƒ¹®{ÞuÝÉd2©óù¼c c¡™R ŽãÀ÷ýžyc ŸÏËd2©]×t]÷<ûÁqœ .˜ÁÁAÒZ‡666pûömÜ¿>Ä¡C‡Ðßß¾Xk Û¶!¥4Õj•¤”CÌ÷ý“‰DÂd³Y L‘ˆ`ŒÁÜÜâñ8&''‘Ëå0??Z­®û³Ù,K$Æ÷ý“Ìq“J¥(‹…ƒ´öööÐjµËåpüøqŒŽŽB)…Z­Ö³OkX,†T*EŽãñ.8ÖÓ2A±X §OŸÆÒÒÖ××±±±t:áááp_·ö}ãœëV«Ïózª·ÛmضFÓl6ÑétívŒ1Í,ËR¯^½Ò«««a*†µµ5|8l»»wïê/^p˲V=Ïû”çr9h­Y–•ßÞÞþH)¥‡††H)Î9²Ù,„ØÙÙA*•B>ŸÇ‘#G¬¯®®šR©ÄlÛþ[k=AD Ƙð‡ÖzʶíŸ*•Š@&“Ö–ea||¼§0ZkpÎÑjµpïÞ=?‰H"ºADÏÀ ‰ècì+"â‹‹‹ÞîînÈ.(žÖ:LJ¥’ßh4d$™;qâÄw? î;uêÔ­h4:×h4ä‚ß]Œ`¦ËËËúñãÇ"o¹®ûõÊÊJX`~öìÙ =hssÓ(¥Y–uq{{;ÙÍ70dŒáÍ›7¸s玑R€Ïˆh™ˆ¬X,†¨c‚1¶¥µž¶m•JÅT«UpÎÃ~ô<³³³¾ëºŒs~‹ˆæÈ}Œ(‹`Ážþ—o¹\Ö[[[">wçÆÄĺ ±ïà;??ïÀ³gÏP©T‚cû…¢S*•8ÓݼûæC|£ÑèÅz½žÜÝÝ5OŸ>Uív›K)gÌcBŽ]A¡÷3 ë—-øÆ˜1ÆØÇq”‚ !Ê™LæÜÚÚSJé÷ {Òÿ†€ïÏÆ˜ë–eqÎù–Rêó••(¥ð_úÖ³;Š— IEND®B`‚routino-3.0/web/www/routino/icons/marker-37-grey.png 644 233 144 2661 12573351600 15627 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“fIDATHÇu•ÑkIÇ¿õ«ªé¶4“F4dÖ!*$­„“lNbÁEAÎÍÃá‚‹°÷îÅ;޼,³aîåü¼ç(æBê &—“eQ.1΄ˆ:G ·Ã&jÏÌètwU݃™ÞÄõ¾PÐõPßúý>¿úýšår9lŠ„Èår:ŸÏfŒùK†¿n6›ÃÏ2–e1)å¿c#¹\n:ŸÏSE €mšrcŒ2ÆüJJy9‚/Ã04©TŠ¥ÓiQ쨵Æêê*|ß7RJ–H$ÆÂ0¼Äû‰1Æ(€Œ1 À>!ÄL½^ßçºntâÄ ò©”hkóE&#FFB¤Ï,,Ä€#I IÀ¹ï«uˆYXé3##!™L3MéccuÇØk-I’`í?˜Ä1I½Nuž?éU«fÃ+0à\Ó‘sçÜûohpìïC^!=~“~×Ì̯LMY_òßø cŒº»»µ··§B¡ (Š”Éd$II’¨X,꯭-ý]*y??}jSÕj?B*±¶`ÿX[#6668<<¤££ƒÁÁAr¹¥R €jµJ6›ett”‰ñqþ©Õ,¯_c¥’¯ÎÎGzòDNò½ POO‚ P¹\Öüü¼677E‘J¥’$iwwW×××ô,ŸW6•òyüXþ½{DW—åË’f)†††X^^`kk‹¦¦¦¨×ëloo333ÃÊÊ ÙL†?ß¾…8ÆtvZ_Îyª×Õ‚1FQ©R©hxxXZ\\”1Fççç*—Ëêïï×ôô´²Ù¬ÎÎÎ$焵ž¯««Oz÷N’œ$…a¨(Š´³³#cŒÖ××Õ××§ÕÕUMNNª··W…BA]é´~yøPããNÅ¢‚››OBZbnÀ`-———Ôj5jµ'''T*޹¹¹áââçqszzŠm¤n˜›ié»Îö÷º1†ÿÃ7ÍY‹çnéì‡pIBËa‹x[¼Îšâ®36v«î´7ïtjÜé<»ÃIû/GµwlÂÉ,IEND®B`‚routino-3.0/web/www/routino/icons/ball-0.png 644 233 144 200 12573351601 14166 0‰PNG  IHDR à‘bKGDÿÿÿ ½§“5IDATÓcüÿÿ?@æ0Â,X$Ñ5021˜p˜‚b"Ñ&¥ˆ‘€â ˜iXà ý2 qû±IEND®B`‚routino-3.0/web/www/routino/icons/limit-11.4.png 644 233 144 1314 12573351604 14650 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”MKY†ŸªN—mIÉØ¸2n‚«ø†eüíZÿD²w-¤f‘Up•ÅÐ{C$`ÀhHobˆ‚ßUuŸYôÇ´Éb6¸Üzï­÷ÜsïyÏA@À8Ž…XÀJåwaÛ(úìä¤>zT89©QôYØîï#Ä}2pT©DBäêjExmšžY¯ë»wÁnW¿×n·‡ëuMÓ3áuÿÿ¨Ï“$vl gf m—–´Ó)ÔÜ G­‡s;Â¥%…¶33Ã$‰qz——Sá‹››ª×j0Ë4Ë4„ÿÆ`Mƒzíæ¦Â——S§§ûׄ7®¬¨Þä××=‚ªyž[·4Ï-²Ì\o\YQx3x³'¦é©í¶¹†ð“£‚?[Áç½5MO…'Û®¯4WmµZ ‰£8„0Œ²Ýnû÷‡ªy¨×¶>Úlª5›–Ëe†ªÍfÓ$IlööÍúQEáìì¬ÔjªEþö­Âǘžòü9â¨T¢Z­¢ESSS„†óÖÖWWWüV­Ä>{>)•$IÀê«WÌÍÍqqqÀÚÚÚ-œ$ ;;;4 jµ{{{üóõ+÷îß'€1!DÜÜ0°Áé£8Š"ºÝ.*óóóìïïÓét888€(¢ˆbNO?Ñj€‰‰ ÊåòÐYš¦Œ°°°Àââ"»»»lll°ðò%¾xŠ÷ï)}fSÍ- ONN¼¼¼fs›e™!ÏÏÏýñí[·¾>ÌfOg‡‡=ÝôôóÿÖ“È/:»U!Ëu8*Úáwžkž~©€;­Í;íwÚÏî°Óþ ¶$o‡¼‹.ÀIEND®B`‚routino-3.0/web/www/routino/icons/limit-178.png 644 233 144 1416 12573351603 14606 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÃIDAT8Ë­”¿K[QÇ?ïŸéLHc¢éTÄ¡:tÐ]IÍàT(¢« @¡c³ë2Ô‚Cw‡@¡ŠH!HÀŽ(­Ú—÷ÞývHR¥:zàÀ=÷~Ϲ¿¾ßƒ2ÆŒÅã/krœª’I)•Š”LJŽS¬µ×˜v¢S(wŽ …¸à£<ï·¥/_¬NN¤_¿¤““V¼¸(yÞoÁÇ6Þiçƒ\ר» å?43#E’BYé¾µâPGG‘ff$ø¡¡¡œº»‘ë”Í¢ÙYOPÓÊŠ$ù’¬‚@ ÉÚ;ïÌIV’¯• jšõ”Ͷ¯ EÍÍIRSa¨Ð÷e­•µVAüsk­¢(Rðç¢f³…Ÿ›“ Øy³—ò¼†%Év =f $Ia(+YJž×¼Œ½‡¼{÷š·o#1®K¥R¡««‹««+Êå2µZƒƒR©ÇÇÇ”ËeÉ$ÙLÆÑóç‘óóç3ö÷cöõù³$EŠ"mnn*‹ikkKÕjUcccšœœToo¯VWW•Ëå4??¯í}û&IQôé“û†DâÆJ8ŽC6›åòò’‘‘vwwÉçó,,,0==M³ÙdjjŠþþ~n|Àhb‰Wc„ë`­¥P(0<<Ìõõ5§§§¬¯¯³¼¼L½^'“ÉP*•¨×ë¤Ói×cd°Ö¡Ùä¾Yk‰¢€ Òé4ƒƒƒ”J%ÆÇÇÙÞÞÆó<öööZxßkC£ñJÀb-===¸íÓV*òù<Åb‘úúú¥ðæ €}ý ÆwkZZ’¤°MH]\\èööV’t~~®›››ôð}_ggg ÂP ÃVÞÒ’kxÖ<àWëÛ¢»q<àÙ£ °÷ >F`{'«ÿð¤Ú|Ò®ñ¤ýì ;í_|ýIÿQ×gAIEND®B`‚routino-3.0/web/www/routino/icons/limit-11.5.png 644 233 144 1360 12573351604 14652 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“¥IDAT8Ë­”½kTAÅÏ̲o7/ ›%K¶[¢ H@´ [_Lä…Ä"i•ü‚¥öù ²D$°¥•Ä" A´’r‹5› $AßÇÌÏbwãúU. Ì™;çÎ˹WHBÖZ$‹$Êå‹H+ó‰JªUG¥Æ|BZéû…dû<¡A rÙ æçËHO Ão,.Âúº§Ó¯_¡ÓéáÅEÃoHOû÷MŸ/–RI4vˆ"h·ã½cØz8§ÝvDH;4(•DX11!ffB¤Ï,/$€'Ë ËÀû_kpHX^é333!ýoJϘ›Hó$ÁõäyŽs¿'˜% Yš’AÊ; =Ôì2axÈÎ9xÿG ï=ÿ´ÞžímÃC¤Ë…ÇÒ=xpƒû÷•ìÆ»wrÎillLÖZmllœbIʲL­VK¯ß¼ÑÇ­-séÖ-WêtFxÿ¾ ¤-šM÷¼Ù¤X,²ºº @³Ù$š=?Ýn—z½Îìì,÷â˜/?~8^¼ÀI[VçÎ]ÓÍ›ò’5…‚jµšI’1FãããòÞk`›››::: ÛQ¤z©d¹~]öüùkV… yIówïjjjJÇÇÇ’¤8ŽÃ’T­VDZ¢(ÒÃGôòÕ+™ZM°òÞ(MO/g1ÀÆIÒîî®Úí¶&''µ°° z½®½½=É{ᜱ:<ü ·o%ÉKÒè訊Åâi°0 522"@ÓÓÓj4Z[[ÓX¥¢«W®è^{µZ*|ÿþAH+,-ä8ÇÁÁ'''§Æûûû$IB·ÛÅ¥i·´ÒÊ/mo÷t“çüϼ÷=í9‡ï‡töWø,c8à°h{ŸçôÅ277ÔgÚ›g:5Îtžá¤ý ÆPI³KŒžIEND®B`‚routino-3.0/web/www/routino/icons/marker-46-grey.png 644 233 144 2660 12573351600 15626 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“eIDATHÇ}U]hW=ßý±F’=ÄŠ³DH È ±×ЂAJRHH©K )}ÐC÷a_vKi!‹¶ˆPØ— ä=ä-ŠÉÏCþ”ÀŠ6¸ŠI±©˜DÆÌJvd+ÈÍÌ{ojÍ:iw Ì\†sÏwî=ßG…B›`B S,ß·ÖþS)õGÏó,Âa#‘I)$¢/ …¿‹Å" ‚ Ð&)·Öjkí ”ò‚ïû+¥¬ëº”J¥À 1XZZB«Õ²RJêéé))¥þJD+DÄh€Yk5€]BˆJ§ÓÙ•H$‚£G²l6K‘HoÃóŸ—0ƄʈŒ10Æ@D°Ö" ŸÏËt:­666Þ•R~ÇÁ|ßÿÀ÷ýO‰„™˜˜`­ }ìu×»kBˆp㉉ ™H$ŒïûŸø¾ÿ³Ö~­”B.—ƒëº0Æ€1k-ˆõz­V+TÜjµðøñc<{ö Dc \×E.—ƒR ÖÚ¯Yï¹®k÷íÛǺ*Œ1 "ÌÍÍáâÅ‹X\\4›M\ºt ÷ïßÇåË—199V”Íf™ëº6‚÷˜çy6•JQ4…1&,½ÙlâÖ­[ˆÇãBîÝ»‡¡¡!œ;wù|+++a±X ©TŠ<ϳâWqìCñ<¥R ™LµZ-ô®Ùl¢¯¯çÏŸG4űcÇàº.´ÖàœwU3Æ97ívJ©ð@nß¾mÛ¶áÔ©SPJAJ ‚žçáĉĵk×°¾¾Î9 Óé€1f˜ã8zaaÁÌÎ΂ˆÐh40==W¯^¡T**• jµ¤”8|ø0FGGqúôiXk±°°¨×ë¨×ëÖqÍüCÁ*•JÐn·ÑÛÛ‹±±1ôöö"! µF__vìØùùy@µZ$“IÀÝ»w5ýŠKüÌ™3ß¿~ýzO»ÝYYY <È2™ öïßááa|ˆJ¥‚§OŸâСCÅÍ›7Íüü22cÌŽãL4w´ÖfÏž=ˆÛ·oÇÎ;FÑßß‘‘$“IŒcll sss¶\.³X,ö³1æ8ý‡çr9ADëæ¤”Ÿ...šÁÁAÖ-+™L"†‰rÉdýýýh·Û¸råJ`Œáœó¯Ü €€$¢oc#"~çε¶¶Æ´Öa<»¹ï^±r¹´Z-ÙÓÓsuxxø_€ {A±\ˆD"W[­–¼qãFðvö»j9çxôè‘™žžñx|Ù÷ý/fffÂÍù‘#Gº?ÓÒÒ’ÕZÿà8ÎGF#ÑõWköÆž?ŽÉÉI+¥$ŸÑ#"4°b±6uƘ`Œ-cò±X SSS¶Z­‚sö¥J¥Ràû>ãœ_ ¢«ä¦(‹`Ý—Mü_7ƒ`–——E$ùÉó¼¿?~[ ±i,Þ"þ¿×¯_àÉ“'˜ššB,ƒ1æ/Bˆr¹ÌØ­ã†oýø=#‘ÈG«««‰µµ5;;;«;—R~ d­ }Ü"êÑ Ø2²€ÀZ›cŒ}ëyžBp!D%›Í¾_«Õ˜ÖÚ¼MøFù¿cC×ßוּ_:ŽÃ9çËZë?ÏÌÌ@kÿ…_zA»#¡FÔIEND®B`‚routino-3.0/web/www/routino/icons/limit-139.png 644 233 144 1405 12573351602 14600 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ºIDAT8Ë­”¿K[]Ç¿÷Ö\Ã…Kåê(æÍRpHÝäm(:ŠC‚c6Ý\ü œ›ÅAœ[th–º¸*N–j‘‚Å‚:ä%b h’{ÏùtÈM«mG8žß<ç|¿„$\×Er‘D:ýÒ&Žó… €çÏ AŽói3ñ ÉMò„…ÒiÉ¡\N#½Á÷Û,-Áû÷–«+h6áꪯ/-ï·‘Þ$ñN’/áy.ÃÃb|<‡ôùy¸¼4@Œµ†‡Ò×c./ óó }c|<Çð°ð¯••]\\hccC•JEÿ¾z%IöÙÇR«õùÑo&€äöö–ûû{¢(âúúš(ñu:F6}Û£ß|„3âø{ì#°c~bÏ ˜ðÎþ`€}PðoàµQDÒô7<)7Ÿtk<é>{ÂMû`j|Ow€IEND®B`‚routino-3.0/web/www/routino/icons/limit-30.6.png 644 233 144 1501 12573351605 14652 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“öIDAT8Ë­”ÁK[YÆ¿÷ZcòLÚD”0¸8"¤eIjKnDH²Íý\¹Æe»w9!S 6˜•ÿBg‘MŒˆc¦J¢U 6yïÞß,[;¥œsï9ß=÷ò}GHB®ë"¹H"þiÇyG<ÃÆxçÒzÿ\Hn¿Nè(v …0Òs<ïKKðæåèÚm8:êÅKKàyŸž÷ó~½D(ä28(R©q¤ssÐl ÀZÃÍÕ‹šMÃÜH R©qE(äŠdRÌÏ{HïYYèßßk¿ÚõX ÃÊ H÷H&ûÏ”^Ëa ëw:˜nc ¾ïc­ý¦Aãûøºär ½¸þ³xÞ¹ÝÝíÝhÌ kkí÷~/ÏÚÝ]ð¼s¤w~‘Ö(•2΂ù«^w7Êe…B!©ÑhhssSÉdR‰DBÖZ¹®«ýý}ýöò¥"Κ͈S«Ý‘‘jT*ìµÛføþ} …©TŠjµJ6›ezzš©©)Úí6­V‹L&Ãìì,=âïósÃÖFª¹ŠÅÒzòDÁÇî¯kkÊç󚜜T¥RQ8V½^W,Óöö¶$iggG{{{ÑÌÓ§‰D\e2rîÝK»îÝ»ÈZMëç…•ËeÉó’t“(ˆ¤¥)SwuܨD0(¶(BÝØîfÄ`ÀeÝû'Lh-Ä­ÓÍ`™"v*XbWjLð×¢’Núòrïg&ŽYyáÂýÞû=‡{/ç! I¸®‹ä"‰––ï‘–qœD£pë–!Çù€´\?’[Ç 5ˆZZ$‡Ç[^àyeææàõkK±ggP,^Ôssàye¤õ~§Ž—hnv …Dgçm¤]ÒiØß7@ k WÇE]cßNƒ´KgçmB!ÑÜìŠx\LLxH;,,ø€% ÀÚfc,à³°Òñxý™ÒSS¨¾©V0ÆÖÚo.ø>AµJU¦¦@ZjüÙ]<ï³Íç±`1æ’¨Ab­ýa½Ï’σç}FºÛô‹´ÈììÎÓ§f{kËýõåKµ¶¶ª­­M»»»Êf³ŠÇãŠÅb’¤ ”ËåôÛ›7ússÓé5¡b±•wïšT“6Y]åOŸLØó&•J±¶¶F?½½½Ü¹s‡³³3J¥‰D‚ÉÉIžd2”¾~5¼z…‘6]ݼy_jÿãG÷§ùy­¯¯«½½]‹‹‹ŠF£ÚÞÞV8Öêêª$iccCççç4žN+ ¹>–¬Æ8®)—·ôö­~ÿÞÖªUår9E"Õj5 ©»»[ÓÓÓêëëÓàࠒɤ²Ù¬bѨ~¸wOO2«\NM_¾l i™çÏù jG……BÃÃC*• ÖZNOO1Æ`Œáääß÷9::jè±Æ³g -_êŒ|þB7uYk1ÿ§9c0`í}ã UØ Ë\‚ÿ½¶µZ£§Ê£GWp­Þ¼ÖÔ¸Ö<»Æ¤ý)9Y ¯Å)ŽIEND®B`‚routino-3.0/web/www/routino/icons/limit-25.3.png 644 233 144 1532 12573351605 14657 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”ÁK[YÆ¿÷,‰ó&ÒTh6-R(ÄÍ X¬K£h«‹@ilÁÅPügÙ.ݸ±‹ŠHÜèÂE S(j­`Ðn$$bŠ:è{ïÞ_&޳ôÀYœsÏù¸çð}GHB®ë"¹H¢¶ö¤ç3ñ8Ô×âqpœÏH3•w!¹•>¡*Pm­ƒäðäI-Òk<ï„ñqX\´Àׯpppƒç ½®Ô;•~‰HÄ%©T Òé4 ±ÖpÕ.âBÁNƒ´G*ÕB4*"W$b`ÀCÚarà°Xû¯Ws`s&'AÚa`À#‘¨Œ)½ah~p~Žñ}‚ ¸tkíåcÀgh¤7Õµãyßíî.,ÆT&²üŸ]æ/ê¬ÝÝÏûŽÔ^ó»ôÏŸÿê<{f¶77Ý?ß½S,S"‘Ђr¹œ¶¶¶ÔÖÖ¦h4*Çq”Ïç5ÿö­¢·n9Éû÷ …ÂOÎúzBil–¿¿|1užGOO­­­¬®®ÒÒÒB?™L†R©ÀÞÞõõõ “L$øÏ²YBiÝU,ö@©Ï»¿½z¥µµ5544hvvVAÈ£¾¾>%“II’1FSSSQcS“üoß\=|(ÅbÄ;Æ”Ëüõþ=÷îÝcbb‚\.ÇØØsss466²²²RY•áøø˜ÁÁAšS)6¶·áôsû¶qm8n$¢Íõöö*“ÉhzzZ¥RIÍÍÍUSS“ŠÅ¢$i~~^]]]Z\\ÔÏž§õ ©¦F6 לœlêãG}øôɆ¾¯¥¥%% íïïkyyYuuuêèèP:Vgg§º»»•L&ÇÕ~÷®†Ÿ>µÊfUszº)¤^¾äËÅ"ÅŠŸáû>‡‡‡c°Örtt„µ–0 )—Ëgg!/^€4sÉ3vw/˜}…gUNUÁªyc ƒùÏ®)À‚oƒ{!™k€×†ÕŸÇ¯(àFµy£WãFïÙ ^ÚR£p¾¦åÑ;IEND®B`‚routino-3.0/web/www/routino/icons/limit-13.4.png 644 233 144 1372 12573351604 14656 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“¯IDAT8Ë­”?K›QÆŸ÷hx…¾¶DëÒ±‚£-•:ƒˆ\ãÐ/àÜìâ ƒ-B‡ø2—(HÑ‚!8„"ŠÖX¨½~Þ$­µ£.œsÏ=çÏsŽ„$Â0D ‘D:ýi… øJW<{æèê‚ øŠ´Ò° )lø 5Òé)àýû4Ò¢è¹ ž“øñNN=—ƒ(ú…ô¡ñ?høK´·‡ttˆ!¤2Ù,T«°xïøû$º¥Zud³ •¢£C´·‡¢§GLMEHßX\¸<Æ€1àýŸÛ|ܲ¸Ò7¦¦"zziJyffîìí-.qÀ9‡1ç8c°pÇÌ HùfÍ^E?)—±à}È{ÿO†þžì­M"<:‚(ú‰ôBH+,,àÁlooS©T888 ŸÏ³»»ÛiFY.—ùR,XŸË´"¤=67ÜçÍMÚÚÚØÚÚâòò’8Ž™¥¯¯F†çÃÃü}óÀÙOŸ@ÚkÓ“'/õúµ¼©”2™Œ¼÷²ÖjyyYýýýªT*ª×ë’¤T*¥¥¥%Õëuug2’òê•Ç/ÅÓ§ŽósL£¬®®P«Õ˜žžfppR©ÀÚÚ½½½ÌÏÏó|hˆãïß¡VÃű å} »;51FÝÝÝ*‹S¡PPgg§J¥’œsòÞkddDûûûªV«:<<”‚@8´jfÀLNN²±±Àøø8q377Çññ1£££œžž°¾¾NöÝ»¤f?‚´×ê&`qŽ««+nnn0Æpvv†1ï=-ùúúšÚùyâ·°Ðêf³££„7 îÑÀ9÷€w$¶<»7Þš€ÿ#ks°ÿ`u6uk<ê>{ÄMûô‡¶)1v‹­IEND®B`‚routino-3.0/web/www/routino/icons/limit-179.png 644 233 144 1415 12573351603 14606 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÂIDAT8Ë­”ÁK[[Æ÷†\ó® ‹\wb]• ˜m)"nÄ€Y êÊ•ÿÀƒ·lAp#îܤà¢tºR °K Fb¢5jî=ó½E’>yÏ¥ÃaÎùfæœÃ÷ È÷}/@™Ì„`[žWS6+ ;e³’çÕÛ½s~/Ñ/”ÉxO¥RFðAaøK««ÒçϦóséçOéü¼¯®JaøKð¡‡÷zù  ð50€ÆÆ^ ¾kqQ:;s’™9=¶nœèìÌiqQ‚ï{©>Š"´´ êÚØ¤I¦8–âX2û×û{’IzÐÆ†u--…Š¢Þ3ᣖ—%©£$Qòð 3“™)ŽãßnfrÎ)¾¿—ëtºøåe >öÿì•°¥ÓSI²~¡§¬ß  Ld’éôT ÖàUêOø‹÷ï_S.;űïÕj•t:ÍÍÍ »»»ÔëuNNNÈår\\\P©T‰"†s9O/^8ïÇ?8:J!8Ò§O’ääœööö”J¥´¿¿¯Z­¦ééiÍÎÎ* CmnnªP(hffFSSSºl4$ÉY¥"Á‘ÏÐPwï|“ð<(Џ¾¾frr’ÃÃCŠÅ"ëëëDQDùà»·oah¨àãû"03J¥ù|žÛÛ[;;;¬¬¬0??O»ÝfaaããcÒé4¤Óàûò1óètxlf†s û?##LLLpyyI>ŸgnnŽl6Ëøø8^’€™çÓj}£Z0Ì$èݶZ­R,¥Ùl²µµE¹\æõ›7–úúZ­o¶µ¶&IIj6›º»»“$]]]©Ýnÿ¦Çýý½F—"]|¢µ5 ¶ÿÇ3%É“üê¯ÎuæúJxij'` >E`‹cõšþGϪÍgÏ:ÏžqÒþ•„D;Î&¢#IEND®B`‚routino-3.0/web/www/routino/icons/ball-2.png 644 233 144 205 12573351601 14175 0‰PNG  IHDR à‘bKGDÿÿÿ ½§“:IDATÓcüÿÿ?0"qþ3ÂX,˜’èþ321ÿÿgøOHQ&«á ì€H‡³ † öp 0¯oIEND®B`‚routino-3.0/web/www/routino/icons/limit-13.8.png 644 233 144 1501 12573351604 14654 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“öIDAT8Ë­”ÏK[KÇ?÷&$¾k5!&‘ê¡oU*ÒòÀÍ#”.DW"T³(‚Ð…þþÊ[¶{wnl„·PÚ• qQì*AŠ WYˆ?HPhµ7wf¾o‘Äöù¶朙9gæ Ÿs @¾ï |êêúC°*Ïû¢tZÊd¬ÒiÉó¾VÛûü¶¢¨«Ëxší¼Q|Ó‚´¹étr"ÕëÒÉIË^X‚à›àMû¼×ö%¾’I4<üHp¤©)©V³’Œœ³úUZ¶Q­f55%Á‘†‡)™D‰„úûÑôt øª¥%I %9E‘E’s?GgMr’B--IðUÓÓúûÛiÂ[ÍÌHRÓ„¡lËAÖZEQ$kÿû@Ûl* CY©©—/%xÛù³Ç ‚+ÉHε9çîdèngçœÔºÀ¹jU ‚+ÁãØ2üÍë×i~Þúàï}ú„1†L&Ãáá!ëëë$“IpÎáû>¼+•èíîöúŸ<±ªÕ~óö÷cöµ±!IöŸ Åãqmmm©Ñh(•J©X,jppP{{{’¤ííme³YÍÍÍé÷‡U>>¶zÿ^öãôö>ãùsø^,F.—Ã9‡1†••†††8>>& CŒ1AÀää$GÕ*7>/^ÀƒÏ|b1‘Hà€Ùb‘‘‘êõ:¹\ŽùùyJ¥FƒT*@½^'ŸÏ³¶¶Æùù9Ù¾>ð}¼XL>Îy4›t$Š"úúúØÙÙ¡P(°¹¹Iww7år€R©ÄØØ»»»A@¹RxgŒçsuõ™@OO××׌“ÏçI§ÓŒŽŽ211A¡P`yy™J¥B6›åϧO)¾zåøðØ÷jqQ’Œ¬Õåå¥nnn$IQéììLQÉ9§‹‹ IR†:==UôãGËoqQ‚ÕŸœU«-²¹å©«µö–³[ÝZÙ;œý¯\©ð.¼·º1jÃÝÔÌÌ/p¯µy¯]ã^ûÙ=vÚyVL*hÙR'IEND®B`‚routino-3.0/web/www/routino/icons/marker-84-red.png 644 233 144 2071 12573351601 15431 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“îIDATHÇ••¿kYÇ?sçÞ}…`DWÉQ·JA,Œ® !þ*¶O±’Wl«Á¦I‰EÄø Sh%Êng!ˆ…HÔÂ÷R}çY–aŒ!Iž?Îׯ_A`­­%I2 |îâl¼áP† @ÉÌÌLÚjµ”e™º-Ë2µZ-ÍÌ̤ ïw¨ˆ¸P…a¸hdd$®×ë’¤4M•$ɶ'MSIR½^×ÈÈHìÁK@”cÁZ{P¥R‰ X¼¾®,Ž¥$‘þAm¼¶¦´Ó‘$U*•µöž1J¥Ò (ŠÒF£!IJÖ×ÕCÙ öJm4Š¢(T*•ư־4==JRǹãÛ·Òì¬ôø±ÔnoêÉ©^Wâ·§§§S¯ö@Ößߟ-//ç¢$©V“@Úµ+Ïœ‘ÖÖ6ÕÞ¿ŸïÏÏçç³LËËËêïïÏü•#—$uÖÖr§óç¥ãÇóù›79`a!_¿|)íÝ›ï=x°Åo||\@j㜳¸r^¿†‹óùÉ“0: í6\¾ ccP.Ãê*Ýæ9ÆY³Ù¤Ýnc­ÍÁ>ä§Z-XYF#LLÀð0ܹ“¯wîÌ+(ÈkèË—/ƘHïÎÎæ_ôÛ7É9ijjóãœ8‘?û÷KGJ.äá>¬Î£G’¤¿ž=A› næöíÛÆÒv÷n²}ûàÝ»\íû÷ðñ# Á¥KpଯC©„€ÐZVßnÞLÀs—r¹Œsî> ÊÙ³‰$u$k¥ È:%}þ¼©üûw ”ÎÏK’~½q#õUõ(9pÎ-ªNN¦’×ëÒÜœôô©TCKŽÔn+™›“>}ÒüÇ™®A0T­Oö9cŒ€NÍ_•¢bz+ª¨ýf³©ÁÁÁ¢ö«Ý<ÖÚI@ƒQ´ÙTâx[í§þ%×®^M|o­lû_[ò ü€ŽWøç‘#G°Öšÿ ÜȯÃPƘ&ðsO4Ûìo³äkäÉ›êÅIEND®B`‚routino-3.0/web/www/routino/icons/limit-7.7.png 644 233 144 1247 12573351604 14605 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“\IDAT8Ë­”?K]‡Ÿ™¼ê2Hüb)¬ ,øÜÖ^¶pK+A»4~Œ¤I¯v)U,·°  ö…Z¨A‚˜¹÷I1»›ÄøÂ[xaŠû̹¿¹çÌïLÓTH¬Tæ…“䳓“:=œœÔ$ù,ìôß#¤ýsÈ@¨RI„Äf³"¼5˾»±¡>D¯®ôÛ7½º*÷šeß…·ýø¤Mù¹ªðÅ•½¸jaŒÁßW¹/¼¸®¬(|qn®êØŽŽ¦8;‹F&´ÝÚRý¡Fó\ó\cüõ ˜Fõ‡[[ mÌÙÙ~šðÎÕUÕ^ÌsóÇGó<7ÏscŒýKÅ!Ë¥hÏÕU…wƒšÕ̲®ççå‹ÂÿµÊ¸èù¹fYW¨ý¼amíu\X)¼ú÷ëWgdd„¥¥%æççét:y½^§Z­&.,„dmí5ïß¿Aøèþ¾…ÕÓÓSëõºËËË&IâÑÑ‘ª'''ðãããò‚ÜßWøˆÑËËÁ߲觹½½íúúz?£âY%¹¼Ô‰‰ˆSSÁ››R+”N¸¾¾vqqÑv»={ŽÅnntj*¤Ä˜ÐëB`ww—™™jµ½^N§ÀÞÞÞ‡HÓz=ˆ1Iév?ÑjÄ$FZ­F€ûû{šÍ&gggC@iµ Ûý„°ãæfYËÒ;ÞÝÝùððP¦‚···ÆÿàêÀÀ…›› ;ÿé³YŸ®!Ægu€Ea|bÜß»`(TÆ<é€íÍ/:Ï^pÒþƒÈÃOV¦.IEND®B`‚routino-3.0/web/www/routino/icons/marker-65-red.png 644 233 144 2152 12573351601 15430 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“IDATHÇ••MhI†Ÿªîš„Q$NÐ2ƒw&ˆobü D46\ðè-#,,Þ^6·„@VTÔ9ˆ/ë»7õ  âŒ`¼lLÔQc’þ{÷Ð=ã$î²îMQÕÔÓß÷V}o×°ííí ­­ísn d£Zçι©¶¶¶CÙ>Û™lô€øÎ97EÑ$uvvš½{÷âœ#I¬µ„aÈýû÷YXX1Æø¾_ Ãpø«…ÓüÂ6Ïój€ºººÂ‰‰‰¸^¯+IµF’$ª×뚘˜ˆ»ººB@Ù¾mŠ=Ï{ ¨¯¯/¨V«’¤8ކáWOÇ’¤jµª¾¾¾ ¿Š)ÖZ|ß¿¨¿¿?¤8I¬¬( )ŠZÓ”ÂPI(XZRœ½ëïïù¾ÅZ ¹\î0 b±×j5IR) öf×j5‹ÅP.—;ìc®&IRÑÀÀ€‰‚?—ƒZ nÞ„¹9èîσׯáÖ-xþž>ÅÎÌuwÓ¹y3m¹œ~¿}Ûc~H …B2??Ÿ&%IÏžI[¶Hë×K ;–¦66–ÎÛÛÓ±£CÉ»w’¤ù7oT(’ìÊJ’¢••tóÀÀн{R©$ÕëÒ‰Òž=Òâ¢ôöm*K+Ê´û€uÎA*Ôë05›6A>…\¸6Àò2<|°q#ŒÁñã†àydkdvv–¥ÏŸñ³–ay9…Á®]pæLª§GŽÀ°{7œ< Õ*&Kjnn ÁZño““é‰~øj6>ž–¿° #]º$}ú$}ü˜®¿/£èòeIÒŸwï HŒ1žçý¨T*…Õ™™ôÒïÛ'=šn—œ“îÜIod¤yh‰1ÒÔ”%õîØeM0N>ŸÇ9wPÿ¡$EHëÖ¥' Ò¹s)èüùtîy(ÎÖ:}:΀O|£M»œs/•‡‡cI ^¼.^”=ZÝOžH““ ?–$]»v-É€Ÿ1=  `Œ9h­U®_Oõm´h’4¯OÃ$iöÕ+•J¥Fï—[y΃ïûÀJÅâS ‚Õ½E͵¡¡¡0óÖÊÖ­[ñ<¯éP)Þ÷mOOιJf.©¾­†") CIÒèèhœg›îÔb{¬Y(:çj€Êårªo–Y£ìééiåóùµöǵe¯¯õ­TVe¸¸¸¨ÞÞÞ0³º_1ŽÿˆUú‹Å a‰’T.—eOù³g϶þ–þ=Öê»ÿþP’*•Š€ØZ+cÌÁ–ÿÛ7ES_ß÷k€N:•ìܹ³Qv9+ÛÿVà*}ÆQ–áÛ·oÇ÷}ûM}³ñgÏód­¾_SÍWñ7–ŽjÛ« ‘\IEND®B`‚routino-3.0/web/www/routino/icons/limit-39.3.png 644 233 144 1514 12573351606 14665 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”ÁK[YÆ¿÷,Iæ „LÍ"ƒ#B7%7a*¥‚³‘¨ÑlÛþ.Ý ºl÷.ÜU; T¡ú¸pÜE°BƒÎF‚(¡Z«¶¼÷îýÍ"qª­.œsïùÎ9÷òOHB®ë"¹H"û iÇù@{;$†övpœH Í{!¹MœÐM¢XÌAr˜˜ˆ!½Âó¾25kk–“8?‡““†?5ž÷éU3Þiâ%"—hTd2]H‡ŒŒ@¥b€k ·WéT ## ’ÉtŠHÄ©”Èç=¤ÌÌÔK@€µß÷ÍX ÎÌ HÉç=R©æ3¥×ŒcÀêuŒï`Œ!Œ¹Û ñ}‚z>ãã ½¾ù³GxÞ¥=8hTlo'°Öb­ýÏn4܃ð¼K¤G-Jó¼|ù»óâ…)ïï»oÞ¾U4U:ÖÞÞžVWW•L&•H$d­•ëº*—Ëz³´¤èƒNçãdžJå'§Tj‘‘J¬¯óÏù¹IÄã º»»Y\\$›Í’ËåÈf³T«UI$LNNÒ™Jñw¹lxÿžP*¹jk{¢gÏ~ùâÎÍÏkbbB]]]ÚÚÚR2™ÔÎÎŽ"‘ˆ677%I¾ïknnNÅbQ¿<|(ÿógWÏŸK­­ODG‡áÓ'®¯®¥§§‡ r¹ƒƒƒD£Q–––ÃëëkÆÆÆø5“aw¾}ÃÄãÆ }ßQk«þz÷NýOŸj}}]mmmÚÞÞVoo¯ÔÑÑ¡ÎÎN…a¨ååeõ÷÷kmmM?{žJ»»RK‹l:²R‰•®Àü10@<§X,r||Ìðð0étšÙÙY...èëëãè舡¡!âñ8…|žK0¬¬`¥’˜žƒZjµJÐ &µZÓÓS¬µc8;;ÃZK†¸Z dz¤…;<3Mž™&ø†S?rÎÆ`~àÙ÷ (|†wÀÿ³ÃÛèÞ§P¸5÷:›÷ª÷ªg÷¨´ÿIw}vì»%¡IEND®B`‚routino-3.0/web/www/routino/icons/limit-22.2.png 644 233 144 1502 12573351605 14650 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“÷IDAT8Ë­”1H\Y†ÿ÷dg&Ï7ò¢Â³y­"™" 6[)V¢HZM1•;DHzaëHÀ !…h dÙÁ $LÒÈ€b A\£ðæÍ½ßŽÙ1°.Üóßsçþó IHÂu]$Id2¿"-â8ï ho78Î{¤ÅÆ»ÜFžÐe¡LÆArxð ƒôÏûÎä$¬¬XáÛ78<¼ð''Áó¾#=mÄ;|‰TÊ%QtéÃÃP­ Žµ†f»ðëT«†áa>EwH§E*åŠ0##ÒffbÀ’$$`íç ÄÌÌ€ô‘0l|SzÆØjIcj5Œ1$I‚1W4µIc ÆØHÏ.gvÏ;±• ,ÄæÖZ¬µWïÆ`ÁÚJ<ïénËïÒ¦X.s#“a~~c »»»xžÇ§§§œŸŸsttD¡PøÿsrBppmmV5©ÈÛ·üùò¥ùÅuéíí%Š"†††èì줧§‡ŽŽòù<£££ÌÍÍáy}}}´µ¶²òîáÍ©è -jjj*Y\4Ç-‰$×u•ÉdT¯×DZ\×UŠãX©TJgggJ’DŽ1j¿}Ûd?n!ŸÏÿà•ʳ"èÿÚEœ¥‰gW6ÀBÍ& 6I°Mm&,@SÌOp­»y­ªq­zvJû/«»u¾ëÿIEND®B`‚routino-3.0/web/www/routino/icons/limit-0.7.png 644 233 144 1344 12573351603 14573 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“™IDAT8Ë­”=K+A†ß%É]üŠ")^c£""xKA¬$E´ôø.ÜR[I)‚ ø¬ÄÂRÁ€ ‚£Ebvgž[lüÄÒ{fç<¼3¼çIHƒdD"ñ)çÐÑ–Žð¼¤|ã¿L£Nè”HxHÓÓ ¤e|ÿ™…ØÝu”Jðø¥R”/,€ï?#-7Î{z‰XÌ‹tº霩)¸¾¶@ˆs–å!××–©)ÎI§{ˆÇE,fD*%²Y©ÀÒÀ àpî}½î^XZ©@6ë“J5®)­ËÔ Cl½N8ç>ˆrA­Z Aëär ­¼¾Y߯pvÕ„áÄ9÷ ø)Â0Rxv¾_AÊ4ý•þinîfg-A`¼æf]\\h{{[©TJÉdR’tyy©  žžª¥­MÉdÒ£«ËzÅâ/5 鈭-X€ûû{ ¯¯r¹ Àþþ>cccŒãy{{{‘@°lmt$ÚÛ77 õkkkŒŽŽ022Âúú:µZ €ÕÕUæçç°ÑUáæÚÛ]³ŒA±˜§FA ––IRkk«ªÕª$)«\.+ŸÏkggGŸ"“ŒÁÈ9Oõº^iétZwww*‹ºººRoo¯noo%I›››êîîV&“‘µVƘ¨¨^—œóŒ*•c¨Ir CMLLhxxXýýýš™™ÑÐÐ&''èððPÙlö]‘s’ätp U*ÇBʳ¸½e䬵<<<`­}ûvÎñôôDµZ}·Gt>dq¤ü·>³Ö¾A¿úì-ÿÆgßvŒûð Á¾tÀöæNg?8iÿdñp{œó¬IEND®B`‚routino-3.0/web/www/routino/icons/limit-3.png 644 233 144 1121 12573351601 14420 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”±N*Q†ÿ=1 Y‹ÝÐCAâ-Œ¥`è, ÅjkÀØJÏlÇkP¡… †Š‚ÄBŒ ìžóY°{e½hnÁI¶8;ÿügfþ™’„1É ‰jõÒÏ{"Š V³DxÞÒ0· Éä~BQµê!y\_W‘î ‚º]Ë%¼¾Âr¹½w»H÷9ÞËý%|ßP©ˆfóé™v d8gÙ=Û{Æbai·Az¦Ù<¥R¾oD½.:iJ¿°i i Î}}Å?pÀš~¤)N@½ž§) ˆc€ YYö7k-išbíN_˜ q Ò ¨Ù9A°b6Û¾¸Cäœû–¥+‚c6ƒ X! iH¯å)”§Ó)ƒÁ€Édò/áŸÑë4ÒI`‹¨Š”æó9µZ››ãñ¸dÏñ–$éáHax¡VK’ŒŒÑîɲLwww:99Ñ|>×z½–$[ÀoÔjIaxq$cï{»$&'=;;S£ÑÐíí­ÞÞÞ†¡$ÉóJpÉ÷%c0rÎÓfS²Yk%II’èòòR£ÑHÇÇÇz||”$9çÊd›äœ··fE‘ßßß¹ºº"Š"â8fµZ•EøV³Õü,ååå…tmŸš¿öY¡œµö¿úì× Ø×¼?OÀAgó [ã û쀛ö5ï‹“ùÎ IEND®B`‚routino-3.0/web/www/routino/icons/marker-48-red.png 644 233 144 2063 12573351600 15431 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“èIDATHÇ••?hTYÆ÷¾w'2…Y%OD²&ˆV©L\Á€ÒÅØl#+N±í®½˜&MüS˜hlÄBDØí,lDT¢HÈ «I1†d’÷ïÛâ½7™Œ»¸{àqæÌÜû½ó}÷~g`'ìž={,@WW×çÜ @@šgµ×ι]]]gò}¶2yö€øÁ97Çñ¤$õööš“'Oâœ#MS¬µDQijgÏX[[“1Æø¾_‹¢è*ðWNë ‡=Ï«êëë‹fff’F£¡4MÕišªÑhhff&éëë‹åûŒ‹ŽÏó>—––$II’(Š¢ož$I$IKKKsà@ÁZ‹ïû³€*•JX€…a˜uÇR{·I¢4 nmµÀ+•JÈ÷ýYk-”J¥Q@A$õz]’EQ `WtÔźz½® @¥Riß÷ŸšžžNþðÉ)—C’ôö­tû¶ôè‘Ôl*ŠcIÒôôt’wû íééIWWW[¡|¡îÝ“@šÍê¹¹¬Þ»7Ë##J›MIÒê—/êééIó+G266&IŠãxðåKi߾ݠ•Štüxöù͛췇•ïÐØØ˜€ÄÖ9€Ò<Ö×a|FG¡\†f3»#çÏëWpîLLÀÐŒŒ´Ü“ãX ¤+++4›M|ßG—.Áà ܼ ››0Àâb– ØØ€z¾~m9èóçÏ)ÖÚHîܺ•èë×’sÒ‰ÒÙ³Å#G¤ùy©»[º~}çÐŽU<1!IúóéS©1&´Æ˜ßûûµkqýãGüÞ^Òñq8p¶·¡T‚4…înؿ޽ËÚzÿ}ú„×ßÏ&ðË•+ `¬µw(—Ë8çîå—?’¤¸¸ìëëY§ssYýàAÆÂ ” IkkúùâÅ$wÕ+ \hÜçœû¨Z­&’nmIͦtÿ¾´¸¸CyyYº{WÑãÇ’¤ûóói¸iŒ(}cÌik­€¸V«ívV‡£ {®,/ë`Þ¯¶ã8c ¾ï_t0¥ܲÉöö7ÞOÂP’499å³µvèÐ!<ÏkM¨ Þ÷íÀÀιÚ.} 3tø}jj*ÉWZÓ©mìÑñEàœ«ïÒ7ﬠ½°° r¹œ²Öžï¤ÝßÕwccCƒƒƒQ>››f{s“X,Æîî.Åb‘ÉÉIfffp‡½½=*• Œ3òè_Á°³ƒ‘öEo¯åóg °³½Íàà ëëëݲVVVX\\ìâÕÕU²Ù,ŸW.—SÇ¢(R*•’$ýÚÛ«›ZMŠÇ%×垬uÔlvƒ­µ2ÆH’666400 L&£z½®Z­¦¡¡!éääDŸ>~Ôï##Rµ*WWWT(H’•¤d2)Ïó$I…BAAH’ªÕªfgg555¥l6«ÑÑQ= ý9=mõîÜëëBʳ¼ a ———Ôëu...¸¹¹iiËÎÏÏ1ÆÜ®VÞò2Hù[¶”E?éêGlŒc0?èì§°aH‡ð¿ˆˆ"Úân2?ÿ]ÜioÞéÔ¸Óyv‡“ö_„nü†íIEND®B`‚routino-3.0/web/www/routino/icons/marker-28-grey.png 644 233 144 2750 12573351600 15626 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“IDATHÇu•KhTYÇÿßyÔ½uC²”'P–”µ(*+ÒŽ (Ø` C+‚͘,ZaFÐÅtÓ4b¨ÂÍlF„Y¸Üˈâ&FQËž1CÁˆhLÊ@| 4•G½,‡û8çÌÂTutzþpàÞÃå¿ó;߃²Ù,VÅ„Èf³:—Ë}iŒù³ïû×u ÂÏ2–e‘”ò1ý˜Ífïår9h USnŒQƘ_I)Ï{ž÷ïû&‰P,c¬ã¨µF¹\FµZ5RJ …Byß÷ÿHD DÄ(€c€¸¢ÐjµâÑh4Ø¿?K§ÓdY>—ëº(•J¦P(¨åååoÇùRj¿1æ51¾gÏ GñÏóâ‰DÂ?vì˜Ü²e qÎaŒùŸ%„À¦M›(•J±J¥â/--E¥”¿ÕZ_7ÆÔùÀÀüõÇ{‰„üøqiÛ6´ÖÈc "}DkŒR Žã “Éð7oÞøïÞ½‹Ú¶½1ß`žç}åyÞP4Õ‡’mnœs0ÆÀƒ1¦cFD`ŒAÑÙ?|ø°ŒF£Úó¼!Ïó¾âûöíu]·g``À$ RJsŽJ¥‚¹¹94›MD"‘N´‹‹‹˜››C½^G$„ÃaH)M©T")åVÁ‘HÄôõõ1àœcffù|ÝÝÝh4H¥RB©TÂØØlÛ†ëºØ¼y3†‡‡ÁC:f÷ïß7­Vë æº®‰Åb‡;ÇÇöíÛqæÌœ>}SSS(—Ëxüø16n܈³gÏâÔ©S˜ÅóçÏŽã ‹‘ëºF|¼‡ŸóP)…t:¾¾>´#·m°cÇäóyŒŽŽ¢V«!™L"r¡˜àœëF£Á|߇”Œ1 B)…b±ˆ»wï"“É ‹áÞ½{0ÆÀu]xž‡f³ ×u‡­V Œ1-lÛV¯^½Âôô4ëïïaee—/_†ëºD&“ëºxðà<ˆ]»v.\¸€Û·oãèÑ£xñâ^¾|ilÛV ÀŸ„¬P(ÕjpõêUh­qòäId2xž)%º»»±°°XZZB³ÙĆ Š>êotñâE,,,Œ¾ÿþw©T*8räˆ8wîB¡8çPJ¡Õjáĉ°, —.]Akžž ãÎ;ºX,2Çq¦}ßßE###ðk)å?[­ÖæÝ»wëÞÞ^¶¼¼ Î9ˆA cýúõ¨×ëxýú5ÇA2™Äôô´¥®®®ÿh­wcfcLø·Öú[Û¶ï?|øÐ$“Iô÷÷w*¨ÓóŒÁºuë°mÛ6nÞ¼X–%ŒÑ,Á$ýÄ9ÿNkͯ_¿î¯¬¬€ˆ ”‚ÖºócL§/LLLµZM†B¡+½½½Àíõ‰ˆíܹó¼mÛWêõº¼qãFÐνv‰¶£åœ£X,êG‰®®®yÏó~xòäI§xøÞ½{ÛS¹\6J©Ù¶ýõÛ·o£J)½uëVRJu c ‹‹‹3RJð{"*‘ €år¹NSgŒ ÆØ¼Öú¸ã8˜œœ4¥R œsh­ADð}ù|>ðÆØO®ë*!BÒéô—Ïž=cJ)ý¹á'Çÿ m¾7ÆühÛ6çœÏ+¥þ055¥þŸþ æu͸ê·ÓIEND®B`‚routino-3.0/web/www/routino/icons/marker-14-grey.png 644 233 144 2451 12573351600 15617 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“ÞIDATHÇ}•AhTGÇÿß73û^v•¸.‘Êš5É!& E´qAAOƒ1^šC{(H+Å‹le–¬à½Ç² ãÅÅ–€ J‰1ŠÈ.5vm4ìFÝÈ{óf¦w_7šö3‡ùß÷{ß7 …Úb)% …‚-‹‡œs?j­? ‚À ü+çy)¥~'¢³…Báv±Xä(ŠÀµM…sÎ8çú”R—Â0<¡µvétš²Ù,˜9v´ÖbaaFÃ)¥(‘H”´ÖßÑßD$ €s@¿”²Òjµú3™LtðàA!Ïóð¡‚ Àüü¼«T*fyyùD2™üÌsÐ9÷±Ø¿¿ð‰”ò·0 ûôøø¸Êår$„€sî£%¥Ä¶mÛhxx˜—––ô«W¯2J©Ï­µ“ιN¥RPJ]X]]Ý‘ËåôÄĄڴi¬µ"3¯YEz{{111¡r¹œ^]]Ý¡”ºJ¥Àa ÃðT&“±ccc œs ¢Øt=I)ãýØØ˜Êd26 ÃSaaçÜy­5òù<Òé4¬µ "šÍ&ž?ŽN î€Õj+++€t:|>­5œsç9Š¢½étÚŽŽ203¬µ‚år·oߎÍ:çææpùòå5GGG9N»(Šör.›ÍROOŒ1€Z­†‹/¢V«aãÆñEfÆ‹/pýúu¤R©µ===Èf³ã÷Éñ~Û·oÇéÓ§188ˆwïÞ„‚¥R ÃÃÃH¥RÐZ¯AÓöaBØ×¯_CkYÏóÐîŠøܸq[¶lÁÑ£G†!”Rk’iµZ`f˾ï›Z­fçææâRºÕ1­×ë¸ÿ>Þ¼yƒR©"B¥RÁÓ§O!„@µZEµZu¾ïð½”’+•JÔh4À̱Q§GÀ÷}ìÙ³6l@EBt—Œ›7oz¯ŸyëÖ­?$‰_–——åµk×¢Ç1@oo/Ž?ŽññqœŸÇÐÐÊå²­×ë"‘HÌi­ÏˆÝ»wÃZ{Ï÷ý±z½¾Ùc‡††¨ÓýýýؼyóÐ×ׇ<{öÌMOOs2™|g­=LD13KfþÓZûE2™ÄÌÌŒ›ŸŸd³Yìܹs "‚íd055yž":GDOˆH2€€"¢;Ìü-‰©©)Ýl6ãAø/MOOGFC%‰+»víú ˆ:¥&"Þ·oß%Ïó®4 599­7û©º{÷®}ðàL¥R‹a~7;;ãè𢅅gŒ¹çûþ±z½ž1ÆØÁÁA2ÆÄ]ÁÌxùò%®^½ê”RàK"ºKD€.‹qm¾‹ÖÚ‰n¾Bˆ8C­5J¥R†! !.ѪÅbÜÙ´õ¿| R©ØÅÅEéyÞ“ Î>|݆hƒÅÆñ-—ËcZf©®{ôDHy›Ë„…«««‹Ånr¹\fgg§[%@¥Raee…Âî.@hs9ò ¥}¾|a·R1?º.žç‘L&) ¤R)<Ïë‚×ëuÒé4³³³üüì]_>}ÂHûŽúûŸÊóTýþÝùõí[moo«¯¯O‡‡‡Z^^Öíí­Õ‘­­-U* iòùs ÅãŽÒiE‰§Î==Ø›e^¼ÐÌÌŒFGGåyžÂ0Ôúúº¦¦¦´··§ããcI’ïû- ÉIýþþ½þøöMzôHV±Aq¢Qýyt¤ééi-,,hmmM’4>>®ƒƒœœ¨X,Ê÷}Åb1õ÷÷kqqQÃÃÃ:©Õ$ÆDäKû|ýÊo?šÇabb‚D"Áææ&d2ÆÆÆ¸¼¼$›ÍÇù%›%ÇXi_HyÞ¼¡áßµµZÓÓSFƒ««+Œ1\\\`­% CÎÏÏ ›M€×¯[¿Ù™3J¥Öd›û ú¯Xk[#b ææ¬Ë ¾ l‹2÷îž„a'ÆçåË; xPn>èÖxÐ}ö€›ö#Ž=s ÜIEND®B`‚routino-3.0/web/www/routino/icons/marker-94-red.png 644 233 144 2062 12573351601 15432 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“çIDATHÇ•U¿OTYþî}÷ÎÀT šMœGˆ²„ÿÂ:ÑÍh‰Xlk ®a Ú¥±±XšiÐPhÀ)Œ‰•&fM,(lHÄ„Æ8C1…Y™ðcÞ}÷~[Üû`²Ñ=ÉË}ç½{¾{Î÷Îùpf²§§G@>Ÿ¿¥µÞ@.¬ìôµÖ›ù|þ„8™‰°F,€_´ÖËišÞ#Éþþ~166­5œsRƒ ìïïS!”R5cÌ€:pNO¸EQ‹Å¢YYY±tαӜs<88àÊÊŠ-‹CÜõ¬â,ã8Š¢Oêõ:IÒZKcÌ…ËZK’¬×ëOð€ØÃJ ¥Ô ,•JI–´ÛtIB¦)»Í9Çää„6¼+•J *¥^H)\.7€qÛF£A’4íöy”Y·oh£Ñ`Çs¹Ü”RŸ°Z­Z’4Iâ··ÉgÏÈσf÷ïÞ‘õ:Mx\­VmÈö¸¾¾>···çK#ɵ5 /]òëƒ>2;0{¿¾î÷;ǽ½=öõõ¹Ðr°år™$™:çûûÉùyðá™Ë‘Ÿ?{s“¼zÕƒ¾|éãNNH’år™¬ µÖ ¤)Ðjƒƒ¾/ŠE I€¯_½ç05 ÀÑ:-àH À5›MCY öö‹‹Àä$pû¶P ˜ŸFF€§O=`o¯Ÿ ághww¤” »ººê¿¨µd«E>yBNO““—/{ÿÊrt”œœôå߸ÁôÍÏÒû÷à„‰Bü @.--¥oß ¤„»{ØÙÞ¾õærÀô´ÏüÚ5 Ýr9@¤Žüñè‘ ¤”«( ÐZ¯`ibÂdZ«ùL²xýÚ¤lZ- ]_'Iþ~ÿ¾ Sµ q\ÔZï`eaÁ’dòå‹ïÓ­­³þ4ÆÓ<N~ÿÎõW¯\<B g€*}SJIi-´J61ì•lö›Í&²Ù¯tâ€B@)µ€q|&*ư۬s¤s¼73c‚¶ÖEÑ©B…ŽQrxxZëZÏo— ˜pÈòò² €ÍSuê=t=ˆµÖ ¬T*žß0žYÙÛÛÛ, ¥”3ÝewÛE~kµsrddÄñø+4¾Æì¿q'™$’d¥RÉÊÞP˜››ëü-ý·uó;ú·V«yÁ’Bˆ›a{ôCÀn~•R œu£££YÙ•P¶úYÀsüøMAiÈðï¡¡!(¥äÿ<å7¬‹QQJÙðkW5ì_^—i°ÿ áIEND®B`‚routino-3.0/web/www/routino/icons/limit-35.9.png 644 233 144 1520 12573351606 14664 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”OHÛYÇ¿¿_ÕüiÕ(ˆDM6ÈzØ<Ù¥PqÁC¢`rÊa-¢^¡çe=¶wï UlmsXÁ£ r ÔºØ= Ù ´› I~¿÷>{H´öèÀfæ½y3ÏŒ„$\×Er‘D0øÒŽóH ‘8Τ­N\HnçžÐu¢`ÐArÈfƒH/‡¿²º oßZ..àò..Úöê*„Ã_‘^tÎ;û==.€‹#}"†rÙ>ÖnKÛö)— é4HŸ‹ˆžW ‹……0ÒG66š€ÅóÀóÀÚozí 4ÙØé# a†‡;mJ/Y\Ä@Ëk61­žçݨµö¦@Ójá5›h±¸ÒËë?›$þbOOÛ/ÓéÈòb­mÇŒÁ‚µ§§Aš¼÷›´É³gÓÎÒ’ù«TrÿxõJ¡PHÑhT{{{:<<ÔÉɉ&&&ä8ŽJ¥’v_¿ÖÐÀ€381a(—CN±xOF*òî_^šÁþ~²Ù,ãããäóy‰étš\.Çùù9¥R‰D"Áôô4?=|È?¾oxó#]õö>Ò“'ò?vßÜT&“Q,ÓÑÑ‘êõº¥R)ŒŒH’ …‚†††t||¬žPHîì¸J¥dïßäº]]ÈZýë×¥%íìì¨V«)‹)›Íj~~^ëëë:88$ÍÎÎêêêJsss:yÿ^ÝÝÝRW—亸~«åèÁmïíéçÇ•ÏçÕÛÛ«ýý}%“I-//+ªR©¨Ñh¨^¯+™LjffF‘ÅãqéêJ8²R‘Ý]þóËÓ§ôõõ‘Ëå( LNNÒßßÏÊÊ Õj•©©)ÎÎÎH¥RŒŽŽò¼Í¥a{¤¢¶X[ð½FƒjµŠ×“FÇ6Æ`­¥V«Ýø+• ¶Í£ÏÚH[ßqf:œYkñ}ÿ†µëdל™g,·8û6™ @Ëzøþ÷€ÞßǶ«o‘ÉÜš€;Í;ÝwºÏîpÓþe=c-iÓ*ÍIEND®B`‚routino-3.0/web/www/routino/icons/limit-100.png 644 233 144 1341 12573351602 14563 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“–IDAT8Ë­”ÏJ[[‡¿s®59F*èDzÁZñ ªNK/EA_AûNÚ™Ÿ …Ž.>€t\ #¢‰j/FŠi’söw‰­¹½ClØ¿½×o-Ö_ŒãXˆøSØ3ŠÊëÓ§¹ÃÃEea¯ûwyȽ¡Hˆ\_ÞX,~wcC?|^^ê·ozyÙÁZ,~Þtõ£.ìï-prò™pâò²^\äjf¹¥ƒ3/.r——Nœœ|f¡€ýý1ŽáÊJQøâö¶jS ¶ÛÚnk¿Îý›µéö¶ÂWVŠŽuÄ·®­©¶Ì2³fÓ<Uó<·Ýnâ? ­VGmMáí}Î^X,Ö­TTCÖlþ$†zîyžÿÂYfÐ`¥¢Åb]x°çæ¦jÖõæÑÑ‘§§§ª»»»ëÙÙY>??·oææ¦ÂÂ'ß¿WÍÍs÷÷÷íëëóààÀ,ËLÓÔ4MµR©¸°°`š¦NOOûÏׯªyx÷NáSL©ô’ׯâ DQÄÈÈI’pxxH¡P \.3>>ÎÖÖ£££”Ëe’$áïÃÃïÕ+(•^ÆÄ±ô÷B`}}™™!(•JÜÞÞ’$ I’pww€Ož@BD«ÅCQiµZLLLpuuEµZåää„¥¥%jµÕj•Z­ÆôóçDY!D1õúgŽŽ!044D£Ñ`nnŽùùyÒ4eqq‘¦¦¦HÓ”ÕÕUþê¤'üññ#ÔëŸ{ªÙmHonnl4?ûêúúÚ<ÏÇýžjöô™Yö`zB‘ÜnÿoŸý6áÁ{£=¸Ý¶ëô?ð¨³ù¨[ãQ÷Ù#nÚ^Ýlý× ßIEND®B`‚routino-3.0/web/www/routino/icons/limit-159.png 644 233 144 1415 12573351603 14604 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÂIDAT8Ë­”OK[[Å×=5×xz5>‚Hê(¨`§>JÁà@ÍÀ ³B"úÇÞ°û ê´£ ‚àÀA@;(˜‘XLÐGÑjÁ$÷žóë ‰µ}}37ìÁÚ{Ÿ}8û¬µ…$$aŒA2H"™FZÇó>†Ð×g Cð¼Hë­¼LëœP»Q2é!yäóI¤7Á7–—áý{G¥_¾@¥ÒÄËËßÞ´ê½Öy ß7tvŠ¡¡çHefgáüÜ1ÎY[ÇœŸ[fgA*34ôœÎNáûF¤Ó"— >±º PQQÎýðv Pgu¤Oärétë™Ò[æçÄ1q½Žu€(ŠÀZKT«afýüûKú[…ŸzýÚEÆø¾¨··W»»»Úßß×ññ±FGGU.—µµµ¥?Òiõõöz¤RÖûü¹K¥Ò3!•ØØ°XËöö6ìììEýýýÌÍͱ´´ÄÞÞÙl–‰‰ ÆÇÇù·Z°îÝ;JF==/ôê•$ò36å²B¬5\~MR.ÆÆ@úL*u‡ŽÑÞîŠDBŒ{H»ÌÍ4K@€µÿÙ¹,Ð`n¤]ÆÇ=‰Ö˜Ò &&0àÆ÷±ÖÁ…Yk/4¾OÐh`Àgb¤ç;ëÅóŽl©„‹1Xk¯$_´å7¦ K%ð¼#¤Þ¶ß¥?xüøWçÑ#³“Ï»½~­îînÕëu­¬¬¨X,ªP((*Ëq‹E­¾z¥Ž7œä½{†rù¦³½Ý¦PÚ&—ãŸ/_ÌžG&“!N³´´ÄÐЃƒƒ8ŽÃúú:¥R‰®®.&''I&¼+ ¹¡´í*½¯¡!•‹E÷·gÏ´¹¹)@ÚØØP6›ÕÌÌŒFFF$IÖZÍÏÏkjjJ?Þ¾-ÿÛ7W™ŒÞñ¸1• ¿}K__ÓÓÓN§ÙÝÝm­©É”““²Ù,?¥R|ØÙ³3Ì­[F&µT«|(¸‰°°°@µZ`qq‘L&@­V£Z­²ººJ?¿ôöòçË—P¯tvZלžæõþ½Þ}ühCß×ÚÚšzzz´µµ¥|>¯ÑÑQIÒññ±†‡‡500 d2©X,¦Þ»w59=m•Ë©íì,/¤ež>¥aeo½–ÕëuŽŽŽ¨Õj#b­% C*• A½òä HË<£Tj2Û˜ïóê6Æ€1˜ÿñìŠ,ø6°MÉ|·axãóàÁ%\«6¯õj\ë=»ÆKû/÷A”`[¥[ÒIEND®B`‚routino-3.0/web/www/routino/icons/limit-1.1.png 644 233 144 1107 12573351603 14563 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“üIDAT8Ë­”¿J3AÅÏŒ¸I¶I!eÀ¯+ÛT¶!Eö’ÈchŸw|ˆ-­ !‚)Òˆà‚(îÎÌï+ö’¾"öž=çÎÝ™;WHBÖZ$‹$Úí?H Œ¹£×ƒƒO¯ÆÜ!-ªïB²•O¨NÔn$C’´‘.ˆã7¦S¸¾¬×ðòëuO§ÇoH•ÞT~‰(²´Zb08Bz`4‚ÕÊŽ<ßQÆŽÕÊ3ôÀ`pD«%¢ÈŠ~_ŒÇ1Ò=ó9À'( ( áë©9À'ó9H÷ŒÇ1ý~õ›Ò%“ @NQ€÷8çðþga@É8Wê'.ë=;&Ž3–ËrEçpÎBØš¨áËdåâ8C:Ò‚Ù ÀQ8MS«­ ÛùÏsøž#$! ×u‘\$?BZÀqöH$àþ}C"޳‡´Ð;’Û«ê…Ã’Ãóça¤×D"-ffàÝ;K­ggP«uý™ˆDZH¯{ùN¯^"t …D:ýéˆÉI¨V àc­á6º¾Oµj˜œéˆtú!¡]‘J‰|>‚Tan  X<<¬ýiýX ÍÜHòù©Tï›Òž=èøí6Öó°ÖâyÞ³Öþx étðÚm txú¤7ýžeˆD.8:Âk»7ÿ/¬µ]bc°`íá!D"H™ÀÒŸ*gzÚ¸’[úøQº¼¼ÔÒÒ’*•ЋŔL&å8Žö÷÷õ×Û·Š…BNjxØP­þæ”Ë!•YY0¯¬X[[coo‘‘FGGq‡ ¶··‰Ç㌑âóׯ†÷ïñ¥²«{÷ëÉYÉu¥R)5›Me³YíììhjjJÅbQ¹\N’trr¢ÙÙYmnn*k÷Ó'W¹œˆF‹dÒP¯ÓïÔøø8‹‹‹Ôj5†‡‡©T*ø¾ÀÖÖÙl–é/0ß¿c ãÊZGŽú°ÖÊ#IZ^^Öàà 2™ŒnnnT¯×U.—511¡B¡ ùùyYIj·åX븺¸ØU©$©F£ ƒ’¤R©¤|>/Ij4* Z__—$­®®jèÁ­}ø`õå‹üfsWH ¼| àc ççç\__Ðh4¸ººêjËÎÎÎhµZœžžr||ÌÉ·o\ƒÏ«WXiá§Î»Êîõå¶®þÆtóoéì— °žGŸðßD}ßz^×~™€;Í;ÝwºÏîpÓþ_*sØÒ…IEND®B`‚routino-3.0/web/www/routino/icons/limit-13.5.png 644 233 144 1473 12573351604 14661 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ðIDAT8Ë­”OK›Y‡齃4¢‰Š&(¢éÀ@72]–A»Št3A­¡‹búü#³l÷âÆ %â® )Ó0.„ e 7ºÈCýGkúæ¾÷>³Hbmgë çÜ{Ϲ÷žs„$$áû>’$¢ÑŸ–ñ¼$ÐÝmI$Àó> -7Î…ä7ü„š¢QÉãÙ³(ÒKb±ÏÌÏC>ï(•àÓ'(•êöü<ÄbŸ‘^6î{ ‰¶6ŸHD ÝG:$›…“ „8g¹-u;ääÄ’Í‚tÈÐÐ}"ÑÖæ‹dRLLÄ>²¸cÀpîÛjîAúÈÄDŒd²‘¦ôŠéi€ZغÖZŒ1XûýM`j5 Ôxú¤WÍš= »äðœkrÎýá÷6õ‹]"=hù]úC¹Ü¯¼xa}Éÿ{gGaª»»[ûûûZ[[S$Q¿$É£­­-ýõîþÙÛó~~òÄFJ¥{‹-BÚc}Àþ¹¾Nkk+›››œÇ™™™a``€J¥©TŠÉÉIžÏÎòïׯ–ׯ±Ò^«:;êñc9É÷ZZÔÛÛ+çœÂ0ÔÒÒ’utt¤jµ*IÚÝÝÕÕÕ•ý–Í*‰ø¯ööv‹E:>>V:ÖÜÜœR©”NOO%焵ž¯ËË÷*$ÉIRGG‡®¯¯•ÉdÔ××§D"¡‘‘kllLétZêJ$ôËȈžÏÎ:mm©åË—÷BZfa ÄZ...¨V«užŒ¡\.cŒÁ9G¥R Êå2¶V«û-,€´ü³ƒƒ:7axÃUVkí g7ºµXpîgÿëg Í€?ÂÚÔ]Ò€»Æôô­¸ÓÞ¼Ó©q§óì'í-ÉvÿVñIEND®B`‚routino-3.0/web/www/routino/icons/limit-160.png 644 233 144 1366 12573351603 14601 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“«IDAT8Ë­”ÏJ[[Æ¿s$1“¨At(æ µBebÉuæDQ0¯`ÀÇhf|€Ð‚BG—Nœ…‚ ‚¬569û¬ßä¤5½wè‚ ûÛ{ýa­õ­%$! ß÷‘|$‘Jý…´‹ç5™˜€\.bb<¯‰´ÿ É턎R)É£\N!½#~°µ?77ðý;ÜÜôñÖÁ¤w±¾ÛK$“>££bv6Ôbm ®¯#Àañ\úØq}±¶R‹ÙÙ<££"™ôÅÌŒX_¾²½ ÐŒ0„0³ßgðtÙÞé+ëë33qšR•ÍM€Îáº]"3¢(" C¢(úþÄz½¾þæ&HÕAÍ^mNOÌu»XìÈÌ~ÝÿÄæÆé)Aéµv©T\z½Îùù9­V‹jµJ£Ñàää„...ˆóuT* í ©Á‡QÄÞÞ‰D‚ýý}ŠÅ"+++,//s||L±X¤P(°°°Àý·o‘½RÃ×øø•J’äÈó<år9¥ÓièììL“““Z]]ÕÑÑ‘FFFÔl6•ÉdôϧO}»·o¥ññ7¾|%“’$3S¹\Öââ¢:ŽÌLSSS*•JªÕj:<<Ôôô´$)“ɨÓéH’H$$ßÇ—™§^OÏ™)N+N«R©(›ÍÊó<ÝßßëòòRWWWZxõJ’ä9'™y¾Úí/ª×%Éd&IÊf³z||ÔÒÒ’æçç566¦|>¯Z­¦¹¹9 mllèï~yläóg©Ýþ2Ô͘<<<ðôô€sŽÛÛ[œs¿xvww×ç]_¨›C<#6ðê9Y‡pþ/Ïþ3öÌáÀéCâ LÀ‹Îæ‹nÝg/¸iÿOBidoE9óIEND®B`‚routino-3.0/web/www/routino/icons/limit-4.8.png 644 233 144 1305 12573351603 14575 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“zIDAT8Ë­”?KcAÅÏ›"†×(›  ‚àÚl™"¶"XX‰ Ûi«@ðKÄÞ.`;?€…ØÙD1(lD .lļ÷îýmñ’¬‘-˜bîÜ?gΜ{…$$B@ H¢XüŽt@]31ß¾E×Hý{!…~œÐ Q±!EüüYDªÇØÞ†ãcçé ~ý‚§§ü¼½ qü©Ö÷úñ…B`lLÌÎÎ!µY]…‡2Ü+?g<<«« µ™clL ALM‰µµé–Ý]€à¤)¤)¸ÿÛ8Ðcw¤[ÖÖb¦¦úÏ”öÙØHHS0ÃÌȲl˜™‘¦)–$ß%ll€´?àìqü›»»¼¢zá¨ÍódÎÝÄño¤B:`g #M1Ëij·Ûœ \]]Q«Õ¸¹¹É&I·³Ò.9:0ÏùÀ̘ŸŸgyyyˆäää„r¹Ìææ&3334›ÍÜŒ£#.ƒÆÇ+Z\”¤… IÚÛÛÓûû»J¥’ËÌDZVVV4==­··7õi Z\”ÆÇ+A! BA&I!èððPFCKKKº¸¸Ðýý½$©ÓéhrrRõz]///*—Ë’¤H’ )‚Ü#%ÉAA•JE­VKjµZ235 -,,èôôTq«ÙlJ’\’’DrF8#ËHû¼ÕëuÖ××qwªÕ*çççT«UJ¥[[[t»]pÇ?pößß43ºÝ.¯¯¯˜Nw§×ëñüü<,ØðÈoŽêì“P? v 33ÃðIg£euƒGÄêΟOð¥½ù¥SãKçÙNÚ¿3‘¥Ž]7ýIEND®B`‚routino-3.0/web/www/routino/icons/limit-1.8.png 644 233 144 1255 12573351603 14576 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“bIDAT8Ë­”1K$M†ŸaÔI”cPA¸‹£C05ÔH ÜÌX€±¿`/73\1¸``°ñr,œpà‰ˆzè¡ìÎt?_0»ûz¡COW¿ouUuU! `š¦B*àÔÔ'áÐ$ùáì¬~øœÕ$ù!ÏÒ!ššJ„ÄFcJhšçÜÝÕoߢ××úû·^_×ûÝ]Íó?BsˆO†|0ËR''qié£ðËÍM½º jeŒÁ¿¥ÞW^]77~¹´ôÑÉI̲ççqk+~º¿¯ÚW£e©e©1þÿtÕ¾ûû ?ÝÚÊŸ† _ÝÞVX–‚UUÂKÇB–ei ´ªjüö¶Â×QÎ>›ç=/.ê«ÊªªŒ1¾Š0¾ÐÅÚXôâBó¼'|F8toOµ²,Ç„v»íåååØ#Õn·k³Ùôüü¼68Ô¼½=…C„ï¶Zªa˜ONN̲ÌV­WõôôÔ¢(ÜÙÙqqqÑN§S_¤ÁVKá{ÊÌÌÖÖR&&ˆ1’$ EQcd$!ò??«zww§j¿ß÷ææÆr„«×¯ù¦Îþ%!„qÙ„Œ£NxUg/; ªôUѾùbÞvÀ»öæ»Nwgï8iÿ¼Fjknnš¯IEND®B`‚routino-3.0/web/www/routino/icons/limit-70.png 644 233 144 1277 12573351602 14521 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“tIDAT8Ë­”¿J#QÆ¿™˜ ‰†˜2à6lµpAð4El,⬶Ô*Mj1,|_ H ‚†¤ð_$ÉÜûÛb’øge«\¸pÏÜï|wÎ9ß9B’p]ÉEñøO¤*ŽsE*óó†T ç ©:º’;òÅã’ÃövéÏ{£T‚‹ K· ÏÏÐí†v©ž÷†t4Â;#‰XÌefFär‹H7lnÂý½¬5|\¡poØÜé†\n‘™‹¹"›…‚‡Ôäà`X†CÁÚ÷=þppR“BÁ#›…)S,øv8døa[k±ÖNÎAâ‹EŽÇ9[Âó^iµÂCЗèB²OgcB|«ž÷Š´ù-ýÑÞÞ/íî|ßu¢QÝÞÞªV«©ÙlêúúZétZ½^O§§§Êf³š››’ce2Fíö5!5¨×L0pyyÉÚÚD£QÎÎÎX__gyy™|>ÏËËKø—aþ õ:H ‘LZ:q<£P+• ‡‡‡œŸŸ³ºº ÀÊÊ '''!Î÷C¿N’IëÊuQ,¦ñ‰Dôøø¨jµªr¹,ß÷5;;+IJ$ê÷ûkT’‹I®‹+kùþ„Ì#IªÕjZXXP&“Q:ÖÃÃÚí¶îîî”Ïç%IŽã„N¾/Yë|ÊA0 qkk‹J¥2©àÎΉD‚r¹ü^ær&UÙßF—ôz=úýþÄ6Æðôô„1æ+YÀþ>HÕÿê죶Æ$ÆlX¥töm¢¯âeLômLµ7§:5¦:Ϧ8iÿÃÝ–³œAIEND®B`‚routino-3.0/web/www/routino/icons/marker-77-grey.png 644 233 144 2477 12573351601 15641 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“ôIDATHÇuUAkTW=ßwïyyƒ„É[TF!:hq"¡ÓLAAwjv‚Ù4`»è¦ ÅLË,Zº©¿ Ë…4"ga§iDÐc£)ØÐd’™ŽÌ”÷î»÷vÑ̘‰í ïxçžï|ß{— …vÀRJ [,O;ç¾ÕZ¿†¡@x —L&I)õˆˆ® …ŸŠÅ"Çq hGT8çŒsî=¥Ôµ(Š.j­]:¦ÞÞ^0s[ÑZ‹ÕÕUT«U§”¢D"1©µþŒˆþ$"ÀHìœ3K)ËFãpñ©S§8—ËQ2™Ä^„aˆ¥¥%W.—ÍÖÖÖEß÷?0ÆœrÎýND,Nž<é”RþEÑá#GŽèK—.©l6KB8çÞYRJd2à ]©T¥Ô9kíι¿8•JA)õu³Ù<”Ífõøø¸êîîFÇpεݽÕ9‡8ŽÑÝÝññq•Ífu³Ù<¤”ú:•J£(:EÑXvttTµ¤”`æö"¢Ž½”²}Ðèè¨ ‚ÀFQ4EÑYéœûJk|>t: ­5–——Çq‡»L&ƒJ¥‚0 Û¼s@Èç󘞞†Rê+Çñ‰t:íŒ1¸uëšÍ&„€Z­†±±1ÌÍÍ¡R©@)ØÞÞÆåË—r¹ÏÎκF£qB†aèØ÷}8çày&&&`­…çy˜ššÂ›7o0<<ŒÁÁÁ¾^¯#—ËÁZ‹T*…ÞÞ^züø±eÜšÃVc”Rð<ËËËXYYÁ¹sçRÊþüùóïíè0 !l½^‡ÖÌÜÑñ{÷îáøñãèééµ¶å^¾eªÑh€™-{žg^½zeÑÊ”ˆðüùslnnbdd¤c¬öòÎ9VVVðòåKçyža_J)¹\.ÇÕjRJÀ£GpðàA¤Óé÷{y!´Ö˜™™1ô/¾çýû÷“H$~ØÚÚ’ÓÓÓ1DQ„/^ ¯¯¯í†™Çqo­ܾ}Û¾~ýZ$‰E­õ„‚µöçy£ëëë=ÖZÛßßOûöíC?ºººÚ¥[kÑÓÓƒ¾¾>tuu™±¸¸èJ¥û¾ÿ·µö ý!™Yxm­ýÈ÷ýŸçææ\&“ÁððpÛI«ARJ µã¨×ë¸{÷nœH$]%¢ßHPD4ËÌŸ‘˜™™ÑÛÛÛïLC«äW*•âjµª‰ÄõcÇŽ}€Ä­¥&"¹–L&¯W«UuóæÍÿfÆýû÷íÇe*•Z‹¢è‹………öa"ŸÏ·šA«««ÎóÀó¼ ëëë1Æ=z”Œ1m×ÌŒÍÍMܸqÃ)¥ÀÇDtŸˆ$\,Û•1³dæ5kí¸ïû˜ŸŸwKKKB´‡_kÉÉÉ8Š"B\#¢ëÔNŒ(‹àÖÃÞÉ÷Î;ºV«µ¿šr¹l×ÖÖd2™ü- ëgΜÁnAì‹=Âïä;55ÀÓ§O1??ß÷a­ýTJÙ,•J@G7ÅîÍå›L&/lllµZÍ=yòÄ4 ¡”š0éœkç¸ËTÇÕ ØueK±sîCfž ÃÐH)…”²œËåN?{öŒ1v¯`GùÿC+ß_œsW<ÏBˆ5cÌ' 0ÆüßÄá|Ŧ¡@â)+IEND®B`‚routino-3.0/web/www/routino/icons/limit-23.3.png 644 233 144 1504 12573351605 14654 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ùIDAT8Ë­”OK[[Å×½ŠIo#M3‰F!Ò‡„  „Ž"8ÿÕam'¶³Gñ •ŠB¬5\]ç~H¥bé€tú‘ˆèèpE2)&&<¤/,,4K@€µ¿ì"h°°Ò&&<’Éæ7¥—LOcÀ Œï`Œ!Œi} ñ}‚F>ÓÓ ½¼èYÏûiËe,Xš‰¿°Ö¶ìMœµå2xÞO¤lÛ_Òs?¾çèý§O6ô}‹E% êïïWgg§r¹œÆÆÆ422¢|>¯T*¥x<®l&£Ù‡­ŠEµíi…§OùÂêÑGM«×ëc¨V«A€µ–““¬µ„ax¯×Bž<iå’g”ËçÌnòËZ{É5cL ÏŒ1` æ7žµ(À‚oƒ{.™V’^=‡áÆgf抮U›×:5®už]ã¤ý8$ŒcÎxIEND®B`‚routino-3.0/web/www/routino/icons/limit-31.6.png 644 233 144 1500 12573351605 14652 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“õIDAT8Ë­”ÁK›YÅÏ÷bMòiR#IÉFp6Š vv%­Ôň`Ê,Æ‚èà?PÆe»w9¡Yi)7n]Ø.´ÐB«Â)‚†ˆBM¾ï½ß,Sm·^xðî}ïÜwîãÜ+$! c ’A±Ø/HËxÞ{:: ³ÓÒÑž÷i¹q.$ÓÀ ]&ŠÅ<$ééÒS|ÿ óó°¶æ8<„rëþü<øþ¤§û^/ÑÚjˆFEwwÒ'&& X´@ˆs–«V÷CŠEËÄHŸèîî!­­Ftu‰ÉIé#‹‹UÀàÜ·uTY\é#““>]]2¥gLMa¡T«ØZ­I& C¬½NÐAµŠ…SS =»ü³>|ÿÌíîÖ_ls„aˆsî»J]=V¿çÜî.øþR_䉴ÄãÇ9ovÖþóáƒYyñBÑhTÙlVÆmnnÊZ«T*%k­Œ1:88Ð_ÏŸ+~ë–÷óÀ€¥XŒ{ÛÛYi›—/Ù+—mçíÛÌÌÌÍfÙÚÚb}}H$B¡Ph2+—Ëär9ÆÇÇypïÿžYVW±Òv‹‰»zøPáé©ùsiI?e³ÚßßW¥R‘1F™LFÎ9]򮮠ööö4::ª_•ŽÇr9yÉä]cZZsêíéѳ³* :99Q"‘ÐØØ˜úûûU©TšÉÂ0T:ÖÐÐþ^YÑÛ7o¤TJN„µš§övVWõàþ}­­­©­­M;;;M°çy’¤R©¤x<®öövÍÍÍ)“Éè¿ÏŸ%Öz&r~þN¯_ë·|ÞÝI§•J¥Ô××§ééiIR2™T<—$ŒŒhxxX½½½ò}_ƒúýÑ#§W¯9?'¤eÂàëWŽŽŽêÂàôô”‹‹ J¥RS2ÇÇÇ„Õ*@ÈÂHË×tf:³Öþ ¯«:³Ö‚µØïtö­òy€š Ãkàöaˆ«³¯‘Ï_é€íÍ7:ÏnpÒþúuGdSÍ4DIEND®B`‚routino-3.0/web/www/routino/icons/marker-44-grey.png 644 233 144 2500 12573351600 15615 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“õIDATHÇ}UMhTWþι÷ΛŸˆ"jetH63‰†FÔ0A´˜EQ°›fÑ.ºiKq#S™…ÐM÷]Bt¡1Št°%% H‰1 H;f4N˜è{÷Ý{»0óš˜Ô.Ü÷Á=÷;ß9ç>*‹XK)Q,m©TrÎý¤µþÔ÷}€ðœçy¤”ú“ˆÎ‹Å_K¥‡ah5¨pÎçÜv¥Ôå Îj­]:¦l6 fŽ"Zk1??F£á”R‹ÅÊZëo‰h‘ˆ#°sÎØ+¥¬´Z­½™L&Ÿçz½®_½z•QJ}f­½îœ{éT J©K+++{r¹œU°ÖFʈÌ-Ã[·nÅèè¨ÊårzeeeRêR*•Ap<‚/2™ŒQàœ‹33ˆhƒRÊh?22¢2™Œ ‚à‹ ޳sî¢ÖƒƒƒH§Ó°Ö‚™áœannFíËÖòoÞ¼¤Ói Bk çÜEÃð`:v}}}ÜVf­affW®\ÁóçÏƘMyçúúú8N»0 ²ïû.›ÍR"‘€µ6JýÅ‹¸yó&R©T”ª”rSÞZ‹D"l6K¾ï;~/Ž×Å÷}”Ëeäóy¤R)Axûöí:^k)mg €Ya›Í&´ÖQAnݺ…®®.œ:u A@)õQ¾}®Õj™­ºP¯×)“ÉЮ]»P«ÕpãÆ $“I<{ö ¯_¿ÆÒÒ|ßÇÔÔb±ªÕ*jµ:;;ÑÕÕ…¹¹9T*çyža?J)¹R©„Íf@GGÂ0D{âñ88€-[¶Düš”qûömCïñ‹8sæÌïÞ½ëi6›ý‹‹‹ááÇ9ŸÏcÿþý( ¸wïNœ8ôôô ¿¿…BwïÞÅÉ“'Q(066f«ÕªˆÇã3ZëÏE?¬µâñøH­VÛfŒ±===†!ˆ;vìÀîÝ»‘H$¢€íÛ·£»»ÕjÕMLLp2™|k­&¢˜™%3ÿm­ý2™LbrrÒÍÎÎBJ fƾ}û°mÛ6€D!VÅ`||<ô<Dtˆž‘d!ED÷™ù;"ãããzyyÌ cLÔ2bbb"l4*‹]- ?`a»A5ñ¡C‡.{žwµÑh¨ëׯ‡›Í~{Ú¦¦¦ìÇe*•Z‚à‡éééèrqôèÑvÓüü¼3Æ<ˆÇã§kµZ¦í¯1&z˜/_¾ÄµkלRŠ|EDSD$àR©‰XõwÁZ;ºÖ_!D¤Pkr¹AÀBˆËDt€Zµ¥R ÜÞ¬â£þ@¥R± Òó¼§¾ï_ÆÚ€X5ÞàïØØX?Æää$’É$¬µßH)Wîܹ#¬«¤Xû±™¿žç®×ë™ååe÷èÑ#Ójµ„Rê{eç\äãQØð¤¯ùeK¡sn™ïû¾o¤”BJYéíízòä cì‡×¥¿‰ msÎÇãB±`ŒùzzzÆüþÙ¢ô)îähIEND®B`‚routino-3.0/web/www/routino/icons/limit-5.6.png 644 233 144 1373 12573351603 14601 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“°IDAT8Ë­”¿K[Ç¿3ÝApYÖè¦Qò`!elE­-\ ‚aƒ?ZÁàAʤ·»€•…­¦X0"ˆ‹‹£Fˆ¤p÷Î=ŸWÌ®/‰ïu˜;ó=çÞûåsŽ„$Â0D ‘D¡ðÒAð•bJ%O±Aði£û_Ha7O¨W¨PÞ½+ }"޲²_¾­|ÿ­V¶^Y8þ‰ô©«ºù¹\H>/†‡_#}£Vƒ‹ ¤˜y~lrqá©Õ@úÆððkòy‘Ë…bpPÌÌÄH Ö×Ú€á8fÿ>½o`@›õuÌÌÄ v¯)}fn ƒs¸vçÎ9Ììñ`Þ{œsøNÒ4ÓÏÍô¹çÙâø''ÙŽ™èI˜Ùo…-Ó''Ç?Þ¼ø[ú¨Æôþ½—÷¡3ÓÎÎŽö÷÷u||¬jµª|>¯ tvv¦ÍÍMEQ¤Ê«W¹ xùÒ«ÙŒttôBHGlocà’$ahhˆÙÙYhµZÜÞÞ266ÆÔÔãã㜟ŸgWÏö6HG¡úûßjrR&…’tpp ûû{šžžV¥R‘$íííéôôTårY*—Ë’¤@ 59)õ÷¿ †(—S ,J¥’æççU«Õ´¶¶¦ÝÝ]IR»Ý~,´µµ¥ÃÃCI’IR.'…!¡Ìu:Á’.//522¢z½®J¥¢««+IREêëëÓÒÒ’Ôl6Õƒ^Ždÿ‡°l}´§G{{ƒ==E…åÖ>BÜŠCÚåó‘ùúu^xg’|svV?|ȼ¸Ð/_ô⢩gg5I¾ ïZþ¨ær±]]80ðBøäø¸žµa–MÝðì,8>®ðÉvua.c±ˆ‰päҒ꣚™¦š¦šeÿÎöšfê£KK GNL$‹­4ὓ“ªu m4LÓôûT !˜¦©!Ûµîä¤Âûö›½4I¾zrÒ¼±iú%»Ì,Ë~Ò†ÐôŸœh’|^vüóö퟼yh4b:;IÓ”ÍÍM¶··©Õj r||Ìêê*ÝÝÝ‹E¢"ž?|þüŒƒƒŽxÅÈ@¤pssÃÂÂ[[[Ôj5666¥V«Q­VÙßß'Š"²,ˆZñ¯:)†Z"΀`ww—ÛÛ[TÆÆÆÈårÄqLµZåôô”ûû{h² 32…ÂP'q,¹\E½½½LMMQ©TX\\dxx˜r¹ÌÊÊ ×××ô÷÷ó£Ÿ\âØ˜,‹¨×i p~~N©Tbff†R©ÄÚÚ•J…’$aoo &ÔëeÂëëÍ߯×U=::²\.[(œŸŸ÷ððС¡!ûúúœžžöîî®ù«Ml‚ëë ËÎÍ©6Z@ªúððàÕÕU“+õññÑËËËïÜ©m€ÎÍ),ÿ—³~â*„`h­µõï8ûmdm8WýŸ xÒÚ|Ò®ñ¤ýì ;í?±÷CÙVš;IEND®B`‚routino-3.0/web/www/routino/icons/limit-110.png 644 233 144 1314 12573351602 14564 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”ÍJQ…Owœzh•ˆ¸SH1"Ñu0O øú>F²sáÌ€‚«00¸%‹ ¢ˆ "¨Á±3Ó÷Ö—E·ãO’ ÷ô­:·î­S%$!‰0 ‘B$Q.¿GZ'~08oßz!~ ­çûB ó8¡¢r9@ ¨ÕÊH_‰¢;–—ak˸¸€›¸¸Èðò2DÑÒ×Ü?Èã%ŠÅRIŒ½C:dnÎÎ<à0ó<µ ;ÎÎ1€¥)ù¡/:àU{óU§Æ«Î³Wœ´Úh;3žBsIEND®B`‚routino-3.0/web/www/routino/icons/marker-38-grey.png 644 233 144 2732 12573351600 15627 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“IDATHÇu•Mh”IÇÿO}äí¼ Ñ¦[Å6ÐF:9Än\â2nñ«ÅDP…ÁGa=̼Ì.K†èÛ^ÖËÝ[ ~­‚hDMg" ¢ jL§Q&,‰´ÝéØߪڃéžèº(¨*Š=ϯªž¢T*…U1!R©”N§ÓIcÌß=ÏëpÇ ü.cYI)ŸQO*•L§ÓÌ÷}Ð@«¦Ü£Œ1›¤”]×ýÞó< )‚1VsÔZcffÅbÑH)©®®®ß󼟉èqJ`Æ E‘©T*-¡PÈ?xð ‹ÇãdY¾”ã8Èf³&“ɨB¡ð½mÛRJ4ÆLã{öì1š…]×m‰ÅbÞéÓ§å¶mÛˆscÌÿ4!"‘µ··³|>ï-..†¤”ǵÖÿ6Æ,ñîînøçÊÊÊÞX,æ;wN(¥@ô %c DTc ”‚mÛèèèàÓÓÓÞüü|(l¨¯¯¿É\×ír]÷‡P(¤Oœ8!«Ü„`Œ1cLÍŒˆÀƒ¢6òäI …´ëº?¸®ÛÅ÷íÛ×ç8Nó‘#GL,#­5c˜ššÂÛ·oáû>Ö¯_ ",,,àõë×XZZB0Ô××CJi²Ù,I)[…ïû߃AÇY5Õû÷ïãáÇhjjB©TÂpèÐ!ŒãêÕ«p[·nÅ™3gÀC<gCCC¦R©|ÃÇ1Ñh”lÛ¸®‹ÁÁAtuu¡§§ÇŽÃOž<Á¦M›páœ?¹\oÞ¼ضh4JŽãñ)8VcÆ9ÇÙ³g±aÃLLL ›Í"‘Hvî܉›7o¢¯¯¥R mmmhii©]µUÆ8çº\.Ãó¼Ú!lß¾Zk\»v ¯^½B]] P(@k Çqàº. …Ç©™V*0Æ4O&“½ù|žÂá0E"¬¬¬`rr‘HÉdííí¸uëÂá0†‡‡‘L&qüøqtvvâÙ³g˜ŸŸG<Çää$†††ŒeYŠøEÁýååe(¥péÒ%d³ÙZœs466¢±±ïÞ½,..byyáp000 è“þÅO:5úñãÇÖr¹ü‡¹¹9¿³³“)¥pïÞ=ŒŽŽbll ؽ{7šššÉd0<<ŒÇcóæÍ8zô(t.—ã@à¥çyßQoo/l‘RŽ~øðaëþýûuww7›žžÆû÷ï±qãFlÙ²¥öš–––055Û¶ÑÖÖ†—/_š¾¾>jhhøMkýGcLN0Æ€ÿh­ÿlÛöÐèè¨innF"‘@4}ö¢Ö­[‡;v€ˆP.—qçÎß²,  —ˆràDô+cì/DÄoß¾í‹E´Öµ(«h­«ýR©$ëêê.'‰`üj¡ôˆˆíÚµë¢eY—K¥’¼qã†_5Z«ê]~ôè‘~úô©hhh˜u]÷oÏŸ?¯eÄ÷îÝ[]L333F)õ$|;77RJéÖÖVRJÕ c ¸r劑R€‰è X:®uƘ`ŒÍj­ÏÙ¶‘‘“ÍfÁ9¯að<ýýý¾ëºŒs~‘ˆ.«‘N§ÁªU}•o©Tª})™LFÏÎΠ˲rŽãô>|k ± _Æ·X,Êëׯû0>>Ž‘‘ض ­õy!ÄÊÝ»w9³–;_;ø_˲¾Íçó¡R©dÆÆÆT¥RáRÊ¿è7ÆÔ8® Ÿ-€5_¶àcö1Æ~uG !¸"Ç“L)¥¿4ü,ý¯`¨ò6ÆôÎ9ŸUJýôâÅ (¥ðÿô_ÑÆÎ…uµIEND®B`‚routino-3.0/web/www/routino/icons/marker-91-grey.png 644 233 144 2566 12573351601 15634 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“+IDATHÇm•OhT×Ç¿¿ß9çÞ;W£\‡gE3 ÉF3"Y45"‰X°.D›]!ÝT¥]<„¶< Zæ•Ù<ºð¹é¶Ë’©5Œ‹7ÖGT¨bIbìʤ/šgŒŒzÿœsÞ¢™kýÂßÝ|Ïï÷ù}ï½T,±"–R¢X,šR©ô¡µöû8Ž»Ã0´od]×%¥ÔïDôM±XüO©Tâ$IÀ­˜ k­¶Ö¾§”:EÑ'qÛ (—Ë™SGc fggQ«Õ¬RŠÇŠãøK"zBD€–ØZ«´I)+F£-›Í&à®®.r]ë†!¦¦¦l¥RÑKKKŸø¾ÿÖú€µöO"b±oß>  UJùß(ŠÚ:::âÁÁAÕÞÞNBXkß:RJlß¾vìØÁ ñÓ§O³J©#ƘŸ­µÏÅ¡C‡à‡—/_öuttÄÇŽSžçÁ“vÆÌ ¢ô€Ö¾ï£»»[T«ÕøñãÇYÏóþ–Éd~á(Š>Š¢èÓl6kT“›Ì f†µöÍ–Vj)eZ ¨l6k¢(ú4Š¢ØZû]ÇèëëCÐZCÅÅEܹsÕju!¡^¯£Z­‚™¡µFèïïGǰÖ~'“$y?»k×.!&''1<<Œ7âÅ‹èííÅáÇ¡µF’$áøñã)ŽB¡ÀW¯^µFã}ÃÐær9Êd2id.^¼ˆÞÞ^œ:u 'NœÀ­[·ðüùsŸÇ–-[011a¯\¹Â¾ï¿2Æ$¢ÿIf–c>ó}ÿêõë×mkk+ …¶nÝ "J ›Êçó ",//£\.'Žã("ú–ˆþ @@ѯÌü‰ÑÑѸV«ˆ`ŒYc¸úU-—ËI­VSŽã ïܹóß@Ò hLDÜÓÓsÖuÝáZ­¦š|×cÀ̸yó¦¹}û¶Ü°aÃ\EÿO/}}}ÍÛivvÖj­ó<ïãùùù¬ÖÚtvv’Ö:3cqqçγJ)ð9Ý$" @—J¥´ f–ÌÆÆÆìÔÔ„)†8Ž144”DQÄBˆ³D4 @­`D©T7‹½Å÷òåËq½^OsY©TÌÜÜœt]÷0 ¿=xð Vb,Ö¿Åwdd$€»wïbll ¾ïÃów)åËr¹,ØÕÜÅê‡wñu]÷ã………l½^·ºÑh¥Ô׆¬µ)ÇUMaíj¬úeK‰µ¶Ÿ™ ÃPK)…”²ÒÕÕõá½{÷XkmÖ®ÿš|¯Yk¿ñ>N<'›ÍH$hlldzzš¶–ö>6¼~MQJºŠDîèÞ=e>|pyúT[[[jjjÒÊÊŠ‚ 1F£££jmm•$Ykåyž†‡‡õc[›þ>9qu÷®‰Ü©®ª©Ážž:“££úáúuõôôh``@SSSZ[[S¿æççUWW§‘‘©¹¹Y«««:>>VcCƒäºrªªpm8n(¤ýƒ )kiiI‡‡‡êèèÐÌÌŒZZZ”Ëå$IëëëêííÕöö¶<ÏÓÞ»wRuµl±èÈ—’¼}Ëï¦Æu‰Åb477³¸¸H,#‰0;;K>Ÿ§¯¯ÝÝ]b± üüàßÀ°±•’BZæÉ¾Añ(›%[ö³³3|ß'ŸÏcŒÁZËÉÉ …B|>OpvPäñc–ÏyF:]böžU¸V»t6óž]R€ß¶$™K€—ˆ\,Vj|îß¿ €+Õæ•n+ÝgW¸iÿ}N[I"r\ãIEND®B`‚routino-3.0/web/www/routino/icons/marker-26-grey.png 644 233 144 2747 12573351600 15632 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“œIDATHÇm•Mh[ÇÿçÞ[ÝÕÛVü&‰"m'Ø:Ÿ¬Zµ póæMMõ7êííÅ›7oþ>77÷»d2vtt¨žžD"H)¡µÆüü<Ž?Ž+VàÌ™3ÐZvî܉¶¶6\»vÍܽ{W8Ž3Áo©»»ÖZ–õoÏó~µ{÷nÓÔÔ$¦§§!¥! C444`Ù²e(•Jxñâ–/_Žõë×ctt”ÏŸ?OŽãü×ókf~¢„ ÀŒ1ÇmÛ¾=<<Ì›6mÂöíÛk%V›yÌXºt)¶nÝ "B¹\Æ­[·ÂH$bQ7= €€ED?K)0ÆÈ«W¯333 "h­aŒ©`æZ‡ „®ëZ‘Hä–-[NÂjD$vìØqÚ¶í ³³³Öõë×ÃjŸWJ5[)%†††Ì½{÷T]]ݤïû©ÍÙÒÒR}˜&&&Xk}×¶ío_¿~ÐZ›7’Öº6X„xûö-.^¼È–e€ïˆhˆˆ "›ÍÖ†ºB !&1'ÇÁàà çóyH)aŒ!ôõõ…¾ï )åi"ºÀZÀˆl6 Q½YP¯â"’ýýýA©Tª­”\.g&''U4}R©Tº÷ïßņX‹ÏŒk|£Ñè×u­+W®„066†ÁÁA8ŽcÌï•Ró/^7rñáK|£Ñè·Åb1Q*•øÑ£GÚóY½€E+[™¹Uñs¥RÑJ)©”Ê¥R©¯?~,´ÖæsÃO>ÿ ª|ÿÉÌ?Ú¶-¥”“ZëïGFFj­ú%ýµÖÏ»‘(ÎIEND®B`‚routino-3.0/web/www/routino/icons/limit-19.4.png 644 233 144 1375 12573351604 14667 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“²IDAT8Ë­”AK[M†ß;Ê5^h«•àFˆ´n.Œ[¡%ø¹ÐÒàBûâÜøÚ+wYØ*|‹"¸íâCÜ(Ä‚ƒP4*ZšBM¢wfž.n’Vü–˜sfÎ;gÎyÏ’„1É ‰Tê9Ò:Að™xúÔ10Aði½}.$Óöê¥RRÀâb é-Qô‹b>~ôÔjðý;Ôj‰^,BýBzÛ¾´ý%ÂÐÐ×'2™gH ¨V`ñÞñ·$º¥Zu UÈdžÑ×'ÂЈáa1?!}ayàðÄ1Ä1xÿgulà–—AúÂü|Äðpû›Ò;níÍ .qÀ9GÇ8w7@¬ÅÅ1nYXé]'gY¢è'• ¼oyïñÞßÛwuk“ON Š~"e…´ÎÒ,Àîî.§§§”ËeÖÖÖºº÷¾e¥Rá¿OŸ¬/AZÒ![[îß­-z{{ÙÞÞ¦V«1::ÊÔÔ\^^ÞãŸ|ÀÙ@:4zü8§—/å%ôôhhhHýýýÚßßW:ÖÞÞžÂ0ÔÎÎŽ:²²²¢V«¥¡tZ’ /^HOžäŒzzPÊKZ|óFããã:??×ÜÜœ†fggutt$cŒ$©T*issSù|^úúí›z=’—0ò>Ðím÷Ul1j6›Êf³šžžÖàà 2™Œ†$irrRårYÕjUÇÇÇRç‚nÎbp…×¯ÙØØ`ff†‘‘VWW©×ëär9...(•J^½Jröþ=H‡Ýjç¨×ë4›MZ­gggݤ_]]Ç1Þ{®¯¯ù‘Ų´Ô­f³““„7 îÐàiãÿòìNø8¦Ø½··¬Åßë€íÍ:ÏpÒþ„ŽfM®]IEND®B`‚routino-3.0/web/www/routino/icons/marker-83-grey.png 644 233 144 2730 12573351601 15626 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“IDATHÇm•MhSkÇÿÏû‘szRhÓøEm›©¤ 5…! uDD¥•ÞvÑáv!¼›«pœÍÌ0taÉ@v³¹nîÒÙUjÑi7Ölë*ÂõTªˆéE›¤$-¦z¾Þw6™úñ‡çÿó¼¿÷ÿ22¿lmmˆÇãÞùóç¥išPJ5+cŒˆ@DÐZ‚ €eYH&“üõë×Þ»wiînii™g®ë~çºîÑhTË7Î9c`Œ}Veã¢ùãññqF•ëº?¸®û?yòä´ã8]£££:Sàœ£\.ãÙ³gØØØ@{{;8ç€W¯^áåË—ð}‘HJ)X–)¥¶m›¤”}Â÷ýH$¢ûûûpÎaÛ6fggaš&ÇAOO.\¸€l6‹ÅÅE´µµ¡V«appCCC€D"Ánß¾­ëõúsGÇb1jiiÁvÖp÷î]ìÝ»—.]ÂÅ‹ñüùs äóy crrcccÈf³p`Yb±9ޣŧ}ø”C¢OÀüü<¦§§Q«ÕÐ×ׇx<މ‰ ttt`yy¶m#‘HÀ0 h­AD<3Æ9W›››ð<¯iº¾¾­5Ç뺨T*ð<„R ׯ_ÇÊÊ B¡Ðgù­×ë`Œ)>444U*•h×®]´ÿ~|øðW¯^Åèè(ÆÆÆpôèQ<|øÅbmmmˆF£8}ú4>ŒùùytvvbÏž=xñâr¹œ6 #`þ.„`¹\ίÕjhiiA8ÆÚÚ \.ckk ­­­¸rå lÛnV&„hV»°°Ð'ý“Ÿ={véãÇ}¿][[ó“É$ëèè@6›Å;wpÿþ}ìÛ·gΜÖ™LKKK( H&“8vìæææÔÊÊ 7Mó±çyghjj öK)—Þ¿ÿ›S§N©‘‘V­VQ,ÑÚÚŠÞÞÞfNß¼yƒJ¥‚Ý»w£»»?ÖÓÓÓ‡?(¥~§µ~*cÀ¯J©-˺½´´¤»ººÐßßöööææ5Ú³§§ÝÝÝ "lnnâÖ­[¾aÀ= €$¢EÆØ_ˆˆ/,,xÕjD„ šqkô~£=3™Œ_­Ve(º–H$~ÀøAé;räÈeÃ0®U«U977ç7†ÉNi­Á9ǽ{÷ÔƒD8^u]÷o…B¡¹~âĉÆÇT,uÿ1Móû·oßFƒ P}}}As°0ÆP.—1;;«¥”à'"ºGD@,N7‡:cL0ÆV•Rç-ËB>Ÿ×¶mƒs¥ˆžçaffÆw]—qÎ/Ñ5r#Òé4Xãf[_ñ½yó¦W«Õšr¹œZ]]†a€Éñ °R†ìï++îD?~$××ÉOŸÜ›/_ºàÇÝúömòüyçØ~ôÈ©ñä DBˆžçý€ù\ÎÔ÷öȽ=Z€¬VdkËA77ÉK—Èk×ÜþÝ»Œ††ÈV‹_¿rb|¼7ÁoÈd2ÐZÿ€ÅÙYC’í7ÈóÈÁAòêUzðÀí䉴’$ºrÅÆÀ?dsZë,—Ë–$ÃgÏÈ•òÕ+wo“{úî¹¼Lóæ Irmm-ЇBˆñ¨@qZJIí`mÍé›Z;*iÏݘÏç“Þ/wó@ ! ”º €yßëïß;À?´l²777gâÙŒŽŽÂó¼Î„rx¥äøø8´ÖA<\œ¾}ÅC’\ZZ²1p·3ºÆú6|­u£Gß8³¤ìZ­ÆL&cPJùcÙýv\ß èÉðàà€&¿ !@ã?¬G_ß÷Ãd$’d¹\NÊ®È,,,t–þÝúõ™™1$RRqºëûö]ÖÑW)ÕÀùùùhrr2)»—­¾Ø£/€Y!´ã 7ÆÆÆ ”’ÿØÑ7ö?{žG)å.€úª9f+ ­h(Ñ%¨IEND®B`‚routino-3.0/web/www/routino/icons/limit-42.png 644 233 144 1250 12573351602 14507 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“]IDAT8Ë­”=KcA†ß;E.b›¤ d+Á&•eK‰)² éLgðO(XXXb•BÐ? Ø[h$…”ÁD?òqgž-î5›Åu·ÉaÎ̼gμgÎ9B’0Æ $‘Hü@:ÀóZ¤R°°`I¥ÀóZHѹLd'ôyQ"á!yüü™@ÚÁ÷_ÙÜ„ÓSG¿Ðï‡ëÍMðýW¤ïEö±˜!¹\©C©Ý®œ³LK¸èv-¥Hr¹<ñ¸ˆÅŒÈdD¹ì#ÝR¯ Çx ã18÷{|î†Ôë ÝR.ûd2Mi—J`D@`­%˜ÒÇã1ÖZ¦0#*v?c¶ˆï¿Ðn‡#cçιïukC|» ¾ÿ‚´(¤j5€ ¢z:ÜÜܰ··G«Õš\áj5„tE£` ‚É ¬µäóyÖÖÖh·Ûø¾ÏÊÊ ¹\Žf³b†ÃЮÑéÊ(™,¨X”$#Ï“çy’¤íím e³Yõû}mmméüü\sssj6›’$bŠE)™,ˆtÚòð@Ñ<>>&›Í²±±A>Ÿ§×ëqyyÉÒÒÕjuÍ<<@:mœó4iZŒ1* º¾¾ÖÓÓ“ŽŽŽ´ººªõõuíïïË9'I$ç¼/1G/<<<¤Z­rrr‚1†ååeæçç9;; ™ ÄìÛß´ÖòööÆóó3ïïïÜßßswwG¯×ãããƒÈë—ßükžýWBÜ—<û¶&ù4•¬Î¹TÀLks¦]c¦ýl†öBA³®°Y»IEND®B`‚routino-3.0/web/www/routino/icons/limit-5.8.png 644 233 144 1377 12573351603 14607 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“´IDAT8Ë­”¿K[QÇ¿ïµ$é5ÄÄ ´èØAA*¸Š (XTŠuü ÛÝÍI² Ž.â$Á!v´ò”•*&÷Ýûéð^Z[ÛÍν÷{νçË÷! Iø¾ä#‰LæÒž÷™lr9K6 ž÷i+¹’ŸÄ ue2’Ç›7¤ÁÖÖ`w×ÑhÀ·oÐhÄûµ5‚H¼—ÄK¤R>é´zŽô…™8;³@„s–ûï#ÎÎ,33 }ahè9é´H¥|Q,ŠÙÙ©Îæ&@ pÆ€s¿Wç Ðbs¤:³³ÅbR¦ô‰ùy€6Æ`Z-Œ1cpÎýú˜µc ¶Ý†(Šñóó }êpö’ øÎéiüb z`ι?»ç8=… øŽôòÉ{éƒÞ½{­·o­¬õsÚÛÛÓáá¡jµšÊå²Òé´<ÏS­VÓÎÎŽº»»U,•„1žW(X}ýúL''O„tB¥‚ †!¥R‰¹¹99??`Ÿ|>ÏÒÒƒƒƒT«Õ¸t°T* øêéy¥‰ 9É—¤ããc]__ Ðôô´$IÎ9A ÉÉIõ÷÷ëööV M¾&&¤žžWOåû(•ò<Å–Ëå´°° ññqmll¨««KSSS ÃP…BAÛÛÛº¼¼T>Ÿ—$y’”JI¾/ç<µÛ±‚%]\\hxxX+++êëëS£Ñ$U*ŽŽêàà@A¨Z­Æ?–¤v[rÎûÅ™M8«×ë”Ëe²Ù,«««4›MÆÆÆ8::bdd„ÞÞ^–——¹¹¹çb®΄´Åú:@”’»»;Â0ÄZ‹sŽ««+Z­Íf“à|Äú:H[tæî µ“ìŸ~§îéìaD.Šþèß~ý§µ7uj<ê<{ÄIû¢bªÁÓUÎIEND®B`‚routino-3.0/web/www/routino/icons/limit-0.1.png 644 233 144 1254 12573351603 14565 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“aIDAT8Ë­”OJ\[Æ÷>¼-%£m\€3‰Û%è\F2sàd$. ": ¢‚ˆ±1hrÿœßôíŽoäΩSõQçÔW…€€q ±€ããï„}£è«SSúæMéÔ”FÑWa¿ºGˆ«8d@4> ‘­Ö¸ðÁ4ýéö¶~ú¼¼Ô?ôò²ÞÞÖ4ý)|¨ü£*L’ØZ ·Âw××õü¼T C(}Žþ¹ðü¼t}]á»Æ[k5L’gfpc#¾¹»«ú[ æ¹æ¹†ðg lÔßîî*|sc#uf¦z&|tsS5³(,³Ì<Ï !ø7Š¢°Ìs-оÿæ¦ÂÇÁŸ½7M{v»ý‡Å$„0BX<»«È‚Ý®¦iOx°ïÎŽj²LÕn·ëÞÞž§§§/H;Ž'''}{ß¿pgGaá³í¶AKÕëëk—––\\\tnnλ»»af&Ib»ÝV5ÿõKµ´ÝVø39Ùde…b€££#jµÇÇÇÔëuȲŒ(Š˜žž&„q ³²““͘8–$a€<Ï™˜˜ ^¯óøø€J«Õbaaah"I Ž !"ˈ*{£Ñàêꊋ‹ ÎÎÎ˜åææf˜Í0«çÈ2!Šéõ¾ÐéðŠ‚ÕÕU–——™ŸŸgkk‹f³ÉÚÚ¤iÊØØ3@ Ó^ïËH5+AZ–¥···–e9²W½¿¿÷éé©_‘¾ÿH5_èlX–å ÷ÿtö¢|.ÎJg#ûÊçe¼jo¾êÔxÕyöŠ“ö_Š÷jÌZ@IEND®B`‚routino-3.0/web/www/routino/icons/limit-17.1.png 644 233 144 1374 12573351604 14661 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“±IDAT8Ë­”¿K[mǿϽzM¯Òš¢dTúB! C—GÉÎ…úø:¶³â;I‹‡.nޱ]¤0 “dH‡Z¼×%yîó|:Ü$ömË;yà ç9?žsßï’DH’(þAÚÆ˜&ÓÓðø±czŒi"müB yBÃB…‚A2¼xQ@zKÿ`}>~ôt:ðý;t:¹½¾qüéí Þ ò%¢(`bBÌÍ=A:gm ÚmdxïøUr;£Ýv¬­tÎÜÜ&&D¢TÕjŒÔbs x¬kÁû;¾zln‚Ô¢Z)•cJï¨ÕúY¯‡·ï=ÖÚ‘zïï:Ì22kqЧVéÝpgeâ8åüœ ¼Ïþ_ɲ Ÿey‡ggÇ)R9|-½Ñ«WÏyùÒRÐ8:Òøø¸ºÝ®vwwÕjµtzzª©©)‹E9熡>}þ,×ë™âÓ§Žvû99 …tB½àöëuÂ0äàà€f³ÉÒÒ+++c8<<À9Çþþ>QQÿÀÙ@:ÓÇϴ¼,/& U*•t}}­ÅÅEkkkKóóóZ]]•sNÆc433#oŒ$Z^–=z&ŠEÇ·o 7U©TØÙÙ Óé°°°@«Õue;­T*ü;ˆ³_¿B±èyoÔïk(Þ{9ç$I{{{šU¹\V¿ß×ÅÅÅÈç½— O²VòÞJÓ/j4$ÉKÒä䤢(’$5 U«UIR’$ªÕjJÓT’DZÆÇÆ$É›FCJÓ/BÚfc Ã9’$áöö€««+nnnF#^^^â\NŠ$I¸ívó¼ ¶ïpvv–ã&ÇÏ/ òüUò¢ÿÁÙ ðÖ2,ø{¡‘e Àýî•›÷z5îõžÝã¥ý ?tc®IEND®B`‚routino-3.0/web/www/routino/icons/limit-122.png 644 233 144 1430 12573351602 14566 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÍIDAT8Ë­”1H›[Çÿß÷•øyI›˜ ŸƒÈ›*dè[´Dp;t1ÐÁÕÁÅExð@„v¯8k‰HqV›¥"b†‚ÅÉ`†–‘ß½÷÷†$¶¾Wèâ÷Ü{Ο{ÿÿ’D†H!’ˆã?ÞMòy(ù<Aémÿ]Ha¿NhÇRÀ‹1ÒkŒùÆü<Ôëžv¾~…v»Ïσ1ß^÷óƒ~½D&24$ŠÅÒ'¦§áòÒï?[/¶\^:¦§AúD±XbhHd2¡H13c>²¸Ðš$¬×õë×àÕ•þþ­WWž^×$ù#|ìøGFGG©T*P.—9<<¤R©°¿¿@»Ý&Š"ÆÆÆQ³´oÞÌÇôõI©DjëëT«UZ­!†††¨T*<>> R«Õ˜™™é10qlLí6Ý¡Òn·™˜˜àúúšËËKÎÏÏ™ššâææ†@±jJS!Ši6¿Óh€ááaZ­ ,..R­VY__g~~žååeH’„þ~€5Ðl~ïeSÍÌsïïïmµZ=ÝÞÞšçù3[-ü ÜÆF/›…Ί4 ýBèó<)Üâî…ΞU@HS»„]Òv–Ù÷?ðªµùª]ãUûÙ+vÚÿªxo)m:‹IEND®B`‚routino-3.0/web/www/routino/icons/limit-27.1.png 644 233 144 1451 12573351605 14657 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÞIDAT8Ë­”ÁK[YÆ¿ûÒ‰™g†šª¸„qÑõ,ª¸SĦ+AZ¶»¡ø ̲]èJ:¡Å¡.Št)‚t  HJÒn$ˆE±GÅIÞ{÷þf‘˜ŽBw^8‹sï9‡ïœû}GHBžç!yH"•úic>Ð×·nYúúÀ˜H+w!y<¡‹B©”A2ÙŸ|Ÿññqr¹KKKäóyÆÆÆ0ư¹¹ €µ–õõu’É$¾| `£W¯@Úó”NßU>¯zµêýúô©¶··¨··W[[[š™™Ñüü¼&&&d­•$c400 gŒ$yºwOºyó®Èd¬=>`wg‡ÑÑQæææ899!—ËQ©Tº¨¢öoR(øãÅ ¢ÏŸ!“±ž‹"ã%“*W** šÕòò²$immMƒƒƒÊf³ ÃP]tÎ9 $IŠ"É9ãÙ³³²Þ½Ó_ïß»8 µ±±¡ááa•J%•ËeMNNJ’†ŠÅ¢‚ $ù¾¯nÜ$gJ%)ÊBZáÉÎ!>><ä°cÍf“ 8??ï¶xzzеmQ4 þýú æñcVº<£VkóÆ^UÐwøÖ޻ijK pº(Âu†|µP×㋘+ ¸Vm^ëÖ¸Ö}v›ö?cz~¾¥å%ŽIEND®B`‚routino-3.0/web/www/routino/icons/limit-38.9.png 644 233 144 1530 12573351606 14670 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ IDAT8Ë­”MK\I†ß{£m{M:Ú*Ú ôH0’ÅÄz¡mq1Æ…þaÖ2.ܺr3Ðó…0À…( … fB/üj„DZôö½UOÝ&:³µ ¨:UuN*žó IHÂu]$ID£?!-à8;Ô×C34ù¼B¬5\oe;$Ÿ7 ô™öö55"qE"!†‡=¤OÌÌø€% ÀÚýj ,à33Ò'†‡=‰Ê3¥Wd2(¾)•0ÆÆÜLДJ¾™ H¯®þì!ž÷Õîí•o¬8þ7€µöûh­c°`íÞxÞW¤‡wf¥9^¼ès&&Ì?»»îŸÙ¬j"µµµi{{[ÙlV±XL‰DBÖZ¹®«ÝÝ]-¿y£æ†'þà!Ÿ¯ur¹;2RŽø÷ôÔÄïß'“ÉÐÕÕÅìì,Œ‘L&ÙÜÜ`gg‡ÎÎNúúúøùÑ#NÂÐðö-Fʹºwﱞ>Uøå‹ûÇÜœFGGÕÒÒ¢‹‹ yž§t:­ÖÖV‹EIÒúúºš››µ¶¶¦Hm­þzýÚÕà l]Ýc×­ªBÖª+•ÒoÊf³* ‚@MMMZ\\ÔÉɉ‰„$)Nëüü\étZü¨êêj©ªJr]ܰTrt÷®–Þ½Ó/OžheeEšŸŸW¿VWWUWW§ ù¾¯³³3uwwk``@õ J¥RÒù¹pd¥ËËœùõÙ3b±ãããlmmÑÓÓC<grr’|>Ooo/ûûû ’L&ù½Ì¥ai ¤œ˜žƒËKŽ Ê`âû>GGG„aˆµ–B¡Àåå%‡‡‡Ø2!ÓÓ -ÜàÌT8³Ö~pÅÜuÎL…3–kœý¨€‘€’ ÃÿÁzc†Ørö%FF®UÀ­Ö歪ƭêÙ-*í7º_b³èÁÈIEND®B`‚routino-3.0/web/www/routino/icons/limit-12.1.png 644 233 144 1352 12573351604 14650 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ŸIDAT8Ë­”½K[aÆŸ{ÓÆx¹´*ÇH;98ô/p1Žâ “ƒƒGÿŒ\µc+‡ Î.ÞÁ±F2Jê Ñ %’ÐJ£ïǯýI?ºxà…÷œ÷=çã9GHBa"…H¢Px´AÔ‚‘ÇÐAi#{R˜ù õ€ …)`~¾€ô–(úA¥Ÿ>y®¯¡Õ‚ëëT¯T Š~ ½Íþ™¿D>20 J¥WHgÌÌÀÅ…,Þ;þ”T·\\8ff@:£TzÅÀ€ÈçC1:*fg#¤VWî1` xÿûôlà{VWA:av6bt4KSzÇÜÀƒ½¿Ç¥8ç0ÆàÜßb-Ö<07Ò»^ÍÆ‰¢ggXð>òÞã½tO±,ÞÚ4ÂÓSˆ¢Ò¸6X^ƃH’„F£Àññ1kkkÔëõG I’ðåôÀúJ¤ !}¦Zp;Õ*¹\޽½=ƒƒƒLMMQ*•8::êîììÏç©~øàÌÇ }õâÅMNÊKaË©X,*—ËéòòR+++ÚßßWǪÕj’$cŒ‚ P±X”I 59)½|ùF ;¾}Ãdõ(—ËlnnpppÀÄÄ‹‹‹ý&˜¬¦år™÷[[©íëWv¡¼ôð žXkDZšÍ¦¦§§µ°° õõuct~~.çœ$É{/²p%ïƒPNMI"I^’¢(RÇ:<<”µV»»»Óöö¶–––t{{«Þ¿çÏžI’’Dêtjýnçh·Ût»]ºÝ.7774›M®®®¸»»£ÕjõÓm·Ûüüþ=õ[^îw3åYÚfOÊŸÿK úˆgM€7†`W’·7¹ÿ™€'Í'ÝOºÏžpÓþ‚´–Ñ…KöIEND®B`‚routino-3.0/web/www/routino/icons/limit-137.png 644 233 144 1425 12573351602 14600 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÊIDAT8Ë­”?K\MÆŸ{•õæúêºë¿r!/DÖ.…UH`…4²¸¦± Ðàˆ¼…EÒ‹¥»`+±–``La±… ×…eeïÜ™_Š{5&yK†áÌ9Ï3sÏ9B’ð}ÉGAð/Òž÷‘Èç-##àyß¶R¿ü'tG’Ç›7Ò°Ãê*T«Ž‹ øñ..{u°ƒô!÷R¼D&ã30 …§HßYX€fÓ1ÎY®ÄŽi6- }§PxÊÀ€Èd|19)Êå©Áú:@pÆ€s¿öÝ8 Çú:H ÊåÉÉ4Mé#KKqLÜëaÀZ‹1k-Î9Œ1˜^E8ˆXZéã]ÍŠ„a›³3÷z¸”èîü•åÛÚä‡gg†m¤bß{é?­¬¼ÐÛ·c|?“Ñññ±â8V>ŸW½^×î‡‡E‘vvvÔ¨×Uo4ôOx¹gÏ,Íæïä¤OH'|þ `±–½½=úûû©Õj\__“Íf©T*LMM±¹¹ÉüüŸ' CúûûI¥RÌÎÎR*•¸‰"£0„¾¾çc„ïàœ£\.3>>ÎÍÍ Î9 …aR­VÙÙÙadd„õõuêõ:…BÏ÷Áœóh6yh’pΑÉdÈd2T*†††¨V«LMM±¿¿O¶šˆ"pÎ345>}p8@oo/×××LOO366FOO£££³»»K¡P`bb‚òË—®ëógh4jVµ¼,I¶-H]]]éöö¶­«z½.k­$)Š"]^^*¶VjŬ–—%XýKgí„;u´Õñ;ºKâø/ý︄¢áû±úÏ<êl>êÖxÔ}öˆ›öíDœš‹i˜IEND®B`‚routino-3.0/web/www/routino/icons/limit-0.3.png 644 233 144 1310 12573351603 14560 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“}IDAT8Ë­”1K+A…Ï.$¬ +iRX,úšX©`+öbµÓÎü€T¶¶¦³ðHºTâ_°R‹@´P#ˆÊ*,ÌîÎ|¯ÈnžÑ6fîœ{˜{çÜ+$! ×u‘\$Q(üE:Æqn˜ž†rÙ0= ŽsƒtœÞ ÉMã„2¢BÁArØÜ, âyŸìíA»my~†÷wx~ž÷öÀó>‘S¼“ÆKär.ù¼‚9¤[Öס×3@‚µ†ï6<'ôz†õun ‚9òy‘˹¢RR‡F`Xââ¬ý¿2X`@£R‡ J%MSjR«D$ &ŠˆãkíØÃŒ1ÄqŒ‰"H’!¾V©™ÕlÏëÓíI’‰µvl?–ñÌÒí‚çõ‘æ…tL½Ø( ÛírttÄýýýèEN‡f³ÉÅÅÅpˆO¨×A:Ò%­ ÀÛÛ‹‹‹,,,P­V À»»;Êå2[[[ÌÌÌp~~Î C«Ò¥+ß_ÒꪌäJÒÙÙ™òù¼®¯¯U*•tzz*I :88Ðöö¶*•ŠƒRsµº*ùþÒ¹.Êåœì&Žc‹EIR©TÒ××—$©Z­*íîîêããC¾ïK’IÊå$×Å•µŽ¢H[zyyÑÓÓ“5;;+cŒNNN´²²¢v»­©©)]]]I’¬$E‘d­3ª`R ±³³C±XdŸ0 Y^^æááµµ5|ß§V«Ñï÷I7ªÙØofdÆÂ0Ä3Ú[kI’„××Wâ—âÇ~ó—Î2)cÆt6æÏ:á‡Î~uß„ûS°ÖZ2Ìï˜hoNtjLtžMpÒþÌ,ˆXØŒ(IEND®B`‚routino-3.0/web/www/routino/icons/marker-10-red.png 644 233 144 2015 12573351600 15413 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“ÂIDATHÇ••¿kIÇ¿3;#Y A†\¡&ø*™Ô)bÅŽƒ*5Iq6„ëÝE…áÚ)ÏáéBŒþ€T Æ)l‚1¸¸Âi‚d°HqFNPás¼³3ß+vV¿Âá»ËÌ3Ÿ}ï;ï½F&gff$d³ÙÇZë#àüÈñw­õQ6›} þœLA à'­õfÇ«$9;;+¡µ†sRJc°¿¿óós !„RªmŒyà¯1Îð w‚ è`©T2­VË:ç8nÎ9¶Z-[*• úswÒˆSà N°Z­FN‡$i­¥1æ‡ÇZK’ìt:¬V«‘Ÿ¬”PJ½ÀZ­¥°Èº8&ãxÂSZKEŒ¾ÂkµZ€J©×RJ “ÉÔ0 CÛívI’ÆÒ9ÒrLE$Én·Ë0 -f2™:”R¸µµe'€I|ä‡# I~úD¾zEîïO€·¶¶¬÷ö\±Xtý~?¹’¼º"¿}#—–È••‘§ïÞ‘A@ÞºEäÆS¿ûý>‹Å¢ó)Ûh4H’ñÕU²ãí[òæÍäà“'#èƒɇÈÄ[€<9aªz£Ñ +H­5€ÒgÃýûÀçÏÀâ"ðõk²6?OŸ&ïF2 «Çs¤àz½ž¼¼¼D.—IˆBP Èå€(Õ\…B2W*£hXAgggऔÒºv» °ÖŽ äh®pãFâ1\^&û3H»ïßcooB‹ ~Àr¹l†Iïo”õ:ùèÑHÓz¼w/™¿|I—Ë‘_¾ðÂ.T*±/‚?Ï硵~ã“ßL\ØÊ ¹¼<‚‘…yû6)%í‹$É_Ÿ=³ø'€|\Ik}€ÍfÓ’dD’»»äÎÎdžžž’­ÏÓíímç !*Cµ@ñPJIq»ÝUÖd7!£õÅÑ;=e¹\Nk¿9Î-„€Rê9–Ã0êø’ê;VªéÚêêªñ½µ=77‡ $ÆM)%+• ´Öí }§Jêýææ¦õÀÞ°;µ=L-„Zë޳´+3ŸÏÛ¤^ä/ÓaOÛµú^\\paaÁøæñ»4®± }Ã0ŒÒ–H’Íf3 û@~}}ý–þݦõ]ZZ2$Ùn·“†!%…ýöàZà´¾J©.®­­¹»wï¦a7}Øê¿'ô°,„ €Ø{¸3??¥”ü¿À¡¾~Ü‚€RÊ€Ÿ§¢ùÁþ¯‰mÀ—6”•IEND®B`‚routino-3.0/web/www/routino/icons/limit-34.9.png 644 233 144 1444 12573351606 14670 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÙIDAT8Ë­”ÍK[Y‡÷B“ô¶Ò¨H@áê¦Rt²N‡B•ÁMTHšû¸t!ÌÞé²Ù¸ÊÊÍ,lK?æp#ºŠÁÌAq$3 $¹÷œgùÛÙzà,ÞsÎûyž÷’„ëºH.’ˆÅ¦Š8Î1ñ8ŒŒâqpœc¤bï^HnOO¨o(sÞ¼‰!½Ãó¾‘Ï×/–«+¨Õàêª+çóàyßÞõÞ;=}‰HÄ%““>R…¥%¨V b­áþêÊ!Õªai ¤ ““>ѨˆD\‘Hˆ•é” €6` °ö¿Ý? ´ÙØé”•D¢—¦T “Á@'h·1Î c a~ étÚm tÈd@*ôköÏ»³gg]Æô2²ƒý}¦½3c°`íÙxÞÒs!m>žS((•JåJ¥ÂÞÞÞ J€r¹ÌÖÖum>RQF*ñõ+ÖjfäÙ3r¹ãããàû> ã'''LOO“J¥øéÅ þCçO©äjh(©W¯Öëîooß*—Ë)‘H( CmnnªÕjittTýuxx¨±±1íïï+òø±þxÿÞU:-ûäIR noø§Ñ`yy™¹¹9Ö××ñ}ŸÕÕU¦¦¦8?? Z­2;;Ëââ"ÑGøýÃC‚¡!ㆎ£§Oµóù³~~ùR»»»ŠÅb*—ËJ¥R:::Òåå¥Êå²îîîÔh4433£ùùy҇åû¾ÔlÊGV*ññ# 0¿¼~M<'›ÍR«ÕØÞÞ&“ÉL&¹¸¸ N311Á¯]. ;; •„Tdm Z-nnn‚k-ÆšÍ&õzc ·½r´Z-®¯¯±]CÖÖº¿yŸ3ÓãÌó?¾îsfzœ°üÀY·²Y€Ž øø¾áƒ0ÄvÛªC6{¯´7tj<è<{ÀIû/Üé©Y.§M÷IEND®B`‚routino-3.0/web/www/routino/icons/marker-20-red.png 644 233 144 2122 12573351600 15413 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“IDATHÇ••1hTY†ÿ{ß½™d°Ð ¸ÅÌ$Û8ÁJ0M‚›! iÁf”ÅJLç¶v„u "hÂt‚E`b±`lÂLÄh‘˜ )²IÞ}÷þ[Üû&“ ‹»ç½Ã{ß;ç眚ìíí•ÉdƵÖï€ ž×Zë÷™LfÂs2‰à#ÀOZë™$I&I²¿¿_ŒŒŒ@k 礔0Æ`ii ÛÛÛB¥TÃsÀF§ý†³Qµ0ŸÏ›z½nwvvèœc§9縳³Ãz½nóù¼ÀðÜÙ´â4ãBEk8::7›M’¤µ–Ƙc‡µ–$Ùl69::ð€‚ÇJ ¥Ôs,—Ëq ‹÷÷éâ˜L’#™ÒZº8f¼¿ß†—Ëå•RÏ¥”@OOÏ, ¶Õj‘$ÍÁÁ1;ôÁL“$[­ …‚Àžžž+PJ-`­V³7òÃrv–|ýšì|ÉÇ>¾´t\«ÕlÈv\.—s[[[þCäÜ ¹œ÷¸°@JIž<éãwï2Í{kk‹¹\Î…–ƒ­T*$É$hÄÁAòúuþî,.’• 92âã³³>¾¶ÆTõJ¥BVZk…ânÝò}‘ÉBÀÛ·Àµk>^©x¿¼ÜžžÀ‘€[__ÇÞÞ” ÖÀãÇÀÅ‹ÀƒÀ… ÀÍ›ÀÕ«Àö6pê”'(å}·'hss¤”1ûôéS/MJI{ïIò·7lþ ›jœ×Z¯`õömË7o?yB>{F¾xá¿t¨‚Ÿ>‘õ:MèÓùùy€ !J)P€rL AH™4^½òúv¨s¤s´aªÖ?f±XLg¿ÚÉ-„€Rêóù¸¹ºêõ=8 9Ï$¡ S499iÂnm Š¢ö† ¢d©T‚Öº–‹ñŒ£ÙcH’3336×ÛÛ©cí¡+PÐZ·°Z­Z’ŒCféVZYYa6›µ(¥üµ»ìnóú 1&¥$€¤ú0Ípww—CCC&,‡BÐøÑ·P(ÄéJ$Éjµš–½ ;==Ýù[úwëÖ÷Ò¥K†$†_RR1n~ìÖW)ÕÀ©©)wþüù´ìj([ýWà}ü"„ €$døçàà ”RòÿÛú7Š"J)×üÜUÍ1û{p€Ûc#çùIEND®B`‚routino-3.0/web/www/routino/icons/limit-5.0.png 644 233 144 1362 12573351603 14571 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“§IDAT8Ë­”AK[AÇÿûZòÒÇ ¦94J !=i½Vðˆ¢`AðP¬¨WA?@¡Çöî7ÐSAÏ^½ê!`=i0øÀ*•"&ûv=¼$m±½9°03;3»ûßÿŒ„$‚ @ D>ÿ icŽ)¡Tr‹`Ì1ÒFg_HA'O¨[(Ÿ7H†wïòHŸ‰¢Ÿ,/Ãׯžf¾‡f3³——!Š~"}îÄ›N¾D.†bpð%Ò7¦¦àüÜ)Þ;þ”ÌN9?wLMôÁÁ—„¡ÈåQ.‹éé©ÎÚ@ ðX Ö‚÷¿W×h±¶Rééˆr¹óLé ³³m¬Å¶ZXk±Öâ½ï]Ì9—ù¬…4ÍâggAúÒÅì5Qôƒ““ìÄ,èxï{…½÷ø,ÎsrQôéõ“Ò'}øðVïß;9Xïµ½½­½½=©Z­* Cctzzª­­-•Ëe=/•„µÆ¼xáÔh<ÓÁÁ!°¹‰$ ýýýÌÌÌ0??O³Ù¤ëaxx˜Z­Æõõ5ð›› êë{£ñqy)¤ýý}ÝÞÞ Ðää¤*•Š$iwwWaêððP…BA;;;’$'—úúÞêÔxÔyöˆ“öý*fº¯ë”µIEND®B`‚routino-3.0/web/www/routino/icons/limit-71.png 644 233 144 1244 12573351602 14514 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“YIDAT8Ë­”1K+A…ÏlHÌÛ%l¾*à/ðu‚mˆkAA@þÀƒWj+ë%`akcãþ±°P´0ˆDqwg¾WdW}F^• SÌÌ™3sîœ{…$$áy’‡$ŠÅŸHŒ9gffg-33`Ì9R'Ý’—žʈŠEƒdX[+"íàûÏlmÁá¡ãîàîn4ßÚßFÚIñ&=/Q(xLM‰Zmé’F®¯-àœåsŒæ ××–F¤Kjµ¦¦D¡à‰jU4›>Rvà pÄ1Ä18÷1²5pÀí6H=šMŸj5•)íÒjD$ .މ? çI’`k3ÒˆV ¤Ý,gu|H¿?º1Iø.’$y'MFø~|ˆTÏý–þhcã—Ö×-Qä™|^WWW ‚@½^O*•Jš››S†rΩ\. cd¬5ªT¬nn~èô4'¤Sº]›¼½prrÂÒÒËËËHâøø˜££#r¹Ý–8޳×Yº]NÅô´ãö6û­wI{{{lnnpppÀüüa{¤Î}ö¯Æ7æ³o+€¯ýJžbÆ+`¢µ9Ñ®1Ñ~6ÁNûSø ¼È¯ÌgIEND®B`‚routino-3.0/web/www/routino/icons/limit-16.3.png 644 233 144 1467 12573351604 14665 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ìIDAT8Ë­”AK\I…¿÷ž¶úæÑÓ<›v#dÄ ‹@Dt1¶1K!ÚËAôøg™ìݪA!‚ ·îÂdVbYDl½Tb¢¦ûUÕ™EwOtfë…¢êÞªsªnqîE€ù¾/ð¨³ó7ÁŠ<ï³2)Ž­2Éó> Všûü&Ñ"êìôžfg;¯†ßµ° mo;œH_¿J'' aA Ãï‚×Íó^J¥|ut ÞÞG‚²ŠE©Zµ’Œœ³ºk ߨZµ*%(«·÷‘::P*å£\MO‡‚/ZZ’¤š$§$‘’DrîçhÅ$'©¦¥% ¾hz:T.×LÞhfF’ê¦V“md­U’$²öþm½®¤V“•êzñB‚7­?P^©\–‘œk9ç䜻“¡»7«qs‡‡R^ ‚?àO^½ú]ssÖÿ¯0ÆÇ1•J…ÕÕUºººÈçó8çð}ŸƒƒÖß¾¥£­ÍëyòĪZíòö÷ûÚÜ”$ûnsSíííÚÚÚ’$ŽŽjrrR…BAÇÇÇ’¤r¹¬8ŽU*•Ô“ËéØo#~ʳg8ð½ Žc¢(bww—££#¦¦¦"›Í`­eyy™|>O¥\¦~qáóü9DÑSŸ ©˜-•äææçÙl–ññqÖÖÖØÛÛ ¿¿Ÿ¹¹9666¸øö_Ói¼ sõ:-“„sŽ(Šˆ¢ˆùùyº»»©T*¬¯¯S(ØÞÞæ—0dÿãGœ1žÏÕÕ'Þ¿pétšëëkÆÆÆèëë# C†‡‡)‹ŒŒŒ011AOO™L†Ç)½|éØÙ!¸¾þ„`E‹‹’dd­.//u{{+I2ÆèììLÖZ9çt~~.県1:==UòãG·¸(ÁÊO6”mÌ¿zj‰µEv/n­ìtö¿ pI¢á=‘Þ]£¦¸ëš™¹SZ›Ú5´Ÿ=`§ýÅ’E;•§áIEND®B`‚routino-3.0/web/www/routino/icons/limit-40.0.png 644 233 144 1410 12573351606 14645 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“½IDAT8Ë­”MK[[†ßsnÉ §'6‹A¬•›N¢ùåvæä ÔNœ q\,—úÚ™‡Þ‰¡ bÎüŠé ˜0*c(i çcïçòq+ס6¬µöz×^{¯w-! I¸®‹ä"‰lviÇùN>OŸòypœïHÛÃs!¹CœÐ(P6ë 9¼}›Eúˆïÿ¢\†¯_-WWÐnÃÕÕ@/—Á÷!}ú;C¼D&ãâybfæ9R0„‹ ¤Xkø} ô”‹ C‚Tgfæ9ž'2WLM‰åeé`IH°ö¿=²"66@úÁò²ÏÔÔð™Ò'VVbǤq €1†$I°ÖÞIÐÄ1Ia!æÍ>þì%¾ÿ“Z ÖnÆZ;r¯lÌÀ¿Vßÿ‰ôRHÛ¬¯c ¨×ëpzzÊÖÖgggãLjµÚÀÞh¤¶\i[HG¶RøÆ1sss,--EÅb‘b±H¡P ÝnÐjµX\\daa‹Ü€áËŒtäjb¢ä¼z%Iîß>èööV³³³:88P&“QµZU.—ÓÞÞž$i_žçéääD¹'OôíógWa(ûøqé‘‘øãÙ3çŸJE»»»úëõk+ŸÏkrrR’”ËåÔï÷%Iiš*‚}bB·½žäy’ëâÊZGý¾\×U©TRµZU£ÑP·ÛÕÍ͚ͦÎÏÏ5??¯8Ž5==­V«¥ËËK7›ú³Pº]9àéˆJ… ÀÎÎa°ººJlnnÒn·)•Jt:ÖÖÖ‚€÷ïÞ*¬tt§š&Šèõzt:qõ®¯¯1ÆÜ/G@Êúú¸šcž–4óiDcÌžcÀÌ=<»Ó$ vpþŸœ¦ ɳ²ò[èÔxÐyö€“ö_[r“%`ÄéoIEND®B`‚routino-3.0/web/www/routino/icons/limit-2.1.png 644 233 144 1303 12573351603 14562 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“xIDAT8Ë­”?K\]Æ÷W¹(j,WòV),ò lÜV,Lea!hiáÇHÀF¬eÁ"~«m„ø¯ÐbQÉ‹(.DMöÜ{~)îj\’—·qà3gÎÃyfžLÓTHìëûGX3IŽÒׯ ‡†4IŽ…µÎ=BÚy‡<õõ%Bâû÷}Â³ì» úéSôòR¯¯õò²ô4˾ :ùIç=X©¤ööbµúFøêÔ”6›…šcás+ýÜf³pjJá«Õê{{±RIqt§§3á‹Ë˪?Õh‚Æøû<Æ4ª?]^Vøâôtæèh‡&|tfFµmž[´Û†,Šî©æyn‚æy™?3£ðñ±foͲ–''%‘ŒO¬¢1Æ. '¿‹žœh–µ„·k..ªæ±ÝVõèèÈ••ÿm4žžž–ñ2?wqQa á³õº…ª{{{ 899iµZuÿ pssÓJ¥b½^W5üø¡ZX¯+|N|ÇÄB Ðl6YZZb{{›þþ~!$ ###Ä MR&&`pð^]©Z”upggÇññqçææžšÊ.Z«Õ\__/c²xu¥ÃÃEJŒ í6H_½âððZ­Æìì,«««„8;;£( €ß¿zní6ʤ´Z4Dˆ»»»äyÎÖÖccclll0??ÏÍÍ Y–ÑÓÓC Òh@«uÐÕMóÜûû{ÿýöÍóós/..¼»»óúúú‰îíí­v¸ÿÑÍ.uôóÿö:란Œ!tië¹pcŒ%Ð_'àEgóE·Æ‹î³Ü´¿ô­ q5‰pIEND®B`‚routino-3.0/web/www/routino/icons/limit-196.png 644 233 144 1404 12573351603 14603 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“¹IDAT8Ë­”½Kc[Å×=/\㉉f´SæU¬…‚X Ó›ÊÊ?#i,ÄÚb,ÿ†ÀˆXŒ£S $:ðPˆ0à…Á|Ü{ÏoŠÜD}ï•n8pÖ9{¯Ã>{í-$! c ’AÉäßH{8ÎwFF “‰ÇùŽ´ß ÉÄqB=¢dÒAr(“He<ï7››ðù³¥Ñ€_¿ ÑèâÍMð¼ßHåØß‰ã%\×00 &'ß"Õ)àê*B¬xn]ruQ(€Tgrò-ÂuëëÒ¶·Ú€% ÀÚ§Õ; ´ÙÞéëëããqšR… €aHØnY @EA@EO¸Õ"êtºþ Uz–Ãó|j5¶ÛؘÈZÛß÷ˆú8 ±`©ÕÀó|¤œö(•BÛ}jµÊåå%gggìììpqq@½^§R©pzzJœoH©Òž¾òé@Dqpp@"‘àððF£ÁÔÔóóóÌÍÍQ«ÕXZZbuu•……þùù ²?‚ôÕ(•z§|^’Œ9Ž£ÑÑQ êøøXÙlVGGGÓÖÖ–îîî”N§µ¸¸¨±7o$É(Ÿ—R©wFÆ ×•$YkU,5==­ÛÛ[­­­éññQ+++:??—$e2åóyíïïëä䤗HHÆ`d­£NGÏÍZ+cŒšÍ¦r¹œ–——•J¥433#×uU*•”Ífu}}-I¢Ó‘¬uŒ|ÿ›ªUI²²V’4<<,IJ§Óò}_»»»* *—Ëš˜˜ÐÐÐfggõáý{I²}ù"ùþ·ÕŒÉÃÃÍf€V«ÅÍÍM_arO††Ý¸gÕ|¡³Ø¡¯³žX{šë‹7þWgÿéûŒ°Gô?µÕ¿:àU{óU§Æ«Î³Wœ´Ücq»õ;IEND®B`‚routino-3.0/web/www/routino/icons/limit-31.1.png 644 233 144 1371 12573351605 14653 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“®IDAT8Ë­”¿N[KÆ¿=c1ÿd•$ns-ªô¹¢¥ B‡6©Ìð7eÜ»O$KHqŠH<€+B$ $¸@A„ÈV|vç—âßÜ’‘Vڙݙùvö›’DEH’(þDjàÜÓÓ0;˜žçƒs!E?¡û@…‚Cr$Ié qü•Z Z-ã⮯áâ"Ók5ˆã¯Ho÷ÝÀ_"Ÿ ‹HǬ®ÂùyýþËËËa¡:···\]] 9×ét¸ýòÀ³¹™ýæÏ< ž…þ—_$ úϲ¨Vú–¦rÈ­ßöÞcú_:àQ{óQ§Æ£Î³Gœ´?úUn³PDÏ{IEND®B`‚routino-3.0/web/www/routino/icons/limit-24.5.png 644 233 144 1511 12573351605 14655 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“þIDAT8Ë­”½K\YÆŸ{]gÜ««“XÌtã,„©b¡„µ¼‚ƒ2 k@“nWü¶°H ±X ÿCBÄT),6… ne¢&ÑfÔY?q˜ÌÜ{Îo‹q\…e+x9¼çœ÷å9‡çy…$$áº.’‹$ššº‘æqœÄbp÷®!Çù€4y.$÷²N¨Þ¨©ÉArxô¨ éžwÁä$¼~m)áË(kùä$xÞÒ³ËûÎe½D$âŠd² éé4 ±Öpµ<¤P0¤Ó }"™ì"‘ˆ+âq1<ì!í0= P,AAÖþõ=°@…éivöˆÇ/Ÿ)='“Á@5¨T0Õêc aÞ T*Õ*TÉd@z^ÿ³{xÞW›ÏcÁb ÖÚñŸ0¦Æ0ŸÏûŠt¯á7éw&&~rÆÇÍÖæ¦»øò¥ZZZÇå8Žvwwµµµ¥ŽŽIRZ^^ÖŸïÞ)—Í:?šh±ø=ïß7(”²¼yÃ_Ÿ?›<ß÷I&“lllÐÕÕ…ïûW„ŽŽŽH$ŒŒŒðóè(ûfxõ #e]µ´Ü—ï«ðñ£ûËÔ”VVVÔÜܬíímÍĮ̀\.«½½]u¬¯¯ëüü\€†Òi%¢Q—ä¶µÝÿ®¡±{qád††”¸sG©TJ¾ï+ CÍÍÍÉ÷}­­­iooOÝÝÝŠÅbU¿~šR[<®Áþ~ÀµAฑˆ6wv400 ±±1ÍÎÎJ’zzz”Ëå´¿¿¯\.§r¹¬B¡ ÎÎNMLL(‘HèääD²Vã¨*eyû–?^¼0®K__­­­,--°°°@&“ÁZKoo/«««¤R)bmmŒ?~L†ÅE¬”Ò.ã:Å¢er¤oôöÞ'á°ÝÝbjÊG:`~  8‚‚œûß®ÖÀUæçA:`jʧ»»ñLéÓÓX¨Õ*¶VÀZKX{ó‚¶V#¨V±Pcz¤wWößÿé 8…ÖZœs×^èš³sŽFžs…øþO¤¡é/^¾ò^¼°û»»æÃÇjkkS"‘Ðáá¡VWW›±sNÆíííéï÷ïõ{4êu?|h)Û¼êÒÙ,ùïßío¾ÏØØ}}}är9R©ããã sttÀÆÆ±XŒL&CO"AþðÐòù3uiǨ½ý±ž>UñëWóç›7ÚÜÜT"‘Ðââ¢J¥’ººº422¢X,&I²ÖÊ÷}¥ÓiÝëéÑ¿ggFOžHííM¨¥W©hzbBétZýýýJ&“š™™‘1F£££Z[[S>Ÿ—$•ËeÅãq­¬¬¨\.+v÷®dŒ¼Pã‚À3á°v”J¥”Éd´´´¤h4ªh4ªÙÙYÅãqK’Ö×וL&•Ëåäû¾òÛÛÒ;rõºgl¥²«­-míï»z­¦l6«ŽŽµ´´h``@‘HDƒƒƒš˜˜ÐÐд½½­X,¦GôÇÌŒS6«Ðùù®–yýšs¨ÿS*QjØÅÅÖZÊår“³³3ªÕ*§§§u^½i¹É…Â%٠ΜsMX¯3×ô­ÅþÂÙ 8¨¹ À]Jæ¬7üzý*§Æ³g×p«Ú¼Õ®q«ýì;íG¹ŠqyIEND®B`‚routino-3.0/web/www/routino/icons/limit-28.1.png 644 233 144 1475 12573351605 14666 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“òIDAT8Ë­”ÍK›Y‡Ÿ÷5ÆÌkÆjýˆˆ(t P‚‹Šà¢‹¬_‹Š`³ÑM»±Ý Å``VÒ.·Ò⌠ö”v Œ˜”Ò# ‰ŽÉ{ßû›E>F;[/8çÞsçžs @®ë \ŠD~¬Ëq>«³Sºy3Pg§ä8Ÿëõwn=ÑH‰8GÉdDðBžWÖò²ôö­Õá¡ôí›txX³——%Ï+ ^Ôýz<(vÕÖ††‡o ¾hnN*IFÖº|j¶Q¡hnN‚/¾¥¶6»(Cóóž`_++’T‘dåû’ïKÖþ';ÉJªheE‚}ÍÏ{ŠÅêß„—ZXP UýJEAµ*I ‚@¾ï+®(cd|_TÕ£G¼lôìŽ<¯hóyYɪø}kí¥\FÖ˜Z…ù¼äyEÁ–_àW=yrÏyü8ø+›uóÏóèïï'“ɰ¹¹IGG±X I¸®Ë‡ *§ëöí@…ÂÎÞ^ öôîþüú5øÑó”H$422¢ÕÕU iqqQƒƒƒÚÝÝmV¸½½­p8¬ß^½’¤ÀýZ‚=—hô.PÈåÜŸŸ?'•JFÉd2tww3==ÍÀÀgggcp‡žž¬ã¸Ü¿7nÜu[Z[eËe>dff†x<Îèè(³³³„B!6668>>¦··I$“Iâñ8çççÐÚ ®+×ú¾ã†Ãd÷÷™œœdii‰µµ5¶¶¶#•JÑÞÞN:¦X,bŒÀZ õâû`­ãår–tš?>}²¦Zegg‡¾¾>‰¹\Ž®®.ÆÇÇ™ššbbb‚R©€çy´†BÖyÿŠÅ,‚u={¦sÉü}p ƒº\\\È÷}ÕP°V'''MdNOOõO©$IFOŸJ°ÞäLù|›Kœ5غ¬7OÍï gW&ÀJUëû²µ‘ù¬Mݘ†Ïwp­³y­[ãZ÷Ù5nÚFO¹q°dvIEND®B`‚routino-3.0/web/www/routino/icons/limit-33.png 644 233 144 1305 12573351602 14510 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“zIDAT8Ë­”1K#Q…ÏL–$;MÆ€ ÉVÁFëE­• “Z°ÐàX²¥öi¬´óGØØiÀ"¢ˆE$‹ qæ½o‹™¸«âVyðŠsß½ï¾sß¹WHB®ë"¹H"ŸÿÔÂq.ð}( ¾ŽsÔJÏ…ä¦qB£‹òyÉ¡ÑÈ#íáyÏloÃñ±¥ß‡ÇGè÷¼½ ž÷Œ´—ú;i¼D6ë’ˉJ¥ŠtÍú:t»ˆ±ÖðïJpL·kX_éšJ¥J.'²YW”J¢^÷:ìî KAµ÷Ȳ» R‡zÝ£TJiJûÀ+q qŒ1†(Š0&yÜ;œú¯Hû£šÕð¼WWIÆ8ÆÂvö3N’X®®ÀóHµÌ/é·¶¶~jsÓ(Ž]29Ž£ËËK…a¨l6«r¹¬N§£0 •Ëå433#$9Æ8šœ4º»û®³³ŒÎ8:J˜¼¾pssC±X$ªÕ*a2;;K”ËeNOOêÃ!€á褳o*µ¼,I®\W’DZšÍ¦J¥’úý¾^^^Ôl6åyžnoo5¥D›IÜò²T(,Љ ÃÃèouyzzbccƒJ¥B»ÝÆC½^gnnŽóóóäeÉ'ÀÃLLQ(Xz=â”æáá! ,--±²²Âêê*óóó¥þôzP(XWƒA[''’d]Ç‘$­­­ijjJ¾ïkzzúí#|ßW­VS£Ñ$e«“i0h ©ÅÎ@œ 2ÉEÜßߥ¶85&q;; µ>ë̬µïÄ:Ú#ü•ξì€/Å ÿ週öæX§ÆXçÙ'í}m‰ÇN`…IEND®B`‚routino-3.0/web/www/routino/icons/limit-39.1.png 644 233 144 1441 12573351606 14662 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÖIDAT8Ë­”?KcY‡÷®^Ãe‚QâÚ)dSì`aÆN˜E°›an°Ü!v6~ƒrÒB »fRŒ_À€X9ŒZκ ŠA!’Œï½ç<[Üèºë–8œ¿ïï¼çœç}…$$áº.’‹$R©Ÿ*8Î>™ ô÷2pœ}¤Jg]HnÇNèN(•rŠÅÒ[|¿E©Ÿ>YÎÎàê ÎÎ’q©¾ßBzÛÙïtì%<Ï¥§G ç¾13§§ˆ±Öð°$ã˜ÓSÃÌ HßÎÑÓ#<σƒbvÖG:`i à°DDXûO½› ܲ´Ò³³>ƒƒkJe^½Â@ÝÞbÂc QaÌ¿$މ£!ARùîÍžãû×öð09±cøPÀZ‹µöVŒãdÿá!øþ5Òs!Ul©ìïS.—ÙÙÙ`ww—ååeŽŽŽ‰Öj5þLˆm©REFúBµÊWW¦¿·— Èç󬮮R(§P(P¯×ï=[__Çó<>¼{`¢÷ïAúâ*~¡‰ ņûû›7*‹ÊårÚÜÜÔÀÀ€¶··åyž666$IaÊqe³YYÇ‘$WRoï ×íêBÖêç\N¿½~­µµ5knnN­VKSSSÚÛÛ“çy’$@ÅbQ###º¹¹‘$©»[r]Ü8 ={¦?ê——/U­V•N§µµµ¥±±1MNNª¯¯OCCCª×ë²ÖJRÒB"E’µŽûÃ÷ï_õù³~ ûc6«L&£|>¯ÅÅEœœheeEóóóÕôô´šÍ¦$É÷}uwuI’uj5éúú«*,,ÄQ»ÍÅÅQ&ív›óós¬µc¸¼¼¼G¦ÑhðW³ ³°üæCÎL‡3Ó1¾Ãà´Éäÿr–D@„6Š òž­Gý8Æ&Þÿ'ž46Ÿ4k{ÂLû78Ïnj ž¸¶IEND®B`‚routino-3.0/web/www/routino/icons/limit-114.png 644 233 144 1260 12573351602 14570 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“eIDAT8Ë­”¿J+QÆ¿=÷î&¬ áª¤¼Š•¾@lWI‘€O{_B{Ÿ  K + ¶Š"($ R؉ü·Éžó»ÅnbŒÍ-8ÅwfæcΙoFHBÆ$ƒ$²ÙßHûxÞ¹üúeÉåÀó®öS¿Lš'Ô'Êf=$J%‹´K>S­Âá¡ãþàþ>ÁÕ*„á3Ònï¥ùA`ÈdÄÌÌ,R‹õuh·-ãœeØÓn[Ö×Aj133K&#‚Àˆ|^”J!Ò ÛÛàèõ ×ç>Nÿ±½ Ò ¥RH>Ÿ>SÚ£\èÇÄQ„unPPÇXûQ¤íõˆ£(‰/—AÚëÿÙaØ¡ÙpqáFˆ†±s.Á ¹£Ù„0ì -iŸÍM€Øu»4 noo£¸ÕjqrrBúÞ˜ÍMö…tN½`±–ƒƒ|ß§V«P¯× ‚`€£(bnnŽÕÕÕ¤r°Ôë ML,©P$ã@žçizzZ€$Éó éóóÐlZ Á9Ë¿­'4›–ùy>ÏßbhH¤Óž˜˜¥’Ô`e  8â✻ô‹5p@—•”J>}šÒc*,Dq·‹"œsÄqpöù3år™|>ÏÎÎN‡©©)ÆUÜûMæææøãÉâ!¬—D‘Q6«/_ê—{÷T­V•Éd´¿¿¯Z­¦\.§B¡ (Štpp0@眓@’¤8–œ3^êË—·zõJ¿†¡»™Ë) •J%mmm©\.K’Z­–Â0T»Ý–$ù¾¯Ÿ®]“$g^¿–Úí·BZgy ‰¿}ãèèh@åôô”óóóÅããcl_:­V‹¯gg ËË ­§3Û×™µv ³ê­Wô;]v@D.Ž¡'ÈÿÄI‚ë¡ÿO\io^éÔ¸Òyv…“ö'uQºÿIEND®B`‚routino-3.0/web/www/routino/icons/marker-15-grey.png 644 233 144 2612 12573351600 15617 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“?IDATHÇ}•OhTYÆ¿sî½õ^^-¬²cB$"©T %Ò6ˆ¨Ø`ãfì,¢ ¶‹Ž0³±izÓTC-ZfÓ‚àrvBTJWj¹˜šÌP£ØÆX&]µH@fB*j•}î½³0UÓöx¼ÿß;÷w¾såóylK)‘ÏçM¡PøÔZû—0 ø¾o~ ë8)¥þMDßæóù¿ Ž¢ Ж¨°Öjkíï”RW‚ ø" C›L&ihhÌÜS4Æ`eeÍfÓ*¥(‹Í„aøg"Z'"@Kl­Õ†¥”åN§3œJ¥¢'Np6›%Çq°3|ßÇ‚-—ËúåË—_xž÷‰Öú„µö9±8räˆ0(¥ügÃ###á¹sçT:&!¬µ¿Ú¤” L&ÃF#|ñâEJ)õ{cÌmkíkŽÇãPJý°¹¹ùQ:§§§U"‘€1@D`f03ˆÞ¡µÖ"Š"ìÚµ ÓÓÓ*N‡›››)¥~ˆÇãà > ‚àËT*e&''U÷¥®@w¿óRÊÞ½ÉÉI•J¥L_Að™8vìØuß÷O:eGFFÈ"¡Õja}}‰DÐn·Q¯×±±±õõu¼zõ ‰DñxRJ»¸¸HJ©QEÑÇÉdÒŽ303´Öˆ¢ÅbD„ .jµnݺ…d2 ß÷Ñ×ׇK—.A)…ññqžµNçcéû¾Íd2Ü××­5„X^^F±XD»ÝF.—ë-ii ™LçÏŸ‡Ö]gXkáy†††èÉ“'†ß%ÇïñÛ»w/.^¼ˆÑÑQ¼yóæ×[‹z½ŽË—/ãêÕ«¨Õj ¢^Q·t˜…¦Ýn# ÞÉÇÁ–+`­í‰j­111©©)ô÷÷ãúõëh6›B:˜Ù°ëºzyyÙT«Õ^Ç|(¢(ÂéÓ§qæÌìß¿SSSRâùóç=4KKKÖu];—Rr¹\ŽšÍ&˜¹—]×Ý.ºví?~ ¨V«°Ö¢¿¿pïÞ=Mïâ¯âìÙ³ÿzûöíèëׯ'FtàÀ¶Ö‚™177‡0 qðàAÄb1„aˆàáǨÕj8|ø0r¹îܹcêõºp]·†á”˜˜˜€1æ'×u'×ÖÖvk­Í¾}û’É$†‡‡±{÷nXk‘N§166†?~¹\ÕjÕ–J%ö<ï1æ$ýW2³ðcÌWžçý½R©ØÁÁAd³YlŸPDÔ[îž={@Dh·Û¸ÿ~‹Å}GD?  ˆh–™/‘¸{÷nØjµÀÌï®+ܽV*•¢f³©b±Ø±±±0€¨;(C"âC‡]qçF³ÙT·oߎvö~׫BŸ¿¤µ~€\8Ùîk­ßçóùKâd$°~ÒZϤi:F’===bxxZk8ç ¥„1oÞ¼Áææ&…B)U3ÆLXoÃiýé(ŠX,MµZµÍf“Î9¶›sŽÍf“ÕjÕ‹E€!îTÆ8Ë8Ž¢hK¥RR¯×I’ÖZcý¬µ$Éz½ÎR©”ే•J©X.—“ ,ÙÝ¥K2M÷Ó4†4†.I˜ììІgår9@¥Ô)%Ëå®`ǶÑhøØ$9@™!³N3á¾Ñh0Žc €¹\îJ$„x蜋§§§yùòe‘¦)T¯^ ÀÎÐ×$ ðä °´|ü|úùáÒ®.ôô÷#¯5ÿ|þ\!~×ÝÝí666|!HòæM Ožôç­[äÞyü¸÷¥$  {ôˆ$¹±¾ÎîînZvdd„$™’ä÷ï>ðÎÏñî]ï7›äî.ùõ«¿#ÏóqAÛ‘‘° €ÔZèËóóÀéÓþ¬Õ€«WcÇ8qxñxùX\ô½ãE8ìÐз··=ý¬ÚKK¤R>ËÑу;{–œšjuDÖb¥R‰,¤” ûÇì¬çËr~žüöÍ-.zàǽÿô)yäz9 ²°°@N‘ Т߰·X4õµ5rm «Uòö­}öÌû×®‘¥’g2ÜÚÚâàà`†à …´Ö°|á‚!ÉôÆ E>«ë×=àö6yô(yû¶Wco$911aàß Ù˜µÖ+X©T,I&¯_“³³ä»wûZîì÷ï“M€¹¹9·… !ÄE)%¤µ¹9¯oV4kɶŒfuu•½½½ÙìWÚñ@ ! ”šÀÞ8NêŸ?{€Î‘5¦5óccc&ìÖZ__¢(jm(¯”€Öº–‹ioì}LO|ffÆÀÕÖvj[{踈µÖú†l3ÚËËË, ¥”£´;í°¾µÚ Cû˜°ê~B€ÆØ}ã8N²•H’•J%£½  099ÙþYúwëÔ÷üùó†$kµX)%…Û¾o?d-}•R wgΜÉhWmõ£€ôpAAiÈð¯þþ~(¥äÿléÎ_£(¢”rÀÏlÙ??œÌüùL®IEND®B`‚routino-3.0/web/www/routino/icons/limit-38.8.png 644 233 144 1476 12573351606 14700 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“óIDAT8Ë­”ÁK[YÆ¿÷”$óÒ¦’C4 8@™‚®\„t#B,"*X nݺqÙîÅ…”>h)-Ýù"±…vº1 QC :Æä½{³Hlk»õÂåžsîùÎ9÷ò#$! ×u‘\$‹ýŠ´ã¼¥£’ICG8Î[¤Ö½ÜNè*P,æ 9<|CzŒç}aq^½²œœ@µ ''M}q<ï Òã–¿ÓÂKD".ѨèééCúÀø8”˱Öðýjê!å²a|¤ôôôŠHÄ™Œ˜˜ðÞ³²P,AAÖ~ÛW6°@•Þ31á‘É´ž)=¡XÄ@#¨×1Æ‚ À˜ëšFƒ ^Ç@ƒb¤'W6€ç}¶GGÍŒ-ଵ_Ok--?kŽÀó># ´­I냃ƒ$“I8>>fxx˜ÝÝ]†††H¥RÌMOóž?ÇJ%!m°´——œ4‰I½^çôô”0 ±ÖR©T®ÙƒËK€¥%6®ñÌ´xf­ýàŠs?ÉÆ`~àÙ·˜œhØ €0ü‰¬×ä0Ä6«o09ù]ÜhoÞèÔ¸Ñyvƒ“öñÛw:ÌN´IEND®B`‚routino-3.0/web/www/routino/icons/limit-27.5.png 644 233 144 1515 12573351605 14664 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”ÏK[YÇ¿ïuLä¥McA’…t  ¤eº¬+Å…üÑ‚`‘š…m7ŠF»ÐMݹ„"¶¸Á©Eœ2RR\¤¤ÝɘhAÅJÞ{¹÷3 £cgºôÀYœsÏ9œ{ø~¿B’p]ÉEÍÍ?#Íá8Û$pã†!‘ÇÙFšk¼ Émô jnvîßoFzŽç35KK–r¾~…rù4žšÏ;FzÞ¨wý‘ˆK4*Òé¤Ïd³P* Žµ†‹v×)• Ù,HŸI§;ˆFE$âŠdR yH¦§|À††`í¿~– øLOƒT`hÈ#™l|SzÁè(‚Ð÷1A€µ–0 ÏÝZ{¾`èû„A@££ ½8»Y'žwh‹E,XŒÁZû]óÍ˜Ó ‹Eð¼C¤ÎŸ$=åÁƒ¸só¦ÙÎç¯üþî‹Å´´´¤x<®¦¦&uuu©££CAheeE»»»Š¸®3ö䉹öðaœ—/Ÿª.}àÍþúòÅ\ó¹¿>{¦õõuŠÅbZ[[ÓÈȈr¹œúûû%I[[[::: ÁlV©hÔåî]¹×¯ß--ÆT*ü±¹É­[·˜˜˜ Z­’Éd( ç§ÚÜÜ$—Ë1??O*™ä··oÁ÷©ÇãÆµa踑ˆò…‚úúú4>>®ÙÙYIÒ‚Z[[ÕÙÙ©Z­¦ýý}•J%µ··krrR©TJÕjU²Vã¸æø8¯÷ïõçǶZ^^V[[›666”Ïç588(I:88P6›U:Öââ¢Z ýrû¶ÆÇƬ^¿Ö•oßòBšãñcN ^ÙÙa§áµZÃÃCNNNH0ìííàû>•Ju=iîg‹§¸1ÿeý_l­c0`íœ}Ç Cì)e~8ÀÖëg5÷î]`À¥róRUãRõì•ö²x¸¯øaIEND®B`‚routino-3.0/web/www/routino/icons/limit-17.3.png 644 233 144 1451 12573351604 14657 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÞIDAT8Ë­”ÁK[YÆ¿÷¢Iæ)m`6‘΢´Ð›AK‘àN‚µ.[èBÿÿÁY¶kÅ4(Ì" ]¹Ma.b!Å„„YeÚªI5MÞ»÷7‹$Vf:;œÅwï=ß¹çð#$! ×u‘\$þŠ´ã”‰Å ‘0Äbà8e¤íÁ½ÜAœÐ(u^¾Œ"½Åó¾±¶…‚¥Ù„/_ Ùìãµ5ð¼oHoïA¼D8쉈túR¥%h4 `­á®õq@£aXZ©N:ýˆHD„îH&E.ç!UØØèßßkøð ,Ðec¤ ¹œG29(SzÇÊ @/èv±¾µß÷oÝZ{ûAÓëáw»èñâHï†=ËàyWÔë`m?óÿÚ-©1}X«ç]!eB¿KèÍ›ßxýÚ¸’[üðA£££j·ÛÚÝÝU¥RÑé驯ÇÇÇå8ŽªÕªÞç󊌌8©'O Æ/N©R‰ý}óçþ>¡PˆÃÃCÊå2³³³,,,à8GGGÔj5‰«««¤’IþªV RiD<Õ³g²’ë„BJ&“jµZš™™Ñññ±¶¶¶455¥ÅÅEI’µV›››šœœÔßõºz_¿ºzþ\*âqÃçÏ ;•ÍfÙÙÙ Ùl2==M¥R´©¯”v»Íòò2Sé4'Ÿ>Áõ5æáCãÊZG½ž†f­•1F’´··§‰‰ e2u:µZ-åóyÍÍÍ©P(hÌóT:9‘B!Ù p\]]}T±(IV’ÆÆÆ‡%IÅbQ¹\N’Ôjµ”Íf5??¯T*¥X,¦ÌãÇZ}õÊêà@¡ëëBÚf} À.//ét:\\\psss[âùù9ÖZ‚ àìì ÿû÷~Üú:HÛ?tV«õ•?×ÕlŒc0ÿÒÙ&Àú>CŸ ÄÝceåÎÜëlÞëÖ¸×}v›ösšo£!ÈåIEND®B`‚routino-3.0/web/www/routino/icons/limit-144.png 644 233 144 1230 12573351602 14570 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“MIDAT8Ë­”±N"Q†ÿ¹YF2 DM(I\ -µ² ë ¼<чP{J*H,(­½c¢ CAgÔD#sï·ˆ°’­8ÉßÌOΜûŸ#$! c ’AÉäo¤*žwK: ËË–t<ï©:þ.$3>'ô•(™ô<ŠÅ$Ò1AðN©ͦ£×ƒçgèõF\*A¼#õÞø¼„ï––D6»†Ô& ¡Ûµ@Œs–éqL·k CÚd³k,- ß7"“ù|€tO¥Žá†Cpîûùzˆ¨T@º'ŸÈdÆ¿)P( ˆcâ(Â:7)ÈZKÇß<GÑH_(€tòÕ³M‚àV ÀÅQ„›J䜛ÏÖŽ*lµ Þ6…T¥\ˆÝ`ÀÅÅ“ív›óóó¹ì ¦\©*¤+ ‹µœžžâû>õz€(ŠX__g€Á`0Ã1X ®ŒR©-år’dÈó<­®® $ªßïkeeE’tpp0ÃHF¹œ”Jmƒ|_’äœS±XÔÆÆ†‰„ÎÎÎT¯×µ»»«‡‡©ÙljooO———êüù£_’H$$c0rÎÓ` épÎÉZ+cŒ¶··uss£N§£§§'íììèúúZÝnWwww#}IÎy3=öû„aH­V›4¼V«†á\Nõlæ6džäõõ•ÏÏωÇ>>>xyyÁZ;ÃcýÌmÎøŒ)sþ7Fº>û1nNÂiãǸQUÿLÀBgs¡[c¡ûl›ö/Nî t…¢ÕIEND®B`‚routino-3.0/web/www/routino/icons/limit-44.png 644 233 144 1150 12573351602 14510 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”¿N2AÅÏLd@ ,LHÄÆ+;kB±† úF{J­è|Ÿ@cL4BÍ4ÄMtwg~» |j¾†›l²g÷ž¹sî?! IXk‘,’(jH}Œ¹¥T‚•G©ÆÜ"õ³ÿB²OhzP¡` {{¤‚àN..<ã1Ý.@’Eù4U£ÑˆËËËû©lHèvAê éŠÁÀ‘$³èÎ9677ÙÝÝ Š¢œ|§Ã1€teU,ÖÕhH’•12ÆH’ŽŽŽôññ¡ÕÕUIÒááá$kS^£!‹uQ.;&“4Z&óüüœµµ5ö÷÷ÙÞÞæøø˜õõu¨Õj<<<¤R§Å™L \vVÞE‘æÍZ«z½®››=>>êééI;;;º¾¾V†º»»“$yH Q$yo~ä ÎnxvvF³Ùœ`Çqü#gVÓ9Çûû;///?ðÌ~©æ¯}ö_û£Ïþœ€Y?-Œ§gÎçŸ Xêl.uk,uŸ-qÓ~+7¿•V.a2IEND®B`‚routino-3.0/web/www/routino/icons/limit-151.png 644 233 144 1341 12573351603 14572 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“–IDAT8Ë­”=K#Q…ÏÜc2ˆ#ÆNÜEPDÐz AÁh‘bÑB[Á?°°¥öþ ˆŠ•µ˜ÎBÄ-ÜÒ… Â‚ÑEÍÌÜûl1“¨ûÑyà-ÞÏûÁ9¯„$Œ1HId³¶ð¼¯ôöB_Ÿ¥·<ï+ÒVš’Iû„Zƒ²YÉ£\Î"m¿XYý}G½?B½žø++¿6Òz/í—ð}Cg§zôR ./-ãœå%?æòÒR*ô¡¡÷tv ß7¢X³³Ò7Öך€#Š ŠÀ¹gkÅÀMÖ×AúÆìl@±˜>SÚd~ $މ›M¬sDQÔ6—Æâ0ĆaR??ÒfëÏÆ‚.n6ÛMÿBÇIÞÚä† ¤±wŸ¥/Z^þ¨OŸ,QdŒï«V« P>Ÿ×ÞÞžŽŽŽt~~®‘‘år9Õj5¹$ïQ(XïÇœNOß é”jÀb-;;;d2vww‰¢ˆþþ~æææ¨T*\]]qpp@&“¡šô¥ZéÔ¨§gJÓÓ’dÈó< år9œœèþþ^€fffT,†¡äœS £éi©§gÊÈäû’$çœÊ岯ÇÇuww§B¡ ÅÅE•J%­­­éððP ÕÃÃÚð}ÉŒœó†z @ÆÕëu kiiIƒƒƒº¹¹iú a(9ç5g:>–$§´¨««K€&&&´½½­|>¯ÉÉIU*IRww·:::Z£œŽ¥FãLH[¬®Ä)!¹½½åññ€§§'®¯¯±öY í|‹Y]ië/žÇ/ÔãÚœ³Ö¾æ_R÷ŠgÿT€ûÏÀv,Ž[²úCoªÍ7ÝoºÏÞpÓþŒFqÈ14IEND®B`‚routino-3.0/web/www/routino/icons/ball-7.png 644 233 144 202 12573351601 14177 0‰PNG  IHDR à‘bKGDÿÿÿ ½§“7IDATÓ¥A ÃVÿÿçz’¨Iìm!0Ô,€TJWóFe¤I|…Z›z¡ý‹¿Ã;=M]†“ÏóIEND®B`‚routino-3.0/web/www/routino/icons/marker-24-grey.png 644 233 144 2653 12573351600 15624 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“`IDATHÇuUMˆSY=ßý©÷’¸y„¦ÅˆU$"•T¡‰”³PJ´Áv‡®Å`ƒ½ÓB»ènšF(ÒMv½EzÛ.ŒJDШ%Nìª)IUÅZ‘IAµ?ÑJR±}?÷Þ^tåui;.Ü·9ßùÎw¾û¨P(`LB¡ ‹ÅâƘï|ßϺ®k~‡±,‹¤”‰èëB¡ð¯b±È‚ ´NÊ1Êó¾”ò”çyû¾oÇ¡D"ÆXȨµÆÒÒ:Ž‘RÒÀÀ@É÷ýωè9qJ`Æ`PQíõzƒñx<8pàËd2dYކ뺨×ë¦Z­ª•••£Ñè_”RŒ1ÿ#"Æ÷îÝküYñÏó“ɤôèQ944Dœscþp„زe ³V«å¿|ù2.¥ü«Öú²1f•:t¾õêÕx2™ô;&mÛ†Ö:TÆ…”RˆD"Èår¼ÙlúÏž=‹Û¶ý^$¹Â<ÏûÐó¼Oâñ¸ž˜˜}ß8ç`Œ1cÌ,B„÷‰‰ ǵçyŸxž÷!3Æ|ëû>ÆÇÇá8”Ràœ£ÕjááÇX\\|Cµ1D„F£ÕÕU€ã8Ø·o|߇1æ[Á˜ã8ftt”çóóó8}ú4nݺ…³gÏ¢T*…“'"ÌÍÍáÌ™3h6›a¡‘‘æ8Ž ‚`Œ¹®k‰E"‘°ÍJ¥‚;wâäÉ“8qâfgg±°°ÆžŸ‡R 333¸}û6²Ù,R©Êå26oތÇ£V«……ú‰èõz`ŒiaÛ¶züø1æææX.—¡Ýnãüùóp]ù|ÙlÏŸ?Çýû÷188ˆR©"BµZ…”Û·oG£Ñ@£Ñ0¶m+à!«V«A§Ó\ºt Zk?~ÙlJ)H)±k×.lÚ´ A€s¾±e\¿~]Ñoø9rä§×¯_§ºÝîŽv»¤R)víÚ5xž‡»wïâÎ;˜ššÂÖ­[±ÿ~ŒŽŽ"Ncjj ù|étårY/..rÛ¶ç|ßÿMNNÀŸ¤”?õz½­{öìÑ###leeœs‚ ÀÐÐÇÖZkÔëu$“I4›MsîÜ9ŠÅb¿h­wccLøYkýwÛ¶ïÜ»wÏlÛ¶ ¹\. úFôWvÇŽX[[C¥R ,Ë’D4ID Dô#çü ­5¿|ù²ßn·ADPJAkýÎU½qãFÐétäÀÀÀ…t:ýO @ШODl÷îݧlÛ¾°ºº*¯\¹ô•õÕmܪ™™ýàÁ‹Å–=ÏûªV«……ùøøx?À´´´d”Rÿµmû£§OŸÆ•R:•J‘R*|Xcxñâ.^¼h¤”àD4CD€V,ÃG1&cËZëcÑhÓÓÓ¦^¯ƒs*ô}¥R)ð>’ä¶$Ih·Ûïznü6Ío<³9×zdí½žþÏþ¹ÿ%+ü°}Ý;^¾Þ³>^Ú?°‰*MâIEND®B`‚routino-3.0/web/www/routino/icons/limit-21.3.png 644 233 144 1507 12573351605 14655 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“üIDAT8Ë­”ÁK[Y‡ï=›Ä7™N"BÚtÕ…BÁÝ Pˆî*BZ]ˆµÝØî†â?08ËvçÂýDB–.¥PS¥†´®‚ "µ)¤±yïÝûÍ"ÑQ׸pϽ÷Ü{Îåû! I¸®‹ä"‰DâW¤ç#©ôõR)pœH+Ý}!¹Ý8¡ó‹ ÉáÉ“Òk|¿É¬¯[ŽŽàË8:êø àûM¤×ÝóN7^"s‰ÇE>é““P¯ ÂZÃeëøõºar¤Oäó÷ˆÇE,æŠLFLMùH{,.´KB‚µÿó5°@›ÅEö˜šòÉdºeJo(1„í6&.’‰¢c®&h‚€°ÝÆ@@±Ò›ó?Ä÷¿ÙZ c°Öb­%Š"¬µ×*íú¬­ÕÀ÷¿! zHòüùoγgæß÷ï·o•L&•Éd亮¶¶¶dŒQ:–µV®ëªZ­ê¯ÕUÅ{zœìð°¡^ïu*O‘T¡TâŸÏŸÍϾO¡P ŸÏ³»»K¹\Æó<ÖÖÖ.2Ûßß§¯¯ééi²™ ïªUC©D$U\%“T(¨^­º¿¿z¥ÍÍM%“ImooË÷}õ÷÷ËZ«s ÃPKKKš™™Ñ»wœžºzøPJ&ôx·na›M§øè‘î¤ÓÖÈÈˆæææ‹Å444¤V«%IŠ¢HÊåršŸŸ×éׯúåömÉóäx® CÇÅ´³·§ññqÍÎÎjyyY€$ ã8’¤F£¡ÕÕUŽŽj}}]?ù¾*>Hž'EŽkšÍ½¯w»»6 mll(—Ë©\.K’âñ¸z{{%IS6›U*•Òàýûš~úÔªT’÷ýûŽVxù’DÇpxxH«Õ ÑhpvvÀÉÉÉ2ÇÇÇ„?~D¼xÒÊgÔj²¯zݬµˆÁ\ãìŠ,6 ±É\…ôò<ŠÎÏ<~|I7ªÍí7ÚÏn°Óþ‚žLc«J¿ÜIEND®B`‚routino-3.0/web/www/routino/icons/limit-185.png 644 233 144 1420 12573351603 14577 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÅIDAT8Ë­”¿K[QÇ¿ï¥$ñ!$‰B B±ŠC§íä–èL*uü ÛÝÍ-•¢P:p”€ut Å_5`1`^Þ»÷ÓáEÛŽ¸p¿çÞï—{ßs„$$áº.’‹$’ÉQ¤5çˆt2C: Žs„´Ö=’Ûå Ý %“’C©”Dú„çµXZ‚/_,ggÐlÂÙY„—–ÀóZHŸº÷._"wI$ÄÈHé”B „Xkè‡4†B¤SFFr$"wÅИ›óŽY]ðK@€µÖ},೺ Ò1ssCCÝoJŸ):„!¡ïc¬ÀC=2‚v› ÓÁB‡b¤Ï÷5{‰çýâäÀ†¾í Ykö÷ø!"qËÉ xÞ/¤—±ÒG½ÿZïÞ‚Àuãqíïï+ Ce2ªR©(•J)›ÍjkkKµZMߎ4–Ë9‰/ FŸS¯Ç„T§Z0ÃÆÆ±XŒ \.“ËåØÝÝett”B¡@¹\æüÇc+êÏ”J½Ò›7’äZã8”$YkÕ××§™™]]]iooO­VK€òù¼†Ÿ?’ë¼}+¥R¯\¹.ŠÇÈ¥RI“““º½½U³ÙT6›ÕúúºÎÏÏ566¦b±¨ÙÙY­¬¬èÛׯr$™XLr]\Yë¨ÓQoc”L&µ¹¹©ééiÕj5õ÷÷k{{[ZXXÐðð°®~þŒŽd­ó¨fA» @>Ÿ§Z­r}}ÍÔÔ™L†ÅÅEêõ:ããã¤Óiæçç }?ªYµ R]Hk,/„]CrssÃÝݾïsqqAÐ=k·Û\^^F¾‹r!ËË ­ýã3°ÇJæ‘çz±‰LûÈgÿíÛ#ø·Y-`ÿ´Õ_ð¤½ù¤SãIçÙNÚßÚÔhëgsÛIEND®B`‚routino-3.0/web/www/routino/icons/marker-38-red.png 644 233 144 2111 12573351600 15422 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“þIDATHÇ••ÁkSYÆ¿{ß½iÍ¢BŠÌ"¯é,lk]vÕ´5ŠBVŠÓºPWÅŒÿ S„Âé,,S](.D„.,Z.©šTº˜Ú"Q2)ïåÞÏÅ}/MÒœ9Nîå_ÎùÞ9'À¾Éîîn ]]]§´Ö¯€<[ÏZëW]]]§ Š“1HDÞ`|§µžk4S$ÙÛÛ+ÆÆÆ µ†µRJ„aˆÕÕUìîîR!”RÅ0 ¯ø«…Óü…£žç•0N‡…BÁT«UZkÙjÖZV«U “N§CŒâŽÆÇûžçm`&“ J¥IÒÃ0 |Œ1$ÉR©ÄL&Dà ¾ÃJ ¥Ô"f³Ù †{{´A@6m™ÒÚ `°·×„g³Ù•R‹RJ ‘Hœ@ß÷M¹\&I†ApÔæ# Ã$Y.—éû¾ÀD"qJ©5œŸŸ7Í!WVÈ;wÈgÏb1ó†\X >$ëu†Q%óóó&Êv l*•²;;;.–$ggI€Þœžˆ#%[©TP¯×¡¤=¸p0¸t X[zz\Ô»wÎW«@­”ËÀçÏÍ ÚÞÞ )eÀü¶°àÞèö6¹¼L~úäjzþÜ•¹¸è4¾ukÿõ²qñ"Iò'OÀ !xž÷3ö¥Óaik‹ÜÚ¢ÈBÁ¾xá “Ç“W®¸û·oi&oÜ`äð±ch~E2™„ÖúwÌNN†$Ù¸vÍ<©) ÐŒŽ’»»üñêUÿŒ5Nk­70ŸÏ’ ž>uýøò¥ëѸO77É»w>zäºìÞ=ÿB Å@Bˆ“RJh—–œ¾ñˆã ÑDÅãYÙÜdŸïdzŸoå€B@)uû|?(½ïÿ0²ñÝÔÔTíÖb?<Ïkn(‡WJ Ak]Œ–‹Ó·c¡Äó>77g"`¥¹ZÖ:.|­u¹Mß(³¸ìõõu&“I€RÊ:Ëî´ƒú‹mÖj5‡ÑòøEß°6}}ßâ•H’ù|>.{@rff¦õoéß­S߉‰‰$‹Å")%…'£Ç½o;õUJ•pzzÚŽŒŒÄe磲Õ¶é `RA(Õ(¥äÿ6õüOžçQJYð}G5ì+cƒˆ‘ýøösIEND®B`‚routino-3.0/web/www/routino/icons/limit-29.3.png 644 233 144 1525 12573351605 14665 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ IDAT8Ë­”ÁK\WÆ¿÷ 3öÕ’q@ž™…SÒEѸŠ`Dq'¢‰.„ šìJð(v™àNÝׂ 2¸v•FBEƬD0 Sœ÷Þ½¿.S-]záÀ9÷žïœ{/ßw„$$áº.’‹$BZÄq>’H@2iH$Àq>"-ÖÏ…äÖqBW…$‡'O‘^ãyçLOÃÊŠåø>†ããËxz<ïéu=ß©ã%b1—x\¤Ó÷‘‚rÙÖ®¯Ë8¢\6 t@:}Ÿx\Äb®ð}1<ì!í33P,aaÖþkW{`33 í3<ìáûõgJoÅ@Öj˜ ÀC†só‚&k5 ŒŽ‚ôæêÏ2xÞW[*aÁR^/`­ÅZûͯ'\†¥xÞW¤LïÒo<þ³óì™ÙÛÙqÿX^–çyjmmÕîî®–——ÕÒÒ¢d2)k­\×U±XÔïKKŠß¹ã¤²YC¹ü³µÕ HÚ¢Pà¯OŸÌžG__íííäóy²Ù,¹\Ž®®.*• $“IÆÆÆHù>ïŠEC¡@$m¹jjz¨þ~•‹E÷—W¯´¾¾.ß÷µ°° ¶¶6mll(‹immM’fgg5>>®Ö{÷|ùâêÑ#©©é¡hn6¦ÞõÏ·oéèè`jjŠÃÃC:;;$³´´@Eœ122Âé4Û{{P­bîÞ5® CÇÅ´³¿¯MLLh~~^ÕjU™LFýýýjnnV*•REÊçóêééÑÊÊŠ¾÷‡ëº˜ŸŸçr¹lÞ¿ÿM,ûµ1æ3¿$"!:Äv(¥þéyÞ®®®.ÿìÙ³:›Í’”ÌüÅPJ!“ÉP.—µZÍ÷î]Rkýkíߘùß"CkýÓÚÚÚÎl6ëêöövAf«B€è£µÌŒ ÐÞÞŽÁÁAÍfýµµµZëŸâñ8„çy_yž÷m2™´º%¢”‚"@Dá\)þd``@'“IëyÞ·žç}¥˜ùGß÷qøða$ Àêê*^¾| !˜RJäóy|øð/^¼y¥º»»‘H$Ð×ׇÑÑQh­TAô& .‹‚™ADXXXÀÍ›7‘H$àº.ÇA>ŸG¥RÁÈȶnÝ ×uÑÖÖ†óçÏCkb±(&&&¸Ùlö*×u9—ˉ¶¶6c ¥Äââ"r¹Î;c "‘àùóçÈçó!ßJ3#‹¡³³“?~lÕÇ=ŸD†™Q©TpáÂD£QœŸÿ  hÔ'"±ÿþ‹Žã\¯×ëztt4h }ža)%îß¿o=z¤âñø²çyœ™™  Ù×××z™–––Øó0~]­V“ÆÛÝÝMƘ°ß…xûö-nܸÁZkð;"ºOD €Q*•ÂC]¡„ËÖÚÁX,†ÉÉIžŸŸ‡”2´Á÷}ŒŒŒžç )åE"º@o؈R©ÑzØÀþÞ¾}Ûou”Ëe»¼¼¬ÇyæºîÐñãDZYÆâ3á/ü½uëVOž<Áää$b±¬µß)¥ÖÆÇÇ%Þì»Ü<ù9ÇùºV«%WVVxvvÖ4›M©µþ€f}ÜT>ÝZ›®l `æÃBˆ ×uRJ*¥Ê…B¡ÿéÓ§Âc?üdù?cCËß0óÑhTJ)—1¿Ÿ™™1ÿÿò¶ bêwEIEND®B`‚routino-3.0/web/www/routino/icons/limit-177.png 644 233 144 1313 12573351603 14601 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“€IDAT8Ë­”½KkAÅϽ‘›pƒÑA°|(DR§xU±í´´³±ôOÐVD[5 ÆâÁëÌ BÀ€‚`D4 ~Ü»»¿WÜø-¼Æ…=»3gf—3#$! ß÷‘|$‘ÉüBÚÀóôöB_Ÿ¥·<¯´Ñ¹’߉z!Êd<$™™ Ò*axÏÂÔjŽV nn ÕJð„á=ÒjÇßëÄKO:-‡Î˜˜€‹ œ³¼·.., 188D:-‚Àýýbr2Dj²¼ ð 8ââœ{[/gà€g–—Aj29Òßßy¦´Æô4@„1˜çgœs8çˆãøuc’ýÓqá bz¤µ—?+†mNOÜ ÑÍÚ¤ÂÓSÃ6R±KÒ’æær±Äq*:<<Ôðð°$©V«)›Í*—Ë)ŸÏëüü\]]]J§Óú].{C##–ÙÙœ·µµ$¤#ªU‹µìíí‘J¥888 ÑhP.—©T*tww³²²Âøø8•JOâïŸ?Öloƒt$zz——I寰¿¿ÏÀÀ;;;¯/Z__g~~þ[l./¡§Ç‰|Þr} @EŒ±¹¹ @«Õ¢T*qrrÀÕÕ¥R‰f³ùFv} ù¼õ圧(Ò{sÎÉZ+IÚÝÝU¡PÐèè¨$©Z­ªP(¨X,Ê#_’¢HrÎóÕn«^—$'ç$IÙlVAH’êõº¦¦¦^}ÀIB§z]j·…´Áâ"€é’»»;¸½½åáááõ¿>àÄß°¸ÒÆaÌI}Ö:~töm¸w„_ˆœKˆŸOð£½ù£SãGçÙNÚV¨‰ª?x@-IEND®B`‚routino-3.0/web/www/routino/icons/limit-19.9.png 644 233 144 1412 12573351605 14665 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“¿IDAT8Ë­”ÏJ[[Æ¿só礷$q¦’ë$â tä ƒLT¨ÕÎJB|£däX.¥ˆ\ú€£Ò¤BAqä ê•‚19g¯_I¬Þ˹`Ã^ßÞßbí½¾µ„$$áû>’$2™?‘¶ñ¼ïäóðì™#ŸÏûŽ´=<’?ä e2’Çúzé=ApMµ Ÿ?í6üü íöÀ¯V!®‘Þï{C¾D*å“N‹éé"Ò++prâ€3Ç}ø1''Ž•Ž˜ž.’N‹TÊ““bu5@úÁÖ@0¢¢Ì~¯ôØÚé««““ÃgJX[èǽn@À9GE8÷0A×ïõz8èóú5HFV":ƒÙ0™afÿ¿w³ÃC‚RIHÛlnbÔëuŽh6›Ôjµ;”a«Õà‡‡±U« m é+;;É$»»»´ÛmfffXXX \.s~~ÀÁÁ³³³|~žâØñéNúêëéÓçzùR&ù^"¡ññqe³YíïïkbbBFC©TJ{{{’¤F£ñÏfõ÷Ǿ^½’årÏ}%(•’IZóFóóó:;;Óòò²nnn´´´¤V«¥t:-IZ\\T†¼ÙÔØØ˜”LJ¾/3Oý¾Fffò}_ÝnW¥RI•JE…BASSSºººR†š››S¥RQ¾PP±X”ÂPx¾:oª×%É$é'O$I…BANGµZM*—˪T*Êår ÃPµZMïÞ¾Õ‹¦/_”¸¾þvWM Æ9.//év»ÜÞÞrzzŠ™áœãâââ!Þïx››wÕèlPf#Žïô4’Â}Ñšn¨3Æ¿tö ,Š‘ÿ³c†âî³¶v¯µ7uj<ê<{ÄIû L:hv‚ˆÁâIEND®B`‚routino-3.0/web/www/routino/icons/limit-2.0.png 644 233 144 1332 12573351603 14563 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”;K+Q…׌×$ 3(Zh!¼Ml|€Øj¡­ÆÊÂBÐÒBÿ…‚… {;«”þ!S±ãƒAЀ3sÎw‹¹÷Ú¹áÀyì½föÚko! I¸®‹ä"‰\î7Ò1ŽScp†† ƒƒà85¤ãô]Hn'ô”Ë9Hkk9¤}<ï…­-8;³<>B§Éyk <ïi?õwÒx‰LÆ%›ùü8Ò5ËËÐh ÆZÃWKÎ1†ay¤kòùq²Y‘ɸbdD¬¬xHWìî¼–(‚(k?×ûXàÝ]®XYñIÓ”(Bâ†DQ„1½?fŒ!Š"lA'þÅ"HïœMàyÏÔëI"Q„ýÈÊb­ýÿ>³ÔëàyÏHB:f{ ¶aÀåå%‡‡‡Ôj5â$z½ÎÑÑ777 hâ³½ Ò±*œžbÀ\\\‹‹‹äóy*• Íf“ééi¦¦¦( <==‘’g8=©âj``FóóBr%©ÑhhggGçççò}_•JE’T.—•ÍfU­VÊå²$ÉH®æç¥™_r]”É8}’¬1Z]]Õèè¨&''5;;« I ß÷%IA¨ÛíêÃ2Éuqe­£0”•äöõ©Z­jiiIëëë*•JŠãXNGcccjµZº»»Óíí­ …‚$É‘¤0”¬u>8‹RÎJ¥ýýýÌÍÍ1<<ÌÉÉ ´Ûm677ñ}Ÿ½½=ÒÊÀÎzªIÓívi5›ÜßßóððÀëë+Nc ÆÚíö§þ÷T³Ggé×þ1kíˆ1æ[õv@ªð¿Eú”8þ¦~´7tjüè<ûÁIû×.ˆˆO¯‡IEND®B`‚routino-3.0/web/www/routino/icons/marker-59-red.png 644 233 144 2132 12573351601 15431 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“IDATHÇ••ÁkIÆ¿ªîšFÄ9ìa:„]„ ¹yLH4*ʈ·M@ö¨ÄSæYÿ€ˆ67C0{ã¹ÄK@Xo9 *!$B`&€°a"’ÌØÝUߪzœLXÜ}Ð<ªºê×ï}Uï5ðÝd&“‘N§/)¥Þ ã<;ÇJ©wétú¸}2 ç=ÀOJ©ù8Ž'I2—ˉ‘‘(¥`Œ”Qa}}‡‡‡Bß÷+QÍø»ƒÓþ€çy5ÌçóÑââ¢n44ưӌ1l4\\\Ôù|>@·o É8‰8ð¢]A` ¥ è?—–ì‰6›äÞy|lsúòÅê÷â…Ï͑׮‘’™ ãÕU«Æë×`„!<Ïûû‚ ªîí‘õ™3ä£Gò䉅îì7o’wîØùÇizzÈFƒGß¾q¨Pˆ], ›ÍB)õ‹ããIÆXçY_.[PrúyîõÊ Iò·Û·µnÈ&ç•R»Xž™Ñ$¾}K.-‘>œ¼øÛÛäÓ§ŒÞ¿'I.//<B oõ¥”W–—­¾q|è|Ržû{{ìëëKj¿ÜÉ%„€ïû3NßïM¥»dµ¦vå999¹ÞZéïï‡çyíeñ¾/ …”R×\¬¾I´I½»ÌÏÏkÜow§Ž¶‡®‰@)UÀr¹lõu‘%iomm1›Íj”RþÚv·Ö·R9áÑч††"×êþB€Â섾A„IK$Ér¹œ¤½ ;==Ýù[úwëÖwll,"ÉJ¥b†”B\t˽»õõ}¿€SSSfxx8I»ìÒöÿ+ð„¾Æ…»ÿ„ïûòÿÛú:?ëy¥”û~îÊæ”ýÕ6bcð3»ÐIEND®B`‚routino-3.0/web/www/routino/icons/limit-28.0.png 644 233 144 1532 12573351605 14657 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”ÁK[Y‡ï9M2ÏhM#A:-cÑ‚! q¨è¦!ƒíF7íÆv7ÿYI»ܺ‘¡`×Ù TÁ(PRA:Q$Š(¦Åä½{¿.;Úµ.÷œ{Ï9Ü{ù~GHB®ë"¹H"ùiÇyO[ܺehkÇy´Ø8’ÛȺ(‰8HG^âyfgáÍËÑ|úGGuv<¯‚ô²ï4ò%B!—pXôöÞFú@&¥’¬5\u? T2d2 } ·÷6á°…\‹lÖCÚan  X||¬ý^ìªÌÍ´C6ë7ž)½bj 5¿ZÅÔjcð}c®^ÐÔjøÕ*jLMôêâÏîáyŸm±ˆK#ñÇÖÚ﫵ŒÁ‚µÅ"xÞg¤{MHòôé¨óä‰ùgkË}½²"ÏóÔÕÕ¥B¡ ååeµ¶¶*Ë#×uµ··§×¹œâííNìî]C©ô³³¹Ù¤@Úäí[6ööL‹ç‘N§d~~žžž¦§§éîîfcc€r¹Ìðð0CCCôݹÃ`XYÁH›®¢Ñûzð@¥Ý]÷÷/”ÏçFU(ÔÞÞ®‰‰ % I’ÖÖÖ‡µ½½­–›7õW.ç*“‘mn¾ÿSÓØJÅ™zøP]±˜”N§•L&µ¿¿¯¥¥%œœ¨££C’¢Ñ¨$©¥µU_¿|‘ÂaÉuq­ï;n(¤­kffF ÊårQ>ŸWss³Ö××(‘HèøøXú÷ãGýÚ×'ÉÇ5•Ê–Þ½ÓßÛÛ6¨Õ´ººªÎÎN¥Óiíîî*‹)•JirrRÉdRcccJ¥Rêïï×oÙ¬Ò££Vkkr+•-!-òü9_!8><ä°1ÏÏÏñ}Ÿr¹LXk9==Ń1¦nW«Ïž´ø3ŠÅ:Ù—8»`ë²m­­3h æή(ÀBÍú>¶.™+°^±ƒà"¦Æ£G—p­Ú¼Ö®q­ýì;í7 £R¾ö¯cIEND®B`‚routino-3.0/web/www/routino/icons/waypoint-search.png 644 233 144 371 12002775154 16245 0‰PNG  IHDR Vu\çbKGDÿÿÿ ½§“ pHYs  šœtIMEÜ;–¸¢†IDAT(ϕѻ ÂP …áÏ©hHG ›0ÒÐRG´d¶`$$Ó\!7@,¹ðã·Î‘#3MŠÌ|&6èqÃ,ßv@‡5fØ"ÑxU€ëk¿©ÉŒˆûRžF=”Ë œËõ#Ú¯’ÊRb‡æc^î˜×¼ÅÔ?4Ãù7ð+&Kz—Ö¢­]ýxIEND®B`‚routino-3.0/web/www/routino/icons/limit-26.png 644 233 144 1341 12573351601 14511 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“–IDAT8Ë­”¿K\M†Ÿ{ÅuÙEV$"VB¬beìTP­DÐ4j)ZZøWHKk»öZØ©³¦h%ë"(¤Xˆ »÷Îów×/òùu Ì™ócÎ;ç=ã8bóù!aÏ(úiOöö¦öôhýöZz„¸å‡´åó‘ùåK^øj¡ðǵ5ýö-xw§¿ëÝ]&¯­i¡ðGøÚ²Zþ`.ÛÕ…ƒƒ…kçæ´ZMÕÄRÿ^™œX­¦ÎÍ)\;8øÑ®.ÌåbìïÇùù‚ðËÍMÕg5Ølj³©!ü»ÛwÔg77~9?_°¿¿¶]\Tm˜$š$¦ij³Ù4M³äÒ4µÙhdrËFm¸¸¨°Ýþ³O u¯®²ÓÔ‚!„tiëî­¶ƒ¯®´P¨ Ÿö\_WMl6_œ.//ÝÝݵR©¨z}}íöö¶­ï mȉëë {ß=8Èx~VõüüÜîîn§§§òøøØr¹ìÌÌŒãããÞÜÜd7ª© ßcJ¥ÏLNBƪÕ*100ÀÖÖµZÞÞ^&&&øðáQG@Ìä$”JŸcâXr9:::!°°°Àìì,ÃÃÃŒ±´´DÇLMM±¿¿ÏÙÙ!Èå Ž !¢ÑÈ”iJÇT*Êå2+++ìììP,)‹¬®®Ò××Çíí-j¬Ñ€¢˜zý''ÙCi Àéé)I’pxxH©T¢³³“ÑÑQòù<###,//gH¢ prõúÿTSõññÑûû{kµšµZͧ§'Ó4õááÁ$£D¶Þ¨ækžýmüÒEáyCvx“gov@›¸¯ÈÚ>ÿo¼ko¾ëÔx×yöŽ“öùf;<ä"°IEND®B`‚routino-3.0/web/www/routino/icons/waypoint-up.png 644 233 144 361 12002775154 15423 0‰PNG  IHDR Vu\çsRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEÜ 'ôÞpqIDAT(Ï’Ñ € Dß1¹ßnÀle¢;˜úC“Š@Ô&—+×k)ð'Ìì k‡G.ˆ!É*¯†'µn’–pÎ|ëàÕC»:Äê3—8”u°Å¡ -`ˆrO`3¸ Õ> pçhWõþörÇúü+.Z‹‚¿£IEND®B`‚routino-3.0/web/www/routino/icons/limit-38.7.png 644 233 144 1514 12573351606 14670 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”ÁK[YÆ¿÷’&™×iâhh "ÎÆ"”qQ]Q#¡IÂìFÿ·.¤.[pgVÙ fÑ)í¢Ý8¡‹€JhË(vÐ… ¨Q¬¥5&ï½û›E’©Îl=páž{îùι—ï;B’°mÉF‘ÈÏHy,ëÐÙéÓÑ–õ)ߊ Énå µ" ÉâáÃÒSç+33ðò¥aNN`¿éÏÌ€ã|EzÚºoµò%B!›pX¤R½HŸ˜œ„Ý]ð0Æç²5}Ý]ŸÉI>‘Jõ‹Pȉ„Èd¤ ææê€ÁuÁuÁ˜ï«}¨37Ò™ŒC"Ñz¦ôŒln½Žßhàû>®ëâûþ¥æ îÅn£ óàHÏÚvÇ93[[ÍŠ­ÄËm+ÖŒ¶¶ÀqÎî¤E?¶¦§ýÍíß‹E…C!uww«R©¨X,**‘HH’vvv´²²¢ÍMýõþ½õãÀ€ÿÓ—/?˜r9 _zÇ«Wü}râwÆbd³YúúúXXX §§‡©©)’É$ëë묭­144Äèè(–ÄŸå²Ï›7¸Ò» nÝP:-ïógûÉâ¢nß¹£|>¯Z­&Çq411¡íímÕëuIÒðð°J¥’–——Õ“Jiüþ}Ûìí)í`cõõö*9=­ß=RµZ•뺊Çã* :::R<—$…B!U«Uåóyýñü¹$I7nHroÞ4Ôj_¼à—{÷H§ÓHb~~€þþ~ …ÇÇÇ,--122€°·±˜±ß¾Uôúµ~ÍåÌíx\±XLÉdRårY«««êêêÒàà ÆÇÇ566&@¥RI™LF-3zûV:;«)Ïì,€ç^\pxxˆÛ$&õzƒƒ<ÏÃCµZÅÃéé)çççàyÍæfgAÊ_á™ßâ™1æ_€6çþË3Ӻ³ï ÈåÆuÛÿGÖöÞx^[V r¹K ¸Vm^ëÔ¸Öyv“öJól$‚É–­IEND®B`‚routino-3.0/web/www/routino/icons/limit-16.1.png 644 233 144 1347 12573351604 14660 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“œIDAT8Ë­”ÏJKÆ¿n3íÐ4] ¹n¢«€àÆ?àNqáä d|#³wm yw½b ‹€£.ÄÀ4G´«Îï.z¦¯&[Ô©ªï«Su¾s„$$†!Rˆ$ªÕ ‚LMA½î™š‚ øt8ÚR8 ‰ªÕ) Ù¬"}"Ž´Zðõ«qs¿~ÁÍMá·ZǤO£óÁ/E!““bnîR—ím¸¾ö€ÃÌóÜ ßq}íÙÞ©ËÜÜ;&'E…bvVììÄH?98xŒ<‡<³ÿÇx xäटììÄÌÎŽž)µÙÝxrø€÷ž<Ïñþe€8‡Ës<<±» R{ügï‰ãŒnf#"3ÃÌž½Ðžq9̹"‹ ˆã é½ÙßÇÀ¤iÊÕÕÝn—v»Íùùù_¤iÊ¿ÎZ-…ôNÀw:T*NNNX^^fss“ÕÕUz½^Ùññ1QÑùüÀç_¾€ô-T­öAëë2) &&T¯×•$‰NOOuyy©F£¡µµ5MOOK’¼÷ ‚@FC’j}]zûöC¨‰ E2I͵°° áp(3+‰ŽŽŽtvvV’5›M-..j8J’T©HaH(³@OO 3S’$J’D{{{š™™Q¯×S–erÎI’ÌL‚”ç’Y*˾+M%É$©V«éþþ^+++šŸŸWÇZZZÒÖÖ–6664 $Iq«òæ$Y¦R–}/³ 8¼§ßïóððPJàööï=fÆÝÝ]©¹~¿ÏÃïßn¿Ìf¡³"ÍF¡̬ŽÉ^X±÷—Î^T€å9cÂ?ÅZÎc$î?*àUkóU»Æ«ö³Wì´ÿ»Fk‡ü°GIEND®B`‚routino-3.0/web/www/routino/icons/limit-29.5.png 644 233 144 1516 12573351605 14667 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”OH\WÅÏ{¡3ö‘FGynFL¡(Šš0t'ŠÙtPL0 4Ù•àÒM¡ËdWÔ(C@W®Ä@D¡aS0L²R†F‰‰eÞ{sï¯ gR-tç…îwïwÎýÃ9Ÿ„$\×Er‘D]ÝH 8Î{ ±ÑÐÐŽói¡º/$·ŠªÕÕ9HÖ!=Çó¾2= ¯_[ øü …Ë|z<ï+Òój½SÅKÄb.ñ¸hi¹‹ô‘LŽ PÁZÃÕq™W8>6d2 }¤¥å.ñ¸ˆÅ\‘LŠ¡!陀°DDXûoÔÖÀ33 24ä‘LVŸ)½`da˜0ÀCEsý‚Q…!„ŒŒ€ô¢ögíxÞ›ËaÁR^%°Öb­½FX­³ärày_Úoý&ýÎÄÄÏÎø¸ùkß]][“çyò}_Z[[SSS“%IQi}}]ÛoÞè ›u~ºßÄ …ïy÷î–*R– þüôÉüàyôõõÑÖÖÆÊÊ ]]]¤Óizzz(•J‹E|ßgxx˜±G(–ˆW¯0RÖÕíÛ÷Ô߯ãÜ_Ÿ=ÓÖÖ–’ɤæçç•J¥´»»«X,¦ IÒÞÞžÎÏÏè—LF~<î’NË­¯¿' cª§î¼}Kgg'SSSÑÝÝÍàà ñxœ¥¥%¶··™œœdqq?™dsk ‚€Ê;ƵQ丱˜ö500 ±±1ÍÍÍéââBíííêïïW"‘P*•R¹\V>ŸWkk«&&&äû¾NNN$k…1ŽB)Ëæ&¼|i¾s]z{{I$,//3::Jss3³³³œ‘N§ÙÙÙ¡££ƒ†úzÆ?¦†ÕU¬”ÒOŸò7TJù<ùj”ËeÂ0¤X,b­ÅÃéé)AP*•jz¬ðä H ßtF.w©›ª¾jÿ«9c0`í]s€…ÐFöÒ2ßÀÿÛJ¥VòàÁܨ7o´kÜh?»ÁNû¡¥€ÁjUÐIEND®B`‚routino-3.0/web/www/routino/icons/limit-1.6.png 644 233 144 1251 12573351603 14570 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“^IDAT8Ë­”?K+QÅÏ^aMA‘•”_£Øh-±H*[I>@>†é­m~»”*XyA CÀ€(îÞß+6ÉóÏ{öΞ3÷Î3#$! ç’C…Â/¤#‚àš¹9˜ŸÏ˜›ƒ ¸F:ý’ñ„Æ …) V+ E/Ôëpzj<>Â`ù¾^‡(zA:áƒ_" ÓÓ¢\^DúÍî.Üßg€Ç,ã£å{Ïý}Æî.H¿)—™žaèD©$öö"¤šM€wÀHSHS0û»Æ>0àf¤öö"J¥QšR‹j !M!ËðÞ“eŸ/–eiš’% xŸã«UZã7[&Іt»ù‰Þã½Ç̾dhŸ|–3º]ˆ¢!Ò²Žh4’$þDÚÁójŒŒ@:mÏ«!íôî…ä÷ê„úD’G>?€T$ÚllÀçÏŽÛ[øõ no»ñÆA©ØË÷zõñ¸O"!&'ß ]±²7708gyŽnl¸¹±¬¬€tÅää û"“««Ò¶·:€#Š ŠÀ¹§Õ?tØÞé««™Lï›ÒGr9€ŒÁt:Xç°ÖEÖÚ§8 ±Ýü\¤ýžÍ-./œétp="çÜã¾Oôcp฼„ h!ÍÆþ’þÖ‡ïT(X¢È÷ãqU*c”N§U«Õtpp  ”Ífuqq¡ýý}%’I¿~íñê•õêõ¤ªÕ˜ª|ú`±–ÃÃCb±år™ëëk’É$‹‹‹ÌÌÌpttÄÄĹ\Ž?ÆÇùçë×îƒK%ª¾†‡ßjaA’|òo‘­}›·p`8Ì93s¾gæ|GHB¾ï#ùH"•ú ©ˆçU Cxü؆àyU¤âà\Hþ Nh˜(•ò<òùÒ‚ C¡>8ÎÏáÇ8?ïÛ…AéÍÀßÄK$“>cc"Î ÕYX€FÃç,¿Jß64–…ê¤ÓÆÆD2é‹©)±´ ³¶p 8ââœû©Ã=pÀ-kk ³´055x¦ô–åe,ôâÛ[l¯7c­Ås Æ`â =ž?éí°fO‚+W«áÀa-ι;ú»cpý µÁÒ!]¡`+666¨V«£Àz½ÎÞÞÞ d?“—Ëe¾×jÆ e¤Ï”Jüóí›ý3ˆ¢ˆt:M¥R “ÉEÑÀöö6Éd’¿ß½°ñû÷ }öõðáSE‘_¿ú¯^¿Öîî®ÆÇÇutt¤õõuÝÜÜhbbB’䜓sNžçirrRÎó$É׳gÒ£GOý? \§£å\NóóóÊf³Š¢HÆmmmiffFûûû:99Q"‘µVù|^ÙlV×××’$%’ïã»8öüdRÇÇšÕÊÊŠ677%IÓÓÓ:<<Ôé驪ժ...dŒ¡ô“űäœçÛNç@Ÿ>éã—/Îôz*•J ÃPajggG«««ÊårZ\\ÔÜÜœÚí¶$)%<$ç•ËÒÕÕŠ¼|É5˜‹f“f³ÉÙÙÝn€n·K«ÕÂZËåå%ÖöIÑjµ¸i· /^ô»9ügôÛì°–ÿ%}¿ÿü³ô\ãú”ù…’îΊ1CŸßp¯Ü¼×©q¯óì'í¿l3€Š<}_IEND®B`‚routino-3.0/web/www/routino/icons/limit-113.png 644 233 144 1322 12573351602 14566 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“‡IDAT8Ë­”ÁJQ†ÿ™š&Èh% -"ØUÐ ®ÜŠP#îÜéø®›½/Ð\Äp…®šD Jܸ\$(±“¹s¾.fŒ‰íÒwñß{Îï¹ç?GHB¾ï#ùH¢Pø„tŒç]2= ïß'LOƒç]"gçBò³8¡g¢BÁCò¨T H_‚ßìïC£aÜßC§÷÷)Þ߇ øô%ó÷²x‰|ÞgrR,..!ݰ¹ ww à0Kµ;îî67Aºaqq‰ÉI‘Ïûb~^lmH¿8<ˆ#Ž!ŽÁìe= ýbk+`~>KSª²½ 0À9\‘˜ äœ#IÒG&IBüçÉ`úooƒT}þ³2AÐãúÀ\a¯ˆžñè>Îa`\_CôÊB:æàÀYzÍf“ÛÛÛa\³Ù¤ÝnpuuEµZå{«E–¯ãà¤c!µ¨×’„““r¹µZ €z½ÎÄħ§§t»]Â0dgg‡>ðíü<ÍüëWZ ÃU­¯K’o ÏóT*•HÒ›™œs:::Ò‚Úí¶"ç$Ég}] ÃU_¾òyI’™©R©hyyYý~_’´»»«••u:•J%ííí©V«©Ûí* ÃôÂ|^ò}|™y 4jf6†ã8Öìì¬ÎÎδ¶¶¦F£¡b±¨­VêE’™ç«×û©fS’LI±XT.—’MMM©ßïkccCsssš™™Q¹\VåógI²wR¯÷s¬š™ y||äééiXÍQÇ1Äq Î¥q#ÕÓYæð_3³ñÆqª³››1ýÓöŠpL¬€½´Õ«xÓÞ|Ó©ñ¦óì 'í_ôh¬Oåh»IEND®B`‚routino-3.0/web/www/routino/icons/limit-1.9.png 644 233 144 1257 12573351603 14601 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“dIDAT8Ë­”±NA†¿;Äa®ÁŠ@”ˆ„&ÐÚ 4È®éàxŒ¤qÅX¢HÅXB¢Š"G(4. @‘°ˆøîöKq¶pJ~i¥ÝÙ™Ù™Ùã8b+•w‘QôÍjUß¼)¬V5о GÃ{„xh‡ŒU*‘ÙhT„¦é/÷÷õóçàõµþü©××åy_Óô—ðq¨ íÁ$‰™Á¥¥·Âwv´Û-ÔÜ ÿEyÎív wv~¸´ôÖ™L’±^O…ïªþVƒY¦Y¦!ü]#™õ·‡‡ ß­×S‡iÂ'wwUf™…yž[Ï+ŠÂ,Ë,²Ló¼ÔßÝUø4ªÙ{Ó´çÅEùbž›ç¹!„†±,¨¡t¼¸Ð4í ïŽ<8PÍͲ±A»Ýöêêj‘j§Ó±ÙlzyyY: J»ƒ…#„/¶ZªÅ°›$‰­R®êùù¹+++Öj5×××½½½EYØj)|‰™›ûÀÆ@ÌÔ!¢(b~~ž#œ±°°Àéé)I’prr@107÷!&Ž%IÆF!kkk<<<Œå[[[ôû}¶··ét:LOOïHˆccBˆ x‰Q„Ýn—ûû{VWWÙÜܤZ­²¼¼ @0@QL¯÷•v ðOZiš2;; @½^'MSúý>Íf“½½=jµä9Sh·¡×û:ñ›#ÜÝÝùøø¨:.öÓÓ“777iSê?ûÍ žý!„1EŠF¤àÙóÈs}AÚ‰ýPg²^µ7_uj¼ê<{ÅIû„ªd³¢Þ/yIEND®B`‚routino-3.0/web/www/routino/icons/limit-9.5.png 644 233 144 1372 12573351604 14604 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“¯IDAT8Ë­”¿K\[Ç¿÷Hîî»»Ko!ŠyòB´1¥XXج…‹‚Á"šB[ÁÒæÁ+“Þÿ@°hie³`e±F¦4âe•Y¢ìî=ç|^±wKœ3Ù/Ÿ! Ic ’ÈçÿFÚ&N( Tr 'HÛÙ»L'ÔK”ÏHïÞå‘>E¿X[ƒÏŸ=——ðã\^vÏkkE¿>fþA/††\N ¿BúFµ çç°xïxhݳåüÜQ­‚ôááWär" óóÒW67Ú€'M!MÁûß«wh³¹ ÒWæç#²2¥O,.t°×é¦)Î=þXš¦ÝÕnã»I;,.‚ô©§Ù¢è'ggÝBÒ_•Ç{Ï“fm÷‡ggE?‘Þôý+ý§¦ôþ½#MMðâ…¾œœhwwWårY¥RI’”¦©ööötxx¨z½®^¿V. ^¾tÁ÷ïéø¸OHÇììàÀœžž2::ÊÔÔ4 ’$!ŽcX^^&I2ñ;; õ÷¿Õô´¼d$éèèHårYµZMaj_½ûf³)@sssŠãX8§@2šž–úû߃°›IR¥RÑíí­fggU¯×†¡$©X,jiiIÕjU:88PÐ×''Ia(ƒ‘÷:õìîîNcccš™™Q±XÔÐÐZ­–...422¢ÕÕUÅq¬««+õ W§#yÜkæ3ÍšÍ&•J…ÁÁA¶¶¶¸¹¹arr’Z­Æøø8…B••¬µ`í#Í„´Íú:€Í€¤Õj‘$ Þ{œs\__Ðn·i4¿ùëú[Ö×AÚþ“3kq[¡}ÈœsÿgOvÖ>‚µ·¿O˜ùüÙÏÚ›Ï:5žuž=ã¤ý‚…f}¢sOMIEND®B`‚routino-3.0/web/www/routino/icons/limit-182.png 644 233 144 1445 12573351603 14603 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÚIDAT8Ë­”ÍK[[Å×½/FM*$ x¡o ʼn8B ™8Sv’I  þÞ°™)úTQ¡ƒ 8K¡8BÐtP´8²*¡¡`h!÷žó{ƒ›´yC78ûì½goÖÞB’p]ÉE‰ÄH»8Î'ÆÇ!6Œƒã|BÚíÅ…äöpB}¢DÂArxý:ôÏûÉÚ¼o¹¿‡ïßáþ>ò×ÖÀó~"½íå;=¼D<î24$|ÿ)Ò––àæÆ!Ö-òCnn KK }Á÷Ÿ24$âqWd2beÅCúÌæ&@°XûûôßÀ67AúÌÊŠG&Ó+S*²º Ð% ;Œµc‚cÌo¿ÝÆt»Qþê*HÅ~ÏžáyM®®lØé`{DÖÚ_÷>ѯŠÃ –«+ð¼&ҳ؟Ò_zóæ… C¸n<®ÓÓS…a¨t:­‹‹ ííí)™L*›ÍªV«éàà@#ɤ2™ŒÃ“'ÆùúuXÕjLHUö÷ ÆpxxH,ãøø˜J¥B*•"ŸÏ333ÃÎÎÙl–\.‡ïûœW*ч߽©êjlì¹^½’$ׂÇÑÄÄ„$ÉZ«ááa-..Ê÷}]^^jccCårY###:¯Õ"ÜË—ÒØØs‘J ‚¨©är9ö÷÷999annŽ\.Çôô4×××T«Ufgg) ˜0Œú÷í¤RÆ•µŽº] š1F‰DBGGGšŸŸW¹\V&“Ñöö¶–——•Ïçµµµ%k­$É ÉZÇU³y®%ɪU»ÝV±XÔÙÙ™R©”499©F£¡R©¤©©)—J’d͇R³y.¤]Öמ yxx ÕjÐét¨×ë„aH«Õ¢^¯s{{ËÝÝ­?"Üú:H»ÿѽ>ôueÄ;¨9"ÍýCgÿ;v€°/ÞÁ» lTÅ¿&àQgóQ·Æ£î³GÜ´õ_k/; 9IEND®B`‚routino-3.0/web/www/routino/icons/limit-85.png 644 233 144 1333 12573351602 14520 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”=KcA†ß%É^„„ I:!BpíRXmagg´ˆU EQ[Á?°°ånog%Ê‚M*óRÄBÔ2‚Ñà )Lîy¶¸7®îGç9sÏ;wæÌsŽ„$¬µHId2³HsI.ù¼#—c.‘’ïB²‰Nh¼Q&c kk¤¯Á€øþÝs?~Àý}ìïì@ ¾&ñ&ÑK¤R–tZÌÌ”‘n©Õ Ûu@„÷Ž×ûÝ®£Vé–™™2é´H¥¬(Åêj€tÅþ>Àð„!„!xÿ{Œ×ÀCö÷Aºbu5 XL®)}£^EE8çÃçâÃ…aø2|Œ¨×Aú6ÎÙG‚à'77ñÃ{÷þÕí<Y¼™çæ‚à'ÒljÏÒmn~ÒúºSY¬•1FNGGGGÊf³* :==U«ÕR§ÓQ¥RQ:“ahL¡àtw÷Aíö„Ú¸h8 Ùl2==M£Ñ \.s~~Îìì,µZF£A¯×‹O<8ŽAjO*›­jqQ’¬¬•$9ç–––Ôï÷uqq¡Á` @ËËË*•Jd&'cÝ⢔ÍV­¬E©”^ÛÓÓ“ …‚ÕëõT©TT¯×µ²²¢½½=5›Mc䜋©”d-VÞF’$@’trr¢……µZ-MMMéììLóóóÚÚÚR©TR¿ß¯ÑHò޼ə‹sÀõõ5Õj•|>Ïöö6ív›¹¹9r¹DñKâcæ^r&¤vw¢H†Ã!„ÉÚóó3/Ü%ðźÝ]þÉ™KX3öÚwÎáãÉ_œý·þ„õ Èÿ­€w­ÍwíïÚÏÞ±Óþ2£iÉ—¹sIEND®B`‚routino-3.0/web/www/routino/icons/limit-194.png 644 233 144 1331 12573351603 14600 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ŽIDAT8Ë­”?K+AÅÏ.¢qAüÔJ”¤ beaaá¦]RÄÂ/ @ðKhce©Xbi)‚`õ@ úŠ QAÝlvg~¯ÈªÉ{¯t``þÜ9sϽç^! I¸®‹ä"‰L&´ƒãT‚‘ÃÐ8Ni'½’›¾úÊd$‡åå Ò&ž÷Æê*Y xz‚F£½_]Ï{CÚLíô½Do¯K_Ÿ˜œÌ!Õ¨× `­¡s´÷ õº!@ª19™£¯Oôöºb|\”JÒ5ëë`‰cˆc°ö{~ž"Ö×Aº¦TòOiJ[”Ë-’„$Š0Ö`Œ!ŽcŒùvÒÄ1IµíËe¶>cVÀó^©VlEØÈZÛµî:kƒ[ªUð¼W¤‚vX[Hl«ÀÙÙ777\^^²½½Íííí—gµZÓÓSR¾ kk íéc8<<¤§§‡ããcSSS,,,0;;Ëãã#ù|ß÷HÀppÒ¯ ÎiqQ’\ rGÙlVýýýº¸¸Ðèè¨ÎÏÏ5??¯““ÝÝÝéããCÙlVi˜\-.JƒƒsbxØþ§4—––ØÛÛ# C¦§§ñ}Ÿ±±1ŠÅ"…B••òù<¿Sêöᆇ+kµZêÖZ¹®«0 U(äû¾”Ëå433£J¥¢z½®«««¶}IÖ:]1‹›M‚ `€b±ÈÄÄ_ ØÝÝ%‚6›Ž˜ue3$///„a@³Ùäþþk-ÆŒ1¼¿¿óüüü)à®lvéŒ$é¨û%ÖNѶӘüWgÿT€íìl'm{õWühmþh×øÑ~öƒö‹¤®~Ax-IEND®B`‚routino-3.0/web/www/routino/icons/limit-4.1.png 644 233 144 1225 12573351603 14567 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“JIDAT8Ë­”OK*QÆŸ9ÜF™RK¡Û&‚ÀO AÛDH¿‚~¡/Q{wE‹„}†h_.… ¡ ý±™9çw3Zv½;˜Åyÿ3Ïû¼¯„$Œ1HId³¿‘Úx^—|VW-ùø>Xûyâ;°À;{{ ÕY]õ˜˜ˆÚ”J‹}Œc‚ß÷ ‚°¸/zdô)A*ŘÍãy]0£1X¾J0ìÔb­…ðÎÒh€çu‘æ…tÂö6€Á÷CC ^¯S*•¸ººàææ†££#jµÚGШeÃö6H'BúM¹ÐïÐl6I§Ó‹Eæææ8>>frr’ååe²Ù,Õj5¬øý  \é·«TjQù¼$¹r]I’1FûûûÚØØP&“Q³ÙÔîî®.//5<<¬jµ*I²ŽúåóR*µ(ÆÆ:l^__Y[[cff†ÛÛ[®¯¯YXX`ssóCcÙéÀØX R)K«€‰Ú<==%—˰´´ÄÎΙL†ƒƒ^^^ðC¬>“·ZJYWÝnU•Š$Y7,[+++×ÈȈr¹œ¦¦¦Ôétt~~®ééi]\\H’‚~_’¬*©Û­þøÍX|ßçéé c ½^ÇÇGhµZôz½ØèÇo~åY`­ýBVk¿3˜´?xöÏ øàÒ7²Zkÿ3Ínî³nÚ?˜@¶¾LøôòIEND®B`‚routino-3.0/web/www/routino/icons/limit-172.png 644 233 144 1427 12573351603 14602 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÌIDAT8Ë­”±K[{Ç¿÷¯y7¾ªÉpA„@ßT4C\´:ˆ›ŠØÉ!ÒAÝý<œÚÍAÜDjÁ¡H}{ ‚ƒ” !`G«[ŠÆ”Xsïï÷yÃMÞÛÑg8¿sÎ÷Çùò=GHB®ë"¹H"™üiÇ)Ó×é´¡¯§Œ´ÞÎ Ém÷ u€’IÉáÅ‹$Ò+|ÿ;‹‹ðî¥Vƒoß V‹ãÅEðýïH¯ÚõN»_Âó\º»E6ûéSSprb€k w-Ž#NN SS }"›}Lw·ðþM¥RBH%Þ¾0ÃÎΉD‚½½=Êå2£££Œ‘J¥X]]e``€ññq²Ù,G>óæ H%W½½Oõü¹$¹ä8Ž‚ Ðõõµr¹œ5;;«ååeŒŒhaaA…BA===:úø1î{öLêí}*úû _¿Ƥ211ÁÆÆµZááa*• ûûûär9òù<&Šbþ¾|þ~ãÊZG­–îšµVÆIÒöö¶2™Œ†††T*•499©ùùy­­­ÉZ+IrÂP²ÖqU¯©X”$«v2•JÉó&»¸û‡ÇŸ÷¸÷Ì9çÞÿØ(ÛÕÕeŠÅâÉ0 _|Þµù= ×Åbñ$@¾Ï¶LÞ v…a8•$É%Iêëë3ÃÃÄaˆ÷k-q³°°À—/_dŒ1ιjÇÀ_›pÖao5@ýýýñôôtÚh4ä½×æòÞ«Ñhhzz:íïïåûö¶·—ƒ xhdd$ZZZ’$¥iª8Ž·=išJ’–––422åÀï€rk-ι€FGG#IJ“DQ«%ERgOÛhmMi’H’FGG#@ιÖZ( c€ÊårZ«Õ$IqȶʙÆ9h­VS¹\N …±À3ë½/ߺuK§N2 à>~„'OàÍxýÞ¾… À{°ž=Ã:GÒÓC_OÅbQOŸ>5ƘŸ|oo¯_^^–¼——¤;w$ºº²ÞÝ-}ýºÁtv6û>7—­÷^ËËËêííõù•#—$%kkÙ¦sç¤áaiuUZY‘¼ßðõÕ+içÎ ôáÃ-ûÆÇǤ°aB~³óÓƒ…èáÑ#p 8ÆÆ T‚f“Í•ãX øz½N«Õ‹p³ gÏÂü< Á… ðáLLÀà ܽ›­Ù±#› “ÍÐçÏŸ<ÖÚHïÍÌd'ÚjIïßKÍf&weE*•¤›7¥]»¤#G¤Ó§3ùûö)yüX’ôçóç¼1&²Æ˜ß;99™Ôêu\á‚Û·3MÕjvâCCpæ ìÞ ß¿C¡€€À9šÀ/×®¥€±ÖÞ£T*†á, ÑãÇcIJnÜȘAÖ¯_ßr?õí›Jçæ$I?_¹’æSõ(µ=îÃð ÊÄD*IÑ‹ÒÌLvÚmÀ8–’Djµß¿/}ú¤¹ùyŸ61ƒm@—›}ÂZ+ ©æ Ú³Îp} ²÷z½®öìW6ã„Æœs€ÊåPù‡‘M½—¼×¥‹ã<[«{öì!‚õ„Êೃƒƒ„aXÍÃ%ó·Í6¯v.LMM¥9`}=6ÅÊaÖU*•Ìß(Ú"{qqQ¥R)d­½Ø)»³¶û[­na¸ººªÃ‡ÇyÔýž_üÔËårÔŽDIªT*mÙ‹@éêÕ«›ÿ–þ½:ý=vìX,IÕj5 keŒ9‘/~Øé¯s®èòåËþèÑ£mÙ•\¶û¯€[üŽc$9Ã?öïßsÎþ_Àuóþk²ÖÖj¶Õß  E~ ›ÜøIEND®B`‚routino-3.0/web/www/routino/icons/marker-60-grey.png 644 233 144 2703 12573351601 15621 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“xIDATHÇm•OhTëÆŸ÷û¾3çäDÐaLŠ1dj˜ˆh"u(ׂHF¼håF¹xÅ»ií¢›¶” ¦0¸é¦nºíB¬DѦl:%Q)BIâ$ :ÒD¦8˜Ì$dbΟï{»09ÍU8pžï=¿ç}ßC¹\ÛJ)är9“Ïç¿dæßAö<þ/¶m›,Ëú}—Ëåþ–ÏçE†`€¶M%3kfþeY7}ßÿ&ŽÇã”L&!„ˆ1XZZB£Ñ`˲(‹Að+"ú/IZ̬RJ[­Ö¡D"ž={Vô÷÷“mÛøXžç¡T*q±XÔ+++߸®û­õYfþ7 yúôiЭ”ú‡ïû‡R©TpõêU«··—¤”`æO.¥ºººèèÑ£¢^¯ïÞ½KX–õScÌ_˜yMf³Yøãæææ`*• FFF,Çq`Œ‰*B€ˆ@ô-3Ck ×u‘N§åââbP«ÕŽãt´µµýUø¾?äûþ·‰D [;ܤ”B@fŽÌˆB(¥¢ƒ‡‡‡­D"a|ßÿÖ÷ý!™Édþìy^w6›åT*EZkH)±ººŠ……´Z-Äãñ¨Òååe”Ëe„aˆx<U¬”âùùy²,«O…aøE<çãÇ R¢^¯ãÖ­[ð}­V ýýý¸rå *• nß¾ Û¶±±±L&ƒsçÎÄää$·Z­/„çyœL&©­­ Zk@¡P@WW®_¿Ž‘‘Ôj5lnnbzz===¸ví.^¼ˆÇ£Ùl\×E2™$ÏóX}ÈáCJ)±µµ…Z­†öövܸqmmm‚mÛX\\Äv°8rä”R¨V«Ø·o_(!¤”f}}ADiAÏópáÂtvvâþýûXYY!‹í6Àö$Z­„F8Ž£_¿~mæææDfÆàà Nœ8K—.™ñæÍìÙ³ïß¿¥ R© R©°ã8ZøRJ‹Åpuu¶m£«« årP*• µFoo/8€ÙÙYÀÌÌ ”RH&“`f Mô'yùòåé­­­¾µµµÕëõ0N‹ŽŽLNN¢X,âåË—8uê°ÿ~-u!„BT1#®ëbjjŠK¥¤”† 066ú¾/¤”7‰è.k#òù<ÄÎͶ>áûðáàÙlFT,MµZU¶m/xž7zþüyì6Ä6X|dü ß„ðâÅ LMMÁu]c~©”Úœ˜˜x7w¹ûás|mÛþª^¯'šÍ&ÏÎÎêV«%-Ëú €1fŽ8î* ßÀ®_¶2sF1éyžVJI¥T±¿¿ÿËùùy¡µ6~ïó?ƒa‡ïcfþÎq)¥¬j­133íÞÏéñ5Ä9?[IEND®B`‚routino-3.0/web/www/routino/icons/limit-2.8.png 644 233 144 1350 12573351603 14573 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”½KcAÅÏ{»ÆøP"&¨ˆØ­´ÔÖÆ"6"èvŠ‚…ÿ„Ë€…XÙY[XÚùÁ–ÁHVø±OHæÍü¶x‰»Y·t``>î½3÷Üs®„$|ßGò‘D:ý©„ç•éï‡K?x^©Ôº’ßòjJ§=$ïßÓHE‚àkkpx踿‡zîï“ýÚÁ/¤bËÞkùK¤R>ÝÝ"Ÿÿ‚tËü>>xzz²:}cs´Ï’çÜH³&©m¤çþÓg?NÀ°—FFÓ}ý8¿:›¿º5~uŸýâ¦ý š‚vT‘SIEND®B`‚routino-3.0/web/www/routino/icons/limit-79.png 644 233 144 1325 12573351602 14524 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ŠIDAT8Ë­”?KcAÅÏ<Ñd_cÚ‰ZI´QÑJl¬$‚Ö ý¶ [*iìlŒéüæA$ ˆ…b£h@Dß{3¿-^â¿•­20ÌÜ™sÏ̹Ü{…$$áy’‡$’Éa¤Œ9&•‚LÆ’J1ÇH;­{!y-?¡6Q2i ËËI¤M|ÿ™ÕU88pÔëððõzl¯®‚ï?#m¶ð¦å/ÑÓã‘Hˆ!¤3àòÒÎY>ØŽ¸¼´,,€tÆÀÀ‰„èéñD_ŸÈç}¤ëëo€# ! Á¹Ù>¼±¾R|Þ§¯¯%SÚbi ŠpaHøi:ç°Ö†!Ö9°¢(Æ/-´ÕŽÙ¾ßäô4~1}SçpÎ}ì¡Mæ8=ßo"tý–þheeF…‚%<ÓÝ­‹‹ •J%Õj5œœ(NëööVûûûÊf³Êd2Âk²Y«««_ªV»„T¥\°ÑÛ‡‡‡LOO3;;‹ïûloo3>>ÎÔÔccc4ø—A`)—AªŠÞ^Çõu[±‚Xj±Xdccƒr¹Ìää$ìîîÆdp} ½½N¤Ó–ÖK|ŠÍÝݹ\Žóósîïïe~~žD"ÁÞÞÞW²FÒiëÉ9£ P{Xk%I¥RIÙlVÃÃÃj4Êårš››S*•Òàà $É;äœñÔl©R‘$'çÞ•JE‹‹‹’¤þþ~===©X,ªP(hffFuÅTN•ŠÔl i‡µ5€¨•<>>òòòòn¿¾¾rssó†Xgû­­´óß<ûœ[ÖÆ•Õ^ʳ+€(úúƒoämÌ¿ÐÑÚìh×èh?ë`§ý Ò—íê›BIEND®B`‚routino-3.0/web/www/routino/icons/limit-87.png 644 233 144 1304 12573351602 14520 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“yIDAT8Ë­”=KcA†ß—${t5$`¡àV)-´ÙÆÆV´°ôø¶4X¤ÓB±ÅNH¡ÿÀBÁïN1(("Š’{ï̳ŽѸºæÌù˜™÷¼çIHÂZ‹d‘D.÷©‚1´·CG‡£½Œ9@ª¤v!Ù4N¨‘(—3H†ññÒáÙ;àßà‰>í€/íÍ/_:ϾpÒþ"%“ß(™RIEND®B`‚routino-3.0/web/www/routino/icons/limit-11.0.png 644 233 144 1334 12573351604 14646 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“‘IDAT8Ë­”ÁJ\I†¿{¥»õjŒÅ dct¡Y‰dfã²é >Aû>F²sáØdY/à„H–H2 B« JŒÒÝ·ê›E·=m˜Ùy  þ:ç?TÕùÏA@À4M…TÀÁÁß„-“ä£ccúàAplL“䣰Õõ#¤]r“hp0WW…WfÙ¥Õª¾{=>Öoßôø¸ƒ«UͲKáU7>éòÁb1µTÂéé‡Â¾å²57Æ`¿upîáa°\VØwzú¡¥‹)NNb¥’ ŸÜØPmªÑv[Ûmñßus¦Qmº±¡ðÉJ%sr²ûLxíÊŠj+o6 ‚ªyžÂí †VËv³iÔ–/^(¼¾ù³ÇfÙ…ûûæã/‰bŒ¿¼4vÎB0jŒõºfÙ…ðaËõu£æª»»»ôÈý8ÏsUëõº›››~ùüY5ÕªÂÂ{k5Õðg­f¡Pp{{[ÕZ­f±X´Öñ«zrrâ‚óóóÎ>NŒ‘ÛÙÙ¡T*±··Ç½û÷ùëÍ›”r™8<ü$e`@ŠE"°úò%sss\]]°¶¶v äyÎÈÈ÷FG¹úùJ%HSSbLhµzÁý·¸ÁI’Ðh4˜šš¢ÑhpttÄß_¿òûÌ üøA¢IÊÅÅvw"Àðð0…B¡—,Ë2†††X^^fii‰ÅÅEfggy^©ðÇÓ§‘ÒË˽jª¹!x~~îõõuïÃûñéé©!CžšÍo}½WÍŽÎêõ޲»åÿ?‹1vD‚á?tv«b»mÂ~ÑööynWÜ-WVú:àN{óN§ÆÎ³;œ´ÿ™6a—§¸EÂIEND®B`‚routino-3.0/web/www/routino/icons/limit-3.9.png 644 233 144 1325 12573351603 14577 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ŠIDAT8Ë­”½J3A†ß]p k‘ A?A´ÒÊBÄBR()üÁÊN/@ðlMcå˜.•·lÔ")JD°PD Šfwgž¯ØÍj°u`˜™3ïœ9?ï9B’p]ÉE™Ì?¤§I.ù¼!—Çi"$÷Br“wB=E™Œƒä°±‘A:Â÷ßÙÝ…ZÍòð//ððŸwwÁ÷ߑ޼“¼—ð<—ÁAQ,N ݰ¶÷÷ˆ°ÖðsÄçˆû{ÃÚH7‹  ÏsE¡ Êe©Åþ>@°„!„!Xû={2°@—ý}Z”Ë>…Bâ¦Ta} Š0A@†Óo˜1&–‡!DQŒ__©Ò‹Ù4¾ÿÆõuìH úá™M×t$8Ëõ5øþÒ´NØÛˆlÐjµ¨T*\^^¦4 Ži·Û±Ò±·Ò‰®¨V1`Úí6ù|žÍÍMFGG©×ë4›M&''YXX`vv–çççž•†j¤+WÙ윖–$É•¤(Štxx¨­­- }~~J’ÎÏÏ522¢z½.Ïótvv&I2’«¥%)›såºÈóbM ©©)íììèôôT¯¯¯–$•J%}||¨T*©Ñhh``@éð<Éuqe­£ ‘$ÇQµZÕââ¢jµš†††tqq¡n·«N§£™™-//+—Ëi||\’äHRHÖ:iÌ,¬¥Óé°²²B6›e{{›ÛÛ[æçç¹»»cuu•±±1âTÇœKcÖ—Íä’0 yzz" C¬µi°¿¾¾x||L)’àû²Ùϳd5Æôñ,•[Û#í/žýª¢èû÷ÄM÷ æwüimþi×øÓ~ö‡ö?ÿˆP‚¬IEND®B`‚routino-3.0/web/www/routino/icons/limit-169.png 644 233 144 1402 12573351603 14601 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“·IDAT8Ë­”ÁK[Æ¿™’1 ƒ&AÈRìsÓbW‚/¥è"âF\˜µ+õÐÿ¢Ùˆ A ]=ìÂ](.Cµ‹B‹à€‚ªIfæüÞ"3­öm=pá~÷žóνß9B’p]ÉEÙì_H8ÎWr9(br9pœ¯HɽÜ$N(%Êf$‡j5‹ôßÿÉæ&|üh\_Ãp}=Ä››àû?‘Þ%þN/áy.##bbâ%R‹•¸ºŠ³˜Ç6ÄWW1++ µ˜˜xÉȈð/ÇqT©Tt~~®L&#IR&#¹.®Ì zl€ÌLA(mll¨X,ªÙljffF‹‹‹Êåršœœ”$9Q$™9®ºÝ/ª×%Éd&IÕÝÝÊ岦¦¦äû¾¦§§µ³³£ËËKíïïk}}]—Ë’d/>–ºÝ/O~3$···<<<E777DQ@¯×£Óé %3ôò›OtF”ê,ÕVª¹TwqÚ èì`S¢'8 I’þÑÏÚ›Ï:5žuž=ã¤ý\ÚeBô“µIEND®B`‚routino-3.0/web/www/routino/icons/marker-36-red.png 644 233 144 2077 12573351600 15433 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“ôIDATHÇ••ÏkSYÇ¿÷¾{“]¥Ê(y¥jgÓ–n»jh .üwÓ"ÎÂ]qcÄÂü ‚LéP”iý¥ƒ ‹­Á.ºkRµt1’"A[Ê»ï¾ï,î{1Ig=Î{‡{?9ç{ï9øf²§§G@:¾¨µ~ €¢Ø³ý]ký6N_€xŸL@"ö à'­õl†“$ÙÛÛ+ÆÆÆ µFERƒ••ìííQ!”RUcÌm·qZÿpÎó¼:ær9S©Tl³ÙdEl·(ŠØl6Y©Tl.—3ï;—Tœdì{ž· €ù|>¨Õj$Ik-1G~ÖZ’d­Vc>Ÿbð6ßa¥„Rê) … ‡‡Œ‚€ ÃŽLi-£ `pxØ‚ …•RO¥”@*•º€¾ïÛz½N’4ApÔòmr$ëêõ:}ß·˜J¥.A)µ€årÙ’¤1Æm^^&?&_½êom¹ø³gdºõ$Ëå²³]€(›ÍFFÃIÞ½Kä©SÎÏÌ8àÆyú4yâ„‹_»Æ$ïF£Ál6ÅW¶X,’$C’üòÅm¸wÏ­~ðÀ½“ä•+äÕ«îùÅ òìY²Vc¢z±X$«H­5€Q¤RÀÒ08èüâ"P,Í&°¾œ< d2@6 Ü¿œ?h˜#ÀŽŽŽòààÀ•Ÿœö»w¤R.Ëë×ɯ_ÉãÇÉ3gÈùy—u*E¾ÏXmæóy°RìssîD?}"—–ÈÏŸÝÊׯxqÑéY.»øÞ)Ã'OH’=N‘"€çy¿`_.gj»»äî.-@V*nóÚšƒ®¬Å"yù²‹?zÄ ××¹Orxp0Œ›à!2™ ´Ö`abÂdxë–yyìyó¦­®:  ½s‡$ùë6nÈ$mšÓZo`©T²$¼|IÎÍ‘oÞ¸ Ÿ\úÈùyšÕU’äÂÂB„C P€â‚”’Âê‚Ó79´®ŽJÚsçãGöõõ%½_jç€B@)uû|?¨mm9ο´l›œœ4ñl­ö÷÷Ãó¼Ö„rx¥äÐдÖÕx¸8}»JÒ–³³³6î´¦SÛØCWÀ×Z×;ô3KÊÞÜÜd&“±(¥ü¥»ìn;ªoµÚ‘áþþ>‡‡‡M<<~B€ÆÿX‡¾¾ïÉH$ÉR©””½ 3==ÝþYúoëÖw||ÜdµZ%+¥¤âBÛ÷í»¬¥¯Rª€SSSÑÈÈHRv).[}/°C_Bã — ”’? léûÏó(¥ÜðsW5Gì*¯¤a´ˆÑIEND®B`‚routino-3.0/web/www/routino/icons/limit-26.3.png 644 233 144 1512 12573351605 14656 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÿIDAT8Ë­”ÁK[Y‡yV_3˜!2ÔE B±*Ù ŠÅŠ» Úê®´ÛÝPýÒîE\˜N•.²7«N¡ XK¥ ±â"!J[Š:$ï½{¿.Œµ÷žsϹÜsøÎ’„ã8H’ˆDz– …>‹Aø>XûŸœÙÀuæçAúÄÄ„K"ÑHSzÆÔ<¿^ÇxÆ|ßǘ‹4ž‡_¯cÀcj ¤gg5Kãºßm©„K#Ѓµö\†öÂÞð³¶T×ýŽ”nù]úƒ‡ =x`¶·¶œ¿^¾T{{»’ɤvww•Ë嚺µVŽã¨X,êÏ/¾r%Ôuó¦¡\nmn¶(6Éçùçógó“ë2::JOO…B±±1ÆÇÇboo€âñ8ÓÓÓt%¼) ù<´é(½¥;wT.ßž<ÑÆÆ†’ɤ–––T©TÇ5<<¬ÎÎNI’1F š™™ÑÏɤ¼¯_ݾ-E£·ÄµkÆT«üýú5étš¹¹9r¹½½½¬®®ÒÝÝM¡PhÖòèèˆÉÉI~I¥x·½ ''˜Ž#Z¾}ãÝÇ´G",..°¾¾N&“ ¿¿Ÿ••ÖÖÖèëë 7fõùs¨Õð¯^µŽ9>ÞÒÛ·zóþ½ ö´e.Bzþg>wïžë€KíÍK—:Ï.qÒþ‡Iƒ)ìvñçIEND®B`‚routino-3.0/web/www/routino/icons/limit-15.1.png 644 233 144 1417 12573351604 14655 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÄIDAT8Ë­”±K\YÅ÷½ñÍø²$Nf@­Ä, „Á"`·……¥8(8±°¦ÐVðXØ2éíÍ`%®i,$˜" å3fœAï»÷¤x3šì.[yàß½÷¾{9çC€A (—û]°%c¾jdDzþÜidD2æ«`«Ž èó¡\ÎŒªÕœà⸫µ5éÓ'¯FCúþ]j4ÒzmMŠã®à]ÿ¾éóAQ(›E/çªT¤zÝIJä½ÓÏHëDõºS¥"Á¹&&^(›EQ ÑQ´° ¾isS’z’¼¬•¬•¼Xƒ=ÉKêisS‚oZXˆ5:Ú&¼×Ò’$Ý%½ž\Jµö~yï:L%ÖÊIwZZ’àýàÏ^*ŽÛ:?W"yßú?$I"Ÿ$i‡ggR·/Ã?á/Þ¾ýCoÞ¸‚¿ŽD>ŸgooƒƒNOO)•Jd³Y¼÷„aÈÑçϸ^ÏäK%§z}Øœœ„NT«I’Û©Õ”Éd´»»+k­ŠÅ¢µ²²¢f³yßÙÎÎŽ¢(RíÃIröãG N2<}úŠ™<& ) s||L§ÓAóóóŒáœÃƒ1†b±ˆ7 `fž={†"Šð@õõkÊå2WWW –——©T*lll°¿¿O†Xk©V«”Ëe®¯¯`h‚@Þîî@AÐh4˜œœduu•ññqšÍ&­V çÞ{R’µà½ h·¿pxà~{òILMM±½½M>Ÿgzzš¹¹9fggév»ÄqÌP&àÍá!´Û_li}]’9§V«¥››IÒíí­...䜓÷^———r. E«ÕÒM§“òÖ×%ØzðÙÙYê›Ô?òÞßu ö RÑ_|ö¯xkõ_‚ƒz€¾¹ÿ‘€GÍæ£NGg8iíMv訅IEND®B`‚routino-3.0/web/www/routino/icons/limit-171.png 644 233 144 1315 12573351603 14575 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“‚IDAT8Ë­”1KQ…Ï̲ãf¶ÐÍ"S ¦ZÐ"M AÜvQÔZˆ ?À?HizÑÊÆ  «)-DXpAKÛHÐuƒâ̼û¥˜YcÓyàoî¹÷ݹœs…$$áû>’$*•HÛx^‡±1xÿÞ16ž×AÚ.âBò‹<¡a¡JÅCòXY© m†?Y_‡ÃC£×ƒ? ×Ëïëë†?‘¶ ¾WäKÏȈ˜˜˜Dº¢Õ‚ëkd˜9^"¿g\_;Z-®˜˜˜ddD/¢H,,„H]67ž#M!MÁì÷~žØÜ©ËÂBH¿)}cy !ËÈžž03ÌŒ4MŸ™% .Irþò2H߆3k†}./lXèȲ,;—wxy aØGj”¾H_õùó'­®:ÒÔ÷ƒ@q«\.k0hooOÝnWªV«ª×ëŠãXªÕjõºó¾§³³’Îh·Îqpp@©TâèèˆN§ÃÌÌ sssHâää„ããcJ¥í<‡í6Hg¾FG?jvV’|yž§(Št¯ééižžjiiIkkkšŸŸ×`0PE23ð5;+Ž~µšãæ&%*Íf“z½SSSt»Ýç¹5›Mvww‡ÁÍ ÔjΗ™§$ÑK˜™œs’¤ýý}«Ñh()x/ºÊ‘$’™ç«ß?WK’© U«UA IŠãX‹‹‹’$à9^.—ŸßVKýþ¹¶ÙØÈ ArwwÇãã#···<<<°?ã¹<266@ÚþGgdÙ?ÚzUw9ï½ê{QðµB–eC[ýå€7õæ›n7Ýgo¸iM2n!$U’HIEND®B`‚routino-3.0/web/www/routino/icons/limit-78.png 644 233 144 1316 12573351602 14523 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ƒIDAT8Ë­”1K#Q…ÏLÖ˜ÂHM²•¥‚Ûø ÔB ,b¯þ€…-µ­‚Å`·½`J iDZX( ¢ˆ*dfÞû¶˜‰«®»•.¼ûÞ¹wæœwï’„ëºH.’Èå¾!mã8Çô÷C¡`èïÇ9FÚNï…ä¦qBÝD¹œƒä07—CZÇó©Tà×/K» wwÐn'~¥ž÷ˆ´žâ4^"›uéíÃÃe¤s¦¦àòÒ1Ö^¯Ä¹¼4LMtÎðp™Þ^‘ͺ¢X33R“ÕU€`‰"ˆ"°öuÏÀVWAj23ãQ,¦4¥ fgBâED¯ÌZ‹1†( 1Æ@'!³³ mt5Áó8;K¾˜€Þ±³Xkßø“àÏÎÀóF2?¤ŸZZú®ÅECºNO...šÍ¦NNNT(Ôjµ´»»«|>¯b±($9Æ80ººúªF##¤{{&ît8<fy¤íÿÖY·¶Œ1ï?¨³;€8~S¤ï“ÿ»>µ7?uj|ê<ûÄIûÌ–!Û=ÖËIEND®B`‚routino-3.0/web/www/routino/icons/marker-34-red.png 644 233 144 2064 12573351600 15425 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“éIDATHÇ•UAkI}U]5Iæ š +L‡ ÙSBþABâ ==(19ìI„ +¸xÓ›xÙ ä2!”Äxñ&HFˆ…=äæLʆB’±««Þª:™Lvq÷ƒæ£jú{õÞëú¾CvvvJèè踠µþ€\Èl]k­?vtt\€P'3 rÀøIk=›¦é ’ìééÃÃÃÐZÃ9)%Œ1X]]Åöö6…B)U1ÆÜðW ÎÁ g£(ª`¡P0årÙ6 :çØÎ96 –Ëe[( †º³™âŒqEÑŽŒŒ$Õj•$i­¥1æØc­%IV«UŽŒŒ$x@ìa¥„Rê9‹Å$KšMº$!Ó”íáœcÒl҆ߊÅb€J©çRJ —Ë`ǶV«‘$M’E ÌÚ×&€Öj5Æql0—ËC)µ€sss–$1¾he…œŸ'ß½ûç^¿&«Uš°=77gÛ5pÝÝÝnkkËK#É{÷H€<}Úçû÷}e¦`qÑï/-ù÷ãÖÖ»»»]¸r°$É”$wv|ÁãÇàÉ¿þöͯ?}:<ìÅ _×l’$'&&ÀJRk  s@.,/—/û\©—.'O;;ÀÕ«Àø8Ï{{h€#%W¯×±¿¿%%EÀµk€µÀô4°¶œ8á«nÝùyØÕå;HøÚÜÜ)eÀ>]Xð_ts“\^>”ûþ=)ùè‘—=4D^¼èåŸ;ÇôÕ+’äoÞ€B$Rñ€|øàAZûòʸë×½tOÃ?§NW®gÎß¿¹ R {~½sÇRʧÈçóÐZ/`qlÌdzû¶gEdWyófvë}Ó.-‘$™ž¶¡«þÏ<.h­7°T*Y’LÞ¾%È<˜sþJ¥)¹¿Oóìùõ+—^¾tpO1ª`öy)%¤•À ëZ{È2´1IÖëuöööf½_jÅ-„€Rê.öÆqRýüÙ´·,I˜ß˜œ4a¶VúúúEÑÁ„òðJÉh­+a¸xÛŠ1¾1gggm¬L§–±‡¶Xk];âo`›É^__g>Ÿ·(¥œl—ÝÇý­TŽ0ÜÝÝåàà  Ãã÷pñ5~Güã8ÉF"I–J¥Lö:€üÌÌLëßÒ¿G»¿£££†$+•ŠRRq>¼ý°Ý_¥T §¦¦ÜÐÐP&»d«ÿ xÄ_cBHÕþþ~(¥äÿ<ð7äߢ(¢”²àç65Çâoº[jبžµ0IEND®B`‚routino-3.0/web/www/routino/icons/limit-26.9.png 644 233 144 1537 12573351605 14673 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”ÏKÛI‡?ß±ILâR ¨ä$¨zØ¢õ"ñ`€Š`{˶ ¶·¥ø,ìIZž¼êIÖÒƒ,½éÍŲ(º XÒŠBÊ*=“%É73OFWï¼Ì¼3ï;Ì;<ŸWHBÆ$ƒ$êë;ñ¼O46B,filÏû„´X;’©å ]^T_ï!y<}Zô†H¤ÀÌ ¼ï8>†oßàøøÂŸ™H¤€ô¦ïÕò%‚AC($ÚÚÚ‘¾06¹œª8g¹>.ü*¹œel ¤/´µµ ‰`ЈÖV1>AÚgv  8||œûß.÷ÀefgAÚg|ŸW,S__Ÿb±˜$ikkKÍÍÍÚÜÜT0ÖŸ++F££rÑèCSà MŒŽjhhH‰DB===šœœ”1FýýýZ^^Ööö¶$i``@ÅbQÃÃÃúgoO@@ºsG2ã|ß3Á v÷÷•N§555¥ùùyE£QE£QMOO«¥¥EGGG*—Ë:??W"‘P*•RcS“ÚÛÛ¥bQxÆ »úøQíí¹j¥¢µµ5ݽ{W@@]]] …BêîîÖÈȈ’ɤT,µ°° _ž=Sï£GN>¨®PØÒ"¯^ñTÿÍçÉ׬T*a­åôôô “³³3J¥'''¸ «¼| Òâgd³d×8sÎ]Áz9ç¶Æ™Ç5În(ÀAÅù>îB27`½±®V/c*ÆïJÂð i7Ñ÷¼Død2¢P˜Dºem ,`pÎòuÅoÃÃem ¤[ …I2¾ëë!Ò5Õ*@pDD8÷¹{2p@‡j¤kÖ×CÆÆ’0¥å2@c°QDEXûÝ1km,"0&Ö/—Aªõr6M¾psE8ç¾DæÒ3½.6渹0|AšÒ>ÛÛÆu»4 jµ———©Gõz½½=îîîb£±¾a{¤}!]pxˆ Ðn·)‹”J%¸¿¿àêꊩ©)ŠÅ"³³³>–¤·´$ Íùò}ê-cLjèàà@ççç’¤••½¿¿«T*©^¯«¯¯/Å($ßÇ—sžº]y‰|ppPÚÚÚÒè訚ͦ:Ž^__533£ååeår9MLLHRŒëv%ç¼4g€MÊÍææ&ýýýT*Z­óóó4›MVWWggg'.u̹4gߪ™|bŒáéé k-ι4Ù´Z­OêÄúߪùgƤTèëñ,•;×#ížýèŒù/qÓ{¢ó³~µ7ujüê<ûÅIûKa„Æ-VIEND®B`‚routino-3.0/web/www/routino/icons/limit-189.png 644 233 144 1366 12573351603 14614 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“«IDAT8Ë­”±K#AÆ¿]ÉÁxJlñއˆba!b Óˆ…•þ‚ÿDl¬,µ¹€ÂU‚HQ4… ä 8ž˜ÍîÌïŠlÔܵ Ì÷fÞ÷xó¾÷„$$áº.’‹$’É/H;8N‰T >}2¤Rà8%¤ø^Hnì'Ô"J&$‡\.‰”Ç÷ÿ°¶?~Xîï¡Vƒûû&^[ßÿƒ”ß;±¿„ç¹tvŠ¡¡ÏH·,,ÀÝ"¬5¼_MqwgXXé–¡¡Ïtv ÏsÅÀ€X\ô‘®ÙØKB‚µo»e ll€tÍâ¢ÏÀ@œ¦´ÅÒ@ƒ(" ŒµcÃcÌ®×1FóýÒH[­?ûŠïÿææÀFA€‰¬µ¯çÑkÆQ„ËÍ øþo¤¯BÚa} ²Íh‹EÊå2äóyJ¥———looSþù“8߈õuv„tN¡`0†ýý}:::8<<äììŒÞÞ^–——Éd2ìíí166ÆÔÔãããüªTŒýþ¤sW==ß43#I®9Ž£þþ~I’µV]]]Êf³Êd2:>>V:Öéé©<ÏÓáÑ‘$¹fzZêéùæÊu‘ç½:çr9ŒŒèùùYµZMétZ»»»*—ËZYYÑÓÓ“²Ù¬®®®”H$$IJ$$×Å•µŽ ½_Æ%“IhrrR'''êîîV±XÔÄÄ„fgg•J¥4<<,Ir¢H²Öiû³°^`~~žB¡ÀÃ㣣ôõõ±ººJµZennŽÁÁA677_‹L¡Òy[5cAòøøÈËË AP­V ã»z½N¥RiJ¦ik«f›Îˆ¢6]ÙwâmíNøGgÿu€}GØoCâ ÿtÀ‡öæ‡Ng8iÿ}®ƒ;÷JòIEND®B`‚routino-3.0/web/www/routino/icons/limit-35.7.png 644 233 144 1505 12573351606 14665 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“úIDAT8Ë­”¿K›kÇ¿ïÛbbð7H ‘^"qèâ­*t3„6NYZD]Üü.×±]tÐÅéB„‚m† r§€ ˆà{q+&1Øj‘˜÷}žÏ’غtòÀÎóœó=Ïsø~„$\×Er‘D0øÒ2Žó‰Žèê2tt€ã|BZ®ß É­× 5€‚AÉab"ˆô†PèÓÓðþ½åôÊe8=­ÅÓÓ ý@zSÏwêõMM.€ˆF!}!‘€ãcøXkøÕj±Ïñ±!‘é Ñè#ÑÔäŠpX$“!¤}ææn‹ççµ?½q¸an¤}’Éápý›Ò[^¾Ä@Õ»¹ÁT«xžwëÖÚúã,^¥‚W­âAÕ¾xÒÛÆÌb„Bßíáa­£1·E¿µZžåðB¡ïH±Ió¼~ý§óê•9øüÙý'“Qss³"‘ˆÖÖÖ”Ëå”Ïç500 @  ££#e2íh/ŸwZ†‡Mçåe³ÝÙy #íòáÿ•˦«½‰‰ úúúÈf³ô÷÷“H$H§ÓœœœËåall GâßÃÇxÒîCµ¶ëéSùß¾¹ÏÏ«;Öùù¹677uuu%@ãããêíí•1F£££ÚÚÚÒÒÒ’ú¢Q=üص_¿êa[Û°èì4”J\]^’L&‰Çã,..2;;ËÊÊ ===lllÜŽ«X,ÇÙßÛ«¯P€ÎNãúÕª£–­®­iôÉe³Yµ¶¶j}}]ƒƒƒšœœT$ÑÙÙ™Êå²$)“ɨ»»[±ÁAI®ïKÖ:²Ò.ïÞq æù³g´µµ‘N§ÙÞÞ&‹ÑÞÞÎÔÔÅb‘¡¡!¬µ¤R)ðÁ°º Ò®–™™ð½J…B¡€W#&•zlŒÁZK©TÂZËÅÅ×××àû5¼™–ïðÌÔyf­Å÷ý[®5Àî(«t‡g?JT­ç5:b­½r«ßoȪJ*õ‹îU›÷º5îuŸÝã¦ýÆ¡9± )ÜIEND®B`‚routino-3.0/web/www/routino/icons/marker-35-grey.png 644 233 144 2730 12573351600 15622 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“IDATHÇu•_hSYÇ¿ç_îÍ-¨!þIb!£¤ ù[Æ)±XêT”eú 8և݇}Y—e^Jò"û²>¸Î›RÅNõA­J3i«ˆ°¶5Ñ€¢)t‰¦Úd£éöþ9çìƒÍÝê¸_¸pν—ïùý>çw~‡är9¬‰rΑËåT>ŸïÓZÿÍuÝ=¶mkÿ“6 ƒ!þIù!—ËMäóyêy( k¦Lk-µÖÛ„gÇùÎu] …H<¥ÔwTJaaaõz] !H q]÷O„ׄ@rTk-ìàœZ­ÖŽp8ì:tˆ¦Óib>•mÛ(‹ºP(È·oß~gYÖ×RÊCZë—„Êzzz4€NÎù]Çqv$ ÷äÉ“bç΄1­õ¯Î9b±I&“´V«¹oÞ¼ !~«”úIkýo600ÿXYYÉ& ÷Ô©SÂ4MH)AÈ””RÜ–”Á`{÷îe•JÅ}õêUØ4Í-Á`ð*uçÇq¾‡ÃjppP´¹qÎA)¥Zk!ÄÇ9÷ápX9Žó½ã8ß°ƒ^°m»óÈ‘#:‘H¥(¥xùò%^¼xÏó°qãFBÐl6Q.—±´´„ׯ_cyy›6mBGG8çºT*!D÷<ï«P(¤Óé4m§zçÎܽ{6l@£Ñ@oo/úûûQ*•0::ŠP(Û¶ qúôi!Édèää¤nµZ_qÛ¶u2™¤–eÇÁÄÄŽ;†žžÜ¿W¯^E?*• vïÞ¡¡!H)Ñ® ­5,ËB<'=RüCpÔÿÈÃÐжlÙ‚R©„b±ˆL&ãoN¹\Æ™3g`š&Ž=Šd2 )%cíz¦”1¦šÍ&\×õ7"•JA)…+W® \.ûI)ÑÝÝãÇ#âÂ… ¨×ë`ŒZ­(¥Šõõõ ×j5²yóf‹Å°²²‚gÏž!‹¡¯¯©T ×®]C,C6›E*•¶mÛ°k×.ÌÌÌ ‰ âùóç( Ú0 Iü•sN'&&¼wïÞAJ‰óçÏ£X,úH¤”8wîèGvâĉéÕÕÕ®f³ù›jµêíß¿ŸJ)qûömLOOcnn{öìA6›Åêê*nݺ…™™<}ú@ww7ÆÆÆT¹\f¦iλ®{œ Àv!Äôû÷ï¿èííU´R©`yy[·nÅöíÛýB¯V«¨V«ˆD"ˆÅb˜ŸŸ×/^$–eýG)õ¥Öú §”rÿRJýβ¬Ÿ§§§ugg'2™ âñ8!þ‰j§‰DüÃpóæM/BÈ0!ä Nx!d’Rzš®_¿îÖëuB ”ò£l/ ”Œ{õz]K©Têï(¯Ý(]BÝ·oßYÃ0.5 166æµÖ«]Ë÷îÝS>䋎ãüevvÖψe³ÙöÏdaaAK)˜¦ùmµZ K)UWW‘Rú…RŠ¥¥%\¾|Y !€ßBîB8 4ŸÏûMRÊ)¥‹J©S–eajjJ‹E0Æ| ®ëbddÄs‡2ÆÎB.k‘ÏçAÛƒ5}–o£Ñð¯”B¡ ¹aOlÛ>|ø0Öb ,>1þˆo½^£££<~üSSS°, J©?rÎWÆÇǽž;[?ù_Ã0¾­ÕjáF£¡çææd«ÕbBˆ?ÑZû×…·Àº+›ð´Ö)¥“¶mKÎ9ãœÒét_©T¢RJõ©áGéC›ï/ZëLÓdŒ±E)åfgg!¥ÄÿÓõÄ.]s:IEND®B`‚routino-3.0/web/www/routino/icons/marker-45-red.png 644 233 144 2123 12573351600 15423 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“IDATHÇ••OhWÆ÷ÎÜ—ðp^Ð"yA%-H¢ ¸M°Ñ€²v)¸(ú„‚«ÖËf‘Uü³0$¾… â¢*´»,• \„÷.ªñOŒÉ3óç~]ÌLL"­íárîÌýæ;ßœï |ÛÙÙi:::Ž9ç|¾jsîœ{ÜÑÑq ?g “¯ß8ç&’$—¤îîn388ˆsï=ÖZâ8fnnŽ7oÞÈcÂ0¬Çq|økÎÆöAÐÔÓÓOMM¥ËËËòÞksxïµ¼¼¬©©©´§§'”ŸÛWT\0®AðÐÐÐPÔh4$Iiš*Žã/®4M%IFCCCCQü¨f°Ö†á4 ááᨋ¢(c™$R"ï¥8–"Eí¶Ò$‘$ G€Â0œ¶ÖB©TT­VÓf³)IŠãX9Uý[Äùýf³©jµš*•J#1fÆ{_½r劎?n’$! Cð¬…À¨T Õ‚{÷àÙ3xò»¸H²w/Ý»vÑQ*é÷û÷1æ;_©TüÒÒÒÆ‡P^–ff$¦§³|r2Ë;;³µ«KþÝ;IÒÒëתT*>o9ÒÑÑQIR’$Ÿçç¥;·‚ŽŒHƒƒÒêªôöm¦qšfç$ŽŽ H-`sÈ{XY±1rÚí¼Y,ÌÍAWìßwîd{ÞãX øV«E»Ý& Cpö, ÀÕ«°¶;vd kkpò$ܾ ‡éSÐh`rR¯^½ðXk# ½qíZöEŸ>•œ“’NœÈÊïë“îÞ•––¤3)Þ¿—ŒQró¦$éχxcLd1¿ö×Ë—“æË—„ÝÝø±1ؽÖ×Á¹ìúð!c?9™±¾u Á¬??ŸÆZ{ƒr¹Œsn&oþX’’š++Ó™™,¿t)˃@¥/J’~}’ÚmivVZ\üÜñóóÒõëŠ=’$ÍÎÎúpÍÓ_†Æ˜£ÖZI½^ßê¬"rÞo½x¡ÞÞÞÂûµÍxÎC†õV«Q#·lº¾žõcI¢4Š$Iãããq>[ë{öì!‚ •Á‡¡íïïÇ9Wߢoa†Âï9û‰‰‰4lmL§McmUç\s‹¾9³¢ì……•Ëåµö‡íeo¯ê»ººª8u¿c_‰-úV«Õ¨‰’T«Õв€ò¹sç6ÿ–þ9¶ë{äÈ‘X’êõz60¬•1æhþxðUÀíú†aØtúôiðàÁ¢ìZ^vø_·è |oŒä ÿèëë# Cû7ôÍןƒ µ¶|»­š/âoI4ŒîÔIEND®B`‚routino-3.0/web/www/routino/icons/limit-27.9.png 644 233 144 1505 12573351605 14667 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“úIDAT8Ë­”OH\WÅÏ{’Ѿ(8Џ+u”n ˆE7þ“•Ä&&{—é¢Ðe²pܸŠÐ ؤA®%-„‚LŒ82Én”•€âŒ¼yïÝûëÂqªm–^8‹ï~¸çrÎ'$! ×u‘\$QSó=ÒŽó‰úzhh0Ô׃ã|BZ*ç…ä–û„.ÕÔ8H÷ï× =Ãó ÌÍÁë×–|¾~…|þ"ž›Ï+ =+×;å~‰XÌ¥ºZ´¶¶!}f|r9DXk¸z.âˆ\Î0>ÒgZ[Û¨®±˜+š›Å䤇”a~ X¬ý—w`óó e˜œôhn.Ó”ž35… ,•0A€µ–0 +°ÖVh‚€°TÂ@ÀÔHÏ/ÿ¬Ï;µÙ,,Æ`­½Ö|i9g ¬ÍfÁóN‘:ª~–~áÑ£~çáC³N»+««jll”ïûZ^^Öîî®vvvT[[«x<.Çq´½½­ß_¾TS<î4ܹcÈå¾s67«I›¼yÃß_¾˜:ÏcppD"ÁÂÂÃÃà à8ëëëlmmÑÞÞN??$E‘áÕ+Œ´©¨¶ÖR,òÇÛ·üôô)]]]¤R)™­ÐL¥Rôõõp··—__¼ß'¼}ÛŠxܘÃCþ|ÿžîînfff8::"‘HÉd*Ãöööèééatt”ê[·ømu¢ˆ°®Î¸6 7S:“ÑÈȈ¦§§•L&%I+++jjjRGG‡J¥’òù¼ÎÎÎÔÙÙ©¡¡!ÕÇãjkk“ŠE9ฦPHëÃýõñ£‚@kkkjiiÑÆÆ†Òé´ÆÆÆ$I'''š˜˜çy*‹J&“úñÁõ÷öZ½{§ªB!-¤%ž<á¢Ãý}öËð}ŸÓÓSÎÏÏ/´e ÇÇÇø¾ÏÁÁ6"?i©¢3²Ù eó?]ý76e°\ÑÙ5Xlb/,óÍADÑeMÀ½{Wp£Þ¼Ñ­q£ûì7í?¨+–O@R¨uIEND®B`‚routino-3.0/web/www/routino/icons/limit-0.2.png 644 233 144 1332 12573351603 14563 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”=KìP†ßä^v—¨ØXXö6Úøb+ˆX.j#h§¥…•­­‚Åþ;-+‚¬n!¬ß¢Ën!,Ê&9ç¹E6~\oé@ '™yÏœ9ÏŒ„$\×Er‘D¡ðiÇ©ÒÓ½½†žpœ*ÒNç¿ÜNœP&T(8Hss¤M<¯Åò2ìíY¡Ù„ÇÇt½¼ ž×BÚìø;x‰\Î%ŸaXDº¤T‚Û[$Xkølé:áöÖP*tIÉçE.犾>13ã!]°¶Ð,q q Ö~<Ù7°@›µ5.˜™ñèëëSÚbv "I0QDÇXk¿$fŒ!ŽcLA’¤þ³³ me5Äó^¨ÕÒƒ$É»ˆµöÿï€Í2¬ÕÀó^…´ÃÊ @b£€Z­F¹\æêêê=#€óós¶··©V«©h꟰²ÒŽNÙÝÅ‚¨×댌Œ0<<ÌÀÀF€ããc‚ `jjŠ0 ©T*éF`ØÝéÔUw÷¨&&d$W’•Ïçuvv¦ tpp Iº¾¾ÖêêªŽŽŽäû¾*•Š$ÉJ®&&¤îîÑßr]”Ë9êXÇò}_’Úí¶$i~~^ýýýÒØØ˜–––$I¿$)—“\WÖ:Š"ejaêééIwwwº¹¹Q±XÔëë«NNN4==­……•ËeYk%Hã¢H²Öy¯`: ±¸¸ˆïû¬¯¯S¯×™œœdccÏó§««‹ýý}ÒêÔìËmfbÆÆŒ14›MZ­ÏÏÏÜßßóððÀÛÛ[ÆÚ—ÛüÆY†‚1æ¸ï– }ãì[ð Ü ØÏàÚ¶ú§~´7tjüè<ûÁIû6–†§§ôç IEND®B`‚routino-3.0/web/www/routino/icons/marker-24-red.png 644 233 144 2107 12573351600 15422 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“üIDATHÇ•UÏkSY=÷¾{“\¥È,’رM[ .Ý4´ Å‘‚ ±?”YŠÝ™ÅÀüÎtŠv#µAQ™Ùe!ˆ‹Û…!qÑÕhº(Ò6}÷Ý{fñîK“È0ÎðåÝ÷îyç;÷û¾œB IH§ÓóZëwÀùÈÞk­õ»t:=~ŸLˆ„ à;­õzEË$9<<,¦§§¡µ†sRJcP¯×±¿¿O!„PJÕŒ1÷üÝÃÓ}Ã… Z˜ËåÌÆÆ†=88 s޽pÎñàà€6—Ëôû.$'ŠóA|Àb±6›M’¤µ–Ƙ¯~ÖZ’d³Ùd±X =ñGù˜VJ(¥`©T ²°Ó¡ C2Š8çÃN‡Öß+•J!*¥I)T*UÀ|>o[­IÒœœô³XKöÚà•OÚjµ˜Ïç-¦R©2”Ro°Z­Z’4ao|ÿž|ð€|ù’ì}‰'ä«Wd³Iã—«Õªõj߀Ëf³®ÝnÇ©‘äÖ Ùl¯]‹•&V$÷?ŽŸwŽív›ÙlÖù’ƒ]\\$IF‰Š±1òÖ­øÿÛ·1ÁÓ§§×çÎÅkÛÛñ¾N‡$¹¸¸HVZk…˜Ÿî܉ëbh(ŽgÎÄñúu \2àè½ð<ì¥K—xttÔ=Y’±÷ï“©yûv¼¶¼L^½JwÓ'Ië=/‹`!¥ ØÍÍÍøDI²Ñ ÇÇÉóçɇcÂÝ]R)òâEra!&eôìIòÏׯ À !BAð  Ó-ú˗ɉ òÓ§SÕ¹´D–Ëäì,™JÑŽ’/^ðääøxä›àwd2h­·°´°`øù3£³gÉ Óé8ö¤J’üò…hýÚO««Öþ “ ”œÖºnŒù¾r÷®ûõæMi>|ˆàä(•€ÑQ Š€(Bôä Ô•+Ø®×¹zㆂàØ9÷#É]P ¤œ“BRFµçÏû:fIïïíí±P($½_ñU·„PJÝÀB.6Ó“5¦¯M­s¤s\^Z2~¶ÖFFFì«1¥”œ˜˜€Öºæ‡‹!Éh@­1qc®¯¯[O¸×N=c y­u +•Š%ÉÐσ$íf2 €RÊ¥Á´û+Äœ”’¢Z­Ö§ððð“““Æß„ ñèó7ŸÏ‡ÉH$ÉJ¥’¤½ ³¶¶ÖûYúw ú;33cH²V«ÅCJ !æz¾oß„®¿J©®¬¬¸©©©$íŠO[}+aŸ¿f…y…ŒA)%ÿ/a×_‚€RÊ=? dóþu¥œÅþCÿIEND®B`‚routino-3.0/web/www/routino/icons/marker-67-grey.png 644 233 144 2653 12573351601 15634 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“`IDATHÇu•ÍkTYÆŸ÷|Ô­Po.ø Ò1‹X‰±…Î,”°1 .†.Wöf"v/z3Ó í¢©i éf6ã_0 C3A(“Z85™!"4Â$Æ2b%âÄ®˜ªXXÑ{Ï=çÌ"©;iíyàÂ=wñÜ÷ý=缇 …vÅ„( ¦X,~l­ý“RêCß÷-ÂÿdÇ!)忉è›B¡ð÷b±ÈÂ0´kÊ­µÚZ{HJy#‚Ï”RÖu]êééc,r4Æ`uuÍfÓJ))‹)¥~GD? f­ÕŽ !*ívû˜çyá¹sçX6›%Çqð®|ßGµZµ•JEonn~–L&¥µ>g­]!"ÆÏž=k¤…ÿ ‚àXoo¯º|ù²Ìd2Ä9‡µö½Gîînêïïgõz]½|ùÒ“RþÆó7kí+–J¥ ¥ü~{{ûƒL&£FGGå µ†µv6c?C`­E†Ø¿?FGGe&“QÛÛÛH)¿O¥R`A|Áçžç™|>/;Ü8ç‘Ù»æŒ1!@´“_>Ÿ—žç™ >‚àa­ýN)…\.×u¡µçF+++Ø·oz{{aŒÁââ"Â0ŒÌ¬µ8zô(<ÏC.—ÃÄĤ”߉0 ?r]×2àœ£^¯ãæÍ›‚ív'OžD>ŸÇÝ»wñæÍpÎFW¯^…çyÈf³lzzÚ¶Ûí„ïû¶¿¿Ÿ%‰¨Ê©©)twwãÒ¥K¨Õj(•Jxýú5®]»ß÷‘H$0>>ŽV«…l6 c R©zzzhvvÖˆT;!pÎñöí[¼xñ©T ׯ_G"‘Àùóçáº.Œ1H$XZZÂòò2®\¹aè0ÀçÜ´Z-(¥¢t•Rð}.\À¡C‡pçμzõ*Ú÷ïßÇàà ººº`Œ‰¾·Ûm0Æ ‹ÇãºV«™ùùyÁZ‹\.‡S§NáâÅ‹°Ö¢V«°±±ááá¨J"Âòò2ž={fãñ¸fþ(„`•J%l4pÝÝÝX\\T«UÀÁƒ³³³H§Óp]ÖZpΡ”Âä䤦ý…>|ø‡X,ö×ÍÍM111ÀÈÈVVVP(P*•pæÌ¤Ói(¥°´´„¾¾¾h@©T2ÏŸ?ç±Xl^)õ5‚1æÇx<ž___ï ÃМ>}špäÈ‘C§Õ®®.ôõõ!‘H€1†ùùy[.—Y2™|cŒ!¢ÿƘðÜóÛd2ùØt:¸®1&"!044¥Ýjµ055Æb1IDßÑÁ„$M3Æ~OD|rrR5›MŒ1Ñ ê´Ü1-—Ëa³Ù”±XìÖ‰'þ €;SB¾á8έf³);|÷FÓœ1<|øÐeZkó®áÏÚÿ ¾ÿ´Ö~Ç9ç|MkýåÜÜ´Öøú/M…¹KÞöZ IEND®B`‚routino-3.0/web/www/routino/icons/marker-5-grey.png 644 233 144 2520 12573351600 15534 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“IDATHÇ…UMhTWþÎý™÷f\è8–B jü‰™H »c"DQ, X B³hÝ´¥¸‘©Ì®›ºéÒ®£`(‚:›¾Ø0% B‰I86ÉLd’À›äýÜ{»0B?8¼÷x÷~ïœï|ç]ÊçóØB ŸÏëB¡pÚósÝžç„÷0–e‘”òo"º–Ïçÿ( , CÐ@¤Ü£Œ1ŸJ)oú¾9“N§)›Í‚13j­Q©TP¯×”’‰ÄHßÑ"qJ`Æ`Âq]wO&“ ûûûY.—#˲°žçaffÆ8Ž£Þ¾}{9•J}¦”ê7ÆÌã'Nœ0Z…ã¾ïïikk ®\¹"÷îÝKœsc>!ZZZèðáìZ­KKK)åçZëQcÌ ?{ö,üÚh4N¶µµÃÃÃÒ¶mc@D`ŒˆšŒ1H&“èîîæoÞ¼ 2¶m’L&g¾ïŸñ}(“ÉèÁÁAmˆÈ”RX__‡ïûqDï1€ÁÁA™Éd´ïûC¾ïŸƘA ··étZk0Æâk©T‚ã8q–kkk¸zõ*:::âÆ¥ÓiôööbttRÊ" Þt:m:;;€¦N@¥RÁÎ;qáÂ4 ¬­­¡¥¥šäèììdcccÆuÝæyžÉf³”L&¡µŽÉ"r×u±{÷nX–…]»v¡§§;vìˆI£l“É$²Ù,yžgÄ»ýÍÙEMj4X\\ÄÒÒ¦§§Ñh4ÐÞÞŽ¡¡!X–¯Û’œs½ººÊ‚ €”²)Î9ÚÛÛ±oß>=zår·nÝÂÄÄN:“Fë]×cL3Û¶ÕëׯõÔÔT\J!.^¼ˆcÇŽsŽàСC(—ËMFD(—Ëxõꕱm[1? !˜ã8a½^c J)Àìì,òùU®ër)åFŒ1±Ž›’j:z›Žl 4Æô2Æyž§„\áär¹ÓÏž=cJ)½•°©üÈéû§1æšmÛœs>§”úfrr2þ?| ÿެŒ#V2¿IEND®B`‚routino-3.0/web/www/routino/icons/marker-75-grey.png 644 233 144 2661 12573351601 15632 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“fIDATHÇu•_hTéÆŸ÷û3sr Ó¹¨3³3"ÉDÅMAd*.¸BÝ\D\/:íEo){³L—¹XéM½ò²‚…4*G°Ó´¦Š‹ qŒëÀD%6t$2SÏŸï{{±™iüÓ>8žóœßyÎ÷R±XÄ–„R ÅbÑ–J¥Ï˜ùAìó<þ'ŽF£¤µ~HD_‹Å¿”J%†!X -SÉ̆™ªµ>çûþ—Ap<§t: !D×ÑZ‹¥¥%4›MÖZS$™ ‚à·Dôo"’Œ ˜ÙÈ(¥*­V+“H$Â#GŽˆ\.GÑhïËó<,,,p¥R1¯^½úÒuÝŸcŽ0óK"òСC `—Rêï¾ïgvïÞœ:uJg³Y’R‚™?XJ)¤R)F#X[[Kh­a­ý33oˆX,­õwívû“l6 ÝÛÛ‹0 ÁÌÝtD¢Ñ23Â0Doo/ …‚Îf³A»ÝþDký],ƒð}ÿsß÷¿J$vllLw ”RBtWÇ´³WJu266¦‰„õ}ÿ+ß÷?WÌümÈçóˆÇã‚õza¾“,“É@z½Ž¥úúúÇ‘Ïç1== ­õ·* ÃOãñ8 0Æàúõëh·ÛRÖÖÖ0117oÞàÂ… H$ð<===˜˜˜€ÖCCCbvv–[­Ö§Êó<®ë‚™á8Μ9k-ÇÁÔÔ666ÍfqéÒ%är9œ>}ÆtšÁÌp]étš=zdÑé!3ƒˆ µ¡^¯ãÅ‹( ÝŽÖj5œ={ŽãàØ±c€1RÊNŸ…RÚÍÍMA!Ä;_üöíÛØ»w/‰˜ÖZ c||Éd/^D³ÙìbjµZBXá8Žyþü¹­V«è0%"Ôj5¬®®btt´›òøñã8qâöìÙƒññq(¥ðòåKÀââ"Ùq#ü^)%*•JØl6¡”<|ø»víB<ø¾óçÏãþýû€jµ fF2™ÌÌÌúQ’'OžüÇÛ·oû666†F¸oß>áû>®]»† NÃH$‚ pëÖ-ܽ{Ïž=ÃÁƒ122‚ééi[«Õ¤ã8Õ Æåðð0¬µß;Ž3¶²²òk­íïï§;v ¿¿===Ýâg2 "•JáðáÃAµZår¹,\×ýµö(ýK !€Zkéºî_ïܹéT û÷¶û‹vÚ‘L&±sçN677qóæÍ0‰h"ú†ˆ~ €€&¢Y!ÄÉ™™™àõë×´ˆº-€r¹6›M‰D.þ€vÊ€ˆÄèèè¹h4z¹Ùlê«W¯†øˆ˜RJÜ»wÏ>xð@Åb±eß÷7??ß óù|çfZZZbcÌ÷Žã|±²²’0ÆØ¾¾>2ÆtS !°ººŠ+W®°ÖšüŠˆî‘`@”J¥î¡.„PBˆekmÁu]ÌÍÍñ¤”°Ö‚ˆ&''Cß÷…”ò] ·0¢T*At.¶ôß7nëëëÝ‘R©Tìòò²ŠF£?xž÷ÍÑ£G±Ý[`ñžñ|§¦¦Bxòä æææàº.¬µ¿QJµËå²ÀÛ¹Ëí›ñF£_4Äúú:?~üØ´Z-©µ>`’™»·…zgô¶l dæŸ !f=Ï3J)©”ªär¹Ïž>}*Œ1ö}Ãw^ÿ#:|ÿÆÌ_;Ž#¥”ËÆ˜_ÏÏÏÃÿ§ÿø ´@Ã] ”IEND®B`‚routino-3.0/web/www/routino/icons/limit-23.0.png 644 233 144 1532 12573351605 14652 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”ÁK[Y‡ï9ÍË<“ªé"¡SѺˆVf3RÁMCÜíÆv7ÿÙvïVP¨(dܺs ŒŠÒAKê¦E X¡4&ïÝûÍÂhk×^¸Üsî=çpïåû! I¸®‹ä"‰hô¤YçHÁqÞ!ÍÖÎ…äÖò„® E£’ÃØXiß/19 oÞXŽáÓ'8>¾ô''Á÷KH3µx§–/‰¸xžhk»ôl „Xkø~\ú!…‚!›émm÷ñ<‰¸"™¹œ´ÏÔ@°Xûm^í*LM´O.ç“LÖž)½bdÕ RÁT«c‚cn^ÐT«• ªŒŒ€ôêêÏâûŸm>K-ñÇÖÚëÕZ Æ`ÁÚ||ÿ3Òú?¤?yölÀyúÔü»³ã¾^Z’ïûjnnÖÞÞžæççåyžR©”¬µr]Wz½¸¨ä½{NS{»¡PøÙÙÞ®S(m³ºÊ?&îû ÒÑÑÁòò2­­­ŒŽŽÒÒÒÂÆÆ'''ôôôÐÝÝM烜ai #m»ŠÅéñcÞ¿wùRëëëŠÅbÚÜÜÔÌÌŒÆÆÆ”L&u~~.IZ[[“çyÚÝÝU¼¡A-.ºÊfeëëýTwç¶TrFžoH&AúHOÏ-‚A¸¢»[LO{H‡¬¬T‹ïƒïƒµÿÙùX ÊÊ H‡LO{tw7Û”ž3;‹š_­bj5Œ1ø¾1WèW«øµ>Ô˜éùùŸÝÆó¾Øl –f¢1kí¥í•‚Í8K6 ž÷évË/Ò¯,,üè<~lþÉdÜß^¼P{{»b±˜ŽŽŽ´±±qáK’ïûJ§ÓúãÍý}pà|?1a‚Åb;ûû-ªKloó×§Oæ;ÏcllŒÞÞ^vwwI$Œ3<¸?-/kggG±XL«««* êììÔÈȈ:::$I{{{:;; ©dRÑ`ÐåÞ=¹áð]·¥µ[.kvjJêëëÓàà æææäº®FGGµ¹¹©ýý}IR$Q*•R2™ÔÏËËúýõk97oÊ®õ}Ç ”9’É$iJe €Ö⢈(Špn80ç¶ÛkcÿB¤r¿fË„á;q"Q„÷þKfÃ÷ƒy ß‘–…T¡T°¾× ^¯S.—¹¾¾€ô£¬ÕjœŸŸÇöØßR*TÒ''xpív›ÕÕU¶··Y[[£Ñh Òsα´´ÄÖÖV\· à89éÊhzzEr’‘¤³³3ÕëuÍÍÍi}}]³³³’$cŒÔét6‚@’Œ66¤éé#cP*¥¾Xk@GGGº¸¸$U«UkssS———z||Ô¯±±˜¬©”d FÞêõ$`SSSšœœÔÞÞžæççÕh4䜓÷^ÙlV777j6›º»»“$yIêõ$ïƒAÍ—tˆÝÝ]&&&(‹<==‘Ífy~~ Z­’Ëåˆ:¡š u3!$ÖZ^^^pÎá½çõõ•(¡Ìçç'ooo1=bÿ¡nóÌÚ ú`ÿ•xöm°öGâøÄçûŒt6Gº5FºÏF¸iÿ:”-"ʪIEND®B`‚routino-3.0/web/www/routino/icons/limit-34.4.png 644 233 144 1401 12573351606 14654 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“¶IDAT8Ë­”=H[QÇÿïQ48NO¡Ý†ÓÓä]*Aü@zÕÿïõí%††|†‡ÅÄDˆT'Ÿ‡fÓç,¿Sò64›–|¤:!ÃÃbhÈccba!@:bm àpÄ1Ä18÷‹¯dà€KÖÖ@:ba!`l¬_¦T¦PÀB/¾¼Äözƒd¬µcþHc°qŒÅ"H嫞Ý%¾¹ãã$¢µýŠÜ€ÿ&ç. à8>† ø†tWHW*˜£Zr¹LµZÖëuvvvNl?X½^gçÓ'ãJ%*²R•i´Ûv$fqq‘l6Ëîî.a277@œô k-“““Ì=~ `Í›7 UoèÖ­{zôH¦Óñ_¼|©ñlVFCÆmll¨ÛíjttT’䜓$­¯¯'ò;w$ÉçáC)¾'nß¶|ý À÷‹ æç癞žfuu•0 YZZ"—ËÑh4ØÚÚb||œååeraÈç/_àü›N[ßôzžnÞÔÛ÷ïõàþ}moo+•Jéàà@³³³ÚÛÛÓÉɉjµš¢(’sN333ÚßßW³ÙÔáá¡äyÂZONªòî`Ÿ>yB&“¡X,Òn·ØÜܤP(055E«Õd˜ö,éÙë× U…TaeÀÄÝ.­V‹8Ž“‹¢ˆN§ƒµ–³³³.Š"ΓöVV’iþŽ3ÛÇ™µö¿øúƒˆüƒ³dŠE€ž‹cø ñWŽŒcpÿlÀµîæµ^k½g×xib¸qyB4ÅIEND®B`‚routino-3.0/web/www/routino/icons/marker-57-grey.png 644 233 144 2657 12573351600 15636 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“dIDATHÇu•OhTYÆ¿sÿ¤^ª¡R 1 T[þAËŠ”&½P"¤Ñ^C²ˆ6Ø.&b»˜Í8 ½ijšZ´Ìf\¸î•LP1– ™Ìa˘L¢LÇI4•)­ŒïÝwï™…©7Q{>8ðîã½ïó;÷žG…BJ) W,¿`æ?c~åû> üO‹ÅHký"ú¶P(Ü-‹" Cp@¦’™-3oÑZ_‚à+c '“IJ§ÓBDŽÎ9,,, R©°ÖšŒ1¿#¢‘`ÁÌÀ6¥ÔH­VÛ–J¥Âîîn‘Ëå(‹ácù¾ÉÉI±¯_¿þ*n­ífæçD$ä¡C‡@›RêïAlÛ±c‡9yò¤Îd2$¥3J)´´´P6›ËËËæÕ«W)­õ¯saæ‹D"­õëëëŸe2Óß߯›šš†!˜9Ên3fF†hjjB¿Îd2f}}ý3­õ‰D"‚/ƒ ø:•J¹ÞÞ^]Q)!Duãz(¥@ô¾½½½:•J¹ ¾‚àKÅÌßcpøða$“IÀÛ·oñüùs!ÀÌÐZcûö혛›ƒ1&2cf´¶¶"•J¡«« CCCÐZ¯Â0ìH&“ÜÞÞ.˜D„ééi\½zÉd¾ï#‘HàìÙ³¸qãÞ¼y¥`uugΜA*•B.—£££\«Õ:”ïûœÍfEcc#¬µRbvvÙl§N‚µžç™qîܹh=88ˆjµŠ\.ç‰Òé4;õ•ø`Ë03fffpþüyxž‡cÇŽ!›ÍBJ ­5ž={†ùùyœ>}:z~S3…Rºjµ c ¤”k-òù<úúú°uëV\ºt «««QÃîܹƒ}ûö¡¹¹ιè~­Vƒ ÏóìÜÜœ+—Ë€0 ÑÓÓƒãÇc÷îÝèëëƒR /^¼LMMaeeQ–D„ùùyÌÎβçyVø£RJܽ{7¬V«°ÖââÅ‹xøð! \.ƒ™±eËÀøø8ÚÚÚL&ÁÌRƒááaKïõ£çÜOžçõ.--5‡aèŽ9B{öìAkk+º»»‘Ïç£R›››±k×.466Br¹Ì¥RIÄãñÿ8çŽÑÏJ¡üÓ9÷›x<þ×{÷îq[[ÚÛÛÑÒÒ"Џ)¥Ïç£nW«Uܺu+lhhÐDôMP@@ѨâÉááaS©T@DpÎE'¨>úꦥR)¬T*º¡¡áòÞ½{ÿ @ëÔ‘èì켋Å.W*=44øÀpópyðà{ôè‘J$‹Aüabb"ú˜ìêêªó¢……¶Öþäy^ÏÒÒRÊZëvîÜIÖÚh!°²²‚+W®°Öš|CDˆH° ŠÅbT™B !sýñxccc<99 )e„Áƒ0!¥¼@D—è Œ(‹õ‹ }Â÷æÍ›fmm-:5###nqqQÅb±)ß÷¿;zô(6b,>2þ„ïàà`Ož<ÁØØâñ8œs¿UJ­—J% €73—›¿Ä7‹õ,//§ÖÖÖøñãǶV«I­õï 0sÄqSRø¤µ›~Ù @È̇…£¾ï[¥”TJär¹/ž>}*¬µîcÃÊÿ u¾cæo=Ï“RÊEkíÙ‰‰ Xkñÿô_uÌ·Öœ7'IEND®B`‚routino-3.0/web/www/routino/icons/limit-6.8.png 644 233 144 1305 12573351603 14577 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“zIDAT8Ë­”1K+A…Ïn‘ÄUˆèAÁWYZh¡¨­6ÁBÑNâÈÏHz;Á&½–6 ZXYI!¨Ý™ù^±›<ó´t`Ø™»gîÌ=÷Ü+$! ß÷‘|$Q(üA:Àón…±1Ëè(xÞ ÒAö_H~vN¨ç¨Pð<¶¶ H5‚àJŽí6t:Ðn§ûJ‚à©–á½ì¼D.ç“Ï‹éé¤Êex~¶€Á9Ëבî ÏÏ–r¤¦§gÈçE.狉 ±± ÝQ­tG’@’€sÿfÏèR­‚tÇÆFÀÄD¦Tgs Æl’$ Ö>ÌZ›ÚãŒIñ›› Õ{œÍoÜß§$ ι/‘¹þwÀž:sÜßC¼!Í é€ý}ãâ€V«E½^çêêªÿ"€ëëkjµ···©ÃoØßé@H—48°N‡¥¥%Ö××Y^^æññ€““Â0dgg‡©©)šÍfzX .}‹sZ]••|I:==U«ÕR†ZYYQ†’$k­‚ ÐÚÚš&''õùù©Œ&_««R±8çË÷Q.§Þ0ÆôéââB’E‘J¥’EQÿO’r9É÷ñ圧8N’FFF4<<¬½½=•J%===I’†tvv¦ Ôl6%IN’âXrÎësØ,Ýloo344D¥R¡Ýn³¸¸Èùù9óó󌳻»ËÇÇ8—rq6ÍLcˆ¢k-Î9^__èv»¼¼¼d¸ ?ÍAÓ—BÏÙë^%ü§³o€1? ·¿Î0ß+àWkóW»Æ¯ö³_ì´p­ƒ}“ŠIEND®B`‚routino-3.0/web/www/routino/icons/limit-124.png 644 233 144 1365 12573351602 14577 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ªIDAT8Ë­”1KQÇÿ»—œçzà˃K!~QˆbáuÖZ^ᇰH@±ñ)®°²#Ø£‡<ç*6Arx{ûöýRÜšhlR8ðàͼ™?3óþ3B’p]ÉE¹Ü[¤-§†ïÛ7 ¾ŽSCÚJß…ä¦qB@¹œƒäP*å>ây¿X^†ÏŸ-××ðó'\_÷ôåeð¼_HS'—Èf]úúD¡PDª3?Íf¬Mx,=ÝÐl&ÌσT§P(Ò×'²YWŒŒˆ…é;««`‰cˆc°öïy°"VWAú΂ÇÈHZ¦ô‰ÅE€.Æ`¢ˆÄZ’$!Žc’äo’Ic¢¨ç¿¸Ò§‡ž½ÃóZœŸXEØÈZûìþÇÖ·œŸƒçµÞ i‹•c»]ªÕ*F€ããcÖ×שÕj2«×ëìïï“ÖkXYiKH_ÙÞHHvvvÈd2T*ýýýA@¡Pàèè€b±HHØÞé««ÁÁ÷š˜$ׂÇÑðð°2™Œ.//U.—µ··§žžjmmM÷÷÷RÚ&WÒàà{W®‹²YI’µV¥RIccc ÃP“““š™™Ñè訂 1F›››šššÒáá¡~\\è•$^¿–\WÖ:êvõXŒ1Êçó ÃPÓÓÓZZZ񮮠$i||\'''j6›:;;ë%E’µŽ«V뛪UI²²V’äyžòù¼dŒQ¥R‘ïûò}_»»»*—ËšÕ‡¹9Éf¾|‘Z­oO~3%$wwwt::777„aÈÕÕív€v»ÍíííŸüæža ÿ%=¿g<{6öà¢>²½¬þ™€ÍÝ/ºÏ^pÓþ&t…ÐziÍIEND®B`‚routino-3.0/web/www/routino/icons/limit-117.png 644 233 144 1333 12573351602 14574 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”±KQÆ¿·—]/{½Àq¥’@à@‹46)‘ ¤SRèà?H™ÔŠVB¸‹4”‹•…²`Ê+®‘ §A¹Ý}óK±§‘H㯘7ó¾73|3B’‚)@Õêc¤Mœë15z¦¦À¹ÒæØ/¤`üN芨ZuHŽ×¯«Hˆã_¬®ÂçÏÆ`?Â`PÚ««Ç¿>ŒãÝø½DLLˆééGH?X\„~ßfž›(í‚~ß³¸Ò¦§11!¢(ͦXZŠ‘RÖ×F€‘çç`öç\Ý#Ö×AJYZŠi6ÇeJYYÈ( ŠÑovPQ˜fFžçä£y–a±²ÒÇ«žµˆã!GGVŒFØ?ˆnÁû2ã#ˆã!R«òNz¯·oŸéÍOžAi_Þ{ÕëuA $I†¡ÎÏϵ³³£4Mõ=Mõ Zuõ'O<ýþ}wxXÒ!Ý.€Ç{vww ÃN§@·Û¥R©°··G¯×c~~ž……œÄ×/_|ñéH‡÷49ùTÏŸKR` 眆I’sNÍfSgggš››ÓÁÁ666433£—¯^ɤ òâ…49ùTÔëžãcò, Ýn³½½}Ýžv»ÍÖÖƒÁ€ÙÙYÒ4-[p| õºdæ”eº 3»e{ï%INGFC­VK¾(HR–If.ÐpøMI"I¦1I­VS†×dµZMQI’’$Ñòòré(?0%‰4~Ò&kkÅXœžžryyy]æMûää„‹‹‹ÒQƬ­´yKgÿƒ•¼¥³N€ýExS´fV•1MÀÎæn;Ýgw¸iIzk4ÚáhgIEND®B`‚routino-3.0/web/www/routino/icons/limit-22.5.png 644 233 144 1524 12573351605 14657 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ IDAT8Ë­”OH\WÅϼPgò2“(¼Ù ¤Pˆ2¤ÑUèJÉb6”¨qa²+ÁË‚ B²*t!JB‚Á…+m4¤òFH˜dçŸWFÑ&óÞÜûë«YûÁåòÝûûçœ#$! Çq$‘Hü€4J,ö†T ._6¤R‹½A­î É©â„j‰RŒÛ·HpÝÏô÷óg– €‚£¼¿\÷3Ò£j}¬Š—¨«sˆÇE&sé=ù<¬­ ‚µ†“q”WX[3äó ½'“¹B<.êêáy¢£ÃEzËÀ@°DDXûÿ¨­Ê €ô–ŽÏ«^SzLW¨\Æ„!Æ¢(˜ÓŒÊe¢0$‚®.×Þì*®ûÉ‹X°T'Xk±ÖžjX­³‹àºŸ®žû]âÞ½Ÿc½½fõõkgâɹ®«t:­••MNN*™LÊó§Šäóâÿ|ø`¾w]ÚÚÚhjj¢P(àyíííd2|ß Òé4üzçÿ~ýjxú#ùŽ’ÉëºySkïÞ9¿=|¨¹¹9¥R)MOOkppP³³³J&“ò}_’´´´¤½½=ú%ŸW:w¸qCN}ýuqé’1¥¿zE6›¥»»€ÅÅE²Ù,===„ÕOYXX ¯¯±±1ÒžÇÌì,”ËT.^42ɤåãGüÕUÎ' cŒayy×uaŸÃÃC¶··ghh€Ÿ®]ãω øò…è«Pò™™áçÏÍwŽCkk+™L†\.Gcc#---444P(ÈårÌÏÏÓÜÜLª¾žÞ»w©€ab+ùBåÁB¨”66ØØØ vwwÙÚÚb}}ÍÍMØÙÙÁZK¹\¦T*ÕøXáþ}FyF±xÄ›oúmsÎ X{‚g§`!´Q„"ì `°Çs¥‚=’UÈ­['p¦Ú°@‰ÉIÞ28èÓÜ\û¦ô˜áa ”ƒR S.`Œ!Œ¹ü@S.”J(3< Òãóš]Ç÷?ÛÝÝêµÀ‹ ¬µXk/ëÆ`ÁÚÝ]ðýÏHׯý$Ípÿþ÷ν{æ÷ç'Oäyžâñ¸¶··µ¸¸¨X,¦h4*k­\×ÕÎÎŽ~}úT žç4߸aÈå¾q²Ùk2R–åeþ,M´±‘t:M{{;óóó$ ’É$‰D‚ÃÃC677 ‡ÃôôôÐÚÒÂoïß^¼ "e]…Ã7uû¶*Ÿ>¹Ó33Q[[›Ö×׋Ŵ±±¡P(¤ÕÕUIÒÞÞž&&&´¶¶¦†pX¿¿~íêÎQ_S45>~àïãc†††èèè`ee…d2Ioo/žç±°°ð_ 3™ üx÷.à艷R.;jhÐ/ÏŸë‡[·´¼¼¬p8¬L&£®®.¥R)555©¥¥E§§§ÚÚÚR__ŸÆÆÆ4;;++I¥’kY)˳gƒéK¥hlldtt”|>O?ñxœ©©)ŽŽŽH¥RLOOãû>ÝÝÝ|[_ÏÒ«W†—/ ¤¬æxð œQ(ª`rvvÆÁÁÖZŒ1‹ENNN( äóyþúð ÂÇXiîg¦Æ™©Ÿ³õ5´5g•Ë œ}é€t lƒ*•KÀ~­Û ¨Êÿ:àJ{óJ§Æ•γ+œ´ÿh6{¯lÚíSIEND®B`‚routino-3.0/web/www/routino/icons/limit-17.9.png 644 233 144 1455 12573351604 14671 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“âIDAT8Ë­”ÏK[YÇ¿ï…ÄøbK"„,…Œ"*ÓEÝdÑE²©k—Ep¡€ÿÀÀ,Û+q'Ú_tc)®SÜ(H1b@—ž0¡¿’÷îýÌ"‰•éÌÎgqî½ç{ï=|Î’„ëºH.’ˆÇCZÁq*$“08hH&Áq*H+Ý}!¹Ý<¡žP<î 9¼zGzƒç]²°Ÿ?[|~üßïÄ ày—Hoºçn¾D,æÒ×'††²HÇLMA­f€k ÷­‡Ôj†©)ŽÊÒ×'b1Wd2¢Tòª,-´K@€µ?½·h±´R•RÉ#“é~SzËì,@;lµ°A€µ– îÜZ{÷@Ón´Zhóò%Ho{5Ëáy炵›ÿ׬µac°`íÑxÞ9R.ò‡ô§æçóÌÍWrËß¾)ªÙljmmMÕjU‡‡‡P*•’ã8:88Ї•N¥œÁ'O µZ¿³·ÒæÃÆ‘H„ÍÍM*•  Çakk €ýý}†‡‡Éçóü>:Êßahøô #í¹züø©ž?—•\'Q&“ÑÅÅ…ÆÆÆ´³³£™™ÍÏÏ«X,J’vww•N§µ½½­X¿¾¼{çêÅ ÙDâ©H¥ õ:½JMNN²ºº €ïûŒŽŽR­VïjvrrÂøø8Åb‘¾h”¿Þ¿‡0$xôȸ²ÖQ»­žYkeŒ‘$­¯¯+N+—Ë©ÕjÉ÷}5›MŒŒ¨P((™J)›ÍJWWrÀqu~þ]å²$YIJ$ŠÅb’¤r¹¬R©$Ij4šžž–çyºººÒòò²æ^¿VþÙ3«¯_¹¼ü.¤BŒ¡ÑhpssÀÙÙ×××¶Œ¡^¯p{{Ëéé)¶Ýîä-.‚´ò“³££Ùaø WÿŽM—3–{œýÒ6è þ—aHî6³³÷:àA{óA§ÆƒÎ³œ´ÿøol™T~IEND®B`‚routino-3.0/web/www/routino/icons/marker-1-grey.png 644 233 144 2256 12573351600 15536 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“cIDATHÇ}•OhTWÆ¿sÞ}æ¹—¡T$8DâF' Yh72¢«bv‚nšEºè¦•âF¦2é¦nºí²Ä@bFgÓ©-#JŒÑ•#Ic£a¦“úÞ}÷ž.Ì›f’˜¼÷~÷;¿s*• ¶ÄJ)T*[­VÏŠÈ÷Zëá8Žá‰ïûäºîŸDtµR©üZ­V9MS°@[¦ŽˆùÔuÝ›I’\ÔZKET(ÀÌ]Gk-–——Ñl6Åu]òoÇÆÆÜlCf¥³Ö"Iè&"€±±17ŸÏÛ$I.'IrŽEäºÖårQÁZÛÓ˜,ñìì,¦§§»ÍÊ’[kEÊå2´Ö‘뜦é©(Šdhhˆ³…™,--ajj <À^ÊÖ qE’¦é)ŽãX …år¹n‚ízýú5Z­<ˆÉZ‹\.‡B¡@q 8Œw-ÌR*•011#GŽ Žcì§-fÇql»Ý†Ö{™göS Ó這-A`^¼xazš°sÃ~¥^¾|‰çÏŸK†|§”âz½ž6›Íž«²Ó|¯J˜Zkܽ{×ÐýćºáyÞÏêöíÛéÇÅqŒ÷ïßï‰æÎ;vuuÕñ}úôMß÷o5›Mwff¦‡/ˆºÝž››³=RXI’äÛùùùî¡N©TÊ’Ðòò²cApamm-¿“oÆñíÛ·˜šš×u ÀÍ‘`€«Õj÷Ê1³bækíx†h4²¸¸Çqº µÖ˜œœL“$aÇqnÑ-îFT«Upö²¥}ù@½^·+++Ê÷ýgq_ÅvClÅã]|§§§Sxòä Â0„µö+¥Ôf­VsôtÐÙþ±_ß÷/¬¯¯ç[­–<~üØt:ÇuÝ+&E¤Ëq[(ììm¿l ‘23ßãØ(¥¥T½X,ž}úô)cìNÞò÷Àñý]D®Aà8޳bŒùr~~ƘM4þn‹jø?Ä%)IEND®B`‚routino-3.0/web/www/routino/icons/limit-22.7.png 644 233 144 1472 12573351605 14663 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ïIDAT8Ë­”AH›Y…ORFÓŸLkªð» tVU³¨î2¸ˆnÜ(Ò¦[m;`»wÙY ˆÐBAW¶#eºh»(³qÓquJ:Ä’\hH †ÖFbþ¼÷u‘¤cfç…Çã¾wïáÞË9WHB~¿É$VðùÞÓÓ×®zzÀç{´Òú’¿•'Ô |H>îÜ =Æq¾07/^X (—¡Phússà8_·â}­|‰®.?ÝÝ"¾Ž”ej  ÐÀZÃykú  SS e ‡¯ÓÝ-ººüÂuÅô´ƒ´Ïü<À`ñ<ð<°ößÓ~ œ1?Ò>ÓÓ®ÛjSzÂíÛ¨{gg˜zc žçaŒ9WœÅ«Õðêu<¨Û[·@zÒžÙ ç“Íd°`i%þÀZÛÑq+Î’É€ã|BºqééWîÝûÑw÷®ùçÝ;ÿïÏŸËqõ÷÷+•JissSÁ`P®ëJ’´±±¡ý”N¥|Á›7MèóçË6™¼¤†´ÇË—$?~4ß;±XŒVWWq]—±±1Âá0»»»lmmFÇ'ñg2ixýOÚS#´T«üñê??z@4err’D"Ààà ëëëÔj5–——ùéþýfǹ\¹bE(dL±À_o߉D˜™™`{{›H$ÂììlÇ K¥CCCì§ÓM°bB!# Z*þN§¹°°°€1†Çaqq‘““jµÙl€D"A, ÏÃÕ«Vui7oøíéSóßÏÈÈáp˜‰‰ úúú¦··—µµ5FGGñÏgIl·^}`x˜™g†g†ÏŒ„$|ßGò‘D4ú;Ò ž÷‰dºº,É$xÞ'¤•¦_H~3N¨•(õ<ž>"½"«1?Žãc¨Váø¸¡ÏÏC,VCzÕ|ï5ã%::|"10pé‰ (—-âœåçÓÐCÊeËÄH‡ Ü%¾H¥Ääd é3‹‹à0Œç~HËX\é3““1R©f™Òkž<¨‡A€m`­Åƒµÿÿ ­×1A€…:ƒôºÕ³{Äbç‚sÍDι_*tW·s¬Ås‹#ÝkûSúKÏŸÿÁÜœõ%?_(( Cuuui_kkkŠD"J§ÓrÎÉ÷}íííéÍÛ·º‰x©û÷-åòoÞöv›¶Y_°¯¯ÓÞÞN6›åää„ÎÎN¦§§éëë#ŸÏP,I$ŒŽŽ2ÐßÏΗ/–wï¥m_·o?ÐÇr’ïµµ©§§GÎ9…a¨¥¥%ÍÌÌ(•J)IR©TÒ‚r¹œn%ÚÍç}=z$âñâÎËׯ˜fo2™ «««œžž255Åàà ;;;Wý+ 1÷ìàÛ7\2i}9ç©^WëcÔÝÝ­\.§‘‘mll(«X,* CmmmillL³³³Z^^–“¤ çœçëü|W>Hj؉„...”ÉdÔÛÛ«d2©ááae2kssS’”ÍfÕŸNëŸ÷ï>~Tøýû®Vxñ ÄZÎÎθ¼¼ÀC¥RÁƒsŽjµJ­V£R©pttÄ¿¥—òò%NZùÁÙÁAƒì0¼â©«µöw4|ŽŸ8»6ÎZ …÷ \crmnt6otkÜè>»ÁMûÿ%tm½zgIEND®B`‚routino-3.0/web/www/routino/icons/marker-49-grey.png 644 233 144 2662 12573351600 15633 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“gIDATHÇ}U_hSYÿ}çž“ÜÞ”ÚÿÓIC•õ¡*jìƒD¦‹—-²û0/»Ë2 CwÈÃÀ¾¬Â‚Ï© (UŒÂÆî’¥0T—¤Ö1:ë¦M•d"©Þ?ç|û0ÍêÌîÜ{Ï=¿ï;¿ïMMMaBJ‰©©)“Ïç?aæ¿ø¾ÿ+×uá'p4%¥Ô¿‰èË©©©¿çóy  R‹™53ïTJ]ò<ï3ß÷9S*•‚"d4Æ`ii Íf“•R‰D ¾ïÿžˆV‰È %ÁÌÀ ”²Ôét‰Dpúôi‘Íf)âc¸®‹ÅÅE.•JúÍ›7Ÿ9ŽsDk}š™¿'"a8q‚ì‘RþÓó¼Á}ûöù*N“eY`æŸ-)%víÚE™LF4 ÿõë× ¥Ô9cÌufþAÄb1(¥¾Y__H§Óþää¤êïï‡1&ôŒˆ „€DfFèïïÇää¤J§Óþúúú€Rê›X,áyÞ˜çyŸ' 3>>®€™C»DÝï]RÊÐðøø¸J$Æó¼Ï=ÏÌüµïû8uêâñ8Œ1B„µZ Íf3ôxmm >Ä‹/ „€Öñx£££ð}Ìüµuüøñ¿õõõ!—Ë ¥ˆ($^XXÀåË—100€d2‰J¥‚+W®àåË—˜››Ã»wïpàÀÀÖ­[iaa]×Ý-\×åT*E===0Æ„W_YYÁÌÌ b±"‘`ffÇŽÃÅ‹qáÂŒÞÞ^A€nD"LOO£ÕjabbB(¥088­5îܹ£éG\±ÎŸ?ÿ¯÷ïßïo·Û‡VWWƒ#GŽˆL&ƒƒbhh÷îÝÃÙ³gÃ(‹EÜ¿¯^½Â¹sçL&qãÆ óäÉ˶íß÷m:tƘomÛ¯×ë[µÖfÿþýˆÉd{÷îEOOvî܉ááaìÞ½'OžD:FµZå»wï ÇqÞcÎѤBxeŒùã8÷Ëå2ïÙ³ÙlÆ ÿÔó˜±}ûvlÛ¶ D„v»b±D"ED_Ñw¤PD4+„øY·oßö[­VX1̦3‡åY,ƒf³©"‘ÈôÐÐÐ_A7A}"###—¢Ñèt³ÙTׯ_>®ý®·–eannÎÌÏÏËX,¶ìyÞŸ*•JhÜíþLKKK¬µþÖ¶íOëõz¢«¯Ö:ìB¬­­áêÕ«¬”"¿%¢9"’4ˆ|>6u!„B,c&ÇA¹\æÅÅEX–c ˆ¾ï£P(žç ˲.Ñ4µ!#òù&üàú¿ CWß0ó—¶m[–e-k­W©T µÆÿÂ\¸:d‡IEND®B`‚routino-3.0/web/www/routino/icons/limit-16.5.png 644 233 144 1466 12573351604 14666 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ëIDAT8Ë­”ÏK[Y†ß{ƒI¼\Ҭƕ¤•B]”)R&Úm{Qª%ÐE±ˆn§ø ̲ݻÕ8–B–ƒ‹NËt#AÊtQð²ˆ)¨4ÚäÞsžY$±ÚÙzà,¾sÎûžóžï’„ëºH.’H&o#-ã8ŸI§!“1¤Óà8Ÿ‘–ÛûBrÛ:¡ŽQ2é 9ÌÎ&‘^áyßXX€·o-Õ*|ý Õj+^XÏû†ôª}Þië%âq—DB ÞBÚ% R1@„µ†Ë£GT*† i—ÁÁ[$"wE¿˜šò¾°´Ð,aaÖþ˜5°@ƒ¥%¾05åÑßßNSzÍÌ @3j40-ÆÂ0Ę«  Âf“š~TEÊd2Úßß×ÊÊŠº»»500 I ÃPÅbQ¿¯··;™DµÚM©Ò6kkæÏµ5ºººØØØ`tt”‰‰ ÆÆÆ(—ËÍf™žžæY¡ÀÁ÷ï†7o0Ò¶«Tê¾>”•\'S&“‘ïûÚÜÜÔÞÞžz{{5>>®žžIÒÖÖ–NOOèq(›H¸>æüü€(ЍÕjc°Örtt@£ÑàððÓl¶t‹‹ -ÿàlg§ÅM]pÕµcv…?c0`í%ÎþW6 éþ ë…aц»ÉÌÌ¥ ¸ÖÚ¼Ö®q­ýì;í:(Q0=”NIEND®B`‚routino-3.0/web/www/routino/icons/limit-2.2.png 644 233 144 1253 12573351603 14567 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“`IDAT8Ë­”?K+AÅÏn㢬¾&ñU~‚4Öbk;ÅÊ"_" `™Þ"i,­" !)„XI0’ Ѩ¸»3¿Wl6^“…¹gÎìÜ?ç^! I¸®‹ä"‰tú/R Çi±°þÀqZH¥Ñ¹ÜÑ=¡äG鴃䰽F:Äó†ìîÂé©åþáþ>¶wwÁó†H‡#¾3º/‘J¹Ì̈lvé†ÍMèt a­áëŠíˆNǰ¹ Ò Ùì 33"•rE&#¶¶<¤k €À††`íç—`` ®ÙÚòÈdFaJGäóQ„ Â0ĘIÇŒ11E1?Ÿé(ÉÙ*ž7 ÝŽ Cì8*‹µöç°‰‡í6xÞiUH%öö"4›MŽiµZc~ÃGüˆ½=JBªS.cÀ\]]1??ÏÆÆÙl–Z­ÀåååÞh4â‡ÀP.ƒTwåûëÊå„äJR§ÓÑÁÁÎÏÏ577§F£!Iº½½ý·’«\Nòýu±¸hxxˆ_‰“ÊÅÅkkkììì`Œçê;žä‡X\4Â÷-Ý.IÝêõ:³³³‹E^^^x{{£×ëQ«Õðk-´ÖáðáÑÛ·o牉 ×jµ¤ïû®»»›‰D¤d||¹\###xòä N:…]»vA3gÎàÕ«WÈåroÅ,‘H ³³“nß¾mù¿>¼Î¡1Ùlh+÷<abÓ¦M8vì2™ VVVÞ‰Ú*K!„m6›¬µ†R ÌŒýû÷é©)\»v }}}Èd2°Ö¢££J)c"²¶­V Ìl¥çyæáǸsç÷÷÷ƒˆ°´´„³gÏÂ÷}8p;vìÀÿÁ9fÆ£GðàÁçyža?J)¹\.‡õzpáÂXkqôèQär9h­a­Q4ºD­5®^½jè?ü&7lØðóóçÏ{¾¸råJ822"+• b±Nž< c VVVÏçÑÛÛiûù̌˗/ÛÇ‹D"qGký¬V«p¢££c×½{÷6OLLØ#GŽðââ"„ ¢¨Im E¤333îúõëœL&W¬µ™yY2³ðØZû•çy7nÜpÛ¶mC±µØ¼y3ˆÍf¥R)ŒÅbŠˆ~ ¢¿HPDô‡⸵V\¼xQ/--ˆ`Œµö½£Z*•Âz½®b±Ø¹žžžS@ب&"Þ¹sçiÏóν|ùR]ºt)l{Ö^(í 33¦¦¦ìÍ›7åºuëªA|?==]&Û·S¥RqƘëžç}þôéÓ´1Æf22ÆD‹…™ñâÅ œ?Þ)¥À"š"" À‹ÅhÚ˜Y2sÕZ{(™LbrrÒÍÍÍAEJkÑÑÑ0Bœ&¢sÔª(‹àv±ŠÈ_f>NDb||\7(—årÙV«UÇÿö}ÿ‡½{÷âMB¬‹5Ä‘¿ñxü\½^Wccc!ÌÎÎbrrÉdÖÚo¤”Ë¥RIxÝEâÍ÷ùÇ?¯ÕjéF£áfffL«ÕJ©ïŒ:ç"ß…wBøÆ/[s{˜ùß÷”RH)ËÙlö“»wï²1Æ®%|ëùﱡíïŸÎ¹žç !DÕóõôôô[[j-þ]sµ-#€Q-IEND®B`‚routino-3.0/web/www/routino/icons/marker-33-red.png 644 233 144 2071 12573351600 15422 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“îIDATHÇ••ÏkSYÇ¿÷WÒFÜ$È,òJ)ÚÒ­«†Ö E]dÝv3‚®ŠF:8ÿ@ÑÍT7Ž ±FŠë‚2ÕMýµEw&K#-¤µ¼÷îýÎâ¾—&)Ã8‡w¸÷óÎùž{ÏŽLöõõIÈf³çŒ1ï€K<;ß1ï²Ùì9HöÉ$¯X?c–â8ž%ÉB¡ &&&`ŒsRJDQ„ ìííQ!´Öõ(Š®ø»ƒÓþÂRª €Åb1ªÕj¶ÕjÑ9ÇNsαÕj±V«Ùb±`²o(­8Í8PJm`©T IÒZË(ŠŽ=ÖZ’d£Ñ`©T ð€Àc¥„Öú–Ëå0……‡‡taHÆqW¦Œcº0dxx؆—ËåµÖ¤”@&“9€AØf³I’ŒÂ°”lnûÄÒuÍf“AXÌd2ç•â¡s.X\\äôô´ˆãZ)àùs`}øö ô"‘]q94„8ŽQ(Íf¹¶¶&„?€Ëçónww×7‚$H€ÿü>‘~–,€´Ö{qo’äääd°´´­5œsBÀƒ££#œžž2‚@)Õ6Æ<ðWgx´”² €¥RÉ´Z-Ûï÷éœc6œsì÷ûlµZ¶T*ôû¦SÆiÆ¡”ò=V*•¨Óé$­µ4Æ$#Š’a ­µ$ÉN§ÃJ¥yà÷ÂV(¥ž`µZR°(Š’,­MFqLg-£ xµZP)õTär¹ ÃÐv»]’¤1&åšÌQDöûäÅÅÈût]·Ûe†s¹Ü”R/°ÙlÚÀ4»wïÈ{÷H€TŠl4È8&ž®o6›Ögû\±Xt½^oxà !oÞ$oß&Ÿ=#?NÀ›Íá÷ô"{½‹Å¢ó–ƒ­Õj^®x4ËýýKMÈõõ¡¾Ù}µZ¬ ´Ö’Þ½Þ¾Å"ðü9°¶–<¿~ ¼z,.â{áqØ……žŸŸ_Ò¿4e2d½žd}ÿ>ùåËÈ÷Ô•J…,„»ï)~÷¢nÜ ¥$ŸÃj0pnn.öEð …´Ö¿{󒌿}Kv½x‘P¾{—\[#É;wÈäpÐöö¶õ€o¤1ι?µÖ?u:âÙÙ™Ûxø00äçÏÀÇÀõëÀׯÀµk€µÀ­[ˆWW!¥ÄÁÁwww…”òÂ9·à¨äƒU!Äív{Tß±Hå999a¹\Nk¿áM †n‚J©GXèãKÖFQ¢m:Œ¡õ‡mnnß[ÛSSSRŠ)¥Äìì,´Öí}3%™Í~ooÏzÀ“awÊ´=Œ½µÖ]l46é'Ñíããc  €BˆŸÇiÇ•úzûß<~ ’êÓ¸"Fô Ã0J["I6”ö1€B½^Ïþ–þ=Æõ]^^6$Ùn·“†!ƒ XõËå•€ãú*¥º¸µµåæççSÚ O[ýWÀ}¬A@±Ïð™™(¥Äÿêëç_¤”BœøqŒÍ?âoñæ¾Á?¨<IEND®B`‚routino-3.0/web/www/routino/icons/limit-39.9.png 644 233 144 1512 12573351606 14671 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÿIDAT8Ë­”AK›Y†ßï«&šVbÁED!ÊTºHÅØ¡AŒ&d9v£?@˜›a\¶{îj5m™?à"¸ 4 t°³P‚([IÀäûî}f‘HÍtë… ÷œ{ßsϽ<çIHÂu]$Iôõý„´‰ã|bp¢QÃà 8Î'¤Íξ܎Nè6P_ŸƒäËõ!½"ª³²>XÎÎàòÎÎÚöÊ „Bu¤WóNG/¸ƒbt4ô……¨V àc­áîhÛ>Õªaa¤/ŒŽ&E àŠ¡!±¸BúÌÚ@°xxXû}ÞúÀMÖÖ@úÌâbˆ¡¡Î3¥×,-a å5›˜V c žçaLw‚¦ÕÂk61Ðbi ¤×·ö„Pè›=:jߨÞ `­ÅZÛ½6 ÖA(ô éɃߥ ^¾œr–—Íß•Šûç›7 ƒŠÇã*—Ë* ŠÅbŠF£²ÖÊu]U*í ŠE"NôñcCµÚï”Jd¤{{üsyi¢á0Ùl–d2ÉÖÖ©TŠÉÉIR©µZ €J¥B2™djjŠÔÓ§üëû†wï0RÉÕÀÀ3½x!ÿëW÷ år9% (‹éððP@@ûûû’¤b±¨X,¦b±¨@¿þzûÖU&#ûðá3×íéAÖêçDB¿./kggG'''Êçóª×ëš™™Q¹\V0”$ÍÎΪÑhhnnNåÕÛÛ+õôH®‹ë·ZŽ=Òöû÷úåùsíííi``@ÅbQãããJ§ÓŠD"Ñõõµ†ÆÆÆ4==­ÁHD‰DBj4ä€#+•ØÝåÌL:M8&ŸÏszzÊüü<ñxœõõu®®®˜˜˜àøø˜L&Ãðð0¿µ¹4loƒTÒ&««¾wsC­VÃkƒÉÍÍ çççXk1ÆpqqÑíoó賺 Òfg¦Ã™éˆoÙú?s¦Ã™ËξW@6 вž¾ß%þaíûØvö-²Ù;p¯µy¯]ã^ûÙ=vÚÿ¯î`§£™XåIEND®B`‚routino-3.0/web/www/routino/icons/limit-29.0.png 644 233 144 1461 12573351605 14661 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“æIDAT8Ë­”ÍK[iÆŸ{‡|p›ÓB Sœd¡FÊDt#ˆBV„´¸p)¤Ýg—ùZ èJ° ”é¢Ýô°cºÒ Ó1¢ì„RS’{ïûþf‘¤µL—¾pàœóžçð~<Ï’„ëºH.’ˆÇF*ã8o€›7 à8o‘ʽ}!¹=œP¿Q<î 9Ü¿GzŒç]P,‹–ÓSøøNO»q±žwô¸WïôðѨK,&R©[HïX\„ãc„Xk¸¼ºqÈñ±aq¤w¤R·ˆÅD4êŠÁA±´ä!²¶Ð,AAÖ~³~,Ðam ¤C––<{×”žP(`À:Œï`Œ!Œùþ€Æ÷ :,ø =é¿YÏûdk5,XzÀË ¬µXk¿÷Á‚µµxÞ'¤ŒÊ¶X«oÞ°¾¾NµZààà€ ŽŽŽÃ€Z­Æææ&wó¡-A*+”öyù’?ß¿7×=ÙÙYÒé4{{{Œ155E6›¥ÑhÐh4Èf³Œ“¾}›Áðü9FÚW˜HXZ-þxõŠßK%fff˜žžfaa€\.Çöö6;;;LNNðë;ìV*Ðn\»fÝŸ"ìÅ… wï*ŸÏkttT###ªT*ª×ëÊçóªV«ŠD"’¤0 •H$$I×oÜЗVKŠÅ$×ŵAà¸Ñ¨þ:<Ôüü¼VVV´µµ¥V«¥L&£¹¹9%“I¥R)µÛm «Ñh¨^¯ëŸôK:-}þ,ùÒ>¯_³ùô©‰¸.¹\Žd2Éîî.ËËË Q*•h6›LLLÐl6Y]]%‘HðÛ£G†gϰҾÊ<|È''œô¬Ýnãû>gggXk1Æp~~Ž1æ›ßé„ϨպÌîñ«ßàGœ3Æ€1˜ðì«,ø6°]É|ÿÏÃ~Ͻ{—p¥Ú¼Ò©q¥óì 'íÏ‚ BIEND®B`‚routino-3.0/web/www/routino/icons/limit-8.3.png 644 233 144 1327 12573351604 14601 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ŒIDAT8Ë­”=K+A†ß]$†M±%"Š‚·J™B;±‹`­ÁB€ÿÀ6éí !?ÀÂNÁP&B ñ"dwfž[ì&÷F[†™9çÃùxÏ’„ïûH>’Èfÿ íáy7ŒŒ@>oÏ»AÚKõBòÓB=CÙ¬‡ä±ºšEªŸlmA½îx|„÷wx|LÞ[[ŸHÕï¥ÿ%2Ÿáa133‹Ô¢\†vÛç,ÿ¯ämh·-å2H-fff™Œ/ÆÇÅÊJ€Ô`g  8ââœû·{2p@—¬¬Œ§aJ5*€c°QDÇX;蘵6‘G“à+j½œ ‚ÍfHã"sg_žs4›¤¢öØÞ0.Џ¾¾¦Z­r{{Û÷ ÑhP«Õ¸¸¸H &xÃö6H{Bºäðàøø˜±±1Ö××™ššâüü€f³I>ŸgmmÉÉIÎÎÎH,a9<érHaXÒâ¢$ù’d­UZZZR«ÕÒ××—$É£ÝÝ]MLLèþþ^ÝnWéòµ¸(…aiH¾2¯§y{{S¡PÐþþ¾^^^T($IÅbQÓÓÓÚØØÐÇLJÂ0”$y’”ÉH¾/çx^)#¤y^¿ÆBP.—9<< Z­R*•nôn…»»»ÌÎβ·½ Úb¤y!}fi Àü¹´DOO+++Ôj5†††edd„³³3677‰Ç㌑N¥ØþúÕðá¡ôÙÕƒOõ왬ä:÷î©¿¿_½½½ÚØØÐÀÀ€*•Š"‘ˆVWW%IGGGšžžÖúúºúâqí|úä*Ÿ÷ï?ɤáÇ‚Nss¹ ø¾Ïðð0ù|žh4ÊâââÍ*• Ùl–?^½Âüü‰M$Œ+kµZê’µV®ëÊ÷}e2år9%“I¥R)]]]ikkKãããšœœÔÜÜœ¬$5›r¬u\5;*—%µíñ¾>IR2™T£ÑP©TÒÔÔ”²Ù¬ …‚ÖÖÖ$IËËËJ=z¤¿>~´ªVþúµs3M Ä...ð}€ëëkNOO±ÖbŒ¡^¯syyÉùù9'''|ÿö BÞ¼Áv¦ÙÆÙþ~Ùaxƒ§.nƒ¶clûßÂÙo`ƒ€nÂnÒÛ² ‚6ÿgît7ïôjÜé=»ÃKû7-c\“ÜG¬IEND®B`‚routino-3.0/web/www/routino/icons/limit-8.4.png 644 233 144 1307 12573351604 14600 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“|IDAT8Ë­”=K+Q†ß=\cX‹H"D¼6–Q¬E°° ÚYYèü±·‹•‚?ÀBlEQL!BÁ@öãœç»É5xoçÀÙw†ùxg„$$aŒA2H"›ý´çÝ1: ù¼et<ïi?ý/$“ú õe³’Çúz©‚ï²µ''ŽfÞÞ ÙLô­-ðýO¤JŠ÷R‰LÆ0<,¦¦¦‘ê”ËÐhX Æ9ËWIô˜FÃR.ƒTgjjšáa‘ÉQ,ŠÕUé‘€pDD8÷÷õlà€€Y]õ)Ó2¥=ÖÖBâ†DQ„µƒ‰Xk‰ƒâ8Á¯­´×ëÙ,¾ÿA­–E¸ÊÜÀw_O‚9j5ðý¤Y!í³½ »0àææ†J¥Âýý}?H/Ëz½ÎùùybOð1ÛÛ í 隣#b°§§§Œ±±±Áää$———ýò¬µÌḬ̀¼¼œ$–£#®r¹’%ÉH’µV¾ïkeeEêt:’$cŒvwwÕívU($Ix^â·¸(år%#cP&£ž´Ûm«Z­êõõUù|^’tpp ÃÃC---éêêJÏÏÏú54”5“‘ŒÁÈ9Oa˜%kaaAgggÑÅÅ…¬µ²ÖjnnN···j4zxx$9I CÉ9¯ß3›öìéé‰R©D¡P`ss“——æççiµZT«UÊå2Q·;гi¦„$Z­q㜣ÝnEÎ9:ïïï =üÀ4xfS§Þ¿òl@þóo@šÑ¿ˆ àRÌ÷ øÑÝüÑ«ñ£÷ì/íwÿ•Z ÄïUIEND®B`‚routino-3.0/web/www/routino/icons/marker-71-red.png 644 233 144 2062 12573351601 15425 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“çIDATHÇ••ÍkYÅïU½tºý Éb]Aü˜MÄ@m’´É˜U²™Ľ;œ?ÀÁÕd9q#zá΀œìW‚Šqº³èÕh4?êëÌ¢^·dÄ™ [U¼wêœS÷Þ‚¯a-@©TšrÎ=ä>«ÿÞ9÷¼T*Møs¶ d|€ øÁ9·˜¦é¼$ŒŒ˜K—.áœ#Ïs¬µ$IÂÓ§Oyÿþ½Œ1& Ãf’$7¿ûpzo8APµZM–––²åy®þÈó\;;;ZZZʪÕjÈŸ;ÕUÜeA° ¨V«Å­VK’”e™’$9´²,“$µZ-ÕjµØoQk-a>T¯×cIÊÒTñî®ò8–’¤X}Œó4U¼·§Ì?«×ë1 0 Xka```PEY»Ý–$%žÉ¿F–KR’$’¤v»­(Š2@31f9Ïóè·;wôÓ•+&ýò…pe^¼€×¯áÍxõ Žƒ¡!067áåKìéÓ¤IÂÈÈ¥RI?6Ƙòááá|ëÝ»BÚ‡ÒÐ’µR¥R\?|X0ÝÚ’ÆÇ¥ééb¿g»µµ¥áááÜ—Ùìì¬$)MÓ»OŸ¤ííd~^ºx±¸~ôH:~¼xÉÜœü¡âœ¤ÙÙYYXç’ yƒƒp䬮“'ðìYQ#.ÀÆÌÍÁöö×¶‘ð86òN§cwww)—ËHÂß·oõkpö,dœ8aå2$IÓØ¢4ß¾} c­ìþýûÅÝÛ+d­¬Hå²äkVy^”–$MMI…z¿mmM@nŒ‰ ‚àW@£££I¯è%éêU©Vû XÔP‘gf¤Ë—•{O?þ¬sçÎ¥¾ þ R©àœ[TŸœL$)ýøQ:zTº{·÷1öNOKêVóõë×3ø¨tm©:ç65nÝÊ$)¾wOòÍÐcÚÍkkJVW%I./çð‹1f¬ c&­µÒf³Yë2<ÔTÇN§£ÑÑÑnï7úñœ1†0 o¢¸µ±±`¨·a~a!ñ³µyòäI‚ èM¨> íØØι¦.I¯!ú¢Ûï‹‹‹™ìô¦SߨãÀƒÈ9×Ôh4 ãxëõõuU*• µö烲Æ·ýõ }ù$~ÔýîÅñØçoEqw$JR£ÑèÊ^*7nÜèÿ-};ú;>>žHR³ÙYkeŒ™ôÛƒïô7 Ã6 ………üüùó]Ù /;ü¯€ûü&Œ1RÏð¯3gΆ¡ý¿€=}þ%Yk;ÀÙjÅ?ŒåzëF:LIEND®B`‚routino-3.0/web/www/routino/icons/ball-5.png 644 233 144 206 12573351601 14201 0‰PNG  IHDR à‘bKGDÿÿÿ ½§“;IDATÓ¥1 [_ÆÏõgç$QI¼¶!PZx(BN8ÌBn*`ux…J›j¡ý‹¿Ã+=M&C`Œ:!IEND®B`‚routino-3.0/web/www/routino/icons/limit-18.7.png 644 233 144 1454 12573351604 14667 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“áIDAT8Ë­”ÁK[KÆ÷Þ6Æëã¢!šÒ·²®\ˆ ‹.q%¡hWB¡ ýòêÔxÔyöˆ“ö³KLTµ”ÒùIEND®B`‚routino-3.0/web/www/routino/icons/waypoint-remove.png 644 233 144 345 12002775154 16276 0‰PNG  IHDR Vu\çsRGB®ÎébKGDùC»IDAT(Ïѱ Â0…áÏ,ÁX‘¨é™€:NÍL;ÀàZèyym­÷×â~Ö ¸ó›Ì¼ÔñJIEND®B`‚routino-3.0/web/www/routino/icons/limit-18.1.png 644 233 144 1360 12573351604 14655 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“¥IDAT8Ë­”¿K\M†Ÿ{7®ëŒ†UA!_¶J!–‚X‰…›Êzýü3´·³H@PHem±Ý‚Ä@„€â×XˆˆÂ.¬÷Þy¾b×ýLÒz``Î̼󞃀€q ±€¥Ò?¶QôÃÑQ}÷.wtT£è‡°ÝÛGˆ{8䙨TŠ„Èjµ$lš$¿¬Õôë×àå¥ÞÞêåeׯÕ4I~ ›½óQ‹±ƒƒ83ó^8syY/.r53„Ü—Öõ3/.r——Μ™yïà ‹1NNâÊJ"ütcCµ£ÓTÓTCø<¯iP;nl(üte%qr²÷LØruUõ)ëtÌ»ó<7MSóü÷Í2³45×'WW¶žÿìƒIÒòìÌLCè… !¼xaxÁ•²¬áé©&IKø€°íúºA3Õz½îùù¹ªÇÇÇnnnzrrò×õzÝOOU³P«)l#|swW5ßÛݵP(xppàÑÑ‘ccc®­­9==íÑÑQŸpooÏb±èîçϪyúå‹Â·˜‘‘ÌÏ Ž Êå2!†††XZZbjjŠ»»;²,#Š"Êå2!ŠbæçáíÛ1…‚‹ úé•J…v»Ííí-ìììp}}Íøø8*Õj•J¥Âýý= @BÄÓÏ–ç9¥R‰ýý}fgg9<>²µµE£Ñ \.377Çââ" ´Ûm’$aàÍ€ÕëÐj}ïgSÍÌs›Í¦ªv:¯®®ºRÁ›››¾æšÍ¦ív·¾ÞÏfWgÝ4»ú1Ïó¾ ^ÎûÖ%ýKg¿U@HSŸ ÿkžeöÄýG¼jm¾j×xÕ~öŠö?­ìm¾â\X+IEND®B`‚routino-3.0/web/www/routino/icons/marker-81-grey.png 644 233 144 2574 12573351601 15632 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“1IDATHÇmUMhTW=ßwï›÷æÍÆÉP¢AÌ( HÌ@t« #øRÌNªM ]¸Q)nd*³©ÝÔM·ÝˆG¦Ö…aD:Ú ˆ‹ µˆ™d˜itßϽ· 3c¢¸pïâïûÎ9ï^J§ÓXK)‘N§u&“ÙoŒù)‚žç„0¶m“eYãDt.Nÿ‘Éd8 CÐ@+¤Â£Œ1­–e]ò}ÿX&S{{;˜¹É¨µF©TBµZ5–eQ$‚à4Í‘ $6Æ(›¥”…z½¾9‘H„ýýýÜÝÝM¶mãcxž‡b±h …‚ªT*Ç\×ýR)ÕoŒù‡ˆXìÙ³ÇØ(¥üË÷ýÍÁñãÇ­-[¶ƘO–”mmmÔÕÕÅår9XXXHX–õ•Öú7cÌâСCðËÒÒÒÞŽŽŽ`ppÐrZëfgÌ "j.PJÁu]ìØ±CLOO¯_¿N8ŽóE4ý}ß?èûþ‰D"¡¬†nB03˜Ƙ.­ì¥”ÍýÀÀ€•H$´ïû'|ß?ÈÆ˜ A ¯¯ñxJ)!0??ññq<{ö J©&!¡V«azzÌ ¥âñ8úúúŒ1d†½ñxܤR)!ŠÅ"²Ù,ÇçyH&“8yò$ˆžç!—ˈ044Ô”#•Jñ;wL½^癮®.ŽF£ÃRJ‡ª½½½(—˸rå ®]»†­[·¢­­ ­­­8}ú4:;;±¼¼üIÔVx˜…zqqA4I+• Œ1ð<¾ï£R©àÝ»w°m±X –e­1¯ñ]½^3kvG½xñB?~üÌŒååeÜ»w‡Æàà Μ9×uqûöm| ó^¾|‰çÏŸÇqøAJÉ…B!¬ÕjˆF£ˆÅb˜››,,,àÍ›7hiiYÓÙjÉ‚ ÀÈȈ¢÷øU®_¿þǹ¹¹m•Jåë\. É#GŽ ›ÍbbbZklÚ´ »víZó›6bÆÌ¸qã†~õꕈF£ƒ 8+zzz µ~è8ÎÀììlK†z÷îÝÔÓÓƒ 6 ··ûöíƒmÛÍQãñ8’É$ZZZ055enݺŮë.k­Ñ¿’™%€WZëo\×½sÿþ}³qãF¤R)¬[·®iÂjC’É$ˆ‹‹‹Èçóa$±ˆè<ý @2€€EDw™ù ‰‘‘‘ Z­‚ˆšc~läóù°Z­Z‘Häê¶mÛ~ÀÂÆEïܹó’mÛW«ÕªuýúõpUöÖ™166¦=z$c±ØŒïûßONN6‹‰½{÷6ªS©T2J©‡ŽãM(¥tgg')¥š 3c~~ÙlÖX–E¾%¢1"’p&“i6ÁÌ’™g´Öƒ®ëbttÔ‹E! µnÆgxx8ô}Ÿ…—ˆè*kEFd2pc³‚Oô½yófP«Õš2 =33#mÛþÛó¼óÀjB¬‹ˆ?Ñ7—Ë…ðäÉŒŽŽÂu]h­OI)—òù¼`Vë.V>§¯mÛGËår¢V«™©©)U¯×…eYg cš:®jjÍÓ XõdK¡1¦™ïzž§¤”BJYèîîÞÿôéSVJé ׌ÿúþiŒ9ç8ŽBÌ(¥¾›œœül~øª¡§K³dƒ IEND®B`‚routino-3.0/web/www/routino/icons/waypoint-centre.png 644 233 144 216 12002775154 16256 0‰PNG  IHDR Vu\çsRGB®ÎébKGDÿÿÿ ½§“6IDAT(Ïcd üg````b øOŠ¢ÿ¤˜Š¡˜‰ZÎÁ q˜ÀHŠ•x@r<¬…Ô¨ ”q†1IEND®B`‚routino-3.0/web/www/routino/icons/limit-101.png 644 233 144 1305 12573351602 14564 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“zIDAT8Ë­”MJ#Q…O=Ì%‰!œ)؃Ð…Öˆ.@Ìt.Þ9p…€P h{Ðh£ˆ âÀF­E*ïݯ©¤M;õ@AÝߺ¯Þ9WHBÎ9$‡$ÊåOH‡DÑj5¨×µDѤÃ<.$—× •ËRD«UFÚ'Žÿ°³Žq¿ÃýýÀÞÙ8þƒ´ŸçGy½D±è(•ÄÜÜ<Ò/66àö6³À[ lÏím`c¤_ÌÍÍS*‰bщ™±¹#ýdo ý>ôû`öïúÀ€{{ ýds3ff&?¦ô•ím€ ïñ½Á €ý~ËmŸe„,äooƒôuøÏ>Ç]..Ì÷z£B3{÷î½øBLxqqÜEú,¤Cvw¼ ¾F’$\^^p~~ÎÁÁ××ףɒ$áêêŠü¼žÝ]…ôv GGGLLLp||Œ÷žÅÅE–––h4<==Ñét( ´5ô!ÐnƒôÍijê‹VW%É(Š"MOO«R©èôôT¥RIgggªV«:99Q­VS½^—™)‡Óêª45õÅÉ9T,J’ÌL­VKÍfSišÊÌ499)IªT*zyyÑúúºšÍ¦^__5B±(9‡“Y¤,Ó[ʲL³³³zxxÐÝÝnnnÔh4Fñ1d™d9u»ß•$’dÊG¯V«JÓTËËËZYYÑ‚¶¶¶´¶¶6Š …a+S’HÝî÷±ÛÌ Éóó3išŽxöøøHÿÄ0Š|c·9Æ3¼£5 !Œ7Ï{dzw °7 ‡MÇlúOªÍݺÏ>pÓþ? f6OÝ”,IEND®B`‚routino-3.0/web/www/routino/icons/marker-61-grey.png 644 233 144 2570 12573351601 15624 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“-IDATHÇu•OhYÇ¿¿÷^uýéSÙˆÚ ‰/1-FaœKhÁÁŒxX&ž‚ÎevspwXæ2ô°ìe½ìu–´˜qÛö³KDÄ5Ñv4&h²­I·‘6©zõÞo¦k’è~áÁ¯¨ªïûÕç÷û½¢R©„u ¥J¥’-—ËŸ1ó_µÖ‡£(b„_Å®ë’ã8ÿ!¢oJ¥Ò?Ëå²H’,к©dfÃÌ;ǹÇñ°ÖšÃ0¤®®.!RGk-æææÐl6ÙqÊd2#Zë?щH0 €`f`¯RªÖn·÷ær¹äøñ㢯¯\×ÅVEQ„z½ÎµZÍ,-- Að©1æ83Ï‘ `RêßqïíééÑgÏžuöíÛGRJ0óK)…|>O½½½¢Ñhèׯ_çÇùµöf~#Ož< ÷î]±§§GŸ;wÎñ<ÖÚ43!ˆ(]`ŒA8|ø°œÕ‹‹‹9Ïó¶û¾ÿ£ˆãøó8Ž¿ÌårvhhÈép“RB!˜ù×*­ÇJ©4rr¹œãøË8Ž?ÌüÖÅbaÂ)%–——qÿþ}<}ú4}™™ADhµZ˜…Æ„aˆcÇŽAk fþN%IòI†|ðàARJ4 \¾|q£Ýn£P(`xxÆ$I‚ÑÑQΟ?Ÿâ( âöíÛÜn·?QQqoo¯ð}?ÍòæÍ›Èçó8sæ ¦§§qýúu¬®®âåË—¨T*xûö-úûû7µ™ïûèêê¢Xõ¾ïûPJ‰µµ5,.."›ÍââÅ‹ð}'Nœ€ïûÈçó¸pá*• VWW?hµu!¤”veeZëô¦ÖQáÔ©Sرc®^½Š7oÞÀ÷}d³Y8޳©xívB+<Ï3ÓÓÓöáÇéÌŒb±ˆþþ~œ>}ÌŒ™™|Lâ=þÏž=cÏóŒðg¥”¨ÕjÉòò2\×E>ŸÇ“'Oõz°}ûöM™u´Ö7ô^ß‹;wþ%“ÉüciiI]»v-€ÁÁAÌÌÌ T*all ؽ{w:Qamm-å866f_¼x!3™ÌC­õ×òСC°ÖþìyÞж$Iì‘#G¨P(`×®])†Y†aˆîînlÛ¶ SSS|ëÖ-Áªµvˆ^*!„ðÂZûÛ nß¹s‡÷ìÙƒB¡€0 SÆG´»»D„••T«Õ$“É8Dô-ý@ ‡ˆ~Bü‘ˆäøø¸n6› "XkS³­£Z­V“f³éd2™Êþ@H:¥&"qôèÑK®ëVšÍ¦Óá»ÕÐZ !îÞ½kïÝ»§²Ùì|ÇšœœL7“Åb±³;ÍÍͱ1ægÏó¾XXXÈcìþýûÉ“,B¼zõ W®\aÇqÀïˆè.)D¹\N“B(!ļµö\˜˜˜àz½)eŠAk‘‘‘$Žc!¥¼DDÎ:F”ËeˆN°®øÞ¸qC·Z­´/kµšŸŸW®ëþEÑ·ƒƒƒØhˆu°ØbüßÑÑÑ=z„‰‰ AkíWJ©wÕjUàÜ寋ñu]÷‹F£‘kµZ<55eÚí¶tçk#ÌœrÜ6—À†_¶0ó1!ÄOQ¥”TJÕúúú>{üø±0ÆØ­†›>ÿ#:|ÿÅÌßxž'¥”óƘßONNƒÿ§ÿPÔ§X©ÖJIEND®B`‚routino-3.0/web/www/routino/icons/marker-39-grey.png 644 233 144 2732 12573351600 15630 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“IDATHÇu•]hÓKÆŸw>’ô¯C¢Kc%[IL"]ÚZ-m•Ó‹ƒzVd÷boÎY–‚”,änoÖ›½tïkÐÕ^hƒÒlVZ„EY’5E©-VS511ÕÿÇÌœ ›luÝf`xæ}óÎ;”J¥°!&„@*•ÒétzØó'×u÷Û¶mþ+ã÷ûIJùo"šH¥R³étšyžhÔc”1æRÊ‹Žã|ﺮ ƒFÁk;j­±¼¼Œjµj¤”äóù¦\×ý‘ˆ^ fŒQz„¹f³Ù …¼£G²D"A~¿_ʶm”J%“ËåÔ›7o¾·,k@)uÔóœˆ?tèÐ-„¸ë8NO,sÇÇÇåîÝ»‰scÌÿ !"‘íÝ»—U*÷õë×!)åi­õß1ïøèè(üe}}ýp,sÏ;'”R ú„’1"j¯1PJÁ²,ìß¿Ÿ/--¹år9¶wttÜ`ŽãŒ8ŽóC(Òccc²ÅMÆc0ƴ͈Œ1! µŒÉP(¤ÇùÁqœ~äÈ‘¿Ù¶Ý}âÄ ‹ÅHk Æž?ŽÅÅExž‡mÛ¶µ ×ÖÖðøñc8Žƒ`0­5,Ë‚Â,,,”²Wxž× M"‘`­Tïܹƒ»w³µZ CCC8vìŠÅ"2™ ¶nÝŠF£ÁÁAœŸ7Íf³Ù¶m¢Ñ(Y–p³³³ÁÄÄN:…|>>`ffƒƒƒ¸páΟ? R©,ËB4%Û¶ ûk3ãœãìٳسgP*•L&!„€mÛƒ€ÎÎN¸®‹r¹Ü.µ &8çº^¯3×u!¥c ñxårW¯^E£Ñ@__¤”Àôô4ñêÕ+ضݮh6›`Œi><<}ŠH$‚ááaÄãqLOOc×®]@GGÞ½{‡x<ŽÕÕUìÛ·ápÏž=C.—3~¿_1B°ÙÙY¯Ñh@)…K—.¡T*µ#àœÃ²,d2Ôj5Œƒ1)%zzz ”ÂÌÌŒ¢Oú+?sæÌüÇ{ëõú7«««ÞÁƒ™R ·o߯üü< …8€þþ~nݺ…|>—/_âôéÓèêêÂ7ô“'Ox øëºßÑää$ì”Rοÿþ—CCCztt”---áí۷رcvîÜÙf·¶¶†/^ «« ]]](‹æòåËdYÖ­õ¯Œ1cLx©µþµeYÿ˜ŸŸ7ÝÝÝH&“ˆF£ ¢Ï^ÔöíÛ‡AD¨×ëÈf³žÏç“D4IDÀ ‰(Ïû‰ˆøÍ›7Ýjµ "‚Öºeë€ÖóÌf³^µZ•>ŸïJ<ÿ3Àk5J—ˆXÿE¿ß¥V«Éëׯ{-£ÍjÕò½{÷ôýû÷Å–-[VÇùC¡PhgÄ>ÜÚLËËËF)õ¯@ ðíêêjH)¥{{{I)Õn,Œ1¬­­!“É)%ø Ý#"@K§Óí¦ÎŒ±­õ9˲077gJ¥8çm ®ëbjjÊs‡qÎ/Ñr#Òé4Xk²¡¯ò­Õjí/%—Ëé••á÷ûÙ¶=yüøql6ÄX|aüßjµ*¯]»æÀÇ177˲ µþb=›Írf3w¾yñ5¾~¿ÿÛJ¥ªÕj¦X,ªf³É¥”¿0eŒisÜ>¿Z›¾lÀ3ÆaŒåmÛVB.„È%‰á……¦”Ò_~–þW0´øþÓ38ç|E)õÛB¡¥þŸ~«õÉ6øà|IEND®B`‚routino-3.0/web/www/routino/icons/marker-19-grey.png 644 233 144 2564 12573351600 15631 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“)IDATHÇ}•MhTYÇÿç¼û>òüâYêˆZQèŒbƒíBÛή!½•éEƒô4Cƒ65Mm†Y8nzÛË!%D'ˆX.¦&Fm’{•r*1±b¨êH©ïãÞ3‹N½IÒ2x¼{/÷ý9÷wÎ= …VÅJ) S,?‘¿Äq|4 C@øŸÄu]²mûG"úºP(ü£X,r’$`€VM-Ñ"òÛ¶oFQôiÇe³Y0sêhŒÁÜܚͦضMŽãŒÄqü%½$" €VXD4€œRªÒn·s™L&9sæ çóyr]†!fff¤R©èåååO}ßÿ­ÖúŒˆü›ˆØ:qâ„Ø§”úWE¹žžžxxxØîîî&˲ "¿z”RسgËd2fhhÈî|Ô1è¼×®33”R0Ɔ††ìL&c¢(ú,Š¢XD¾ã§NB0ƤQµZ-Ôëõu†KKKxòä êõ:˜ZkA€ÁÁAÄq ùV%IòAÒ××ÇÒI’`ttD„Ë—/ƒˆ0==R©„Í›7ãõë×Àùóç}}}<>>.ívûÃP²Ù,uuuAk ¨Õj¸qãjµ¶lÙH’wïÞÅÀÀ®]»†+W®àñãÇh4ß÷‘Íf) Cá_‚ãuüöïß«W¯¢··oß¾Më3IAغu+â8ÆââbÊ|Õ‡•eYfee…ã8†mÛ×uÁ̰m;Þq?~cccxþü9^¾|‰0 ×%²Ýnƒ™ {ž§kµš™žžN#zŸD§OŸÆÅ‹ADèïïǶmÛÒ@fgg1;;+žçið'¥W*•¤Ùl‚™!")޵hJ¥šÍ&†‡‡Ó“är9h­qÿþ}M¿è{Þ½{÷ŸÇùÛòò²ºsçN²ñ:¾{÷.;v ¸~ý:>|ˆ .Àu]Œ™/^XŽãLÇqü•uäÈc~ðEµZ…ïû0Æ|¡”zS.—-²–»µvò>¾®ë~Òh42­VK¦¦¦t»Ý¶lÛþ Àˆˆ¤×…õ©°æ—­$"rŠ™ÇÃ0ÔJ)K)UÉçó>{öŒµÖf£áºã¿C‡ïCùÚó<˲¬y­õç“““i÷zŸþ ö+¢WÁMIEND®B`‚routino-3.0/web/www/routino/icons/marker-68-grey.png 644 233 144 2723 12573351601 15633 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“ˆIDATHÇm•MhTëÆŸ÷+çÌP†ÑˆcdŒL²‰vB¹D¢xÅ;ˆ”k xÅ뢳hnj)w‘0…ÁM7uÓmB ¬uaF¤%AR‘ª“qШè@Šã$™/=š÷œó¾of¦ñãçë}øŸßÿž—d³YlˆrΑÍfu.—ûÖó'ß÷‡¥”Áÿe,Ë"BˆÿB~Êf³ÿÈår4Ð@6L™1Fcv!.{ž÷ƒïû&‰x<Ji×QkJ¥‚F£a„¤§§gÒ÷ýßBÞBÅPcŒÐÏ9/¸®ÛFƒcÇŽÑd2I,ËÂç’R¢T*™B¡ ÖÖÖ~pçJ©cƘ—„Ê>lôqÎÿåy^"‘ðÏ;'öîÝKc0Æ|qp΋ÅȾ}ûh­VóWWW£Bˆ_j­ÿfŒi±t: yÿþýH"‘ð3™Œ°mZëne”RB@ÈG´Æ(¥à8†‡‡Ù«W¯üjµµm{{(ú;õ<ï;Ïó~ŒF£úôéÓ¢Ã1J)(¥0ÆtÍ! ”‚sÞ½?::*¢Ñ¨ö<ïGÏó¾cGŽ™Rö¥Ói“H$ˆR Œ1Ôëu”Ëe¸®‹H$Ò­teeOŸ>E«ÕB$„B!!L©T"BˆÁ7‘HÄìß¿Ÿc µZ W®\çyp]ÉdgÏžÅââ"¦¦¦`Û6¤”سgΟ?J)’É$™™1®ë~C¥”&“P(¥ ŸÏ#‹all ™LÕjRJÜ»w½½½Ã… P.—±´´pñxœH) ÿ؇sÈÃúú:ªÕ*Âá0.]º„P(„ãÇò,¤R)ܼyh6›Dÿ' @)cL·Ûmø¾ß}èû>¤”8yò$vìØ©©)|øðívZkH)áyÖÖÖ ¥ì®s]”RMmÛV/^¼ÐÅb@1###H¥Rc Åb H§ÓÈd2¸xñ"ÇÁ;wÏž=ÃóçÏmÛŠø#çœ … ^¯Ã²,Äb1¯Ëå2³m»èûþ¯Èøø8ìBÌ¿{÷nÏÑ£Gu:¦õz•J½½½ØµkWwð[­^¾| Çq088ˆb±h&&&H8þ µþ¹1¦Ì)¥ÀµÖ¿vgf~~Þôõõahh¨;ôCc ¶nÝŠ€‚v»éééÀ²,`œRÀ)€€ „ÌRJ/BØôô´ßh4@ÖºûÏwŒ;¹Ïçƒf³)zzz® ýt‚Ò'„Ѓ^¶,ëj£Ñ7nÜ:F›eŒc wïÞÕ÷ïßçápxÙó¼?|ØÍÞ¯éˆ(ÏšþÓáIEND®B`‚routino-3.0/web/www/routino/icons/limit-18.4.png 644 233 144 1407 12573351604 14662 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“¼IDAT8Ë­”¿K[QÇ¿ï¥Äø¤­F« ‚кq¨âª:Åà œâ øO¤»[Zœ‹7!*¢(„B¤lB-6h|÷ÞO‡—¤J;zàÂ9÷Þs8?¾ß#$! ß÷‘|$‘H¼BZÁóéì„dÒÒÙ žwˆ´Òx’ßðjJ$<$¹¹R– øM&Ž‹ ¨Váâ"²3‚ßHÙÆ¯á/û´µ‰ÁÁ—HEÒi(•,`pÎr_"ÛP*YÒiŠ ¾¤­MÄã¾èë33Ò KKuÀ††àÜßÓ¼ÔYZé„™™€¾¾F™ÒfgîL½Ž°Ö†!Ö>Lc°aˆ;fgAúÐìÙk‚àÅ"œkrÎ᜻WáCÝexz Að éµVX\ÄØÞÞæìì €ýý}²Ù,GGG­ Í,‹Å"_¿|0.“iEH{äóös>O,css“B¡@WWóóó P(Z¥[kâm*`ͧO íùzöì&'å$ß‹ÅÔÓÓ#IrΩ½½]SSSêïïW­V“$ù¾¯ååeÝÞÞªûÅ Iò™˜ž?ã+Cñ¸œ¤¹÷ï5<<¬ëëkU«Uõöö*—ËéòòRÉdR’´ººªµµ5¥R)íîîêÛ÷ïzòô©œ„/ç<ÝÝ©)ÖZ% ­¯¯k||\[[[êèèÐÎÎŽ¬µ²ÖjttT*•J:>>–êÖxÔ}öˆ›ö«“ça)ÊIEND®B`‚routino-3.0/web/www/routino/icons/marker-55-red.png 644 233 144 2100 12573351600 15417 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“õIDATHÇ•UAhSY=ïý÷’]”ì"¿Té hKWnZƒEÉNh»pöÝ5ÂÀè¾âfºÒRÌ€Š% Aq3"ÎìºK颈HRhP˜ÚZƒ¦‘ÿÿ{gÿý6IgèÌ…Ï%‡ÿο÷¼{O€Ã===ÒéôE­õ*°.³ý·Öz5N_wN&DÂe€Яµ^ˆ¢hš$ûúúÄØØ´Ö°ÖBJ‰0 ±²²‚ÝÝ] !„Rª†á€¿Úx¾pÆó¼ær¹piiÉ4 ZkÙÖZ6 .--™\. ;w&é8©Ø÷ÐB(¥æœ¾‡¦Ò½²QDãævzz:tÞZ„çyí¡”’ÃÃÃÐZWœ¹Äú&Õ&ûî>²°°`aýÀÚl]€¯µ®`©TŠõu•%moll0“É”RNu·ÝGõ­T:*l6› Õý*„c¢C_ß÷ƒÄI²T*%moÈÌÎζÿ-ý{të;>>’d¥R‰ CJ !.¸×½c »õUJÕpffÆŽŽŽ&m—\Ûê¿vè `BA‘«ð¡¡!(¥äÿ%<Ð×åŸ=Ï£”²à‡®nŽÄßxØg£EÑÛ¯IEND®B`‚routino-3.0/web/www/routino/icons/limit-27.png 644 233 144 1304 12573351601 14511 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“yIDAT8Ë­”=K#Q†ßA“A‰1  ¸•Á6¬ƒElô¤µXØFPPlRXXi¥X[´$ ÑRc@ƒÈ€„Ä™{Ÿ-f¢ÝÎîÇ{>ï{Ž„$\×Er‘D"ñ ©„ã\08CC†ÁApœ ¤Rü.$7ÖêJ$$‡¹¹Ò:ž÷Êò2Zêux~†z=://ƒç½"­Çx'Ö—èíuéëccãH·äópwg€k Ÿ%:‡ÜÝòyn§¯OôöºbdDÌÎzHUŠE€6` °öcuîÀmŠEªÌÎzŒŒÄiJ o„!„!Æ‚·7Œ1Xk ‚à}Ù €0Œð…HšMày>77‘ÇXÙZgö±ï’Șåæ<ÏGšèù#ýÕââo-,…¡‹ëÊq]^^jooO™LF­VK»»»º¾¾ÖÕÕ•úûû•ÎdD8Îð°Ñý}Rçç=B:gÀ˜v€³³3Èård³Y¶¶¶˜™™azzÇq8>>Ž‚‹ð†ý}ÎE*eyxˆ£ârppÀêê*“““ììì°½½ÍÒÒ‘g} ÀäRV¤Ó†F£óõ899ajjŠùùyžžžÈf³T«Õ¯Æ H§MWd&ެR©L&Y[[ãåå€ÍÍMr¹\\ûðÝùçÈ\ù~Eå²$YkŒ$éôôTaêèèH£££*—˪T*Êçóêk%ɪ\–|¿"¤++aLHšÍ&Ôj5jµ­V ß÷i6›Ýôˆð!++ •¾ò¬“Â7ÒÅ·oxößèõ3y» }Û?Ú›?:5~tžýà¤ý«ËÊäÙÔ IEND®B`‚routino-3.0/web/www/routino/icons/marker-61-red.png 644 233 144 2053 12573351601 15424 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“àIDATHÇ••ÁkSYÆ¿{ß½I®Rt„¼P¤³j)‚kccl¥ B7c7uÝ]ƒ Ìß L7Áq\HÇü"2ÅMº¤+›ÉjJJ‰ÐNúÞ»÷›Å½¯ISg<ÞMòîïžï{眃ccc²ÙìœÖzXçðg­õv6›¿O¦ áïà­õZ’$Ir||\ܼyZkXk!¥DÇØÚÚÂÁÁ…B)ÕŒãxÀ_CœÓ®AÐÀB¡7 Óëõh­åpXkÙëõØh4L¡PˆÐï»–*N3ƒ ØÀR©µZ-’¤1†qŸ»Œ1$ÉV«ÅR©yð€Ða¥„RêV*•ˆ$µŒNNh£ˆLކMFý>WQ©T"TJ½’R™LfÃ04ív›$G9,{xmŒ»HÆqL’l·Û ÃÐ`&“Y€Rê#ÖëuC’ñɉۼ»K>N¾yCúÍ)Œ­ùþý ’õzÝøl?€Íçó¶Ûíº¤HòógòêUòÒ% ÛTöÎÎs¹œ@)åO£²Gã¼¿Íæ™ }ùÄ~xü*„ïÄÃ0ŒÒ‘H’µZ-•½ ·²²2ü·ôï1êïììlL’Íf“Œ”’BˆÛþñà»ÀQ•Rm\ZZ²333©ìš—­þ+ðŒ¿ÊBH|†LNNB)%ÿ/ðÔ_ÿ9J);~Qs.þYË—5âÀ_IEND®B`‚routino-3.0/web/www/routino/icons/limit-43.png 644 233 144 1237 12573351602 14515 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“TIDAT8Ë­”?K+AÅÏ.$¬E6ZD‰$•e>A@,%$íl“°°²7}:±J§ÁÒʤ| ) "ˆl²3¿Wì&æéóUX¸3{ÎÜ?sî’„ëºH.’H¥ Hmç߇õuƒïƒãÜ#µãÿBrcžÐü¢TÊAr8¤Ñ©-¤.€! QcÈçó0ð}Ÿ££#¶¶¶¸½½0Añ:º¿”NU*I’+Ç‘ã8’¤““A  ctvv¦íím=>>*)ÒfÄ+•¤tº(2Ãh@§yyyÉææ&ÇÇÇ žžžøøø Z­²³³C¯×‹"‹ëËh™Œqe­£éTËËu]‹Eu»]M&žžj_×××Z[[S¯×“$Yk#Ât*Yë|«À,Žðââ‚jµ ÀÞÞ¾ïS«ÕÇÑ#D¸EÍ~|Mc ïïï¼½½-¼¼¼,Ňß^óŸ:ûª«¹\Œ1ÿÕÙðU° ûÇXio®tj¬tž­pÒþ®g¹ê9¼n>IEND®B`‚routino-3.0/web/www/routino/icons/limit-32.0.png 644 233 144 1535 12573351605 14655 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”OK›YÆŸ¼JâÄøgl™ ™k+´j þY¸(~€ |ëÖt£ 7‚_`ݵݸÐ --X‹KW݆j ¬Y•ˆÉÐV36yß{]$Nµk\¸çÞ{ι÷ò{Ž„$ÇArD[Ûm¤UwtwCO¡»wH«Í}!9Í8¡‹Dmm¤µ!=!>cf^¼°A¥GG fÂá3¤'Íóf¼D0è ‰D¢é#é4‹ð±ÖpÙ¾O±hH§AúH"ÑO($‚AGD£"“ #}`a X<<¬ý>.ÖÀ5@ú@&&m>SzÊä$ê^­†©×0ÆàyÆ\½ ©×ñj5,Ô™œééÅŸÝ#þl÷ö›—Xk±Ö^ƒk÷ö þŒt¯åi‘ÇÇÙ¬ùçý{篵5…‚AÅb1íîî*—Ë)‰(Ê#Çq´¿¿¯¿s9EoÜü<0`( äó-2Rž—/Ù¯TLOW®ë200Àòò2½½½LLLH$Èçó”J%R©CCCܽs‡ÁðìFÊ;êèx ‡åúäü¹¸¨©©)Åãq ÍÏÏk{{[‘HDù|^’´¹¹©P(¤utui3—s”N˶·?huZ[‘µ»ýýú5›Õt6«B¡ ••Õëu%“I kzzZ’(‰H’::;õ_µ*…B’ã ¯½Ýr~ÎÚóç¤îß`dd„¹¹9âñ8KKKœžžR­V)—Ëlmm‘L&)‹Ü¾u‹í7oàËüHÄ:-Õê[½z¥ß\×þró¦:;;•J¥‹Åtrr¢ õõõi}}]®ëjttTcccÔ&ÆÇ­^¿–svöVH«ÌÎøÞׯãû>ççç”J%8<<¤Z­R©T0Æ`Œ¡\.cj5ŸÙYV¯pfšœcþçêG³Ö64ógßàºuëyàûW½ ,¾mȪŽë^RÀµjóZ»Æµö³kì´ß† d£SAKrIEND®B`‚routino-3.0/web/www/routino/icons/limit-14.5.png 644 233 144 1366 12573351604 14663 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“«IDAT8Ë­”¿K[QÇ¿ï’ð5lbu'„Nqí# …¨ ®‚ÿ„ŽR¡Cœ´Hu:\íP0èÁª¡J%y?îýtHòj¥£.—sïýž{ï÷|Ï’„ëºH.’Èd†Öqœod³ðü¹!›Çù†´ÞÙ’ÛÁ ue2’Û7¤<ï7óó°»k¹º‚Ÿ?áêªíÏσçýFZéœw:x‰TÊ%/ªø>Ôjˆ±ÖðÐÚ~L­fð}ª ¼ ©”+òyQ,zHßYZKAµGw ,°´ÒwŠE|¾óMi•™€0L€1†8Žÿy`DaH!¥H«]ÎFð¼_T«Ä`íƒ@ÖZ¬µü׌i¿ðì <ïÒˆÖYXÀB pppÀÅÅE‚©V«ìïï'~†ììì°¶¶ÆÇ¸ƒ˜ÅE¬´.¤c¶¶ÌöÖ©TŠÍÍM‚ `xx˜©©©$Øõõ5…BééiÞ½}ËVËðù3F:vÕÓ3¦W¯d%×yöL¹\N€$iyyY­VKýýýêÚÑÑ‘îîîèµï«N»¼|)··wLôõêuºLMNN²½½ÍÞÞ¹\Žr¹ÌÐÐçççti˜››£R©PÈçùòõ+qOqe­£0Ln¶ÖÊ#×u5>>®““]^^êôôTÍfSµZMƒƒƒšU¡PÐíí­d­0ÆI8‹Àø¾ÏÆÆFÂQ¥R¡T*a­ebb‚ÃÃCFGGÉööò¾\&çOXé8É&c Fƒf³™hìþþžF£1†z½ž$æææ†mÜÂt²ÙÖÙÙY[7úØíƒkéìŸ °QÄã€]á&sÓwÈÌ̃ xÒÚ|Ò®ñ¤ýì ;í¯®µ4­uÒµIEND®B`‚routino-3.0/web/www/routino/icons/limit-0.5.png 644 233 144 1362 12573351603 14571 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“§IDAT8Ë­”±K_Ç¿»ÊÞe¹Ã½¸íùÅ`¡)%‚¥•¢`@Œ¦ÐV°² ¤Lzÿ­ZXÛV‚¦+=ñôÎ+"Ù{ûÞ'Åíú‹ÄÒ)æ½™/3_¾3B’ð}ÉGÅâ+¤ <ï;QÏŸ[¢<ï;ÒFö/$?«ÊŠEÉãýû"ÒÂð7ËËðí›ãòÚm¸¼ìÆËˆ¿‘¾dù^V/>…‚¨Õ^"ýdj ÎÏ-âœåoëÆ)çç–©)~R«½¤PAà‹jULO‡H?X[H‡1` 8÷¿çoà€„µ5~0=R­fcJ_™è¦ØNc ιcºž$¸.h‡ÙY¾æœ½! qrÒ$MïAœsÿÞ[šv;<90ü…ô¦ç“ôY?¾Ó‡c|¯·W§§§ÚÚÚRµZU¥R‘$c´½½­½½=ë¿×¯U/¬W¯?ÓáaÙÜÄh6›ŒŒŒ0<<Ìàà ív€F£AÇÌÌÌ0??O£Ñ #ϲ¹ Ò¡¯¾¾·—•|IÚÝÝU¡PÐÑÑ‘Êå²vvv$Iº½½ ÉÉIÅq,¬•'ù—úúÞöÊ÷QxÊÌ£R©$I*—˺»»“$U*ÍÍÍillL«««Š¢H²’z‚@ò}|9ç©ÓQŽV«Õtuu¥z½®³³3 (I]\\¨¿¿_KKKŠãXÍfS¹èÕéHÎy÷œ6Ó ”J%Ö××iµZŒŽŽ²¿¿ÏÐÐQ±¸¸Hš¦¦8Ò++if­åææk-ÖZZ­I’p}}µ6^·ne¤Gu–'[kÕœµ÷ˆÎÝþnô0Ëùwžt7Ÿôj<é={ÂKû—"h£Z8IEND®B`‚routino-3.0/web/www/routino/icons/marker-60-red.png 644 233 144 2106 12573351601 15422 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“ûIDATHÇ•UÏO“Y=ï}ïVŒǤ_5†YAˆ—ü²1Æ…v£‹Äàš]˜ÌÖ…;† +â ö?0j˜&ÄÈbbp´$ ‹QXÔ¾×÷Î,ÞûJ)™8s“æ¶7½ç»÷ôžSà(dGG‡€öööëZëàBfóg­õJ{{ûu}2!G,€Ÿ´ÖÓõz}”$»»»ÅÀÀ´ÖpÎAJ c –––°»»K!„PJ•1“þjÂi<árEUÌf³¦T*ÙZ­Fç›Ã9ÇZ­ÆR©d³Ù¬ÀÐw9Ý88Ž¢h“J¥B’´ÖÒsâe­%IV*&x@ìa¥„Rêæóù„$­sLé’„¬×MJké’„ÉÁA<ŸÏ'¨”z!¥ÚÚÚn`ǶZ­’$M’Ík‡fZ{¬n’„$Y­VDZÀ¶¶¶›PJ-àÌÌŒ%Isxè;66ȧOÉW¯HcŽðé97G.-ž™™±aÚep]]]nggÇÿ$ùñ#yáÙÙId¡à_¿&£ˆ7ç77™²^(ÀJRk xB€Z XYÖ×L¸˜šΞ»wý½ >//7Ôp¤à¶··ñ÷þ>T <øãÇÀ•+Àø8°¶h tvz¥|N’†‚¾~ý RÊ€öÌÿý;ÙÑAÎΦd‘J‘óód“SS¾þù3 °^.“$ÿxó†œ"AE¿`.—3•õu9CCä­[¾ùÉÏÝÚyçyõª¯?zDwêùå ÷Œa_oo=ˆ`™LZëß0?2bH²þîyú´ÈbÑ}ø@ž9Cž?OJIûð!IrüÞ=ÿI9Îj­7°89iI2ÙØ Ÿ?'ß¿OEïóÖY*Ñ„;]XXpp_Ñ›*B\“R@½üò¥ç7•hª(çHçhö·¶˜ËåRí›ñ@ ! ”šÀ\™JPL³dÓÚèè¨ ÞZ¾té¢(j8T¸%{{{¡µ.sñü¶Š ’žž¶p»áNM¶‡–B¬µ®`±Xôü†ÉRWZ]]e&“±(¥ü¥uíÖ8Éo¸Ãt½½=öõõ™`¿ !@ãqŒß8Ž“ÔI²X,¦k¯ÈLLL4ÿ-ý{´ò;<Øv\_{¦§Aº »»‡ÖV‘J…¢£CÌÌDHg¬¬¼F£˜}|Í90à•Θ™‰èèHÒ” ÌÏÔqœÃ{O£ÑÀûøpMÛÌÀ{p.öŸŸ©Ð¼³¢¨J¹ïè=f%Ã'sq¦ö!F¹ QTEÒ&ËËŽæÎÀÉÉ ëëë”J%ÎÏÏÙØØàòòò]4IÙ±¼ Ò¦ŽØÞŽðöÀáá!™L†ÉÉIz{{ÙÛÛcdd„¡¡!r¹ÏÏϱ`,æÙÞéHd³F¥€‹)‹¬®®066Æèè(ù|€ááa¶¶¶bÿz=¾‡J²Yû£0D©T I---23ÍÍÍ©³³SƒƒƒÊçóêëëS±X”$e2Õj55•$¥RRÊ,P½.I2J¥’¦¦¦´¸¸¨B¡ ®®.ÝßßëææFWWWÊår’¤ b±z]2 BU«ÇÚß—$3ï%IrÎiwwWÙlVÎ9MLL¨¿¿_³³³—$µÄR¦ý}©Z=þöšµZ‡‡noo©T*¼¾¾bf<>>¾süøš_9‹aü¯Šì ¼Mh¿qöc4áü ïûâó½~µ6µküj?ûÅNûxÑ”P±ùâÖIEND®B`‚routino-3.0/web/www/routino/icons/limit-26.0.png 644 233 144 1522 12573351605 14654 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“IDAT8Ë­”ÏK\IÇ¿¯ÅyúFã€2^„˜°f.ô #¬fÐK“‹xH ˜Ü–à?°°'I<{ÕSDÈA6Þô¸Q²`˜(莃0bB&Áyoº?{pœÕ=ÛPtUuUÓÕ|ª„$$aŒA2H¢¡¡iÏûHk+´·[Z[Áó>"-VÏ…dªyB—54xHOž4 ½&JÌλwŽ“øòNN.ìÙY‚Òëj¼WÍ—ˆÅ ¾/º»ï }&›…|Þœ³\]v…|Þ’Í‚ô™îî;ø¾ˆÅŒèì““ÒsseÀEEàÜré”™›iÉÉ€ÎÎj™Ò¦¦°Få26 °ÖEÖ^  C¢r!SS ½¹ü³ûÁW—ËáÀQM´Ö✻R¡«íÎ9°Îår_‘î×ý&ýγgÃÞÓ§ö¯óvuUJ$:88ÐÒÒRͶÖÊ£ýý}½]YQçíÛ^Û½{–|¾ÑÛÞ®SEÚfm­ý}ÛŒÑÓÓÃææ&™L†ññqÒé4‡‡‡‹Eúûûéëë£÷î]þËê*VÚ6jjz ‡•ÿôÉüúê•666”H$4??¯B¡ öövŒŒ¨­­M’´¾¾.ß÷µ»»«æ–ý±²b”ÍÊÅãL]}=®TÒÔ£Gš˜˜P2™Ôàà ¦§§eŒÑè訖——µµµ%I ÃPMMM’¤æ[·ôãûwÉ÷%c0.Š<‹igoO™LF333ZXXP<W<×óçÏÕÑÑ¡££#êêêR±XÔññ±þ>:ÒO½½Ò·oòÀ3¶TÚчúsw×UÂPkkkjiiQ}}½äû¾R©”²Ù¬R©”Òé´†††”L&õËä¤~vzÿ^¦TÚÒ"/_ò*ÅBBUÎÏϱÖrzzZÃäìì k-ÖÚ ½\¨ðâH‹5ÎÈå.È®r末Áz•¹šßZìÿ8»ÖBE¸‹–¹ë5½R¹Œ yüøJÜhoÞèÔ¸Ñyvƒ“ö_2AK#·ha­IEND®B`‚routino-3.0/web/www/routino/icons/limit-3.5.png 644 233 144 1370 12573351603 14573 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“­IDAT8Ë­”±K[Æ¿™•ÙÍX̰ÝBLà-Á*õ[±ÓJQ0¢X¬¦ÐVðxøÊ¤··ØnÁÿÀB A,L1L£•U"dIáî{)v7‰ÑÒ ι÷;‡{>¾s„$$áû>’$ …×H»xÞ'âŠEKƒç}BÚí½ Éïå õ  ’Ç»w¤„á66 ^w4ðí4ÝxcÂðÒ‡ÞëåKO>/ÆÆ^!}an®®,áœåÏÓ3®®,ss }alìù¼_ ‹ùùé3ÛÛmÀa Îý¶þ8 Íö6HŸ™Ÿîµ)}dq C–a;Œ1XûðcƘ®µÛ¸nÑ‹‹ }ìsö†0üÎÅE·‘,û«3Ç“§‹s\\@~Gz“ûOú_ïßÿ«jÕbŒï èüü\{{{Êçó•$c´¿¿¯ƒƒéŸrYù ðxùÒz_¿¾ÐéiNH§ÔjX°išR,YZZ¢T*qtt@£Ñ IX]]åúúšy–Z ¤ÓEÑ[MMI’/IY–iggG###JÓT÷÷÷’¤ããcµZ-šU’$ÂZy¹œ¯©))ŠÞÈ÷Qx¾$Êå²J¥’ªÕªîîîE‘$ihhHËË˪T*ÚÚÚRÇš™™‘•” É÷ñ圧NGV’cs¤ÝÇ:ûC¬ÖÚ_:{ä?¡³''€,{ Ö¾ïœëú=Ìã xÖÙ|Ö­ñ¬ûì7íO¶ci^b;EIEND®B`‚routino-3.0/web/www/routino/icons/limit-52.png 644 233 144 1366 12573351602 14520 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“«IDAT8Ë­”½KœY‡Ÿ÷5Œî(*a,„‘¬MP„@À"……•Í ``Àb0ňµÿÀ–Igá? v¿JAìld$E@K£¢BŠ‘àǼóÞg‹wÜ]v+¸çÞßùºüÎA@À8Ž…XÀ®®ß…£è‹ýýZ(¤ö÷k}VÚïqÛy ÔÕ ‘ïßw ÍçX«éçÏÁ‹ ýþ]/.2»VÓ|þ‡ð±Úþ`.ÛÙ‰¥Ò+áÄrYOOSµe©ÿ–ÌnyzšZ.+œX*½²³s¹‹EœžÎ _]ZR}PƒI¢I¢!ü£wÔ—–¾:=·Xl· ŸœUmÚji«e’$«jš¦&Ibš¦>bÔ¦³³ Ÿÿìµù|Ããã,cú©»`áé9M3üñ±æó áuÇð'>¼£ZMiµb^¼ I666ØÛÛãèèˆÑÑQNNNX[[£§§‡b±ˆ@”¦/_¦|ûö‡‡‡®¯«¦¡ÙTõêêÊËå²µZÍ­­- …‚“““–J%ëõzÖúÃjêúºÂaL_ß&&â@&ÜÜÜ 233CE,..²»»KOOõz€E1Ð×÷&&Ž%— Ê) T*fff¨V«twwS©TáíÛ·T«U:::²ì¹ı1!D4›<àüüœ¡¡!æççfgg‡©©)æææX^^&„ð$9Í&„Å4uö÷³ªÍ±ººJoo/ããã q}}Íææ&ƒƒƒloofEö÷¡Ñ¨#¬¸° ÚjRÕûû{¯®® !x{{ëåå¥gggžŸŸ{ww—2|Ë……•_y–¦Ox•¶í_$ããžýç„6A&ná&àYgóY·Æ³î³gÜ´ð?ÝzOIEND®B`‚routino-3.0/web/www/routino/icons/marker-25-red.png 644 233 144 2202 12573351600 15417 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“7IDATHÇ•UÏkI}U]5‘0÷0=FÍ.˜ApQ\‡ !W7þÚ£èÍöÝÜ”"(Á¹ÍaEØ=™ƒ QŸ€ðœÌ€DÈ à­õxš¦c$ÙÓÓ#††† µ†sRJc0;;‹wïÞQ!”RucÌEuà´ß°3Š¢&–J%311aWWWéœcg8縺ºÊ‰‰ [*• †çvfŒ³Žã(Š^`¥RIIÒZKcÌ?k-I²Ñh°R©$ø€ØÃJ ¥Ôm¬V«I–|þL—$dšv¶IC—$LÖ×iÃÕj5@¥Ôm)%ËåF0ŽcÛl6I’¦ÕÚ@™ÖzÀMaBÇÍf“q[Ìår#‘bÊ9_¾|™GŽ©1P¹0?ÌÌKK@o/ ðæ pïðü9ðìäÂÒ;гmò¹»_!¾W,ÝÊÊŠgH’SS$@‹>ŒøÖnÜð÷]]>wwÓ}ø@’\Y^f±Xtaä`GGGI’i Ã¾>òôiýø±xøÐ×$×ÖÈ÷ï½$Ö2 ÚŽŽŽ€•¤Ö@!€$†‡sçü\äó>[ }jÏ!I²Õ"¯^%s9òÌ_&'ïÞ%#… _¾dàÇJ¥BRÊ€œœô'J’ d?¹};yó¦?}cÈÅE2¼œ?’B0½u‹$ùǃà„ ¢(úËå²iýäÀùö­X_'—–È­[É+W|íúu:!ȹ9®‘ìïOÃÜ@¡P€Öz «G./3ݲ…Œ"2Ÿ÷ §§Ék×üu¨ÙK—H’?=kà3…ÌPJZëYcÌŽÚùóîÚ‰Ò¼xá…" ÕªU`×.àÉàéS¤{÷BíÛ‡;wîðÔ©S"Š¢uçÜ÷$ÿBÊÃRBÊ´>3ãõí\Ñl³Â“äëÅE–Ëål÷k¡A•ŠB@)uË¥RÒXXð­–?¤l*Ò”6IH’ccc&xk½··QµÊÃ+% µ®s1cc·Æ’äøø¸ €¯ÛîÔa{ØTˆµÖM¬Õj–$“ÐYF{~~ž…BÁ ”òÇÍ´7‡×WˆÃRJHëõú†×ÖÖ888h‚Õý*„ÿˆ úÆqœd–H’µZ-£= páÂ…ÎÏÒ¿Çf}:dH²^¯{Ã’BˆÃß·¯Š¶¾J©&žQ*å‹)ÁyÞ/­¬HŸ?[œH?J''ÝzeEò¼_‚½~§‡¹®Ñà ÊfŸ ¾iaA:>Ž%E²6ÖíèÖ‘Žc-,HðMÙìS "×5(Ðâ¢'¨kmM’Ú’¬ÂP CÉÚÙß“¬¤¶ÖÖ$¨kqÑSôž U(HRGQ¤¨Ý–µVÖZ…aø7û{ß¿w:ÝþBA‚ý?{.ÏkêèH’lŸè¾è“I’¢HV²::’<¯)xžxïyûö%oÞÄ Cc\—J¥B2™äòò’­­-êõ:‡‡‡¤ÓiZ­›››<ò}ÆÆÆ¥Ó±Óh<âà à@Ÿ>IR¬8Öî„öööT«Õ433£¹¹9%“Iíìì(ŸÏk~~^³³³úñý»$Ŷ\–à`€ááärÆJ8ŽC´Z-&''©V«lll0==ïûìïï“ÏçÉf³Œ>y`Èå`xø…ÁáºXk)‹LLLpuuÀéé)¥R‰õõuÚí6£££är9¶··©V«]ÜÀ#ƒµ·ÃZKÇ”Ëe2™ Aà8CCC,//“Édh4¨ÓkC³ù•JÀb-¾ïãön[©T( ,--1>>ŽïûLMMñúÕ+›øòšÍ¯JZ]•¤¨'H]\\èææF’t~~®ëëë¿òˆ¢HgggŠ¢HŠ¢.nuU‚Òõîè«¿Æq×aqÞÑÙ½°·ï°ýg«ÿð Þ|Щñ óì'íùBh¤8IEND®B`‚routino-3.0/web/www/routino/icons/limit-19.0.png 644 233 144 1432 12573351604 14655 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“ÏIDAT8Ë­”ßJ[YÆ¿³Õ$žª5ñFˆt cD0¹ŒPŠWz2TûB|£½ ^øÒŠèô‚W¥±…ˆ0­B4`C­ùsÎÞ¿¹È‰¶ÌÌ6¬µöþ¾ýg}k IHƒdD"ñÒ6ž÷‰ÑQxôÈ2: ž÷ i;Z’‰pB=¢DÂCòX[K ½Ä÷¯)áÝ;G­ß¾A­Öõ‹Eðýk¤—Ñ~/ÂKÄb†x\¤R‘ŽÉçáôÔ!ÎY~]?äôԒσtL*õ˜x\ÄbFLLˆBÁGúÌæ&@p8w7{1p@›ÍM>S(øLLDÏ”^±º Ð Ûml€µ– °ö× ÚN‡ ÝÆA‡çÏAzÕû³4¾ßàø˜œ‹ˆœs8çþß¶ÎU«àû ¤´¶ÙØÀAP.—999 R©P*•ný0 ¨V«lmmñW7ºb¤m!}`gÀ¾ÙÙ¡¿¿ŸÝÝ]jµSSSär92™ õz€z½N&“annŽé'Oø,oßb¥F##Y=}*'¯¯OcccÔáá¡ÆÇÇupp X,¦½½=IÒþþ¾âñ¸*•І>ÔŸ¯_åórdúúP,&'iíÅ ÍÎÎêââB+++º¹¹Ñòò²ŽŽŽ400 I ÃPCCC’¤á‘Ýüø!Åã’19ç©ÓQo8çdŒQ³ÙT:ÖÒÒ’’ɤR©”Z­–&''U¯×uvv¦¯_¾è÷éiéûwyà5U.K’“¤áèÔd2©F£¡R©¤õõue³Y-,,hqqQóó󚙙х‚žårNïßË\_¼Í&b-WWW4›MZ­ççç8ç°Öryy‰µöÎn·»¸ÛlvuV­v•¥¿GÐï]EEqk±ÿ¡³_*À=Âø_v‰»ÃêêOp¯µy¯]ã^ûÙ=vÚ{hâQÃ8IEND®B`‚routino-3.0/web/www/routino/icons/limit-36.1.png 644 233 144 1460 12573351606 14660 0‰PNG  IHDRrP6ÌbKGDÿÿÿ ½§“åIDAT8Ë­”ÏK[[Ç?÷¯É¥E£Ñ\|P^qU¸h%à& ©MÖµ›øø<žËvïV- mÁê?P^W‚ZèÚEÈBPü‘PëkrÏ9ß·HLm»õÀ3sÎÌ™>3 ß÷¾ÅãÖäy52"ŽZŒHž÷Q°Ö»Gà÷ì׎âqOà©TŠ ž+ /U.K¯_;IggÒÑQW.—¥0¼<ï½÷zö  ð54„²Ù)Á-,H†•däœÕÍÕ• «… ¾(›ÒÐ ¥Óhq1|ÖÊŠ$µ%9E‘E’s?öµNr’ÚZY‘à³C¥Ó½4á…ž<‘•:Q»-ÛéH’¬µŠ¢HÖþ Œ‘‰"Y©£bQ‚×5»¯0l¹ƒƒî=Ck­œs72t7|9cºï¤0l îü«zöì¡·´dÿýôÉ߬T‚€ÉÉIjµëëë$ 2™ ’ð}Ÿ޿ǶÛ^òÞ=«F#áíï`a_oÞèðìÌŽ«T*)›ÍjwwW…BA…BA³³³ª×ëýȶ¶¶ª››’d£—/%Øq÷îòyL³éÿ½ºÊx:Íùù9;;;Ôj5fffÈårŒ`­Åó&§§§}æšÍ¦þûúU’Œ–—%Xû‰3ÛãÌ:'kmßðWæzÊß8ûÑÅ¢$u\I] ƒµ6F®ý/p«½y«SãVçÙ-NÚÿAŸK öÖºIEND®B`‚routino-3.0/web/www/routino/icons/marker-96-grey.png 644 233 144 2725 12573351601 15636 0‰PNG  IHDRÞÕeíbKGDÿÿÿ ½§“ŠIDATHÇu•_HU[Ç¿¿õdzÝE§Ó1ûg9…¾¤FÊpË"RºÔ• ë5¼/#qïÃ¼Ì Ã…½ÌËô2¯ó5NDêK'”`;ÅD%ZÛc¦ýg­ß<ä9×[w¾°aoØ|ÖZŸõû­E½½½ØŒPJ¡··×¦R©/™ùOa6ù¾Ï?†c±i­ÿMD?ôöö>J¥R"Š"°@›PÉ̆™÷h­oAІ!' ª®®†¢D´Öbaažç±ÖšÊÊÊúÂ0ü-åˆH0 €`fà°R*]('“Éèܹs¢¾¾žb±>ïûÈf³œN§Íëׯ;]×=iŒ9ÇÌÿ!"!Ïœ9ê”Rÿ ‚àpMMMØÕÕ¥9BRJ0ógR û÷ï§£GŠ•••pmm-©µþÚZûwfÎ˶¶6øËû÷ïÏÖÔÔ„ÝÝÝÚqXkK3B€ˆ@ôQ-3Ã×uÑÔÔ$_¾|.//'ÇÙ]^^þÁWA|›L&mGG‡.z“RB!˜¹+¢”* ÜÑÑ¡“ɤ ‚àÛ ¾’---ó}¿ª­­kjjÈ)%VWW1== °sçNÁó>Ž|>Gaß¾}¸~ý:º»»‘ËåàyÀu]TWW“ïû¬>*ú±1ˆ¢‰D°cÇ03fff°¶¶"Â7P^^ŽóçÏ#‘H ¨l“#””Ònllˆ0 !¥„ÖÍÍ͸ÿ>æçç±¼¼ ß÷aÂZ‹‹/brrwïÞÅ¡C‡Ç…BB+Ç1sss6“É”vºµµííí "œæ¯òÊ•+c>|¨ÍçóÇWVV¢¦¦&!¥ÄÐÐFFF°´´„öövTVV¢¢¢OžÆÆF Øééié8N& Ã_QOOÐZ½{÷î­­­¶­­Mär9,--áÀسg˜D„|>ùùyTTTààÁƒÈd2|ûömr]÷¿ÖÚ_2ó”B(KÖÚ_»®ûxllŒ«ªªÐÐЀÊÊJQ È̈Çã8~ü8ˆŠÊÊÊ4õÑ%D4!~GDrpp0ô<Dkm©ç‹àb{Gžçé²²²þººº?¢b†D$Nœ8q3‹õ{ž§¢"hk˜RJ<}úÔŽ«mÛ¶-Að‡‰‰‰ÒÙ Ïž=[ü™Øó/Çq¾yõêUÒckkkÉS*7!VWWqçÎÖZ€ïˆè))D*•*êB%„X´Öv»®‹ÑÑQÎf³R–4„aˆ¾¾¾(!¥¼IDýô¦F¤R)ˆâËf>óûðáÃp}}½t¥¤Ói»¸¸¨b±Ø”ïû=.\ÀV 6Åâðg~ïÝ»ÀóçÏ1::Zì®ß(¥ÞK¼Õ»Üúñs~c±Ø7+++Éõõu~öì™) Rký{}Ì\ò¸eRøéÖØre+3·!F|ß7J)©”J×××999)Œ1öSàO–ÿ3Š~Ÿ0óŽãH)å¢1æû‰‰ cðÿò?øË«¸øL`IEND®B`‚routino-3.0/web/www/routino/visualiser.html.de 644 233 144 52472 12573351574 15034 0 Routino : Visualisierung der Routing-Daten
Visualiser Router Data
Routino Ansichten This web page allows visualisation of the data that Routino uses for routing. Only data relevant for routing is displayed and some will therefore be excluded.
Anweisungen Zoom in and then use the buttons below to download the data. The server will only return data if the selected area is small enough.
Status
Keine Daten angezeigt
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ - Hilfe
Quick Start
Zoom to an area and select one of the buttons to display that type of data.
More data options can be found by expanding the details below each button.

Data Failure
If the area selected is too large (depends on the data type) then the status will say "Failed to get visualiser data" - zoom in and try again.

Router: Routino | Geodaten: | Kacheln:
routino-3.0/web/www/routino/mapprops.js 644 233 144 5720 12271223510 13521 0//////////////////////////////////////////////////////////////////////////////// /////////////////////////// Routino map properties ///////////////////////////// //////////////////////////////////////////////////////////////////////////////// var mapprops={ // contains all properties for the map to be displayed. // EDIT THIS below to change the map library (either 'openlayers' or 'leaflet'). library: "openlayers", //library: "leaflet", // EDIT THIS above to change the map library (either 'openlayers' or 'leaflet'). // EDIT THIS below to change the visible map limits westedge: -11.0, // Minimum longitude (degrees) eastedge: 2.0, // Maximum longitude (degrees) southedge: 49.5, // Minimum latitude (degrees) northedge: 61.0, // Maximum latitude (degrees) zoomout: 4, // Minimum zoom zoomin: 15, // Maximum zoom // EDIT THIS above to change the visible map limits // EDIT THIS below to change the map URL(s) and copyright notices mapdata: [ { label: "OpenStreetMap", tiles: { url: "http://${s}.tile.openstreetmap.org/${z}/${x}/${y}.png", subdomains: ["a","b","c"] }, attribution: { data_url: "http://www.openstreetmap.org/copyright", data_text: "© OpenStreetMap contributors", tile_url: "http://www.openstreetmap.org/copyright", tile_text: "© OpenStreetMap" } }, { label: "MapQuest", tiles: { url: "http://otile${s}.mqcdn.com/tiles/1.0.0/map/${z}/${x}/${y}.jpg", subdomains: ["1","2","3","4"] }, attribution: { data_url: "http://www.openstreetmap.org/copyright", data_text: "© OpenStreetMap contributors", tile_url: "http://www.mapquest.com/", tile_text: "© MapQuest " } } ], // EDIT THIS above to change the map URL(s) and copyright notices // EDIT THIS below to change the map source data editing URL (or leave blank for no link) editurl: "http://www.openstreetmap.org/edit", // EDIT THIS above to change the map source data editing URL (or leave blank for no link) // EDIT THIS below to change the map source data browsing URL (or leave blank for no link) browseurl: "http://www.openstreetmap.org/browse", // EDIT THIS above to change the map source data browsing URL (or leave blank for no link) // EDIT THIS below to change the maximum number of markers to include in the HTML maxmarkers: 9 // EDIT THIS above to change the maximum number of markers to include in the HTML }; // end of map properties routino-3.0/web/www/routino/visualiser.html.hu 644 233 144 52531 12573351575 15055 0 Routino : Útvonaltervező adatok vizuálisan
Visualiser Router Data
Routino vizualizáció This web page allows visualisation of the data that Routino uses for routing. Only data relevant for routing is displayed and some will therefore be excluded.
Útmutatók Zoom in and then use the buttons below to download the data. The server will only return data if the selected area is small enough.
Ãllapot
Nincs megjelenítendő adat
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ - Súgó
Quick Start
Zoom to an area and select one of the buttons to display that type of data.
More data options can be found by expanding the details below each button.

Data Failure
If the area selected is too large (depends on the data type) then the status will say "Failed to get visualiser data" - zoom in and try again.

Útvonaltervező: Routino | Geo Data: | Térképszeletek:
routino-3.0/web/www/routino/router.leaflet.js 644 233 144 144347 12572605622 14700 0// // Routino router web page Javascript // // Part of the Routino routing software. // // This file Copyright 2008-2015 Andrew M. Bishop // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . // var vismarkers, markers, icons, markersmoved, paramschanged; var homelat=null, homelon=null; //////////////////////////////////////////////////////////////////////////////// /////////////////////////////// Initialisation ///////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // Make a deep copy of the routino profile. var routino_default={}; for(var l1 in routino) if(typeof(routino[l1])!="object") routino_default[l1]=routino[l1]; else { routino_default[l1]={}; for(var l2 in routino[l1]) if(typeof(routino[l1][l2])!="object") routino_default[l1][l2]=Number(routino[l1][l2]); else { routino_default[l1][l2]={}; for(var l3 in routino[l1][l2]) routino_default[l1][l2][l3]=Number(routino[l1][l2][l3]); } } // Store the latitude and longitude in the routino variable routino.point=[]; for(var marker=1;marker<=mapprops.maxmarkers;marker++) { routino.point[marker]={}; routino.point[marker].lon=""; routino.point[marker].lat=""; routino.point[marker].search=""; routino.point[marker].active=false; routino.point[marker].used=false; routino.point[marker].home=false; } // Process the URL query string and extract the arguments var legal={"^lon" : "^[-0-9.]+$", "^lat" : "^[-0-9.]+$", "^zoom" : "^[0-9]+$", "^lon[1-9]" : "^[-0-9.]+$", "^lat[1-9]" : "^[-0-9.]+$", "^search[1-9]" : "^.+$", "^transport" : "^[a-z]+$", "^highway-[a-z]+" : "^[0-9.]+$", "^speed-[a-z]+" : "^[0-9.]+$", "^property-[a-z]+" : "^[0-9.]+$", "^oneway" : "^(1|0|true|false|on|off)$", "^turns" : "^(1|0|true|false|on|off)$", "^weight" : "^[0-9.]+$", "^height" : "^[0-9.]+$", "^width" : "^[0-9.]+$", "^length" : "^[0-9.]+$", "^language" : "^[-a-zA-Z]+$"}; var args={}; if(location.search.length>1) { var query,queries; query=location.search.replace(/^\?/,""); query=query.replace(/;/g,"&"); queries=query.split("&"); for(var i=0;i=1;marker--) { var lon=args["lon" + marker]; var lat=args["lat" + marker]; var search=args["search" + marker]; if(lon !== undefined && lat !== undefined && search !== undefined && lon !== "" && lat !== "" && search !== "") { markerAddForm(marker); formSetSearch(marker,search); formSetCoords(marker,lon,lat); markerAddMap(marker); markerSearch(marker); vismarkers++; } else if(lon !== undefined && lat !== undefined && lon !== "" && lat !== "") { markerAddForm(marker); formSetCoords(marker,lon,lat); markerAddMap(marker); markerCoords(marker); vismarkers++; } else if(search !== undefined && search !== "") { markerAddForm(marker); formSetSearch(marker,search); markerSearch(marker); DoSearch(marker); vismarkers++; } else if(vismarkers || marker<=2) { markerAddForm(marker); vismarkers++; } var searchfield=document.forms["form"].elements["search" + marker]; if(searchfield.addEventListener) searchfield.addEventListener("keyup", searchOnReturnKey, false); else if(searchfield.attachEvent) searchfield.attachEvent("keyup", searchOnReturnKey); // Internet Explorer } // Update the transport type with the URL settings which updates all HTML forms to defaults. var transport=routino.transport; if(args["transport"] !== undefined) transport=args["transport"]; formSetTransport(transport); // Update the HTML with the URL settings if(args["language"] !== undefined) formSetLanguage(args["language"]); for(var key in routino.profile_highway) if(args["highway-" + key] !== undefined) formSetHighway(key,args["highway-" + key]); for(var key in routino.profile_speed) if(args["speed-" + key] !== undefined) formSetSpeed(key,args["speed-" + key]); for(var key in routino.profile_property) if(args["property-" + key] !== undefined) formSetProperty(key,args["property-" + key]); for(var key in routino.restrictions) { if(key=="oneway" || key=="turns") { if(args[key] !== undefined) formSetRestriction(key,args[key]); } else { if(args["restrict-" + key] !== undefined) formSetRestriction(key,args["restrict-" + key]); } } // Get the home location cookie and compare to each waypoint var cookies=document.cookie.split("; "); for(var cookie=0;cookie100) value=100; if(value< 0) value= 0; document.forms["form"].elements["highway-" + type].value=value; routino.profile_highway[type][routino.transport]=value; paramschanged=true; updateURLs(); } // // Change of Speed in the form // function formSetSpeed(type,value) // called from router.html (with one argument) { if(value == "+") { value=routino.profile_speed[type][routino.transport]; if(value<10) value=2*Math.floor(value/2)+2; else if(value<30) value=5*Math.floor(value/5)+5; else value=10*Math.floor(value/10)+10; } else if(value == "-") { value=routino.profile_speed[type][routino.transport]; if(value<=10) value=2*Math.ceil(value/2)-2; else if(value<=30) value=5*Math.ceil(value/5)-5; else value=10*Math.ceil(value/10)-10; } else if(value == "=") value=document.forms["form"].elements["speed-" + type].value; value=Number(value); if(isNaN(value)) value= 60; if(value>150) value=150; if(value< 0) value= 0; document.forms["form"].elements["speed-" + type].value=value; routino.profile_speed[type][routino.transport]=value; paramschanged=true; updateURLs(); } // // Change of Property in the form // function formSetProperty(type,value) // called from router.html (with one argument) { if(value == "+") { value=routino.profile_property[type][routino.transport]; if(value>=40 && value<60) value=2*Math.floor(value/2)+2; else value=5*Math.floor(value/5)+5; } else if(value == "-") { value=routino.profile_property[type][routino.transport]; if(value>40 && value<=60) value=2*Math.ceil(value/2)-2; else value=5*Math.ceil(value/5)-5; } else if(value == "=") value=document.forms["form"].elements["property-" + type].value; value=Number(value); if(isNaN(value)) value= 50; if(value>100) value=100; if(value< 0) value= 0; document.forms["form"].elements["property-" + type].value=value; routino.profile_property[type][routino.transport]=value; paramschanged=true; updateURLs(); } // // Change of Restriction rule in the form // function formSetRestriction(type,value) // called from router.html (with one argument) { if(type=="oneway" || type=="turns") { if(value === undefined) routino.profile_restrictions[type][routino.transport]=document.forms["form"].elements["restrict-" + type].checked; else document.forms["form"].elements["restrict-" + type].checked=value; routino.profile_restrictions[type][routino.transport]=value; } else if(type=="weight") { if(value == "+") value=routino.profile_restrictions[type][routino.transport]+5; else if(value == "-") value=routino.profile_restrictions[type][routino.transport]-5; else if(value == "=") value=document.forms["form"].elements["restrict-" + type].value; value=Number(value); if(isNaN(value)) value= 0; if(value>50) value=50; if(value< 0) value= 0; document.forms["form"].elements["restrict-" + type].value=value; routino.profile_restrictions[type][routino.transport]=value; } else /* if(type=="height" || type=="width" || type=="length") */ { if(value == "+") value=routino.profile_restrictions[type][routino.transport]+1; else if(value == "-") value=routino.profile_restrictions[type][routino.transport]-1; else if(value == "=") value=document.forms["form"].elements["restrict-" + type].value; value=Number(value); if(isNaN(value)) value= 0; if(value>25) value=25; if(value< 0) value= 0; document.forms["form"].elements["restrict-" + type].value=value; routino.profile_restrictions[type][routino.transport]=value; } paramschanged=true; updateURLs(); } // // Set the feature coordinates from the form when the form changes. // function formSetCoords(marker,lon,lat) // called from router.html (with one argument) { clearSearchResult(marker); if(lon === undefined && lat === undefined) { lon=document.forms["form"].elements["lon" + marker].value; lat=document.forms["form"].elements["lat" + marker].value; } if(lon === "" && lat === "") { document.forms["form"].elements["lon" + marker].value=""; document.forms["form"].elements["lat" + marker].value=""; routino.point[marker].lon=""; routino.point[marker].lat=""; updateURLs(); } else { var lonlat; if(lon==="") { lonlat=map.getCenter(); lon=lonlat.lon; } if(lon<-180) lon=-180; if(lon>+180) lon=+180; if(lat==="") { lonlat=map.getCenter(); lat=lonlat.lat; } if(lat<-90 ) lat=-90 ; if(lat>+90 ) lat=+90 ; lonlat = L.latLng(lat,lon); markers[marker].setLatLng(lonlat); markersmoved=true; document.forms["form"].elements["lon" + marker].value=format5f(lon); document.forms["form"].elements["lat" + marker].value=format5f(lat); routino.point[marker].lon=lon; routino.point[marker].lat=lat; routino.point[marker].used=true; markerCheckHome(marker); } } // // Set the search field from the form when the form changes. // function formSetSearch(marker,search) // called from event handler linked to router.html (with one argument) { clearSearchResult(marker); if(search === undefined) { routino.point[marker].search=document.forms["form"].elements["search" + marker].value; DoSearch(marker); } else { document.forms["form"].elements["search" + marker].value=search; routino.point[marker].search=search; } } // // Format a number in printf("%.5f") format. // function format5f(number) { var newnumber=Math.floor(number*100000+0.5); var delta=0; if(newnumber>=0 && newnumber<100000) delta= 100000; if(newnumber<0 && newnumber>-100000) delta=-100000; var string=String(newnumber+delta); var intpart =string.substring(0,string.length-5); var fracpart=string.substring(string.length-5,string.length); if(delta>0) intpart="0"; if(delta<0) intpart="-0"; return(intpart + "." + fracpart); } // // Build a set of URL arguments // function buildURLArguments(lang) { var url= "transport=" + routino.transport; for(var marker=1;marker<=vismarkers;marker++) if(routino.point[marker].active) { url=url + ";lon" + marker + "=" + format5f(routino.point[marker].lon); url=url + ";lat" + marker + "=" + format5f(routino.point[marker].lat); if(routino.point[marker].search !== "") url=url + ";search" + marker + "=" + encodeURIComponent(routino.point[marker].search); } for(var key in routino.profile_highway) if(routino.profile_highway[key][routino.transport]!=routino_default.profile_highway[key][routino.transport]) url=url + ";highway-" + key + "=" + routino.profile_highway[key][routino.transport]; for(var key in routino.profile_speed) if(routino.profile_speed[key][routino.transport]!=routino_default.profile_speed[key][routino.transport]) url=url + ";speed-" + key + "=" + routino.profile_speed[key][routino.transport]; for(var key in routino.profile_property) if(routino.profile_property[key][routino.transport]!=routino_default.profile_property[key][routino.transport]) url=url + ";property-" + key + "=" + routino.profile_property[key][routino.transport]; for(var key in routino.restrictions) if(routino.profile_restrictions[key][routino.transport]!=routino_default.profile_restrictions[key][routino.transport]) url=url + ";" + key + "=" + routino.profile_restrictions[key][routino.transport]; if(lang && routino.language) url=url + ";language=" + routino.language; return(url); } // // Build a set of URL arguments for the map location // function buildMapArguments() { var lonlat = map.getCenter(); var zoom = map.getZoom(); return "lat=" + format5f(lonlat.lat) + ";lon=" + format5f(lonlat.lng) + ";zoom=" + zoom; } // // Update the URLs // function updateURLs() { var urlargs1=buildURLArguments(true); var urlargs2=buildURLArguments(false); var mapargs=buildMapArguments(); var links=document.getElementsByTagName("a"); for(var i=0; i" + data_text + ""; document.getElementById("attribution_tile").innerHTML="" + tile_text + ""; } change_attribution(0); // Define a GPX layer but don't add it yet layerGPX={shortest: null, quickest: null}; // Add a markers vectors layer layerVectors = L.layerGroup(); map.addLayer(layerVectors); // A set of markers markers={}; icons={}; markersmoved=false; paramschanged=false; for(var marker=1;marker<=mapprops.maxmarkers;marker++) { icons[marker]=L.icon({iconUrl: "icons/marker-" + marker + "-red.png", iconSize: L.point(21,25), iconAnchor: L.point(10,25)}); markers[marker]=L.marker(L.point(0,0), {clickable: true, draggable: true, icon: icons[marker]}); markers[marker].on("drag" , (function(m) { return function(evt) { dragMarkerMove (m,evt); }; }(marker))); markers[marker].on("dragend", (function(m) { return function(evt) { dragMarkerComplete(m,evt); }; }(marker))); } icons.home=L.icon({iconUrl: "icons/marker-home-red.png", iconSize: L.point(21,25), iconAnchor: L.point(11,-25)}); // Markers to highlight a selected point for(var highlight in highlights) { highlights[highlight]=L.circleMarker(L.latLng(0,0), {radius: 10, stroke: true, weight: 4, color: route_dark_colours[highlight], opacity: 1.0, fill: false}); } // A popup for routing results for(var popup in popups) popups[popup] = createPopup(popup); // Move the map map.on("moveend", updateURLs); var lon =args["lon"]; var lat =args["lat"]; var zoom=args["zoom"]; if(lon !== undefined && lat !== undefined && zoom !== undefined) { if(lonmapprops.eastedge) lon=mapprops.eastedge; if(latmapprops.northedge) lat=mapprops.northedge; if(zoommapprops.zoomin) zoom=mapprops.zoomin; map.setView(L.latLng(lat,lon),zoom); } else map.fitBounds(map.options.maxBounds); // Unhide editing URL if variable set if(mapprops.editurl !== undefined && mapprops.editurl !== "") { var edit_url=document.getElementById("edit_url"); edit_url.style.display=""; edit_url.href=mapprops.editurl; } updateURLs(); } // // Callback for a marker drag occuring on the map. // function dragMarkerMove(marker,event) { dragMarkerSetForm(marker); } // // Callback for completing a drag occuring on the map. // function dragMarkerComplete(marker,event) { dragMarkerSetForm(marker); updateURLs(); } // // Set the feature coordinates in the form after dragging it on the map. // function dragMarkerSetForm(marker) { var lonlat = markers[marker].getLatLng(); formSetCoords(marker,lonlat.lng,lonlat.lat); } //////////////////////////////////////////////////////////////////////////////// /////////////////////////////// Marker dragging //////////////////////////////// //////////////////////////////////////////////////////////////////////////////// var dragged_waypoint=null,dragged_marker=null; var dragged_waypoint_over=null,dragged_marker_over=null; var dragged_icon_x,dragged_icon_y; // // Drag a waypoint up or down the list. // function dragWaypointStart(e) { var w=e.target; while(w!=null && w.className != "waypoint") w=w.parentElement; if(w===null) return; w.style.opacity = "0.5"; dragged_waypoint=w; dragged_marker=Number.parseInt(dragged_waypoint.id.substring(8)); dragged_icon_x=e.clientX-e.target.offsetLeft; dragged_icon_y=e.clientY-e.target.offsetTop; } function dragWaypointEnd(e) { e.preventDefault(); if(dragged_waypoint===null) return; dragged_waypoint.style.opacity = ""; dragged_waypoint=null; dragged_marker=null; if(dragged_waypoint_over===null) return; dragged_waypoint_over.style.border = ""; dragged_waypoint_over=null; dragged_marker_over=null; } // // Drag a waypoint over another one up or down the list. // function dragWaypointEnter(e) { var w=e.target; while(w!=null && w.className != "waypoint") w=w.parentElement; if(w===null) return; if(dragged_waypoint_over!==null) dragged_waypoint_over.style.border = ""; if(w==dragged_waypoint) return; dragged_waypoint_over=w; dragged_marker_over=Number.parseInt(dragged_waypoint_over.id.substring(8)); if(dragged_marker>dragged_marker_over) w.style.borderTop = "3px solid black"; else w.style.borderBottom = "3px solid black"; } function dragWaypointOver(e) { e.preventDefault(); } function dragWaypointLeave(e) { var w=e.target; while(w!=null && w.className != "waypoint") w=w.parentElement; if(w===null) return; if(w==dragged_waypoint_over) return; w.style.border = ""; } // // Drop the waypoint after dragging up or down the list. // function dragWaypointDrop(e) { e.preventDefault(); if(dragged_marker_over===null) return; if(dragged_marker_over>dragged_marker) for(var m=dragged_marker;mdragged_marker_over;m--) markerSwap(m,m-1); } // // Drag a waypoint over the map. // function dragWaypointMapEnter(e) { e.preventDefault(); if(dragged_waypoint_over!==null) dragged_waypoint_over.style.border = ""; } function dragWaypointMapOver(e) { e.preventDefault(); } function dragWaypointMapLeave(e) { e.preventDefault(); } // // Drop the waypoint after dragging it over the map. // function dragWaypointMapDrop(e) { e.preventDefault(); var rect = document.getElementById("map").getBoundingClientRect(); var lonlat=map.containerPointToLatLng(L.point(e.clientX-rect.left-window.scrollX-dragged_icon_x+8, e.clientY-rect.top -window.scrollY-dragged_icon_y+21)); formSetCoords(dragged_marker,lonlat.lng,lonlat.lat); if(!routino.point[dragged_marker].active) markerToggleMap(dragged_marker); } //////////////////////////////////////////////////////////////////////////////// /////////////////////////////// Marker handling //////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // // Toggle a marker on the map. // function markerToggleMap(marker) // called from router.html { if(!routino.point[marker].used) { routino.point[marker].used=true; markerCentre(marker); markerCoords(marker); } markerAddRemoveMap(marker,!routino.point[marker].active); updateSearchButtons(); } // // Show or hide a marker on the map. // function markerAddRemoveMap(marker,active) { if(active) markerAddMap(marker); else markerRemoveMap(marker); } // // Show a marker on the map. // function markerAddMap(marker) { clearSearchResult(marker); layerVectors.addLayer(markers[marker]); routino.point[marker].active=true; routino.point[marker].used=true; updateIcon(marker); markersmoved=true; updateURLs(); } // // Remove a marker from the map. // function markerRemoveMap(marker) { clearSearchResult(marker); layerVectors.removeLayer(markers[marker]); routino.point[marker].active=false; updateIcon(marker); markersmoved=true; updateURLs(); } // // Display search string for the marker // function markerSearch(marker) // called from router.html { clearSearchResult(marker); document.getElementById("coords" + marker).style.display="none"; document.getElementById("search" + marker).style.display=""; } // // Display coordinates for the marker // function markerCoords(marker) // called from router.html { clearSearchResult(marker); document.getElementById("search" + marker).style.display="none"; document.getElementById("coords" + marker).style.display=""; } // // Centre the marker on the map // function markerCentre(marker) // called from router.html { if(!routino.point[marker].used) return; clearSearchResult(marker); var lonlat=map.getCenter(); formSetCoords(marker,lonlat.lng,lonlat.lat); } // // Centre the map on the marker // function markerRecentre(marker) // called from router.html { if(!routino.point[marker].used) return; clearSearchResult(marker); var lon=routino.point[marker].lon; var lat=routino.point[marker].lat; var lonlat = L.latLng(lat,lon); map.panTo(lonlat); } // // Clear the current marker. // function markerRemove(marker) // called from router.html { clearSearchResult(marker); for(var m=marker;mmarker;m--) markerCopy(m,m-1); markerClearForm(marker-1); } // // Add a marker after the current one. // function markerAddAfter(marker) // called from router.html { if(vismarkers==mapprops.maxmarkers) return false; clearSearchResult(marker); markerAddForm(++vismarkers); for(var m=vismarkers;m>(marker+1);m--) markerCopy(m,m-1); markerClearForm(marker+1); } // // Set this marker as the home location. // function markerHome(marker) // called from router.html { if(!routino.point[marker].used) { markerMoveHome(marker); } else { clearSearchResult(marker); markerSetClearHome(marker,!routino.point[marker].home); } } // // Set this marker as the current location. // function markerLocate(marker) // called from router.html { clearSearchResult(marker); if(navigator.geolocation) navigator.geolocation.getCurrentPosition( function(position) { formSetCoords(marker,position.coords.longitude,position.coords.latitude); markerAddMap(marker); }); } // // Update the search buttons enable/disable. // function updateSearchButtons() { var markersactive=0; for(var m=1;m<=vismarkers;m++) if(routino.point[m].active) markersactive++; if(markersactive<2) { document.getElementById("shortest").disabled="disabled"; document.getElementById("quickest").disabled="disabled"; } else { document.getElementById("shortest").disabled=""; document.getElementById("quickest").disabled=""; } } // // Update an icon to set colours and home or normal marker. // function updateIcon(marker) { if(routino.point[marker].home) { if(routino.point[marker].active) document.getElementById("icon" + marker).src="icons/marker-home-red.png"; else document.getElementById("icon" + marker).src="icons/marker-home-grey.png"; markers[marker].setIcon(icons.home); } else { if(routino.point[marker].active) document.getElementById("icon" + marker).src="icons/marker-" + marker + "-red.png"; else document.getElementById("icon" + marker).src="icons/marker-" + marker + "-grey.png"; markers[marker].setIcon(icons[marker]); } markers[marker].update(); } // // Move the marker to the home location // function markerMoveHome(marker) { if(homelon===null || homelat===null) return; routino.point[marker].home=true; routino.point[marker].used=true; formSetCoords(marker,homelon,homelat); markerAddMap(marker); } // // Set or clear the home marker icon // function markerSetClearHome(marker,home) { var cookie; var date = new Date(); if(home) { homelat=routino.point[marker].lat; homelon=routino.point[marker].lon; cookie="Routino-home=lon:" + homelon + ":lat:" + homelat; date.setUTCFullYear(date.getUTCFullYear()+5); routino.point[marker].home=true; } else { homelat=null; homelon=null; cookie="Routino-home=unset"; date.setUTCFullYear(date.getUTCFullYear()-1); routino.point[marker].home=false; } document.cookie=cookie + ";expires=" + date.toGMTString(); updateIcon(marker); for(var m=1;m<=mapprops.maxmarkers;m++) markerCheckHome(m); } // // Check if a marker is the home marker // function markerCheckHome(marker) { var home=routino.point[marker].home; if(routino.point[marker].lon==homelon && routino.point[marker].lat==homelat) routino.point[marker].home=true; else routino.point[marker].home=false; if(home!=routino.point[marker].home) updateIcon(marker); } // // Move this marker up. // function markerMoveUp(marker) // called from router.html { if(marker==1) { for(var m=1;m1;m--) markerSwap(m,m-1); } else markerSwap(marker,marker+1); } // // Copy a marker from one place to another. // function markerCopy(marker1,marker2) { for(var element in routino.point[marker2]) routino.point[marker1][element]=routino.point[marker2][element]; document.getElementById("search" + marker1).style.display=document.getElementById("search" + marker2).style.display; document.getElementById("coords" + marker1).style.display=document.getElementById("coords" + marker2).style.display; document.forms["form"].elements["search" + marker1].value=document.forms["form"].elements["search" + marker2].value; formSetCoords(marker1,routino.point[marker1].lon,routino.point[marker1].lat); markerAddRemoveMap(marker1,routino.point[marker1].active); } // // Swap a pair of markers. // function markerSwap(marker1,marker2) { for(var element in routino.point[marker2]) { var temp=routino.point[marker1][element]; routino.point[marker1][element]=routino.point[marker2][element]; routino.point[marker2][element]=temp; } var search_display=document.getElementById("search" + marker1).style.display; document.getElementById("search" + marker1).style.display=document.getElementById("search" + marker2).style.display; document.getElementById("search" + marker2).style.display=search_display; var coords_display=document.getElementById("coords" + marker1).style.display; document.getElementById("coords" + marker1).style.display=document.getElementById("coords" + marker2).style.display; document.getElementById("coords" + marker2).style.display=coords_display; var search_value=document.forms["form"].elements["search" + marker1].value; document.forms["form"].elements["search" + marker1].value=document.forms["form"].elements["search" + marker2].value; document.forms["form"].elements["search" + marker2].value=search_value; formSetCoords(marker1,routino.point[marker1].lon,routino.point[marker1].lat); formSetCoords(marker2,routino.point[marker2].lon,routino.point[marker2].lat); markerAddRemoveMap(marker1,routino.point[marker1].active); markerAddRemoveMap(marker2,routino.point[marker2].active); } // // Reverse the markers. // function markersReverse() // called from router.html { for(var marker=1;marker<=vismarkers/2;marker++) markerSwap(marker,vismarkers+1-marker); markersmoved=true; updateURLs(); } // // Close the loop. // function markersLoop() // called from router.html { if(vismarkers==mapprops.maxmarkers) return false; if(routino.point[vismarkers].lon==routino.point[1].lon && routino.point[vismarkers].lat==routino.point[1].lat) { if(routino.point[vismarkers].active) return false; else { markerToggleMap(vismarkers); return true; } } if(routino.point[vismarkers].used) markerAddForm(++vismarkers); markerCopy(vismarkers,1); markersmoved=true; updateURLs(); updateSearchButtons(); } // // Display the form for a marker // function markerAddForm(marker) { document.getElementById("waypoint" + marker).style.display=""; } // // Hide the form for a marker // function markerRemoveForm(marker) { document.getElementById("waypoint" + marker).style.display="none"; markerClearForm(marker); } // // Clear the form for a marker // function markerClearForm(marker) { markerRemoveMap(marker); markerCoords(marker); formSetCoords(marker,"",""); formSetSearch(marker,""); updateIcon(marker); routino.point[marker].used=false; routino.point[marker].home=false; routino.point[marker].active=false; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////// Route results handling //////////////////////////// //////////////////////////////////////////////////////////////////////////////// var route_light_colours={shortest: "#60C060", quickest: "#6060C0"}; var route_dark_colours ={shortest: "#408040", quickest: "#404080"}; var highlights={shortest: null, quickest: null}; var popups={shortest: null, quickest: null}; var routepoints={shortest: {}, quickest: {}}; // // Highlight a specific item in the route // function highlight(type,line,action) { if(action == "clear") { layerVectors.removeLayer(highlights[type]); drawPopup(type,null); } else if(action == "zoom") { var lonlat = L.latLng(routepoints[type][line].lat,routepoints[type][line].lon); map.setView(lonlat,mapprops.zoomin-2); } else { // Marker var lonlat = L.latLng(routepoints[type][line].lat,routepoints[type][line].lon); highlights[type].setLatLng(lonlat); layerVectors.addLayer(highlights[type]); // Popup drawPopup(type,"" + routepoints[type][line].html + "
"); } highlights[type].redraw(); } // // Create a popup - independent of map because want it fixed on screen not fixed on map. // function createPopup(type) { var popup=document.createElement("div"); popup.className = "popup"; popup.innerHTML = ""; popup.style.display = "none"; popup.style.position = "fixed"; popup.style.top = "-4000px"; popup.style.left = "-4000px"; popup.style.zIndex = "100"; popup.style.padding = "5px"; popup.style.opacity=0.85; popup.style.backgroundColor=route_light_colours[type]; popup.style.border="4px solid " + route_dark_colours[type]; document.body.appendChild(popup); return(popup); } // // Draw a popup - independent of map because want it fixed on screen not fixed on map. // function drawPopup(type,html) { var popup=popups[type]; if(html===null) { popup.style.display="none"; return; } if(popup.style.display=="none") { var map_div=document.getElementById("map"); popup.style.left =map_div.offsetParent.offsetLeft+map_div.offsetLeft+60 + "px"; popup.style.top = map_div.offsetTop +30 + "px"; popup.style.width =map_div.clientWidth-120 + "px"; popup.style.display=""; } var close="X"; popup.innerHTML=close+html; } // // Remove a GPX trace // function removeGPXTrace(type) { map.removeLayer(layerGPX[type]); layerGPX[type]=null; displayStatus(type,"no_info"); document.getElementById(type + "_links").style.display = "none"; document.getElementById(type + "_route").innerHTML = ""; hideshow_hide(type); } //////////////////////////////////////////////////////////////////////////////// /////////////////////////////// Server handling //////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // // Define an AJAX request object // function ajaxGET(url,success,failure,state) { var ajaxRequest=new XMLHttpRequest(); function ajaxGOT(options) { if(this.readyState==4) if(this.status==200) { if(typeof(options.success)=="function") options.success(this,options.state); } else { if(typeof(options.failure)=="function") options.failure(this,options.state); } } ajaxRequest.onreadystatechange = function(){ ajaxGOT.call(ajaxRequest,{success: success, failure: failure, state: state}); }; ajaxRequest.open("GET", url, true); ajaxRequest.send(null); } // // Display data statistics // function displayStatistics() // called from router.html { // Use AJAX to get the statistics ajaxGET("statistics.cgi", runStatisticsSuccess); } // // Success in running data statistics generation. // function runStatisticsSuccess(response) { document.getElementById("statistics_data").innerHTML="
" + response.responseText + "
"; document.getElementById("statistics_link").style.display="none"; } // // Submit form - perform the routing // function findRoute(type) // called from router.html { tab_select("results"); hideshow_hide("help_options"); hideshow_hide("shortest"); hideshow_hide("quickest"); displayStatus("result","running"); var url="router.cgi" + "?" + buildURLArguments(true) + ";type=" + type; // Destroy the existing layer(s) highlight("shortest",-1,"clear"); highlight("quickest",-1,"clear"); if(markersmoved || paramschanged) { if(layerGPX.shortest!==null) removeGPXTrace("shortest"); if(layerGPX.quickest!==null) removeGPXTrace("quickest"); markersmoved=false; paramschanged=false; } else if(layerGPX[type]!==null) removeGPXTrace(type); // Use AJAX to run the router routing_type=type; ajaxGET(url, runRouterSuccess, runRouterFailure); } // // Success in running router. // function runRouterSuccess(response) { var lines=response.responseText.split("\n"); var uuid=lines[0]; var success=lines[1]; var link; // Update the status message if(success=="ERROR") { displayStatus("result","error"); hideshow_show("help_route"); link=document.getElementById("router_log_error"); link.href="results.cgi?uuid=" + uuid + ";type=router;format=log"; return; } else { displayStatus("result","complete"); hideshow_hide("help_route"); link=document.getElementById("router_log_complete"); link.href="results.cgi?uuid=" + uuid + ";type=router;format=log"; } // Update the routing result message link=document.getElementById(routing_type + "_html"); link.href="results.cgi?uuid=" + uuid + ";type=" + routing_type + ";format=html"; link=document.getElementById(routing_type + "_gpx_track"); link.href="results.cgi?uuid=" + uuid + ";type=" + routing_type + ";format=gpx-track"; link=document.getElementById(routing_type + "_gpx_route"); link.href="results.cgi?uuid=" + uuid + ";type=" + routing_type + ";format=gpx-route"; link=document.getElementById(routing_type + "_text_all"); link.href="results.cgi?uuid=" + uuid + ";type=" + routing_type + ";format=text-all"; link=document.getElementById(routing_type + "_text"); link.href="results.cgi?uuid=" + uuid + ";type=" + routing_type + ";format=text"; document.getElementById(routing_type + "_links").style.display = ""; // Add a GPX layer var url="results.cgi?uuid=" + uuid + ";type=" + routing_type + ";format=gpx-track"; ajaxGET(url, runGPXSuccess); hideshow_show(routing_type); displayResult(routing_type,uuid); } // // Success in getting GPX. // function runGPXSuccess(response) { var lines=response.responseText.split("\n"); var coords=[]; var segment=-1; for(var line=0;line/)) { segment++; coords[segment]=[]; } if(lines[line].match(/^")) table=1; else continue; } if(thisline.match("")) break; if(thisline.match("")) { var rowtype=RegExp.$1; if(rowtype=="c") { thisline.match(": *([-0-9.]+) *([-0-9.]+)"); points[point]={lat: Number(RegExp.$1), lon: Number(RegExp.$2), html: "", highway: "", distance: "", total: ""}; point++; } else if(rowtype=="n") { points[point-1].html += thisline; } else if(rowtype=="s") { thisline.match("([^<]+)"); points[point-1].highway = RegExp.$1; thisline.match("([^<]+)"); points[point-1].distance = RegExp.$1; thisline.match("([^<]+)"); points[point-1].total = RegExp.$1; thisline.match("^(.*)."); points[point-1].html += RegExp.$1; } else if(rowtype=="t") { points[point-1].html += thisline; thisline.match("([^<]+)"); points[point-1].total = RegExp.$1; thisline.match("(.*)"); points[point-1].highway = RegExp.$1; } } } displayStatus(routing_type,"info",points[point-1].total.bold()); var result=""; for(var p=0;p" + "
#" + (p+1) + "" + points[p].highway; } result=result + "
"; document.getElementById(routing_type + "_route").innerHTML=result; } // // Failure in getting route. // function getRouteFailure(response) { document.getElementById(routing_type + "_route").innerHTML = ""; } // // Perform a search // function DoSearch(marker) { // Use AJAX to get the search result var search=routino.point[marker].search; var mapbounds=map.getBounds(); var url="search.cgi"; url=url + "?marker=" + marker; url=url + ";lonmin=" + format5f(mapbounds.getWest()); url=url + ";latmin=" + format5f(mapbounds.getSouth()); url=url + ";lonmax=" + format5f(mapbounds.getEast()); url=url + ";latmax=" + format5f(mapbounds.getNorth()); url=url + ";search=" + encodeURIComponent(search); ajaxGET(url,runSearchSuccess); } var searchresults=[]; // // Success in running search. // function runSearchSuccess(response) { var lines=response.responseText.split("\n"); var marker=lines[0]; var cpuinfo=lines[1]; // not used var message=lines[2]; if(message !== "") { alert(message); return; } searchresults[marker]=[]; for(var line=3;line"; for(var n=0;n0) innerHTML+="
"; innerHTML+="" + searchresults[marker][n].name + ""; } results.innerHTML=innerHTML; results.style.display=""; } } // // Display search results. // function choseSearchResult(marker,n) { if(n>=0) { formSetSearch(marker,searchresults[marker][n].name); formSetCoords(marker,searchresults[marker][n].lon,searchresults[marker][n].lat); markerAddMap(marker); } } // // Clear search results. // function clearSearchResult(marker) { document.getElementById("searchresults" + marker).style.display="none"; } routino-3.0/web/www/routino/visualiser.openlayers.js 644 233 144 102760 12327767604 16313 0// // Routino data visualiser web page Javascript // // Part of the Routino routing software. // // This file Copyright 2008-2014 Andrew M. Bishop // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . // // // Data types // var data_types=[ "junctions", "super", "waytype", "highway", "transport", "barrier", "turns", "speed", "weight", "height", "width", "length", "property", "errorlogs" ]; //////////////////////////////////////////////////////////////////////////////// /////////////////////////////// Initialisation ///////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // Process the URL query string and extract the arguments var legal={"^lon" : "^[-0-9.]+$", "^lat" : "^[-0-9.]+$", "^zoom" : "^[0-9]+$"}; var args={}; if(location.search.length>1) { var query,queries; query=location.search.replace(/^\?/,""); query=query.replace(/;/g,"&"); queries=query.split("&"); for(var i=0;i" + data_text + ""; document.getElementById("attribution_tile").innerHTML="" + tile_text + ""; } change_attribution(0); // Add two vectors layers (one for highlights that display behind the vectors) layerHighlights = new OpenLayers.Layer.Vector("Highlights",{displayInLayerSwitcher: false}); map.addLayer(layerHighlights); layerVectors = new OpenLayers.Layer.Vector("Markers",{displayInLayerSwitcher: false}); map.addLayer(layerVectors); // Handle feature selection and popup select = new OpenLayers.Control.SelectFeature(layerVectors, {onSelect: selectFeature, onUnselect: unselectFeature}); map.addControl(select); select.activate(); createPopup(); // Add a boxes layer layerBoxes = new OpenLayers.Layer.Boxes("Boundary",{displayInLayerSwitcher: false}); map.addLayer(layerBoxes); box=null; // Move the map map.events.register("moveend", map, updateURLs); var lon =args["lon"]; var lat =args["lat"]; var zoom=args["zoom"]; if(lon !== undefined && lat !== undefined && zoom !== undefined) { if(lonmapprops.eastedge) lon=mapprops.eastedge; if(latmapprops.northedge) lat=mapprops.northedge; if(zoommapprops.zoomin) zoom=mapprops.zoomin; var lonlat = new OpenLayers.LonLat(lon,lat); lonlat.transform(epsg4326,epsg900913); map.moveTo(lonlat,zoom-map.minZoomLevel); } else { map.setCenter(map.restrictedExtent.getCenterLonLat(), map.getZoomForExtent(map.restrictedExtent,true)); map.maxResolution = map.getResolution(); } // Unhide editing URL if variable set if(mapprops.editurl !== undefined && mapprops.editurl !== "") { var edit_url=document.getElementById("edit_url"); edit_url.style.display=""; edit_url.href=mapprops.editurl; } updateURLs(); } // // Format a number in printf("%.5f") format. // function format5f(number) { var newnumber=Math.floor(number*100000+0.5); var delta=0; if(newnumber>=0 && newnumber<100000) delta= 100000; if(newnumber<0 && newnumber>-100000) delta=-100000; var string=String(newnumber+delta); var intpart =string.substring(0,string.length-5); var fracpart=string.substring(string.length-5,string.length); if(delta>0) intpart="0"; if(delta<0) intpart="-0"; return(intpart + "." + fracpart); } // // Build a set of URL arguments for the map location // function buildMapArguments() { var lonlat = map.getCenter().clone(); lonlat.transform(epsg900913,epsg4326); var zoom = map.getZoom() + map.minZoomLevel; return "lat=" + format5f(lonlat.lat) + ";lon=" + format5f(lonlat.lon) + ";zoom=" + zoom; } // // Update the URLs // function updateURLs() { var mapargs=buildMapArguments(); var links=document.getElementsByTagName("a"); for(var i=0; i" + id + ""); } } } drawPopup(string.split("\n").join("
")); } //////////////////////////////////////////////////////////////////////////////// /////////////////////////////// Server handling //////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // // Define an AJAX request object // function ajaxGET(url,success,failure,state) { var ajaxRequest=new XMLHttpRequest(); function ajaxGOT(options) { if(this.readyState==4) if(this.status==200) { if(typeof(options.success)=="function") options.success(this,options.state); } else { if(typeof(options.failure)=="function") options.failure(this,options.state); } } ajaxRequest.onreadystatechange = function(){ ajaxGOT.call(ajaxRequest,{success: success, failure: failure, state: state}); }; ajaxRequest.open("GET", url, true); ajaxRequest.send(null); } // // Display the status // function displayStatus(type,subtype,content) { var child=document.getElementById("result_status").firstChild; do { if(child.id !== undefined) child.style.display="none"; child=child.nextSibling; } while(child !== null); var chosen_status=document.getElementById("result_status_" + type); chosen_status.style.display=""; if(subtype !== undefined) { var format_status=document.getElementById("result_status_" + subtype).innerHTML; chosen_status.innerHTML=format_status.replace("#",String(content)); } } // // Display data statistics // function displayStatistics() { // Use AJAX to get the statistics ajaxGET("statistics.cgi", runStatisticsSuccess); } // // Success in running data statistics generation. // function runStatisticsSuccess(response) { document.getElementById("statistics_data").innerHTML="
" + response.responseText + "
"; document.getElementById("statistics_link").style.display="none"; } // // Get the requested data // function displayData(datatype) // called from visualiser.html { for(var data in data_types) hideshow_hide(data_types[data]); if(datatype !== "") hideshow_show(datatype); // Delete the old data unselectFeature(); select.deactivate(); layerVectors.destroyFeatures(); layerHighlights.destroyFeatures(); if(box !== null) layerBoxes.removeMarker(box); box=null; // Print the status displayStatus("no_data"); // Return if just here to clear the data if(datatype === "") return; // Get the new data var mapbounds=map.getExtent().clone(); mapbounds.transform(epsg900913,epsg4326); var url="visualiser.cgi"; url=url + "?lonmin=" + format5f(mapbounds.left); url=url + ";latmin=" + format5f(mapbounds.bottom); url=url + ";lonmax=" + format5f(mapbounds.right); url=url + ";latmax=" + format5f(mapbounds.top); url=url + ";data=" + datatype; // Use AJAX to get the data switch(datatype) { case "junctions": ajaxGET(url, runJunctionsSuccess, runFailure); break; case "super": ajaxGET(url, runSuperSuccess, runFailure); break; case "waytype": var waytype; var waytypes=document.forms["waytypes"].elements["waytype"]; for(var h in waytypes) if(waytypes[h].checked) waytype=waytypes[h].value; url+="-" + waytype; ajaxGET(url, runWaytypeSuccess, runFailure); break; case "highway": var highway; var highways=document.forms["highways"].elements["highway"]; for(var h in highways) if(highways[h].checked) highway=highways[h].value; url+="-" + highway; ajaxGET(url, runHighwaySuccess, runFailure); break; case "transport": var transport; var transports=document.forms["transports"].elements["transport"]; for(var t in transports) if(transports[t].checked) transport=transports[t].value; url+="-" + transport; ajaxGET(url, runTransportSuccess, runFailure); break; case "barrier": var transport; var transports=document.forms["barriers"].elements["barrier"]; for(var t in transports) if(transports[t].checked) transport=transports[t].value; url+="-" + transport; ajaxGET(url, runBarrierSuccess, runFailure); break; case "turns": ajaxGET(url, runTurnsSuccess, runFailure); break; case "speed": case "weight": case "height": case "width": case "length": ajaxGET(url, runLimitSuccess, runFailure); break; case "property": var property; var properties=document.forms["properties"].elements["property"]; for(var p in properties) if(properties[p].checked) property=properties[p].value; url+="-" + property; ajaxGET(url, runPropertySuccess, runFailure); break; case "errorlogs": ajaxGET(url, runErrorlogSuccess, runFailure); break; } } // // Success in getting the junctions. // function runJunctionsSuccess(response) { var lines=response.responseText.split("\n"); var junction_colours={ 0: "#FFFFFF", 1: "#FF0000", 2: "#FFFF00", 3: "#00FF00", 4: "#8B4513", 5: "#00BFFF", 6: "#FF69B4", 7: "#000000", 8: "#000000", 9: "#000000" }; var styles={}; for(var colour in junction_colours) styles[colour]=new OpenLayers.Style({},{stroke: false, pointRadius: 2,fillColor: junction_colours[colour], cursor: "pointer"}); var features=[]; for(var line=0;line. // // // Display one of the tabs and associated DIV and hide the others // function tab_select(name) { var tab=document.getElementById("tab_" + name); if(tab.className=="tab_selected") return; // Hide the deslected tabs and DIVs var parent=tab.parentNode; var child=parent.firstChild; do { if(String(child.id).substr(0,4)=="tab_") { var div=document.getElementById(child.id + "_div"); child.className="tab_unselected"; div.style.display="none"; } child=child.nextSibling; } while(child!==null); // Display the newly selected tab and DIV tab.className="tab_selected"; document.getElementById(tab.id + "_div").style.display=""; } // // Show the associated DIV // function hideshow_show(name) { document.getElementById("hideshow_" + name + "_show").className="hideshow_hide"; document.getElementById("hideshow_" + name + "_hide").className="hideshow_show"; document.getElementById("hideshow_" + name + "_div").style.display=""; } // // Hide the associated DIV // function hideshow_hide(name) { document.getElementById("hideshow_" + name + "_show").className="hideshow_show"; document.getElementById("hideshow_" + name + "_hide").className="hideshow_hide"; document.getElementById("hideshow_" + name + "_div").style.display="none"; } // // Toggle the associated DIV // function hideshow_toggle(name) { if(document.getElementById("hideshow_" + name + "_div").style.display=="none") hideshow_show(name); else hideshow_hide(name); } routino-3.0/web/www/routino/visualiser.html.en 644 233 144 51762 12573351573 15046 0 Routino : Data Visualiser for Routing Data
Visualiser Router Data
Routino Visualiser This web page allows visualisation of the data that Routino uses for routing. Only data relevant for routing is displayed and some will therefore be excluded.
Instructions Zoom in and then use the buttons below to download the data. The server will only return data if the selected area is small enough.
Status
No data displayed
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ - Help
Quick Start
Zoom to an area and select one of the buttons to display that type of data.
More data options can be found by expanding the details below each button.

Data Failure
If the area selected is too large (depends on the data type) then the status will say "Failed to get visualiser data" - zoom in and try again.

Router: Routino | Geo Data: | Tiles:
routino-3.0/web/www/routino/paths.pl 644 233 144 2701 11763176234 13011 0# # Routino CGI paths Perl script # # Part of the Routino routing software. # # This file Copyright 2008-2012 Andrew M. Bishop # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # # Directory path parameters # EDIT THIS to set the root directory for the non-web data files. $root_dir="../.."; # EDIT THIS to change the location of the individual directories. $bin_dir="$root_dir/bin"; $data_dir="$root_dir/data"; $results_dir="$root_dir/results"; # EDIT THIS to set the filename prefix for the routing database files. $data_prefix=""; # EDIT THIS to change the names of the executables (enables easy selection of slim mode). $router_exe="router"; $filedumper_exe="filedumper"; # EDIT THIS to change the search type and base URL (must be a type recognised by search.pl). $search_type="nominatim"; $search_baseurl="http://nominatim.openstreetmap.org/search"; 1; routino-3.0/web/www/routino/update-profiles.pl 755 233 144 4526 12306670424 15001 0#!/usr/bin/perl # # Update the Routino profile files # # Part of the Routino routing software. # # This file Copyright 2011-2014 Andrew M. Bishop # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # use strict; # Use the directory paths script require "paths.pl"; # The parameters for the execution my $params=""; $params.=" --dir=$main::data_dir" if($main::data_dir); $params.=" --prefix=$main::data_prefix" if($main::data_prefix); # Generate the Perl profiles. open(PROFILE,">profiles.pl") || die "Cannot open 'profiles.pl' to write.\n"; print PROFILE "################################################################################\n"; print PROFILE "########################### Routino default profile ############################\n"; print PROFILE "################################################################################\n"; print PROFILE "\n"; open(EXECUTE,"$main::bin_dir/$main::router_exe $params --help-profile-perl |") || die "Failed to execute router to generate profiles.\n"; while() { print PROFILE; } close(EXECUTE); print PROFILE "\n"; print PROFILE "1;\n"; close(PROFILE); # Generate the Javascript profiles. open(PROFILE,">profiles.js") || die "Cannot open 'profiles.js' to write.\n"; print PROFILE "////////////////////////////////////////////////////////////////////////////////\n"; print PROFILE "/////////////////////////// Routino default profile ////////////////////////////\n"; print PROFILE "////////////////////////////////////////////////////////////////////////////////\n"; print PROFILE "\n"; open(EXECUTE,"$main::bin_dir/$main::router_exe $params --help-profile-json |") || die "Failed to execute router to generate profiles.\n"; while() { print PROFILE; } close(EXECUTE); close(PROFILE); routino-3.0/web/www/routino/visualiser.html.pl 644 233 144 52403 12573351576 15053 0 Routino : Data Visualiser for Routing Data
Visualiser Router Data
Wizualizer Routino This web page allows visualisation of the data that Routino uses for routing. Only data relevant for routing is displayed and some will therefore be excluded.
Instrukcje Zoom in and then use the buttons below to download the data. The server will only return data if the selected area is small enough.
Status
Brak danych do wyświetlenia
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ - Pomoc
Quick Start
Zoom to an area and select one of the buttons to display that type of data.
More data options can be found by expanding the details below each button.

Data Failure
If the area selected is too large (depends on the data type) then the status will say "Failed to get visualiser data" - zoom in and try again.

Router: Routino | Geo Data: | Kafelki:
routino-3.0/web/www/routino/router.html.hu 644 233 144 75247 12573351571 14214 0 Routino : Openstreetmap alapú útvonaltervező
Beállítások Eredmény Adatok
Routino openstreetmap útvonaltervező This web page allows routing within the data collected by OpenStreetMap. Select start and end points (click on the marker icons below), select routing preferences then find a route.
+ - Útpontok
+ - Közlekedési mód
Gyalog:
Lovas:
Kerekesszékes:
Kerékpáros:
Robogós:
Motoros:
Autós:
Kisteherautós:
Kamionos:
Buszos:
+ - Út preferencia
+ - Sebességkorlát
+ - Út tulajdonságok
+ - Kizáró tényezők
Find
+ - Súgó
Quick Start
Click on marker icons (above) to place them on the map (right). Then drag them to the correct position. Zooming the map before placing the markers is probably easiest. Alternatively type the latitude and longitude into the boxes above.

Select the transport type, allowed highway types, speed limits, highway properties and other restrictions from the options above. Select "Shortest" or "Quickest" to calculate the route and display it on the map.

Waypoints
Clicking on the marker icons will toggle the display of them on the map. When a route is calculated it will visit (as close as possible for the selected transport type) each of the waypoints that have markers on the map in the order given.

Transport Type
Selecting a transport type will restrict the chosen route to those on which it is allowed and set default values for the other parameters.

Highway Preferences
The highway preference is selected as a percentage and routes are chosen that try to follow the preferred highways. For example if a "Primary" road is given a "110%" preference and a "Secondary" road is given a "100%" preference then it means that a route on a Primary road can be up to 10% longer than on a secondary road and still be selected.

Speed Limits
The speed limits chosen here for the different types of highway apply if the highway has no other speed limit marked or it is higher than the chosen one.

Property Preferences
The property preference is selected as a percentage and routes are chosen that try to follow highways with the preferred property. For example if a "Paved" highway is given a "75%" preference then it means that an unpaved highway is automatically given a "25%" preference so that a route on a paved highway can be 3 times the length of an unpaved one and still be selected.

Other Restrictions
These allow a route to be found that avoids marked limits on weight, height, width or length. It is also possible to ignore one-way restrictions (e.g. if walking).

Útvonaltervező: Routino | Geo Data: | Térképszeletek:
routino-3.0/web/www/routino/visualiser.html.nl 644 233 144 52127 12573351575 15053 0 Routino : Data Visualiser for Routing Data
Visualiser Router Data
Routino Visualiser This web page allows visualisation of the data that Routino uses for routing. Only data relevant for routing is displayed and some will therefore be excluded.
Instructies Zoom in and then use the buttons below to download the data. The server will only return data if the selected area is small enough.
Status
Geen data getoond
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ - Help
Quick Start
Zoom to an area and select one of the buttons to display that type of data.
More data options can be found by expanding the details below each button.

Data Failure
If the area selected is too large (depends on the data type) then the status will say "Failed to get visualiser data" - zoom in and try again.

Router: Routino | Geo Data: | Tiles:
routino-3.0/web/www/routino/search.pl 644 233 144 5060 12325774241 13135 0# # Routino generic Search Perl script # # Part of the Routino routing software. # # This file Copyright 2012-2014 Andrew M. Bishop # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # use strict; # Use the directory paths script require "paths.pl"; # Use the perl encoding/decoding functions use Encode qw(decode encode); # Use the perl URI module use URI::Escape; # Use the perl LWP module use LWP::UserAgent; # Use the perl JSON module use JSON::PP; # Use the perl Time::HiRes module use Time::HiRes qw(gettimeofday tv_interval); my $t0 = [gettimeofday]; # # Run the search # sub RunSearch { my($search,$lonmin,$lonmax,$latmax,$latmin)=@_; # Perform the search based on the type my $message=""; my @places=[]; if($main::search_type eq "nominatim") { ($message,@places)=DoNominatimSearch($search,$lonmin,$lonmax,$latmax,$latmin); } else { $message="Unknown search type '$main::search_type'"; } my(undef,undef,$cuser,$csystem) = times; my $time=sprintf "time: %.3f CPU / %.3f elapsed",$cuser+$csystem,tv_interval($t0); # Return the results return($time,$message,@places); } # # Fetch the search URL from Nominatim # sub DoNominatimSearch { my($search,$lonmin,$lonmax,$latmax,$latmin)=@_; $search = uri_escape($search); my $url; if($lonmin && $lonmax && $latmax && $latmin) { $url="$main::search_baseurl?format=json&viewbox=$lonmin,$latmax,$lonmax,$latmin&q=$search"; } else { $url="$main::search_baseurl?format=json&q=$search"; } my $ua=LWP::UserAgent->new; my $res=$ua->get($url); if(!$res->is_success) { return($res->status_line); } my $result=decode_json($res->content); my @places=(); foreach my $place (@$result) { my $lat=$place->{"lat"}; my $lon=$place->{"lon"}; my $name=encode('utf8',$place->{"display_name"}); push(@places,"$lat $lon $name"); } return("",@places); } 1; routino-3.0/web/www/routino/visualiser.leaflet.js 644 233 144 73370 12330730254 15513 0// // Routino data visualiser web page Javascript // // Part of the Routino routing software. // // This file Copyright 2008-2014 Andrew M. Bishop // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . // // // Data types // var data_types=[ "junctions", "super", "waytype", "highway", "transport", "barrier", "turns", "speed", "weight", "height", "width", "length", "property", "errorlogs" ]; //////////////////////////////////////////////////////////////////////////////// /////////////////////////////// Initialisation ///////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // Process the URL query string and extract the arguments var legal={"^lon" : "^[-0-9.]+$", "^lat" : "^[-0-9.]+$", "^zoom" : "^[0-9]+$"}; var args={}; if(location.search.length>1) { var query,queries; query=location.search.replace(/^\?/,""); query=query.replace(/;/g,"&"); queries=query.split("&"); for(var i=0;i" + data_text + ""; document.getElementById("attribution_tile").innerHTML="" + tile_text + ""; } change_attribution(0); // Add two vectors layers (one for highlights that display behind the vectors) layerVectors = L.layerGroup(); map.addLayer(layerVectors); layerHighlights = L.layerGroup(); map.addLayer(layerHighlights); // Handle popup createPopup(); // Add a boxes layer layerBoxes = L.rectangle(map.options.maxBounds,{stroke: false, color: "#f00", weight: 1, opacity: 1.0, fill: false}); map.addLayer(layerBoxes); box=false; // Move the map map.on("moveend", updateURLs); var lon =args["lon"]; var lat =args["lat"]; var zoom=args["zoom"]; if(lon !== undefined && lat !== undefined && zoom !== undefined) { if(lonmapprops.eastedge) lon=mapprops.eastedge; if(latmapprops.northedge) lat=mapprops.northedge; if(zoommapprops.zoomin) zoom=mapprops.zoomin; map.setView(L.latLng(lat,lon),zoom); } else map.fitBounds(map.options.maxBounds); // Unhide editing URL if variable set if(mapprops.editurl !== undefined && mapprops.editurl !== "") { var edit_url=document.getElementById("edit_url"); edit_url.style.display=""; edit_url.href=mapprops.editurl; } updateURLs(); } // // Format a number in printf("%.5f") format. // function format5f(number) { var newnumber=Math.floor(number*100000+0.5); var delta=0; if(newnumber>=0 && newnumber<100000) delta= 100000; if(newnumber<0 && newnumber>-100000) delta=-100000; var string=String(newnumber+delta); var intpart =string.substring(0,string.length-5); var fracpart=string.substring(string.length-5,string.length); if(delta>0) intpart="0"; if(delta<0) intpart="-0"; return(intpart + "." + fracpart); } // // Build a set of URL arguments for the map location // function buildMapArguments() { var lonlat = map.getCenter(); var zoom = map.getZoom(); return "lat=" + format5f(lonlat.lat) + ";lon=" + format5f(lonlat.lng) + ";zoom=" + zoom; } // // Update the URLs // function updateURLs() { var mapargs=buildMapArguments(); var links=document.getElementsByTagName("a"); for(var i=0; i" + id + ""); } } } drawPopup(string.split("\n").join("
")); } //////////////////////////////////////////////////////////////////////////////// /////////////////////////////// Server handling //////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // // Define an AJAX request object // function ajaxGET(url,success,failure,state) { var ajaxRequest=new XMLHttpRequest(); function ajaxGOT(options) { if(this.readyState==4) if(this.status==200) { if(typeof(options.success)=="function") options.success(this,options.state); } else { if(typeof(options.failure)=="function") options.failure(this,options.state); } } ajaxRequest.onreadystatechange = function(){ ajaxGOT.call(ajaxRequest,{success: success, failure: failure, state: state}); }; ajaxRequest.open("GET", url, true); ajaxRequest.send(null); } // // Display the status // function displayStatus(type,subtype,content) { var child=document.getElementById("result_status").firstChild; do { if(child.id !== undefined) child.style.display="none"; child=child.nextSibling; } while(child !== null); var chosen_status=document.getElementById("result_status_" + type); chosen_status.style.display=""; if(subtype !== undefined) { var format_status=document.getElementById("result_status_" + subtype).innerHTML; chosen_status.innerHTML=format_status.replace("#",String(content)); } } // // Display data statistics // function displayStatistics() { // Use AJAX to get the statistics ajaxGET("statistics.cgi", runStatisticsSuccess); } // // Success in running data statistics generation. // function runStatisticsSuccess(response) { document.getElementById("statistics_data").innerHTML="
" + response.responseText + "
"; document.getElementById("statistics_link").style.display="none"; } // // Get the requested data // function displayData(datatype) // called from visualiser.html { for(var data in data_types) hideshow_hide(data_types[data]); if(datatype !== "") hideshow_show(datatype); // Delete the old data unselectFeature(); layerVectors.clearLayers(); layerHighlights.clearLayers(); layerBoxes.setStyle({stroke:false}); box=false; // Print the status displayStatus("no_data"); // Return if just here to clear the data if(datatype === "") return; // Get the new data var mapbounds=map.getBounds(); var url="visualiser.cgi"; url=url + "?lonmin=" + format5f(mapbounds.getWest()); url=url + ";latmin=" + format5f(mapbounds.getSouth()); url=url + ";lonmax=" + format5f(mapbounds.getEast()); url=url + ";latmax=" + format5f(mapbounds.getNorth()); url=url + ";data=" + datatype; // Use AJAX to get the data switch(datatype) { case "junctions": ajaxGET(url, runJunctionsSuccess, runFailure); break; case "super": ajaxGET(url, runSuperSuccess, runFailure); break; case "waytype": var waytype; var waytypes=document.forms["waytypes"].elements["waytype"]; for(var h in waytypes) if(waytypes[h].checked) waytype=waytypes[h].value; url+="-" + waytype; ajaxGET(url, runWaytypeSuccess, runFailure); break; case "highway": var highway; var highways=document.forms["highways"].elements["highway"]; for(var h in highways) if(highways[h].checked) highway=highways[h].value; url+="-" + highway; ajaxGET(url, runHighwaySuccess, runFailure); break; case "transport": var transport; var transports=document.forms["transports"].elements["transport"]; for(var t in transports) if(transports[t].checked) transport=transports[t].value; url+="-" + transport; ajaxGET(url, runTransportSuccess, runFailure); break; case "barrier": var transport; var transports=document.forms["barriers"].elements["barrier"]; for(var t in transports) if(transports[t].checked) transport=transports[t].value; url+="-" + transport; ajaxGET(url, runBarrierSuccess, runFailure); break; case "turns": ajaxGET(url, runTurnsSuccess, runFailure); break; case "speed": case "weight": case "height": case "width": case "length": ajaxGET(url, runLimitSuccess, runFailure); break; case "property": var property; var properties=document.forms["properties"].elements["property"]; for(var p in properties) if(properties[p].checked) property=properties[p].value; url+="-" + property; ajaxGET(url, runPropertySuccess, runFailure); break; case "errorlogs": ajaxGET(url, runErrorlogSuccess, runFailure); break; } } // // Success in getting the junctions. // function runJunctionsSuccess(response) { var lines=response.responseText.split("\n"); var junction_colours={ 0: "#FFFFFF", 1: "#FF0000", 2: "#FFFF00", 3: "#00FF00", 4: "#8B4513", 5: "#00BFFF", 6: "#FF69B4", 7: "#000000", 8: "#000000", 9: "#000000" }; for(var line=0;line Routino : Planowanie trasy dla Danych OpenStreetMap
Opcje Wyniki Dane
Routino OpenStreetMap Planowanie Trasy This web page allows routing within the data collected by OpenStreetMap. Select start and end points (click on the marker icons below), select routing preferences then find a route.
+ - Punkty
+ - Typ transportu
Pieszo:
Konno:
Wózek inwalidzki:
Rower:
Moped:
Motocykl:
Samochód:
Goods:
HGV:
Pojazd użyteczności publicznej:
+ - Preferowanie autostrad
+ - Ograniczenia prędkości
+ - Property Preferences
+ - Inne ograniczenia
Znajdź
+ - Pomoc
Quick Start
Click on marker icons (above) to place them on the map (right). Then drag them to the correct position. Zooming the map before placing the markers is probably easiest. Alternatively type the latitude and longitude into the boxes above.

Select the transport type, allowed highway types, speed limits, highway properties and other restrictions from the options above. Select "Shortest" or "Quickest" to calculate the route and display it on the map.

Waypoints
Clicking on the marker icons will toggle the display of them on the map. When a route is calculated it will visit (as close as possible for the selected transport type) each of the waypoints that have markers on the map in the order given.

Transport Type
Selecting a transport type will restrict the chosen route to those on which it is allowed and set default values for the other parameters.

Highway Preferences
The highway preference is selected as a percentage and routes are chosen that try to follow the preferred highways. For example if a "Primary" road is given a "110%" preference and a "Secondary" road is given a "100%" preference then it means that a route on a Primary road can be up to 10% longer than on a secondary road and still be selected.

Speed Limits
The speed limits chosen here for the different types of highway apply if the highway has no other speed limit marked or it is higher than the chosen one.

Property Preferences
The property preference is selected as a percentage and routes are chosen that try to follow highways with the preferred property. For example if a "Paved" highway is given a "75%" preference then it means that an unpaved highway is automatically given a "25%" preference so that a route on a paved highway can be 3 times the length of an unpaved one and still be selected.

Other Restrictions
These allow a route to be found that avoids marked limits on weight, height, width or length. It is also possible to ignore one-way restrictions (e.g. if walking).

Router: Routino | Geo Data: | Kafelki:
routino-3.0/web/www/routino/.htaccess 644 233 144 3415 12556715416 13140 0## ## Options for Apache web server for language specific web pages and to run ## Routino CGI scripts. ## # The translated router pages use the MultiViews option to serve up a version of # the web page depending on the client language preference. If the line below # is used in a .htaccess file like this one and the "AllowOverride none" option # is set in the main Apache configuration file then the entry in the .htaccess # file will not work. #Options +MultiViews # The English language option will be served if there is no other version # present and no errors will be returned to the user in case of problems LanguagePriority en ForceLanguagePriority Prefer Fallback # The Routino CGI scripts are stored in this directory and use the filename # extension ".cgi". This filename extension needs to be registered with Apache # for the scripts to be executed. AddHandler cgi-script .cgi # The ExecCGI option must be set for the CGIs in this directory to be executed # by Apache. If the line below is used in a .htaccess file like this one and # the "AllowOverride none" option is set in the main Apache configuration file # then the entry in the .htaccess file will not work. #Options +ExecCGI # The CGI scripts that are used by Routino also call some other Perl scripts, to # stop these scripts from being seen by web users they can be denied by the # following entry. Order deny,allow Deny from all # The Polish language web page translations will have a '.html.pl' extension for # the MultiViews option so they must be allowed specifically and not blocked by # the above prohibition on serving Perl scripts. They must also be served with # the HTML mime type. AddType text/html .pl Allow from all routino-3.0/web/www/routino/visualiser.html.ru 644 233 144 53224 12573351577 15071 0 Routino : Data Visualiser for Routing Data
Visualiser Router Data
Routino Visualiser This web page allows visualisation of the data that Routino uses for routing. Only data relevant for routing is displayed and some will therefore be excluded.
+ - Язык
ИнÑтрукции Zoom in and then use the buttons below to download the data. The server will only return data if the selected area is small enough.
СтатуÑ
Ðет данных Ð´Ð»Ñ Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ -
+ - Помощь
Quick Start
Zoom to an area and select one of the buttons to display that type of data.
More data options can be found by expanding the details below each button.

Data Failure
If the area selected is too large (depends on the data type) then the status will say "Failed to get visualiser data" - zoom in and try again.

Router: Routino | Geo Data: | Тайлы:
routino-3.0/web/www/routino/documentation/ 40755 233 144 0 12575036711 14167 5routino-3.0/web/www/routino/search.cgi 755 233 144 4275 12325774546 13306 0#!/usr/bin/perl # # Routino search results retrieval CGI # # Part of the Routino routing software. # # This file Copyright 2012-2014 Andrew M. Bishop # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # use strict; # Use the generic search script require "search.pl"; # Use the perl CGI module use CGI ':cgi'; # Create the query and get the parameters my $query=new CGI; my @rawparams=$query->param; # Legal CGI parameters with regexp validity check my %legalparams=( "marker" => "[0-9]+", "lonmin" => "[-0-9.]+", "lonmax" => "[-0-9.]+", "latmax" => "[-0-9.]+", "latmin" => "[-0-9.]+", "search" => ".+" ); # Validate the CGI parameters, ignore invalid ones my %cgiparams=(); foreach my $key (@rawparams) { foreach my $test (keys (%legalparams)) { if($key =~ m%^$test$%) { my $value=$query->param($key); if($value =~ m%^$legalparams{$test}$%) { $cgiparams{$key}=$value; last; } } } } # Parse the parameters my $marker=$cgiparams{marker}; my $search=$cgiparams{search}; my $lonmin=$cgiparams{lonmin}; my $lonmax=$cgiparams{lonmax}; my $latmax=$cgiparams{latmax}; my $latmin=$cgiparams{latmin}; # Run the search my($search_time,$search_message,@places)=RunSearch($search,$lonmin,$lonmax,$latmax,$latmin); # Return the output print header(-type=>'text/plain',-charset=>'utf-8'); print "$marker\n"; print "$search_time\n"; print "$search_message\n"; foreach my $place (@places) { print "$place\n"; } routino-3.0/web/www/routino/results.cgi 755 233 144 3446 12306670162 13525 0#!/usr/bin/perl # # Routino router results retrieval CGI # # Part of the Routino routing software. # # This file Copyright 2008-2014 Andrew M. Bishop # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # use strict; # Use the generic router script require "router.pl"; # Use the perl CGI module use CGI ':cgi'; # Create the query and get the parameters my $query=new CGI; my @rawparams=$query->param; # Legal CGI parameters with regexp validity check my %legalparams=( "type" => "(shortest|quickest|router)", "format" => "(html|gpx-route|gpx-track|text|text-all|log)", "uuid" => "[0-9a-f]{32}" ); # Validate the CGI parameters, ignore invalid ones my %cgiparams=(); foreach my $key (@rawparams) { foreach my $test (keys (%legalparams)) { if($key =~ m%^$test$%) { my $value=$query->param($key); if($value =~ m%^$legalparams{$test}$%) { $cgiparams{$key}=$value; last; } } } } # Parse the parameters my $uuid =$cgiparams{"uuid"}; my $type =$cgiparams{"type"}; my $format=$cgiparams{"format"}; # Return the file ReturnOutput($uuid,$type,$format); routino-3.0/web/www/routino/visualiser.html 777 233 144 0 12573351577 20010 2visualiser.html.enroutino-3.0/xml/ 40755 233 144 0 12575036711 7016 5routino-3.0/xml/routino-translations.xsd 644 233 144 15101 12572577346 14021 0 routino-3.0/xml/routino-profiles.xml 644 233 144 52066 12327516351 13123 0 routino-3.0/xml/routino-tagging.xsd 644 233 144 10176 12156135452 12711 0 routino-3.0/xml/osc.xsd 644 233 144 13507 12051456324 10357 0 routino-3.0/xml/Makefile 644 233 144 3725 12531654133 10475 0# XML directory Makefile # # Part of the Routino routing software. # # This file Copyright 2010-2015 Andrew M. Bishop # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # # All configuration is in the top-level Makefile.conf include ../Makefile.conf # Files to install STANDARD_FILES=profiles.xml \ translations.xml \ tagging.xml SPECIAL_FILES=tagging-drive.xml \ tagging-ride.xml \ tagging-walk.xml ######## all: $(SPECIAL_FILES) #### tagging-drive.xml : routino-tagging.xml scripts/drive.pl perl scripts/drive.pl < routino-tagging.xml > tagging-drive.xml tagging-ride.xml : routino-tagging.xml scripts/ride.pl perl scripts/ride.pl < routino-tagging.xml > tagging-ride.xml tagging-walk.xml : routino-tagging.xml scripts/walk.pl perl scripts/walk.pl < routino-tagging.xml > tagging-walk.xml ######## test: ######## install: all @[ -d $(DESTDIR)$(datadir) ] || mkdir -p $(DESTDIR)$(datadir) @for file in $(STANDARD_FILES) ; do \ echo cp routino-$$file $(DESTDIR)$(datadir)/$$file ;\ cp -f routino-$$file $(DESTDIR)$(datadir)/$$file ;\ done @for file in $(SPECIAL_FILES); do \ echo cp $$file $(DESTDIR)$(datadir)/$$file ;\ cp -f $$file $(DESTDIR)$(datadir)/$$file ;\ done ######## clean: rm -f *~ rm -f $(SPECIAL_FILES) ######## distclean: clean ######## .PHONY:: all test install clean distclean routino-3.0/xml/routino-tagging-nomodify.xml 644 233 144 2736 11663245320 14516 0 routino-3.0/xml/routino-profiles.xsd 644 233 144 7431 11523232407 13067 0 routino-3.0/xml/scripts/ 40755 233 144 0 12324523025 10474 5routino-3.0/xml/scripts/ride.pl 755 233 144 3656 12306667762 12026 0#!/usr/bin/perl # # Special case tagging rule generator. # # Part of the Routino routing software. # # This file Copyright 2011-2014 Andrew M. Bishop # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # use strict; # Process the input while() { if(m%
%) { print " \n"; print "\n"; print " \n"; print " \n"; print " \n"; print " \n"; print " \n"; print " \n"; print " \n"; print " \n"; print " \n"; print "\n"; print " \n"; print " \n"; print "\n"; print " \n"; print " \n"; print "\n"; } if(m%%) { print " \n"; print "\n"; print " \n"; print " \n"; print " \n"; print "\n"; } print; } routino-3.0/xml/scripts/walk.pl 755 233 144 4214 12324523025 12007 0#!/usr/bin/perl # # Special case tagging rule generator. # # Part of the Routino routing software. # # This file Copyright 2011-2014 Andrew M. Bishop # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # use strict; # Process the input while() { if(m%
%) { print " \n"; print "\n"; print " \n"; print " \n"; print " \n"; print " \n"; print " \n"; print " \n"; print " \n"; print " \n"; print " \n"; print "\n"; print " \n"; print "\n"; print " \n"; print " \n"; print "\n"; print " \n"; print " \n"; print " \n"; print "\n"; } if(m%%) { print " \n"; print "\n"; print " \n"; print " \n"; print "\n"; print " \n"; print " \n"; print "\n"; } print; } routino-3.0/xml/scripts/drive.pl 755 233 144 3616 12324522764 12200 0#!/usr/bin/perl # # Special case tagging rule generator. # # Part of the Routino routing software. # # This file Copyright 2011-2014 Andrew M. Bishop # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # use strict; # Process the input while() { if(m%%) { print " \n"; print "\n"; print " \n"; print " \n"; print " \n"; print " \n"; print " \n"; print "\n"; print " \n"; print " \n"; print " \n"; print " \n"; print " \n"; print " \n"; print "\n"; } if(m%%) { print " \n"; print "\n"; print " \n"; print " \n"; print " \n"; print " \n"; print "\n"; } print; } routino-3.0/xml/routino-osm.xsd 644 233 144 13477 12051504736 12075 0 routino-3.0/xml/xsd.xsd 644 233 144 5261 11506610624 10346 0 routino-3.0/xml/routino-tagging.xml 644 233 144 75725 12453270124 12722 0 routino-3.0/xml/routino-osc.xsd 644 233 144 13542 12051456376 12062 0 routino-3.0/xml/osm.xsd 644 233 144 13460 12042033044 10355 0 routino-3.0/xml/routino-translations.xml 644 233 144 104675 12573351577 14057 0 <!-- %s = [shortest|quickest] --> <start text="Start at %s, head %s" /> <!-- 1st %s = [waypoint|junction], 2nd %s = [heading] --> <node text="At %s, go %s heading %s" /> <!-- 1st %s = [waypoint|junction], 2nd %s = [turn], 3rd %s = [heading] --> <rbnode text="Leave %s, take the %s exit heading %s" /> <!-- 1st %s = [roundabout], 2nd %s = [first|second|...], 3rd %s = [heading] --> <segment text="Follow %s for %.3f km, %.1f min" /> <!-- 1st %s = street name --> <stop text="Stop at %s" /> <!-- 1st %s = [waypoint|junction] --> <total text="Total %.1f km, %.0f minutes" /> <subtotal text="%.1f km, %.0f minutes" /> </output-html> <!-- GPX output --> <output-gpx> <waypoint type="start" string="START" /> <!-- For the first route waypoint --> <waypoint type="inter" string="INTER" /> <!-- For the intermediate route waypoints --> <waypoint type="trip" string="TRIP" /> <!-- For the other route points --> <waypoint type="finish" string="FINISH"/> <!-- For the last route waypoint --> <desc text="%s route between 'start' and 'finish' waypoints" /> <!-- %s = [shortest|quickest] --> <name text="%s route" /> <!-- %s = [shortest|quickest] --> <step text="%s on '%s' for %.3f km, %.1f min" /> <!-- 1st %s = [turn], 2nd %s = street name --> <final text="Total Journey %.1f km, %.0f minutes" /> </output-gpx> </language> <language lang="de" language="Deutsch"> <!-- Copyright of the data being routed, not of this file --> <copyright> <creator string="Urheber" text="Routino - http://www.routino.org/" /> <source string="Quelle" text="Basierend auf OpenStreetMap-Daten, erhältlich via http://www.openstreetmap.org/" /> <license string="Lizenz" text="http://www.openstreetmap.org/copyright" /> </copyright> <!-- Turn directions, 0 = ahead, -2 = left, +/-4 = behind, +2 = right --> <turn direction="-4" string="Sehr scharf links" /> <turn direction="-3" string="Scharf links" /> <turn direction="-2" string="Links" /> <turn direction="-1" string="Halb links" /> <turn direction="0" string="Geradeaus" /> <turn direction="1" string="Halb rechts" /> <turn direction="2" string="Rechts" /> <turn direction="3" string="Scharf rechts" /> <turn direction="4" string="Sehr scharf rechts" /> <!-- Heading directions, 0 = North, -2 = West, +/-4 = South, +2 = East --> <heading direction="-4" string="Süd" /> <heading direction="-3" string="Süd-West" /> <heading direction="-2" string="West" /> <heading direction="-1" string="Nord-West" /> <heading direction="0" string="Nord" /> <heading direction="1" string="Nord-Ost" /> <heading direction="2" string="Ost" /> <heading direction="3" string="Süd-Ost" /> <heading direction="4" string="Süd" /> <!-- Ordinals, 1 = first, 2 = second ... --> <ordinal number="1" string="Erste" /> <ordinal number="2" string="Zweite" /> <ordinal number="3" string="Dritte" /> <ordinal number="4" string="Vierte" /> <ordinal number="5" string="Fünfte" /> <ordinal number="6" string="Sechste" /> <ordinal number="7" string="Siebte" /> <ordinal number="8" string="Achte" /> <ordinal number="9" string="Neunte" /> <ordinal number="10" string="Zehnte" /> <!-- Highway names --> <highway type="motorway" string="Autobahn" /> <highway type="trunk" string="Schnellstraße" /> <highway type="primary" string="Bundesstraße" /> <highway type="secondary" string="Landesstraße" /> <highway type="tertiary" string="Kreisstraße" /> <highway type="unclassified" string="Nebenstraße" /> <highway type="residential" string="Wohngebietsstraße" /> <highway type="service" string="Erschließungsweg" /> <highway type="track" string="Feld-/Waldweg" /> <highway type="cycleway" string="Radweg" /> <highway type="path" string="Weg/Pfad" /> <highway type="steps" string="Treppe" /> <highway type="ferry" string="Fähre" /> <!-- The type of route --> <route type="shortest" string="Kürzeste" /> <!-- For the description and route name --> <route type="quickest" string="Schnellste" /> <!-- For the description and route name --> <!-- HTML output --> <output-html> <waypoint type="waypoint" string="Wegpunkt" /> <!-- For the chosen waypoints --> <waypoint type="junction" string="Anschlussstelle" /> <!-- For the interesting junctions --> <waypoint type="roundabout" string="Kreisverkehr" /> <!-- For roundabouts --> <title text="%s Route" /> <!-- %s = [shortest|quickest] --> <start text="Start bei %s halten Sie sich Richtung %s" /> <!-- 1st %s = [waypoint|junction], 2nd %s = [heading] --> <node text="Bei %s wenden Sie sich nach %s Richtung %s" /> <!-- 1st %s = [waypoint|junction], 2nd %s = [turn], 3rd %s = [heading] --> <rbnode text="Verlassen Sie %s, nehmen Sie die %s Ausfahrt Richtung %s" /> <!-- 1st %s = [roundabout], 2nd %s = [first|second|...], 3rd %s = [heading] --> <segment text="Folgen Sie der %s für %.3f km bzw. %.1f min" /> <!-- 1st %s = street name --> <stop text="Stop Sie sind bei %s angekommen" /> <!-- 1st %s = [waypoint|junction] --> <total text="Gesamt %.1f km, %.0f minuten" /> <subtotal text="%.1f km, %.0f minuten" /> </output-html> <!-- GPX output --> <output-gpx> <waypoint type="start" string="START" /> <!-- For the first route waypoint --> <waypoint type="inter" string="INTER" /> <!-- For the intermediate route waypoints --> <waypoint type="trip" string="TRIP" /> <!-- For the other route points --> <waypoint type="finish" string="FINISH"/> <!-- For the last route waypoint --> <desc text="%s Strecke zwischen 'Start' und 'Ziel'" /> <!-- %s = [shortest|quickest] --> <name text="%s Strecke" /> <!-- %s = [shortest|quickest] --> <step text="%s auf '%s' für %.3f km, %.1f min" /> <!-- 1st %s = [turn], 2nd %s = street name --> <final text="Gesamtstrecke %.1f km, %.0f minuten" /> </output-gpx> </language> <language lang="fr" language="Francais"> <!-- Copyright of the data being routed, not of this file --> <copyright> <creator string="Créateur" text="Routino - http://www.routino.org/" /> <source string="Source" text="Basé sur les données OpenStreetMap de http://www.openstreetmap.org/" /> <license string="License" text="http://www.openstreetmap.org/copyright" /> </copyright> <!-- Turn directions, 0 = ahead, -2 = left, +/-4 = behind, +2 = right --> <turn direction="-4" string="demi-tour à gauche" /> <turn direction="-3" string="Très à gauche" /> <turn direction="-2" string="à gauche" /> <turn direction="-1" string="Légèrement à gauche" /> <turn direction="0" string="Tout droit" /> <turn direction="1" string="légèrement à droite" /> <turn direction="2" string="à droite" /> <turn direction="3" string="très à droite" /> <turn direction="4" string="demi-tour à droite" /> <!-- Heading directions, 0 = North, -2 = West, +/-4 = South, +2 = East --> <heading direction="-4" string="Sud" /> <heading direction="-3" string="Dud-Ouest" /> <heading direction="-2" string="Ouest" /> <heading direction="-1" string="Nord-Ouest" /> <heading direction="0" string="Nord" /> <heading direction="1" string="Nord-Est" /> <heading direction="2" string="Est" /> <heading direction="3" string="Sud-Est" /> <heading direction="4" string="Sud" /> <!-- Ordinals, 1 = first, 2 = second ... --> <ordinal number="1" string="Premier" /> <ordinal number="2" string="Second" /> <ordinal number="3" string="Troisième" /> <ordinal number="4" string="Quatrième" /> <ordinal number="5" string="Cinquième" /> <ordinal number="6" string="Sixième" /> <ordinal number="7" string="Septième" /> <ordinal number="8" string="huitième" /> <ordinal number="9" string="Neuvième" /> <ordinal number="10" string="Dixième" /> <!-- Highway names --> <highway type="motorway" string="autoroute" /> <highway type="trunk" string="route de jonction" /> <highway type="primary" string="route nationale" /> <highway type="secondary" string="route départementale" /> <highway type="tertiary" string="route locale" /> <highway type="unclassified" string="route non classifiée" /> <highway type="residential" string="rue résidentielle" /> <highway type="service" string="rue de service" /> <highway type="track" string="chemin" /> <highway type="cycleway" string="voie cyclable" /> <highway type="path" string="sentier" /> <highway type="steps" string="escalier" /> <highway type="ferry" string="ferry" /> <!-- The type of route --> <route type="shortest" string="le plus court" /> <!-- For the description and route name --> <route type="quickest" string="le plus rapide" /> <!-- For the description and route name --> <!-- HTML output --> <output-html> <waypoint type="waypoint" string="Etape" /> <!-- For the chosen waypoints --> <waypoint type="junction" string="Croisement" /> <!-- For the interesting junctions --> <waypoint type="roundabout" string="rond-point" /> <!-- For roundabouts --> <title text="Itinéraire %s" /> <!-- %s = [shortest|quickest] --> <start text="Débute à %s, direction %s" /> <!-- 1st %s = [waypoint|junction], 2nd %s = [heading] --> <node text="à %s, aller %s direction %s" /> <!-- 1st %s = [waypoint|junction], 2nd %s = [turn], 3rd %s = [heading] --> <rbnode text="Quitter %s, prendre le %s sortir direction %s" /> <!-- 1st %s = [roundabout], 2nd %s = [first|second|...], 3rd %s = [heading] --> <segment text="Suivre %s pendant %.3f km, %.1f min" /> <!-- 1st %s = street name --> <stop text="S'arrêter à %s" /> <!-- 1st %s = [waypoint|junction] --> <total text="Total %.1f km, %.0f minutes" /> <subtotal text="%.1f km, %.0f minutes" /> </output-html> <!-- GPX output --> <output-gpx> <waypoint type="start" string="DEBUT" /> <!-- For the first route waypoint --> <waypoint type="inter" string="INTER" /> <!-- For the intermediate route waypoints --> <waypoint type="trip" string="POINT" /> <!-- For the other route points --> <waypoint type="finish" string="FINAL"/> <!-- For the last route waypoint --> <desc text="Itinéraire %s entre les étapes 'début' et 'fin'" /> <!-- %s = [shortest|quickest] --> <name text="Itinéraire %s" /> <!-- %s = [shortest|quickest] --> <step text="%s sur '%s' pendant %.3f km, %.1f min" /> <!-- 1st %s = [turn], 2nd %s = street name --> <final text="Trajet total %.1f km, %.0f minutes" /> </output-gpx> </language> <language lang="hu" language="Magyar"> <!-- Copyright of the data being routed, not of this file --> <copyright> <creator string="KészítÅ‘" text="Routino - http://www.routino.org/" /> <source string="Forrás" text="Openstreetmap adatok alapján http://www.openstreetmap.org/" /> <license string="Liszenc" text="http://www.openstreetmap.org/copyright" /> </copyright> <!-- Turn directions, 0 = ahead, -2 = left, +/-4 = behind, +2 = right --> <turn direction="-4" string="Nagyon élesen balra" /> <turn direction="-3" string="Élesen balra" /> <turn direction="-2" string="Balra" /> <turn direction="-1" string="Balra tarts" /> <turn direction="0" string="Egyenesen" /> <turn direction="1" string="Jobbra tarts" /> <turn direction="2" string="Jobbra" /> <turn direction="3" string="Élesen jobbra" /> <turn direction="4" string="Nagyon élesen jobbra" /> <!-- Heading directions, 0 = North, -2 = West, +/-4 = South, +2 = East --> <heading direction="-4" string="dél" /> <heading direction="-3" string="délnyugat" /> <heading direction="-2" string="nyugat" /> <heading direction="-1" string="északnyugat" /> <heading direction="0" string="észak" /> <heading direction="1" string="északkelet" /> <heading direction="2" string="kelet" /> <heading direction="3" string="délkelet" /> <heading direction="4" string="dél" /> <!-- Ordinals, 1 = first, 2 = second ... --> <ordinal number="1" string="elsÅ‘" /> <ordinal number="2" string="második" /> <ordinal number="3" string="harmadik" /> <ordinal number="4" string="negyedik" /> <ordinal number="5" string="ötödik" /> <ordinal number="6" string="hatodik" /> <ordinal number="7" string="hetedik" /> <ordinal number="8" string="nyolcadik" /> <ordinal number="9" string="kilencedik" /> <ordinal number="10" string="tizedik" /> <!-- Highway names --> <highway type="motorway" string="autópálya" /> <highway type="trunk" string="autóút" /> <highway type="primary" string="főút" /> <highway type="secondary" string="összekötőút" /> <highway type="tertiary" string="bekötőút" /> <highway type="unclassified" string="egyéb közút" /> <highway type="residential" string="lakóút" /> <highway type="service" string="szervízút" /> <highway type="track" string="földút" /> <highway type="cycleway" string="kerékpárút" /> <highway type="path" string="ösvény" /> <highway type="steps" string="lépcsÅ‘" /> <highway type="ferry" string="komp" /> <!-- The type of route --> <route type="shortest" string="Legrövidebb" /> <!-- For the description and route name --> <route type="quickest" string="Leggyorsabb" /> <!-- For the description and route name --> <!-- HTML output --> <output-html> <waypoint type="waypoint" string="Útpont" /> <!-- For the chosen waypoints --> <waypoint type="junction" string="KeresztezÅ‘dés" /> <!-- For the interesting junctions --> <waypoint type="roundabout" string="Körforgalom" /> <!-- For roundabouts --> <title text="%s útvonal" /> <!-- %s = [shortest|quickest] --> <start text="Indulás %s, %s felé" /> <!-- 1st %s = [waypoint|junction], 2nd %s = [heading] --> <node text="Itt %s, menj %s %s felé" /> <!-- 1st %s = [waypoint|junction], 2nd %s = [turn], 3rd %s = [heading] --> <rbnode text="Kijárat %s, %s kijárat %s felé" /> <!-- 1st %s = [roundabout], 2nd %s = [first|second|...], 3rd %s = [heading] --> <segment text="Erre %s, %.3f km, %.1f perc" /> <!-- 1st %s = street name --> <!-- TRANSLATION REQUIRED: stop text="Stop at %s" / --> <!-- 1st %s = [waypoint|junction] --> <total text="Összesen %.1f km, %.0f perc" /> <subtotal text="%.1f km, %.0f perc" /> </output-html> <!-- GPX output --> <output-gpx> <waypoint type="start" string="Indulás" /> <!-- For the first route waypoint --> <!-- TRANSLATION REQUIRED: waypoint type="inter" string="INTER" / --> <!-- For the intermediate route waypoints --> <waypoint type="trip" string="Utazás" /> <!-- For the other route points --> <!-- TRANSLATION REQUIRED: waypoint type="finish" string="FINISH"/ --> <!-- For the last route waypoint --> <desc text="%s útvonal a kezdÅ‘ és utolsó pont között" /> <!-- %s = [shortest|quickest] --> <!-- TRANSLATION REQUIRED: name text="%s route" / --> <!-- %s = [shortest|quickest] --> <!-- TRANSLATION REQUIRED: step text="%s on '%s' for %.3f km, %.1f min" / --> <!-- 1st %s = [turn], 2nd %s = street name --> <final text="Az egész út %.1f km, %.0f perc" /> </output-gpx> </language> <language lang="nl" language="Nederlands"> <!-- Copyright of the data being routed, not of this file --> <copyright> <creator string="Creator" text="Routino - http://www.routino.org/" /> <source string="Source" text="Gebouwd op OpenStreetMap data van http://www.openstreetmap.org/" /> <license string="License" text="http://www.openstreetmap.org/copyright" /> </copyright> <!-- Turn directions, 0 = ahead, -2 = left, +/-4 = behind, +2 = right --> <turn direction="-4" string="Haarspeld naar links" /> <turn direction="-3" string="Scherp links" /> <turn direction="-2" string="Links" /> <turn direction="-1" string="Half links" /> <turn direction="0" string="Rechtdoor" /> <turn direction="1" string="Half rechts" /> <turn direction="2" string="Rechts" /> <turn direction="3" string="Scherp rechts" /> <turn direction="4" string="Haarspeld naar rechts" /> <!-- Heading directions, 0 = North, -2 = West, +/-4 = South, +2 = East --> <heading direction="-4" string="Zuid" /> <heading direction="-3" string="Zuid-West" /> <heading direction="-2" string="West" /> <heading direction="-1" string="Noord-West" /> <heading direction="0" string="Noord" /> <heading direction="1" string="Noord-Oost" /> <heading direction="2" string="Oost" /> <heading direction="3" string="Zuid-Oost" /> <heading direction="4" string="Zuid" /> <!-- Ordinals, 1 = first, 2 = second ... --> <ordinal number="1" string="Eerste" /> <ordinal number="2" string="Tweede" /> <ordinal number="3" string="Derde" /> <ordinal number="4" string="Vierde" /> <ordinal number="5" string="Vijfde" /> <ordinal number="6" string="Zesde" /> <ordinal number="7" string="Zevende" /> <ordinal number="8" string="Achtste" /> <ordinal number="9" string="Negende" /> <ordinal number="10" string="Tiende" /> <!-- Highway names --> <highway type="motorway" string="Autostrade" /> <highway type="trunk" string="Autoweg" /> <highway type="primary" string="Provinciale weg" /> <highway type="secondary" string="Nationale weg" /> <highway type="tertiary" string="Doorgangsweg" /> <highway type="unclassified" string="Niet geclassificeerd" /> <highway type="residential" string="Woongebied" /> <highway type="service" string="Toegangsweg" /> <highway type="track" string="Veldweg" /> <highway type="cycleway" string="Fietspad" /> <highway type="path" string="Pad" /> <highway type="steps" string="Trap" /> <highway type="ferry" string="Veerboot" /> <!-- The type of route --> <route type="shortest" string="Kortste" /> <!-- For the description and route name --> <route type="quickest" string="Snelste" /> <!-- For the description and route name --> <!-- HTML output --> <output-html> <waypoint type="waypoint" string="Punt" /> <!-- For the chosen waypoints --> <waypoint type="junction" string="de splitsing" /> <!-- For the interesting junctions --> <waypoint type="roundabout" string="rotonde" /> <!-- For roundabouts --> <title text="%s Route" /> <!-- %s = [shortest|quickest] --> <start text="Start bij %s neemt u de richting %s" /> <!-- 1st %s = [waypoint|junction], 2nd %s = [heading] --> <node text="Bij %s gaat u %s richting %s" /> <!-- 1st %s = [waypoint|junction], 2nd %s = [turn], 3rd %s = [heading] --> <rbnode text="Leave aan de %s, neem de %s afslag richting %s" /> <!-- 1st %s = [roundabout], 2nd %s = [first|second|...], 3rd %s = [heading] --> <segment text="Volg u de %s voor %.3f km %.1f min" /> <!-- 1st %s = street name --> <stop text="Stop U bent bij %s aangekomen" /> <!-- 1st %s = [waypoint|junction] --> <total text="Totaal %.1f km, %.0f minuten" /> <subtotal text="%.1f km, %.0f minuten" /> </output-html> <!-- GPX output --> <output-gpx> <waypoint type="start" string="START" /> <!-- For the first route waypoint --> <waypoint type="inter" string="INTER" /> <!-- For the intermediate route waypoints --> <waypoint type="trip" string="TRIP" /> <!-- For the other route points --> <waypoint type="finish" string="FINISH"/> <!-- For the last route waypoint --> <desc text="%s Route tussen 'Start' und 'Finish'" /> <!-- %s = [shortest|quickest] --> <name text="%s Route" /> <!-- %s = [shortest|quickest] --> <step text="%s op '%s' voor %.3f km, %.1f min" /> <!-- 1st %s = [turn], 2nd %s = street name --> <final text="Totaal trip %.1f km, %.0f minuten" /> </output-gpx> </language> <language lang="pl" language="Polski"> <!-- Copyright of the data being routed, not of this file --> <copyright> <creator string="Twórca" text="Routino - http://www.routino.org/" /> <source string="ŹródÅ‚o" text="Oparte na danych OpenStreetMap ze strony http://www.openstreetmap.org/" /> <license string="Licencja" text="http://www.openstreetmap.org/copyright" /> </copyright> <!-- Turn directions, 0 = ahead, -2 = left, +/-4 = behind, +2 = right --> <turn direction="-4" string="Bardzo ostro w lewo" /> <turn direction="-3" string="Ostro w lewo" /> <turn direction="-2" string="W lewo" /> <turn direction="-1" string="Lekko w lewo" /> <turn direction="0" string="Prosto" /> <turn direction="1" string="Lekko w prawo" /> <turn direction="2" string="W prawo" /> <turn direction="3" string="Ostro w prawo" /> <turn direction="4" string="Bardzo ostro w prawo" /> <!-- Heading directions, 0 = North, -2 = West, +/-4 = South, +2 = East --> <heading direction="-4" string="Na poÅ‚udnie" /> <heading direction="-3" string="Na poÅ‚udniowy zachód" /> <heading direction="-2" string="Na zachód" /> <heading direction="-1" string="Na północny zachód" /> <heading direction="0" string="Na północ" /> <heading direction="1" string="Na północny wschód" /> <heading direction="2" string="Na wschód" /> <heading direction="3" string="Na poÅ‚udniowy wschód" /> <heading direction="4" string="Na poÅ‚udnie" /> <!-- Ordinals, 1 = first, 2 = second ... --> <ordinal number="1" string="Pierwszy" /> <ordinal number="2" string="Drugi" /> <ordinal number="3" string="Trzeci" /> <ordinal number="4" string="Czwarty" /> <ordinal number="5" string="PiÄ…ty" /> <ordinal number="6" string="Szósty" /> <ordinal number="7" string="Siódmy" /> <ordinal number="8" string="Ósmy" /> <ordinal number="9" string="DziewiÄ…ty" /> <ordinal number="10" string="DziesiÄ…ty" /> <!-- Highway names --> <highway type="motorway" string="Autostrada" /> <highway type="trunk" string="Droga ekspresowa" /> <highway type="primary" string="Droga krajowa" /> <highway type="secondary" string="Droga powiatowa" /> <highway type="tertiary" string="Droga lokalna" /> <highway type="unclassified" string="Droga nieznanego typu" /> <highway type="residential" string="Droga osiedlowa" /> <highway type="service" string="Droga dojazdowa" /> <highway type="track" string="Droga polna" /> <highway type="cycleway" string="Droga rowerowa" /> <highway type="path" string="Åšcieżka" /> <highway type="steps" string="Pieszo" /> <highway type="ferry" string="Prom" /> <!-- The type of route --> <route type="shortest" string="Najkrótsza" /> <!-- For the description and route name --> <route type="quickest" string="Najszybsza" /> <!-- For the description and route name --> <!-- HTML output --> <output-html> <waypoint type="waypoint" string="Punkt" /> <!-- For the chosen waypoints --> <!-- TRANSLATION REQUIRED: waypoint type="junction" string="Junction" / --> <!-- For the interesting junctions --> <waypoint type="roundabout" string="Rondo" /> <!-- For roundabouts --> <title text="%s Trasa" /> <!-- %s = [shortest|quickest] --> <start text="Start %s kieruj siÄ™ na %s" /> <!-- 1st %s = [waypoint|junction], 2nd %s = [heading] --> <!-- TRANSLATION REQUIRED: node text="At %s, go %s heading %s" / --> <!-- 1st %s = [waypoint|junction], 2nd %s = [turn], 3rd %s = [heading] --> <!-- TRANSLATION REQUIRED: rbnode text="Leave %s, take the %s exit heading %s" / --> <!-- 1st %s = [roundabout], 2nd %s = [first|second|...], 3rd %s = [heading] --> <segment text="Podążaj %s przez %.3f km, %.1f min." /> <!-- 1st %s = street name --> <stop text="Stop Na %s" /> <!-- 1st %s = [waypoint|junction] --> <total text="CaÅ‚kowity %.1f km, %.0f min." /> <subtotal text="%.1f km, %.0f min." /> </output-html> <!-- GPX output --> <output-gpx> <waypoint type="start" string="START" /> <!-- For the first route waypoint --> <waypoint type="inter" string="INTER" /> <!-- For the intermediate route waypoints --> <waypoint type="trip" string="TRIP" /> <!-- For the other route points --> <waypoint type="finish" string="KONIEC"/> <!-- For the last route waypoint --> <desc text="%s trasa pomiÄ™dzy 'start' a 'koniec'" /> <!-- %s = [shortest|quickest] --> <name text="%s trasa" /> <!-- %s = [shortest|quickest] --> <step text="%s na %s przez %.3f km, %.1f min." /> <!-- 1st %s = [turn], 2nd %s = street name --> <final text="CaÅ‚kowita podróż %.1f km, %.0f min." /> </output-gpx> </language> <language lang="ru" language="РуÑÑкий"> <!-- Copyright of the data being routed, not of this file --> <copyright> <creator string="Ðвтор" text="Routino - http://www.routino.org/" /> <source string="ИÑточник" text="ИÑпользованы данные OpenStreetMap http://www.openstreetmap.org/" /> <license string="ЛицензиÑ" text="http://www.openstreetmap.org/copyright" /> </copyright> <!-- Turn directions, 0 = ahead, -2 = left, +/-4 = behind, +2 = right --> <turn direction="-4" string="очень крутой поворот налево" /> <turn direction="-3" string="крутой поворот налево" /> <turn direction="-2" string="налево" /> <turn direction="-1" string="плавно налево" /> <turn direction="0" string="прÑмо" /> <turn direction="1" string="плавно направо" /> <turn direction="2" string="направо" /> <turn direction="3" string="крутой поворот направо" /> <turn direction="4" string="очень крутой поворот направо" /> <!-- Heading directions, 0 = North, -2 = West, +/-4 = South, +2 = East --> <heading direction="-4" string="юг" /> <heading direction="-3" string="юго-запад" /> <heading direction="-2" string="запад" /> <heading direction="-1" string="Ñеверо-запад" /> <heading direction="0" string="Ñевер" /> <heading direction="1" string="Ñеверо-воÑток" /> <heading direction="2" string="воÑток" /> <heading direction="3" string="юго-воÑток" /> <heading direction="4" string="юг" /> <!-- Ordinals, 1 = first, 2 = second ... --> <ordinal number="1" string="Первый" /> <ordinal number="2" string="Второй" /> <ordinal number="3" string="Третий" /> <ordinal number="4" string="Четвертый" /> <ordinal number="5" string="ПÑтый" /> <ordinal number="6" string="ШеÑтой" /> <ordinal number="7" string="Седьмой" /> <ordinal number="8" string="ВоÑьмой" /> <ordinal number="9" string="ДевÑтый" /> <ordinal number="10" string="ДеÑÑтый" /> <!-- Highway names --> <highway type="motorway" string="автомагиÑтраль" /> <highway type="trunk" string="Ð¼ÐµÐ¶Ð´ÑƒÐ½Ð°Ñ€Ð¾Ð´Ð½Ð°Ñ Ñ‚Ñ€Ð°ÑÑа" /> <highway type="primary" string="дорога регионального значениÑ" /> <highway type="secondary" string="дорога облаÑтного значениÑ" /> <highway type="tertiary" string="дорога районного значениÑ" /> <highway type="unclassified" string="дорога меÑтного значениÑ" /> <highway type="residential" string="улица" /> <highway type="service" string="проезд" /> <highway type="track" string="дорога Ñ/Ñ… назначениÑ" /> <highway type="cycleway" string="велодорожка" /> <highway type="path" string="тропинка" /> <highway type="steps" string="леÑтница" /> <highway type="ferry" string="паром" /> <!-- The type of route --> <route type="shortest" string="Короткий" /> <!-- For the description and route name --> <route type="quickest" string="БыÑтрый" /> <!-- For the description and route name --> <!-- HTML output --> <output-html> <waypoint type="waypoint" string="Ð¿ÑƒÑ‚ÐµÐ²Ð°Ñ Ñ‚Ð¾Ñ‡ÐºÐ°" /> <!-- For the chosen waypoints --> <waypoint type="junction" string="перекреÑтке" /> <!-- For the interesting junctions --> <!-- TRANSLATION REQUIRED: waypoint type="roundabout" string="Roundabout" / --> <!-- For roundabouts --> <title text="%s маршрут" /> <!-- %s = [shortest|quickest] --> <start text="Старт %s, на %s" /> <!-- 1st %s = [waypoint|junction], 2nd %s = [heading] --> <node text="на %s, %s, на %s" /> <!-- 1st %s = [waypoint|junction], 2nd %s = [turn], 3rd %s = [heading] --> <!-- TRANSLATION REQUIRED: rbnode text="Leave %s, take the %s exit heading %s" / --> <!-- 1st %s = [roundabout], 2nd %s = [first|second|...], 3rd %s = [heading] --> <segment text="Следуйте по %s %.3f км, %.1f мин" /> <!-- 1st %s = street name --> <stop text="Стоп %s" /> <!-- 1st %s = [waypoint|junction] --> <total text="Ð’Ñего %.1f км, %.0f минут" /> <subtotal text="%.1f км, %.0f минут" /> </output-html> <!-- GPX output --> <output-gpx> <waypoint type="start" string="Старт" /> <!-- For the first route waypoint --> <waypoint type="inter" string="INTER" /> <!-- For the intermediate route waypoints --> <waypoint type="trip" string="TRIP" /> <!-- For the other route points --> <waypoint type="finish" string="Финиш"/> <!-- For the last route waypoint --> <desc text="%s маршрут от 'Старта' до 'Финиша'" /> <!-- %s = [shortest|quickest] --> <name text="%s маршрут" /> <!-- %s = [shortest|quickest] --> <step text="на %s по '%s' %.3f км, %.1f мин" /> <!-- 1st %s = [turn], 2nd %s = street name --> <final text="Ð’Ñего - %.1f км, продолжительноÑть - %.0f минут" /> </output-gpx> </language> </routino-translations> �������������������������������������������������������������������routino-3.0/ChangeLog������������������������������������������������������������������������������� 644 � 233 � 144 � 1124715 12575040001 10062� 0�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������2015-09-12 Andrew M. Bishop <amb> Version 3.0 released. 2015-09-12 [r1798] Andrew M. Bishop <amb> * FILES, doc/NEWS.txt, doc/README.txt, doc/html/readme.html: Update files for release. 2015-09-09 [r1797] Andrew M. Bishop <amb> * doc/USAGE.txt, doc/html/usage.html, extras/find-fixme/README.txt, extras/find-fixme/fixme-dumper.c, extras/find-fixme/fixme-finder.c, extras/tagmodifier/README.txt, extras/tagmodifier/tagmodifier.c, src/filedumper.c, src/filedumperx.c, src/planetsplitter.c, src/router+lib.c, src/router.c, src/version.h (added): Add a '--version' option to all executables to print the current version (defined in version.h). 2015-09-07 [r1796] Andrew M. Bishop <amb> * src/output.c, src/translations.c, web/translations/translation.de.txt, web/translations/translation.en.txt, web/translations/translation.fr.txt, web/translations/translation.hu.txt, web/translations/translation.nl.txt, web/translations/translation.pl.txt, web/translations/translation.ru.txt, web/translations/translations-body.xml, web/translations/translations-head.xml, web/www/routino/router.leaflet.js, web/www/routino/router.openlayers.js, xml/routino-translations.xml, xml/routino-translations.xsd: Merge some of the translation phrases together to simplify them. Change the HTML output and web pages to work with this. 2015-09-03 [r1795] Andrew M. Bishop <amb> * doc/LIBRARY.txt, doc/html/library.html, src/output.c, src/router+lib.c, src/routino.c, src/routino.h: Add in an HTML-all linked list formats that includes the full set of points and the HTML directions for the important ones. 2015-09-03 [r1794] Andrew M. Bishop <amb> * src/router.c: Bug fix in usage information. 2015-08-17 [r1793] Andrew M. Bishop <amb> * web/www/routino/router.leaflet.js, web/www/routino/router.openlayers.js: Fix a bug with dragging a marker from the left panel onto the map when the left panel has scrolled the page. 2015-08-17 [r1792] Andrew M. Bishop <amb> * doc/LIBRARY.txt, doc/html/library.html, src/router+lib.c, src/routino.c, src/routino.h, src/translations.c, src/translations.h: Add a new API function to return the full names of the languages available in the translations XML file. Increase API version to 6. 2015-08-17 [r1791] Andrew M. Bishop <amb> * src/test/copyright.xml, src/translations.c, src/translations.h, web/translations/translate.pl, web/translations/translations-body.xml, xml/routino-translations.xml, xml/routino-translations.xsd: Add the long version of the language name to the XML translations file. 2015-08-17 [r1790] Andrew M. Bishop <amb> * web/translations/translation.de.txt: Replace one German word (via http://www.routino.org/translations/). 2015-08-16 [r1789] Andrew M. Bishop <amb> * web/translations/translate.pl, web/translations/translation.pl.txt, xml/routino-translations.xml: Delete some Polish documentation strings that were incorrectly formed (not enough '%s'). 2015-08-15 [r1788] Andrew M. Bishop <amb> * doc/html/index.html, doc/html/installation-ms-windows.html, doc/html/installation.html: Some small documentation tidying up. 2015-08-15 [r1787] Andrew M. Bishop <amb> * extras/find-fixme/Makefile, extras/tagmodifier/Makefile, src/Makefile, src/xml/Makefile: Use $^ instead of $< in Makefiles where it is simpler and where there are multiple dependencies that all need to be used together. 2015-08-15 [r1786] Andrew M. Bishop <amb> * src/test/Makefile: Compile the executables all in one go rather than running make for each one. 2015-08-15 [r1785] Andrew M. Bishop <amb> * Makefile, src/Makefile: Don't automatically choose the order in which to enter the sub-directories but hard-code it to make it more sensible. 2015-08-15 [r1784] Andrew M. Bishop <amb> * Makefile.conf, doc/INSTALL-MS-WIN.txt, doc/LIBRARY.txt (added), doc/html/index.html, doc/html/installation-ms-windows.html, doc/html/library.html (added), extras/find-fixme/Makefile, extras/find-fixme/fixme-dumper.c, extras/find-fixme/fixme-finder.c, extras/find-fixme/osmparser.c, extras/tagmodifier/Makefile, extras/tagmodifier/tagmodifier.c, src, src/Makefile, src/errorlogx.c, src/fakes.c, src/fakes.h, src/filedumper.c, src/filedumperx.c, src/files.c, src/files.h, src/functions.h, src/logerror.c, src/nodes.c, src/nodesx.c, src/optimiser.c, src/osmo5mparse.c, src/osmparser.c, src/osmpbfparse.c, src/osmxmlparse.c, src/output.c, src/planetsplitter.c, src/profiles.c, src/profiles.h, src/relations.c, src/relationsx.c, src/relationsx.h, src/results.c, src/router+lib.c (added), src/router.c, src/routino.c (added), src/routino.h (added), src/segments.c, src/segmentsx.c, src/superx.c, src/tagging.c, src/test, src/test/Makefile, src/test/a-b-c-d.sh, src/test/a-b-c.sh, src/test/a-b.sh, src/test/cycle-drive.sh, src/test/only-split.sh, src/test/run-tests.sh (added), src/test/start-1-finish.sh, src/translations.c, src/translations.h, src/types.c, src/visualiser.c, src/ways.c, src/waysx.c, src/xml/Makefile, src/xml/xsd-to-xmlparser.c, src/xmlparse.c, src/xmlparse.h, web/Makefile, web/www/routino/documentation: Merge libroutino branch back into the trunk. 2015-08-15 [r1783] Andrew M. Bishop <amb> (from 'branches/libroutino') * Makefile.conf, extras/find-fixme/Makefile, extras/tagmodifier/Makefile, src/Makefile, src/test/Makefile, src/xml/Makefile, web/Makefile: Add '.exe' to the EXE targets to stop MinGW recompiling the executables each time. 2015-08-14 [r1782] Andrew M. Bishop <amb> (from 'branches/libroutino') * Makefile.conf, doc/INSTALL-MS-WIN.txt, doc/html/installation-ms-windows.html, extras/find-fixme/Makefile, extras/tagmodifier/Makefile, src/Makefile, web/Makefile: Fully automatic host detection (for Cygwin, MinGW and generic UNIX). 2015-08-14 [r1781] Andrew M. Bishop <amb> (from 'branches/libroutino') * Makefile.conf, src/Makefile: Using 'make install' now installs the libraries. On Windows installation uses 'Program Files/Routino' as the base directory. 2015-08-14 [r1780] Andrew M. Bishop <amb> * web/translations/translation.de.txt, web/translations/translation.nl.txt, web/translations/translation.ru.txt, xml/routino-translations.xml: Remove duplicated words and whitespace in translations. 2015-08-11 [r1779] Andrew M. Bishop <amb> (from 'branches/libroutino') * Makefile.conf: Don't include '-fPIC' for MinGW compilation (stops some warnings). 2015-08-11 [r1776-1778] Andrew M. Bishop <amb> (from 'branches/libroutino') * doc/INSTALL-MS-WIN.txt, doc/html/installation-ms-windows.html: Updated documentation for compiling with MinGW64 and compiling library files. * src/Makefile: An attempt at creating routino.def and routino.lib using dlltool instead of gendef. * src/files.c, src/files.h: Undefine some #defines that MinGW64 uses to remove lots of compiler warnings. 2015-08-10 [r1773-1775] Andrew M. Bishop <amb> (from 'branches/libroutino') * src/Makefile: Create routino.dll and routino.def when compiling with MinGW (based on suggestion from Oliver Eichler). * src/router+lib.c: Use 'use_stdout' instead of 'stdout' as a variable name (patch from Oliver Eichler). * src/routino.h: Use DLL_PUBLIC for the extern definitions of the global variables (patch from Oliver Eichler). 2015-08-08 [r1772] Andrew M. Bishop <amb> (from 'branches/libroutino') * src/translations.c: Put the missing space back in the HTML string. 2015-08-08 [r1771] Andrew M. Bishop <amb> (from 'branches/libroutino') * doc/LIBRARY.txt, doc/html/library.html, src/output.c, src/router+lib.c, src/routino.c, src/routino.h, src/translations.c, src/translations.h: Simplify the HTML generation by making more complex format strings when parsing the translations. Add another field to the API HTML format output (cumulative distance). Increase API version to 5. 2015-08-08 [r1770] Andrew M. Bishop <amb> (from 'branches/libroutino') * doc/LIBRARY.txt, doc/html/library.html: Add some missing API changes. 2015-08-08 [r1769] Andrew M. Bishop <amb> * doc/OUTPUT.txt: Fix some text formatting problems. 2015-08-08 [r1768] Andrew M. Bishop <amb> (from 'branches/libroutino') * doc/LIBRARY.txt, doc/html/library.html, src/output.c, src/router+lib.c, src/routino.c, src/routino.h, src/translations.c, src/translations.h: Add a new output list format that contains a text version of the normal HTML output. Increase API version to 4. 2015-08-04 [r1767] Andrew M. Bishop <amb> (from 'branches/libroutino') * doc/LIBRARY.txt, doc/html/library.html, src/optimiser.c, src/router+lib.c, src/routino.c, src/routino.h: Add a progress callback that reports routing progress and can abort the routing algorithm if required. Increase API version to 3. 2015-08-04 [r1766] Andrew M. Bishop <amb> (from 'branches/libroutino') * doc/LIBRARY.txt, doc/html/library.html, src/output.c, src/routino.c, src/routino.h: Add speed for each route segment (text-all version) and rename the 'string' parameter to 'name'. Increase API version to 2. 2015-08-03 [r1765] Andrew M. Bishop <amb> (from 'branches/libroutino') * doc/LIBRARY.txt, doc/html/library.html, src/router+lib.c, src/routino.c, src/routino.h: Add a library API version number #define and variable and a function to compare the two. 2015-08-03 [r1764] Andrew M. Bishop <amb> (from 'branches/libroutino') * web/www/routino/documentation: Ignore the library documentation when copied to the web directory. 2015-08-03 [r1763] Andrew M. Bishop <amb> * web/www/routino/router.leaflet.js, web/www/routino/router.openlayers.js: Format the web links to only use 5 decimal places. 2015-08-02 [r1761-1762] Andrew M. Bishop <amb> (from 'branches/libroutino') * src/output.c: Another fix for a mistake in output generation. * src/output.c: Patch from Oliver Eichler for some mistakes in output generation. 2015-07-31 [r1760] Andrew M. Bishop <amb> (from 'branches/libroutino') * doc/LIBRARY.txt (added), doc/html/index.html, doc/html/library.html (added), src/routino.c, src/routino.h: Documentation for the libroutino library. 2015-07-31 [r1759] Andrew M. Bishop <amb> * web/translations/translation.pl.txt: More Polish translations (via http://www.routino.org/translations/). 2015-07-30 [r1758] Andrew M. Bishop <amb> (from 'branches/libroutino') * src/functions.h, src/output.c, src/router+lib.c, src/router.c, src/routino.c, src/routino.h: Add the ability to request a linked list output representing the route when using the routino library. 2015-07-21 [r1757] Andrew M. Bishop <amb> (from 'branches/libroutino') * src/routino.c, src/routino.h: Add a user profile type and functions to convert it to and from the Routino profile. 2015-07-20 [r1756] Andrew M. Bishop <amb> (from 'branches/libroutino') * src/router+lib.c, src/router.c, src/routino.c, src/routino.h: Add options to the routing function to allow selection of the type of output files generated. 2015-07-20 [r1755] Andrew M. Bishop <amb> (from 'branches/libroutino') * src/profiles.c, src/profiles.h, src/router+lib.c, src/routino.c, src/routino.h, src/translations.c, src/translations.h: Add functions to the library to return the list of loaded translation languages and profile names. 2015-07-20 [r1754] Andrew M. Bishop <amb> (from 'branches/libroutino') * Makefile.conf, src/Makefile: Compile the version of the router using libroutino to search for the shared library in the same directory. 2015-07-20 [r1753] Andrew M. Bishop <amb> (from 'branches/libroutino') * src/routino.c, src/routino.h: Check for validated profiles before using them. 2015-07-18 [r1752] Andrew M. Bishop <amb> (from 'branches/libroutino') * src/test/Makefile, src/test/run-tests.sh (added): Put the test script execution into a script. 2015-07-18 [r1751] Andrew M. Bishop <amb> (from 'branches/libroutino') * src/test, src/test/Makefile, src/test/a-b-c-d.sh, src/test/a-b-c.sh, src/test/a-b.sh, src/test/cycle-drive.sh, src/test/only-split.sh, src/test/start-1-finish.sh: Add tests of the router built with libroutino. 2015-07-16 [r1750] Andrew M. Bishop <amb> (from 'branches/libroutino') * src/router+lib.c: Fix bug in last check-in. 2015-07-16 [r1749] Andrew M. Bishop <amb> (from 'branches/libroutino') * src/router+lib.c, src/router.c, src/routino.c, src/translations.c: Allow choosing a named translation, the first in the file or the built-in English one. Make the routers use the first in the file if no language is specified rather than the built-in one. 2015-07-16 [r1748] Andrew M. Bishop <amb> (from 'branches/libroutino') * src/profiles.c, src/profiles.h, src/router+lib.c, src/router.c, src/routino.c, src/routino.h: Validate profile parameters better when reading XML or router command line. Change the Profile data structure so that UpdateProfile() does not change the parts that are loaded from file so that it can be used multiple times on the same profile. Change the highway and props data to be between 0 and 1 rather than a percentage. Add a new function to the library to validate a profile and also update it. 2015-07-15 [r1746-1747] Andrew M. Bishop <amb> (from 'branches/libroutino') * src/profiles.c, src/routino.c, src/routino.h, src/translations.c: Add a Routino_errno variable that indicates the error status of the most recent library function called. * src/Makefile: Fix bug with Makefile dependencies for libroutino.so and libroutino-slim.so. 2015-07-14 [r1745] Andrew M. Bishop <amb> * src/files.c, src/files.h: Merge changes from MS-Windows branch (changes for stati64/fstati64/lseeki64). 2015-07-14 [r1743] Andrew M. Bishop <amb> (from 'branches/MS-Windows') * src/files.c, src/files.h: Fix changes for stati64/fstati64/lseeki64. 2015-07-11 [r1741] Andrew M. Bishop <amb> * src/cache.h, src/errorlog.h, src/errorlogx.c, src/files.c, src/files.h, src/logerror.c, src/nodes.c, src/nodes.h, src/nodesx.c, src/relations.h, src/relationsx.c, src/relationsx.h, src/ways.h, src/waysx.c, src/waysx.h: Merge change from MS-Windows branch (offset_t). 2015-07-11 [r1740] Andrew M. Bishop <amb> (from 'branches/MS-Windows') * src/cache.h, src/errorlog.h, src/errorlogx.c, src/files.c, src/files.h, src/logerror.c, src/nodes.c, src/nodes.h, src/nodesx.c, src/relations.h, src/relationsx.c, src/relationsx.h, src/ways.h, src/waysx.c, src/waysx.h: Define a custom type for the offset within a file (because MS Windows can create a 4GB file but only seek +/-2GB within it). 2015-07-10 [r1739] Andrew M. Bishop <amb> * src/nodes.h, src/nodesx.h, src/relations.h, src/segments.h, src/segmentsx.h, src/ways.h, src/waysx.h: Clarify the comments surrounding the definition of the slim mode cache data structures. 2015-07-09 [r1738] Andrew M. Bishop <amb> (from 'branches/libroutino') * src, src/Makefile, src/router+lib.c (added), src/routino.c, src/routino.h: Update the library and include a version of the router program that uses the libroutino shared library for calculating routes. Currently generates output files of all types and accepts but ignores all options to change this. 2015-07-08 [r1737] Andrew M. Bishop <amb> (from 'branches/libroutino') * src/translations.c: Bug fix when freeing the loaded translations. 2015-07-08 [r1736] Andrew M. Bishop <amb> (from 'branches/libroutino') * src/translations.c: Bug fix for change introduced into xmlparse.c by r1701. 2015-07-08 [1735] Andrew M. Bishop <amb> * src/files.c: Merge change from MS-Windows branch. 2015-07-08 [r1734] Andrew M. Bishop <amb> * src/xmlparse.c: Remove a commented out line left over from a previous change. 2015-07-08 [r1733] Andrew M. Bishop <amb> (from 'branches/MS-Windows') * src/files.c: Use the same definition of ssize_t in files.c as other files (for MS Windows). 2015-07-07 [r1732] Andrew M. Bishop <amb> * web/translations/translation.pl.txt: More Polish translations (via http://www.routino.org/translations/). 2015-07-06 [r1731] Andrew M. Bishop <amb> * web/translations/translation.pl.txt (added), web/www/routino, web/www/routino/.htaccess, xml/routino-translations.xml: Added Polish version of translations (submitted through http://www.routino.org/translations/). 2015-07-04 [r1730] Andrew M. Bishop <amb> (from 'branches/libroutino') * src/functions.h, src/optimiser.c, src/router.c: Move the CalculateRoute function from router.c into optimiser.c. 2015-07-02 [r1729] Andrew M. Bishop <amb> (from 'branches/libroutino') * src/functions.h, src/output.c, src/profiles.c, src/profiles.h, src/router.c, src/translations.c, src/translations.h: Identify the best bits from the profiles XML reader and translations XML reader functions and implement them in both. 2015-07-02 [r1728] Andrew M. Bishop <amb> * src/profiles.c: Fix error with --help-profile-xml option. 2015-07-01 [r1726] Andrew M. Bishop <amb> * src/files.c, src/files.h, src/osmo5mparse.c, src/osmpbfparse.c, src/xmlparse.c: Merge changes from MS-Windows branch. 2015-07-01 [r1724-1725] Andrew M. Bishop <amb> (from 'branches/MS-Windows') * src/files.c: More fixes for MSVC, set permission for creating files and combine code with MinGW. * src/files.h, src/osmo5mparse.c, src/osmpbfparse.c, src/xmlparse.c: More fixes for MSVC from Oliver Eichler (include basestd.h and define ssize_t). 2015-06-22 [r1723] Andrew M. Bishop <amb> (from 'branches/libroutino') * src/optimiser.c: Bug fix for latest change (logassert and LIBROUTINO). 2015-06-22 [r1722] Andrew M. Bishop <amb> (from 'branches/libroutino') * src/files.c, src/nodes.c, src/optimiser.c, src/relations.c, src/results.c, src/segments.c, src/ways.c: Remove all references to log_memory(), log_free(), log_mmap(), log_munmap() and logassert() from code compiled into the library. 2015-06-20 [r1720] Andrew M. Bishop <amb> (from 'branches/libroutino') * src/routino.h: Avoid defining DLL_PUBLIC twice on Cygwin. 2015-06-20 [r1719] Andrew M. Bishop <amb> * extras/tagmodifier/tagmodifier.c, src/osmxmlparse.c, src/profiles.c, src/tagging.c, src/translations.c, src/xml/xsd-to-xmlparser.c, src/xmlparse.c, src/xmlparse.h: Make the xmltags definitions of XML files be constants. 2015-06-20 [r1717-1718] Andrew M. Bishop <amb> (from 'branches/libroutino') * src/xmlparse.c, src/xmlparse.h: Don't print an error when XML parsing fails but store a string for later use (for use within library version). * src/optimiser.c: Check for defined(LIBROUTINO) instead of LIBROUTINO. 2015-06-19 [r1716] Andrew M. Bishop <amb> (from 'branches/libroutino') * src/files.c, src/optimiser.c, src/output.c, src/profiles.c, src/translations.c: Do not print error or debug messages when compiled into library. Return an appropriate error value from functions instead of exiting. 2015-06-18 [r1715] Andrew M. Bishop <amb> (from 'branches/libroutino') * Makefile.conf, src/Makefile, src/routino.c (added), src/routino.h (added): Add stub files for Routino library exported functions and Makefile support. 2015-06-17 [r1713] Andrew M. Bishop <amb> * extras/tagmodifier/README.txt, extras/tagmodifier/tagmodifier.c: Add the '--logmemory' option that the other programs have. 2015-06-17 [r1712] Andrew M. Bishop <amb> (from 'branches/libroutino') * extras/find-fixme/fixme-finder.c: Fix error with command line tagging filename selection. Change code to make it clearer that the error log file is not optional. 2015-06-16 [r1711] Andrew M. Bishop <amb> (from 'branches/libroutino') * extras/find-fixme/osmparser.c, extras/tagmodifier/tagmodifier.c, src/errorlogx.c, src/fakes.c, src/fakes.h, src/logerror.c, src/nodesx.c, src/osmo5mparse.c, src/osmparser.c, src/osmpbfparse.c, src/osmxmlparse.c, src/profiles.c, src/relationsx.c, src/segmentsx.c, src/tagging.c, src/translations.c, src/visualiser.c, src/waysx.c, src/xmlparse.c: Audit the use of file static variables to make sure that there are no implicit assumptions about initialisation conditions that would be wrong for library usage. Fix problems and add comments for clarity. 2015-06-14 [r1710] Andrew M. Bishop <amb> (from 'branches/libroutino') * extras/find-fixme/fixme-dumper.c, extras/tagmodifier/tagmodifier.c, src/filedumper.c, src/nodesx.c, src/osmxmlparse.c, src/planetsplitter.c, src/relationsx.c, src/relationsx.h, src/segmentsx.c, src/superx.c, src/tagging.c, src/translations.c, src/types.c, src/waysx.c, src/xml/xsd-to-xmlparser.c, src/xmlparse.c: Audit the use of function static variables to make sure that there are no implicit assumptions about initialisation conditions that would be wrong for library usage. Fix problems and add comments for clarity. 2015-06-12 [r1709] Andrew M. Bishop <amb> (from 'branches/libroutino') * src/filedumperx.c: Correct an error in a comment. 2015-06-12 [r1708] Andrew M. Bishop <amb> (from 'branches/libroutino') * extras/find-fixme/fixme-finder.c, src/planetsplitter.c, src/router.c: Minimise the number of times that FileName() is called since each one will allocate memory and take time. 2015-06-12 [r1706-1707] Andrew M. Bishop <amb> (from 'branches/libroutino') * src/profiles.c, src/profiles.h, src/router.c: Add a function to free the memory in the Profile structures loaded from file. * src/output.c, src/router.c, src/translations.c, src/translations.h: Create a Translation structure to hold the translated strings and have one global variable instead of 30. Add a function to free the memory in the Translation structure. 2015-06-10 [r1705] Andrew M. Bishop <amb> * doc/html/index.html, web/www/routino/documentation: Merge the MS-Windows branch back into the trunk. More documentation changes. 2015-06-10 [r1704] Andrew M. Bishop <amb> (from 'branches/MS-Windows') * doc/html/index.html: Update the index to point to the new MS Windows installation documentation. 2015-06-10 [r1703] Andrew M. Bishop <amb> (from 'branches/MS-Windows') * web/www/routino/documentation: Ignore the new MS Windows installation documentation file. 2015-06-10 [r1701-1702] Andrew M. Bishop <amb> (from 'branches/libroutino') * src/router.c: The translations are required to be loaded for the text output formats. * src/output.c, src/xmlparse.c: The ParseXML_Encode_Safe_XML() function now returns a pointer to the same re-allocated string each time rather than allocating a new string each time that it is called. 2015-06-09 [r1699] Andrew M. Bishop <amb> * Makefile.conf, doc/INSTALL-MS-WIN.txt (added), doc/INSTALL.txt, doc/html/installation-ms-windows.html (added), doc/html/installation.html, extras/find-fixme/Makefile, extras/tagmodifier/Makefile, src/Makefile, src/errorlogx.c, src/files.c, src/files.h, src/logerror.c, src/nodesx.c, src/output.c, src/relationsx.c, src/segmentsx.c, src/test/Makefile, src/uncompress.c, src/waysx.c, src/xml/Makefile, src/xmlparse.c, web/Makefile: Merge the MS-Windows branch back into the trunk. Code changes and documentation for Cygwin and MinGW compilers. 2015-05-31 [r1697] Andrew M. Bishop <amb> (from 'branches/MS-Windows') * src/errorlogx.c, src/files.c, src/files.h, src/nodesx.c, src/relationsx.c, src/segmentsx.c, src/waysx.c: Microsoft Windows does not allow deleting an open file and continuing to use it like UNIX does. For MS Windows rename the file instead of deleting and replacing it and do not delete open files immediately but wait until they are closed. 2015-05-30 [r1696] Andrew M. Bishop <amb> (from 'branches/MS-Windows') * src/files.c, src/logerror.c, src/output.c: Open files in binary mode for MSVC and MinGW. 2015-05-29 [r1695] Andrew M. Bishop <amb> * src/nodesx.c, src/relationsx.c, src/segmentsx.c, src/waysx.c: Ensure that allocated strings are long enough even if the %p format is extravagant in the number of characters it uses. 2015-05-29 [r1694] Andrew M. Bishop <amb> * web/Makefile: Change the order so that the translations are created before the icons (because the icons are more difficult to make and more likely to fail). 2015-05-29 [r1693] Andrew M. Bishop <amb> * Makefile.conf: Remove the -Wfloat-conversion gcc option since it was only included in gcc version 4.9 so is not available everywhere. 2015-05-29 [r1692] Andrew M. Bishop <amb> (from 'branches/MS-Windows') * doc/INSTALL-MS-WIN.txt, doc/html/installation-ms-windows.html: Add instructions for compiling with Cygwin (no source code changes needed). 2015-05-28 [r1690] Andrew M. Bishop <amb> * extras/find-fixme/Makefile, extras/tagmodifier/Makefile, src/Makefile, src/test/Makefile, src/xml/Makefile, web/Makefile, web/www/routino, web/www/routino/router.html (removed), web/www/routino/visualiser.html (removed), xml/Makefile: Update Makefiles so that 'make clean' goes back to the source code in the release tar files and 'make distclean' goes back to the source code in subversion (the difference mainly being web page icons and web page translations). 2015-05-28 [r1687-1689] Andrew M. Bishop <amb> (from 'branches/MS-Windows') * doc/INSTALL-MS-WIN.txt (added), doc/INSTALL.txt, doc/html/installation-ms-windows.html (added), doc/html/installation.html: Update documentation to describe compilation on Microsoft Windows. * src/uncompress.c: Do not try to compile the built-in file decompression on MINGW or MSVC due to the lack of fork() function. * Makefile.conf, extras/find-fixme/Makefile, extras/tagmodifier/Makefile, src/Makefile, src/xml/Makefile, web/Makefile: Update Makefiles for compiling with MINGW to include mman-win32.o and handle executables with .exe file extension. 2015-05-26 [r1683-1686] Andrew M. Bishop <amb> (from 'branches/MS-Windows') * src/xmlparse.c: When compiling with MINGW there is no strcasecmp() function so _stricmp() must be used (the same as with MSVC). * src/files.c: When compiling with MINGW the same mman-win32 functions are required as with MSVC. The open() function can not set the 'group' and 'other' permissions although it can set the 'user' permissions. * src/files.h: When compiling with MINGW the pread() and pwrite() functions are not available. Fix a signed/unsigned assignment warning in the inline functions. * src/uncompress.c: Only compile the pipe_and_fork() function if any of the compression methods are enabled. 2015-05-26 [r1680] Andrew M. Bishop <amb> * Makefile.conf, extras/find-fixme/fixme-dumper.c, extras/find-fixme/fixme-finder.c, extras/tagmodifier/tagmodifier.c, src/Makefile, src/cache.h, src/fakes.c, src/filedumper.c, src/files.c, src/files.h, src/logging.c, src/logging.h, src/mman-win32.c (added), src/mman-win32.h (added), src/nodes.c, src/optimiser.c, src/osmo5mparse.c, src/osmpbfparse.c, src/output.c, src/planetsplitter.c, src/profiles.c, src/router.c, src/segments.h, src/uncompress.c, src/ways.c, src/ways.h, src/xml/xsd-to-xmlparser.c, src/xmlparse.c: Merge branch 'MSVC' back into the trunk. 2015-05-26 [r1679] Andrew M. Bishop <amb> * web/www/leaflet/install.sh: Update to Leaflet version 0.7.3. 2015-05-21 [r1678] Andrew M. Bishop <amb> * src/sorting.c: Fix bug with 64-bit version failing 'make test'. 2015-05-20 [r1677] Andrew M. Bishop <amb> * src/output.c: Change a static variable to a const to clarify it usage. 2015-05-20 [r1676] Andrew M. Bishop <amb> (from 'branches/MSVC') * Makefile.conf: Add the -Wfloat-conversion gcc option to catch any future score_t related conversions required. 2015-05-20 [r1675] Andrew M. Bishop <amb> (from 'branches/MSVC') * src/optimiser.c, src/profiles.c, src/router.c: Typecasts for score_t and explicit float (not double) literals for MSVC compilation [based on patch from Oliver Eichler]. 2015-05-20 [r1674] Andrew M. Bishop <amb> (from 'branches/MSVC') * src/logging.c, src/xmlparse.c: Updated MSVC code changes after testing [patch from Oliver Eichler]. 2015-05-20 [r1673] Andrew M. Bishop <amb> (from 'branches/MSVC') * src/files.c, src/files.h, src/mman-win32.c (added), src/mman-win32.h (added): Added a Win32 implementation of the mmap/munmap functions [files from https://code.google.com/p/mman-win32 suggested by Oliver Eichler]. 2015-05-19 [r1666-1671] Andrew M. Bishop <amb> (from 'branches/MSVC') * src/ways.c: Fix uninitialised memory [found by Oliver Eichler when compiling with Microsoft C compiler]. * src/fakes.c, src/segments.h, src/ways.h: Add some explicit casts for some assignments resulting from pointer arithmetic [patch from Oliver Eichler for compiling with Microsoft C]. * src/files.c, src/nodes.c, src/xmlparse.c: Add some explicit casts for some assignments between different integer types [patch from Oliver Eichler for compiling with Microsoft C]. * src/Makefile, src/planetsplitter.c, src/router.c: Rename DATADIR to ROUTINO_DATADIR to avoid problems when compiling with Microsoft C compiler [inspired by patches from Oliver Eichler]. * src/files.c, src/files.h: Remove memory mapping functions when compiling with Microsoft C compiler [inspired by patches from Oliver Eichler]. This will only allow slim more to be compiled. * src/xmlparse.c: Remove <strings.h> when compiling with Microsoft C compiler (in which use a macro to replace strcasecmp) [inspired by patches from Oliver Eichler]. 2015-05-19 [r1664-1665] Andrew M. Bishop <amb> (from 'branches/MSVC') * src/files.c, src/files.h: Remove <unistd.h> where not needed at all or when compiling with Microsoft C compiler (in which case add <io.h> and some macros to replace read/write/open/close/lseek etc.) [inspired by patches from Oliver Eichler]. * extras/find-fixme/fixme-finder.c, extras/tagmodifier/tagmodifier.c, src/cache.h, src/osmo5mparse.c, src/osmpbfparse.c, src/output.c, src/planetsplitter.c, src/uncompress.c, src/xml/xsd-to-xmlparser.c, src/xmlparse.c: Remove <unistd.h> where not needed at all or when compiling with Microsoft C compiler (in which case add <io.h> and some macros to replace read/write/open/close/lseek etc.) [inspired by patches from Oliver Eichler]. 2015-05-19 [r1663] Andrew M. Bishop <amb> (from 'branches/MSVC') * extras/find-fixme/fixme-dumper.c, src/filedumper.c, src/logging.c, src/logging.h: Remove <sys/time.h> where not needed at all or when compiling with Microsoft C compiler (in which case add a replacement gettimeofday function) [inspired by patches from Oliver Eichler]. 2015-05-18 [r1661] Andrew M. Bishop <amb> * src/optimiser.c: Fix use-after-free error found by valgrind. 2015-05-16 [r1657] Andrew M. Bishop <amb> * web/www/routino/router.leaflet.js, web/www/routino/router.openlayers.js: Fix bug with moving markers on the map (OpenLayers version) and enable markers when they are dragged onto the map (both versions). 2015-05-16 [r1656] Andrew M. Bishop <amb> * web/translations/router.html, web/translations/translation.de.txt, web/translations/translation.en.txt, web/translations/translation.fr.txt, web/translations/translation.nl.txt, web/www/routino/router.css, web/www/routino/router.leaflet.js, web/www/routino/router.openlayers.js: Allow dragging the waypoint icon up-and-down in the list and onto the map. 2015-05-15 [r1655] Andrew M. Bishop <amb> * web/translations/translation.hu.txt: Add updated Hungarian translations submitted via http://www.routino.org/translations/ on 2015-05-14. 2015-05-14 [r1652-1653] Andrew M. Bishop <amb> * Makefile.conf: Add the -pedantic compilation flag to allow detection of more potential errors and portability issues. * src/errorlog.h, src/files.c, src/nodes.h, src/relations.h, src/segments.h, src/sorting.c, src/ways.h: Replace all arithmetic involving 'void*' pointers with 'char*' since it isn't strictly valid although it is accepted by gcc. 2015-05-13 [r1651] Andrew M. Bishop <amb> * src/xmlparse.c: Remove a gcc warning about overflow in implicit constant conversion (by making it an explicit type cast). 2015-05-13 [r1650] Andrew M. Bishop <amb> * extras/find-fixme/fixme-dumper.c, src/filedumper.c, src/logging.c: Use "%zu" to print 'size_t' type values and use Pindex_t to print 'index_t' type values. 2015-05-13 [r1649] Andrew M. Bishop <amb> * src/sorting.c: Remove some pthread related code that was being used even if compiled without pthreads. 2015-05-05 [r1648] Andrew M. Bishop <amb> * web/translations/translation.de.txt: Add updated German translations submitted via http://www.routino.org/translations/ on 2015-05-04. 2015-05-01 [r1646] Andrew M. Bishop <amb> * doc/html/algorithm.html, doc/html/configuration.html, doc/html/data.html, doc/html/index.html, doc/html/installation.html, doc/html/limits.html, doc/html/output.html, doc/html/readme.html, doc/html/style.css, doc/html/tagging.html, doc/html/usage.html, extras/find-fixme/web/www/index.html, web/www/routino/index.html: Add "meta" header to HTML to help mobile devices and tidy up some CSS. 2015-05-01 [r1644-1645] Andrew M. Bishop <amb> * doc/html/readme.html: Fixed some header links. * doc/TAGGING.txt, doc/html/tagging.html: Fixed some text formatting. 2015-04-26 [r1643] Andrew M. Bishop <amb> * web/translations/translation.hu.txt (added), web/www/routino, xml/routino-translations.xml: Added a Hungarian translation of the Routino routes and router web pages (from unknown person using http://routino.org/translations/). 2015-04-11 [r1642] Andrew M. Bishop <amb> * web/Makefile: Run make in the xml directory after updating the xml/translations.xml file. 2015-04-10 [r1641] Andrew M. Bishop <amb> * src/translations.c: Change built-in default HTML translation strings so that they work with the web page if they have to be used. 2015-03-30 [r1638] Andrew M. Bishop <amb> * src/optimiser.c: Fix bug with indenting of debug output in FindMiddleRoute() function. 2015-03-28 [r1636] Andrew M. Bishop <amb> * src/optimiser.c: More verbose, consistent, complete and descriptive debugging of routes found. 2015-03-28 [r1634] Andrew M. Bishop <amb> * src/optimiser.c: The new FindStartRoutes() function does not need to be so complicated. 2015-03-28 [r1632] Andrew M. Bishop <amb> * src/functions.h, src/optimiser.c, src/router.c: Remove the ExtendStartRoutes() function by merging its functionality with the FindStartRoutes() function since they were almost identical anyway. 2015-03-21 [r1626-1627] Andrew M. Bishop <amb> * src/optimiser.c, src/router.c: Make sure that all complete routes have finish_node and last_segment filled in. * src/optimiser.c: Bug fix and clarification for previous change. 2015-03-21 [r1625] Andrew M. Bishop <amb> * src/functions.h, src/optimiser.c, src/router.c: Don't merge the end of the route with the middle part of the route before combining with the beginning of the route - combine beginning, middle and end all in one function. 2015-02-02 [r1624] Andrew M. Bishop <amb> * web/translations/translation.de.txt, xml/routino-translations.xml: Add updated German translations submitted via http://www.routino.org/translations/ on 2014-01-31. 2015-01-17 [r1623] Andrew M. Bishop <amb> * web/translations/translation.de.txt, xml/routino-translations.xml: Add updated German translations submitted via http://www.routino.org/translations/ on 2014-01-16. 2015-01-13 [r1622] Andrew M. Bishop <amb> * web/translations/translation.de.txt: Add updated German translations submitted via http://www.routino.org/translations/ on 2014-01-13. 2015-01-09 [r1621] Andrew M. Bishop <amb> * web/translations/translation.nl.txt: Add updated Dutch translations submitted via http://www.routino.org/translations/ on 2014-01-08. 2015-01-07 [r1620] Andrew M. Bishop <amb> * xml/routino-tagging.xml: Remove cycle_barrier and bicycle_barrier since these don't always block bicycles. 2014-12-04 [r1619] Andrew M. Bishop <amb> * src/typesx.h: Increase MAX_SEG_PER_NODE to avoid further problems. 2014-11-29 [r1618] Andrew M. Bishop <amb> * src/visualiser.c: Include typesx.h to get the definition of MAX_SEG_PER_NODE rather than having another one. 2014-11-08 Andrew M. Bishop <amb> Version 2.7.3 released. 2014-11-08 [r1616] Andrew M. Bishop <amb> * FILES, doc/NEWS.txt, doc/README.txt, doc/html/readme.html: Updated for version 2.7.3. 2014-11-08 [r1615] Andrew M. Bishop <amb> * web/translations/translation.de.txt, xml/routino-translations.xml: Translation of the final German word missing from the XML file. 2014-10-25 [r1614] Andrew M. Bishop <amb> * doc/DATALIFE.txt, src/nodesx.c, src/planetsplitter.c, src/relationsx.c: Sort the data geographically before pruning so that the data points physically close together are close together in memory which reduces swapping/paging and therefore runs much faster when memory is limited. 2014-10-23 [r1613] Andrew M. Bishop <amb> * src/logging.c: Comment fixes, tidy-up and one bug fixed. 2014-10-22 [r1612] Andrew M. Bishop <amb> * doc/DATALIFE.txt, src/waysx.c: Use the waysx->idata array instead of wayx->id when logging node errors during the segment creation. 2014-10-21 [r1609-1611] Andrew M. Bishop <amb> * doc/DATALIFE.txt: Correct errors in wayx->id usage when compacting ways. * src/logging.c: Improve the message printed at the end when using --logtime or --logmemory. * src/planetsplitter.c: Clarify some comments. 2014-10-18 [r1608] Andrew M. Bishop <amb> * doc/DATALIFE.txt, src/segmentsx.c: Use the waysx->idata array when logging duplicate segments rather than looking up the wayx and using its id, also saves mapping the ways into memory. 2014-10-18 [r1606-1607] Andrew M. Bishop <amb> * doc/DATALIFE.txt, src/segmentsx.c: Use the nodesx->idata array when logging duplicate segments rather than looking up the nodex and using its id. * src/nodesx.c: Shrink the size of the nodesx->idata array when removing non-highway nodes. 2014-10-18 [r1605] Andrew M. Bishop <amb> * doc/DATALIFE.txt, src/nodesx.c, src/planetsplitter.c, src/relationsx.c, src/segmentsx.c, src/superx.c: Free memory that it allocated by IndexSegments() when no longer needed rather than holding on to it. 2014-10-14 [r1604] Andrew M. Bishop <amb> * doc/DATALIFE.txt, src/planetsplitter.c: Speed up the database generation when pruning by reducing the amount of random memory accesses are required by compacting the database after each step. Unless there is enough RAM to hold all the memory mapped files this should be faster. 2014-10-13 [r1603] Andrew M. Bishop <amb> * src/nodes.c, src/segments.c, src/segments.h, src/segmentsx.c: Try to speed up the search for the closest node/segment by minimising the number of nodes that are examined in detail. 2014-10-10 [r1602] Andrew M. Bishop <amb> * src/nodes.c, src/relations.c, src/segments.c, src/ways.c: Record the memory used by the node, segment, way and relation caches in the slim mode router. 2014-10-10 [r1601] Andrew M. Bishop <amb> * extras/find-fixme/fixme-finder.c, src/logging.c, src/planetsplitter.c, src/router.c: Log the router time in microseconds rather than milliseconds. Add a note at the end about the format of the time and memory logging. 2014-10-10 [r1600] Andrew M. Bishop <amb> * doc/USAGE.txt, doc/html/usage.html, src/logging.c, src/nodes.c, src/optimiser.c, src/results.c, src/router.c: Add the '--logtime' and '--logmemory' options to the router to report the time and maximum memory in use (allocated and mapped files) during each step of the routing. 2014-09-30 [r1599] Andrew M. Bishop <amb> * extras/find-fixme/fixme-dumper.c, extras/find-fixme/fixme-finder.c, extras/tagmodifier/tagmodifier.c, src/filedumper.c, src/filedumperx.c, src/planetsplitter.c, src/router.c: Use exit() when exiting the program other than at the end of the main function. 2014-09-27 [r1598] Andrew M. Bishop <amb> * doc/DATALIFE.txt, doc/USAGE.txt, doc/html/usage.html, extras/find-fixme/README.txt, extras/find-fixme/fixme-finder.c, src/errorlogx.c, src/files.c, src/logging.c, src/logging.h, src/nodesx.c, src/planetsplitter.c, src/prunex.c, src/relationsx.c, src/segmentsx.c, src/sorting.c, src/superx.c, src/typesx.h, src/waysx.c: Add a '--logmemory' option to planetsplitter which will report the maximum memory in use (allocated and mapped files) during each step of the processing. 2014-09-27 [r1597] Andrew M. Bishop <amb> * src/nodes.h, src/relations.c, src/segments.c, src/ways.c, src/waysx.h: Be more consistent in the way that cache.h is included. 2014-09-26 [r1596] Andrew M. Bishop <amb> * src/logging.c, src/logging.h: Make a function static in logging.c rather than global. 2014-09-26 [r1592-1595] Andrew M. Bishop <amb> * src/planetsplitter.c: Free the segment list before generating the errorlog files (it isn't used). * src/prunex.c: Change a comment and the style in which some data is freed. * src/segmentsx.c: Free segmentsx->usedway in FreeSegmentList() rather than letting it leak. * src/nodesx.c: Free segmentsx->firstnode in SaveNodeList() like DATALIFE.txt says it should be. 2014-09-23 [r1591] Andrew M. Bishop <amb> * src/files.c, src/files.h, src/sorting.c: Allocate only the memory that is needed (but never more than the limit) when sorting files (i.e. don't just allocate the limit without checking). 2014-09-18 [r1589-1590] Andrew M. Bishop <amb> * src/visualiser.c: Update comments for the functions (some were wrong, all were unclear). * extras/find-fixme/osmparser.c: Remove unused macros. 2014-08-27 [r1588] Andrew M. Bishop <amb> * web/translations/translation.de.txt: Add updated German translation submitted via http://www.routino.org/translations/ on 2014-08-26. 2014-07-26 [r1587] Andrew M. Bishop <amb> * src/profiles.c: Limit the property preferences to a factor of 100 preference for a highway having a property compared to a highway not having the property (was 10000). 2014-07-04 [r1586] Andrew M. Bishop <amb> * doc/NEWS.txt: Fix release date for 2.7.2. 2014-06-26 Andrew M. Bishop <amb> Version 2.7.2 released. 2014-06-26 [r1584] Andrew M. Bishop <amb> * FILES, doc/NEWS.txt, doc/README.txt, doc/html/readme.html: Updated for version 2.7.2 release. 2014-06-25 [r1583] Andrew M. Bishop <amb> * doc/INSTALL.txt, doc/html/installation.html: Add a note about another Perl module required if compiling from subversion. 2014-06-25 [r1582] Andrew M. Bishop <amb> * src/router.c: Clarify the reason for the unreachable code (#if 0) and fix bug in it. 2014-06-25 [r1581] Andrew M. Bishop <amb> * src/errorlogx.c: Fix for compiler warning on 64-bit systems but not 32-bit systems. 2014-06-24 [r1580] Andrew M. Bishop <amb> * src/output.c: Fix for revision r1565 that crashes on 64-bit systems but not 32-bit systems. 2014-06-24 [r1579] Andrew M. Bishop <amb> * src/optimiser.c: Fix for revision r1553 that crashes on 64-bit systems but not 32-bit systems. 2014-06-09 [r1578] Andrew M. Bishop <amb> * src/cache.h: Increase the size of the caches for the slim programs by a factor of four (gives a large speed-up on virtual machines with low memory and slow disks even though it makes little difference on machines with lots of memory and fast disks). 2014-06-07 [r1577] Andrew M. Bishop <amb> * doc/TAGGING.txt, doc/html/tagging.html: Document the default assumptions about allowed transport types on ferry routes (none). 2014-06-05 [r1576] Andrew M. Bishop <amb> * web/translations/translate.pl: When creating the translated HTML and XML files give the statistics for each file separately. 2014-05-26 [r1575] Andrew M. Bishop <amb> * web/translations/translation.de.txt: Add updated German translations submitted via http://www.routino.org/translations/ on 2014-05-25. 2014-05-21 [r1574] Andrew M. Bishop <amb> * web/translations/translation.ru.txt: Add updated Russian translations submitted via http://www.routino.org/translations/ around 2014-05-20. 2014-05-20 [r1573] Andrew M. Bishop <amb> * src/visualiser.c: When visualising segments include all of the ones that overlap the selected region (not missing a few that cross the edges). 2014-05-19 [r1572] Andrew M. Bishop <amb> * web/translations/translation.de.txt, web/translations/translation.fr.txt, web/translations/translation.nl.txt, web/translations/translation.ru.txt, web/translations/translations-body.xml, xml/routino-translations.xml: Remove un-needed whitespace in translations files. 2014-05-17 Andrew M. Bishop <amb> Version 2.7.1 released. 2014-05-17 [r1570] Andrew M. Bishop <amb> * FILES, doc/NEWS.txt, doc/README.txt, doc/html/readme.html: Update documentation for version 2.7.1. 2014-05-17 [r1569] Andrew M. Bishop <amb> * web/Makefile: Re-create the xml/routino-translations.xml file if the translations are updated or the file is deleted. 2014-05-17 [r1568] Andrew M. Bishop <amb> * xml/routino-translations.xml: Add updated German translations submitted via http://www.routino.org/translations/ around 2014-04-11 and 2014-05-02. 2014-05-12 [r1567] Andrew M. Bishop <amb> * src/prunex.c: When pruning short segments take the highway types into account when sharing the pruned segment length between the two neighbouring segments. 2014-05-10 [r1565-1566] Andrew M. Bishop <amb> * src/test, src/test/a-b-c-d.sh (added), src/test/coincident-waypoint.osm (added), src/test/coincident-waypoint.sh (added), src/test/expected/coincident-waypoint-WP01.txt (added), src/test/expected/coincident-waypoint-WP02.txt (added), src/test/expected/coincident-waypoint-WP03.txt (added), src/test/expected/coincident-waypoint-WP04.txt (added): Add test cases for routes with contain two consecutive coincident waypoints. * src/fakes.c, src/fakes.h, src/output.c, src/router.c: Don't crash if the specified route contains two consecutive coincident waypoints (route instructions at those points may not be perfect). 2014-05-09 [r1564] Andrew M. Bishop <amb> * src/output.c, src/test/expected/loops-WP01.txt, src/test/expected/loops-WP02.txt, src/test/expected/loops-WP06.txt, src/test/expected/loops-WP07.txt: Fix bug with results output that would miss a segment and get the distance/time wrong if a waypoint node was passed again on the way to the next waypoint. 2014-05-05 [r1563] Andrew M. Bishop <amb> * src/optimiser.c: Remove some left-over debugging print statements. 2014-05-03 [r1562] Andrew M. Bishop <amb> * web/translations/translation.de.txt: Add updated German translations submitted via http://www.routino.org/translations/ around 2014-05-02. (Some of the changes from the 2014-04-11 submission were not merged last time, they have been included this time). 2014-05-02 [r1561] Andrew M. Bishop <amb> * web/translations/translation.de.txt: Add updated German translations submitted via http://www.routino.org/translations/ around 2014-04-11. 2014-04-30 [r1560] Andrew M. Bishop <amb> * doc/USAGE.txt, doc/html/usage.html, src/filedumper.c, src/osmparser.c, src/visualiser.c, src/visualiser.h, web/translations/translation.en.txt, web/translations/visualiser.html, web/www/routino/visualiser.cgi, web/www/routino/visualiser.leaflet.js, web/www/routino/visualiser.openlayers.js: Update the visualiser web page to allow displaying the "cyclebothways" highway type and the "roundabout" highway type. Also "cyclebothways" is no longer a property so removed from that part of the visualiser. 2014-04-29 [r1559] Andrew M. Bishop <amb> * src/filedumper.c, src/optimiser.c, src/osmparser.c, src/output.c, src/segments.c, src/types.c, src/types.h, xml/routino-profiles.xml: Remove the "cyclebothways" property and replace it with a "cyclebothways" highway type. This means that it is no longer possible to choose a preference for this type of highway when calculating a route. There was never really any reason for allowing users to do this since they can't specify a preference for oneway streets. It does however mean that the broken Javascript in the router web page (no entry field for this property) is fixed. Unfortunately this means that a database created by previous versions are not compatible with this one. 2014-04-28 [r1558] Andrew M. Bishop <amb> * doc/TAGGING.txt, doc/html/tagging.html: Add some missing items into the documentation related to cycling both ways. 2014-04-28 [r1557] Andrew M. Bishop <amb> * web/Makefile: Fix bug with updating XML files in web/data directory (Makefile error). 2014-04-28 [r1556] Andrew M. Bishop <amb> * src/test, src/test/cycle-both-ways.osm (added), src/test/cycle-both-ways.sh (added), src/test/cycle-drive.sh (added), src/test/expected/cycle-both-ways-WP01.txt (added), src/test/expected/cycle-both-ways-WP02.txt (added): Add a test case for the ability to cycle both ways on highways that allow it. Tests the roundabout exit naming as well as shortest route. 2014-04-28 [r1555] Andrew M. Bishop <amb> * src/test/fake-node-with-loop.osm, src/test/prune-straight.osm, src/test/roundabout-waypoints.osm: Remove unneeded tag from <osm> XML element. 2014-04-27 [r1553-1554] Andrew M. Bishop <amb> * src/test, src/test/expected/fake-node-with-loop-WP01.txt (added), src/test/expected/fake-node-with-loop-WP02.txt (added), src/test/fake-node-with-loop.osm (added), src/test/fake-node-with-loop.sh (added): Add test case for the bug with particular arrangement of a fake node (waypoint in middle of segment) and a roundabout. * src/optimiser.c, src/segments.h: Fix bug with particular arrangement of a fake node (waypoint in middle of segment) and a roundabout. The FindFinishRoutes() function was invalidly allowing a U-turn which the later parts of the route calculation didn't and therefore failed to find a route. 2014-04-26 [r1552] Andrew M. Bishop <amb> * doc/INSTALL.txt, doc/html/installation.html, web/www/routino/search.cgi, web/www/routino/search.pl: Correct the list of Perl modules required to be installed to use the search function. 2014-04-24 [r1551] Andrew M. Bishop <amb> * xml/scripts/drive.pl, xml/scripts/walk.pl: Omit some more properties from the special case tagging rules. 2014-04-14 [r1550] Andrew M. Bishop <amb> * src/optimiser.c: Revert r1462 which makes no noticeable difference to the speed in normal operation but makes a lot of difference for databases created with the special "drive" tagging rules. 2014-04-14 [r1549] Andrew M. Bishop <amb> * src/router.c: Check the number of waypoints after considering the --help and --help-profile options. 2014-04-12 [r1548] Andrew M. Bishop <amb> * web/www/routino/router.leaflet.js, web/www/routino/router.openlayers.js: Disable the route calculation buttons if fewer than two waypoints are active (more cases). 2014-04-12 [r1545-1547] Andrew M. Bishop <amb> * web/Makefile: Automatically update the translated files if the translation files or HTML templates change. * web/translations/router.html, web/www/routino/router.css, web/www/routino/router.leaflet.js, web/www/routino/router.openlayers.js: Disable the route calculation buttons if fewer than two waypoints are active. * src/router.c: Refuse to calculate a route if fewer than two waypoints are specified. 2014-04-08 [r1544] Andrew M. Bishop <amb> * web/translations/translate.pl: Make script work with older versions of Perl. 2014-04-06 [r1543] Andrew M. Bishop <amb> * src/output.c: Change routing instructions if on a bicycle and cyclebothways is enabled on the highways at the junctions (e.g. different count of roundabout exits). 2014-04-05 [r1540-1542] Andrew M. Bishop <amb> * src/test, src/test/expected/roundabout-waypoints-WP01.txt (added), src/test/expected/roundabout-waypoints-WP02.txt (added), src/test/expected/roundabout-waypoints-WP03.txt (added), src/test/expected/roundabout-waypoints-WP04.txt (added), src/test/expected/roundabout-waypoints-WP05.txt (added), src/test/expected/roundabout-waypoints-WP06.txt (added), src/test/expected/roundabout-waypoints-WP07.txt (added), src/test/roundabout-waypoints.osm (added), src/test/roundabout-waypoints.sh (added): Add test case for router error when waypoint is on a roundabout. [Test case also unintentionally detected the super-segment merging bug.] * src/test/Makefile: Compile programs before running tests (fix Makefile bug). * src/superx.c: Fix bug with merging super-segments and segments - an improvement on fix that was applied in version 2.7. 2014-04-04 [r1539] Andrew M. Bishop <amb> * src/output.c: Fix router error when waypoint is on a roundabout (stops crash). 2014-04-02 [r1537-1538] Andrew M. Bishop <amb> * web/translations/translate.pl: Don't use HTML character entity encoding for UTF-8 characters in the HTML. * web/translations/translation.de.txt, web/translations/translation.fr.txt, web/translations/translation.nl.txt, web/translations/translation.ru.txt: Trivial changes to the translation files to put them all into the same order. 2014-04-01 [r1536] Andrew M. Bishop <amb> * web/translations/router.html, web/translations/translate.pl, web/translations/translation.ru.txt, web/translations/translations-body.xml, web/translations/visualiser.html: Use '~~' delimiters in the templates for the special-case replacement strings (like the language name). 2014-03-31 [r1535] Andrew M. Bishop <amb> * web/translations/router.html, web/translations/translate.pl, web/translations/visualiser.html: Use '$$' delimiters in the templates for the multi-line replacement strings (to match the files of translation phrases). 2014-03-25 [r1534] Andrew M. Bishop <amb> * web/translations/translation.ru.txt, web/www/routino, xml/routino-translations.xml: Add Russian translations submitted via http://www.routino.org/translations/ around 2014-03-23. 2014-03-24 [r1533] Andrew M. Bishop <amb> * web/translations/translate.pl, web/translations/translation.de.txt, web/translations/translation.en.txt, web/translations/translation.fr.txt, web/translations/translation.nl.txt, web/translations/translation.ru.txt (added), web/translations/translations-body.xml (added), web/translations/translations-head.xml (added), web/translations/translations-tail.xml (added): Create the routino-translations.xml file from the translated language files in the same way as the HTML. Reverse engineer the existing XML file into the translation files for the languages. 2014-03-23 [r1532] Andrew M. Bishop <amb> * doc/README.txt, doc/html/readme.html: Fixed typo in subversion command line example. 2014-03-22 Andrew M. Bishop <amb> Version 2.7 released. 2014-03-22 [r1529-1530] Andrew M. Bishop <amb> * FILES, doc/NEWS.txt, doc/README.txt, doc/html/readme.html: Updated for new release. * doc/INSTALL.txt: Fix missing text when translated from HTML to plain text. 2014-03-22 [r1528] Andrew M. Bishop <amb> * doc/Makefile, extras/find-fixme/Makefile, extras/tagmodifier/Makefile, src/Makefile, src/test/Makefile, src/xml/Makefile, web/Makefile, xml/Makefile: Another iteration through the Makefiles with some small changes. 2014-03-18 [r1527] Andrew M. Bishop <amb> * src/profiles.c, web/www/routino/router.leaflet.js, web/www/routino/router.openlayers.js: Run jshint again and fix some recently added changes. 2014-03-17 [r1525-1526] Andrew M. Bishop <amb> * src/osmo5mparse.c, src/osmparser.h, src/osmpbfparse.c: Make two global functions local to the files that contain them. * src/errorlog.h, src/tagging.c: Fix some invalid function comments. 2014-03-15 [r1524] Andrew M. Bishop <amb> * web/translations/translate.pl, web/translations/translation.de.txt: Store the translations as UTF-8 in the text files and convert to HTML character entities when writing the HTML. 2014-03-11 [r1523] Andrew M. Bishop <amb> * Makefile, Makefile.conf, doc/Makefile, extras/find-fixme/Makefile, extras/tagmodifier/Makefile, src/Makefile, web/Makefile (added), xml/Makefile: Update the Makefiles by creating one in the web directory and moving parts from the src, doc and xml Makefiles into it. 2014-03-11 [r1522] Andrew M. Bishop <amb> * web/www/routino: Ignore the translated HTML files. 2014-03-08 [r1521] Andrew M. Bishop <amb> * web/translations (added), web/translations/router.html (added), web/translations/translate.pl (added), web/translations/translation.de.txt (added), web/translations/translation.en.txt (added), web/translations/translation.fr.txt (added), web/translations/translation.nl.txt (added), web/translations/visualiser.html (added), web/www/routino/router.html.de (removed), web/www/routino/router.html.en (removed), web/www/routino/router.html.fr (removed), web/www/routino/router.html.nl (removed), web/www/routino/visualiser.html.en (removed): Create the router and visualiser HTML files from templates and lists of translated phrases. 2014-03-08 [r1520] Andrew M. Bishop <amb> * extras/errorlog/summarise-log.pl, extras/find-fixme/web/www/fixme.cgi, extras/plot-time/plot-planetsplitter-time.pl, src/test/waypoints.pl, web/www/routino/results.cgi, web/www/routino/router.cgi, web/www/routino/router.pl, web/www/routino/search.cgi, web/www/routino/search.pl, web/www/routino/statistics.cgi, web/www/routino/update-profiles.pl, web/www/routino/visualiser.cgi, xml/scripts/drive.pl, xml/scripts/ride.pl, xml/scripts/walk.pl: Update all Perl scripts to "use strict". 2014-03-08 [r1518-1519] Andrew M. Bishop <amb> * src/xmlparse.h: Print the XML line number using the correct formatting for a uint64_t type. * src/files.c: Don't ignore the return value of the write() function call. 2014-03-01 [r1516] Andrew M. Bishop <amb> * doc/INSTALL.txt, doc/html/installation.html, extras/find-fixme/web/www/fixme.openlayers.js, web/www/openlayers/install.sh, web/www/routino/router.openlayers.js, web/www/routino/visualiser.openlayers.js: Updated to version 2.13.1 of OpenLayers (also 2.12 still supported). 2014-02-23 [r1515] Andrew M. Bishop <amb> * web/www/routino/icons/waypoint-left.png (added), web/www/routino/icons/waypoint-right.png (added), web/www/routino/router.html.de, web/www/routino/router.html.en, web/www/routino/router.html.fr, web/www/routino/router.html.nl, web/www/routino/router.leaflet.js, web/www/routino/router.openlayers.js: Add buttons to allow increasing/decreasing the transport properties and preferences (to help on tablet devices where typing a number in a box is hard). 2014-02-22 [r1514] Andrew M. Bishop <amb> * extras/tagmodifier/README.txt, extras/tagmodifier/tagmodifier.c, src/uncompress.h, doc/html/installation.html, doc/html/usage.html, Makefile.conf, src/planetsplitter.c, src/uncompress.c, doc/USAGE.txt, extras/find-fixme/README.txt, doc/INSTALL.txt, extras/find-fixme/fixme-finder.c: Add the option for automatic uncompression of .xz compressed files (not enabled by default in Makefile.conf). 2014-02-22 [r1513] Andrew M. Bishop <amb> * web/data/create.sh: Downloads from GeoFabrik only and URLs changed. 2014-02-22 [r1512] Andrew M. Bishop <amb> * doc/INSTALL.txt, doc/html/installation.html: Clarify that gzip support is required for some PBF files. Clarify that multi-threading, gzip and bzip2 are enabled by default at compilation time. 2014-02-02 [r1511] Andrew M. Bishop <amb> * xml/routino-tagging.xml: Add some synonyms for "cycleway=opposite_lane". 2014-02-02 [r1510] Andrew M. Bishop <amb> * xml/routino-tagging.xml: Handle "access=bus" like "access=psv". 2014-02-01 [r1509] Andrew M. Bishop <amb> * web/www/routino/maploader.js: Ensure that all Javascript files are loaded before calling the callbacks (better implementation). 2014-02-01 [r1508] Andrew M. Bishop <amb> * web/www/routino/maploader.js: Ensure that all Javascript files are loaded before calling the callbacks. 2014-02-01 [r1507] Andrew M. Bishop <amb> * web/www/routino/router.openlayers.js, web/www/routino/router.leaflet.js: Allow mouse clicks in the router result description to popup the details and not just mouseovers. Hopefully this should work better for touch devices. 2014-01-31 [r1506] Andrew M. Bishop <amb> * extras/find-fixme/web/www/fixme.leaflet.js, extras/find-fixme/web/www/fixme.openlayers.js: Handle the new format XML (using ''' instead of '''). 2014-01-31 [r1505] Andrew M. Bishop <amb> * src/xmlparse.c, src/output.c: Output HTML4 strict DTD compliant HTML (fix bug with using ''' instead of '''). 2014-01-30 [r1504] Andrew M. Bishop <amb> * doc/html/usage.html, doc/USAGE.txt, src/router.c: Add an option to calculate a circular route. 2014-01-30 [r1503] Andrew M. Bishop <amb> * doc/USAGE.txt, src/router.c, doc/html/usage.html: Add an option to calculate a route in the reverse order. 2014-01-30 [r1502] Andrew M. Bishop <amb> * src/types.h: Make the type conversion inline functions static so that compiling with -O0 still works. 2014-01-29 [r1501] Andrew M. Bishop <amb> * src/results.h, src/types.h, src/output.c, src/router.c, src/results.c: Refactor the code so that the Results data type has the start and finish waypoints defined within it and the array passed to the PrintRoute() function doesn't have holes in it. 2014-01-28 [r1500] Andrew M. Bishop <amb> * src/router.c: Remove ancient option that allowed latitude and longitude to be specified on the command line without the --lat<n> or --lon<n> options. 2014-01-28 [r1499] Andrew M. Bishop <amb> * web/www/routino/router.leaflet.js, extras/find-fixme/web/www/fixme.leaflet.js, web/www/routino/router.openlayers.js, web/www/routino/visualiser.leaflet.js, extras/find-fixme/web/www/fixme.openlayers.js, web/www/routino/visualiser.openlayers.js: Add close buttons to the popup boxes. 2014-01-27 [r1498] Andrew M. Bishop <amb> * web/www/routino/visualiser.html.en, src/profiles.c: Allow displaying the cyclebothways property in the visualiser. 2014-01-27 [r1497] Andrew M. Bishop <amb> * doc/html/tagging.html, src/types.c, xml/routino-tagging.xml, src/segments.c, xml/routino-profiles.xml, src/types.h, doc/TAGGING.txt, src/optimiser.c, src/osmparser.c: Detect the "cycleway=opposite_lane" tag and allow bicycles to travel in both directions along those highways. Based on parts of https://github.com/cgravier/routino-2.6-bikeopposite-elevation/commit/47d68b37f1ea0d2f967ea6aa1555991747491200 https://github.com/cgravier/routino-2.6-bikeopposite-elevation/commit/764832f2671e6f6d8176be65cea3992bd1a488d3 https://github.com/cgravier/routino-2.6-bikeopposite-elevation/commit/37af908880c045309fba1125c4d683f6925f7d25 by Christophe Collard. 2014-01-26 [r1496] Andrew M. Bishop <amb> * extras/find-fixme/web/www/fixme.leaflet.js, web/www/routino/router.openlayers.js, web/www/routino/visualiser.leaflet.js, extras/find-fixme/web/www/fixme.openlayers.js, web/www/routino/visualiser.openlayers.js, web/www/routino/router.leaflet.js: Fix bugs in displayStatus() function after jshint tidy-up. 2014-01-26 [r1495] Andrew M. Bishop <amb> * web/www/routino/router.leaflet.js, extras/find-fixme/web/www/fixme.leaflet.js, web/www/routino/visualiser.leaflet.js: Fix bug with Leaflet map startup. 2014-01-26 [r1494] Andrew M. Bishop <amb> * web/www/routino/mapprops.js: Reformat the whitespace. 2014-01-26 [r1493] Andrew M. Bishop <amb> * web/www/routino/router.leaflet.js, extras/find-fixme/web/www/fixme.leaflet.js, src/profiles.c, web/www/routino/router.openlayers.js, web/www/routino/visualiser.leaflet.js, web/www/routino/maploader.js, extras/find-fixme/web/www/fixme.openlayers.js, web/www/routino/page-elements.js, web/www/routino/visualiser.openlayers.js: Run jshint again and update some more in the JavaScript. 2014-01-25 [r1492] Andrew M. Bishop <amb> * doc/INSTALL.txt, doc/html/readme.html, web/www/leaflet/install.sh (added), doc/html/installation.html, web/www/leaflet (added), doc/README.txt: Add a script to download Leaflet Javascript and update documentation to match. 2014-01-25 [r1491] Andrew M. Bishop <amb> * extras/find-fixme/web/www/fixme.html, extras/find-fixme/Makefile, web/www/routino/router.html.de, web/www/routino/router.openlayers.js (added), web/www/routino/mapprops.js, web/www/routino/visualiser.leaflet.js (added), web/www/routino/maploader.js (added), extras/find-fixme/web/www/fixme.js (removed), web/www/routino/visualiser.openlayers.js (added), web/www/routino/router.html.en, web/www/routino/router.html.fr, web/www/routino/visualiser.html.en, extras/find-fixme/web/www/fixme.leaflet.js (added), web/www/routino/router.html.nl, web/www/routino/router.js (removed), extras/find-fixme/web/www, extras/find-fixme/web/www/fixme.openlayers.js (added), web/www/routino/visualiser.js (removed), web/www/routino/maplayout.css, web/www/routino/router.leaflet.js (added): Add the option to use Leaflet Javascript library instead of OpenLayers. Dynamically load the appropriate Javascript library based on mapprops.js. 2014-01-16 [r1489-1490] Andrew M. Bishop <amb> * src/superx.c: When merging segments and super-segments ensure that all super-segments are added to the merged list. * src/visualiser.c: When searching for nodes for the visualiser don't exceed the database lat/long limits. 2014-01-13 [r1488] Andrew M. Bishop <amb> * web/www/routino/router.html.en, web/www/routino/router.html.fr (added), web/www/routino/router.html.de, web/www/routino/router.html.nl, xml/routino-translations.xml: French language web page and routing translations based on https://github.com/ocivelo/routino-2.6-bikeopposite-elevation/commit/d426c7ff42e217ca5ace1244afc085c1433843c8 by Christophe Collard. 2014-01-11 [r1487] Andrew M. Bishop <amb> * web/www/routino/router.js, web/www/routino/search.pl, extras/find-fixme/web/www/fixme.js, web/www/routino/visualiser.js, web/www/routino/search.cgi: Change the search CGI to use latmin/max and lonmin/max instead of left, right, top, bottom. Change the Javascript to send the parameters to 5 decimal places only. 2014-01-11 [r1486] Andrew M. Bishop <amb> * extras/find-fixme/web/www/fixme.js, web/www/routino/visualiser.js, web/www/routino/router.html.en, extras/find-fixme/web/www/fixme.html, web/www/routino/router.html.de, web/www/routino/visualiser.html.en, web/www/routino/router.html.nl, web/www/routino/router.js: Update the web page URLs as things change rather than using on(focus|click) action handlers in the HTML that don't work very well. 2014-01-05 [r1485] Andrew M. Bishop <amb> * web/www/routino/maplayout-ie6-bugfixes.css (removed), web/www/routino/maplayout-ie7-bugfixes.css (removed), web/www/routino/router.html.en, extras/find-fixme/web/www/fixme.html, web/www/routino/router.html.de, web/www/routino/visualiser.html.en, web/www/routino/router.html.nl: Remove special support for IE6 and IE7 browsers. 2014-01-05 [r1484] Andrew M. Bishop <amb> * web/www/routino/router.js, extras/find-fixme/web/www/fixme.js, web/www/routino/visualiser.js: Replace the unescape() function with standard decodeURIComponent() function. 2014-01-03 [r1483] Andrew M. Bishop <amb> * web/www/routino/router.js, extras/find-fixme/web/www/fixme.js, web/www/routino/visualiser.js: Run 'jshint' to check for Javascript errors (fix the important ones). 2014-01-03 [r1480-1482] Andrew M. Bishop <amb> * web/www/routino/page-elements.js: Add a new function to hide and show sections (not currently used). * web/www/routino/page-elements.css: Make the tabs and hide/show targets a few pixels wider to make them easier to select. * web/www/routino/router.html.en, web/www/routino/router.html.de, web/www/routino/router.html.nl: Squeeze out a bit more space for the waypoint coords/name. 2014-01-02 [r1479] Andrew M. Bishop <amb> * src/relationsx.h: Fix error in function prototype (argument names switched). 2013-12-31 [r1477-1478] Andrew M. Bishop <amb> * extras/find-fixme/web/www/fixme.js, web/www/routino/visualiser.js, web/www/routino/router.js: Update Javascript to make map tile function more self-contained. * extras/find-fixme/web/www/fixme.html, web/www/routino/router.html.de, web/www/routino/visualiser.html.en, web/www/routino/router.html.nl, web/www/openlayers/routino.cfg, web/www/routino/router.html.en: Update HTML to make it work better on mobile devices (no zooming allowed). 2013-12-31 [r1476] Andrew M. Bishop <amb> * web/www/routino/router.html.en, web/www/routino/router.html.de, web/www/routino/visualiser.html.en, web/www/routino/router.html.nl: Update HTML ready for HTML5 but keeping HTML4.01 loose DTD (form action attribute must not be empty). 2013-12-31 [r1475] Andrew M. Bishop <amb> * web/www/routino/router.css, extras/find-fixme/web/www/fixme.html, web/www/routino/router.html.de, web/www/routino/visualiser.html.en, web/www/routino/router.html.nl, web/www/routino/router.js, extras/find-fixme/web/www/fixme.css, web/www/routino/visualiser.css, web/www/routino/router.html.en: Update HTML ready for HTML5 but keeping HTML4.01 loose DTD (align attribute and image tags with names are deprecated). 2013-12-31 [r1474] Andrew M. Bishop <amb> * doc/html/readme.html, doc/html/output.html, doc/html/tagging.html, doc/html/installation.html, doc/html/limits.html, doc/html/usage.html, doc/html/algorithm.html, doc/html/configuration.html, doc/html/index.html, doc/html/data.html: Update HTML ready for HTML5 but keeping HTML4.01 strict DTD (anchors with names are deprecated). 2013-12-30 [r1473] Andrew M. Bishop <amb> * doc/html/readme.html, doc/html/data.html: Update some URLs. 2013-12-30 [r1472] Andrew M. Bishop <amb> * web/www/routino/router.html.en, extras/find-fixme/web/www/fixme.html, web/www/routino/index.html, web/www/routino/router.html.de, web/www/routino/visualiser.html.en, web/www/routino/router.html.nl: Fix some changes that were missed from the last set of HTML updates. 2013-12-30 [r1471] Andrew M. Bishop <amb> * doc/html/installation.html: Fix links within the page. 2013-12-30 [r1469-1470] Andrew M. Bishop <amb> * extras/find-fixme/web/www/fixme.html, web/www/routino/index.html, web/www/routino/router.html.de, web/www/routino/visualiser.html.en, web/www/routino/router.html.nl, web/www/routino/router.html.en: Convert map pages to use lower case HTML tags and fix some HTML 4.01 strict DTD errors (but not converted to strict DTD due to use of target attribute on <a> tags). * doc/html/style.css, doc/html/usage.html, doc/html/algorithm.html, doc/html/configuration.html, doc/html/index.html, doc/html/data.html, extras/find-fixme/web/www/index.html, doc/html/readme.html, doc/html/output.html, doc/html/tagging.html, doc/html/installation.html, doc/html/limits.html: Convert documentation to HTML 4.01 strict DTD (from loose DTD). 2013-11-17 [r1468] Andrew M. Bishop <amb> * web/www/routino/router.cgi: Fix bug that did not allow more than 9 waypoints to be routed. 2013-11-13 [r1467] Andrew M. Bishop <amb> * src/osmparser.c: Refactor the length, weight and speed parsing functions a little bit and add some new formats. 2013-09-07 [r1466] Andrew M. Bishop <amb> * xml/routino-tagging.xml: Add the same "access=foot" aliasing to nodes as previously existed for ways. 2013-08-02 [r1465] Andrew M. Bishop <amb> * doc/html/usage.html, doc/USAGE.txt, src/output.c, src/router.c: Add a '--output-stdout' option. 2013-07-31 [r1464] Andrew M. Bishop <amb> * xml/routino-translations.xml: Updated Dutch translations. 2013-07-18 [r1463] Andrew M. Bishop <amb> * src/types.h: Replace the macros for type conversion with inline functions where there is a risk of overflow for normal data. 2013-07-14 [r1462] Andrew M. Bishop <amb> * src/optimiser.c: Removal of some code intended to speed things up but that actually slows things down. 2013-07-12 [r1461] Andrew M. Bishop <amb> * doc/html/algorithm.html, doc/ALGORITHM.txt: Update the algorithm documentation with a description of the algorithm used for finding the shortest path. 2013-07-10 [r1460] Andrew M. Bishop <amb> * Makefile.conf: Add an option to enable debugging symbols. 2013-07-08 [r1459] Andrew M. Bishop <amb> * doc/USAGE.txt: Fix typo in documentation string. 2013-07-08 [r1458] Andrew M. Bishop <amb> * doc/html/usage.html, src/filedumper.c: Fix typo in documentation string. 2013-07-06 Andrew M. Bishop <amb> Version 2.6 released. 2013-07-06 [r1455-1456] Andrew M. Bishop <amb> * FILES: Add some new files for version 2.6. * doc/Makefile, extras/Makefile, src/test/Makefile, src/Makefile, extras/find-fixme/Makefile, Makefile, extras/tagmodifier/Makefile, xml/Makefile: Update some Makefiles for running 'make test' from a clean set of source code. 2013-07-06 [r1454] Andrew M. Bishop <amb> * doc/NEWS.txt, doc/README.txt, FILES, doc/html/readme.html: Update for version 2.6 release. 2013-07-04 [r1453] Andrew M. Bishop <amb> * doc/html/installation.html, doc/INSTALL.txt: Added a 'quick start' set of installation instructions. 2013-07-04 [r1452] Andrew M. Bishop <amb> * web/data/create.sh: Fix error with URL. 2013-07-03 [r1451] Andrew M. Bishop <amb> * src/planetsplitter.c: Revert r1268 which was applied between v2.5 and v2.5.1 and could be the cause of the slight slowdown in version 2.5.1. 2013-07-02 [r1450] Andrew M. Bishop <amb> * src/relationsx.c, src/errorlog.c, src/logerror.c, src/optimiser.c, src/waysx.c, src/xmlparse.c: Fix some comments. 2013-07-02 [r1449] Andrew M. Bishop <amb> * src/logging.c: Fix bug in time printed by --logtime option. 2013-07-02 [r1448] Andrew M. Bishop <amb> * src/segmentsx.c, src/prunex.c, src/segmentsx.h: Revert r1432 because even though it seemed like it should have been faster in slim mode it was actually much slower on the routino.org virtual server. 2013-07-01 [r1447] Andrew M. Bishop <amb> * src/output.c: Small optimisation for calling GetLatLong(). 2013-07-01 [r1446] Andrew M. Bishop <amb> * web/data/create.sh: Fix the URLs in the example download script. 2013-07-01 [r1445] Andrew M. Bishop <amb> * src/xmlparse.c, src/xmlparse.h: Forcing the xmlparse tags to be lower case adds a further speed-up (and was implicitly assumed already in other code). 2013-07-01 [r1444] Andrew M. Bishop <amb> * src/results.h, src/superx.c, src/results.c, src/queue.c: Re-use the Queue and Results data structure for all routes - saves a huge number of malloc/free calls (found by valgrind/callgrind). 2013-06-29 [r1443] Andrew M. Bishop <amb> * src/xmlparse.c: Optimise out most calls to strcasecmp the most-called C library functions (found by valgrind/callgrind). 2013-06-29 [r1442] Andrew M. Bishop <amb> * src/prunex.c: Close file and free memory (found by valgrind). 2013-06-29 [r1441] Andrew M. Bishop <amb> * src/sorting.c: Free allocated memory (found by valgrind). 2013-06-29 [r1440] Andrew M. Bishop <amb> * src/logerror.c: Avoid writing uninitialised to disk (found by valgrind). 2013-06-29 [r1439] Andrew M. Bishop <amb> * extras/find-fixme/web/www/fixme.js, extras/find-fixme/web/www/fixme.html: Update highlight size and help text as was done with visualiser. 2013-06-29 [r1438] Andrew M. Bishop <amb> * web/www/routino/router.html.en, web/www/routino/router.html.de, web/www/routino/visualiser.html.en, web/www/routino/router.html.nl: Add some help to the visualiser web page and slightly reformatted the help on the router web pages. 2013-06-29 [r1435-1437] Andrew M. Bishop <amb> * web/www/routino/visualiser.js: Increase the size of the nodes in the super-nodes/segments display to make them clickable. * web/www/routino/visualiser.cgi: Increase the maximum size that will be returned by CGI. * web/www/routino/visualiser.js: Fix bug with visualiser failing to run failure callback in case of CGI error. 2013-06-29 [r1433-1434] Andrew M. Bishop <amb> * web/www/routino/visualiser.js: Make the node highlights smaller (to match the segment highlight width). * src/filedumper.c: Print the fake XML for the visualiser with special routino:* top-level tag names. 2013-06-28 [r1431-1432] Andrew M. Bishop <amb> * src/segmentsx.c, src/prunex.c, src/segmentsx.h: Keep the next2 pointer in memory while pruning rather than in the segmentx object. * src/prunex.h, src/planetsplitter.c, src/segmentsx.c, src/prunex.c, src/segmentsx.h, doc/DATALIFE.txt: Revert the last three changes because r1430 didn't work and r1428+r1429 didn't give any speed advantage and was possibly marginally slower. 2013-06-28 [r1430] Andrew M. Bishop <amb> * src/segmentsx.c: The IndexSegments() function can now process the file in forward order rather than reverse. 2013-06-27 [r1429] Andrew M. Bishop <amb> * src/segmentsx.c: Fixed error with last checkin. 2013-06-27 [r1428] Andrew M. Bishop <amb> * src/segmentsx.c, src/prunex.c, src/segmentsx.h, doc/DATALIFE.txt, src/prunex.h, src/planetsplitter.c: Put the next1 pointer in the segmentx object rather than in-memory. 2013-06-27 [r1427] Andrew M. Bishop <amb> * doc/DATALIFE.txt, src/relationsx.c, src/planetsplitter.c, src/waysx.c, src/relationsx.h, src/segmentsx.c, src/nodesx.c, src/segmentsx.h: Revert the last change because, paradoxically, it was faster to create the database (as expected) but slower to route. 2013-06-26 [r1426] Andrew M. Bishop <amb> * doc/DATALIFE.txt, src/relationsx.c, src/planetsplitter.c, src/waysx.c, src/relationsx.h, src/segmentsx.c, src/nodesx.c, src/segmentsx.h: Sort the nodes geographically at the beginning rather than at the end. 2013-06-26 [r1425] Andrew M. Bishop <amb> * doc/html/installation.html, doc/INSTALL.txt: Add some more details about configuring Apache. 2013-06-25 [r1424] Andrew M. Bishop <amb> * src/relationsx.c, src/planetsplitter.c, src/nodesx.c, doc/DATALIFE.txt: Remove one usage of the nodesx->gdata array. Remove one call of the IndexSegments() function. Update the DATALIFE.txt file with both and the previous changes to mapped files and add a new column for segmentx->next2. 2013-06-25 [r1423] Andrew M. Bishop <amb> * src/superx.c: Change the ChooseSuperNodes() and MergeSuperSegments() functions to read through the file instead of mapping the data to help slim mode (since the nodes in the first case and segments in the second case are read sequentially). 2013-06-24 [r1422] Andrew M. Bishop <amb> * src/segmentsx.c: Change the IndexSegments() function so that in slim mode larger chunks are read from the file (since it reads sequentially but in reverse through the file). 2013-06-24 [r1420-1421] Andrew M. Bishop <amb> * src/files.c: Increase the buffer to 4kB from 1kB. * src/osmo5mparse.c, src/waysx.c, src/nodesx.c, src/osmpbfparse.c, src/prunex.c, src/superx.c, src/relationsx.c: Move some printf_first() messages to the front of the function and printf_last() function to the end of the function. 2013-06-23 [r1419] Andrew M. Bishop <amb> * src/ways.h: Fix error in slim mode WayName() function. 2013-06-22 [r1412-1418] Andrew M. Bishop <amb> * src/files.c, src/files.h: Make the changes required to handle the new function names from the last few checkins. * src/prunex.c: Use SlimMapFile(), SlimUnmapFile(), SlimFetch() and SlimReplace() [see earlier log message] and also refactor the code so that the additional ways are placed in a separate file using the Slim*() functions rather than being appended to the open (or mapped) way file. * src/ways.h: Use SlimFetch() instead of SeekReadFileUnbuffered() [see previous log message] and also refactor the code for reading the way name from file. * src/errorlog.h, src/relations.c, src/ways.c, src/segments.c, src/cache.h, src/nodes.c, src/errorlog.c: Use SlimMapFile() and SlimUnmapFile() [see previous log message] and also use SlimFetch() instead of SeekReadFileUnbuffered() and SlimReplace() instead of SeekWriteFileUnbuffered() to hide the internals of the slim mode. * src/superx.c, src/relationsx.c, src/waysx.c, src/segmentsx.c, src/errorlogx.c: Use SlimMapFile() and SlimUnmapFile() as the function names for the slim mode of operation to open and close the files (to hide the fact that they are files being opened for reading or writing unbuffered). * src/errorlogx.c: Use buffered file accesses for appending the error strings to the binary file. * src/planetsplitter.c, src/tagging.c, src/translations.c, extras/find-fixme/fixme-finder.c, extras/tagmodifier/tagmodifier.c, src/profiles.c: Create simple OpenFile() and CloseFile() functions for those files which are used by the parsers (they just call open() and close() internally). 2013-06-22 [r1411] Andrew M. Bishop <amb> * src/logerror.c: Fix for closing binary error file that only shows up after the recent file function changes. 2013-06-21 [r1410] Andrew M. Bishop <amb> * src/files.c, extras/tagmodifier/tagmodifier.c, src/files.h, src/cache.h, src/nodes.c, src/planetsplitter.c, src/waysx.c, src/segmentsx.c, src/tagging.c, src/prunex.c, src/translations.c, extras/find-fixme/fixme-finder.c, src/errorlogx.c, src/profiles.c, src/ways.c, src/filedumperx.c, src/segments.c, src/superx.c, src/ways.h, src/relationsx.c, src/errorlog.c, src/errorlog.h, src/relations.c: Rename the functions for unbuffered file access to make this clear. 2013-06-21 [r1409] Andrew M. Bishop <amb> * src/waysx.c, src/segmentsx.c, src/nodesx.c, src/errorlogx.c, src/sorting.c, src/relationsx.c: Use the new buffered functions in the filesort functions. 2013-06-21 [r1407-1408] Andrew M. Bishop <amb> * src/segmentsx.c, src/nodesx.c, src/prunex.c, src/errorlogx.c, src/filedumperx.c, src/relationsx.c, src/logerror.c, src/waysx.c: Use the new functions for buffering while reading when looping through files other than the ones already done that use the FILESORT_VARINT method of storing data. * src/files.c, src/files.h: Add a new function for seeking in one of the buffered files. 2013-06-20 [r1406] Andrew M. Bishop <amb> * src/errorlogx.c, src/files.h, src/relationsx.c, src/waysx.c, src/nodesx.c, src/files.c: Rename the function that skips forward in a buffered file to avoid confusion. 2013-06-20 [r1404-1405] Andrew M. Bishop <amb> * src/relationsx.c, src/waysx.c, src/nodesx.c, src/errorlogx.c, src/filedumperx.c: Use the new functions for buffering while reading when looping through files that use the FILESORT_VARINT method of storing data. * src/files.c, src/files.h: Add new functions for buffering when reading and also allow seeking in one of these buffered files. 2013-06-20 [r1403] Andrew M. Bishop <amb> * src/files.c: Fix the non-buffered close function assertion and re-factor the code for buffered reading (although not used yet). 2013-06-19 [r1401-1402] Andrew M. Bishop <amb> * src/nodesx.c, src/relationsx.c, src/waysx.c, src/segmentsx.c: Use the buffered write functions when creating the nodes, segments, ways and relation raw files. * src/files.c, src/files.h: Add functions to read and write file descriptors with buffering. 2013-06-19 [r1400] Andrew M. Bishop <amb> * extras/find-fixme/fixme-finder.c, src/logging.c, src/planetsplitter.c: Bug fix for the change to the --logtime option functions. 2013-06-19 [r1399] Andrew M. Bishop <amb> * src/files.h: Split the function prototypes into two groups for the ones in files.c and the inline ones in files.h. 2013-06-17 [r1398] Andrew M. Bishop <amb> * extras/find-fixme/fixme-finder.c, src/logging.c, src/planetsplitter.c, src/logging.h: Change the --logtime internals so that programs don't need to store their start time themselves. 2013-06-15 [r1397] Andrew M. Bishop <amb> * xml/routino-tagging.xml: Add some more barriers which are too generic to warn about and fix spelling of motorcycle_barrier. 2013-06-13 [r1396] Andrew M. Bishop <amb> * doc/html/usage.html, doc/USAGE.txt: Document that --errorlog and --keep together will create the binary database of errors. 2013-06-13 [r1395] Andrew M. Bishop <amb> * src/errorlogx.c, src/logerror.c, src/logging.h: Separate out the type and id parts of the errorlogobject. 2013-06-12 [r1394] Andrew M. Bishop <amb> * web/www/routino/mapprops.js, doc/html/installation.html, extras/find-fixme/web/www/fixme.js, web/www/routino/visualiser.js, doc/INSTALL.txt: Add links to the OpenStreetMap browse URLs from the error logs. 2013-06-11 [r1393] Andrew M. Bishop <amb> * extras/find-fixme/web/www/fixme.js, extras/find-fixme/web/www/fixme.cgi, extras/find-fixme/web/www/fixme.html: Put the data tab back and display the statistics in it. 2013-06-10 [r1391-1392] Andrew M. Bishop <amb> * src/errorlogx.c: Fix typo in program logging. * doc/html/usage.html, doc/USAGE.txt: Fix typo in documentation. 2013-06-06 [r1387-1390] Andrew M. Bishop <amb> * src/Makefile: Tidy up the compilation and linking flags again. * Makefile.conf: Tidy up the compilation and linking flags again. * src/test/Makefile, src/test/is-fast-math.c (added), src/test, src/test/start-1-finish.sh, src/test/a-b-c.sh, src/test/a-b.sh: When compiled with -ffast-math don't expect the results to match exactly, display the differences. * src/test/only-split.sh: Remove a debugging message. 2013-06-06 [r1386] Andrew M. Bishop <amb> * src/test/expected/dead-ends-WP08.txt, src/test/expected/dead-ends-WP09.txt, src/test/dead-ends.osm, src/test/expected/node-restrictions-WP08.txt, src/test/expected/dead-ends-WP01.txt, src/test/expected/dead-ends-WP10.txt, src/test/expected/dead-ends-WP02.txt, src/test/expected/dead-ends-WP11.txt, src/test/expected/dead-ends-WP03.txt, src/test/expected/dead-ends-WP04.txt, src/test/expected/dead-ends-WP05.txt, src/test/expected/dead-ends-WP06.txt, src/test/expected/dead-ends-WP07.txt: Change test cases so that they don't show differences due to pruning or the last checkin for divide by zero which changed behaviour in trivial case. 2013-06-06 [r1385] Andrew M. Bishop <amb> * src/prunex.c, src/nodes.c, src/fakes.c: Fix some code that could, potentially, have given a divide by zero and which therefore behaves differently with FPU and -ffast-math compilation options. 2013-06-06 [r1384] Andrew M. Bishop <amb> * src/translations.c: Fix bug if using the built-in translations for GPX route files (present since v2.0). Make a few other translations match the ones in the XML file. 2013-06-05 [r1383] Andrew M. Bishop <amb> * doc/DATALIFE.txt, src/nodesx.c: Update the node id just before sorting geographically rather than relying on the pruning process to do it. 2013-06-05 [r1381-1382] Andrew M. Bishop <amb> * web/www/routino/index.html, doc/Makefile: Copy the style.css into the web page documentation directory, fix the link to it from index.html. * extras/find-fixme/Makefile, extras/find-fixme/web/www, extras/find-fixme/web/www/paths.pl, extras/find-fixme/web/www/index.html (added), extras/find-fixme/web/www/fixme.html: Add an index.html page to redirect to fixme.html, copy in a style.css file, slightly change the web page titles. 2013-06-04 [r1380] Andrew M. Bishop <amb> * src/waysx.c, src/waysx.h, src/prunex.c: Remember what types of transports we have so that we don't spend time pruning for transport types we don't have. 2013-06-04 [r1379] Andrew M. Bishop <amb> * src/tagging.c: Unconditionally execute the tagging rules within '<if> ... </if>' even if there are no input tags to match against the match-all rule. 2013-06-03 [r1377-1378] Andrew M. Bishop <amb> * extras/find-fixme/fixme-dumper.c, extras/find-fixme/README.txt: Reinstate the --statistics option. * extras/find-fixme/web/www/fixme.js: Nicely format the item tag information. 2013-06-03 [r1374-1376] Andrew M. Bishop <amb> * extras/find-fixme/fixme.xml, extras/find-fixme/README.txt: Make it easier to select arbitrary tags and store them. * extras/find-fixme/osmparser.c: Store a whole XML-like item in the log file. * src/tagging.c, src/tagging.h: Add a new function to convert a TagList into an HTML-like string. 2013-06-03 [r1373] Andrew M. Bishop <amb> * Makefile.conf: Use the -ffast-math compilation option (trivial changes to estimated journey times and distances). 2013-06-03 [r1371-1372] Andrew M. Bishop <amb> * web/bin: Don't ignore tagmodifier (not put here any more). * extras/find-fixme/Makefile, extras/tagmodifier/Makefile: Compile all of src directory before starting here. 2013-06-03 [r1370] Andrew M. Bishop <amb> * src/osmparser.c, src/relationsx.h, extras/find-fixme/osmparser.c, src/errorlogx.c, src/relationsx.c: Write relation nodes into the file as well as ways and relations. 2013-06-01 [r1367-1369] Andrew M. Bishop <amb> * extras/errorlog/README.txt: Make the README files more consistent with each other in style. * extras/README.txt, extras/plot-time/README.txt, extras/tagmodifier/README.txt: Make the README files more consistent with each other in style. * extras/find-fixme/fixme-dumper.c (added), extras/find-fixme/web/www/fixme.js (added), extras/find-fixme/web/bin (added), extras/find-fixme/web/data (added), extras/find-fixme/web/www/paths.pl (added), extras/find-fixme/osmparser.c (added), extras/find-fixme/fixme-finder.c (added), extras/find-fixme/web/www/fixme.css (added), extras/find-fixme (added), extras/find-fixme/web/www (added), extras/find-fixme/fixme.xml (added), extras/find-fixme/web/www/fixme.cgi (added), extras/find-fixme/README.txt (added), extras/find-fixme/web/www/fixme.html (added), extras/find-fixme/web (added), extras/find-fixme/Makefile (added): A tool to search an OSM file for "fixme" tags to create a database and display them on an interactive map. 2013-06-01 [r1366] Andrew M. Bishop <amb> * src/planetsplitter.c: Fix minor error with usage message. 2013-06-01 [r1363-1365] Andrew M. Bishop <amb> * extras/tagmodifier/README.txt, extras/tagmodifier/Makefile: Compile all main Routino files before trying to build tagmodifier. Small changes to the README.txt file. * src/Makefile: Use the WEBBINDIR variable rather than a hard-coded path. * doc/Makefile: Make the Makefile clearer with respect to the copying of HTML files to the web directory. 2013-06-01 [r1361-1362] Andrew M. Bishop <amb> * src/errorlogx.h, src/planetsplitter.c, src/errorlogx.c: Make the functions for processing error logs more like the ones for nodes, ways and relations. * src/waysx.c, src/nodesx.c, src/relationsx.c: Store the number of kept nodes, ways and relations when first sorted. 2013-06-01 [r1360] Andrew M. Bishop <amb> * web/www/routino/visualiser.cgi: Return an error if neither type of recognised request was made. 2013-05-31 [r1359] Andrew M. Bishop <amb> * src/planetsplitter.c, src/router.c: Use exit(EXIT_FAILURE) instead of return(1). 2013-05-31 [r1357-1358] Andrew M. Bishop <amb> * extras/README.txt, extras/plot-time/README.txt (added), extras/plot-time/plot-planetsplitter-time.pl (added), extras/plot-time (added): Add a Perl script that allows plotting a graph of the time taken to run planetsplitter. * extras/errorlog/README.txt (added): Add a README file for the summarise-log.pl script. 2013-05-31 [r1356] Andrew M. Bishop <amb> * src/osmo5mparse.c, src/osmxmlparse.c, src/osmparser.c, src/osmparser.h, src/osmpbfparse.c: Move some functions about so that osmparser.c can be replaced for other types of parsing. 2013-05-31 [r1355] Andrew M. Bishop <amb> * src/segmentsx.c, src/planetsplitter.c, src/waysx.c: Small changes to comments and log messages. 2013-05-30 [r1354] Andrew M. Bishop <amb> * src/segmentsx.c: Don't de-duplicate when sorting segments (now done in ProcessSegments() function). 2013-05-30 [r1353] Andrew M. Bishop <amb> * src/relationsx.c, src/planetsplitter.c, src/relationsx.h, doc/DATALIFE.txt: Merge the ProcessTurnRelations1() and ProcessTurnRelations2() functions into a single one now that segment processing is already complete. 2013-05-30 [r1352] Andrew M. Bishop <amb> * doc/DATALIFE.txt, src/planetsplitter.c: Move the first IndexSegments() function call earlier in the sequence. 2013-05-30 [r1351] Andrew M. Bishop <amb> * src/planetsplitter.c, src/segmentsx.c, src/segmentsx.h, doc/DATALIFE.txt: Merge the RemoveBadSegments() and MeasureSegments() functions. Saves one read/write iteration through the segments file. 2013-05-30 [r1350] Andrew M. Bishop <amb> * src/planetsplitter.c, src/segmentsx.c, src/nodesx.c, src/segmentsx.h, doc/DATALIFE.txt, src/nodesx.h, src/relationsx.c: Delete the non-highway nodes by searching for them in the ways rather than marking them when processing the segments. 2013-05-29 [r1349] Andrew M. Bishop <amb> * doc/DATALIFE.txt, extras/errorlog/summarise-log.pl, src/relationsx.c, src/planetsplitter.c, src/waysx.c, src/segmentsx.c, src/nodesx.c, src/waysx.h, src/segmentsx.h: Simplify the segments by using the node and way index instead of node and way id which avoids lots of IndexNodeX() lookups. Move some other code around to cope with it. 2013-05-27 [r1348] Andrew M. Bishop <amb> * src/planetsplitter.c, src/waysx.c, src/waysx.h, doc/DATALIFE.txt: Simplify the sorting of the way names (only sort the names, not all the ways twice), merge the generating of segments and separation of way names. 2013-05-27 [r1347] Andrew M. Bishop <amb> * src/osmparser.c, src/waysx.c, src/segmentsx.c: Redistributed error log messages from osmparser way handling. 2013-05-26 [r1346] Andrew M. Bishop <amb> * extras/errorlog/summarise-log.pl (added), extras/errorlog (added), extras/README.txt, web/bin/summarise-log.pl (removed): Move the summarise-log.pl script into the extras directory. 2013-05-26 [r1345] Andrew M. Bishop <amb> * extras/tagmodifier/README.txt (added), extras/tagmodifier/tagmodifier.c (added), extras/tagmodifier/Makefile (added), doc/html/installation.html, extras/tagmodifier (added), doc/html/usage.html, extras/README.txt, src/tagmodifier.c (removed), src/Makefile, src, doc/USAGE.txt, doc/INSTALL.txt: Move the tagmodifier program into the extras directory. 2013-05-26 [r1344] Andrew M. Bishop <amb> * extras (added), extras/README.txt (added), extras/Makefile (added): Create a new directory for extra (non-essential) programs 2013-05-26 [r1343] Andrew M. Bishop <amb> * doc/Makefile, src/test/Makefile, src/Makefile, src/xml/Makefile, doc/INSTALL.txt, Makefile, doc/html/installation.html, xml/Makefile, Makefile.conf (added): Re-organise the Makefiles so that all configuration information is one of them (Makefile.conf at the top level) rather than being spread between them. 2013-05-25 [r1342] Andrew M. Bishop <amb> * src/errorlogx.c, src/relationsx.c, src/relationsx.h: Rename the route relation structure parameters (r* -> rr*) to match the turn relation parameter names (tr*). 2013-05-25 [r1341] Andrew M. Bishop <amb> * src/errorlogx.c, src/relationsx.c, src/relationsx.h: Finished allocating coordinates to error logs, nodes in preference to ways in preference to relations. 2013-05-23 [r1340] Andrew M. Bishop <amb> * doc/USAGE.txt, src/filedumperx.c, doc/html/usage.html: There are no segments stored after parsing so cannot be dumper by filedumperx. 2013-05-23 [r1339] Andrew M. Bishop <amb> * src/superx.c, src/types.h, src/planetsplitter.c, src/osmparser.c, src/waysx.c, src/segmentsx.c, src/osmparser.h, src/waysx.h, src/segmentsx.h, doc/DATALIFE.txt, src/types.c: Don't create segments when parsing input file but create the segments later using the nodes stored in the ways file. This makes applying changes simpler (segments file is not kept with the --keep option) and handling changed ways is simpler than changed segments. 2013-05-22 [r1338] Andrew M. Bishop <amb> * src/osmparser.c, src/waysx.c, src/waysx.h, src/errorlogx.c, src/filedumperx.c: Store the list of nodes in the raw ways file for use by the errorlog functions. 2013-05-21 [r1337] Andrew M. Bishop <amb> * src/sorting.c: Don't waste memory in filesort_vary() when the pre-sort function drops the data. 2013-05-20 [r1336] Andrew M. Bishop <amb> * src/osmparser.c: Store more logerror information even for items that are discarded to allow them to be located geographically. 2013-05-20 [r1335] Andrew M. Bishop <amb> * src/xml/Makefile: Update CLFLAGS and LDFLAGS. 2013-05-18 [r1334] Andrew M. Bishop <amb> * web/www/routino/router.html.en, doc/INSTALL.txt, web/www/routino/router.html.de, web/www/routino/visualiser.html.en, web/www/routino/router.html.nl, web/www/routino/router.js, web/www/routino/mapprops.js, doc/html/installation.html, web/www/routino/visualiser.js: Make the OSM editor URL be configurable in the mapprops.js file. 2013-05-18 [r1333] Andrew M. Bishop <amb> * web/www/openlayers/routino.cfg: Need to include OpenLayers/Control/SelectFeature.js when building OpenLayers.js. 2013-05-18 [r1332] Andrew M. Bishop <amb> * web/www/routino/visualiser.css, web/www/routino/visualiser.js: Put the popup colours in the Javascript, not CSS. Set the popup font (fixed) and size (smaller). 2013-05-18 [r1330-1331] Andrew M. Bishop <amb> * src/visualiser.c: Remove unused header file. * src/filedumper.c, doc/USAGE.txt, web/www/routino/visualiser.cgi, doc/html/usage.html: Create specific HTML formatted output from filedumper for the visualiser web page. 2013-05-18 [r1329] Andrew M. Bishop <amb> * web/www/routino/visualiser.cgi, src/visualiser.c, web/www/routino/visualiser.js: Add the ability to select any item displayed in the visualiser and display information about it in a popup. 2013-05-18 [r1327-1328] Andrew M. Bishop <amb> * web/www/routino/router.js, web/www/routino/visualiser.js: Don't display the marker layers in the layer switcher control. * web/www/routino/visualiser.js: Store the feature attributes using the feature.attributes object. 2013-05-18 [r1326] Andrew M. Bishop <amb> * web/www/routino/visualiser.js, web/www/routino/visualiser.css: Change to using a popup like in the router and highlight the selected item when the popup is displayed. 2013-05-17 [r1324-1325] Andrew M. Bishop <amb> * web/www/routino/visualiser.html.en: Selecting the radio buttons updates the display. * web/www/routino/router.html.de, web/www/routino/router.html.nl, web/www/routino/router.html.en: Added some missing ';' to the Javascript actions in the HTML. 2013-05-17 [r1323] Andrew M. Bishop <amb> * doc/html/usage.html, doc/USAGE.txt: Add the documentation for the change to the filedumper program. 2013-05-17 [r1322] Andrew M. Bishop <amb> * src/visualiser.c: Limit the error log outputs to the geographical ones and make the strings HTML safe. 2013-05-17 [r1321] Andrew M. Bishop <amb> * src/errorlog.h, web/www/routino/visualiser.html.en, src/errorlogx.c, src/visualiser.c, web/www/routino/visualiser.js, src/planetsplitter.c, src/errorlog.c, src/visualiser.h, src/Makefile, src/filedumper.c, web/www/routino/visualiser.cgi: Allow dumping error logs from filedumper. 2013-05-14 [r1320] Andrew M. Bishop <amb> * src/errorlogx.c, src/errorlogx.h, src/errorlog.c (added), src/errorlog.h (added): Copy errorlogx.h to errorlog.h and create errorlog.c so that they mirror the nodes.h and nodes.c filenames. Add functions to read in a set of error logs from a file. 2013-05-13 [r1319] Andrew M. Bishop <amb> * src/logerror.c, src/Makefile, src/logerror.h (removed), src/errorlogx.c (added), src/logerrorx.c (removed), src/errorlogx.h (added), src/planetsplitter.c: Rename logerrorx.c to errorlogx.c and logerrorx.h to errorlogx.h so that they mirror the nodesx.c and nodesx.h filenames. 2013-05-13 [r1318] Andrew M. Bishop <amb> * src/tagmodifier.c, src/logging.h, src/osmparser.c, src/segmentsx.c, src/logerror.h, src/tagging.c, src/relationsx.c: Move the logerror function prototypes back into logging.h and remove the logerror.h header file from most source files again. 2013-05-12 [r1317] Andrew M. Bishop <amb> * src/logerror.c, src/waysx.c, src/Makefile, src/relationsx.h, src/segmentsx.c, src/logerror.h, src/nodesx.c, src/waysx.h, src/segmentsx.h, src/logerrorx.c (added), src/nodesx.h, src/relationsx.c, src/planetsplitter.c: Add functions to process the binary error log file and convert it into a geographically searchable database. 2013-05-11 [r1314] Andrew M. Bishop <amb> * src/planetsplitter.c: Rename the Nodes, Segments, Ways and Relations variables to avoid confusion with types of the same name. 2013-05-11 [r1313] Andrew M. Bishop <amb> * src/logerror.h (added), src/tagging.c, src/logging.c, src/relationsx.c, src/planetsplitter.c, src/tagmodifier.c, src/logerror.c (added), src/logging.h, src/osmparser.c, src/Makefile, src/segmentsx.c: Create a binary log file that contains the node, way and relation id and a link to the error message for easy parsing. 2013-05-11 [r1312] Andrew M. Bishop <amb> * src/ways.c, src/relations.h, src/segments.c, src/nodes.c, src/ways.h, src/segments.h, src/nodes.h, src/relations.c, src/router.c: Add functions to destroy the node/segment/way/relation lists and don't call them from the end of the router by default. 2013-05-10 [r1308-1311] Andrew M. Bishop <amb> * src/Makefile: Enable -Wextra compilation option (but not -Wunused-parameter option) by default. * src/sorting.c: Change data type from signed to unsigned (pedantic compiler warning). * src/results.c: Change data value from signed to unsigned (pedantic compiler warning). * src/waysx.h, src/segmentsx.h, src/nodesx.h: Make no-op macros look like real statements. 2013-05-10 [r1305-1307] Andrew M. Bishop <amb> * src/results.c: Change data value from signed to unsigned (pedantic compiler warning). * src/prunex.c: Change data value from unsigned to signed (pedantic compiler warning). * src/filedumper.c: Remove always true condition (pedantic compiler warning). 2013-05-10 [r1304] Andrew M. Bishop <amb> * src/queue.c: Small change to algorithm to match sorting.c. 2013-05-09 [r1302-1303] Andrew M. Bishop <amb> * src/relations.c: Change data value from unsigned to signed (pedantic compiler warning). * src/planetsplitter.c, src/waysx.c: Change datatype from signed to unsigned (pedantic compiler warning). 2013-05-09 [r1299-1301] Andrew M. Bishop <amb> * src/osmpbfparse.c, src/osmo5mparse.c, src/xmlparse.c: Change datatype from signed to unsigned (pedantic compiler warning). Use inttypes.h printf formatting for unsigned long long data type. * src/files.h: Cast data to signed before comparison (pedantic compiler warning). * src/filedumperx.c: Change datatype from signed to unsigned (pedantic compiler warning). 2013-05-07 [r1298] Andrew M. Bishop <amb> * src/nodes.c: Change the GetLatLong() function to have one binary search instead of two. 2013-05-07 [r1297] Andrew M. Bishop <amb> * src/cache.h, src/nodes.c, src/relationsx.c, src/waysx.c, src/segmentsx.c, src/nodesx.c, src/waysx.h, src/prunex.c, src/segmentsx.h, src/nodesx.h, src/superx.c: Add cache functions for NodesX, SegmentsX and WaysX to speed up the planetsplitter in slim mode. 2013-05-07 [r1296] Andrew M. Bishop <amb> * src/cache.c (removed), src/relations.h, src/cache.h, src/ways.h, src/segments.h, src/Makefile, src/nodes.h: Move the cache functions out of cache.c and into each data type's header file as inline functions. 2013-05-03 [r1294-1295] Andrew M. Bishop <amb> * src/cache.c: Revert to the round-robin cache eviction algorithm. * src/cache.c: Implement an LRU eviction algorithm for the cached objects - it's slower, but code kept for possible future re-use. 2013-05-03 [r1293] Andrew M. Bishop <amb> * src/cache.c, src/relations.h, src/cache.h, src/ways.h, src/segments.h, src/nodes.h: Tidy up the code for the last check-in and use macros to allow replication of the functions for each type. 2013-05-03 [r1292] Andrew M. Bishop <amb> * src/segments.h, src/Makefile, src/nodes.h, src/relations.c, src/router.c, src/cache.c (added), src/ways.c, src/relations.h, src/segments.c, src/cache.h (added), src/nodes.c, src/ways.h: Add node, segment, way and turn relation cache for slim mode. Approx 40% speed-up for router. 2013-05-01 [r1291] Andrew M. Bishop <amb> * src/output.c, src/router.c, src/segments.c, src/visualiser.c, src/nodes.c, src/fakes.c, src/optimiser.c, src/filedumper.c, src/nodes.h: The GetLatLong function takes a pointer to the node as an argument - must be an optimisation for slim mode if not normal mode. 2013-05-01 [r1290] Andrew M. Bishop <amb> * src/results.c, src/queue.c, src/results.h: Move the queue score back into the results structure since it is quicker but uses slightly more memory. 2013-05-01 [r1289] Andrew M. Bishop <amb> * src/queue.c, src/results.h, src/superx.c, src/optimiser.c, src/results.c: Try to speed up the priority queue by allocating less memory and storing the score in the queue rather than in the result. 2013-04-28 [r1288] Andrew M. Bishop <amb> * src/results.c: Set pointers to NULL when resizing the hash table. 2013-04-27 [r1287] Andrew M. Bishop <amb> * src/superx.c: Update for change to NewResultsList() function. 2013-04-27 [r1286] Andrew M. Bishop <amb> * src/optimiser.c, src/results.c, src/results.h: Increase the starting number of bins to allow more results to be stored before resizing. 2013-04-27 [r1285] Andrew M. Bishop <amb> * src/results.c, src/results.h: Use a linked list to store the results in each bin rather than pre-allocated pointers. 2013-04-27 [r1283-1284] Andrew M. Bishop <amb> * src/results.c: Improve the hash function to avoid node/segment correlations in some geographic areas. * src/router.c: De-allocate the final routes at the end. 2013-04-27 [r1282] Andrew M. Bishop <amb> * src/results.c, src/results.h: Increase the allowed number of collisions as the number of bins increases. 2013-04-27 [r1281] Andrew M. Bishop <amb> * src/results.h, src/optimiser.c, src/router.c, src/results.c: Remove the FindResult1 function which allows hashing to be performed on a combination of node and segment rather than just node. 2013-04-26 [r1280] Andrew M. Bishop <amb> * src/results.c, src/results.h: Force a hard limit on the number of hash collisions. 2013-04-20 Andrew M. Bishop <amb> Version 2.5.1 released 2013-04-20 [r1279] Andrew M. Bishop <amb> * doc/html/readme.html, doc/NEWS.txt, FILES: Updated for version 2.5.1 release. 2013-04-18 [r1278] Andrew M. Bishop <amb> * src/router.c, src/optimiser.c, src/functions.h: Fix a bug where the shortest route crossing super-nodes requires two U-turns and is therefore impossible to compute even though an obvious shorter route without crossing super-nodes exists (but cannot be taken until the super-node route is fully tested). Requires quite a major change in router handling of this special case. 2013-04-18 [r1277] Andrew M. Bishop <amb> * src/xmlparse.c: Fix bug with handling UTF-8 characters that are four bytes long (it didn't since v2.5). 2013-04-17 [r1276] Andrew M. Bishop <amb> * src/optimiser.c: Fix bug that corrupts the combined route score when combining the route (only important if comparing non-super-node route with super-node route). 2013-04-15 [r1275] Andrew M. Bishop <amb> * web/www/openlayers/install.sh: Default to downloading openlayers 2.12. 2013-04-13 [r1274] Andrew M. Bishop <amb> * doc/INSTALL.txt, doc/html/installation.html: Add a note about the *-slim executables to the installation section. 2013-04-13 [r1273] Andrew M. Bishop <amb> * src/tagmodifier.c: Use single quotes rather than double quotes when writing out the XML for similarity with filedumper. 2013-04-13 [r1272] Andrew M. Bishop <amb> * src/xmlparse.c: Fix XML character quoting for characters within the 7-bit printable ASCII range (bug reported by Dirk Eversmann). 2013-04-13 [1271] Andrew M. Bishop <amb> * web/www/routino/router.js, web/www/routino/visualiser.js: Fix the Javascript so that it works with OpenLayers version 2.11 again (bug reported by Dirk Eversmann). 2013-04-13 [r1269-1270] Andrew M. Bishop <amb> * doc/html/readme.html, doc/README.txt: Remove some differences between the HTML and text versions of the documents. * doc/INSTALL.txt, doc/html/installation.html: Fix some errors in the installation documents and improve the description of pre-requisites and compilation (prompted by bug report from Dirk Eversmann). 2013-03-24 [r1268] Andrew M. Bishop <amb> * src/planetsplitter.c: Prune the straight highways after removing the isolated sections and short segments rather than before. 2013-03-19 [r1267] Andrew M. Bishop <amb> * doc/html/output.html, doc/html/tagging.html, doc/html/installation.html, doc/html/limits.html, doc/README.txt, doc/html/usage.html, doc/html/algorithm.html, doc/html/configuration.html, doc/html/index.html, doc/html/data.html, doc/html/readme.html, web/www/routino/index.html: Remove e-mail addresses and replace with links to website. 2013-03-03 [r1266] Andrew M. Bishop <amb> * src/prunex.c: Improve the pruning of straight highways (more likely to remove larger sections). 2013-03-03 [r1265] Andrew M. Bishop <amb> * src/test, src/prunex.c, src/test/prune-straight.sh (added), src/test/prune-straight.osm (added): Add a test case for pruning straight segments. Found an error case related to loops and fixed it. 2013-03-02 [r1264] Andrew M. Bishop <amb> * src/test/prune-short.sh (added), src/test, src/test/prune-short.osm (added), src/prunex.c, src/test/only-split.sh: Add a test case for pruning short segments. Found some disallowed cases that had not been detected before and fixed them. 2013-03-02 [r1263] Andrew M. Bishop <amb> * doc/html/tagging.html, xml/routino-tagging.xml, doc/TAGGING.txt, src/osmparser.c, src/filedumper.c: Recognise mini-roundabouts tagged as junction=roundabout (as well as highway=mini_roundabout). Pass them through the parser as roundabout=yes. Output them from the filedumper as junction=roundabout. Update the documentation for mini-roundabouts. 2013-03-02 [r1262] Andrew M. Bishop <amb> * src/test/oneway-loop.osm, src/test/node-restrictions.osm: Remove the 'update' element from the osm tag. 2013-02-28 [r1261] Andrew M. Bishop <amb> * src/relationsx.c: Rationalise some of the turn relation error messages. 2013-02-26 [r1260] Andrew M. Bishop <amb> * web/www/routino/router.js, web/www/routino/visualiser.js: Clarify comment. 2013-02-18 [r1259] Andrew M. Bishop <amb> * xml/routino-tagging.xml: Add some more tags to not be reported as errors (barrier, highway), add some more aliases for highway types, bridges and tunnels are enabled for anything except 'no'. 2013-02-16 [r1257-1258] Andrew M. Bishop <amb> * web/www/routino/index.html: Move the meta tag for charset declaration to the top of the head, before the copyright notice, within the first 1024 bytes. * doc/html/readme.html, web/www/routino/router.html.de, web/www/routino/visualiser.html.en, web/www/routino/router.html.nl, doc/html/output.html, doc/html/tagging.html, doc/html/installation.html, doc/html/limits.html, doc/html/usage.html, doc/html/algorithm.html, doc/html/configuration.html, doc/html/index.html, web/www/routino/router.html.en, doc/html/data.html: Move the meta tag for charset declaration to the top of the head, before the copyright notice, within the first 1024 bytes. 2013-02-09 [r1256] Andrew M. Bishop <amb> * xml/routino-tagging.xml: Stop two contradictory errors messages about 'access = foot' etc. 2013-02-09 Andrew M. Bishop <amb> Version 2.5 released 2013-02-09 [r1255] Andrew M. Bishop <amb> * doc/html/usage.html, doc/USAGE.txt: Fix HTML validation error. 2013-02-09 [r1254] Andrew M. Bishop <amb> * doc/html/readme.html, doc/NEWS.txt, doc/README.txt, FILES: Update documentation for version 2.5. 2013-02-09 [r1253] Andrew M. Bishop <amb> * doc/html/tagging.html, doc/TAGGING.txt: Update documentation for the new tagging transformations. 2013-02-09 [r1252] Andrew M. Bishop <amb> * xml/routino-tagging.xml: Add some more highway tagging transformations (motorroad, sidewalk, footway, cycleway), remove some rare bicycle specific ones and add some access tag values. 2013-02-09 [r1251] Andrew M. Bishop <amb> * src/osmo5mparse.c: Rename the local functions that perform the integer conversions (from pbf_* to o5m_*). 2013-02-08 [r1250] Andrew M. Bishop <amb> * web/www/routino/documentation, doc/html/limits.html (added), doc/html/index.html, doc/LIMITS.txt (added): Add documentation about the numerical limits (OSM identifiers and database size). 2013-02-03 [r1249] Andrew M. Bishop <amb> * src/prunex.c: Some trivial changes, same functionality. 2013-01-24 [r1248] Andrew M. Bishop <amb> * web/www/routino/visualiser.js, src/visualiser.h, src/filedumper.c, doc/USAGE.txt, web/www/routino/visualiser.cgi, web/www/routino/visualiser.html.en, src/visualiser.c, doc/html/usage.html: Add the ability for the visualiser to display highways that have a particular property. 2013-01-24 [r1247] Andrew M. Bishop <amb> * doc/html/tagging.html, xml/routino-tagging.xml, doc/TAGGING.txt, src/osmparser.c: Change the "lanes=..." tag processing because it counts lanes in both directions. A normal road may be tagged as having two lanes (one in each direction) but the multilane property is intended to allow prioritisation of roads where traffic can use multiple lanes in each direction. 2013-01-21 [r1246] Andrew M. Bishop <amb> * src/tagging.c, src/osmparser.c: Remove unnecessary word from logerror messages. 2013-01-21 [r1245] Andrew M. Bishop <amb> * xml/routino-translations.xml: Updated German translations from Alex Treiber. 2013-01-20 [r1244] Andrew M. Bishop <amb> * xml/routino-tagging.xml: Change the comments to clarify what the way access tag rules are for. Change slightly the logged message. Add new tagging rules to transform (for example) access=foot to foot=yes, access=no. 2013-01-20 [r1243] Andrew M. Bishop <amb> * xml/routino-tagging.xml, src/types.c, xml/routino-profiles.xml, doc/README.txt, doc/html/usage.html, src/types.h, doc/html/configuration.html, src/osmparser.c, xml/scripts/ride.pl, web/www/routino/router.html.en, doc/USAGE.txt, web/www/routino/visualiser.html.en, doc/CONFIGURATION.txt, web/www/routino/router.html.nl, doc/html/tagging.html, xml/scripts/walk.pl, src/relationsx.c, doc/TAGGING.txt, doc/html/readme.html, web/www/routino/router.html.de: Replace 'motorbike' with 'motorcycle' everywhere. 2013-01-20 [r1242] Andrew M. Bishop <amb> * doc/CONFIGURATION.txt, xml/routino-tagging.xsd, xml/routino-tagging.xml, src/tagging.h, doc/html/configuration.html, src/tagging.c: Change the <logerror> element of the configuration file to lookup the tag value if not specified and add a custom error message. Rework the access tag checking to use the new logcheck. 2013-01-19 [r1241] Andrew M. Bishop <amb> * xml/routino-tagging.xml: Ignore some more highway types ('no' and 'disused'). 2013-01-19 [r1240] Andrew M. Bishop <amb> * web/www/routino/visualiser.html.en: Fix link to documentation directory. 2013-01-19 [r1239] Andrew M. Bishop <amb> * web/www/routino/router.html.de, web/www/routino/visualiser.html.en, web/www/routino/router.html.nl, web/www/routino/router.js, web/www/routino/mapprops.js, web/www/routino/visualiser.js, web/www/routino/router.html.en: Added MapQuest as an optional map layer, added layer specific attributions to mapprops.js. 2013-01-15 [r1238] Andrew M. Bishop <amb> * web/bin/summarise-log.pl: Fix stupid typo. 2013-01-12 [r1237] Andrew M. Bishop <amb> * web/bin/summarise-log.pl: Sort the listed nodes, ways or relations by ID. 2013-01-09 [r1236] Andrew M. Bishop <amb> * src/osmparser.c: Reset the to/via/from indexes before parsing each relation. 2012-12-29 [r1235] Andrew M. Bishop <amb> * src/xmlparse.h, src/osmpbfparse.c, src/osmo5mparse.c, src/osmxmlparse.c, src/xmlparse.c, src/filedumper.c: Replace the remaining 'long long' and 'unsigned long long' types with uint64_t. 2012-12-29 [r1234] Andrew M. Bishop <amb> * src/osmo5mparse.c, src/osmxmlparse.c, src/tagmodifier.c, src/osmparser.c, src/osmparser.h, src/tagging.c, src/osmpbfparse.c, src/tagging.h: Re-factor parsing code to remove duplicated parts from three parsers (osmo5mparse.c, osmpbfparse.c and osmxmlparse.c) into a common place (osmparser.c), also removes lots of global variables. Change the node, way and relation count to uint64_t instead of index_t to avoid wrap-around (although it would have been a cosmetic problem only), also removes dependency on types.h. Make the node, way and relation counters be 'int64_t' instead of 'long long' in the XML parsers for consistency with the non-XML parsers. 2012-12-28 [r1233] Andrew M. Bishop <amb> * src/osmparser.c: Log errors for areas that are oneway. 2012-12-28 [r1232] Andrew M. Bishop <amb> * src/osmparser.c: Log errors for areas that are not closed. 2012-12-27 [r1231] Andrew M. Bishop <amb> * src/segmentsx.c, src/osmparser.c, web/bin/summarise-log.pl: Don't append segments if they are duplicates within a way or have duplicated nodes. Log errors for middle nodes that repeat within a way (can be non-trivial unintentional loops). 2012-12-26 [r1230] Andrew M. Bishop <amb> * src/osmpbfparse.c: Some small changes for similarity with the O5M/O5C parser. 2012-12-26 [r1229] Andrew M. Bishop <amb> * doc/ALGORITHM.txt, doc/html/algorithm.html: Remove the "practicalities" section because it is out of date and not very relevant. 2012-12-26 [r1228] Andrew M. Bishop <amb> * src/relationsx.c, src/segmentsx.c: Make the log error messages more useful when there are missing nodes or ways. 2012-12-24 [r1227] Andrew M. Bishop <amb> * src/osmparser.h, doc/html/usage.html, src/osmo5mparse.c (added), src/planetsplitter.c, src/osmparser.c, src/Makefile, doc/USAGE.txt: Added parsing of O5M/O5C format (a binary format but otherwise very close to OSM/OSC). 2012-12-24 [r1226] Andrew M. Bishop <amb> * src/planetsplitter.c, src/osmparser.c, src/osmparser.h, src/osmpbfparse.c: The PBF format does not support change files (the 'visible' part of the info message is only for historical data and not for changes). 2012-12-24 [r1225] Andrew M. Bishop <amb> * src/osmpbfparse.c: Fix memory allocation error. 2012-12-22 [r1224] Andrew M. Bishop <amb> * doc/html/usage.html, src/planetsplitter.c, src/tagmodifier.c, doc/USAGE.txt: Data can no longer be read from stdin for planetsplitter or tagmodifier. 2012-12-21 [r1223] Andrew M. Bishop <amb> * web/data/create.sh: Correct the URLs to use to download data. 2012-12-21 [r1221] Andrew M. Bishop <amb> * doc/html/usage.html, src/osmxmlparse.c, src/planetsplitter.c, src/osmparser.c, src/Makefile, doc/USAGE.txt, src/osmparser.h, src/osmpbfparse.c (added): Add a parser for OSM PBF format. Separate the XML parser from the data processing in osmparser.c. Update planetsplitter and documentation to use new format. 2012-12-19 [r1219-1220] Andrew M. Bishop <amb> * src/xmlparse.c: Use 'unsigned char' instead of 'char' for buffer. Renumber the LEX states to remove hole. * src/uncompress.c: Trivial change to not set a state variable where not needed. 2012-12-19 [r1218] Andrew M. Bishop <amb> * src/osmxmlparse.c (added): Copying osmparser.c to create osmxmlparse.c for the XML callback functions and shared variables. 2012-12-17 [r1217] Andrew M. Bishop <amb> * src/optimiser.c: Refactor to remove duplicated code in each branch of if statement (in each optimiser loop). 2012-12-17 [r1216] Andrew M. Bishop <amb> * doc/NEWS.txt, doc/README.txt, FILES, doc/html/readme.html: Reintegrate the changes from 2.4.1 branch back into trunk. 2012-12-15 [r1209] Andrew M. Bishop <amb> * xml/routino-tagging.xml: Fix some errors that appeared in the tagging file after adding nesting. 2012-12-15 [r1206-1207] Andrew M. Bishop <amb> * xml/routino-tagging.xml: Change the tagging rules to use the nested <if> rules. * doc/html/configuration.html, src/tagging.c, doc/CONFIGURATION.txt, xml/routino-tagging.xsd: Change the tagging rules to have an <ifnot ...> rule which can also be nested. 2012-12-15 [r1205] Andrew M. Bishop <amb> * src/translations.c, xml/routino-translations.xsd: Change one entry in the translations XSD file that used a different case from the other defined types (not consistent with other XSD files but self-consistent). 2012-12-15 [r1204] Andrew M. Bishop <amb> * src/xml/xsd-to-xmlparser.c, src/osmparser.c, src/tagging.c, src/translations.c, src/profiles.c: Change the xsd-to-xmlparser functions to output the source code in the same order as the XSD file and do not attempt to sort them into reverse order of reference. 2012-12-15 [r1203] Andrew M. Bishop <amb> * doc/html/configuration.html, src/tagging.c, doc/CONFIGURATION.txt, xml/routino-tagging.xml: Change the tagging rules to use the nested <if> rules. 2012-12-15 [r1200-1202] Andrew M. Bishop <amb> * src/planetsplitter.c: Change the order of the command line option parsing to match the program usage output. * doc/USAGE.txt: Add the --logtime and --errorlog options to tagmodifier. * doc/html/usage.html, src/tagmodifier.c: Add the --logtime and --errorlog options to tagmodifier. 2012-12-15 [r1199] Andrew M. Bishop <amb> * xml/routino-tagging.xsd, src/tagging.h, src/tagmodifier.c, src/osmparser.c, src/tagging.c: Allow the tagging rule syntax to contain nested <if ...> statements. 2012-12-14 [r1197] Andrew M. Bishop <amb> * doc/USAGE.txt, doc/html/usage.html, src/planetsplitter.c, src/tagmodifier.c: Update the usage messages and documentation for bzip2/gzip uncompression. 2012-12-14 [r1196] Andrew M. Bishop <amb> * src/Makefile, src/uncompress.c, src/uncompress.h, src/planetsplitter.c, src/tagmodifier.c: Add the ability to read gzip compressed files when specified by name. 2012-12-13 [r1194-1195] Andrew M. Bishop <amb> * src/xmlparse.c: Handle the output of the uncompressor where reading may return only a partial buffer. Makes it more robust generally against short reads. * src/Makefile, src/uncompress.c (added), src/uncompress.h (added), src/planetsplitter.c, src/tagmodifier.c: Add the ability to read bzip2 compressed files when specified by name. 2012-12-12 [r1192] Andrew M. Bishop <amb> * src/xml/xsd-to-xmlparser.c, src/planetsplitter.c: Use STDIN_FILENO instead of 0 for the stdin file descriptor. 2012-12-11 [r1190] Andrew M. Bishop <amb> * src/xmlparse.c: Reorder if/then/else statements so that most common ones come first (using profiling when parsing GB OSM file). 2012-12-11 [r1189] Andrew M. Bishop <amb> * src/xmlparse.c: Most xml attribute values are ASCII so optimise for that case. 2012-12-10 [r1188] Andrew M. Bishop <amb> * src/Makefile: Re-enable the optimisation option. 2012-12-10 [r1185-1187] Andrew M. Bishop <amb> * src: Change svn ignored files (don't ignore xmlparse.c now). * src/xml/xsd-to-xmlparser.c, src/planetsplitter.c, src/tagmodifier.c, src/osmparser.c, src/xml/Makefile, src/osmparser.h, src/tagging.c, src/xmlparse.h, src/translations.c, src/profiles.c: New XML parser doesn't use stdio buffered file access but lower level read functions. * src/xmlparse.l (removed), src/xmlparse.c (added), src/Makefile: Remove flex based XML parser and replace with a parser created by implementing the same lex rules by hand. Operates faster because tag attributes do not need memory allocated or copying from file buffer and there are no yylex() function calls/returns. 2012-12-17 Andrew M. Bishop <amb> Version 2.4.1 released 2012-12-17 [r1214] Andrew M. Bishop <amb> * doc/html/readme.html, doc/NEWS.txt, doc/README.txt, FILES: Update for version 2.4.1. 2012-12-17 [r1213] Andrew M. Bishop <amb> * src/optimiser.c, src/waysx.c, src/segmentsx.c, src/nodesx.c, src/router.c, src/prunex.c, src/logging.c, src/relationsx.c: Merge revisions 1191, 1193, 1198, 1208 and 1210 from trunk into 2.4.1 branch. 2012-12-17 [r1210] Andrew M. Bishop <amb> * src/optimiser.c: Fix the incorrect finish_score variable that was set to infinite distance and not infinite score (infinte distance << infinite score so search was terminating early). 2012-12-15 [r1208] Andrew M. Bishop <amb> * src/nodesx.c, src/prunex.c, src/relationsx.c, src/waysx.c, src/segmentsx.c: Stop planetsplitter crashing out in unusual ways if there is no data. 2012-12-14 [r1198] Andrew M. Bishop <amb> * src/waysx.c, src/nodesx.c: Don't crash in binary search if no nodes/ways. 2012-12-13 [r1193] Andrew M. Bishop <amb> * src/logging.c: Fix bug with printing messages if not to stdout. 2012-12-12 [r1191] Andrew M. Bishop <amb> * src/router.c: Fix error when searching for default profiles.xml file. 2012-12-08 Andrew M. Bishop <amb> Version 2.4 released 2012-12-08 [r1182-1183] Andrew M. Bishop <amb> * doc/NEWS.txt, doc/README.txt, FILES, doc/html/readme.html: Update for version 2.4. * doc/TAGGING.txt: Update with the tagging rule changes in this version. 2012-12-08 [r1181] Andrew M. Bishop <amb> * src/xmlparse.l, src/xml/test/good.xml, src/xml/test/bad-cdata-start.xml (removed), src/xml/test/bad-text-outside.xml (added): Simplify the XML parser by not handling the CDATA and DOCTYPE sections and also raise an explicit error for text outside of tags. Modify test cases for these changes. 2012-12-06 [r1180] Andrew M. Bishop <amb> * src/xmlparse.l: Some further small changes to pull out bigger groups of characters (only marginally faster though). 2012-12-05 [r1179] Andrew M. Bishop <amb> * src/prunex.c: Minor theoretical improvements to pruning (slim mode is still very slow). 2012-12-05 [r1178] Andrew M. Bishop <amb> * src/xmlparse.l: Change rules to remove all states that require backing up (only marginally faster though). 2012-12-05 [r1176-1177] Andrew M. Bishop <amb> * doc/html/tagging.html: Update with the tagging rule changes in this version. * xml/routino-tagging.xml: Small change to the tag processing for nodes for easier future expansion. 2012-12-01 [r1175] Andrew M. Bishop <amb> * src/tagging.c: Fix memory leak from making incorrect assumption when freeing tagging rule. 2012-12-01 [r1174] Andrew M. Bishop <amb> * src/superx.c, src/translations.h, src/visualiser.c, src/profiles.h, src/types.h, src/osmparser.c, src/filedumper.c, src/output.c, src/router.c, src/translations.c, src/profiles.c, src/types.c: Rename the Way_* enumerated values to Highway_*, add a new Highway_None type, change the HighwayType() function to return Highway_None instead of Highway_Count if no match found - all changes for consistency with similar types and functions. 2012-11-27 [r1173] Andrew M. Bishop <amb> * src/osmparser.c, web/bin/summarise-log.pl, src/segmentsx.c: Log an error about duplicated segments within a way while parsing the OSM instead of later (will have been removed by de-duplication code before tested later in most cases). 2012-11-27 [r1172] Andrew M. Bishop <amb> * web/bin/summarise-log.pl: Make the script still work when no command line argument is used. 2012-11-27 [r1171] Andrew M. Bishop <amb> * src/relationsx.c, src/planetsplitter.c, src/waysx.c, src/segmentsx.c, src/nodesx.c: Don't log an error for duplicated nodes, ways or relations because it can only occur when applying changes or if using multiple geographically overlapping files and neither is a data error. 2012-11-21 [r1170] Andrew M. Bishop <amb> * xml/routino-tagging.xml: Add some more tag checking, accept more tags. 2012-11-21 [r1169] Andrew M. Bishop <amb> * src/types.h, src/segmentsx.c: Finally fix the segment area handling - segments that are areas are discarded in preference to those that are not (as it was between r914 and r1136) and segments that are areas don't have the wrong distance (as they did between r914 and r1136). Revision r1137 correctly changed to use a flag and fixed the distance bug but then didn't sort using the new flag. Revision r1153 started sorting using the segment flags but the area was not the most significant bit so they were not sorted last. Revision r1164 correctly cleared the area flag when no longer needed but didn't fix the rest. Revision r1168 reverted r1164 so needed to be re-applied. 2012-11-21 [r1168] Andrew M. Bishop <amb> * src/prunex.c, src/segmentsx.h, src/filedumperx.c, src/segments.c, src/superx.c, src/fakes.c, src/types.h, src/segments.h, src/optimiser.c, src/osmparser.c, src/filedumper.c, src/segmentsx.c, src/fakes.h, src/output.c: Revert r1164 - some super-segments are longer than 65535 metres even if no individual segment is. 2012-11-20 [r1167] Andrew M. Bishop <amb> * doc/html/usage.html, src/relationsx.c, src/planetsplitter.c, src/waysx.c, src/relationsx.h, src/segmentsx.c, doc/USAGE.txt, src/nodesx.c, src/waysx.h, src/segmentsx.h, src/nodesx.h: Rename the '--preserve' command line option to '--keep' for simplicity. 2012-11-20 [r1166] Andrew M. Bishop <amb> * src/segmentsx.c, src/nodesx.c, src/prunex.c, src/results.c, src/sorting.c, src/logging.c, src/superx.c, src/files.h, src/relationsx.c, src/tagmodifier.c, src/logging.h, src/optimiser.c, src/osmparser.c, src/waysx.c, src/Makefile: Replace all assert statements with a custom error message that explains the cause and suggests a solution. 2012-11-20 [r1165] Andrew M. Bishop <amb> * src/types.h, src/osmparser.c, src/nodes.h, src/nodesx.c, src/nodesx.h: Use a specific type for the node flags instead of a generic uint16_t. 2012-11-20 [r1164] Andrew M. Bishop <amb> * src/filedumperx.c, src/segments.c, src/superx.c, src/fakes.c, src/types.h, src/segments.h, src/optimiser.c, src/osmparser.c, src/filedumper.c, src/segmentsx.c, src/fakes.h, src/output.c, src/prunex.c, src/segmentsx.h: Replace the 32-bit combined distance and flags in the segment with 16 bits for each. 2012-11-20 [r1163] Andrew M. Bishop <amb> * src/relationsx.c, src/relationsx.h, src/typesx.h, src/filedumperx.c: Tidy up all of the recent code changes - Rename TurnRestrictRelX structure to TurnRelX. 2012-11-20 [r1162] Andrew M. Bishop <amb> * src/files.c: Tidy up all of the recent code changes - Fix comment. 2012-11-20 [r1161] Andrew M. Bishop <amb> * src/nodesx.c, src/waysx.h, src/segmentsx.h, doc/DATALIFE.txt, src/nodesx.h, src/superx.c, src/relationsx.c, src/osmparser.c, src/waysx.c, src/relationsx.h, src/segmentsx.c: Tidy up all of the recent code changes - change the name of a few of the functions. 2012-11-20 [r1160] Andrew M. Bishop <amb> * src/waysx.c, src/relationsx.h, src/segmentsx.c, src/nodesx.c, src/waysx.h, src/segmentsx.h, src/nodesx.h: Tidy up all of the recent code changes - change the order of the functions within the files to a more sensible and consitent order. 2012-11-19 [r1159] Andrew M. Bishop <amb> * src/osmparser.c: Unconditionally mark ways as deleted if they have been modified to handle the case when applying more than one change file if a way is created by the first of the change files and modified by the second it will not be in the index. 2012-11-19 [r1158] Andrew M. Bishop <amb> * src/waysx.c, src/waysx.h, src/planetsplitter.c: Do not create the way indexes when loading the parsed ways to apply changes (reverses r1145). 2012-11-19 [r1157] Andrew M. Bishop <amb> * doc/html/usage.html, src/planetsplitter.c, doc/USAGE.txt: Do not require that --preserve must be used with --parse-only before changes can be applied (reverses r1151 for the change to functionality but preserves the changes to the functions that enable it). 2012-11-19 [r1156] Andrew M. Bishop <amb> * src/filedumperx.c: Fix bug with dumping ways. 2012-11-19 [r1155] Andrew M. Bishop <amb> * src/segmentsx.c: De-duplicate segments when sorting only if they have the same nodes, way and distance - i.e. the same data imported twice. 2012-11-18 [r1154] Andrew M. Bishop <amb> * src/osmparser.c: When marking modified nodes as deleted don't accidentally re-include them as new ways with the deleted flag set. 2012-11-18 [r1152-1153] Andrew M. Bishop <amb> * src/segmentsx.c: When sorting segments use the distance flags as the tie-breaker so that duplicated segments with different flags get sorted into the same order when applying changes as when not applying changes. * src/osmparser.c: Mark modified relations as deleted before storing the modification to handle the case where the modification causes it to be invalid and not stored therefore leaving the old version. 2012-11-18 [r1151] Andrew M. Bishop <amb> * src/segmentsx.h, src/nodesx.h, src/superx.c, doc/html/usage.html, src/relationsx.c, src/planetsplitter.c, src/waysx.c, src/relationsx.h, src/segmentsx.c, doc/USAGE.txt, src/nodesx.c, src/waysx.h: Using --parse-only and --preserve must sort the data so that it is ready to apply the changes. 2012-11-17 [r1149-1150] Andrew M. Bishop <amb> * src/filedumper.c: Some small changes to match the new filedumperx program. * src, doc/USAGE.txt, src/filedumperx.c (added), doc/html/usage.html, src/Makefile, web/bin: Add a new program to dump the contents of the intermediate files that are generated by using --preserve or --changes. 2012-11-17 [r1147-1148] Andrew M. Bishop <amb> * src/waysx.c: Replace a hard-coded constant with the #defined value it should have been. * src/relationsx.c: Clear the route relation before adding data to it so that there are no unused bytes in the structure to get written to disk (avoid byte-level differences when applying changes). 2012-11-17 [r1146] Andrew M. Bishop <amb> * src/nodesx.c, src/relationsx.c, src/planetsplitter.c, src/waysx.c, src/segmentsx.c: Suppress some error log messages when applying changes (false positive duplicate detection due to modification of existing items). 2012-11-17 [r1144-1145] Andrew M. Bishop <amb> * src/planetsplitter.c, src/osmparser.c, src/waysx.c, src/waysx.h: Fix applying changes for ways (highways that have been modified to be non-highways were not added to the database so the original remains). * src/typesx.h, src/types.h: Change the type-casting of some constants. 2012-11-16 [r1140-1143] Andrew M. Bishop <amb> * src/xml: Ignore the automatically generated executables from the new XML Schema. * xml/routino-osm.xsd, xml/osm.xsd: Changes to comments to make them more like the OSC files. * xml/routino-osc.xsd (added), xml/osc.xsd (added): XML Schema for OSC change files (.osc files) used to create the XML parser. * doc/html/usage.html, src/relationsx.c, src/types.h, src/planetsplitter.c, src/osmparser.c, src/waysx.c, src/segmentsx.c, doc/USAGE.txt, src/nodesx.c, src/osmparser.h, src/segmentsx.h, doc/DATALIFE.txt: Code to allow adding OSC change files (.osc files) to an existing set of parsed (and preserved) data. 2012-11-15 [r1139] Andrew M. Bishop <amb> * src/nodesx.h, src/superx.c, src/relationsx.c, src/planetsplitter.c, src/waysx.c, src/relationsx.h, src/segmentsx.c, src/nodesx.c, src/waysx.h, src/segmentsx.h: Fixed the --preserve option. 2012-11-12 [r1138] Andrew M. Bishop <amb> * src/relationsx.c: Fix mis-use of NO_WAY/NO_WAY_ID and NO_RELATION/NO_RELATION_ID constants in route relation handling. 2012-11-11 [r1137] Andrew M. Bishop <amb> * src/types.h, src/osmparser.c, src/segmentsx.c: Mark those segments that come from ways which are areas with an explicit flag rather than an implicit one (also fixes a bug). 2012-11-10 [r1136] Andrew M. Bishop <amb> * src/nodesx.c, src/waysx.h, src/segmentsx.h, src/nodesx.h, doc/html/usage.html, src/relationsx.c, src/planetsplitter.c, src/waysx.c, src/relationsx.h, src/segmentsx.c, doc/USAGE.txt: Added a --preserve option which keeps the raw data files after parsing, sorting and de-duplication. 2012-11-10 [r1134-1135] Andrew M. Bishop <amb> * doc/DATALIFE.txt, src/waysx.c: Don't index the ways in the first sorting, but wait until after de-duplicating. * src/relationsx.c: Sort the route relations and remove duplicates. 2012-11-10 [r1133] Andrew M. Bishop <amb> * src/planetsplitter.c, src/segmentsx.c, src/segmentsx.h, doc/DATALIFE.txt: The MergeSuperSegments function creates the output file in the sorted order already, there is no need to re-sort it. 2012-11-10 [r1132] Andrew M. Bishop <amb> * src/segmentsx.c, src/segmentsx.h, doc/DATALIFE.txt, src/planetsplitter.c: De-duplicate the super-segments as a post-processing function after the sort so both operations are combined in a single function. 2012-11-10 [r1131] Andrew M. Bishop <amb> * src/segmentsx.h, src/planetsplitter.c, src/segmentsx.c: De-duplicate the raw segments before any other processing (to match the node, way and turn relation processing). 2012-11-10 [r1129-1130] Andrew M. Bishop <amb> * src/planetsplitter.c: Separate the de-duplication of the ways from the extracting of the names. Use the modified functions for creating lists of nodes,segments,ways and relations from r1123. * src/waysx.c, src/waysx.h, doc/DATALIFE.txt: Separate the de-duplication of the ways from the extracting of the names. 2012-11-08 [r1128] Andrew M. Bishop <amb> * web/bin/summarise-log.pl: Allow generation of an HTML version of the log file summary. 2012-11-08 [r1127] Andrew M. Bishop <amb> * src/osmparser.c: Add two extra parsing rules for feet and inches. 2012-11-04 [r1126] Andrew M. Bishop <amb> * src/tagging.c: Clarify that errors logged when examining tags mean that tag will be ignored. 2012-11-04 [r1125] Andrew M. Bishop <amb> * src/osmparser.c: Log an error for ways with only 1 node and for relations with no nodes, ways or relations. 2012-11-03 [r1124] Andrew M. Bishop <amb> * src/prunex.c: Append the new ways directly to the end of the existing ways rather than using a new file. 2012-11-03 [r1123] Andrew M. Bishop <amb> * src/nodesx.h, src/superx.c, src/relationsx.c, src/waysx.c, src/relationsx.h, src/segmentsx.c, src/nodesx.c, src/waysx.h, src/segmentsx.h: Don't open the input file for appending if there is no intention to write anything to it. 2012-11-03 [r1122] Andrew M. Bishop <amb> * src/superx.c, src/files.h, src/relationsx.c, src/segmentsx.c, src/prunex.c, src/files.c: Change the UnmapFile() function to take a pointer to the data instead of the filename (like the CloseFile() function takes the file descriptor). 2012-11-02 [r1121] Andrew M. Bishop <amb> * src/prunex.c, src/segmentsx.h: Fix a bug which gave different results for slim mode and normal mode when pruning short segments. 2012-11-01 [r1120] Andrew M. Bishop <amb> * src/planetsplitter.c, src/waysx.c, src/relationsx.h, src/segmentsx.c, doc/USAGE.txt, src/nodesx.c, src/waysx.h, src/prunex.c, src/segmentsx.h, src/nodesx.h, src/superx.c, doc/html/usage.html, src/relationsx.c: Introduce a new'--append' option for appending data from a file to the currently parsed data. Rename the intermediate file used for storing data to be appended to. Add a function to call after appending to a file which closes the file and renames it to a temporary filename which is used for the remaining processing. 2012-11-01 [r1119] Andrew M. Bishop <amb> * src/files.c, src/files.h: Add a function to rename a file. 2012-10-31 [r1118] Andrew M. Bishop <amb> * src/relationsx.c, src/sorting.h, src/waysx.c, src/segmentsx.c, src/nodesx.c: Add the option for the sorting function to preserve the input order of equivalent items on the output. Use this feature in sorting so that slim mode and normal mode give the same results. 2012-10-24 [r1116-1117] Andrew M. Bishop <amb> * doc/html/usage.html, doc/html/algorithm.html, src/planetsplitter.c, doc/USAGE.txt, doc/ALGORITHM.txt, src/prunex.c: Perform the pruning for isolated regions in terms of each transport type individually. * doc/DATALIFE.txt: Use the index provided by the pre-sort function rather than the way's internal id when pruning/compacting. 2012-10-24 [r1114-1115] Andrew M. Bishop <amb> * src/segmentsx.c: Remove a debugging print statement. * src/waysx.c: Use the index provided by the pre-sort function rather than the way's internal id when pruning/compacting. 2012-10-22 [r1112-1113] Andrew M. Bishop <amb> * src/waysx.c: Use the new pre-sort function to allow CompactWays() to delete the unused segments before sorting them. * src/segmentsx.c, src/sorting.c, src/relationsx.c: Fix bug with index parameter in new pre-sort function and change comments to clarify. 2012-10-22 [r1110-1111] Andrew M. Bishop <amb> * src/segmentsx.c: Use the new pre-sort function to allow RemovePrunedSegments() to delete the pruned segments before sorting them. * src/segmentsx.c, src/relationsx.c: Change the message after sorting geographically to be consistent with others. 2012-10-21 [r1109] Andrew M. Bishop <amb> * src/planetsplitter.c, src/nodesx.c, doc/DATALIFE.txt, src/nodesx.h: Move the UpdateNodes() work into the callback for SortNodeListGeographically() and use firstnode when saving the nodes. 2012-10-21 [r1108] Andrew M. Bishop <amb> * src/planetsplitter.c, src/relationsx.h, doc/DATALIFE.txt, src/relationsx.c: Use the new pre-sort function to allow UpdateTurnRelations() and SortTurnRelationList() to be combined into a single SortTurnRelationListGeographically() function that only reads and writes the data once instead of twice. 2012-10-21 [r1107] Andrew M. Bishop <amb> * src/segmentsx.h, doc/DATALIFE.txt, src/planetsplitter.c, src/segmentsx.c: Use the new pre-sort function to allow UpdateSegments() and SortSegmentList() to be combined into a single SortSegmentListGeographically() function that only reads and writes the data once instead of twice. 2012-10-21 [r1106] Andrew M. Bishop <amb> * src/nodesx.c, src/sorting.c, src/relationsx.c, src/sorting.h, src/waysx.c, src/segmentsx.c: Change the sorting functions to have a pre-sort and post-sort selection function instead of just a post-selection one (this will allow deletion of some items before sorting instead of after sorting in some cases). 2012-10-21 [r1103-1105] Andrew M. Bishop <amb> * doc/DATALIFE.txt: Added new columns showing when the data files are mapped into memory. * src/waysx.c: Delete the onumber parameter from the Ways file header. Don't map the ways file into memory when writing the ways. * src/ways.h, src/filedumper.c: Delete the onumber parameter from the Ways file header. 2012-10-21 [r1102] Andrew M. Bishop <amb> * src/segmentsx.c: Reallocate the firstnode array when indexing segments because there may be fewer nodes now. 2012-10-21 [r1101] Andrew M. Bishop <amb> * src/nodesx.c: Remove some unused parts of the SortNodeListGeographically() function. 2012-10-20 [r1100] Andrew M. Bishop <amb> * doc/DATALIFE.txt, src/relationsx.c, src/planetsplitter.c, src/waysx.c, src/segmentsx.c, src/waysx.h, src/segmentsx.h: Move the compacting of the ways back to the top, delete the unused ways at this point and also call the function again after pruning segments. 2012-10-20 [r1099] Andrew M. Bishop <amb> * src/nodesx.c: Mark pruned nodes in the node index. 2012-10-20 [r1098] Andrew M. Bishop <amb> * src/relationsx.c, src/planetsplitter.c, src/relationsx.h, src/segmentsx.c, src/nodesx.c, src/prunex.c, doc/DATALIFE.txt, src/nodesx.h, src/superx.c: Delete the pruned nodes before searching for super-nodes etc. 2012-10-20 [r1097] Andrew M. Bishop <amb> * src/nodesx.c: Move the calculation of lat/long extents to the UpdateNodes() function. 2012-10-20 [r1096] Andrew M. Bishop <amb> * doc/DATALIFE.txt: Add missing data (nodesx->super). 2012-10-20 [r1095] Andrew M. Bishop <amb> * doc/DATALIFE.txt (added): A description of the data lifetime in the planetsplitter program (as an aid to understanding it better and not messing it up when editing it). 2012-10-19 [r1094] Andrew M. Bishop <amb> * src/waysx.c: Remove one filesort and one read through the ways file when compacting. 2012-10-19 [r1093] Andrew M. Bishop <amb> * src/waysx.c, src/segmentsx.c, src/waysx.h: Change to an external index for the compacted ways. 2012-10-18 [r1092] Andrew M. Bishop <amb> * src/planetsplitter.c, src/waysx.c, src/waysx.h: When compacting ways exclude the ones that are not used by any segments. 2012-10-17 [r1091] Andrew M. Bishop <amb> * src/planetsplitter.c: Perform the Way compacting at the end (after pruning segments). 2012-10-17 [r1090] Andrew M. Bishop <amb> * src/waysx.h, src/waysx.c, src/segmentsx.c: Rename the WayX->prop entry to WayX->cid to disambiguate it. 2012-10-17 [r1089] Andrew M. Bishop <amb> * src/typesx.h, src/superx.c: Rename the BitMask functions to set or clear all bits. 2012-09-28 [r1078] Andrew M. Bishop <amb> * src/ways.c, src/segments.c, src/visualiser.c, src/nodes.c, src/ways.h, src/fakes.c, src/segments.h, src/optimiser.c, src/filedumper.c, src/fakes.h, src/output.c: Rename some variables so that pointers to nodes, segments, ways and relations use the Hungarian notation "p" suffix (only applies to the router, not planetsplitter). 2012-07-22 [r1027-1028] Andrew M. Bishop <amb> * web/www/routino/noscript.cgi (removed), web/www/routino/noscript.html (removed), web/www/routino/noscript.template.html (removed): Delete obsolete noscript web pages and CGIs. * web/www/routino/customvisualiser.cgi (removed), web/www/routino/customrouter.cgi (removed): Delete obsolete custom* CGIs. 2012-10-06 Andrew M. Bishop <amb> Version 2.3.2 released 2012-10-06 [r1083] Andrew M. Bishop <amb> * doc/NEWS.txt, doc/README.txt, FILES, doc/html/readme.html: Update for 2.3.2 release. 2012-10-02 [r1079] Andrew M. Bishop <amb> * xml/routino-tagging.xml: Make the access tag normalisation consistent between nodes an ways. 2012-09-26 [r1077] Andrew M. Bishop <amb> * src/visualiser.c, web/www/routino/visualiser.js, src/visualiser.h, src/filedumper.c, web/www/routino/visualiser.cgi, web/www/routino/visualiser.html.en: Add an option to the visualiser to display nodes that disallow selected transport type. 2012-09-25 [r1076] Andrew M. Bishop <amb> * doc/OUTPUT.txt, doc/html/output.html: Change the example output now that the copyright notice has changed, the final turn is no longer missed and minor junctions are formatted differently in the all text format. 2012-09-23 [r1075] Andrew M. Bishop <amb> * src/test/expected/turns-WP08.txt, src/test/expected/turns-WP09.txt, src/test/expected/dead-ends-WP10.txt, src/test/expected/dead-ends-WP11.txt, src/test/expected/loops-WP01.txt, src/test/expected/loops-WP02.txt, src/test/expected/loops-WP03.txt, src/test/expected/loops-WP04.txt, src/test/expected/loops-WP05.txt, src/test/expected/loops-WP06.txt, src/test/expected/loops-WP07.txt, src/test/expected/loops-WP08.txt, src/test/expected/loops-WP09.txt, src/test/expected/turns-WP10.txt, src/test/expected/turns-WP11.txt, src/test/expected/turns-WP12.txt, src/test/expected/turns-WP13.txt, src/test/expected/turns-WP14.txt, src/test/expected/turns-WP15.txt, src/test/expected/turns-WP16.txt, src/test/expected/dead-ends-WP01.txt, src/test/expected/dead-ends-WP02.txt, src/test/expected/dead-ends-WP03.txt, src/test/expected/dead-ends-WP04.txt, src/test/expected/dead-ends-WP05.txt, src/test/expected/dead-ends-WP06.txt, src/test/expected/dead-ends-WP07.txt, src/test/expected/dead-ends-WP08.txt, src/test/expected/dead-ends-WP09.txt, src/test/expected/loops-WP10.txt, src/test/expected/loops-WP11.txt, src/output.c, src/test/expected/turns-WP01.txt, src/test/expected/turns-WP02.txt, src/test/expected/turns-WP03.txt, src/test/expected/turns-WP04.txt, src/test/expected/turns-WP05.txt, src/test/expected/turns-WP06.txt, src/test/expected/turns-WP07.txt: Change the all text output format so that minor junctions (where no turn instructions are output for the HTML) are labelled differently. This also required the expected results for the tests cases to be changed. 2012-09-22 [r1074] Andrew M. Bishop <amb> * src/test/expected/super-or-not-WP02.txt, src/test/expected/turns-WP10.txt, src/test/expected/turns-WP11.txt, src/test/expected/turns-WP12.txt, src/test/expected/turns-WP13.txt, src/test/expected/turns-WP14.txt, src/test/expected/turns-WP15.txt, src/test/expected/turns-WP16.txt, src/test/expected/dead-ends-WP01.txt, src/test/expected/dead-ends-WP02.txt, src/test/expected/dead-ends-WP03.txt, src/test/expected/dead-ends-WP04.txt, src/test/expected/dead-ends-WP05.txt, src/test/expected/dead-ends-WP06.txt, src/test/expected/dead-ends-WP07.txt, src/test/expected/dead-ends-WP08.txt, src/test/expected/dead-ends-WP09.txt, src/test/expected/loops-WP10.txt, src/test/expected/loops-WP11.txt, src/output.c, src/test/expected/oneway-loop-WP01.txt, src/test/expected/node-restrictions-WP01.txt, src/test/expected/turns-WP01.txt, src/test/expected/node-restrictions-WP02.txt, src/test/expected/turns-WP02.txt, src/test/expected/node-restrictions-WP03.txt, src/test/expected/turns-WP03.txt, src/test/expected/node-restrictions-WP04.txt, src/test/expected/turns-WP04.txt, src/test/expected/node-restrictions-WP05.txt, src/test/expected/turns-WP05.txt, src/test/expected/node-restrictions-WP06.txt, src/test/expected/turns-WP06.txt, src/test/expected/node-restrictions-WP07.txt, src/test/expected/turns-WP07.txt, src/test/expected/node-restrictions-WP08.txt, src/test/expected/turns-WP08.txt, src/test/expected/turns-WP09.txt, src/test/expected/dead-ends-WP10.txt, src/test/expected/dead-ends-WP11.txt, src/test/expected/loops-WP01.txt, src/test/expected/loops-WP02.txt, src/test/expected/loops-WP03.txt, src/test/expected/loops-WP04.txt, src/test/expected/loops-WP05.txt, src/test/expected/loops-WP06.txt, src/test/expected/loops-WP07.txt, src/test/expected/loops-WP08.txt, src/test/expected/loops-WP09.txt: Fix a bug that stopped the last turn before a waypoint from being described in the HTML output if the final section of the route was a fake-segment. Update the test case expected results since the last turn was not being described properly. 2012-09-20 [r1073] Andrew M. Bishop <amb> * src/test/start-1-finish.sh, src/test/a-b-c.sh, src/test/a-b.sh: Change the scripts for the test cases to use 'diff' instead of 'cmp' so that it is possible to see the changes. 2012-09-19 [r1071-1072] Andrew M. Bishop <amb> * src/router.c: Change the error message printed if a super-route cannot be converted into a normal route. * src/superx.c: When not marking nodes that allow no traffic as super-nodes don't route through them when calculating super-segments. 2012-09-18 [r1070] Andrew M. Bishop <amb> * xml/routino-translations.xml: Change the URL for the license/copyright file (not CC specific and points to openstreetmap site). 2012-09-17 [r1069] Andrew M. Bishop <amb> * src/superx.c, src/test/node-restrictions.osm, src/types.h, src/test/expected/node-restrictions-WP04.txt: Do not mark barriers that cannot be passed by any type of transport as super-nodes. 2012-09-16 [r1068] Andrew M. Bishop <amb> * src/test/expected/node-restrictions-WP06.txt (added), src/test/node-restrictions.sh (added), src/test/expected/node-restrictions-WP07.txt (added), src/test/expected/node-restrictions-WP08.txt (added), src/test/node-restrictions.osm (added), src/optimiser.c, src/test/expected/node-restrictions-WP01.txt (added), src/test, src/test/expected/node-restrictions-WP02.txt (added), src/test/expected/node-restrictions-WP03.txt (added), src/test/expected/node-restrictions-WP04.txt (added), src/test/expected/node-restrictions-WP05.txt (added): Don't fail to route if a selected waypoint is a node that does not permit chosen traffic type. Add test cases for this change. 2012-09-13 [r1067] Andrew M. Bishop <amb> * src/test/oneway-loop.osm, src/test/invalid-turn-relations.osm, src/test/turns.osm: Make every test case loadable in JOSM. 2012-09-13 [r1066] Andrew M. Bishop <amb> * src/superx.c, src/optimiser.c: Update some comments and make a few very small optimisations. 2012-09-10 [r1065] Andrew M. Bishop <amb> * src/relationsx.c, src/waysx.c: Tidy up relation expression. 2012-09-10 [r1064] Andrew M. Bishop <amb> * src/relationsx.c: Log an error if a foot/bicycle way doesn't allow foot/bicycle transport (it already overrides the way tagging but didn't warn). 2012-09-09 [r1062-1063] Andrew M. Bishop <amb> * src/optimiser.c: Refactor the code for the previous change. * src/superx.c: Tiny optimisation to super-segment calculation. 2012-09-08 [r1058-1061] Andrew M. Bishop <amb> * src/optimiser.c: Fix the FindSuperSegment() function for routing problem. * src/test: Ignore new log files. * src/test/Makefile: Fixed a spelling mistake in the printed output. * src/test/oneway-loop.osm (added), src/test/expected/oneway-loop-WP01.txt (added), src/test/oneway-loop.sh (added): Added a new test case for a real-life pathological routing problem involving oneway streets and loops. 2012-08-12 [r1057] Andrew M. Bishop <amb> * src/visualiser.c: Fix for highway type visualiser (was missing one-way segments). 2012-08-11 Andrew M. Bishop <amb> Version 2.3.1 released 2012-08-11 [r1050] Andrew M. Bishop <amb> * web/www/routino/router.html.en, web/www/routino/router.html.de, web/www/routino/router.html.nl: Revert the change to waypoint table widths. 2012-08-11 [r1049] Andrew M. Bishop <amb> * web/www/routino/router.pl: Fix for older versions of Perl that don't accept certain anonymous list syntax. 2012-08-11 [r1048] Andrew M. Bishop <amb> * doc/README.txt, FILES, doc/html/readme.html, doc/NEWS.txt: Updated for version 2.3.1. 2012-08-11 [r1047] Andrew M. Bishop <amb> * web/www/routino/router.pl, web/www/routino/router.js, web/www/routino/router.html.nl, web/www/routino, web/www/routino/visualiser.js, web/www/routino/icons/create-icons.pl, web/www/routino/maplayout.css, src/xml/Makefile, src/Makefile, web/www/routino/router.css, web/www/routino/router.html.de, web/www/routino/icons, src/xmlparse.l, web/www/routino/router.cgi, src/test/Makefile, web/www/routino/router.html.en, src: Merge the changes from trunk version into version 2.3.1 branch. 2012-08-06 [r1044-1045] Andrew M. Bishop <amb> * src/test/Makefile, src/Makefile, src/xml/Makefile: Be more consistent about what files to clean up. * src/xmlparse.l: Allow an unlimited number of attributes per tag without crashing. 2012-08-04 [r1043] Andrew M. Bishop <amb> * web/www/routino/router.pl, web/www/routino/router.js, web/www/routino/router.cgi: Don't send back the unused lines from the router CGI, add the complete command line and execution time to the log file. 2012-08-03 [r1040] Andrew M. Bishop <amb> * web/www/routino/router.html.de, web/www/routino/router.html.nl, web/www/routino/maplayout.css, web/www/routino/router.html.en, web/www/routino/router.css: Force the font size in pixels and adjust the table width so that user browser preferences don't destroy layout (using small or large font). 2012-08-03 [r1039] Andrew M. Bishop <amb> * web/www/routino/router.js: Fix some bugs in the latest check-ins. 2012-08-03 [r1038] Andrew M. Bishop <amb> * web/www/routino/router.html.de, web/www/routino/router.html.nl, web/www/routino/router.js, web/www/routino/router.html.en: Add a button to close the loop (duplicate the first waypoint at the end). 2012-08-03 [r1037] Andrew M. Bishop <amb> * web/www/routino/router.js: Don't add the waypoint items at the start and hide them if not needed but make them invisible to start with and display them if required. 2012-08-03 [r1036] Andrew M. Bishop <amb> * web/www/routino/router.js: Improve the way that the home marker is handled (dragging etc). 2012-08-03 [r1035] Andrew M. Bishop <amb> * web/www/routino/visualiser.js, web/www/routino/router.js: Add comments to the functions that are called from the HTML file (to simplify debugging and make easier to maintain). 2012-08-02 [r1034] Andrew M. Bishop <amb> * web/www/routino/router.js: Never-used markers now show as blank, not 0,0. Clicking an unused marker centres it on the map and updates the coordinates. 2012-08-02 [r1033] Andrew M. Bishop <amb> * web/www/routino/router.js: Refactor the code that inserts, removes and moves markers around so that all properties are moved including search/coords selection, search values etc. 2012-08-02 [r1032] Andrew M. Bishop <amb> * web/www/routino/router.js: Change the formSetCoords() function so that it doesn't change the active state. 2012-07-31 [r1030-1031] Andrew M. Bishop <amb> * web/www/routino/icons: Generate the full set of icons and ignore them from SVN. * web/www/routino/icons/create-icons.pl: Create more limit markers for the visualiser. 2012-07-22 [r1029] Andrew M. Bishop <amb> * web/www/routino/icons/create-icons.pl: Create marker-XXX-(red|grey).png icons which can get requested before the Javascript removes them. 2012-07-21 Andrew M. Bishop <amb> Version 2.3 released 2012-07-21 [r1026] Andrew M. Bishop <amb> * doc/NEWS.txt, doc/README.txt, FILES, doc/html/readme.html: Update to version 2.3. 2012-07-21 [r1025] Andrew M. Bishop <amb> * src/osmparser.c: Fix problem with not logging all invalid tags. Minor optimisation to speed up tag recognition. 2012-07-17 [r1023-1024] Andrew M. Bishop <amb> * doc/html/output.html: Change the comment describing the parameters for the example route. * doc/html/usage.html, doc/USAGE.txt: Add a note that too many threads and not enough memory will slow down planetsplitter operation. 2012-07-17 [r1022] Andrew M. Bishop <amb> * src/xmlparse.l: Some small lex changes and an optimisation to remove repeated memory allocation. 2012-07-16 [r1021] Andrew M. Bishop <amb> * src/sorting.c: Restore the shortcut that doesn't write the data to a temporary file if it all can be sorted in one go. This removes the slowdown with the multi-threaded code even when running with no threads. 2012-07-15 [r1020] Andrew M. Bishop <amb> * src/sorting.c: Don't call any of the pthread functions unless running with multiple threads. 2012-07-14 [r1019] Andrew M. Bishop <amb> * src/logging.c: Default not to use the --logtime option. 2012-07-12 [r1018] Andrew M. Bishop <amb> * web/www/routino/router.js: Another change related to OpenLayers 2.12. 2012-07-11 [r1017] Andrew M. Bishop <amb> * src/prunex.c: Fix bug with pruning straight highways (uninitialised data). 2012-07-10 [r1016] Andrew M. Bishop <amb> * web/www/routino/router.html.en, web/www/routino/router.html.de, web/www/routino/router.html.nl, web/www/routino/router.js: Trigger the search form only when pressing the return key. 2012-07-10 [r1014-1015] Andrew M. Bishop <amb> * web/www/routino/page-elements.js: Remove some temporary variables by combining statements. * web/www/routino/visualiser.js: A change that should have been in r985. 2012-07-09 [r1013] Andrew M. Bishop <amb> * web/www/openlayers/routino.cfg, web/www/routino/visualiser.js, web/www/routino/router.js: Make compatible with OpenLayers version 2.12 (but don't default to using it). 2012-07-09 [r1012] Andrew M. Bishop <amb> * doc/INSTALL.txt, web/www/routino/router.js, web/www/routino/mapprops.js: Move the maxmarkers variable from router.js to mapprops.js. 2012-06-30 [r1011] Andrew M. Bishop <amb> * web/www/routino/router.js, web/www/routino/visualiser.js: Remove some temporary variables by combining statements. 2012-06-29 [r1010] Andrew M. Bishop <amb> * web/www/routino/router.html.de, web/www/routino/visualiser.html.en, web/www/routino/router.html.nl, web/www/routino/router.js, web/www/routino/router.html.en: Fix HTML so that it validates. 2012-06-29 [r1009] Andrew M. Bishop <amb> * web/www/routino/router.js, web/www/routino/visualiser.js: Be more consistent with the .transform() operation. 2012-06-29 [r1008] Andrew M. Bishop <amb> * web/www/routino/router.js, web/www/routino/search.pl, web/www/routino/search.cgi: Pass bounding box to search to help find local places. Properly URI encode search strings. Properly check CGI parameters. 2012-06-29 [r1007] Andrew M. Bishop <amb> * web/www/routino/router.html.en, web/www/routino/router.css, web/www/routino/router.html.de, web/www/routino/router.html.nl: Remove all style definitions from HTML files except for "display:none". 2012-06-29 [r1005-1006] Andrew M. Bishop <amb> * web/www/routino/icons/waypoint-coords.png, web/www/routino/icons/waypoint-search.png: Fix icons to have transparent background. * web/www/routino/router.html.de, web/www/routino/router.html.nl, web/www/routino/router.js, web/www/routino/search.pl, web/www/routino/router.html.en, web/www/routino/search.cgi, web/www/routino/router.css, doc/INSTALL.txt: Display all of the search results and allow the user to select one. 2012-06-05 [r1004] Andrew M. Bishop <amb> * web/www/routino/search.pl, web/www/routino/router.cgi, web/www/routino/results.cgi, web/www/routino/search.cgi, web/www/routino/visualiser.cgi, web/www/routino/router.pl, web/www/routino/statistics.cgi: Made some of the perl variables scope-local and checked other perl functions. 2012-06-05 [r1003] Andrew M. Bishop <amb> * src/visualiser.c, doc/html/usage.html, web/www/routino/visualiser.js, src/visualiser.h, src/filedumper.c, doc/USAGE.txt, web/www/routino/visualiser.cgi, web/www/routino/visualiser.html.en: Add an option to the visualiser to display segments of each of the highway types. 2012-06-05 [r1002] Andrew M. Bishop <amb> * src/visualiser.h, src/filedumper.c, doc/USAGE.txt, web/www/routino/visualiser.cgi, web/www/routino/visualiser.html.en, web/www/routino/visualiser.css, src/visualiser.c, doc/html/usage.html, web/www/routino/visualiser.js: Add an option to the visualiser to display segments accessible to each of the transport types. 2012-06-05 [r1001] Andrew M. Bishop <amb> * web/www/routino/router.html.en, web/www/routino/search.cgi (added), web/www/routino/router.css, web/www/routino/paths.pl, web/www/routino/router.html.de, web/www/routino/icons/waypoint-search.png (added), web/www/routino/router.html.nl, web/www/routino/router.js, web/www/routino/icons/waypoint-coords.png (added), web/www/routino/search.pl (added): Add a button to replace the lat/long text entry with a location search entry. Use Nominatim service via CGI to get first search result and fill in coords. 2012-06-04 [r999-1000] Andrew M. Bishop <amb> * web/www/routino/results.cgi: No need to include paths.pl. * doc/html/installation.html: Move the filename prefix parameter to the paths.pl script with the other user-editable parameters. 2012-06-04 [r998] Andrew M. Bishop <amb> * doc/INSTALL.txt, web/www/routino/paths.pl, web/www/routino/router.pl: Move the filename prefix parameter to the paths.pl script with the other user-editable parameters. 2012-06-04 [r997] Andrew M. Bishop <amb> * web/www/routino/router.pl: On OSX the md5 program is called "md5" and not "md5sum". 2012-05-10 [r996] Andrew M. Bishop <amb> * src/sorting.c: Added some mutexes and condition variables to communicate between threads. 2012-05-09 [r995] Andrew M. Bishop <amb> * src/relationsx.c: Force bicycle routes to be bicycle accessible and foot routes to be foot accessible. 2012-05-08 [r994] Andrew M. Bishop <amb> * web/www/routino/router.html.de: Merge in the changes to the HTML template. 2012-05-08 [r993] Andrew M. Bishop <amb> * web/www/routino/router.html.de: Make link to documentation a relative one rather than to the Routino website. 2012-05-08 [r992] Andrew M. Bishop <amb> * web/www/routino/router.html.en, web/www/routino/router.html.de (added), web/www/routino/router.html.nl: Add a German language router webpage, and links to it from the other ones (patch from Andreas Matthus). 2012-05-02 [r991] Andrew M. Bishop <amb> * src/planetsplitter.c, src/Makefile, doc/USAGE.txt, src/sorting.c, doc/html/usage.html: Convert sorting algorithms to optionally use multiple threads. 2012-05-01 [r990] Andrew M. Bishop <amb> * xml/routino-osm.xsd, xml/osm.xsd, src/osmparser.c: Handle OSM files that contain changesets. 2012-04-29 [r989] Andrew M. Bishop <amb> * src/planetsplitter.c: Handle the --process-only and --parse-only options better. 2012-04-01 [r988] Andrew M. Bishop <amb> * web/www/routino/customvisualiser.cgi, web/www/routino/customrouter.cgi: Don't even bother checking the legality of the parameters since the JavaScript does that. 2012-04-01 [r987] Andrew M. Bishop <amb> * web/www/routino/icons, web/www/routino/router.html.nl, web/www/routino/router.js, web/www/routino/icons/create-icons.pl, web/www/routino/router.html.en: The number of waypoints is controlled by the JavaScript and they are automatically inserted so there is no need to insert multiple lines in the HTML. 2012-03-31 [r986] Andrew M. Bishop <amb> * web/www/routino/router.html.en, web/www/routino/visualiser.html.en, web/www/routino/router.html.nl, web/www/routino/router.js, web/www/routino/visualiser.js: Update the link URLs just-in-time rather than every time the map moves or parameters are changed. 2012-03-24 [r985] Andrew M. Bishop <amb> * web/www/routino/visualiser.js, web/www/routino/customvisualiser.cgi, web/www/routino/router.html.en, web/www/routino/visualiser.html.en, web/www/routino/router.html.nl, web/www/routino/router.js, web/www/routino/customrouter.cgi: Process the URL query string in the Javascript not in custom*.cgi. Refactor a lot of the code for coordinate handling. Simplify custom*.cgi so that they just redirect to the HTML page (will be removed in later versions - for existing link compatibility only). 2012-03-23 [r984] Andrew M. Bishop <amb> * web/www/routino/router.html.en, web/www/routino/router.html.nl, web/www/routino/router.js: Added new buttons to centre map on marker and to add coordinates for current location (Javascript geolocation function). Shuffled the existing buttons around. Allow "up" on first marker and "down" on last marker to wrap around. 2012-03-23 [r983] Andrew M. Bishop <amb> * web/www/routino/icons/waypoint-locate.png (added), web/www/routino/icons/waypoint-recentre.png (added), web/www/routino/icons/waypoint-down.png, web/www/routino/icons/waypoint-add.png, web/www/routino/icons/waypoint-home.png, web/www/routino/icons/waypoint-remove.png, web/www/routino/icons/waypoint-centre.png, web/www/routino/icons/waypoint-up.png: Enlarged the button icons, changed some and added two new ones. 2012-03-17 [r982] Andrew M. Bishop <amb> * src/logging.c, doc/html/usage.html, src/planetsplitter.c, src/logging.h, doc/USAGE.txt: Add a new '--logtime' option that prints the elapsed time for planetsplitter. 2012-03-03 Andrew M. Bishop <amb> Version 2.2 released 2012-03-03 [r978-981] Andrew M. Bishop <amb> * doc/html/output.html: Updated to version 2.2. * doc/html/readme.html: Updated to version 2.2. * doc/README.txt, FILES: Updated to version 2.2. * doc/NEWS.txt: Updated to version 2.2. 2012-02-21 [r977] Andrew M. Bishop <amb> * src/prunex.c: Refactor code slightly for isolated regions. 2012-02-21 [r976] Andrew M. Bishop <amb> * src/prunex.c: Re-arrange small sections of code based on results of profiling. 2012-02-21 [r975] Andrew M. Bishop <amb> * src/test/a-b-c.sh, src/test/a-b.sh, doc/html/usage.html, src/planetsplitter.c, src/test/Makefile, src/test, doc/USAGE.txt, src/test/start-1-finish.sh, src/test/only-split.sh: Enable pruning by default. Fix the test cases to run with and without pruning but only compare against the expected results when not pruned. 2012-02-20 [r974] Andrew M. Bishop <amb> * src/planetsplitter.c: Prune straight highways then isolated regions and then short segments. 2012-02-20 [r973] Andrew M. Bishop <amb> * src/prunex.c: Remove compiler warnings (when compiled with optimisation). 2012-02-20 [r972] Andrew M. Bishop <amb> * src/prunex.c: Allow pruning isolated regions to be run second or later. 2012-02-20 [r971] Andrew M. Bishop <amb> * src/prunex.c: Don't remove nodes/segments when straightening ways if it would cause the loss of a way name. 2012-02-19 [r970] Andrew M. Bishop <amb> * src/prunex.c: Some fixes to be able to process the whole of the UK. 2012-02-18 [r969] Andrew M. Bishop <amb> * doc/html/algorithm.html, doc/ALGORITHM.txt: Add a general description of data pruning. 2012-02-18 [r968] Andrew M. Bishop <amb> * src/prunex.c: Fix bug with pruning that caused super-node search to fail. 2012-02-18 [r967] Andrew M. Bishop <amb> * src/prunex.c: Refactored the code for straight highways and made improvements. 2012-02-18 [r966] Andrew M. Bishop <amb> * src/prunex.h, doc/html/usage.html, src/planetsplitter.c, doc/USAGE.txt, src/prunex.c: Prune nodes in the middle of straight highways. 2012-02-12 [r965] Andrew M. Bishop <amb> * src/nodesx.h: Need 3 cached nodes for slim mode. 2012-02-11 [r964] Andrew M. Bishop <amb> * doc/html/usage.html, src/planetsplitter.c, src/segments.h, doc/USAGE.txt, src/waysx.h, src/prunex.c, src/segmentsx.h: Prune short segments. 2012-02-09 [r963] Andrew M. Bishop <amb> * src/prunex.h, src/planetsplitter.c, src/prunex.c: Prune isolated segments if they cannot be routed to anywhere else, not just if they are not connected. 2012-02-09 [r962] Andrew M. Bishop <amb> * src/types.h: The latlong_t type is signed so must use an appropriate constant. 2012-02-08 [r961] Andrew M. Bishop <amb> * src/nodesx.h, src/types.h, src/prunex.c: Change the way that pruned nodes are recorded. 2012-02-08 [r960] Andrew M. Bishop <amb> * src/prunex.c: Don't mark pruned nodes as they are found but mark them all at the end. 2012-02-07 [r959] Andrew M. Bishop <amb> * src/Makefile: Revert the CFLAGS value. 2012-01-28 [r958] Andrew M. Bishop <amb> * src/typesx.h: Fix the recent change with the bitmask type. 2012-01-28 [r956-957] Andrew M. Bishop <amb> * src/files.h, src/prunex.c: Fix function comments. * src/sorting.h: Replace a missing header. 2012-01-28 [r955] Andrew M. Bishop <amb> * src/segments.c, src/prunex.h, src/superx.c, src/visualiser.c, src/relationsx.c, src/profiles.h, src/sorting.h, src/fakes.h, src/nodesx.c, src/output.c, src/relations.c, src/typesx.h, src/results.c, src/relations.h, src/nodes.c, src/waysx.c, src/optimiser.c, src/osmparser.c, src/segmentsx.c, src/nodes.h, src/tagging.c, src/prunex.c, src/segmentsx.h, src/profiles.c, src/queue.c: Simplify and standardise the included headers. 2012-01-14 [r954] Andrew M. Bishop <amb> * src/typesx.h: Change the bitmask type from uint8_t to uint32_t. 2012-01-14 [r953] Andrew M. Bishop <amb> * src/prunex.h, doc/html/usage.html, src/planetsplitter.c, doc/USAGE.txt, src/prunex.c: Add the option to prune small isolated regions out of the database to avoid routes starting of finishing on them. 2012-01-14 [r951-952] Andrew M. Bishop <amb> * src/segmentsx.c: Bug fix for latest change. * src/relationsx.c: Zero the structure before filling it in so that no junk is written to disk. 2012-01-13 [r950] Andrew M. Bishop <amb> * src/nodesx.h, src/superx.c, src/segmentsx.c, src/typesx.h, src/segmentsx.h: Add new macros to abstract the bit mask types. 2012-01-13 [r949] Andrew M. Bishop <amb> * src/nodesx.h, src/prunex.h (added), src/superx.c, src/relationsx.c, src/types.h, src/planetsplitter.c, src/Makefile, src/segmentsx.c, src/nodesx.c, src/prunex.c (added), src/segmentsx.h: Add an infrastructure to allow adding new functions to prune nodes and segments. 2012-01-11 [r948] Andrew M. Bishop <amb> * src/sorting.c, src/relationsx.c, src/sorting.h, src/waysx.c, src/nodesx.c: The filesort_*() functions now return a count of the number of items kept after sorting. 2012-01-10 [r947] Andrew M. Bishop <amb> * src/superx.c, src/nodesx.c: Move the allocation of the nodexs super flags memory until just before it is needed and free it as soon as no longer needed. 2011-12-11 [r946] Andrew M. Bishop <amb> * src/segmentsx.c: Remove unnecessary test. 2011-12-11 [r945] Andrew M. Bishop <amb> * src/output.c: Remove warning about uninitialised variable. 2011-12-11 [r944] Andrew M. Bishop <amb> * src/relationsx.c, src/segmentsx.c, src/nodesx.c: Fill the structures with zero before inserting data and writing to file (removes junk from unused spaces in database files). 2011-12-11 [r943] Andrew M. Bishop <amb> * src/superx.c, src/relationsx.c, src/segmentsx.c, src/segmentsx.h: Remove the "position" parameter from the NextSegmentX() function. 2011-12-11 [r942] Andrew M. Bishop <amb> * src/nodesx.h, src/relationsx.c, src/segmentsx.c, src/waysx.h, src/segmentsx.h: Remove the "position" parameter from the PutBack*X() functions (only used in slim mode). 2011-12-10 [r940-941] Andrew M. Bishop <amb> * src/osmparser.h: Update file now that the name has changed. * src/functionsx.h (removed), src/planetsplitter.c, src/osmparser.c, src/osmparser.h (added): Rename functionsx.h to osmparser.h. 2011-12-09 [r939] Andrew M. Bishop <amb> * web/www/routino/customvisualiser.cgi, web/www/routino/customrouter.cgi: The custom router uses the translated router.html or visualiser.html depending on the browser's Accept-Language header. 2011-12-08 [r936-938] Andrew M. Bishop <amb> * web/www/routino/visualiser.html (added): Create a link from visualiser.html.en to visualiser.html. * web/www/routino/visualiser.html (removed), web/www/routino/visualiser.html.en (added): Rename visualiser.html to visualiser.html.en. * web/www/routino/visualiser.js, web/www/routino/visualiser.html, web/www/routino/router.js: Move semi-constant strings from the JavaScript to the HTML so that they can be translated. 2011-12-08 [r935] Andrew M. Bishop <amb> * web/www/routino/router.html.en, web/www/routino/router.html.nl, web/www/routino/router.js: Use the translated total distance from the summary and not the untranslated one from the CGI. 2011-12-08 [r934] Andrew M. Bishop <amb> * src/visualiser.c: Make limit checking work with one-way streets and in slim mode. 2011-12-07 [r933] Andrew M. Bishop <amb> * doc/html/installation.html, web/www/routino/visualiser.js, web/www/routino/router.html.en, doc/INSTALL.txt, web/www/routino/visualiser.html, web/www/routino/router.html.nl, web/www/routino/router.js, web/www/routino/mapprops.js (added): Move the map preferences (N/S/E/W range, zoom range and URLs) to a separate file. 2011-12-07 [r932] Andrew M. Bishop <amb> * web/www/routino/page-elements.css, web/www/routino/router.html.en, web/www/routino/visualiser.html, web/www/routino/router.html.nl: Replace the "show"/"hide" button with "+"/"-" buttons. 2011-12-07 [r931] Andrew M. Bishop <amb> * web/data/create.sh: Generate an error log. 2011-12-06 [r930] Andrew M. Bishop <amb> * doc/TAGGING.txt, doc/html/tagging.html: Describe what the roundabout and mini-roundabout tags are used for. 2011-12-06 [r929] Andrew M. Bishop <amb> * src/output.c: Mini-roundabouts are now described as roundabouts instead of junctions. 2011-12-06 [r927-928] Andrew M. Bishop <amb> * src/test/expected/turns-WP09.txt, src/test/expected/turns-WP10.txt, src/test/expected/turns-WP11.txt, src/test/expected/turns-WP12.txt, src/test/expected/turns-WP13.txt, src/test/expected/turns-WP14.txt, src/test/expected/turns-WP15.txt, src/test/expected/turns-WP07.txt, src/test/expected/turns-WP08.txt: Updated test case expected results with the roundabout changes. * src/output.c: Use constants for the values of the "important" variable. Fix the missing junctions on roundabouts. 2011-12-06 [r925-926] Andrew M. Bishop <amb> * src/output.c: Output HTML directions for roundabouts. * xml/routino-translations.xml, src/translations.h, src/translations.c, xml/routino-translations.xsd: Add new translate-able strings for roundabouts. 2011-12-06 [r924] Andrew M. Bishop <amb> * src/ways.h: Cache three ways not two. 2011-11-26 [r923] Andrew M. Bishop <amb> * src/types.h, doc/TAGGING.txt, src/osmparser.c, src/filedumper.c, doc/html/tagging.html, src/types.c, xml/routino-tagging.xml: Parse and store information about roundabouts (to improve routing instructions). 2011-11-26 [r921-922] Andrew M. Bishop <amb> * doc/OUTPUT.txt, src/output.c, doc/html/output.html: Refactor a lot of the code, simplify it and fix some bugs: Names of highways in HTML format. Names of highways and bearings for GPX routes. Change the format of the text file to be more like GPX & HTML. * src/ways.h, src/ways.c: Allow space to cache one name for each cached way (in slim mode). 2011-11-23 [r920] Andrew M. Bishop <amb> * xml/routino-tagging-nomodify.xml: Fix the invalid XML. 2011-11-22 [r919] Andrew M. Bishop <amb> * src/osmparser.c, xml/routino-osm.xsd: Check that XML file contains version='0.6' in 'osm' tag. 2011-11-22 [r918] Andrew M. Bishop <amb> * src/filedumper.c: Refactor the code by moving the dumping of an OSM region into a separate function. 2011-11-22 [r917] Andrew M. Bishop <amb> * src/filedumper.c: Include a bounding box in the --dump-osm XML output. 2011-11-21 [r916] Andrew M. Bishop <amb> * src/filedumper.c: Ensure that only segments completely within the specified region are dumped when using --dump-osm. 2011-11-21 [r914-915] Andrew M. Bishop <amb> * doc/TAGGING.txt, doc/html/tagging.html: Document the use of the area tag. * src/osmparser.c, src/segmentsx.c, xml/routino-tagging.xml: When an area and a way overlap keep the way and discard the area. 2011-11-20 [r913] Andrew M. Bishop <amb> * src/test/Makefile, src/xml/Makefile: Fix some more Makefile oddities. 2011-11-20 [r912] Andrew M. Bishop <amb> * web/www/openlayers/install.sh: Change script to default to downloading OpenLayers v2.11. 2011-11-19 [r910-911] Andrew M. Bishop <amb> * Makefile: Fix some Makefile oddities. * src/test/Makefile, src/Makefile, src/xml/Makefile: Fix some Makefile oddities. 2011-11-19 [r907-909] Andrew M. Bishop <amb> * doc/html/tagging.html: Fix heading anchor names. * src/xml/test/bad-comment-extra-double-dash.xml (added), src/xmlparse.l: Fixed bug in XMl parsing that allowed invalid XML (double dash within comments). * src/queue.c: Revert back to r874 (itself the same as r867) but with the change that should have happened in r883 rather than being based on r868. 2011-11-12 Andrew M. Bishop <amb> Version 2.1.2 released 2011-11-12 [r903] Andrew M. Bishop <amb> * doc/NEWS.txt, doc/README.txt, FILES, doc/html/readme.html: Updated for version 2.1.2. 2011-11-12 [r902] Andrew M. Bishop <amb> * xml/routino-translations.xml, web/www/routino/router.html.en, web/www/routino/router.html.nl: Added Russian language translations. 2011-11-12 [r901] Andrew M. Bishop <amb> * doc/OUTPUT.txt, doc/TAGGING.txt, doc/ALGORITHM.txt, doc/INSTALL.txt: Small formatting changes. 2011-11-11 [r900] Andrew M. Bishop <amb> * doc/OUTPUT.txt, src/output.c, doc/html/output.html: Change the names of the variables for the XML and raw versions of the highway names. Output the text files with translated highway names. Update the documentation to say that only the header is untranslated in the text files. 2011-11-11 [r899] Andrew M. Bishop <amb> * xml/routino-tagging.xml: Fix invalid XML file. 2011-11-11 [r898] Andrew M. Bishop <amb> * doc/TAGGING.txt, doc/html/tagging.html, xml/routino-tagging.xml: Improve the documentation for the tagging rule configuration file. 2011-11-11 [r896-897] Andrew M. Bishop <amb> * xml/routino-tagging.xml: Add some more tagging rules from the UK error.log file. * web/bin/summarise-log.pl: Summarise segments that are loops. 2011-11-11 [r895] Andrew M. Bishop <amb> * src/relationsx.c: Make the progress messages more consistent. 2011-11-10 [r894] Andrew M. Bishop <amb> * web/www/routino/router.pl: Use the same convention to indicate the user-editable part of the file as used elsewhere. 2011-11-10 [r893] Andrew M. Bishop <amb> * src/translations.h, doc/OUTPUT.txt, src/output.c, src/translations.c, doc/html/output.html: Change the names of the variables for the XML and raw versions of the translations. Output the text files with the raw versions and not the XML versions of the copyright information. Update the documentation to say that only the copyright information is translated in the text files. 2011-11-10 [r892] Andrew M. Bishop <amb> * src/translations.c: Don't convert the highway types to XML numeric entities here (it is already done in the output functions). 2011-11-09 [r891] Andrew M. Bishop <amb> * src/optimiser.c: Change the condition used to terminate the search for the best route. 2011-11-08 [r890] Andrew M. Bishop <amb> * src/superx.c: Improve comment. 2011-11-08 [r889] Andrew M. Bishop <amb> * xml/Makefile: Delete the auto-generated profile.js and profile.pl files with distclean target. 2011-10-31 [r888] Andrew M. Bishop <amb> * src/files.h: Add a #define to disable the use of pread()/pwrite() but this must be manually configured, there is no configure script. 2011-10-31 [r887] Andrew M. Bishop <amb> * src/nodesx.h, src/relations.h, src/files.h, src/relationsx.c, src/ways.h, src/segments.h, src/waysx.c, src/Makefile, src/xml/Makefile, src/nodes.h, src/waysx.h, src/segmentsx.h: Use pread() and pwrite() functions instead of seek() followed by read() or write(). 2011-10-30 [r886] Andrew M. Bishop <amb> * src/nodes.c, src/nodes.h: Copy the node offsets into RAM for the slim mode since looking them up in the file is the largest single contributor to the time. 2011-10-29 [r885] Andrew M. Bishop <amb> * src/segments.c, src/visualiser.c, src/nodes.c, src/optimiser.c, src/filedumper.c, src/nodes.h, src/output.c: Rationalise and reduce the usage of LookUpNode() function. 2011-10-24 [r884] Andrew M. Bishop <amb> * src/Makefile, src/xml/Makefile: Fix long-standing annoying bug with dependencies for slim versions. 2011-10-24 [r883] Andrew M. Bishop <amb> * src/queue.c: No need to use uint32_t (just use int). 2011-10-23 Andrew M. Bishop <amb> Version 2.1.1 released 2011-10-23 [r881-882] Andrew M. Bishop <amb> * doc/NEWS.txt, FILES, doc/html/readme.html: Update for version 2.1.1. * doc/html/configuration.html: Update copyright year. 2011-10-22 [r880] Andrew M. Bishop <amb> * Makefile: Fix running 'make test' from the top level. 2011-10-22 [r879] Andrew M. Bishop <amb> * src/filedumper.c: Add some more typecasts before printing the values. 2011-10-22 [r878] Andrew M. Bishop <amb> * xml/Makefile: Fix the installation of the XML files. 2011-10-22 [r876-877] Andrew M. Bishop <amb> * src/test/expected/turns-WP09.txt, src/test/turns.osm, src/test/expected/turns-WP10.txt, src/test/expected/turns-WP11.txt, src/test/expected/turns-WP12.txt, src/test/expected/turns-WP04.txt, src/test/expected/turns-WP13.txt, src/test/expected/turns-WP05.txt, src/test/expected/turns-WP14.txt, src/test/expected/turns-WP06.txt, src/test/expected/turns-WP15.txt, src/test/expected/turns-WP16.txt (added), src/test/expected/turns-WP07.txt, src/test/expected/turns-WP08.txt: Test case for 'except' tags on turn restrictions. * src/osmparser.c, xml/routino-tagging.xml: Fix handling of 'except' tags for turn restrictions. 2011-10-22 [r875] Andrew M. Bishop <amb> * src/sorting.c: Revert back to something very close to r869 because it is fastest by a tiny fraction. 2011-10-22 [r874] Andrew M. Bishop <amb> * src/results.h, src/queue.c: Revert back to r867 because it is faster (although only by 1%) than any of the other combinations. 2011-10-22 [r873] Andrew M. Bishop <amb> * src/sorting.c, src/queue.c: Revert back to r864 zero-based binary heap but with r868/r869 refactored code. 2011-10-15 [r872] Andrew M. Bishop <amb> * src/sorting.c, src/queue.c: Change the binary heap to a 3-ary heap. 2011-10-15 [r871] Andrew M. Bishop <amb> * src/sorting.c: Bug fixes for the previous change. 2011-10-15 [r870] Andrew M. Bishop <amb> * src/sorting.c, src/results.h, src/queue.c: Change the binary heap to a 4-ary heap. 2011-10-15 [r868-869] Andrew M. Bishop <amb> * src/sorting.c: Refactor the binary heap to reduce the number of comparisons. * src/queue.c: Refactor the binary heap to reduce the number of comparisons. 2011-10-09 [r867] Andrew M. Bishop <amb> * src/sorting.c: Change to a unity based binary heap rather than zero based one to save some additions. 2011-10-09 [r866] Andrew M. Bishop <amb> * src/queue.c: Bug fix with previous change. 2011-10-06 [r865] Andrew M. Bishop <amb> * src/results.h, src/queue.c: Change to a unity based binary heap rather than zero based one to save some additions. 2011-10-06 [r864] Andrew M. Bishop <amb> * src/results.c: Swap the order of two parts of an && statement. 2011-10-06 [r863] Andrew M. Bishop <amb> * src/results.h, src/results.c: Change bin counters to 8-bit (reduces memory) and pre-allocate first dimension of pointer array (saves time). 2011-10-06 [r862] Andrew M. Bishop <amb> * Makefile, xml/Makefile, doc/Makefile, src/Makefile, src/xml/Makefile: Makefiles are more consistent with each other and 'make test' can be run from the top level. 2011-10-06 [r861] Andrew M. Bishop <amb> * doc/html/usage.html, src/planetsplitter.c, doc/USAGE.txt: Change the default number of iterations to 5 since testing shows that there is negligible improvement beyond here. 2011-10-05 [r860] Andrew M. Bishop <amb> * src/optimiser.c: Optimise the number of hash function bins by trial and error. 2011-10-05 [r859] Andrew M. Bishop <amb> * src/Makefile, src/xml/Makefile: Add the gcc options for profiling (coverage) and delete the files generated by it. 2011-10-05 [r858] Andrew M. Bishop <amb> * src/results.c: If there are too many results in one bin then double the number of bins. 2011-10-05 [r857] Andrew M. Bishop <amb> * src/results.h, src/results.c: Remove the two RESULTS_*_INCREMENT constants by swapping the dimensions on the 'point' array so that both have unity value and are pointless. 2011-10-05 [r856] Andrew M. Bishop <amb> * src/superx.c: Optimise the number of hash function bins by trial and error. 2011-10-04 [r854-855] Andrew M. Bishop <amb> * src/superx.c, src/optimiser.c: Increase the size of the hash array used to store the results. * src/results.h, src/results.c: Change the way that allocated memory is tracked. 2011-10-04 [r853] Andrew M. Bishop <amb> * src/results.c: Split the data increment constant into two for the different parts of the data structure. 2011-10-03 [r852] Andrew M. Bishop <amb> * web/www/routino/router.cgi: Ensure that the shortest or quickest option is passed to the router. 2011-10-03 Andrew M. Bishop <amb> Version 2.1 released 2011-10-03 [r851] Andrew M. Bishop <amb> * FILES: Remove another .svn directory. 2011-10-03 [r850] Andrew M. Bishop <amb> * doc/NEWS.txt, FILES, doc/html/readme.html: Update for version 2.1. 2011-09-07 [r849] Andrew M. Bishop <amb> * src/test/super-or-not.osm, src/optimiser.c, src/test/expected/super-or-not-WP03.txt (added): Handle the special case where the start point is a super-node and the finish point is somewhere within one of the super-segments from that node. 2011-09-07 [r848] Andrew M. Bishop <amb> * src/nodes.c: Fix for previous binary search change. 2011-09-07 [r847] Andrew M. Bishop <amb> * src/filedumper.c: Fix bug with earlier change to OSM file creator. 2011-09-07 [r846] Andrew M. Bishop <amb> * src/router.c: Fix confusing, duplicated, output message. 2011-09-07 [r845] Andrew M. Bishop <amb> * src/nodes.c: Make stricter checks for closest nodes just like in v2.0.3 for segments. 2011-09-07 [r844] Andrew M. Bishop <amb> * src/filedumper.c: Fix formatting problem with dumped OSM file. 2011-09-07 [r842-843] Andrew M. Bishop <amb> * src/nodes.c, src/waysx.c, src/nodesx.c, src/relations.c: Check binary search functions and improve comments, fix pathological case with end point and/or improve start point. * src/filedumper.c: Use macro test function rather than direct check. 2011-09-06 [r841] Andrew M. Bishop <amb> * src/test/super-or-not.osm (added), src/test/a-b.sh (added), src/test/expected/super-or-not-WP01.txt (added), src/test/expected/super-or-not-WP02.txt (added), src/test, src/test/super-or-not.sh (added): Added a new test case for the routing bug-fix in version 2.0.3 (route via super-nodes may not be shortest). 2011-09-06 [r840] Andrew M. Bishop <amb> * src/test/expected/dead-ends-WP01.txt, src/test/expected/dead-ends-WP02.txt, src/test/expected/dead-ends-WP03.txt, src/test/expected/dead-ends-WP04.txt, src/test/expected/dead-ends-WP05.txt, src/test/expected/dead-ends-WP06.txt, src/test/expected/dead-ends-WP07.txt, src/test/expected/dead-ends-WP08.txt, src/test/expected/dead-ends-WP09.txt, src/test/expected/loops-WP10.txt, src/test/expected/loops-WP11.txt, src/test/copyright.xml (added), src/test/expected/no-super-WP01.txt, src/test/expected/no-super-WP02.txt, src/test/expected/no-super-WP03.txt, src/test/expected/no-super-WP04.txt, src/test/expected/turns-WP01.txt, src/test/expected/turns-WP02.txt, src/test/expected/turns-WP03.txt, src/test/start-1-finish.sh, src/test/expected/turns-WP04.txt, src/test/expected/turns-WP05.txt, src/test/expected/turns-WP06.txt, src/test/expected/turns-WP07.txt, src/test/expected/turns-WP08.txt, src/test/expected/turns-WP09.txt, src/test/a-b-c.sh, src/test/expected/dead-ends-WP10.txt, src/test/expected/dead-ends-WP11.txt, src/test/expected/loops-WP01.txt, src/test/expected/loops-WP02.txt, src/test/expected/loops-WP03.txt, src/test/expected/loops-WP04.txt, src/test/expected/loops-WP05.txt, src/test/expected/loops-WP06.txt, src/test/expected/loops-WP07.txt, src/test/expected/loops-WP08.txt, src/test/expected/loops-WP09.txt, src/test/expected/turns-WP10.txt, src/test/expected/turns-WP11.txt, src/test/expected/turns-WP12.txt, src/test/expected/turns-WP13.txt, src/test/expected/turns-WP14.txt, src/test/expected/turns-WP15.txt: Ensure that test cases have correct copyright notice (Routino, AGPL3) in generated data and not the default one (OSM, CC-SA). 2011-09-06 [r838-839] Andrew M. Bishop <amb> * src/test/expected/dead-ends-WP01.txt (added), src/test/expected/dead-ends-WP02.txt (added), src/test/expected/dead-ends-WP03.txt (added), src/test/expected/dead-ends-WP04.txt (added), src/test/expected/dead-ends-WP05.txt (added), src/test/expected/dead-ends-WP06.txt (added), src/test/expected/dead-ends-WP07.txt (added), src/test/expected/dead-ends-WP08.txt (added), src/test/expected/loops-WP10.txt (added), src/test/expected/dead-ends-WP09.txt (added), src/test/expected/loops-WP11.txt (added), src/test/expected/no-super-WP01.txt (added), src/test/expected/no-super-WP02.txt (added), src/test/expected/no-super-WP03.txt (added), src/test/expected/turns-WP01.txt (added), src/test/expected/no-super-WP04.txt (added), src/test/expected/turns-WP02.txt (added), src/test/expected/turns-WP03.txt (added), src/test/expected/turns-WP04.txt (added), src/test/expected/turns-WP05.txt (added), src/test/expected/turns-WP06.txt (added), src/test/expected/turns-WP07.txt (added), src/test/expected/turns-WP08.txt (added), src/test/expected/turns-WP09.txt (added), src/test/expected/dead-ends-WP10.txt (added), src/test/expected/dead-ends-WP11.txt (added), src/test/expected/loops-WP01.txt (added), src/test/expected/loops-WP02.txt (added), src/test/expected/loops-WP03.txt (added), src/test/expected/loops-WP04.txt (added), src/test/expected/loops-WP05.txt (added), src/test/expected/loops-WP06.txt (added), src/test/expected/loops-WP07.txt (added), src/test/expected/loops-WP08.txt (added), src/test/expected/loops-WP09.txt (added), src/test/expected/turns-WP10.txt (added), src/test/expected/turns-WP11.txt (added), src/test/expected/turns-WP12.txt (added), src/test/expected/turns-WP13.txt (added), src/test/expected/turns-WP14.txt (added), src/test/expected/turns-WP15.txt (added): Store the expected results to check for future regressions. * src/test/a-b-c.sh, src/test/expected (added), src/test/start-1-finish.sh: Store the expected results to check for future regressions. 2011-09-05 [r837] Andrew M. Bishop <amb> * src/relationsx.c: Ignore relations based on all vehicle types (including bicycles) not just motor vehicles. 2011-09-05 [r836] Andrew M. Bishop <amb> * xml/Makefile, xml/scripts/walk.pl (added), xml, xml/scripts/ride.pl (added), web/data, xml/scripts (added), xml/scripts/drive.pl (added): Generate special-use sets of tagging rules for walking, riding and driving 2011-08-27 [r834-835] Andrew M. Bishop <amb> * web/bin/summarise-log.pl (added): A script to process the error log file and summarise it. * xml/routino-tagging.xml: Add lots more tagging rules based on errors logged from parsing UK, add some more error logging. 2011-08-27 [r832-833] Andrew M. Bishop <amb> * src/osmparser.c: Only log errors for highways. * src/relationsx.c: Improve the error messages for bad relations. 2011-08-27 [r830-831] Andrew M. Bishop <amb> * src/filedumper.c: Change the 'generator' tag in the dumped XML file. * xml/routino-tagging.xsd: Whitespace change. 2011-08-21 [r828] Andrew M. Bishop <amb> * doc/NEWS.txt, doc/README.txt, src/nodes.c, FILES, src/optimiser.c, src/router.c, doc/html/readme.html: Merge version 2.0.3 into working version. 2011-08-14 [r827] Andrew M. Bishop <amb> * src/tagging.h, src/tagging.c, xml/routino-tagging.xsd: Add an unset rule in the tagging processing XML file. 2011-08-13 [r826] Andrew M. Bishop <amb> * src/tagging.h, src/tagmodifier.c, src/osmparser.c, src/tagging.c, xml/routino-tagging.xsd: Add a logerror rule in the tagging processing XML file. 2011-08-04 [r825] Andrew M. Bishop <amb> * src/osmparser.c: Add more acceptable number suffixes. 2011-07-23 [r813] Andrew M. Bishop <amb> * src/osmparser.c: Better parsing of width/height/length and weight and more information about value actually used. 2011-07-21 [r812] Andrew M. Bishop <amb> * src/relationsx.c, src/osmparser.c, src/waysx.c, src/segmentsx.c, src/nodesx.c: Add logging of parsing and processing errors. 2011-07-21 [r810-811] Andrew M. Bishop <amb> * src/test/a-b-c.sh, src/test/start-1-finish.sh, src/test/only-split.sh: Use the --errorlog option. * doc/html/usage.html, src/planetsplitter.c, doc/USAGE.txt: The filename is now optional in the --errorlog option. 2011-07-21 [r809] Andrew M. Bishop <amb> * src/planetsplitter.c: Only open/close the error log file if one was requested. 2011-07-10 [r806-808] Andrew M. Bishop <amb> * src/test: Ignore the auto-generated files from the new test case. * src/test/invalid-turn-relations.osm (added), src/test/invalid-turn-relations.sh (added), src/test/only-split.sh (added): Add test cases for the new turn relation validity checks. * src/relationsx.c: Check turn relations more carefully and discard them if they are invalid. 2011-07-04 [r805] Andrew M. Bishop <amb> * src/relationsx.c: Change the termination of route relation way/relation lists. 2011-07-03 [r804] Andrew M. Bishop <amb> * src/logging.c, doc/html/usage.html, src/planetsplitter.c, src/logging.h, doc/USAGE.txt: Add framework for logging error during OSM parsing and subsequent processing. 2011-07-02 [r803] Andrew M. Bishop <amb> * src/nodes.h: Replace over-sized file entry with one of appropriate size. 2011-08-04 Andrew M. Bishop <amb> Version 2.0.3 released 2011-08-04 [r823] Andrew M. Bishop <amb> * doc/NEWS.txt, doc/README.txt, FILES, doc/html/readme.html: Updated for version 2.0.3. 2011-08-04 [r822] Andrew M. Bishop <amb> * src/router.c: If there is a route that passes super-nodes and one that doesn't then choose the better one. 2011-08-04 [r820-821] Andrew M. Bishop <amb> * src/router.c: If there is a direct route without passing any super-nodes then keep it as a backup in case the potential route that does pass super-nodes doesn't work out. * src/optimiser.c: Allow calling FixForwardRoute() more than once. 2011-08-04 [r819] Andrew M. Bishop <amb> * src/optimiser.c: Revert previous change because it breaks the dead-end handling. 2011-08-03 [r818] Andrew M. Bishop <amb> * src/router.c: Find a valid route if the start and end point are the same location (it doesn't require a U-turn). 2011-08-03 [r817] Andrew M. Bishop <amb> * src/optimiser.c, src/router.c: Add a new (less confusing) error message for when the start of the route has no super-nodes and doesn't include the end node and make clearer the error message when the combining of routes fails. 2011-08-03 [r816] Andrew M. Bishop <amb> * src/nodes.c: Make more checks on the closest segment to avoid choosing one that our profile does not allow us to use. 2011-08-02 [r815] Andrew M. Bishop <amb> * src/optimiser.c: Handle the case where the start node is a super-node and there is no previous segment. 2011-06-26 Andrew M. Bishop <amb> Version 2.0.2 released 2011-06-26 [r800-r801] Andrew M. Bishop <amb> * doc/README.txt, doc/html/readme.html: Update for version 2.0.2. * doc/NEWS.txt, FILES, doc/html/readme.html: Update for version 2.0.2. 2011-06-25 [r798-799] Andrew M. Bishop <amb> * src/results.c: Fix comment associated with results list memory handling. * src/optimiser.c: Free temporary results that are calculated. 2011-06-25 [r795-797] Andrew M. Bishop <amb> * src/tagging.h, src/planetsplitter.c, src/tagging.c: Add some functions to free the tagging rules when they have been used. * src/osmparser.c: Free some memory allocated when parsing the file. * src/nodesx.c: Free some memory allocated when writing the file. 2011-06-19 [r794] Andrew M. Bishop <amb> * src/tagmodifier.c: Change to unsigned long and ensure that printf format specifiers are correct. 2011-06-19 [r792-793] Andrew M. Bishop <amb> * src/segmentsx.c: If a node has no segments return a NULL pointer rather than random junk. * xml/routino-tagging.xml: Reinstate the line that makes roundabouts one-way. 2011-06-18 [r791] Andrew M. Bishop <amb> * src/osmparser.c, src/xmlparse.h, src/xmlparse.l: Don't use the flex yylineno but keep track with an unsigned long long line counter instead (if there are more than 2^31 nodes then there are more than 2^31 lines as well). 2011-06-18 [r790] Andrew M. Bishop <amb> * src/superx.c, src/relationsx.c, src/types.h, src/osmparser.c, src/waysx.c, src/filedumper.c, src/segmentsx.c, src/nodesx.c, src/router.c, src/typesx.h: Ensure that when printing numbers of the index_t type that an appropriate printf format specifier is used (ready for if it is redefined as 64-bit). 2011-06-18 [r788-789] Andrew M. Bishop <amb> * src/Makefile: Use the -std=c99 option by default. * src/relationsx.c, src/waysx.c, src/segmentsx.c, src/nodesx.c, src/segmentsx.h: Fix some more warnings from -Wextra and/or -pedantic options. 2011-06-18 [r787] Andrew M. Bishop <amb> * src/xmlparse.l: Use flex %options instead of #defines, force clean compilation with C99. 2011-06-18 [r786] Andrew M. Bishop <amb> * src/relationsx.c, src/relationsx.h: Rename structure element "restrict" to "restriction" to avoid C99 error (reserved word). 2011-06-18 [r785] Andrew M. Bishop <amb> * src/superx.c: Removed warning from gcc-4.6. 2011-06-14 [r784] Andrew M. Bishop <amb> * xml/routino-tagging.xml: Fix error with handling ferry routes (patch from Michael Günnewig). 2011-06-07 Andrew M. Bishop <amb> Version 2.0.1 released 2011-06-07 [r782] Andrew M. Bishop <amb> * doc/html/readme.html: Update for version 2.0.1. 2011-06-07 [r781] Andrew M. Bishop <amb> * doc/NEWS.txt, doc/README.txt, FILES: Update for version 2.0.1. 2011-06-05 [r779-780] Andrew M. Bishop <amb> * src/superx.c, src/visualiser.c, src/nodes.c, src/relationsx.c, src/waysx.c, src/filedumper.c, src/segmentsx.c, src/nodesx.c, src/relations.c: Replace int with appropriate defined types (mostly index_t, ll_bin_t and ll_bin2_t). * src/types.h: Add some comments to clarify the latitude/longitude bin types and a new type for latitude/longitude bins (two dimensions). 2011-06-05 [r777-778] Andrew M. Bishop <amb> * src/profiles.c: Change unsigned int to int for consistency with the rest of the code. * src/optimiser.c: Remove unused variable (hangover from previous U-turn searching). 2011-06-04 [r776] Andrew M. Bishop <amb> * src/superx.c, src/osmparser.c: Add missing header file. 2011-06-04 [r773-775] Andrew M. Bishop <amb> * src/osmparser.c: Convert integer and floating point values inline. Check that node, way and relation IDs don't need to be long long types. * src/translations.c, src/profiles.c: Convert integer and floating point values inline. * src/xmlparse.h, src/xmlparse.l: The XMLPARSE_ASSERT_(INTEGER|FLOATING) functions now don't return the converted type. 2011-06-04 [r770-772] Andrew M. Bishop <amb> * src/segments.h: Add a type cast to a macro. * src/segmentsx.c, src/segmentsx.h: Change name of function parameters to clarify what they are. * src/relationsx.c, src/segmentsx.c: Fix some more potential problems with a transition to 64-bit node_t. 2011-06-03 [r761] Andrew M. Bishop <amb> * src/superx.c, src/relationsx.c, src/segmentsx.c: Shorten the messages when running to avoid going beyond 80 characters. 2011-06-03 [r759-760] Andrew M. Bishop <amb> * src/visualiser.c: Remove hard-coded numeric value and replace with a #define value. * src/superx.c, src/relationsx.c, src/segmentsx.c, src/typesx.h: Remove hard-coded numeric values and replace with a common #define value. Handle overflows consistently. 2011-06-03 [r758] Andrew M. Bishop <amb> * src/nodesx.h, src/typesx.h: Move some macros from nodesx.h to typesx.h. 2011-06-03 [r757] Andrew M. Bishop <amb> * src/relationsx.c, src/tagmodifier.c, src/optimiser.c, src/osmparser.c, src/waysx.c: Rationalise the increment of the numbers used for the output when not --loggable. 2011-06-01 [r756] Andrew M. Bishop <amb> * src/relationsx.c: Delete turn relations that refer to nodes or ways that don't exist as soon as possible. 2011-05-31 [r755] Andrew M. Bishop <amb> * src/nodesx.h, src/osmparser.c, src/segmentsx.c, src/waysx.h, src/typesx.h: Fix some obvious problems with a transition to 64-bit node_t. 2011-05-31 [r754] Andrew M. Bishop <amb> * src/tagging.c, src/translations.c, src/profiles.c: Fix inconsistent C language version usage. 2011-05-30 Andrew M. Bishop <amb> Version 2.0 released 2011-05-30 [r742] Andrew M. Bishop <amb> * src/relationsx.c: Don't crash on malformed relations, give better reporting of number when processing them. 2011-05-30 [r741] Andrew M. Bishop <amb> * FILES: Update for release. 2011-05-30 [r740] Andrew M. Bishop <amb> * src/segmentsx.c: Fix spelling mistake in function parameter comment. 2011-05-30 [r738-739] Andrew M. Bishop <amb> * src/test/Makefile: Make sure that clean really means it. * doc/NEWS.txt, doc/README.txt, doc/html/readme.html: Update for version 2.0 release. 2011-05-30 [r737] Andrew M. Bishop <amb> * doc/html/usage.html, doc/html/algorithm.html, doc/TAGGING.txt, doc/html/index.html, doc/html/data.html, doc/USAGE.txt, doc/ALGORITHM.txt, doc/DATA.txt, doc/html/tagging.html: Run a spelling check on the documentation. 2011-05-30 [r736] Andrew M. Bishop <amb> * doc/html/algorithm.html: Describe new philosophy of alloing U-turn at waypoints to avoid dead-ends. 2011-05-30 [r735] Andrew M. Bishop <amb> * src/optimiser.c: Fix problem with test case loops WP11. 2011-05-30 [r734] Andrew M. Bishop <amb> * src/optimiser.c, src/functions.h, src/router.c: Change the philosophy on dead ends so that now a U-turn is made at the waypoint if continuing in the previous direction would lead into a dead-end. This simplifies the algorithm and removes a lot of special case handling. 2011-05-30 [r731-733] Andrew M. Bishop <amb> * src/test/loops.osm: Give the loops unique names. * src/test/a-b-c.sh, src/test/start-1-finish.sh: Print less information when running. * src/fakes.c: Fix error with calculating length of fake segment and optimise the ExtraFakeSegment function. 2011-05-29 [r730] Andrew M. Bishop <amb> * src/test/a-b-c.sh: Exit on error. 2011-05-21 [r729] Andrew M. Bishop <amb> * src/optimiser.c, src/functions.h, src/router.c: Find all routes in the no-super.osm test case. 2011-05-20 [r727-728] Andrew M. Bishop <amb> * src/test/no-super.osm: Add new test cases for fake nodes/segments. * src/fakes.c, src/optimiser.c, src/fakes.h: Add a special function to handle the detection of U-turns between two fake segments that sit on the same real segment. 2011-05-18 [r725-726] Andrew M. Bishop <amb> * src/test/a-b-c.sh (added), src/test, src/test/no-super.sh (added), src/test/no-super.osm (added): Add new test cases for very simple routes with no super-nodes. * src/fakes.c: Fix routing between two fake nodes on the same segment (again). 2011-05-18 [r724] Andrew M. Bishop <amb> * src/test/dead-ends.osm: Add a new waypoint at the very end of a dead-end (not super-node). 2011-05-18 [r722-723] Andrew M. Bishop <amb> * src/optimiser.c, src/functions.h: Remove the override flag from FindNormalRoute(). * src/optimiser.c, src/functions.h, src/router.c: Use the beginning of the route as the start of the combined route (since it may have special override segments in it). 2011-05-17 [r721] Andrew M. Bishop <amb> * src/optimiser.c, src/functions.h, src/router.c: Change the order of the arguments to the routing functions (move profile earlier). 2011-05-17 [r720] Andrew M. Bishop <amb> * doc/Makefile: Install the license file in the doc directory. 2011-05-15 [r719] Andrew M. Bishop <amb> * src/optimiser.c, src/router.c: Finally find a way out of dead-ends, might have some nasty side-effects though. 2011-05-14 [r717-718] Andrew M. Bishop <amb> * src/optimiser.c: Fix slim/non-slim variation. * src/test/dead-ends.osm: Add another waypoint at the terminal super-node. 2011-05-13 [r716] Andrew M. Bishop <amb> * src/test/turns.osm: Force waypoint 13 to go round the roundabout twice. 2011-05-12 [r714-715] Andrew M. Bishop <amb> * src/test/turns.osm (added), src/test, src/test/turns.sh (added): Added turn restriction test cases. * src/test/start-1-finish.sh: Bug fix for logging. 2011-05-11 [r712-713] Andrew M. Bishop <amb> * src/superx.c, src/segmentsx.c: Add comments to assert statements that don't already have them. * src/optimiser.c: Crash out if infinite loop (usually caused by a bug elsewhere). 2011-05-08 [r708-711] Andrew M. Bishop <amb> * src/test/start-1-finish.sh: Run filedumper, allow running under a run-time debugger. * src/optimiser.c: Remove clash of cache locations. * src/test/Makefile: Print an extra message after comparing the slim and non-slim results. * src/segments.c, src/segments.h: Make the NextSegment function inline (move from segments.c to segments.h). 2011-05-08 [r707] Andrew M. Bishop <amb> * src/segments.c, src/visualiser.c, src/nodes.c, src/optimiser.c, src/filedumper.c, src/nodes.h, src/output.c: The FirstSegment function now takes a cache position argument. 2011-05-08 [r706] Andrew M. Bishop <amb> * src/segments.c, src/nodes.c, src/relations.c, src/ways.c: Ensure that the correct number of cached nodes, segments, ways or relations are initialised. 2011-05-08 [r705] Andrew M. Bishop <amb> * src/ways.h, src/filedumper.c, src/ways.c: Remove the unused name caching for the ways (in slim mode). 2011-05-08 [r704] Andrew M. Bishop <amb> * src/segments.h, src/segmentsx.h: Simplify the lookup of the segment index in slim mode. 2011-05-07 [r703] Andrew M. Bishop <amb> * src/optimiser.c: Allow the start of a route to double-back to the initial node even if a super-node. 2011-05-07 [r700-702] Andrew M. Bishop <amb> * src/test/loops.osm: Rename the waypoints. * src/files.c: Remove useless assert statement. * src/optimiser.c, src/nodes.h, src/segmentsx.c: Fix bugs found by valgrind. 2011-05-07 [r697-699] Andrew M. Bishop <amb> * src/optimiser.c: Handle things correctly if the FindSuperSegment() function is called with a fake segment. * src/test/Makefile: Ensure that executables are compiled before running the tests. * src/Makefile: Require slim and non-slim versions of fakes.o. 2011-05-07 [r695-696] Andrew M. Bishop <amb> * src/router.c: Calculate an override version of the start of the route to get out of dead-ends. * src/output.c: Use real segments when making comparisons (not pointers or non-real segments). 2011-05-06 [r690-694] Andrew M. Bishop <amb> * src/test: Ignore files and directories generated by running 'make test'. * src/xml: Ignore files generated by running 'make test'. * src/Makefile: Allow running 'make test' in the source directory. * src/test/waypoints.pl (added), src/test/loops.osm (added), src/test/Makefile (added), src/test/dead-ends.sh (added), src/test/dead-ends.osm (added), src/test/start-1-finish.sh (added), src/test/loops.sh (added): Routing test cases. * src/test (added): A directory for routing test cases. 2011-05-06 [r689] Andrew M. Bishop <amb> * src/xml/test/bad-attr-character-ref.xml (removed): Remove false-positive test case (a bug in xmlparse.l previously flagged this as an error). 2011-04-27 [r688] Andrew M. Bishop <amb> * src/optimiser.c: Force going straight on if a waypoint is a super-node. 2011-04-27 [r686-687] Andrew M. Bishop <amb> * src/optimiser.c: Improve the FindSuperSegment() function when the existing segment is the right answer. * src/optimiser.c, src/router.c: Rename the variables in and around the CombineRoutes() function for clarity. 2011-04-26 [r685] Andrew M. Bishop <amb> * src/optimiser.c: When starting a super-route ensure that all starting segments are super-segments to avoid u-turns at the starting super-node. 2011-04-25 [r683-684] Andrew M. Bishop <amb> * src/output.c: Fix error with turn description. * src/output.c: Include a point number (hidden) in the HTML file. 2011-04-24 [r682] Andrew M. Bishop <amb> * src/waysx.c, src/waysx.h: Fix error is last semi-automated update. 2011-04-24 [r681] Andrew M. Bishop <amb> * src/segments.c, src/superx.c, src/visualiser.c, src/relationsx.c, src/segments.h, src/superx.h, src/filedumper.c, src/nodesx.c, src/relations.c, src/nodesx.h, src/relations.h, src/nodes.c, src/waysx.c, src/nodes.h, src/segmentsx.c, src/waysx.h, src/segmentsx.h, src/ways.c: Make the comments more consistent. 2011-04-24 [r680] Andrew M. Bishop <amb> * src/translations.h, src/fakes.c, src/filedumper.c, src/fakes.h, src/nodesx.c, src/output.c, src/results.c, src/files.c, src/nodesx.h, src/results.h, src/files.h, src/nodes.c, src/planetsplitter.c, src/osmparser.c, src/nodes.h, src/profiles.c, src/segments.c, src/sorting.c, src/tagging.h, src/visualiser.c, src/superx.c, src/logging.c, src/ways.h, src/profiles.h, src/relationsx.c, src/segments.h, src/sorting.h, src/tagmodifier.c, src/visualiser.h, src/superx.h, src/logging.h, src/relationsx.h, src/relations.c, src/functionsx.h, src/relations.h, src/types.h, src/optimiser.c, src/waysx.c, src/segmentsx.c, src/functions.h, src/waysx.h, src/router.c, src/segmentsx.h: Update comments throughout the source code. 2011-04-23 [r679] Andrew M. Bishop <amb> * doc/html/algorithm.html, doc/ALGORITHM.txt: Add description of U-turns at dead-ends. 2011-04-23 [r678] Andrew M. Bishop <amb> * src/optimiser.c, src/functions.h, src/output.c, src/router.c: Allow U-turns at dead-ends to avoid getting stuck. 2011-04-22 [r677] Andrew M. Bishop <amb> * src/optimiser.c, src/router.c: Handle failure to find route gracefully. 2011-04-22 [r676] Andrew M. Bishop <amb> * web/www/routino/visualiser.cgi: Another change related to turn restrictions (missed in last checkin). 2011-04-22 [r675] Andrew M. Bishop <amb> * src/segments.c, doc/html/usage.html, web/www/routino/router.cgi, src/segments.h, doc/USAGE.txt, src/router.c: Add in the option to specify an initial heading. 2011-04-22 [r674] Andrew M. Bishop <amb> * src/segmentsx.c, src/nodesx.c: Finish off the geographic sorting of segments. 2011-04-22 [r673] Andrew M. Bishop <amb> * src/filedumper.c: Use the common TurnAngle() function from segments.c instead of a local one. 2011-04-22 [r672] Andrew M. Bishop <amb> * src/segments.c, src/segments.h, src/output.c: Move the turn_angle() and bearing_angle() functions from output.c into segments.c. 2011-04-22 [r671] Andrew M. Bishop <amb> * doc/html/algorithm.html, doc/ALGORITHM.txt: Simplify the language used describing the highway properties. 2011-03-21 [r670] Andrew M. Bishop <amb> * src/relationsx.c: Ignore turn restrictions that ban going the wrong way down a one-way road. 2011-03-21 [r668-669] Andrew M. Bishop <amb> * src/segments.c, src/filedumper.c, src/profiles.c: Include math.h for files that use math functions. * src/types.h: Round the node latitude/longitude rather than truncating. 2011-03-21 [r667] Andrew M. Bishop <amb> * src/filedumper.c: Include some of the Routino internal information when dumping an OSM format output. 2011-03-21 [r666] Andrew M. Bishop <amb> * src/segmentsx.c: Fix bug with segment deduplication. 2011-03-21 [r665] Andrew M. Bishop <amb> * src/relationsx.c, src/planetsplitter.c, src/relationsx.h, src/nodesx.c: Sort the segments geographically. 2011-03-20 [r664] Andrew M. Bishop <amb> * src/nodesx.c: Sort nodes strictly by latitude/longitude within the bins (helps with regresssion testing). 2011-03-20 [r661-663] Andrew M. Bishop <amb> * web/www/routino/documentation: Ignore extra image files. * src/xmlparse.l: Ensure that UTF-8 is used internally when reading in a numeric entity. * src/router.c: Fix bug found by gcc-4.5. 2011-03-20 [r660] Andrew M. Bishop <amb> * src/segmentsx.c: Return early from the IndexSegments function if there are no segments. 2011-03-19 [r659] Andrew M. Bishop <amb> * doc/html/algorithm.html, doc/html/example0.png, doc/html/example1.png, doc/ALGORITHM.txt, doc/html/example2.png, doc/html/example3.png (added), doc/html/example4.png (added): Update the algorithm documents for turn restrictions. 2011-03-19 [r658] Andrew M. Bishop <amb> * src/segmentsx.c: Deduplicate in pairs only (i.e. if a segment occurs 4 times then keep 2 of them). 2011-03-19 [r657] Andrew M. Bishop <amb> * src/segmentsx.c: Cache the recently used ways when de-duplicating segments. 2011-03-19 [r656] Andrew M. Bishop <amb> * src/superx.c: Use previous segment in router rather than looking at previous node. 2011-03-12 [r655] Andrew M. Bishop <amb> * src/segmentsx.c, src/nodesx.c: Make the used nodes marker bit-wide rather than byte-wide. 2011-03-12 [r654] Andrew M. Bishop <amb> * src/nodesx.h, src/superx.c, src/nodesx.c: Make the nodes super marker bit-wide rather than byte-wide. 2011-03-12 [r653] Andrew M. Bishop <amb> * src/nodesx.h, src/superx.c, src/planetsplitter.c, src/superx.h, src/nodesx.c: Make the nodes super marker a boolean. 2011-03-12 [r652] Andrew M. Bishop <amb> * src/superx.c, src/planetsplitter.c, src/superx.h: Optimise the search for supernodes, consider traffic when counting segments that meet at a node. 2011-02-27 [r651] Andrew M. Bishop <amb> * src/nodesx.h, src/superx.c, src/relationsx.c, src/waysx.c, src/segmentsx.c, src/waysx.h, src/segmentsx.h: Rename the xdata and xcached members of the nodesx, segmentsx and waysx structures. 2011-02-27 [r650] Andrew M. Bishop <amb> * src/nodesx.h, src/relationsx.c, src/planetsplitter.c, src/waysx.c, src/relationsx.h, src/segmentsx.c, src/nodesx.c, src/waysx.h, src/segmentsx.h: Don't have both xnumber and number in the nodesx, segmentsx, waysx and relationsx structures. 2011-02-27 [r649] Andrew M. Bishop <amb> * src/segmentsx.c, src/segmentsx.h: Remove a now unused array of segment indexes. 2011-02-27 [r648] Andrew M. Bishop <amb> * src/logging.c: Handle the case where the middle string is shorter than the previous one. 2011-02-26 [r646-647] Andrew M. Bishop <amb> * src/superx.c: Use the OtherNode and IsOneWay* macros when routing. * src/superx.c, src/relationsx.c, src/segmentsx.c, src/segmentsx.h: Remove a pair of functions that are no longer used and rename the other pair. 2011-02-26 [r645] Andrew M. Bishop <amb> * src/relationsx.c, src/planetsplitter.c, src/relationsx.h: Fixed the turn relations with a few more functions. 2011-02-26 [r644] Andrew M. Bishop <amb> * src/planetsplitter.c, src/segmentsx.c, src/segmentsx.h: Renamed a couple of functions for clarity. 2011-02-26 [r643] Andrew M. Bishop <amb> * src/nodesx.h, src/superx.c, src/relationsx.c, src/planetsplitter.c, src/osmparser.c, src/segmentsx.c, src/nodesx.c, src/segmentsx.h: Go back to the internal structure used (but reverted) during version 1.2 development where each segment is stored only once. This halves the memory usage (mmap files or just files) for planetsplitter. This is allowed because a new algorithm to create the node to segment indexes makes it simpler now that it was. This change is required so that super-node/segment optimisation doesn't remove mutual loops. This change doesn't handle turn restrictions yet. 2011-02-24 [r642] Andrew M. Bishop <amb> * src/superx.c: Change a variable name to match the one used in optimiser.c. 2011-02-24 [r641] Andrew M. Bishop <amb> * src/superx.c, src/segmentsx.c: Create super-segments that go in loops and preserve all such loops. 2011-02-23 [r640] Andrew M. Bishop <amb> * src/segmentsx.c: Fix latent bug that can occur when de-duplicating segments. 2011-02-23 [r639] Andrew M. Bishop <amb> * xml/Makefile: Fix error in creating web files containing profiles. 2011-02-20 [r638] Andrew M. Bishop <amb> * src/optimiser.c: Allow U-turns at via points for transport types that ignore turn restrictions. 2011-02-20 [r637] Andrew M. Bishop <amb> * src/optimiser.c, src/functions.h, src/fakes.h: Don't allow U-turns at via points (but doesn't necessarily include turning round in the score when searching for optimum). 2011-02-18 [r636] Andrew M. Bishop <amb> * src/optimiser.c: Fix the code that stops routes doubling-back on themselves. 2011-02-11 [r635] Andrew M. Bishop <amb> * web/www/routino/update-profiles.pl (added), xml/Makefile, web/www/routino, web/www/routino/router.html.en, web/www/routino/router.pl, web/www/routino/router.html.nl, web/www/routino/router.js: Move the Javascript and Perl profiles into separate files. 2011-02-11 [r634] Andrew M. Bishop <amb> * doc/html/installation.html, web/www/openlayers/install.sh, doc/INSTALL.txt: Change to OpenLayers 2.10. 2011-02-11 [r632-633] Andrew M. Bishop <amb> * src/output.c: Don't confuse fake segments with junctions. * src/optimiser.c: Fix problem with only one super-node in the route. 2011-02-11 [r631] Andrew M. Bishop <amb> * src/fakes.c: Fix bug with generating fake segments. 2011-02-11 [r629-630] Andrew M. Bishop <amb> * xml/routino-profiles.xml: Wheelchairs do not obey turn restrictions. * web/www/routino/results.cgi, web/www/routino/router.html.en, src/router.c, web/www/routino/router.pl, web/www/routino/router.html.nl, web/www/routino/router.js: Print a message if routed OK, allow web users to see router output (now logged to file). 2011-02-05 [r628] Andrew M. Bishop <amb> * src/filedumper.c: Fix statistics for ways (broken by change for relations). 2011-02-05 [r626-627] Andrew M. Bishop <amb> * src/superx.c, src/optimiser.c, src/segmentsx.c, src/nodesx.c: Change some output printed while running. * src/filedumper.c: Fix problem with dumping turn relations. 2011-02-05 [r625] Andrew M. Bishop <amb> * src/filedumper.c: Print out the size of the relations.mem file. 2011-02-05 [r623-624] Andrew M. Bishop <amb> * web/www/routino/visualiser.cgi: Updated the visualiser to include turn restrictions. * src/visualiser.c, doc/html/usage.html, web/www/routino/visualiser.js, src/visualiser.h, src/filedumper.c, doc/USAGE.txt, web/www/routino/visualiser.html: Updated the visualiser to include turn restrictions. 2011-02-05 [r622] Andrew M. Bishop <amb> * src/profiles.h, web/www/routino/noscript.cgi, web/www/routino/customrouter.cgi, xml/routino-profiles.xsd, web/www/routino/noscript.template.html, xml/routino-profiles.xml, doc/html/usage.html, web/www/routino/router.cgi, src/optimiser.c, web/www/routino/router.html.en, doc/USAGE.txt, src/router.c, web/www/routino/router.pl, src/profiles.c, web/www/routino/router.html.nl, web/www/routino/router.js: Include the option to obey turn restrictions in the profile for each transport type. 2011-01-30 [r620-621] Andrew M. Bishop <amb> * doc/html/algorithm.html, doc/ALGORITHM.txt: Update algorithm description to include turn restrictions and a note about how the algorithm terminates the search. * doc/TAGGING.txt, doc/USAGE.txt: Update text versions of documents to match HTML. 2011-01-30 [r618-619] Andrew M. Bishop <amb> * src/output.c: Correct comments. * src/filedumper.c: Put a "restriction" tag into the turn restrictions when dumped. 2011-01-30 [r617] Andrew M. Bishop <amb> * src/optimiser.c, src/functions.h, src/router.c: Ensure that the first/last node and first/last segment of the Results structure are filled in properly. 2011-01-30 [r616] Andrew M. Bishop <amb> * src/optimiser.c: Fix routing where the final node is a super-node. 2011-01-29 [r615] Andrew M. Bishop <amb> * src/relationsx.c: All nodes adjacent to a turn restriction must also be turn restrictions. 2011-01-29 [r613-614] Andrew M. Bishop <amb> * src/files.h: Fix assert problem. * src/Makefile, src/xml/Makefile: Make dependency filename based on object file name (fixes overwriting problem with slim versions). 2011-01-29 [r612] Andrew M. Bishop <amb> * src/superx.c, src/files.h, src/relationsx.c, src/waysx.c, src/segmentsx.c, src/nodesx.c, src/files.c: Ensure that record of closed file descriptors are erased. 2011-01-29 [r610-611] Andrew M. Bishop <amb> * src/optimiser.c: Don't check for turn relations in FindStartRoutes(). * src/optimiser.c: Add some comments, shuffle a few lines of code. 2011-01-29 [r609] Andrew M. Bishop <amb> * src/optimiser.c: Fix the code that allows overshooting by one node when finding finish nodes. 2011-01-29 [r608] Andrew M. Bishop <amb> * src/fakes.c, src/optimiser.c, src/Makefile, src/fakes.h, src/relations.c, src/router.c: When finding a normal route check for turn relations (considering previous segment). When finding turn relations convert fake segments into real ones. 2011-01-29 [r607] Andrew M. Bishop <amb> * src/nodes.c: Fix pathological case of rounding error for points almost exactly on a segment. 2011-01-29 [r606] Andrew M. Bishop <amb> * src/superx.c: Fix for route finding in planetsplitter. 2011-01-24 [r605] Andrew M. Bishop <amb> * src/results.h, src/superx.c, src/optimiser.c, src/functions.h, src/output.c, src/router.c, src/results.c: Finds routes and obeys turn restrictions (only tested with very simple route and restrictions, more turn restriction testing and regression testing required). 2011-01-16 [r604] Andrew M. Bishop <amb> * src/relations.h, src/relations.c: Fix logic error with searching for via nodes. 2011-01-15 [r603] Andrew M. Bishop <amb> * src/results.h, src/superx.c, src/optimiser.c, src/output.c, src/results.c: Change the results structure to contain next segment and rename elements to clarify prev/next node and prev/next segment. 2011-01-15 [r602] Andrew M. Bishop <amb> * src/segmentsx.c: Change to comment for clarification. 2011-01-15 [r599-601] Andrew M. Bishop <amb> * doc/html/usage.html: Correction and clarification to filedumper usage. * src/nodesx.h: Change to comment for clarification. * src/relations.h, src/relationsx.c, src/planetsplitter.c, src/filedumper.c, src/relationsx.h, src/relations.c: Store the 'from' and 'to' segments and not nodes (to handle fake nodes inserted in segments). 2011-01-15 [r598] Andrew M. Bishop <amb> * src/visualiser.c, src/output.c: Change the IsSuperNode() macro to take a single pointer argument. 2011-01-09 [r597] Andrew M. Bishop <amb> * src/superx.c, src/relationsx.c, src/types.h: Make the 'from' and 'to' nodes of turn restrictions super-nodes. 2011-01-09 [r596] Andrew M. Bishop <amb> * src/relations.h, src/optimiser.c, src/nodes.h, src/relations.c: Check turn relations when finding a route. 2011-01-08 [r595] Andrew M. Bishop <amb> * src/optimiser.c, src/filedumper.c, src/nodes.h: Change the IsSuperNode() macro to take a single pointer argument. 2011-01-08 [r594] Andrew M. Bishop <amb> * src/optimiser.c: Move the local variables closer to where they are used. 2011-01-08 [r593] Andrew M. Bishop <amb> * doc/html/tagging.html: Add information about the tags used for turn relations. 2010-12-29 Andrew M. Bishop <amb> Changed version control environment from RCS to CVS to SVN. 2010-12-29 Andrew M. Bishop <amb> * doc/NEWS.txt: Temporary checkin to allow transition from RCS to CVS to SVN. * xml/routino-tagging.xml: Pass through turn relation information. 2010-12-21 Andrew M. Bishop <amb> * src/filedumper.c: Add turn relations to the statistics and dump outputs. 2010-12-21 Andrew M. Bishop <amb> * src/ways.h, src/segments.h, src/nodes.h, src/ways.c: Optimise the node, segment, way lookup in slim mode by checking if the previous index is being requested again. * src/relations.h, src/relations.c: Optimise the turn relation lookup. 2010-12-21 Andrew M. Bishop <amb> * src/relations.h, src/relations.c: Add functions to search for turn relations that match a particular node. 2010-12-21 Andrew M. Bishop <amb> * src/relations.h (added), src/relations.c (added): Initial revision * src/superx.c, src/relationsx.c, src/types.h: Update the nodes to force a super-node where there is a turn restriction. 2010-12-21 Andrew M. Bishop <amb> * src/relationsx.c, src/planetsplitter.c, src/relationsx.h: Finish the processing of the turn relations now that the extra node lookup table is in place. 2010-12-20 Andrew M. Bishop <amb> * src/nodesx.c, src/segmentsx.c, src/segmentsx.h: Handle the SegmentX Segment in the same way as the other data structures (map into memory when used, open/close the file if slim). Create the real nodes without mapping the segments into memory. * src/nodesx.c, src/nodesx.h, src/relationsx.c, src/segmentsx.c, src/segmentsx.h, src/waysx.h: Make the PutBack*() functions be no-ops in slim mode and remove the pre-processor guards from around the function calls. * src/nodesx.c: Don't map the file into memory for writing out the Nodes file. * src/superx.c, src/waysx.c, src/waysx.h, src/nodesx.c, src/relationsx.c, src/segmentsx.c: Close and open the files for the slim case to match the map/unmap of files for the non-slim case. * src/nodesx.c, src/segmentsx.c: Make the last two changes work for slim mode. * src/nodesx.c, src/nodesx.h: Create the Nodes offset table at the end rather than during the sort process. * src/nodesx.c, src/nodesx.h, src/segmentsx.c, src/segmentsx.h: Don't maintain a copy of the whole set of Nodes along with the NodeXs but generate the Node from the NodeX when written to disk. Create a lookup table between the original index and the geographically sorted index. 2010-12-19 Andrew M. Bishop <amb> * src/planetsplitter.c, src/relationsx.c: Process the turn relations (apart from updating the indexes to the geographically sorted nodes). * src/superx.c: Handle the case of no super segments better. * src/planetsplitter.c: Change around the order of the functions. * src/relationsx.c: A temporary check-in that handles turn restrictions more complicated than actually allowed (ways must start/end at the via node). * xml/routino-tagging.xml: Add mini-roundabouts. * src/sorting.c: Bug fix for last change. 2010-12-18 Andrew M. Bishop <amb> * src/segmentsx.c: Remove the test for sorting zero segments (now that the sort function doesn't crash). * src/nodesx.c, src/segmentsx.c, src/segmentsx.h, src/superx.c: Duplicate the IndexFirstSegmentX() and IndexNextSegmentX() functions to create two distinct one for use at different times. * src/sorting.c: Handle the case where there is no data in the file. * src/Makefile, src/filedumper.c, src/functions.h, src/optimiser.c, src/planetsplitter.c, src/relationsx.c, src/relationsx.h, src/router.c, src/types.h: Add a Relations data type and write out the turn relations that have been read in. Still doesn't perform the required processing after reading the data or use the information for routing. 2010-12-12 Andrew M. Bishop <amb> * src/osmparser.c, src/typesx.h: Change the names of the enumerated types for turn restrictions. 2010-12-05 Andrew M. Bishop <amb> * src/osmparser.c, src/relationsx.c, src/relationsx.h, src/typesx.h: Parse turn restriction relations and store ones with a single via node. (Doesn't do anything with them yet). * src/nodesx.h, src/segmentsx.h, src/waysx.h: Updated the comments for clarity. 2010-12-04 Andrew M. Bishop <amb> * src/filedumper.c, src/nodesx.c, src/nodesx.h, src/osmparser.c, src/types.h: Improved version of previous change. 2010-11-28 Andrew M. Bishop <amb> * src/filedumper.c, src/nodesx.c, src/nodesx.h, src/osmparser.c, src/types.h: Add parsing of mini-roundabouts. * xml/routino-tagging.xml, src/filedumper.c, src/osmparser.c, src/types.c, src/types.h: Remove the roundabout type from the parsing. * src/fakes.c: Fix some problems with fake nodes, in particular a route between two fake nodes on the same segment can now be calculated. * src/nodes.c: Return the two nodes of a segment in the same order each time. 2010-11-27 Andrew M. Bishop <amb> * src/fakes.h, src/sorting.h: New file. * src/fakes.c, src/functions.h, src/nodesx.c, src/optimiser.c, src/output.c, src/relationsx.c, src/router.c, src/segmentsx.c, src/sorting.c, src/types.h, src/waysx.c: Split functions.h into fakes.h, sorting.h and the remainder in functions.h. * src/optimiser.c, src/router.c: Move some of the complexity from router.c to optimiser.c. * src/types.c, src/types.h, src/ways.h, src/waysx.c: Change the wayprop_t type into properties_t. * src/nodesx.h, src/osmparser.c, src/profiles.c, src/profiles.h, src/relationsx.c, src/relationsx.h, src/types.c, src/types.h, src/ways.h, src/waysx.c, src/filedumper.c, src/nodes.h, src/nodesx.c: Change the allow_t type into transports_t (and associated enums and macros). * src/types.h, src/ways.h: Change the waytype_t type into highway_t. 2010-11-14 Andrew M. Bishop <amb> * xml/routino-tagging.xml: Fix mis-spelling with surface=asphalt tag (patch from Michael Günnewig). * src/filedumper.c, src/types.c, src/types.h, src/ways.h, src/waysx.c: Print out statistics about what highways are included in the database. 2010-11-13 Andrew M. Bishop <amb> Version 1.5.1 released 2010-11-13 Andrew M. Bishop <amb> * doc/NEWS.txt, doc/README.txt: Updated for version 1.5.1. * doc/USAGE.txt: Update program usage for new logging option. * xml/routino-translations.xml: Add translation for ferry into German (patch from Michael Günnewig). * src/relationsx.c: Fix bug with relation processing. * src/logging.h: Add GCC attributes for the logging functions. * src/logging.h, src/logging.c: New file. * src/Makefile, src/nodesx.c, src/optimiser.c, src/osmparser.c, src/planetsplitter.c, src/relationsx.c, src/router.c, src/segmentsx.c, src/superx.c, src/tagmodifier.c, src/waysx.c: Add an option to make the output more suitable for a log file. 2010-10-31 Andrew M. Bishop <amb> * src/files.c: Ensure that enough memory gets allocated in FileName() function. 2010-10-30 Andrew M. Bishop <amb> Version 1.5 released 2010-10-30 Andrew M. Bishop <amb> * doc/README.txt, doc/NEWS.txt: Updated for version 1.5. 2010-10-18 Andrew M. Bishop <amb> * src/profiles.c: Use sqrt() function to reduce the effect of property preferences close to 50%. Ensure that preferences cannot equal zero (error on division). * doc/ALGORITHM.txt, doc/INSTALL.txt, doc/USAGE.txt: Updated with information about the new features. * doc/CONFIGURATION.txt, doc/TAGGING.txt: Add in the footroute and bicycleroute configuration options and route relation tag processing. 2010-10-16 Andrew M. Bishop <amb> * src/files.c: Fixed some comments for recent changes. 2010-10-09 Andrew M. Bishop <amb> * xml/routino-profiles.xml: Add footroute and bicycleroute to the profiles. * src/files.c, src/files.h, src/relationsx.c: The ReOpenFile() function cannot be read/write because it stops the router running with read-only access to the database. * src/nodesx.c, src/relationsx.c, src/segmentsx.c, src/superx.c: Fix previous check-in on this set of files. * src/xmlparse.l: Ensure that comparisons are made with unsigned chars. 2010-10-03 Andrew M. Bishop <amb> * src/nodesx.c, src/relationsx.c, src/segmentsx.c, src/superx.c: Don't try mapping a file if it is zero length (e.g. no super-segments). * src/files.c, src/files.h, src/relationsx.c: Add a function to map a file writeable and use it for updating the ways when processing route relations. * src/relationsx.c: Avoid self-recursion and adding route information to relations that already have it. 2010-09-25 Andrew M. Bishop <amb> * src/osmparser.c, src/relationsx.c, src/relationsx.h, src/waysx.h: Apply the route=bicycle or route=foot tags from the relation to all ways contained in it and to all ways in all sub-relations of it (including recursion to depth 5). This requires all relations to be stored even if not routes because they might be included by another relation that is. * src/segmentsx.c: Don't sort the (super-)segments if there are none. * src/nodesx.c, src/functions.h, src/sorting.c: Rename the heapsort() function to filesort_heapsort(). 2010-09-19 Andrew M. Bishop <amb> * src/files.c, src/files.h, src/nodesx.c, src/segmentsx.c, src/sorting.c, src/waysx.c: Change the names of the functions used to open files, change the ReOpen function to open R/W. * src/relationsx.c: Remove the sorting of the route relations. 2010-09-17 Andrew M. Bishop <amb> * src/nodesx.c, src/segmentsx.c: Zero the NodesFile and SegmentsFile data structures before writing them (zeros unused bytes). * src/planetsplitter.c, src/waysx.c, src/waysx.h: Split the sorting of waysx from the compacting so that the route relation information can be included before compacting. * xml/routino-tagging.xml, src/functionsx.h, src/osmparser.c, src/planetsplitter.c: Parse relations and extract foot and bicycle routes to be added as properties to the ways. * src/types.c, src/types.h: Add footroute and bicycleroute properties. * src/relationsx.c, src/relationsx.h: New file. * src/typesx.h, src/Makefile: Add files and datatypes for processing relations. * xml/routino-tagging-nomodify.xml, xml/routino-tagging.xsd, src/tagging.c: Process tags for relations. 2010-09-16 Andrew M. Bishop <amb> * src/waysx.c, src/segmentsx.c, src/nodesx.c: Fix the comment for the Append...() function. 2010-09-15 Andrew M. Bishop <amb> * xml/routino-profiles.xml, xml/routino-tagging.xml, xml/routino-translations.xml, src/output.c, src/translations.c, src/types.c, src/types.h: Add routing on ferries. * src/filedumper.c, src/planetsplitter.c, src/router.c: Bug fix for last change. * src/filedumper.c, src/planetsplitter.c, src/router.c: Improve the usage information to tell which command line argument was in error. * src/profiles.c: Fix --help-profile-perl option and make perl and JSON outputs more pretty. * src/router.c, src/planetsplitter.c: Usage message has wrong option name. * src/xmlparse.l: Fix last change to make UTF-8 parsing more strict, also added strict conversion to XML-safe character references. * src/translations.c: Convert translations read from file into XML-safe encodings before using them. * src/output.c: HTML file has UTF-8 meta-tag. * xml/routino-translations.xml: Revert to UTF-8 multi-byte representations instead of character references. 2010-09-14 Andrew M. Bishop <amb> * src/xmlparse.l: Stricter checking on XML data (Unicode). 2010-09-05 Andrew M. Bishop <amb> * xml/Makefile, src/Makefile, doc/Makefile, Makefile: Move all of the installation pathnames to the top level Makefile and include it into the lower level makefiles. * src/planetsplitter.c, src/router.c, src/tagmodifier.c: Use the installed tagging.xml, profiles.xml or translations.xml files as the fallback option if no other given. 2010-09-04 Andrew M. Bishop <amb> * xml/routino-translations.xml: Change German translations from named HTML character encodings to numeric ones (works in GPX files as well as HTML). * xml/routino-translations.xml: Added Dutch translations (from Jan Jansen). 2010-08-30 Andrew M. Bishop <amb> * xml/routino-translations.xml: Change German translation to UTF-8, add comments indicating the origin of the two translations. * xml/routino-tagging-nomodify.xml: Relation rules are not allowed at all. * xml/Makefile, src/Makefile, doc/Makefile, Makefile: Added 'install' to top level (and lower) Makefiles. * src/ways.h, src/output.c: Change the names of the functions used to get the highway names. * src/filedumper.c: Only print the way name in OSM output when the way has a name. Change the names of the functions used to get the highway names. * src/profiles.c: Fix bug with writing out JSON profile information. 2010-08-30 Andrew M. Bishop <amb> * src/ways.h, src/output.c: Change the names of the functions used to get the highway names. * src/filedumper.c: Only print the way name in OSM output when the way has a name. Change the names of the functions used to get the highway names. * src/profiles.c: Fix bug with writing out JSON profile information. 2010-08-04 Andrew M. Bishop <amb> * src/output.c, src/segmentsx.c, src/types.h, src/fakes.c, src/functions.h, src/nodesx.c, src/optimiser.c: Change the way that fake nodes and segments are recognised (allows nearly 4G nodes to be stored instead of 2G nodes). 2010-08-03 Andrew M. Bishop <amb> * src/filedumper.c, src/nodes.h, src/nodesx.c, src/optimiser.c, src/types.h: Rename the variables that hold the node allowed transports and flags. 2010-08-02 Andrew M. Bishop <amb> * xml/routino-tagging-nomodify.xml, xml/routino-tagging.xml, xml/routino-tagging.xsd, src/filedumper.c, src/nodesx.c, src/nodesx.h, src/optimiser.c, src/osmparser.c, src/superx.c, src/tagging.c, src/types.h: Understand node traffic type restrictions. 2010-07-31 Andrew M. Bishop <amb> * src/profiles.h, src/types.c, src/types.h, src/ways.h, src/waysx.c: Rename the wayallow_t type to allow_t (since it applies to nodes as well now). * src/filedumper.c, src/nodes.h, src/nodesx.c, src/segmentsx.c, src/types.h: Add extra information to a node to store turn restrictions and properties. (Move the super-node bit from the first segment to here.) * src/nodesx.c, src/segmentsx.c, src/waysx.c: Assert if the number of nodes, segments or ways exceeds the legal range of the index counters. * src/nodes.h, src/nodesx.h, src/segments.h, src/segmentsx.h, src/ways.h, src/waysx.h: Change the data types to index_t where they are counting nodes/segments/ways. * src/nodes.h, src/nodesx.h, src/segments.h, src/segmentsx.h, src/ways.h, src/waysx.c, src/waysx.h: Ensure that seeking within a file uses a 64-bit offset. * src/nodesx.c, src/segmentsx.c, src/superx.c, src/waysx.c: Remove the assert statements that check the order of calling the functions. 2010-07-26 Andrew M. Bishop <amb> * src/filedumper.c, src/nodes.c, src/nodes.h, src/visualiser.c: Final part of slim mode for the router (node offsets). 2010-07-24 Andrew M. Bishop <amb> * src/nodesx.c, src/segmentsx.c, src/waysx.c: Some tidying up of the writing of the file headers. * src/ways.c, src/ways.h, src/waysx.c, src/filedumper.c, src/nodes.c, src/optimiser.c, src/output.c, src/profiles.c, src/visualiser.c: Finished slim mode for the router by adding ways. 2010-07-23 Andrew M. Bishop <amb> * src/filedumper.c, src/nodes.c, src/nodes.h, src/output.c, src/segments.c, src/segments.h, src/segmentsx.c: Added slim mode to the router for segments. * src/Makefile: Add the fakes.c file. * src/optimiser.c, src/results.c, src/results.h: Change the results structure to hold the index of the segment instead of a pointer to it. * src/types.h, src/router.c, src/functions.h: Move the fake nodes and segments to a new file. * src/fakes.c: New file. 2010-07-19 Andrew M. Bishop <amb> * xml/routino-profiles.xml: Reduce the "multilane" preference for motor vehicles. Gives too much bias with previous setting. 2010-07-15 Andrew M. Bishop <amb> * src/Makefile, src/filedumper.c, src/nodes.c, src/nodes.h, src/nodesx.c, src/visualiser.c: Added a slim mode to the router (just for nodes to start with). 2010-07-14 Andrew M. Bishop <amb> * src/segmentsx.h, src/superx.c, src/waysx.c, src/waysx.h, src/Makefile, src/nodesx.c, src/nodesx.h, src/planetsplitter.c, src/segmentsx.c: Replaced the runtime selection of slim mode / non-slim mode with compile time selection that gives no runtime overhead but gives two executables. 2010-07-13 Andrew M. Bishop <amb> * src/nodesx.c, src/nodesx.h, src/segmentsx.c, src/segmentsx.h, src/waysx.c, src/waysx.h: Move the functions for slim mode out into the header file and make it inline. 2010-07-12 Andrew M. Bishop <amb> * src/files.h: New file. * src/segmentsx.h, src/sorting.c, src/superx.c, src/tagging.c, src/tagmodifier.c, src/translations.c, src/ways.c, src/waysx.c, src/waysx.h, src/filedumper.c, src/files.c, src/functions.h, src/nodes.c, src/nodesx.c, src/nodesx.h, src/optimiser.c, src/output.c, src/planetsplitter.c, src/profiles.c, src/router.c, src/segments.c, src/segmentsx.c: Create a files.h header and put some of the most heavily used files.c functions into it and make them inline. 2010-07-11 Andrew M. Bishop <amb> * src/segmentsx.c, src/segmentsx.h, src/files.c, src/nodesx.c, src/nodesx.h: Made the planetsplitter slim mode handle the output node and segment data in a slim way as well as in the input data. * src/nodesx.c, src/segmentsx.c, src/waysx.c: Change the names of the temporary files. 2010-07-10 Andrew M. Bishop <amb> Version 1.4.1 released 2010-07-10 Andrew M. Bishop <amb> * doc/NEWS.txt: Update NEWS for release. * doc/ALGORITHM.txt: Update documentation for slight modification to algorithm, also add more information about how preferences etc are handled. 2010-07-09 Andrew M. Bishop <amb> * src/Makefile: Default compilation flags include optimisation and not debugging symbols. 2010-07-08 Andrew M. Bishop <amb> * src/nodes.c: Fix error with finding closest segment to the specified point. * src/optimiser.c: Bug fix for not crashing when finding the middle part of the route. 2010-07-07 Andrew M. Bishop <amb> * src/results.c, src/optimiser.c: Changed the amount of memory allocated for intermediate results => routes much faster. * src/output.c: Remove compilation warning. * src/Makefile: Copy files to web directory like done in other Makefiles. * doc/Makefile: Change location of HTML files in web directory and clean up web directory on distclean. * src/xml/Makefile: Stop message being printed when make runs. * xml/Makefile: Fix error from last checkin and clean up web directory on distclean. 2010-07-06 Andrew M. Bishop <amb> * src/optimiser.c: Don't crash if the middle part of the route can't be found but exit cleanly. 2010-07-05 Andrew M. Bishop <amb> * src/superx.c: Change the algorithm used to determine supernodes. 2010-07-03 Andrew M. Bishop <amb> * xml/routino-translations.xml: Added German translation [patch from Christoph Eckert]. * src/translations.c: Don't crash if more than one language is in translations.xml but --language option is not used. 2010-06-28 Andrew M. Bishop <amb> * src/router.c: Don't crash if start and finish are the same point. 2010-06-27 Andrew M. Bishop <amb> * doc/DATA.txt: New file. * doc/ALGORITHM.txt, doc/CONFIGURATION.txt, doc/INSTALL.txt, doc/OUTPUT.txt, doc/README.txt, doc/TAGGING.txt, doc/USAGE.txt: Updated documentation to match new web site. * doc/Makefile: New file. * xml/Makefile: Add some new variables. 2010-06-26 Andrew M. Bishop <amb> * xml/routino-profiles.xml, xml/routino-tagging-nomodify.xml, xml/routino-tagging.xml, xml/routino-translations.xml, src/translations.c: Changed URLs to http://www.routino.org/ * doc/README.txt: *** empty log message *** * doc/OUTPUT.txt: Changed URLs to http://www.routino.org/ 2010-05-31 Andrew M. Bishop <amb> Version 1.4 released 2010-05-31 Andrew M. Bishop <amb> * doc/INSTALL.txt, doc/NEWS.txt, doc/README.txt: Update for version 1.4. * src/xml/Makefile: Make sure that distclean really cleans up. * Makefile: Make sure that xml sub-directory is made. * src/router.c: Fix the code that should stop routing if no segment is found. 2010-05-30 Andrew M. Bishop <amb> * doc/USAGE.txt: Add the planetsplitter tagging rules option (and remove the unnecessary options that it replaces), add the filedumper OSM dump option and add the tagmodifier program. * doc/TAGGING.txt: Describe the new tagging rules. * doc/OUTPUT.txt: Note that the HTML and GPX outputs are translated. * doc/CONFIGURATION.txt: Add the tagging rules configuration file. * doc/ALGORITHM.txt: An update to the current size of the UK database. * xml/routino-tagging-nomodify.xml: New file. * src/tagmodifier.c: A tagging XML file must be read (just like planetsplitter). * src/filedumper.c: Add the option to dump a region rather than all and to not output super segments. * src/optimiser.c: Fix printing the number of super-segments tried. 2010-05-29 Andrew M. Bishop <amb> * xml/routino-translations.xml, xml/routino-translations.xsd, src/ways.h, src/filedumper.c, src/osmparser.c, src/output.c, src/translations.c, src/translations.h: Translate the names given to unnamed roads (the highway type). * src/profiles.c, src/profiles.h, src/router.c: Stricter check on specified profile before routing. * src/router.c: Ensure that if no segment is found the routing stops. * src/nodes.c: When finding a closest segment one of the nodes must be within the search distance. 2010-05-28 Andrew M. Bishop <amb> * src/router.c: Make sure that some profiles are loaded. 2010-05-27 Andrew M. Bishop <amb> * src/optimiser.c, src/profiles.c: Fix bug with profile preferences (used incorrectly in route optimisation). * src/Makefile, src/filedumper.c, src/types.c, src/types.h: Add an option to filedumper to dump an OSM format file. 2010-05-25 Andrew M. Bishop <amb> * src/xmlparse.l: Fix bug with encoding XML strings. 2010-05-23 Andrew M. Bishop <amb> * xml/Makefile: Make sure that modified files are copied to web directory. * src/tagmodifier.c: Fix bug when filename is specified on command line. * src/tagging.c, src/tagging.h, src/tagmodifier.c, src/xmlparse.l, src/osmparser.c: Fix some memory leaks. * src/tagmodifier.c, xml/osm.xsd, xml/routino-osm.xsd, src/osmparser.c: Add the 'bound' element to the XML parser. 2010-05-22 Andrew M. Bishop <amb> * src/functionsx.h, src/osmparser.c, src/planetsplitter.c, src/ways.h, src/waysx.c, src/waysx.h: Remove the --transport=<transport>, --not-highway=<highway> and --not-property=<property> options from planetsplitter because they can be done by the tagging.xml file now. 2010-05-18 Andrew M. Bishop <amb> * src/Makefile: Add tagmodifier program. * src/xmlparse.l: Handle floating point numbers in scientific notation. * src/planetsplitter.c: Read in the tag transformation rules before calling the OSM parser. * src/functionsx.h, src/osmparser.c: Almost completely re-written OSM parser using tagging transformations. * src/tagmodifier.c, src/tagging.h, src/tagging.c: New file. * xml/Makefile: Copy the tagging rules to the web directory. * xml/routino-tagging.xml, xml/routino-tagging.xsd, xml/routino-osm.xsd: New file. * xml/osm.xsd: Small fix for OSM schema. 2010-05-14 Andrew M. Bishop <amb> * src/types.c: Remove highway type aliases from HighwayType() function. * src/xmlparse.h, src/xmlparse.l: Allow empty strings to be returned. 2010-05-10 Andrew M. Bishop <amb> * src/xmlparse.h, src/xmlparse.l: The line number is now a long integer. * src/xml/Makefile: Running 'make test' now compiles everything first. 2010-04-28 Andrew M. Bishop <amb> * src/xml/Makefile: Delete zero length file if xsd-to-xmlparser fails. * src/nodes.c, src/nodesx.c, src/segments.c, src/segmentsx.c, src/ways.c, src/waysx.c: Change file format to allow 64-bit off_t type with 32 bit void* type. * src/Makefile, src/filedumper.c, src/xml/Makefile: Compile with _FILE_OFFSET_BITS=64 to get 64-bit fopen() and stat(). 2010-04-27 Andrew M. Bishop <amb> * src/output.c: Fix mistake of writing GPX information to wrong file. * doc/OUTPUT.txt, doc/CONFIGURATION.txt: New file. * doc/TAGGING.txt, doc/USAGE.txt, doc/ALGORITHM.txt, doc/INSTALL.txt, doc/NEWS.txt, doc/README.txt: Interim checkin of updated documentation. 2010-04-24 Andrew M. Bishop <amb> * src/router.c: Merged the three functions to output the head/body/tail of the results back into a single function. Added the '--output-none' option. * src/functions.h, src/output.c: Merged the three functions to output the head/body/tail of the results back into a single function. * xml/routino-translations.xml, xml/routino-translations.xsd, src/output.c, src/translations.c, src/translations.h: Added translations for the HTML output. * src/xmlparse.h, src/xmlparse.l: Changed functions from const. * src/output.c: Add the copyright information into the translations.xml file instead of the separate copyright.txt file. Add the translated copyright strings into the outputs. * src/functions.h, src/router.c, src/translations.c, src/translations.h: Add the copyright information into the translations.xml file instead of the separate copyright.txt file. * src/xmlparse.h, src/xmlparse.l: Add an option to not convert the XML strings into decoded representations (saves converting them back later for the translated strings). 2010-04-23 Andrew M. Bishop <amb> * src/xml/xsd-to-xmlparser.c, src/translations.c, src/xmlparse.h, src/xmlparse.l, src/profiles.c: Pass the tag name to the tag function. 2010-04-22 Andrew M. Bishop <amb> * Makefile: Fix bug in makefile. * xml/Makefile: Move the translations into the web directory. * xml/routino-translations.xml, xml/routino-translations.xsd: New file. * src/output.c: Changed HTML output to be useful in web pages. * src/xmlparse.l: Restart properly so that a different file can be read. 2010-04-13 Andrew M. Bishop <amb> * src/xml/xsd-to-xmlparser.c, src/profiles.c, src/translations.c: Name the tag variables and functions after the XSD data type and not the tag name that uses it. 2010-04-12 Andrew M. Bishop <amb> * src/profiles.c, src/translations.c, src/xmlparse.h, src/xmlparse.l, src/xml/xsd-to-xmlparser.c, src/xml/Makefile: Change the last parameter to the ParseXML function to be general options. * src/Makefile, src/types.h, src/ways.c, src/ways.h: Move the type checking/printing functions from way.c to type.c. * src/types.c: New file. 2010-04-11 Andrew M. Bishop <amb> * src/xml/xsd-to-xmlparser.c, src/profiles.c, src/translations.c, src/xmlparse.h, src/xmlparse.l: Added helper functions for parsing strings into numbers. Added macros to perform common error checking. Change XML parser callback functions to return an error status. 2010-04-10 Andrew M. Bishop <amb> * src/router.c: Fix usage information. * src/translations.h, src/translations.c: New file. * src/output.c: Added translations for GPX and turn/heading. * src/Makefile, src/router.c: Added file of translations and language selection. 2010-04-09 Andrew M. Bishop <amb> * src/functions.h, src/planetsplitter.c, src/sorting.c: Add an option '--sort-ram-size' to specify the RAM to use for sorting - defaults to 256MB if not using slim mode. 2010-04-08 Andrew M. Bishop <amb> * src/xml/Makefile: Fix test program generation and running. * src/xmlparse.h, src/xmlparse.l: Make the strings const and add the number of attributes to the xmltag structure. Add functions to convert character entities and character references. * src/profiles.c, src/xml/xsd-to-xmlparser.c: Make the strings const and add the number of attributes to the xmltag structure. 2010-04-07 Andrew M. Bishop <amb> * xml/Makefile: New file. 2010-04-06 Andrew M. Bishop <amb> * src/Makefile: Remove special lex/flex flags. Remove profiles.o from planetsplitter. * src/xml/xsd-to-xmlparser.c: Don't print anything for attributes that are not set. * src/xmlparse.l: Change error message for bad character in a quoted string. Make sure attribute values are cleared before calling tag function (for end-tags). 2010-04-04 Andrew M. Bishop <amb> * src/xml/Makefile: Add some XML parsing test cases. * src/xml/xsd-to-xmlparser.c: Rename the XML handling function. * src/xmlparse.h, src/xmlparse.l, src/profiles.c: Added error checking. 2010-04-03 Andrew M. Bishop <amb> * src/functionsx.h, src/osmparser.c, src/planetsplitter.c: Rename the old ParseXML() function as ParseOSM(). 2010-04-01 Andrew M. Bishop <amb> * src/output.c: Wrap GPX descriptions in CDATA. 2010-03-31 Andrew M. Bishop <amb> * xml/routino-profiles.xml: New file. * src/xml/xsd-to-xmlparser.c, src/profiles.c, src/xmlparse.h, src/xmlparse.l: Call the XML tag functions for the end tags as well as the start tags. 2010-03-30 Andrew M. Bishop <amb> * src/profiles.c, src/profiles.h: Change the name of the --profile-json and --profile-perl options. * src/filedumper.c, src/planetsplitter.c, src/router.c: Improve the program help messages. 2010-03-29 Andrew M. Bishop <amb> * src/files.c, src/functions.h, src/profiles.c, src/profiles.h, src/router.c: Added command line option to specify a file containing profiles. Added command line option to select profile by name from loaded set. Use XML parser to read in the profiles. * src/Makefile: Better handling of the xml sub-directory. * src/xml/xsd-to-xmlparser.c: Add the option to ignore unknown attributes. Print out the skeleton file using static functions and variables. * src/xml/Makefile: Keep the intermediate files. * src/xmlparse.h, src/xmlparse.l: Add the option to ignore unknown attributes. 2010-03-28 Andrew M. Bishop <amb> * src/profiles.h, src/router.c, src/profiles.c: Add an option to print out the profiles as XML format. * src/xmlparse.h, xml/xsd.xsd, xml/osm.xsd, src/xml/xsd-to-xmlparser.c: New file. * src/Makefile: Added the XML subdirectory and xmlparser.c. * src/xmlparse.l, src/xml/Makefile: New file. 2010-03-20 Andrew M. Bishop <amb> * src/output.c: Add descriptions to each point in the GPX route file. * src/files.c, src/functions.h, src/nodesx.c, src/output.c, src/segmentsx.c, src/waysx.c: Move the stat() calls to find a file size into a helper function in files.c. * src/files.c, src/output.c, src/planetsplitter.c: Improve the error messages by adding strerror() to them. * src/filedumper.c, src/router.c: Don't check the return value of the functions to load the nodes, segments and ways because those functions will exit in case of an error. * src/nodes.c, src/segments.c, src/ways.c: Don't check the return value of MapFile() because it will exit in case of an error. * src/planetsplitter.c: Allow filenames on the planetsplitter command line. 2010-03-19 Andrew M. Bishop <amb> * src/waysx.h, src/filedumper.c, src/files.c, src/functions.h, src/nodesx.c, src/nodesx.h, src/planetsplitter.c, src/segmentsx.c, src/segmentsx.h, src/superx.c, src/waysx.c: Allow planetsplitter to be run with a --parse-only or --process-only option and append to existing file or read from existing file. 2010-03-18 Andrew M. Bishop <amb> * src/router.c: Fix usage message error and shuffle order. * src/output.c, src/router.c: Allow selection of which outputs are to be created. 2010-03-17 Andrew M. Bishop <amb> * src/output.c: Re-order the code for HTML. 2010-03-15 Andrew M. Bishop <amb> * src/output.c: Create a simple HTML output. 2010-03-06 Andrew M. Bishop <amb> * src/router.c, src/nodes.c: Speed up start/via/stop point search algorithm. 2010-03-05 Andrew M. Bishop <amb> * src/profiles.c: Change the format of the output for the --help-profile-{pl|js} options. 2010-01-21 Andrew M. Bishop <amb> Version 1.3 released 2010-01-21 Andrew M. Bishop <amb> * doc/NEWS.txt: Update to latest news. 2010-01-18 Andrew M. Bishop <amb> * doc/USAGE.txt, doc/TAGGING.txt, doc/INSTALL.txt: Updated documentation. 2010-01-15 Andrew M. Bishop <amb> * src/router.c, src/functions.h: Change the test output formats to add turn, node type and bearing information. 2010-01-13 Andrew M. Bishop <amb> * src/output.c: Change the test output formats to add turn, node type and bearing information. 2009-12-16 Andrew M. Bishop <amb> * src/router.c: Added an option to use only nodes and not interpolate a point into a segment. 2009-12-15 Andrew M. Bishop <amb> * src/osmparser.c, src/profiles.c, src/types.h, src/ways.c: Added wheelchair as type of transport. 2009-12-13 Andrew M. Bishop <amb> * src/osmparser.c, src/profiles.c, src/types.h, src/ways.c: Add bridge and tunnel to highway properties. 2009-12-12 Andrew M. Bishop <amb> * src/Makefile: Ignore the error if executables cannot be copied after compiling. * src/functions.h, src/nodesx.c, src/segmentsx.c, src/sorting.c, src/waysx.c: Add some FILESORT_* #defines and use them. 2009-12-11 Andrew M. Bishop <amb> * src/functions.h, src/nodesx.c, src/planetsplitter.c, src/segmentsx.c, src/sorting.c, src/waysx.c, src/waysx.h: Added a new function to sort variable length data - simplifies the compacting of ways, reduces memory usage potentially required for it and simplifies the code. 2009-12-10 Andrew M. Bishop <amb> * src/waysx.c: Write out the list of ways without memory mapping anything. 2009-11-27 Andrew M. Bishop <amb> * src/osmparser.c, src/profiles.c, src/types.h, src/ways.c: Add in "multilane" as a new highway property. 2009-11-25 Andrew M. Bishop <amb> * src/filedumper.c, src/optimiser.c, src/osmparser.c, src/planetsplitter.c, src/profiles.h, src/router.c, src/ways.h, src/waysx.c, src/waysx.h: Store the selected options when parsing (planetsplitter) and display them in the statistics (filedumper) and check them when routing (router). 2009-11-23 Andrew M. Bishop <amb> * src/osmparser.c, src/output.c, src/profiles.c, src/types.h, src/ways.c: Add in "steps" as a new highway type. 2009-11-19 Andrew M. Bishop <amb> * src/optimiser.c, src/router.c: Made the verbose output consistent between different places. 2009-11-18 Andrew M. Bishop <amb> * src/router.c: Fix bug with previous segment-splitting routing. 2009-11-14 Andrew M. Bishop <amb> * src/optimiser.c, src/output.c, src/router.c, src/segments.h, src/functions.h, src/nodes.c, src/nodes.h: If a selected waypoint is not very close to an existing node then insert a fake node in the segment that comes closest and use that instead. 2009-11-13 Andrew M. Bishop <amb> * src/optimiser.c, src/osmparser.c, src/queue.c, src/results.c, src/results.h, src/types.h: Added in some more constants with the value ~0. 2009-11-06 Andrew M. Bishop <amb> * src/filedumper.c: Check the values for the --node=, --segment= and --way= options. 2009-11-03 Andrew M. Bishop <amb> * src/output.c, src/planetsplitter.c, src/profiles.c, src/profiles.h, src/router.c, src/types.h, src/ways.c: Rename Way_Unknown to Way_Count to make more sense and match the properties. 2009-11-02 Andrew M. Bishop <amb> * src/osmparser.c: Allow the tag "paved" as well as "surface=paved". * src/filedumper.c, src/optimiser.c, src/osmparser.c, src/planetsplitter.c, src/profiles.c, src/profiles.h, src/router.c, src/types.h, src/ways.c, src/ways.h: Added the ability to set routing preferences using highway properties. Initially the only choice is either paved or unpaved but the code has been updated to allow any number of properties to be added. 2009-10-27 Andrew M. Bishop <amb> * src/osmparser.c: Handle the "designation=..." tag for bridleway, byway and footpath. (Also change to using a macro for testing if access is allowed and now allow "destination"). * src/osmparser.c, src/profiles.c, src/types.h, src/ways.c, src/ways.h: Added Moped to the list of transports (and incidentally increased the transport data type to 16 bits and re-ordered the Way data-type in response). 2009-10-26 Andrew M. Bishop <amb> * src/profiles.c: Ensure that horses and bicycles have a default speed on trunk even though they have a default preference not to use it. * src/osmparser.c, src/profiles.c, src/types.h, src/ways.c: Re-ordered the types so that Horse comes before Bicycle. * src/osmparser.c, src/output.c, src/profiles.c, src/types.h, src/ways.c: Remove the Bridleway and Footway highway types and use the Path type instead (also re-ordered the types so that Cycleway comes before Path). * src/profiles.c: Remove unneeded spaces at the end of the output. 2009-10-25 Andrew M. Bishop <amb> * src/output.c: Fix bug in code that determines waypoints for abbreviated output. 2009-10-24 Andrew M. Bishop <amb> * src/functions.h, src/optimiser.c, src/router.c: Fix missing segments in output if start and finish points are found by the start search. 2009-10-22 Andrew M. Bishop <amb> * src/files.c, src/nodesx.c, src/segmentsx.c, src/sorting.c, src/superx.c, src/waysx.c: Added some missing comments and corrected some existing ones. 2009-10-21 Andrew M. Bishop <amb> Version 1.2 released 2009-10-21 Andrew M. Bishop <amb> * doc/README.txt, doc/USAGE.txt, doc/NEWS.txt: Updated for version 1.2. 2009-10-20 Andrew M. Bishop <amb> * src/Makefile: Add sorting.o to the Makefile. 2009-10-12 Andrew M. Bishop <amb> * src/waysx.c: When sorting we cannot have NULL pointers now. * src/nodesx.c, src/segmentsx.c, src/waysx.c: Re-order the functions in the file into a more logical order. No functional changes. * src/nodesx.c, src/planetsplitter.c, src/segmentsx.c, src/sorting.c, src/waysx.c: Rename the tmpdirname variable. 2009-10-10 Andrew M. Bishop <amb> * src/nodesx.c, src/osmparser.c, src/segmentsx.c, src/sorting.c, src/waysx.c: Corrections after running with valgrind. * src/planetsplitter.c: Fix early termination test. * src/nodesx.c, src/nodesx.h, src/segmentsx.c: Remove the nodesx->gdata index. 2009-10-09 Andrew M. Bishop <amb> * src/nodesx.c, src/segmentsx.c, src/typesx.h, src/waysx.c, src/waysx.h: Free the nodesx->super array and the segmentsx->firstnode array when finished with them. Remove wayx->cid and overwrite wayx->id instead. Overwrite nodex[i]->id=i for later geographically sorted use. 2009-10-08 Andrew M. Bishop <amb> * src/nodesx.c, src/planetsplitter.c, src/segmentsx.c, src/segmentsx.h, src/superx.c: Replace node, segment and way indexes with a single index for a set of segments containing the location of the first segment for each node. * src/nodesx.h: Fix comment. 2009-10-07 Andrew M. Bishop <amb> * src/osmparser.c, src/segmentsx.c, src/superx.c: AppendSegment adds a single segment and not a pair. * src/waysx.c: Use heapsort() instead of qsort(). * src/nodesx.c, src/nodesx.h, src/planetsplitter.c, src/segmentsx.c, src/segmentsx.h, src/superx.c, src/waysx.c: Go back to the version 1.1 method of having each segment listed twice. This simplifies the lookup of first/next segments at no in-RAM index cost and now that slim mode has sorting of file contents the balance has tipped back. 2009-10-04 Andrew M. Bishop <amb> * src/functions.h, src/sorting.c: Change the sort function to allow the indexing callback to veto the write. * src/nodesx.c: Remove the duplicates when sorting. * src/waysx.c: Sort the ways using the same method as the nodes. Also remove the duplicates. * src/nodesx.c: Use the new sort functions to allow sorting the data in the file without needing to read (or mmap) the whole file into RAM at the same time. * src/functions.h: Add some functions to perform sorting. * src/sorting.c: New file. * src/queue.c: Fix bug with binary heap sort. 2009-09-25 Andrew M. Bishop <amb> * src/queue.c: Add comments describing the algorithm used. 2009-09-23 Andrew M. Bishop <amb> * src/nodesx.c, src/waysx.c: Simplify the de-duplication when sorting and update some comments. 2009-09-22 Andrew M. Bishop <amb> * src/nodesx.c, src/nodesx.h: Remove a leftover from the last change on these files. * src/segmentsx.c: Improve the super-segment de-duplication. 2009-09-21 Andrew M. Bishop <amb> * src/nodesx.c, src/nodesx.h, src/planetsplitter.c: Remove the non-highway nodes without re-sorting the whole list again. 2009-09-17 Andrew M. Bishop <amb> * src/osmparser.c, src/planetsplitter.c, src/segmentsx.c, src/superx.c, src/waysx.c, src/waysx.h: Added the slim mode to Ways as well. * src/ways.h: Add padding to Ways structure to allow it to be zeroed. * src/nodesx.c: Add some comments when closing and re-opening files. * src/files.c, src/functions.h: The WriteFile function now has a const parameter. 2009-09-15 Andrew M. Bishop <amb> * src/nodesx.c, src/nodesx.h, src/planetsplitter.c, src/segmentsx.c: Some bug fixes and some missing unmap function calls. 2009-09-07 Andrew M. Bishop <amb> * src/segmentsx.h, src/superx.c, src/nodesx.c, src/nodesx.h, src/segmentsx.c: Fixed slim mode for segments and nodes (slim now means mapping only one file into RAM at a time and none when creating the final output). 2009-09-06 Andrew M. Bishop <amb> * src/nodesx.h, src/planetsplitter.c, src/segmentsx.c, src/segmentsx.h, src/superx.c, src/superx.h, src/nodesx.c: Slim version of segments code (still very slow and only works on simple cases). * src/files.c, src/functions.h: Remove the delete option from UnmapFile() and make it return NULL. * src/filedumper.c: Allow dumping all nodes, segments or ways. 2009-09-05 Andrew M. Bishop <amb> * src/nodesx.c: Don't re-sort unnecessarily. * src/nodesx.c, src/nodesx.h, src/planetsplitter.c, src/segmentsx.c, src/superx.c: Improve slim mode for nodes so that no data is not loaded into RAM at all. * src/files.c, src/functions.h: Add some more file functions. 2009-09-03 Andrew M. Bishop <amb> * src/nodesx.c, src/files.c, src/functions.h: Remove extra argument from MapFile function. * src/nodesx.c, src/nodesx.h, src/planetsplitter.c, src/segmentsx.c, src/superx.c: Added slim mode (--slim) to planetsplitter for nodes only. * src/files.c, src/functions.h: Changes to mapping and unmapping files for slim mode. 2009-08-25 Andrew M. Bishop <amb> * src/planetsplitter.c: Revert the order that the functions are called. * src/nodesx.c: Fix for assert statement. * src/files.c: Bug fix for mmap(). 2009-08-20 Andrew M. Bishop <amb> * src/osmparser.c: Fix bug with memory allocation. 2009-08-19 Andrew M. Bishop <amb> * src/nodesx.c, src/nodesx.h, src/planetsplitter.c, src/segmentsx.c, src/segmentsx.h, src/superx.c, src/waysx.c, src/waysx.h: Remove "sorted" parameter in data structure and change assert statements. 2009-08-17 Andrew M. Bishop <amb> * src/router.c: Increase to 99 the number of waypoints that can be specified. 2009-08-15 Andrew M. Bishop <amb> * src/queue.c: Fix comment. * src/Makefile: Tidy the compilation options to make it easier to turn them on and off. * src/router.c: Remove the --all, --super and --no-output command line options. Handle the renamed routing functions. * src/functions.h, src/optimiser.c: Rename the routing functions and make FindRoute only find routes with no super-nodes in them. * src/queue.c: When popping from queue make sure that place in queue is cleared. * src/optimiser.c, src/queue.c, src/results.c, src/results.h, src/superx.c: Optimise the priority queue used for routing. * src/filedumper.c: Fix dumping nodes when they are super-nodes. 2009-07-23 Andrew M. Bishop <amb> * src/Makefile, src/optimiser.c, src/results.c, src/results.h, src/superx.c: Split off queue functions into a separate file. * src/queue.c: New file. 2009-07-19 Andrew M. Bishop <amb> * src/nodesx.c, src/segments.h, src/segmentsx.c, src/ways.h, src/waysx.c, src/filedumper.c, src/nodes.h: Include the number of super-nodes, super-segments etc in the database as useful information to put in the statistics output. * src/superx.c: Fix incorrect progress indicator message. * src/waysx.c: Fix problem with memory reallocation. * src/nodesx.c, src/osmparser.c, src/planetsplitter.c, src/segmentsx.c, src/segmentsx.h, src/superx.c: Store only one copy of each segment but index once for each direction. 2009-07-12 Andrew M. Bishop <amb> * src/functionsx.h, src/nodesx.c, src/nodesx.h, src/osmparser.c, src/output.c, src/planetsplitter.c, src/profiles.c, src/results.c, src/segments.c, src/segmentsx.c, src/segmentsx.h, src/superx.c, src/superx.h, src/ways.h, src/waysx.c, src/waysx.h: Tidy up and fix comments and include files. * src/osmparser.c, src/planetsplitter.c, src/router.c, src/segmentsx.c, src/superx.c, src/waysx.c, src/filedumper.c, src/nodesx.c, src/optimiser.c: Check all print statements and made them more consistent and/or accurate. 2009-07-11 Andrew M. Bishop <amb> * src/nodesx.c, src/nodesx.h, src/planetsplitter.c, src/segmentsx.c, src/waysx.c, src/waysx.h: Free memory at the end of planetsplitter (to aid finding potential leaks earlier). 2009-07-09 Andrew M. Bishop <amb> * src/segmentsx.c: Free memory correctly (really). * src/planetsplitter.c, src/waysx.c, src/waysx.h: Separate the sorting of Ways from compacting of Ways. * src/nodes.h, src/nodesx.c, src/nodesx.h, src/segmentsx.c, src/visualiser.c, src/filedumper.c, src/nodes.c: Rename structure members after recent changes. * src/segmentsx.c: Free memory correctly. * src/types.h, src/segmentsx.c: Fix duplicate checking. * src/planetsplitter.c: Ensure that variable is reset before using it. * src/types.h, src/visualiser.c, src/visualiser.h, src/filedumper.c, src/nodes.c, src/nodes.h, src/nodesx.c, src/nodesx.h, src/optimiser.c, src/osmparser.c, src/output.c, src/router.c, src/segments.c, src/segments.h, src/segmentsx.c: Change from float to double for latitude and longitude. Store latitude and longitude as an integer type rather than float (higher precision). 2009-07-08 Andrew M. Bishop <amb> * src/superx.c: Ensure that variable is reset before using it. 2009-07-06 Andrew M. Bishop <amb> * src/visualiser.c: Print all super-segments within and crossing the border. Don't display speed limits for tracks and paths unless set. 2009-07-04 Andrew M. Bishop <amb> * src/segmentsx.h, src/superx.c, src/waysx.c, src/waysx.h: Change data structure to avoid calling realloc() each time to allocate more memory. 2009-07-02 Andrew M. Bishop <amb> * src/types.h, src/waysx.c, src/waysx.h: Handle duplicate ways. * src/nodes.c, src/nodesx.c, src/planetsplitter.c, src/profiles.c, src/results.c, src/segments.c, src/segmentsx.c, src/superx.c, src/superx.h, src/types.h, src/ways.c, src/waysx.c: Fix some gcc pedantic warnings. * src/files.c, src/nodesx.c, src/osmparser.c, src/results.c, src/router.c, src/segments.c, src/segmentsx.c, src/superx.c, src/ways.c, src/waysx.c: Removed unused header files, change assert statements, tidy some code. 2009-07-01 Andrew M. Bishop <amb> * src/nodesx.c, src/nodesx.h, src/planetsplitter.c, src/segmentsx.c, src/segmentsx.h, src/superx.c: Remove the Node structure from the NodeX structure to save memory. * src/filedumper.c: Print latitude and longitude in degrees. 2009-06-30 Andrew M. Bishop <amb> * src/segmentsx.h: Re-order the data in the structure. * src/nodesx.c, src/nodesx.h, src/osmparser.c, src/planetsplitter.c, src/segmentsx.c, src/segmentsx.h, src/superx.c, src/waysx.h: Remove the Segment structure from the SegmentX structure to save memory. 2009-06-29 Andrew M. Bishop <amb> * src/filedumper.c, src/nodes.h, src/nodesx.c, src/segments.c, src/segments.h, src/segmentsx.c, src/superx.c, src/types.h: Move the super-segment and normal-segment flags from the nodes to the distance. Remove the NODE() macro and rename SUPER_FLAG to NODE_SUPER. * src/waysx.c: Replace memmove with structure copy. * src/nodesx.c, src/segmentsx.c, src/segmentsx.h, src/superx.c: Rename SegmentsX sdata to ndata. 2009-06-25 Andrew M. Bishop <amb> * src/waysx.c, src/waysx.h: Rename part of the structure. * src/nodesx.c, src/nodesx.h, src/planetsplitter.c, src/segmentsx.c, src/segmentsx.h, src/superx.c, src/waysx.h: Undo part of the previous change - only update the Segment way index at the end. * src/waysx.h, src/nodesx.c, src/osmparser.c, src/planetsplitter.c, src/segmentsx.c, src/segmentsx.h, src/superx.c, src/superx.h, src/typesx.h, src/waysx.c: Reduce the number of ways in the output by compacting them (sharing the same information between identical ways). 2009-06-24 Andrew M. Bishop <amb> * src/filedumper.c, src/nodes.h: Allow dumping out of nodes, segments and ways. 2009-06-15 Andrew M. Bishop <amb> * src/segmentsx.c, src/superx.c, src/visualiser.c, src/ways.c, src/ways.h: Rename WaysSame() with WaysCompare() and reverse the sense of the output. * src/functionsx.h, src/typesx.h: New file. * src/functions.h, src/nodesx.h, src/osmparser.c, src/planetsplitter.c, src/segmentsx.h, src/superx.h, src/types.h, src/waysx.h: Put some of types.h into typesx.h (for extended data types). Put some of functions.h into functionsx.h (for OSM parser). Change included files to match. * src/filedumper.c, src/osmparser.c, src/output.c, src/router.c, src/types.h, src/visualiser.c: Add a macro for converting degrees to radians and radians to degrees. * src/optimiser.c: Fix weight, height, width, length restriction routing. * doc/TAGGING.txt, src/osmparser.c: Recognise tags "vehicle" and "motor_vehicle". 2009-06-13 Andrew M. Bishop <amb> Version 1.1 released 2009-06-13 Andrew M. Bishop <amb> * src/nodesx.c, src/planetsplitter.c, src/segmentsx.c, src/segmentsx.h: Handle nodes that are missing from the .osm file (ignore the segment). * src/nodesx.c: Revert the last change (Print an error message and exit if a node cannot be found). * doc/NEWS.txt: New file. * src/Makefile: Delete the executables from the web directory for 'distclean'. 2009-06-12 Andrew M. Bishop <amb> * doc/USAGE.txt, doc/INSTALL.txt, doc/README.txt: Update the documentation. * src/Makefile: Copy the executables into the web directory. 2009-06-08 Andrew M. Bishop <amb> * src/filedumper.c: Change help text. * src/visualiser.c: Change format of super-node/segment visualiser output. 2009-06-07 Andrew M. Bishop <amb> * doc/TAGGING.txt: Updated with imperial to metric conversions. * src/Makefile: Added visualiser.c. * src/filedumper.c: Now used for data visualisation and statistics. * src/visualiser.h, src/visualiser.c: New file. 2009-06-05 Andrew M. Bishop <amb> * src/osmparser.c: Improve parsing of imperial units (mph, feet & inches). 2009-06-03 Andrew M. Bishop <amb> * src/nodesx.c: Print an error message and exit if a node cannot be found. 2009-05-31 Andrew M. Bishop <amb> * src/ways.c, src/ways.h, src/waysx.c, src/waysx.h: Move function from waysx.c to ways.c. 2009-05-29 Andrew M. Bishop <amb> * doc/USAGE.txt: Update usage information with new options and copyright.txt usage. * src/nodes.c, src/nodes.h, src/router.c: Make sure that the chosen "nearest point" is a highway that the profile allows. 2009-05-23 Andrew M. Bishop <amb> * src/profiles.c: Change the default profile; horses are slower, bicycles may be allowed on footways (and similar). 2009-05-15 Andrew M. Bishop <amb> * src/files.c, src/output.c: Error checking on opening files (to read/write data and to write output). 2009-05-14 Andrew M. Bishop <amb> * src/output.c, src/results.c, src/router.c, src/segments.c, src/segmentsx.c, src/superx.c, src/types.h, src/nodes.c, src/nodesx.c, src/optimiser.c: Replace ~0 or 0 with NO_NODE value for "no node" condition. 2009-05-13 Andrew M. Bishop <amb> * src/output.c: Remove one more NODE macro and fix an output formatting error. * src/nodes.c, src/nodes.h, src/optimiser.c, src/output.c, src/router.c: Remove some node macros, change some node function arguments. * src/optimiser.c, src/profiles.c, src/profiles.h: Move some common code into the profile. * src/superx.c: Remove distance and duration from Result structure. * src/output.c: Better junction detection. * src/optimiser.c, src/results.c, src/results.h: Remove distance and duration from Result structure. 2009-05-09 Andrew M. Bishop <amb> * src/output.c: Add better junction detection for deciding on route waypoints. 2009-05-06 Andrew M. Bishop <amb> * src/optimiser.c, src/profiles.c, src/profiles.h, src/types.h: Route using preferences for each highway. * src/router.c: Print out longitude then latitude. 2009-04-30 Andrew M. Bishop <amb> * src/results.h, src/router.c, src/superx.c, src/types.h, src/optimiser.c, src/osmparser.c, src/planetsplitter.c, src/profiles.c, src/profiles.h, src/results.c: First attempt at preferences for highways - uses integer arithmetic and doesn't work well. 2009-04-27 Andrew M. Bishop <amb> * src/functions.h, src/optimiser.c, src/output.c, src/results.c, src/results.h, src/router.c: Allow generating a route with intermediate waypoints. 2009-04-24 Andrew M. Bishop <amb> * src/functions.h, src/output.c, src/router.c: Split the output functions into separate head/body/tail. Read in an optional copyright.txt file and include contents in output. 2009-04-23 Andrew M. Bishop <amb> * src/profiles.c: Improve Javascript and perl print out. * src/filedumper.c, src/files.c, src/functions.h, src/planetsplitter.c, src/router.c: Move the filename generation to a new function. 2009-04-22 Andrew M. Bishop <amb> * src/Makefile, src/functions.h, src/optimiser.c: Split the function to print the output into a new file. * src/output.c: New file. 2009-04-15 Andrew M. Bishop <amb> * src/osmparser.c: Fix for parsing nodes from XML (no effect on results). 2009-04-12 Andrew M. Bishop <amb> * doc/USAGE.txt, src/optimiser.c: Create a GPX route as well as a track. * src/ways.c: Changed the license to Affero GPLv3. 2009-04-10 Andrew M. Bishop <amb> * src/optimiser.c: Add a waypoint to the GPX file for the start and finish points. * doc/USAGE.txt: Include more information about the output file formats. 2009-04-08 Andrew M. Bishop <amb> Version 1.0 released 2009-04-08 Andrew M. Bishop <amb> * Makefile: New file. * src/Makefile: Fix dependency file generation. * doc/USAGE.txt, doc/TAGGING.txt, doc/README.txt, doc/INSTALL.txt, doc/ALGORITHM.txt: New file. * src/Makefile, src/filedumper.c, src/files.c, src/functions.h, src/nodes.c, src/nodes.h, src/nodesx.c, src/nodesx.h, src/optimiser.c, src/osmparser.c, src/planetsplitter.c, src/profiles.c, src/profiles.h, src/results.c, src/results.h, src/router.c, src/segments.c, src/segments.h, src/segmentsx.c, src/segmentsx.h, src/superx.c, src/superx.h, src/types.h, src/ways.h, src/waysx.c, src/waysx.h: Changed the license to Affero GPLv3. 2009-04-07 Andrew M. Bishop <amb> * src/planetsplitter.c: Remove the --help-profile command line option. 2009-03-28 Andrew M. Bishop <amb> * src/optimiser.c: Fix file headers (again) and fix segment distance/duration for abbreviated text output. 2009-03-24 Andrew M. Bishop <amb> * src/osmparser.c, src/profiles.c, src/types.h, src/ways.c: Added highway=path; defaults to foot=yes but also is defaulted for bicycle and horse transport. 2009-03-23 Andrew M. Bishop <amb> * src/optimiser.c: Fixed the header in the output text files. * src/osmparser.c: Add parsing for *=designated allowing passage along a highway. * src/profiles.h, src/router.c, src/profiles.c: Add a function to output default profiles as perl data structures. 2009-03-21 Andrew M. Bishop <amb> * src/nodesx.c: Handle duplicated nodes (e.g. from concatenated input files). * src/optimiser.c: Add a header to the output text files. 2009-03-07 Andrew M. Bishop <amb> * src/optimiser.c: Renamed the *.txt output to *-all.txt and added a new shorted *.txt output. * src/router.c: Renamed the --no-print option to --no-output. 2009-03-04 Andrew M. Bishop <amb> * src/nodes.c: Fix bug with finding nearest node. 2009-03-03 Andrew M. Bishop <amb> * src/superx.c: Fix the merging of super-segments. 2009-03-01 Andrew M. Bishop <amb> * src/profiles.c, src/profiles.h: Added more limits (weight, height, width, length). * src/segments.c: Use the lower speed from the profile and the way. * src/osmparser.c: Added more limits (weight, height, width, length). Added highway=living_street and highway=services. * src/ways.c, src/ways.h, src/optimiser.c, src/router.c, src/segmentsx.c, src/superx.c, src/types.h: Added more limits (weight, height, width, length). * src/waysx.c, src/waysx.h: Added a function to test if two ways are the same. 2009-02-28 Andrew M. Bishop <amb> * src/nodesx.c: Round the node location to avoid if falling into the wrong bin. * src/nodesx.c, src/planetsplitter.c, src/segmentsx.c, src/waysx.c: Move print statements from planetsplitter into individual functions. * src/Makefile: Compile with optimisation and no profiling. * src/profiles.c, src/router.c: Add new command line options to make it more CGI friendly. 2009-02-27 Andrew M. Bishop <amb> * src/profiles.c, src/profiles.h, src/router.c: Print out Javascript code containing the profiles. 2009-02-24 Andrew M. Bishop <amb> * src/segmentsx.h, src/superx.c, src/nodesx.c, src/segments.c, src/segments.h, src/segmentsx.c: Remove segment->next1 since it always points at the next segment or nowhere. * src/profiles.c: Remove track from valid types for most transports. 2009-02-15 Andrew M. Bishop <amb> * src/functions.h, src/optimiser.c, src/router.c: Change some function names. * src/osmparser.c: Add in tests for motorcar=1 etc. * src/nodes.c, src/nodes.h, src/router.c: The search to find a node given the lat/long now searches harder. * src/optimiser.c: Better test for failing to find a route. * src/router.c: Change --only-super to --super. * src/nodesx.c, src/optimiser.c, src/osmparser.c, src/router.c, src/segments.c, src/segmentsx.c, src/types.h, src/nodes.c: Store radians rather than degrees. * src/segments.c, src/segmentsx.c: Change to sinf(), cosf(), sqrtf(), asinf() functions. * src/optimiser.c: Set the sortby parameter to the minimum distance/duration consistent with the travelled distance/duration and the remaining straight line distance with the fastest possible speed. * src/filedumper.c, src/nodes.c, src/nodes.h, src/nodesx.c, src/types.h: Add macros for handling lat/long to bin conversions. * src/osmparser.c: Handle oneway=1 and oneway=-1. 2009-02-10 Andrew M. Bishop <amb> * src/results.c, src/results.h: Added a new 'sortby' entry to the Result. Changed node_t to index_t. * src/router.c: Changed node_t to index_t. * src/nodes.c, src/segments.c, src/segments.h: Change the Distance() function to return distance_t. 2009-02-08 Andrew M. Bishop <amb> * src/optimiser.c, src/results.c, src/results.h, src/router.c, src/superx.c: Calculate quickest or shortest, not both. * src/optimiser.c, src/profiles.c, src/router.c: Give appropriate error messages if start or end of route are not possible. 2009-02-07 Andrew M. Bishop <amb> * src/results.c: Slight speedup by doing a linear search when looking up results and not storing in sorted order. * src/superx.h, src/superx.c, src/waysx.h, src/waysx.c, src/segmentsx.h, src/segmentsx.c, src/nodesx.h, src/nodesx.c: New file. * src/ways.h, src/Makefile, src/filedumper.c, src/functions.h, src/nodes.c, src/nodes.h, src/optimiser.c, src/osmparser.c, src/planetsplitter.c, src/router.c, src/segments.c, src/segments.h, src/types.h, src/ways.c: Split the extended data types from the normal data types. * src/nodes.c: Return NULL if the node cannot be found. * src/Makefile, src/filedumper.c, src/optimiser.c, src/router.c: Add new command line options. * src/supersegments.c: Fix some status messages. * src/optimiser.c, src/types.h: Routing works with super-nodes now. 2009-02-06 Andrew M. Bishop <amb> * src/ways.c, src/segments.c, src/segments.h, src/supersegments.c, src/types.h, src/nodes.c, src/nodes.h, src/optimiser.c, src/osmparser.c, src/planetsplitter.c, src/functions.h: Segments now not duplicated in database. Routing with all nodes works, not with super-nodes. 2009-02-04 Andrew M. Bishop <amb> * src/router.c: Fix usage output. * src/ways.c, src/ways.h: Only sort once, don't store the index. * src/planetsplitter.c, src/router.c: Use '--*' command line arguments, not '-*'. * src/nodes.c, src/router.c, src/segments.c, src/ways.c: Make sure that nodes, segments and ways could be loaded. * src/nodes.h, src/optimiser.c, src/router.c, src/segments.c, src/segments.h, src/supersegments.c, src/types.h, src/filedumper.c, src/nodes.c: Sort the nodes geographically and take coordinates as command line arguments. 2009-02-02 Andrew M. Bishop <amb> * src/ways.c, src/ways.h, src/nodes.c, src/nodes.h, src/osmparser.c, src/segments.c, src/segments.h, src/supersegments.c, src/types.h: More variable and function name changes. 2009-02-01 Andrew M. Bishop <amb> * src/profiles.c, src/router.c, src/segments.c, src/segments.h, src/supersegments.c, src/ways.c, src/ways.h, src/files.c, src/functions.h, src/nodes.c, src/nodes.h, src/optimiser.c, src/osmparser.c, src/planetsplitter.c, src/filedumper.c: Rename some variable types. 2009-01-31 Andrew M. Bishop <amb> * src/segments.c, src/segments.h, src/supersegments.c, src/types.h, src/ways.c, src/ways.h, src/functions.h, src/nodes.c, src/nodes.h, src/optimiser.c, src/planetsplitter.c, src/profiles.h, src/router.c: Intermediate version during code cleanup. * src/optimiser.c, src/planetsplitter.c, src/router.c, src/segments.c, src/segments.h, src/functions.h, src/nodes.h: Intermediate checkin, routing now working. * src/Makefile: Don't print out anything when creating the dependencies directory. * src/planetsplitter.c, src/router.c: Add command line options to specify the directory and filename prefix. 2009-01-30 Andrew M. Bishop <amb> * src/results.c, src/planetsplitter.c: Remove gcc warning. * src/Makefile: Move dependencies to subdir. * src/osmparser.c: Remove gcc warning. 2009-01-29 Andrew M. Bishop <amb> * src/functions.h, src/nodes.c, src/nodes.h, src/optimiser.c, src/planetsplitter.c, src/router.c, src/segments.c, src/segments.h, src/supersegments.c: Intermediate version while transitioning data format for nodes and segments. 2009-01-28 Andrew M. Bishop <amb> * src/Makefile, src/functions.h, src/nodes.c, src/nodes.h, src/optimiser.c, src/osmparser.c, src/planetsplitter.c, src/segments.c, src/segments.h, src/supersegments.c, src/ways.c, src/ways.h: Intermediate version while transitioning data format for nodes and segments. 2009-01-27 Andrew M. Bishop <amb> * src/Makefile, src/functions.h, src/nodes.c, src/nodes.h, src/optimiser.c, src/planetsplitter.c, src/router.c, src/segments.c, src/segments.h, src/supersegments.c, src/ways.c, src/ways.h: Intermediate version while transitioning data format for nodes and segments. 2009-01-26 Andrew M. Bishop <amb> * src/osmparser.c, src/planetsplitter.c, src/segments.c, src/segments.h, src/supersegments.c, src/ways.c, src/ways.h, src/filedumper.c, src/files.c, src/functions.h, src/optimiser.c: Change Segment to contain index of way not its real ID. Don't store the real way ID to save space. 2009-01-25 Andrew M. Bishop <amb> * src/segments.c, src/segments.h: Slightly speed up the Duration calculation by changing the macro. * src/osmparser.c, src/profiles.c, src/ways.c, src/ways.h: Fix misspelling of Unclassified. * src/planetsplitter.c, src/segments.c, src/segments.h, src/supersegments.c, src/ways.h, src/optimiser.c: Change the segment->way so that it contains the index of the way, not the id. * src/profiles.c, src/profiles.h: New file. * src/ways.c, src/ways.h, src/Makefile, src/functions.h, src/optimiser.c, src/osmparser.c, src/planetsplitter.c, src/router.c, src/segments.c, src/segments.h: Added profiles to define speed and allowed highways. Added new options to planetsplitter and router to use the profiles. 2009-01-24 Andrew M. Bishop <amb> * src/optimiser.c: Changed some variable names for clarity. * src/planetsplitter.c: Print more information about progress. Don't quit until 99.9% unchanged. * src/optimiser.c, src/results.c, src/results.h, src/supersegments.c: Change the Results structure so that the real data doesn't need to be realloc(). Add functions to access the first and subsequent elements of the Results structure. 2009-01-23 Andrew M. Bishop <amb> * src/osmparser.c, src/planetsplitter.c: Fix bug with not specifying a method of transport. * src/optimiser.c, src/router.c: Proper check that it was unroutable. * src/functions.h, src/optimiser.c, src/planetsplitter.c, src/supersegments.c: Remove "iteration" as function argument. * src/functions.h, src/optimiser.c, src/osmparser.c, src/planetsplitter.c, src/router.c, src/ways.c, src/ways.h: Add command line options to planetsplitter and router. Select transport type (must be allowed on way for parsing). Select highway types (ignore when parsing or routing). * src/ways.h, src/functions.h, src/optimiser.c, src/osmparser.c, src/router.c, src/segments.c, src/segments.h, src/ways.c: Add enumerated type Transport. Replace variables of AllowType with Transport where more appropriate. Replace AllowType with Allowed. Replace WayType with Highway. * src/osmparser.c: Only include ways that are not Way_Unknown type. * src/osmparser.c: Include permissive access. * src/functions.h, src/optimiser.c, src/results.c, src/results.h, src/router.c: Create a large or small results structure depending on how many nodes are expected. 2009-01-22 Andrew M. Bishop <amb> * src/results.h: Increase the number of bins to 64k. * src/optimiser.c, src/osmparser.c, src/segments.c, src/segments.h, src/supersegments.c: Remove INVALID_DISTANCE and INVALID_DURATION. * src/optimiser.c, src/osmparser.c, src/supersegments.c, src/ways.c, src/ways.h: Removed the Way_TYPE() macro. * src/results.c, src/results.h, src/optimiser.c: Move queue functions into results.c. * src/filedumper.c, src/nodes.c, src/nodes.h, src/planetsplitter.c, src/router.c: Nodes, Segments, Ways - Nodes, Segments, Ways. * src/filedumper.c, src/nodes.c, src/nodes.h, src/segments.c, src/segments.h, src/ways.c, src/ways.h: Remove the choice of indexed or non-indexed data structures. 2009-01-21 Andrew M. Bishop <amb> * src/optimiser.c: Various small speed-ups including not-reversing direction. * src/functions.h, src/optimiser.c, src/osmparser.c, src/router.c, src/segments.c, src/segments.h, src/supersegments.c, src/ways.c, src/ways.h: Calculate way speeds at routing time. * src/supersegments.c: Add reverse-oneway segments when creating supernodes. Check incoming oneway streets as well as outgoing ones. * src/osmparser.c: Don't change speed on roundabouts. 2009-01-20 Andrew M. Bishop <amb> * src/planetsplitter.c: Add command line options for skipping parsing and iteration limit. * src/optimiser.c, src/osmparser.c, src/segments.c, src/segments.h, src/supersegments.c: Remove duration from segment, calculate duration depending on speed. 2009-01-19 Andrew M. Bishop <amb> * src/functions.h, src/optimiser.c, src/planetsplitter.c, src/supersegments.c: Iteratively calculate the super-segments. * src/ways.h: Redefine Way_TYPE() to include one-way status. 2009-01-18 Andrew M. Bishop <amb> * src/optimiser.c, src/supersegments.c: Fix problems with way-type matching and duplicated/missing super-segments. * src/functions.h, src/optimiser.c, src/router.c: Print out a GPX file. * src/optimiser.c, src/filedumper.c, src/functions.h, src/planetsplitter.c, src/router.c, src/segments.c, src/segments.h, src/supersegments.c, src/ways.c, src/ways.h: Added Super-Ways and allow user to select method of transport. * src/segments.c: Fix for changes made to ways. * src/supersegments.c: Ensure that supernodes are inserted wherever the way type changes. * src/osmparser.c: Fill in the extra way information. * src/ways.h: Store more information about a way (allowed modes of transport). * src/filedumper.c: Fix output printing. * src/router.c: Print an error if no route can be found. * src/optimiser.c: Fix bugs when start and/or finish nodes are supernodes. 2009-01-17 Andrew M. Bishop <amb> * src/Makefile: Add the option to create assembler output files. * src/optimiser.c, src/results.c, src/results.h, src/supersegments.c: Change the contents of the results data structure. * src/router.c: Added an option to not print the result. 2009-01-16 Andrew M. Bishop <amb> * src/optimiser.c, src/results.h, src/router.c: Speed optimisation by changing the contents of the Results structure. * src/optimiser.c: Don't bother calculating the distance to go, it takes too long. 2009-01-14 Andrew M. Bishop <amb> * src/planetsplitter.c: Remove bad segments and non-way nodes. * src/nodes.c, src/nodes.h: Remove nodes which are not in highways. Fix the sorting and create indexes after sorting, not before saving. * src/segments.c, src/segments.h: Remove bad segments (repeated consecutive nodes and duplicate segments). Fix the sorting and create indexes after sorting, not before saving. * src/supersegments.c: Use invalid distances properly. * src/ways.c: Fix the sort algorithm and update the indexes after sorting, not before saving. * src/optimiser.c: Fix the bug with merging the results. Fix the bug with not clearing the results structure properly. * src/osmparser.c: Add segments that correspond to the wrong way along one-way routes with an invalid distance. 2009-01-11 Andrew M. Bishop <amb> * src/functions.h, src/optimiser.c, src/router.c: Routes correctly using super-nodes (not Lands End to John O'Groats though). * src/filedumper.c, src/functions.h, src/optimiser.c, src/planetsplitter.c, src/router.c, src/segments.h, src/supersegments.c: Replace Junction with SuperNode. * src/nodes.c, src/nodes.h, src/segments.h, src/ways.c, src/ways.h: Some small changes to the nodes, segments and ways functions. * src/Makefile, src/filedumper.c, src/functions.h, src/optimiser.c, src/planetsplitter.c, src/results.h, src/router.c, src/segments.c, src/segments.h, src/supersegments.c: Working version with supersegments and junctions. 2009-01-10 Andrew M. Bishop <amb> * src/ways.c, src/ways.h, src/osmparser.c, src/segments.c: Store more information about ways. * src/results.h, src/results.c: New file. * src/Makefile, src/optimiser.c: Move the results data type into new files. * src/nodes.h, src/segments.h, src/ways.h: Increase the increment for the indexed array case. * src/ways.h, src/Makefile, src/filedumper.c, src/functions.h, src/nodes.c, src/nodes.h, src/optimiser.c, src/osmparser.c, src/planetsplitter.c, src/router.c, src/segments.c, src/segments.h, src/supersegments.c, src/ways.c: About to add the super-segment functionality using Segments data type to hold them. * src/functions.h, src/types.h: Changed after nodes, ways and segment changes. 2009-01-09 Andrew M. Bishop <amb> * src/segments.h: New file. * src/segments.c: Changed the format of the segments data type to match the nodes. * src/nodes.h: Enable indexed arrays. * src/ways.h: New file. * src/ways.c: Changed the format of the ways data type to match the nodes. * src/nodes.c, src/nodes.h: Changed the format of the nodes data type again. 2009-01-07 Andrew M. Bishop <amb> * src/nodes.h: New file. * src/nodes.c: Lots of modifications: Two data structures - in memory (pointers) and in file (array). Data is hashed into multiple bins. Each function takes a nodes structure as an argument. 2009-01-06 Andrew M. Bishop <amb> * src/supersegments.c: New file. * src/Makefile, src/filedumper.c, src/functions.h, src/planetsplitter.c, src/types.h: Added SuperSegments data type, but it does nothing yet. * src/optimiser.c: Tried to optimise the Queue data type. It was slower than the original. 2009-01-05 Andrew M. Bishop <amb> * src/filedumper.c: Print out the longest segment. * src/optimiser.c: Some optimisations. Increase the number of result bins and change find_insert_result() into insert_result(). 2009-01-04 Andrew M. Bishop <amb> * src/optimiser.c: Introduced some new data types to simplify the code. * src/filedumper.c: Print more useful information. * src/segments.c, src/types.h, src/ways.c, src/filedumper.c, src/functions.h, src/nodes.c, src/optimiser.c, src/osmparser.c, src/planetsplitter.c: Changed the node, way and segment functions and data types. Removed 'alloced', shortened the prototype array. Remove the automatic sorting of the data. Added assert statements. 2009-01-03 Andrew M. Bishop <amb> * src/ways.c: New file. * src/router.c, src/types.h, src/Makefile, src/filedumper.c, src/functions.h, src/optimiser.c, src/osmparser.c, src/planetsplitter.c: Added the ways to the output. 2009-01-02 Andrew M. Bishop <amb> * src/optimiser.c, src/osmparser.c, src/segments.c, src/types.h: Added macros to convert between distance/km and duration/hours/minutes. Shortened the Segment data type with shorter distances and durations. 2009-01-01 Andrew M. Bishop <amb> * src/functions.h, src/nodes.c, src/planetsplitter.c, src/segments.c, src/types.h: Remove the functions to initialise the node and segment arrays. * src/optimiser.c, src/router.c, src/Makefile: Print out the results. 2008-12-31 Andrew M. Bishop <amb> * src/types.h, src/segments.c, src/router.c, src/planetsplitter.c, src/osmparser.c, src/optimiser.c, src/nodes.c, src/functions.h, src/files.c, src/filedumper.c, src/Makefile: New file. ���������������������������������������������������routino-3.0/Makefile�������������������������������������������������������������������������������� 644 � 233 � 144 � 2603 12563636400 7671� 0�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Top level Makefile # # Part of the Routino routing software. # # This file Copyright 2009-2015 Andrew M. Bishop # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. # # All configuration is in the top-level Makefile.conf include Makefile.conf # Sub-directories and sub-makefiles SUBDIRS=src xml doc web extras ######## all: for dir in $(SUBDIRS); do \ ( cd $$dir && $(MAKE) $@ ); \ done ######## test: for dir in $(SUBDIRS); do \ ( cd $$dir && $(MAKE) $@ ); \ done ######## install: for dir in $(SUBDIRS); do \ ( cd $$dir && $(MAKE) $@ ); \ done ######## clean: for dir in $(SUBDIRS); do \ ( cd $$dir && $(MAKE) $@ ); \ done ######## distclean: for dir in $(SUBDIRS); do \ ( cd $$dir && $(MAKE) $@ ); \ done ######## .PHONY:: all test install clean distclean �����������������������������������������������������������������������������������������������������������������������������routino-3.0/Makefile.conf��������������������������������������������������������������������������� 644 � 233 � 144 � 5673 12573351513 10627� 0�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Configuration Makefile # # Part of the Routino routing software. # # This file Copyright 2013-2015 Andrew M. Bishop # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. # # Automatic operating system detection UNAME=$(shell uname) HOST=UNIX ifneq ($(findstring CYGWIN,$(UNAME)),) HOST=CYGWIN endif ifneq ($(findstring MINGW,$(UNAME)),) HOST=MINGW endif # Simplify handling of executable targets ending in .exe ifeq ($(HOST),MINGW) .EXE=.exe else .EXE= endif # Installation locations (edit if required) ifneq ($(HOST),MINGW) prefix=/usr/local bindir=$(prefix)/bin incdir=$(prefix)/include libdir=$(prefix)/lib docdir=$(prefix)/doc/routino datadir=$(prefix)/share/routino else prefix="c:/Program Files/Routino" bindir=$(prefix)/bin incdir=$(prefix)/include libdir=$(prefix)/lib docdir=$(prefix)/doc datadir=$(prefix)/xml endif # Compilation programs CC=gcc LD=gcc # Language dialect selection CFLAGS=-std=c99 # Warning options CFLAGS+=-Wall -Wmissing-prototypes -Wextra -Wno-unused-parameter -pedantic # Optimisation options CFLAGS+=-O3 CFLAGS+=-ffast-math # Optimisation option (only works if compilation and execution use exactly the same CPU architecture). #CFLAGS+=-march=native # Debugging symbols #CFLAGS+=-g # Maths library LDFLAGS=-lm # Extra flags for compiling libroutino shared library (visibility of symbols, shared) CFLAGS_LIB=-fvisibility=hidden LDFLAGS_LIB=-shared ifeq ($(HOST),UNIX) # Extra flags for compiling libroutino shared library (position independent code) CFLAGS_LIB+=-fPIC LDFLAGS_LIB+=-fPIC endif # Put the current directory in the shared library path for the router using libroutino LDFLAGS_LDSO=-Wl,-R. # Required for multi-threaded support (comment these two lines out if not required) CFLAGS+=-pthread -DUSE_PTHREADS LDFLAGS+=-pthread -lpthread ifneq ($(HOST),MINGW) # Required for bzip2 support (comment these two lines out if not required) CFLAGS+=-DUSE_BZIP2 LDFLAGS+=-lbz2 endif # Required for gzip support (comment these two lines out if not required) CFLAGS+=-DUSE_GZIP LDFLAGS+=-lz # Required for xz support (uncomment these two lines if required) #CFLAGS+=-DUSE_XZ #LDFLAGS+=-llzma # Required to use stdio with files > 2GiB on 32-bit system. CFLAGS+=-D_FILE_OFFSET_BITS=64 ifneq ($(HOST),MINGW) # Required to compile on Linux without a warning about pread() and pwrite() functions. CFLAGS+=-D_POSIX_C_SOURCE=200809L endif ���������������������������������������������������������������������routino-3.0/INSTALL.txt����������������������������������������������������������������������������� 777 � 233 � 144 � 0 12031126065 12417� 2doc/INSTALL.txt����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������routino-3.0/README.txt������������������������������������������������������������������������������ 777 � 233 � 144 � 0 12031126065 12075� 2doc/README.txt�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������routino-3.0/NEWS.txt�������������������������������������������������������������������������������� 777 � 233 � 144 � 0 12031126065 11533� 2doc/NEWS.txt�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������routino-3.0/agpl-3.0.txt���������������������������������������������������������������������������� 644 � 233 � 144 � 103330 11506610625 10247� 0������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU Affero General Public License is a free, copyleft license for software and other kinds of works, specifically designed to ensure cooperation with the community in the case of network server software. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, our General Public Licenses are intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. Developers that use our General Public Licenses protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License which gives you legal permission to copy, distribute and/or modify the software. A secondary benefit of defending all users' freedom is that improvements made in alternate versions of the program, if they receive widespread use, become available for other developers to incorporate. Many developers of free software are heartened and encouraged by the resulting cooperation. However, in the case of software used on network servers, this result may fail to come about. The GNU General Public License permits making a modified version and letting the public access it on a server without ever releasing its source code to the public. The GNU Affero General Public License is designed specifically to ensure that, in such cases, the modified source code becomes available to the community. It requires the operator of a network server to provide the source code of the modified version running there to the users of that server. Therefore, public use of a modified version, on a publicly accessible server, gives the public access to the source code of the modified version. An older license, called the Affero General Public License and published by Affero, was designed to accomplish similar goals. This is a different license, not a version of the Affero GPL, but Affero has released a new version of the Affero GPL which permits relicensing under this license. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU Affero General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Remote Network Interaction; Use with the GNU General Public License. Notwithstanding any other provision of this License, if you modify the Program, your modified version must prominently offer all users interacting with it remotely through a computer network (if your version supports such interaction) an opportunity to receive the Corresponding Source of your version by providing access to the Corresponding Source from a network server at no charge, through some standard or customary means of facilitating copying of software. This Corresponding Source shall include the Corresponding Source for any work covered by version 3 of the GNU General Public License that is incorporated pursuant to the following paragraph. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the work with which it is combined will remain governed by version 3 of the GNU General Public License. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU Affero General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU Affero General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU Affero General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU Affero General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. <one line to give the program's name and a brief idea of what it does.> Copyright (C) <year> <name of author> This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Also add information on how to contact you by electronic and paper mail. If your software can interact with users remotely through a computer network, you should also make sure that it provides a way for users to get its source. For example, if your program is a web application, its interface could display a "Source" link that leads users to an archive of the code. There are many ways you could offer source, and different solutions will be better for different programs; see section 13 for the specific requirements. You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU AGPL, see <http://www.gnu.org/licenses/>. ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������routino-3.0/extras/��������������������������������������������������������������������������������� 40755 � 233 � 144 � 0 12313333771 7520� 5�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������routino-3.0/extras/find-fixme/���������������������������������������������������������������������� 40755 � 233 � 144 � 0 12575036712 11553� 5�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������routino-3.0/extras/find-fixme/fixme.xml������������������������������������������������������������� 644 � 233 � 144 � 3547 12156135452 13426� 0�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8" ?> <!-- ============================================================ An XML format file containing Routino tagging rules - copy the input file directly to the output with no modifications. Part of the Routino routing software. ============================================================ This file Copyright 2010-2013 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. ============================================================ --> <routino-tagging xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.routino.org/xml/routino-tagging.xsd"> <!-- - - - - - - - - - - Node rules - - - - - - - - - - --> <node> <!-- Add a marker for those nodes that match the wanted tag(s) --> <if k="fixme"> <output k="fixme-finder:keep" v="yes" /> </if> <!-- Copy all tags from input to output --> <if> <output /> </if> </node> <!-- - - - - - - - - - - Way rules - - - - - - - - - - --> <way> <!-- Add a marker for those ways that match the wanted tag(s) --> <if k="fixme"> <output k="fixme-finder:keep" v="yes" /> </if> <!-- Copy all tags from input to output --> <if> <output /> </if> </way> <!-- - - - - - - - - - - Relation rules - - - - - - - - - - --> <relation> <!-- Add a marker for those relations that match the wanted tag(s) --> <if k="fixme"> <output k="fixme-finder:keep" v="yes" /> </if> <!-- Copy all tags from input to output --> <if> <output /> </if> </relation> </routino-tagging> ���������������������������������������������������������������������������������������������������������������������������������������������������������routino-3.0/extras/find-fixme/fixme-finder.c�������������������������������������������������������� 644 � 233 � 144 � 24757 12574075132 14345� 0�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************** OSM planet file fixme finder. Part of the Routino routing software. ******************/ /****************** This file Copyright 2008-2015 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. ***************************************/ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include "version.h" #include "types.h" #include "ways.h" #include "typesx.h" #include "nodesx.h" #include "waysx.h" #include "relationsx.h" #include "files.h" #include "logging.h" #include "errorlogx.h" #include "functions.h" #include "osmparser.h" #include "tagging.h" #include "uncompress.h" /* Global variables */ /*+ The name of the temporary directory. +*/ char *option_tmpdirname=NULL; /*+ The amount of RAM to use for filesorting. +*/ size_t option_filesort_ramsize=0; /*+ The number of threads to use for filesorting. +*/ int option_filesort_threads=1; /* Local functions */ static void print_usage(int detail,const char *argerr,const char *err); /*++++++++++++++++++++++++++++++++++++++ The main program for the find-fixme. ++++++++++++++++++++++++++++++++++++++*/ int main(int argc,char** argv) { NodesX *OSMNodes; WaysX *OSMWays; RelationsX *OSMRelations; ErrorLogsX *OSMErrorLogs; char *dirname=NULL,*prefix=NULL,*tagging=NULL; int option_keep=1; int option_filenames=0; int arg; printf_program_start(); /* Parse the command line arguments */ for(arg=1;arg<argc;arg++) { if(!strcmp(argv[arg],"--version")) print_usage(-1,NULL,NULL); else if(!strcmp(argv[arg],"--help")) print_usage(1,NULL,NULL); else if(!strncmp(argv[arg],"--dir=",6)) dirname=&argv[arg][6]; else if(!strncmp(argv[arg],"--sort-ram-size=",16)) option_filesort_ramsize=atoi(&argv[arg][16]); #if defined(USE_PTHREADS) && USE_PTHREADS else if(!strncmp(argv[arg],"--sort-threads=",15)) option_filesort_threads=atoi(&argv[arg][15]); #endif else if(!strncmp(argv[arg],"--tmpdir=",9)) option_tmpdirname=&argv[arg][9]; else if(!strncmp(argv[arg],"--tagging=",10)) tagging=&argv[arg][10]; else if(!strcmp(argv[arg],"--loggable")) option_loggable=1; else if(!strcmp(argv[arg],"--logtime")) option_logtime=1; else if(!strcmp(argv[arg],"--logmemory")) option_logmemory=1; else if(argv[arg][0]=='-' && argv[arg][1]=='-') print_usage(0,argv[arg],NULL); else option_filenames++; } /* Check the specified command line options */ if(!option_filesort_ramsize) { #if SLIM option_filesort_ramsize=64*1024*1024; #else option_filesort_ramsize=256*1024*1024; #endif } else option_filesort_ramsize*=1024*1024; if(!option_tmpdirname) { if(!dirname) option_tmpdirname="."; else option_tmpdirname=dirname; } if(tagging) { if(!ExistsFile(tagging)) { fprintf(stderr,"Error: The '--tagging' option specifies a file that does not exist.\n"); exit(EXIT_FAILURE); } } else { tagging=FileName(dirname,prefix,"fixme.xml"); if(!ExistsFile(tagging)) { fprintf(stderr,"Error: The '--tagging' option was not used and the default 'fixme.xml' does not exist.\n"); exit(EXIT_FAILURE); } } if(ParseXMLTaggingRules(tagging)) { fprintf(stderr,"Error: Cannot read the tagging rules in the file '%s'.\n",tagging); exit(EXIT_FAILURE); } /* Create new node, segment, way and relation variables */ OSMNodes=NewNodeList(0,0); OSMWays=NewWayList(0,0); OSMRelations=NewRelationList(0,0); /* Create the error log file */ open_errorlog(FileName(dirname,prefix,"fixme.log"),0,option_keep); /* Parse the file */ for(arg=1;arg<argc;arg++) { int fd; char *filename,*p; if(argv[arg][0]=='-' && argv[arg][1]=='-') continue; filename=strcpy(malloc(strlen(argv[arg])+1),argv[arg]); fd=OpenFile(filename); if((p=strstr(filename,".bz2")) && !strcmp(p,".bz2")) { fd=Uncompress_Bzip2(fd); *p=0; } if((p=strstr(filename,".gz")) && !strcmp(p,".gz")) { fd=Uncompress_Gzip(fd); *p=0; } if((p=strstr(filename,".xz")) && !strcmp(p,".xz")) { fd=Uncompress_Xz(fd); *p=0; } printf("\nParse OSM Data [%s]\n==============\n\n",filename); fflush(stdout); if((p=strstr(filename,".pbf")) && !strcmp(p,".pbf")) { if(ParsePBFFile(fd,OSMNodes,OSMWays,OSMRelations)) exit(EXIT_FAILURE); } else if((p=strstr(filename,".o5m")) && !strcmp(p,".o5m")) { if(ParseO5MFile(fd,OSMNodes,OSMWays,OSMRelations)) exit(EXIT_FAILURE); } else { if(ParseOSMFile(fd,OSMNodes,OSMWays,OSMRelations)) exit(EXIT_FAILURE); } CloseFile(fd); free(filename); } DeleteXMLTaggingRules(); FinishNodeList(OSMNodes); FinishWayList(OSMWays); FinishRelationList(OSMRelations); /* Sort the data */ printf("\nSort OSM Data\n=============\n\n"); fflush(stdout); /* Sort the nodes, ways and relations */ SortNodeList(OSMNodes); SortWayList(OSMWays); SortRelationList(OSMRelations); /* Process the data */ RenameFile(OSMNodes->filename_tmp,OSMNodes->filename); RenameFile(OSMWays->filename_tmp,OSMWays->filename); RenameFile(OSMRelations->rrfilename_tmp,OSMRelations->rrfilename); RenameFile(OSMRelations->trfilename_tmp,OSMRelations->trfilename); close_errorlog(); printf("\nCreate Error Log\n================\n\n"); fflush(stdout); OSMErrorLogs=NewErrorLogList(); ProcessErrorLogs(OSMErrorLogs,OSMNodes,OSMWays,OSMRelations); SortErrorLogsGeographically(OSMErrorLogs); SaveErrorLogs(OSMErrorLogs,FileName(dirname,prefix,"fixme.mem")); FreeErrorLogList(OSMErrorLogs); /* Free the memory (delete the temporary files) */ FreeNodeList(OSMNodes,0); FreeWayList(OSMWays,0); FreeRelationList(OSMRelations,0); printf("\n"); fflush(stdout); printf_program_end(); exit(EXIT_SUCCESS); } /*++++++++++++++++++++++++++++++++++++++ Print out the usage information. int detail The level of detail to use: -1 = just version number, 0 = low detail, 1 = full details. const char *argerr The argument that gave the error (if there is one). const char *err Other error message (if there is one). ++++++++++++++++++++++++++++++++++++++*/ static void print_usage(int detail,const char *argerr,const char *err) { if(detail<0) { fprintf(stderr, "Routino version " ROUTINO_VERSION " " ROUTINO_URL ".\n" ); } if(detail>=0) { fprintf(stderr, "Usage: fixme-finder [--version]\n" " [--help]\n" " [--dir=<dirname>]\n" #if defined(USE_PTHREADS) && USE_PTHREADS " [--sort-ram-size=<size>] [--sort-threads=<number>]\n" #else " [--sort-ram-size=<size>]\n" #endif " [--tmpdir=<dirname>]\n" " [--tagging=<filename>]\n" " [--loggable] [--logtime] [--logmemory]\n" " [<filename.osm> ...\n" " | <filename.pbf> ...\n" " | <filename.o5m> ..." #if defined(USE_BZIP2) && USE_BZIP2 "\n | <filename.(osm|o5m).bz2> ..." #endif #if defined(USE_GZIP) && USE_GZIP "\n | <filename.(osm|o5m).gz> ..." #endif #if defined(USE_XZ) && USE_XZ "\n | <filename.(osm|o5m).xz> ..." #endif "]\n"); if(argerr) fprintf(stderr, "\n" "Error with command line parameter: %s\n",argerr); if(err) fprintf(stderr, "\n" "Error: %s\n",err); } if(detail==1) fprintf(stderr, "\n" "--version Print the version of Routino.\n" "\n" "--help Prints this information.\n" "\n" "--dir=<dirname> The directory containing the fixme database.\n" "\n" "--sort-ram-size=<size> The amount of RAM (in MB) to use for data sorting\n" #if SLIM " (defaults to 64MB otherwise.)\n" #else " (defaults to 256MB otherwise.)\n" #endif #if defined(USE_PTHREADS) && USE_PTHREADS "--sort-threads=<number> The number of threads to use for data sorting.\n" #endif "\n" "--tmpdir=<dirname> The directory name for temporary files.\n" " (defaults to the '--dir' option directory.)\n" "\n" "--tagging=<filename> The name of the XML file containing the tagging rules\n" " (defaults to 'fixme.xml' with '--dir' option)\n" "\n" "--loggable Print progress messages suitable for logging to file.\n" "--logtime Print the elapsed time for each processing step.\n" "--logmemory Print the max allocated/mapped memory for each step.\n" "\n" "<filename.osm>, <filename.pbf>, <filename.o5m>\n" " The name(s) of the file(s) to read and parse.\n" " Filenames ending '.pbf' read as PBF, filenames ending\n" " '.o5m' read as O5M, others as XML.\n" #if defined(USE_BZIP2) && USE_BZIP2 " Filenames ending '.bz2' will be bzip2 uncompressed.\n" #endif #if defined(USE_GZIP) && USE_GZIP " Filenames ending '.gz' will be gzip uncompressed.\n" #endif #if defined(USE_XZ) && USE_XZ " Filenames ending '.xz' will be xz uncompressed.\n" #endif ); exit(!detail); } �����������������routino-3.0/extras/find-fixme/Makefile�������������������������������������������������������������� 644 � 233 � 144 � 12544 12563637555 13266� 0�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# find-fixme Makefile # # Part of the Routino routing software. # # This file Copyright 2013-2015 Andrew M. Bishop # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. # # All configuration is in the top-level Makefile.conf include ../../Makefile.conf # Web file paths WEBBINDIR=web/bin WEBDATADIR=web/data WEBWWWDIR=web/www # Compilation targets C=$(wildcard *.c) D=$(wildcard .deps/*.d) ROUTINO_SRC=../../src ROUTINO_WEBWWWDIR=../../web/www/routino ROUTINO_DOCDIR=../../doc/html EXE=fixme-finder$(.EXE) fixme-finder-slim$(.EXE) fixme-dumper$(.EXE) fixme-dumper-slim$(.EXE) DATA=fixme.xml WWW_COPY=page-elements.css page-elements.js maplayout.css mapprops.js maploader.js DOC_COPY=style.css ######## all: all-bin all-data all-www all-bin: $(EXE) @[ -d $(WEBBINDIR) ] || mkdir -p $(WEBBINDIR) @for file in $(EXE); do \ if [ ! -f $(WEBBINDIR)/$$file ] || [ $$file -nt $(WEBBINDIR)/$$file ]; then \ echo cp $$file $(WEBBINDIR) ;\ cp -f $$file $(WEBBINDIR) ;\ fi ;\ done all-data: @[ -d $(WEBDATADIR) ] || mkdir -p $(WEBDATADIR) @for file in $(DATA); do \ if [ ! -f $(WEBDATADIR)/$$file ] || [ $$file -nt $(WEBDATADIR)/$$file ]; then \ echo cp $$file $(WEBDATADIR) ;\ cp -f $$file $(WEBDATADIR) ;\ fi ;\ done all-www: @for file in $(WWW_COPY); do \ if [ ! -f $(WEBWWWDIR)/$$file ] || [ $(ROUTINO_WEBWWWDIR)/$$file -nt $(WEBWWWDIR)/$$file ]; then \ echo cp $(ROUTINO_WEBWWWDIR)/$$file $(WEBWWWDIR) ;\ cp -f $(ROUTINO_WEBWWWDIR)/$$file $(WEBWWWDIR) ;\ fi ;\ done @for file in $(DOC_COPY); do \ if [ ! -f $(WEBWWWDIR)/$$file ] || [ $(ROUTINO_DOCDIR)/$$file -nt $(WEBWWWDIR)/$$file ]; then \ echo cp $(ROUTINO_DOCDIR)/$$file $(WEBWWWDIR) ;\ cp -f $(ROUTINO_DOCDIR)/$$file $(WEBWWWDIR) ;\ fi ;\ done ######## FIXME_FINDER_OBJ=fixme-finder.o osmparser.o \ $(ROUTINO_SRC)/nodesx.o $(ROUTINO_SRC)/segmentsx.o $(ROUTINO_SRC)/waysx.o $(ROUTINO_SRC)/relationsx.o \ $(ROUTINO_SRC)/ways.o $(ROUTINO_SRC)/types.o \ $(ROUTINO_SRC)/files.o $(ROUTINO_SRC)/logging.o $(ROUTINO_SRC)/logerror.o $(ROUTINO_SRC)/errorlogx.o \ $(ROUTINO_SRC)/sorting.o \ $(ROUTINO_SRC)/xmlparse.o $(ROUTINO_SRC)/tagging.o \ $(ROUTINO_SRC)/uncompress.o $(ROUTINO_SRC)/osmxmlparse.o $(ROUTINO_SRC)/osmpbfparse.o $(ROUTINO_SRC)/osmo5mparse.o ifeq ($(HOST),MINGW) FIXME_FINDER_OBJ+=$(ROUTINO_SRC)/mman-win32.o endif fixme-finder$(.EXE) : $(FIXME_FINDER_OBJ) $(LD) $^ -o $@ $(LDFLAGS) ######## FIXME_FINDER_SLIM_OBJ=fixme-finder-slim.o osmparser.o \ $(ROUTINO_SRC)/nodesx-slim.o $(ROUTINO_SRC)/segmentsx-slim.o $(ROUTINO_SRC)/waysx-slim.o $(ROUTINO_SRC)/relationsx-slim.o \ $(ROUTINO_SRC)/ways.o $(ROUTINO_SRC)/types.o \ $(ROUTINO_SRC)/files.o $(ROUTINO_SRC)/logging.o $(ROUTINO_SRC)/logerror-slim.o $(ROUTINO_SRC)/errorlogx-slim.o \ $(ROUTINO_SRC)/sorting.o \ $(ROUTINO_SRC)/xmlparse.o $(ROUTINO_SRC)/tagging.o \ $(ROUTINO_SRC)/uncompress.o $(ROUTINO_SRC)/osmxmlparse.o $(ROUTINO_SRC)/osmpbfparse.o $(ROUTINO_SRC)/osmo5mparse.o ifeq ($(HOST),MINGW) FIXME_FINDER_SLIM_OBJ+=$(ROUTINO_SRC)/mman-win32.o endif fixme-finder-slim$(.EXE) : $(FIXME_FINDER_SLIM_OBJ) $(LD) $^ -o $@ $(LDFLAGS) ######## FIXME_DUMPER_OBJ=fixme-dumper.o \ $(ROUTINO_SRC)/errorlog.o \ $(ROUTINO_SRC)/files.o $(ROUTINO_SRC)/logging.o $(ROUTINO_SRC)/xmlparse.o ifeq ($(HOST),MINGW) FIXME_DUMPER_OBJ+=$(ROUTINO_SRC)/mman-win32.o endif fixme-dumper$(.EXE) : $(FIXME_DUMPER_OBJ) $(LD) $^ -o $@ $(LDFLAGS) ######## FIXME_DUMPER_SLIM_OBJ=fixme-dumper-slim.o \ $(ROUTINO_SRC)/errorlog-slim.o \ $(ROUTINO_SRC)/files.o $(ROUTINO_SRC)/logging.o $(ROUTINO_SRC)/xmlparse.o ifeq ($(HOST),MINGW) FIXME_DUMPER_SLIM_OBJ+=$(ROUTINO_SRC)/mman-win32.o endif fixme-dumper-slim$(.EXE) : $(FIXME_DUMPER_SLIM_OBJ) $(LD) $^ -o $@ $(LDFLAGS) ######## $(ROUTINO_SRC)/%.o : cd $(ROUTINO_SRC) && $(MAKE) $(notdir $@) $(ROUTINO_SRC)/%-slim.o : cd $(ROUTINO_SRC) && $(MAKE) $(notdir $@) %.o : %.c @[ -d .deps ] || mkdir .deps $(CC) -c $(CFLAGS) -DSLIM=0 -I$(ROUTINO_SRC) $< -o $@ -MMD -MP -MF $(addprefix .deps/,$(addsuffix .d,$(basename $@))) %-slim.o : %.c @[ -d .deps ] || mkdir .deps $(CC) -c $(CFLAGS) -DSLIM=1 -I$(ROUTINO_SRC) $< -o $@ -MMD -MP -MF $(addprefix .deps/,$(addsuffix .d,$(basename $@))) ######## test: ######## install: ######## clean: rm -f *~ rm -f *.o cd $(WEBBINDIR) && rm -f $(EXE) cd $(WEBDATADIR) && rm -f $(DATA) cd $(WEBWWWDIR) && rm -f $(WWW_COPY) cd $(WEBWWWDIR) && rm -f $(DOC_COPY) rm -f $(EXE) rm -f $(D) rm -fr .deps rm -f core ######## distclean: clean ######## include $(D) ######## .PHONY:: all test install clean distclean .PHONY:: all-bin all-data all-www ������������������������������������������������������������������������������������������������������������������������������������������������������������routino-3.0/extras/find-fixme/README.txt������������������������������������������������������������ 644 � 233 � 144 � 10536 12574075462 13316� 0������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� Find and Display FIXME tags =========================== The "fixme" tag is often used in OSM data to mark an item whose details are not completely known - as a reminder or request for somebody to check it. Since Routino can now generate a map of tagging problems that it finds it is easy to extend this to finding all "fixme" tags. The files in this directory provide a complete set of executables and web pages for extracting and displaying all items with "fixme" tags on a map. Editing fixme.xml and changing the rules for selecting tags allows for creating custom databases to display items containing any desired tag(s). fixme-finder ------------ This program is a modified version of the Routino planetsplitter program and can be used on an OSM file to extract the fixme tags and generate a database of them. Usage: fixme-finder [--version] [--help] [--dir=<dirname>] [--sort-ram-size=<size>] [--sort-threads=<number>] [--tmpdir=<dirname>] [--tagging=<filename>] [--loggable] [--logtime] [--logmemory] [<filename.osm> ... | <filename.pbf> ... | <filename.o5m> ... | <filename.(osm|o5m).bz2> ... | <filename.(osm|o5m).gz> ... | <filename.(osm|o5m).xz> ...] --version Print the version of Routino. --help Prints this information. --dir=<dirname> The directory containing the fixme database. --sort-ram-size=<size> The amount of RAM (in MB) to use for data sorting (defaults to 256MB otherwise.) --sort-threads=<number> The number of threads to use for data sorting. --tmpdir=<dirname> The directory name for temporary files. (defaults to the '--dir' option directory.) --tagging=<filename> The name of the XML file containing the tagging rules (defaults to 'fixme.xml' with '--dir' option) --loggable Print progress messages suitable for logging to file. --logtime Print the elapsed time for each processing step. --logmemory Print the max allocated/mapped memory for each step. <filename.osm>, <filename.pbf>, <filename.o5m> The name(s) of the file(s) to read and parse. Filenames ending '.pbf' read as PBF, filenames ending '.o5m' read as O5M, others as XML. Filenames ending '.bz2' will be bzip2 uncompressed (if bzip2 support compiled in). Filenames ending '.gz' will be gzip uncompressed (if gzip support compiled in). Filenames ending '.xz' will be xz uncompressed (if xz support compiled in). fixme-dumper ------------ This program is a modified version of the Routino filedumper program and is used by the web page CGI to display the information on a map. Usage: fixme-dumper [--version] [--help] [--dir=<dirname>] [--statistics] [--visualiser --latmin=<latmin> --latmax=<latmax> --lonmin=<lonmin> --lonmax=<lonmax> --data=<data-type>] [--dump--visualiser [--data=fixme<number>]] --version Print the version of Routino. --help Prints this information. --dir=<dirname> The directory containing the fixme database. --statistics Print statistics about the fixme database. --visualiser Extract selected data from the fixme database: --latmin=<latmin> * the minimum latitude (degrees N). --latmax=<latmax> * the maximum latitude (degrees N). --lonmin=<lonmin> * the minimum longitude (degrees E). --lonmax=<lonmax> * the maximum longitude (degrees E). --data=<data-type> * the type of data to select. <data-type> can be selected from: fixmes = fixme tags extracted from the data. --dump-visualiser Dump selected contents of the database in HTML. --data=fixme<number> * the fixme with the selected index. ������������������������������������������������������������������������������������������������������������������������������������������������������������������routino-3.0/extras/find-fixme/fixme-dumper.c�������������������������������������������������������� 644 � 233 � 144 � 26637 12574075134 14373� 0�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*************************************** Fixme file dumper. Part of the Routino routing software. ******************/ /****************** This file Copyright 2013-2015 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. ***************************************/ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/stat.h> #include <time.h> #include <math.h> #include "version.h" #include "types.h" #include "errorlog.h" #include "files.h" #include "xmlparse.h" /* Local functions */ static void OutputErrorLog(ErrorLogs *errorlogs,double latmin,double latmax,double lonmin,double lonmax); static void print_errorlog_visualiser(ErrorLogs *errorlogs,index_t item); static char *RFC822Date(time_t t); static void print_usage(int detail,const char *argerr,const char *err); /*++++++++++++++++++++++++++++++++++++++ The main program for the fixme dumper. ++++++++++++++++++++++++++++++++++++++*/ int main(int argc,char** argv) { ErrorLogs*OSMErrorLogs; int arg; char *dirname=NULL,*prefix=NULL; char *errorlogs_filename; int option_statistics=0; int option_visualiser=0,coordcount=0; double latmin=0,latmax=0,lonmin=0,lonmax=0; char *option_data=NULL; int option_dump_visualiser=0; /* Parse the command line arguments */ for(arg=1;arg<argc;arg++) { if(!strcmp(argv[arg],"--version")) print_usage(-1,NULL,NULL); else if(!strcmp(argv[arg],"--help")) print_usage(1,NULL,NULL); else if(!strncmp(argv[arg],"--dir=",6)) dirname=&argv[arg][6]; else if(!strcmp(argv[arg],"--statistics")) option_statistics=1; else if(!strcmp(argv[arg],"--visualiser")) option_visualiser=1; else if(!strcmp(argv[arg],"--dump-visualiser")) option_dump_visualiser=1; else if(!strncmp(argv[arg],"--latmin",8) && argv[arg][8]=='=') {latmin=degrees_to_radians(atof(&argv[arg][9]));coordcount++;} else if(!strncmp(argv[arg],"--latmax",8) && argv[arg][8]=='=') {latmax=degrees_to_radians(atof(&argv[arg][9]));coordcount++;} else if(!strncmp(argv[arg],"--lonmin",8) && argv[arg][8]=='=') {lonmin=degrees_to_radians(atof(&argv[arg][9]));coordcount++;} else if(!strncmp(argv[arg],"--lonmax",8) && argv[arg][8]=='=') {lonmax=degrees_to_radians(atof(&argv[arg][9]));coordcount++;} else if(!strncmp(argv[arg],"--data",6) && argv[arg][6]=='=') option_data=&argv[arg][7]; else if(!strncmp(argv[arg],"--fixme=",8)) ; else print_usage(0,argv[arg],NULL); } if((option_statistics + option_visualiser + option_dump_visualiser)!=1) print_usage(0,NULL,"Must choose --visualiser, --statistics or --dump-visualiser."); /* Load in the data - Note: No error checking because Load*List() will call exit() in case of an error. */ OSMErrorLogs=LoadErrorLogs(errorlogs_filename=FileName(dirname,prefix,"fixme.mem")); /* Write out the visualiser data */ if(option_visualiser) { if(coordcount!=4) print_usage(0,NULL,"The --visualiser option must have --latmin, --latmax, --lonmin, --lonmax.\n"); if(!option_data) print_usage(0,NULL,"The --visualiser option must have --data.\n"); if(!strcmp(option_data,"fixmes")) OutputErrorLog(OSMErrorLogs,latmin,latmax,lonmin,lonmax); else print_usage(0,option_data,NULL); } /* Print out statistics */ if(option_statistics) { struct stat buf; /* Examine the files */ printf("Files\n"); printf("-----\n"); printf("\n"); stat(errorlogs_filename,&buf); printf("'%s%sfixme.mem' - %9"PRIu64" Bytes\n",prefix?prefix:"",prefix?"-":"",(uint64_t)buf.st_size); printf("%s\n",RFC822Date(buf.st_mtime)); printf("\n"); printf("\n"); printf("Error Logs\n"); printf("----------\n"); printf("\n"); printf("Number(total) =%9"Pindex_t"\n",OSMErrorLogs->file.number); printf("Number(geographical) =%9"Pindex_t"\n",OSMErrorLogs->file.number_geo); printf("Number(non-geographical)=%9"Pindex_t"\n",OSMErrorLogs->file.number_nongeo); printf("\n"); stat(errorlogs_filename,&buf); #if !SLIM printf("Total strings=%9zu Bytes\n",(size_t)buf.st_size-(OSMErrorLogs->strings-(char*)OSMErrorLogs->data)); #else printf("Total strings=%9zu Bytes\n",(size_t)buf.st_size-(size_t)OSMErrorLogs->stringsoffset); #endif } /* Print out internal data (in HTML format for the visualiser) */ if(option_dump_visualiser) { index_t item; if(!option_data) print_usage(0,NULL,"The --dump-visualiser option must have --data.\n"); for(arg=1;arg<argc;arg++) if(!strncmp(argv[arg],"--data=fixme",12)) { item=atoi(&argv[arg][12]); if(item<OSMErrorLogs->file.number) print_errorlog_visualiser(OSMErrorLogs,item); else printf("Invalid fixme number; minimum=0, maximum=%"Pindex_t".\n",OSMErrorLogs->file.number-1); } } exit(EXIT_SUCCESS); } /*++++++++++++++++++++++++++++++++++++++ Output the data for error logs within the region. ErrorLogs *errorlogs The set of error logs to use. double latmin The minimum latitude. double latmax The maximum latitude. double lonmin The minimum longitude. double lonmax The maximum longitude. ++++++++++++++++++++++++++++++++++++++*/ static void OutputErrorLog(ErrorLogs *errorlogs,double latmin,double latmax,double lonmin,double lonmax) { ll_bin_t latminbin=latlong_to_bin(radians_to_latlong(latmin))-errorlogs->file.latzero; ll_bin_t latmaxbin=latlong_to_bin(radians_to_latlong(latmax))-errorlogs->file.latzero; ll_bin_t lonminbin=latlong_to_bin(radians_to_latlong(lonmin))-errorlogs->file.lonzero; ll_bin_t lonmaxbin=latlong_to_bin(radians_to_latlong(lonmax))-errorlogs->file.lonzero; ll_bin_t latb,lonb; index_t i,index1,index2; /* Loop through all of the error logs. */ for(latb=latminbin;latb<=latmaxbin;latb++) for(lonb=lonminbin;lonb<=lonmaxbin;lonb++) { ll_bin2_t llbin=lonb*errorlogs->file.latbins+latb; if(llbin<0 || llbin>(errorlogs->file.latbins*errorlogs->file.lonbins)) continue; index1=LookupErrorLogOffset(errorlogs,llbin); index2=LookupErrorLogOffset(errorlogs,llbin+1); if(index2>errorlogs->file.number_geo) index2=errorlogs->file.number_geo; for(i=index1;i<index2;i++) { ErrorLog *errorlogp=LookupErrorLog(errorlogs,i,1); double lat=latlong_to_radians(bin_to_latlong(errorlogs->file.latzero+latb)+off_to_latlong(errorlogp->latoffset)); double lon=latlong_to_radians(bin_to_latlong(errorlogs->file.lonzero+lonb)+off_to_latlong(errorlogp->lonoffset)); if(lat>latmin && lat<latmax && lon>lonmin && lon<lonmax) printf("fixme%"Pindex_t" %.6f %.6f\n",i,radians_to_degrees(lat),radians_to_degrees(lon)); } } } /*++++++++++++++++++++++++++++++++++++++ Print out an error log entry from the database (in visualiser format). ErrorLogs *errorlogs The set of error logs to use. index_t item The error log index to print. ++++++++++++++++++++++++++++++++++++++*/ static void print_errorlog_visualiser(ErrorLogs *errorlogs,index_t item) { char *string=LookupErrorLogString(errorlogs,item); printf("%s\n",ParseXML_Encode_Safe_XML(string)); } /*+ Conversion from time_t to date string (day of week). +*/ static const char* const weekdays[7]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"}; /*+ Conversion from time_t to date string (month of year). +*/ static const char* const months[12]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"}; /*++++++++++++++++++++++++++++++++++++++ Convert the time into an RFC 822 compliant date. char *RFC822Date Returns a pointer to a fixed string containing the date. time_t t The time. ++++++++++++++++++++++++++++++++++++++*/ static char *RFC822Date(time_t t) { static char value[32]; /* static allocation of return value */ char weekday[4]; char month[4]; struct tm *tim; tim=gmtime(&t); strcpy(weekday,weekdays[tim->tm_wday]); strcpy(month,months[tim->tm_mon]); /* Sun, 06 Nov 1994 08:49:37 GMT ; RFC 822, updated by RFC 1123 */ sprintf(value,"%3s, %02d %3s %4d %02d:%02d:%02d %s", weekday, tim->tm_mday, month, tim->tm_year+1900, tim->tm_hour, tim->tm_min, tim->tm_sec, "GMT" ); return(value); } /*++++++++++++++++++++++++++++++++++++++ Print out the usage information. int detail The level of detail to use: -1 = just version number, 0 = low detail, 1 = full details. const char *argerr The argument that gave the error (if there is one). const char *err Other error message (if there is one). ++++++++++++++++++++++++++++++++++++++*/ static void print_usage(int detail,const char *argerr,const char *err) { if(detail<0) { fprintf(stderr, "Routino version " ROUTINO_VERSION " " ROUTINO_URL ".\n" ); } if(detail>=0) { fprintf(stderr, "Usage: fixme-dumper [--version]\n" " [--help]\n" " [--dir=<dirname>]\n" " [--statistics]\n" " [--visualiser --latmin=<latmin> --latmax=<latmax>\n" " --lonmin=<lonmin> --lonmax=<lonmax>\n" " --data=<data-type>]\n" " [--dump--visualiser [--data=fixme<number>]]\n"); if(argerr) fprintf(stderr, "\n" "Error with command line parameter: %s\n",argerr); if(err) fprintf(stderr, "\n" "Error: %s\n",err); } if(detail==1) fprintf(stderr, "\n" "--version Print the version of Routino.\n" "\n" "--help Prints this information.\n" "\n" "--dir=<dirname> The directory containing the fixme database.\n" "\n" "--statistics Print statistics about the fixme database.\n" "\n" "--visualiser Extract selected data from the fixme database:\n" " --latmin=<latmin> * the minimum latitude (degrees N).\n" " --latmax=<latmax> * the maximum latitude (degrees N).\n" " --lonmin=<lonmin> * the minimum longitude (degrees E).\n" " --lonmax=<lonmax> * the maximum longitude (degrees E).\n" " --data=<data-type> * the type of data to select.\n" "\n" " <data-type> can be selected from:\n" " fixmes = fixme tags extracted from the data.\n" "\n" "--dump-visualiser Dump selected contents of the database in HTML.\n" " --data=fixme<number> * the fixme with the selected index.\n"); exit(!detail); } �������������������������������������������������������������������������������������������������routino-3.0/extras/find-fixme/web/������������������������������������������������������������������ 40755 � 233 � 144 � 0 12216114770 12321� 5�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������routino-3.0/extras/find-fixme/web/bin/�������������������������������������������������������������� 40755 � 233 � 144 � 0 12575036712 13100� 5�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������routino-3.0/extras/find-fixme/web/data/������������������������������������������������������������� 40755 � 233 � 144 � 0 12575036712 13241� 5�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������routino-3.0/extras/find-fixme/web/www/�������������������������������������������������������������� 40755 � 233 � 144 � 0 12575036712 13154� 5�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������routino-3.0/extras/find-fixme/web/www/fixme.css����������������������������������������������������� 644 � 233 � 144 � 3133 12260524267 15010� 0�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* // Routino (extras) fixme web page style sheet. // // Part of the Routino routing software. // // This file Copyright 2008-2013 Andrew M. Bishop // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. */ /*--------------------------------*/ /* Left panel - override defaults */ /*--------------------------------*/ DIV.hideshow_box { overflow-x: auto; } /*-----------------------------------*/ /* Left panel - specific tab options */ /*-----------------------------------*/ DIV#tab_fixme_div INPUT { padding: 0; border: 1px solid; margin: 0; text-align: center; } DIV#tab_fixme_div INPUT:hover { background: #F0F0C0; } DIV#tab_fixme_div DIV.center { text-align: center; } DIV#tab_fixme_div TABLE { padding: 0; border: 0 hidden; margin: 0; } DIV#tab_fixme_div TABLE TD { padding: 0; border: 0; margin: 0; } DIV#tab_fixme_div INPUT { padding: 0; border: 1px solid; margin: 0; } /*-------*/ /* Popup */ /*-------*/ DIV.popup { font-family: monospace; font-size: 10px; } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������routino-3.0/extras/find-fixme/web/www/fixme.html���������������������������������������������������� 644 � 233 � 144 � 13240 12270737731 15207� 0�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta name="keywords" content="openstreetmap routino fixme"> <meta name="viewport" content="width=device-width, height=device-height, initial-scale=1, user-scalable=no"> <title>Routino Extras : Viewer for OpenStreetMap "fixme" Tags
Fixme Data
OSM "fixme" Tags This web page allows viewing the "fixme" tags in OSM data. It is generated using a modified version of the Routino router data processor.
Instructions Zoom in and then use the button below to download the data. The server will only return data if the selected area is small enough.
Status
No data displayed
Get Data
The points displayed on the map are the location of items in the OSM data that are tagged with "fixme" = "...". Clicking on one of the points will display the Node, Way or Relation identifier and the contents of the tag.
+ - Help
Quick Start
Zoom to an area and select one of the buttons to display the fixme data.

Data Failure
If the area selected is too large (depends on the data type) then the status will say "Failed to get fixme data" - zoom in and try again.

Data Generator: Routino | Geo Data: | Tiles:
routino-3.0/extras/find-fixme/web/www/fixme.openlayers.js 644 233 144 36570 12304345114 17036 0// // Routino (extras) fixme web page Javascript // // Part of the Routino routing software. // // This file Copyright 2008-2014 Andrew M. Bishop // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . // //////////////////////////////////////////////////////////////////////////////// /////////////////////////////// Initialisation ///////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // Process the URL query string and extract the arguments var legal={"^lon" : "^[-0-9.]+$", "^lat" : "^[-0-9.]+$", "^zoom" : "^[0-9]+$"}; var args={}; if(location.search.length>1) { var query,queries; query=location.search.replace(/^\?/,""); query=query.replace(/;/g,"&"); queries=query.split("&"); for(var i=0;i" + data_text + ""; document.getElementById("attribution_tile").innerHTML="" + tile_text + ""; } change_attribution(0); // Add two vectors layers (one for highlights that display behind the vectors) layerHighlights = new OpenLayers.Layer.Vector("Highlights",{displayInLayerSwitcher: false}); map.addLayer(layerHighlights); layerVectors = new OpenLayers.Layer.Vector("Markers",{displayInLayerSwitcher: false}); map.addLayer(layerVectors); // Handle feature selection and popup select = new OpenLayers.Control.SelectFeature(layerVectors, {onSelect: selectFeature, onUnselect: unselectFeature}); map.addControl(select); select.activate(); createPopup(); // Add a boxes layer layerBoxes = new OpenLayers.Layer.Boxes("Boundary",{displayInLayerSwitcher: false}); map.addLayer(layerBoxes); box=null; // Move the map map.events.register("moveend", map, updateURLs); var lon =args["lon"]; var lat =args["lat"]; var zoom=args["zoom"]; if(lon !== undefined && lat !== undefined && zoom !== undefined) { if(lonmapprops.eastedge) lon=mapprops.eastedge; if(latmapprops.northedge) lat=mapprops.northedge; if(zoommapprops.zoomin) zoom=mapprops.zoomin; var lonlat = new OpenLayers.LonLat(lon,lat); lonlat.transform(epsg4326,epsg900913); map.moveTo(lonlat,zoom-map.minZoomLevel); } else { map.setCenter(map.restrictedExtent.getCenterLonLat(), map.getZoomForExtent(map.restrictedExtent,true)); map.maxResolution = map.getResolution(); } // Unhide editing URL if variable set if(mapprops.editurl !== undefined && mapprops.editurl !== "") { var edit_url=document.getElementById("edit_url"); edit_url.style.display=""; edit_url.href=mapprops.editurl; } updateURLs(); } // // Format a number in printf("%.5f") format. // function format5f(number) { var newnumber=Math.floor(number*100000+0.5); var delta=0; if(newnumber>=0 && newnumber<100000) delta= 100000; if(newnumber<0 && newnumber>-100000) delta=-100000; var string=String(newnumber+delta); var intpart =string.substring(0,string.length-5); var fracpart=string.substring(string.length-5,string.length); if(delta>0) intpart="0"; if(delta<0) intpart="-0"; return(intpart + "." + fracpart); } // // Build a set of URL arguments for the map location // function buildMapArguments() { var lonlat = map.getCenter().clone(); lonlat.transform(epsg900913,epsg4326); var zoom = map.getZoom() + map.minZoomLevel; return "lat=" + format5f(lonlat.lat) + ";lon=" + format5f(lonlat.lon) + ";zoom=" + zoom; } // // Update the URLs // function updateURLs() { var mapargs=buildMapArguments(); var links=document.getElementsByTagName("a"); for(var i=0; i" + id + "'"); } } } drawPopup(string.split("><").join(">
<").split("
<tag").join("
  <tag")); } //////////////////////////////////////////////////////////////////////////////// /////////////////////////////// Server handling //////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // // Define an AJAX request object // function ajaxGET(url,success,failure,state) { var ajaxRequest=new XMLHttpRequest(); function ajaxGOT(options) { if(this.readyState==4) if(this.status==200) { if(typeof(options.success)=="function") options.success(this,options.state); } else { if(typeof(options.failure)=="function") options.failure(this,options.state); } } ajaxRequest.onreadystatechange = function(){ ajaxGOT.call(ajaxRequest,{success: success, failure: failure, state: state}); }; ajaxRequest.open("GET", url, true); ajaxRequest.send(null); } // // Display the status // function displayStatus(type,subtype,content) { var child=document.getElementById("result_status").firstChild; do { if(child.id !== undefined) child.style.display="none"; child=child.nextSibling; } while(child !== null); var chosen_status=document.getElementById("result_status_" + type); chosen_status.style.display=""; if(subtype !== undefined) { var format_status=document.getElementById("result_status_" + subtype).innerHTML; chosen_status.innerHTML=format_status.replace("#",String(content)); } } // // Display data statistics // function displayStatistics() { // Use AJAX to get the statistics ajaxGET("fixme.cgi?statistics=yes", runStatisticsSuccess); } // // Success in running data statistics generation. // function runStatisticsSuccess(response) { document.getElementById("statistics_data").innerHTML="
" + response.responseText + "
"; document.getElementById("statistics_link").style.display="none"; } // // Get the requested data // function displayData(datatype) // called from fixme.html { // Delete the old data unselectFeature(); select.deactivate(); layerVectors.destroyFeatures(); layerHighlights.destroyFeatures(); if(box !== null) layerBoxes.removeMarker(box); box=null; // Print the status displayStatus("no_data"); // Return if just here to clear the data if(datatype === "") return; // Get the new data var mapbounds=map.getExtent().clone(); mapbounds.transform(epsg900913,epsg4326); var url="fixme.cgi"; url=url + "?lonmin=" + format5f(mapbounds.left); url=url + ";latmin=" + format5f(mapbounds.bottom); url=url + ";lonmax=" + format5f(mapbounds.right); url=url + ";latmax=" + format5f(mapbounds.top); url=url + ";data=" + datatype; // Use AJAX to get the data ajaxGET(url, runFixmeSuccess, runFailure); } // // Success in getting the error log data // function runFixmeSuccess(response) { var lines=response.responseText.split("\n"); var style = new OpenLayers.Style({},{stroke: false, pointRadius: 3,fillColor: "#FF0000", cursor: "pointer"}); var features=[]; for(var line=0;line Routino Extras : Viewer for OpenStreetMap "fixme" Tags

Routino Extras : Viewer for OpenStreetMap "fixme" Tags

routino-3.0/extras/find-fixme/web/www/fixme.leaflet.js 644 233 144 31554 12272743374 16304 0// // Routino (extras) fixme web page Javascript // // Part of the Routino routing software. // // This file Copyright 2008-2014 Andrew M. Bishop // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . // //////////////////////////////////////////////////////////////////////////////// /////////////////////////////// Initialisation ///////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // Process the URL query string and extract the arguments var legal={"^lon" : "^[-0-9.]+$", "^lat" : "^[-0-9.]+$", "^zoom" : "^[0-9]+$"}; var args={}; if(location.search.length>1) { var query,queries; query=location.search.replace(/^\?/,""); query=query.replace(/;/g,"&"); queries=query.split("&"); for(var i=0;i" + data_text + ""; document.getElementById("attribution_tile").innerHTML="" + tile_text + ""; } change_attribution(0); // Add two vectors layers (one for highlights that display behind the vectors) layerVectors = L.layerGroup(); map.addLayer(layerVectors); layerHighlights = L.layerGroup(); map.addLayer(layerHighlights); // Handle popup createPopup(); // Add a boxes layer layerBoxes = L.rectangle(map.options.maxBounds,{stroke: false, color: "#f00", weight: 1, opacity: 1.0, fill: false}); map.addLayer(layerBoxes); box=false; // Move the map map.on("moveend", updateURLs); var lon =args["lon"]; var lat =args["lat"]; var zoom=args["zoom"]; if(lon !== undefined && lat !== undefined && zoom !== undefined) { if(lonmapprops.eastedge) lon=mapprops.eastedge; if(latmapprops.northedge) lat=mapprops.northedge; if(zoommapprops.zoomin) zoom=mapprops.zoomin; map.setView(L.latLng(lat,lon),zoom); } else map.fitBounds(map.options.maxBounds); // Unhide editing URL if variable set if(mapprops.editurl !== undefined && mapprops.editurl !== "") { var edit_url=document.getElementById("edit_url"); edit_url.style.display=""; edit_url.href=mapprops.editurl; } updateURLs(); } // // Format a number in printf("%.5f") format. // function format5f(number) { var newnumber=Math.floor(number*100000+0.5); var delta=0; if(newnumber>=0 && newnumber<100000) delta= 100000; if(newnumber<0 && newnumber>-100000) delta=-100000; var string=String(newnumber+delta); var intpart =string.substring(0,string.length-5); var fracpart=string.substring(string.length-5,string.length); if(delta>0) intpart="0"; if(delta<0) intpart="-0"; return(intpart + "." + fracpart); } // // Build a set of URL arguments for the map location // function buildMapArguments() { var lonlat = map.getCenter(); var zoom = map.getZoom(); return "lat=" + format5f(lonlat.lat) + ";lon=" + format5f(lonlat.lng) + ";zoom=" + zoom; } // // Update the URLs // function updateURLs() { var mapargs=buildMapArguments(); var links=document.getElementsByTagName("a"); for(var i=0; i" + id + "'"); } } } drawPopup(string.split("><").join(">
<").split("
<tag").join("
  <tag")); } //////////////////////////////////////////////////////////////////////////////// /////////////////////////////// Server handling //////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // // Define an AJAX request object // function ajaxGET(url,success,failure,state) { var ajaxRequest=new XMLHttpRequest(); function ajaxGOT(options) { if(this.readyState==4) if(this.status==200) { if(typeof(options.success)=="function") options.success(this,options.state); } else { if(typeof(options.failure)=="function") options.failure(this,options.state); } } ajaxRequest.onreadystatechange = function(){ ajaxGOT.call(ajaxRequest,{success: success, failure: failure, state: state}); }; ajaxRequest.open("GET", url, true); ajaxRequest.send(null); } // // Display the status // function displayStatus(type,subtype,content) { var child=document.getElementById("result_status").firstChild; do { if(child.id !== undefined) child.style.display="none"; child=child.nextSibling; } while(child !== null); var chosen_status=document.getElementById("result_status_" + type); chosen_status.style.display=""; if(subtype !== undefined) { var format_status=document.getElementById("result_status_" + subtype).innerHTML; chosen_status.innerHTML=format_status.replace("#",String(content)); } } // // Display data statistics // function displayStatistics() { // Use AJAX to get the statistics ajaxGET("fixme.cgi?statistics=yes", runStatisticsSuccess); } // // Success in running data statistics generation. // function runStatisticsSuccess(response) { document.getElementById("statistics_data").innerHTML="
" + response.responseText + "
"; document.getElementById("statistics_link").style.display="none"; } // // Get the requested data // function displayData(datatype) // called from fixme.html { // Delete the old data unselectFeature(); layerVectors.clearLayers(); layerHighlights.clearLayers(); layerBoxes.setStyle({stroke:false}); box=false; // Print the status displayStatus("no_data"); // Return if just here to clear the data if(datatype === "") return; // Get the new data var mapbounds=map.getBounds(); var url="fixme.cgi"; url=url + "?lonmin=" + format5f(mapbounds.getWest()); url=url + ";latmin=" + format5f(mapbounds.getSouth()); url=url + ";lonmax=" + format5f(mapbounds.getEast()); url=url + ";latmax=" + format5f(mapbounds.getNorth()); url=url + ";data=" + datatype; // Use AJAX to get the data ajaxGET(url, runFixmeSuccess, runFailure); } // // Success in getting the error log data // function runFixmeSuccess(response) { var lines=response.responseText.split("\n"); for(var line=0;line. # use strict; # Use the directory paths script require "paths.pl"; # Use the perl CGI module use CGI ':cgi'; # Create the query and get the parameters my $query=new CGI; my @rawparams=$query->param; # Legal CGI parameters with regexp validity check my %legalparams=( "latmin" => "[-0-9.]+", "latmax" => "[-0-9.]+", "lonmin" => "[-0-9.]+", "lonmax" => "[-0-9.]+", "data" => "fixmes", "dump" => "fixme[0-9]+", "statistics" => "yes" ); # Validate the CGI parameters, ignore invalid ones my %cgiparams=(); foreach my $key (@rawparams) { foreach my $test (keys (%legalparams)) { if($key =~ m%^$test$%) { my $value=$query->param($key); if($value =~ m%^$legalparams{$test}$%) { $cgiparams{$key}=$value; last; } } } } # Data, dump or statistics? my $params=""; my $data =$cgiparams{"data"}; my $dump =$cgiparams{"dump"}; my $statistics=$cgiparams{"statistics"}; if(!defined $data && !defined $dump && !defined $statistics) { print header(-status => '500 Invalid CGI parameters'); exit; } if(defined $statistics) { # Print the output print header('text/plain'); # Set the parameters $params.=" --statistics"; } elsif(defined $data) { # Parameters to limit range selected my $limits=0.5; # Check the parameters my $latmin=$cgiparams{"latmin"}; my $latmax=$cgiparams{"latmax"}; my $lonmin=$cgiparams{"lonmin"}; my $lonmax=$cgiparams{"lonmax"}; if($latmin eq "" || $latmax eq "" || $lonmin eq "" || $lonmax eq "" || $data eq "") { print header(-status => '500 Invalid CGI parameters'); exit; } if(($latmax-$latmin)>$limits || ($lonmax-$lonmin)>$limits) { print header(-status => '500 Selected area too large'); exit; } # Print the output print header('text/plain'); print "$latmin $lonmin $latmax $lonmax\n"; # Set the parameters $params.=" --visualiser --data=$data"; $params.=" --latmin=$latmin --latmax=$latmax --lonmin=$lonmin --lonmax=$lonmax"; } else { # Print the output print header('text/plain'); # Set the parameters $params.=" --dump-visualiser --data=$dump"; } # Run the filedumper $params.=" --dir=$main::data_dir" if($main::data_dir); $params.=" --prefix=$main::data_prefix" if($main::data_prefix); system "$main::bin_dir/$main::fixme_dumper_exe $params 2>&1"; routino-3.0/extras/find-fixme/web/www/paths.pl 644 233 144 2172 12153665547 14654 0# # Routino CGI paths Perl script # # Part of the Routino routing software. # # This file Copyright 2008-2013 Andrew M. Bishop # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # # Directory path parameters # EDIT THIS to set the root directory for the non-web data files. $root_dir=".."; # EDIT THIS to change the location of the individual directories. $bin_dir="$root_dir/bin"; $data_dir="$root_dir/data"; # EDIT THIS to change the name of the executable (enables easy selection of slim mode). $fixme_dumper_exe="fixme-dumper"; 1; routino-3.0/extras/find-fixme/osmparser.c 644 233 144 20176 12563633050 13767 0/*************************************** OSM file parser (either JOSM or planet) Part of the Routino routing software. ******************/ /****************** This file Copyright 2008-2015 Andrew M. Bishop This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . ***************************************/ #include #include #include #include "types.h" #include "typesx.h" #include "nodesx.h" #include "waysx.h" #include "relationsx.h" #include "osmparser.h" #include "tagging.h" #include "logging.h" /* Local parsing variables (re-initialised for each file) */ static NodesX *nodes; static WaysX *ways; static RelationsX *relations; static node_t *way_nodes; static int way_nnodes; static node_t *relation_nodes; static int relation_nnodes; static way_t *relation_ways; static int relation_nways; static relation_t *relation_relations; static int relation_nrelations; /*++++++++++++++++++++++++++++++++++++++ Initialise the OSM parser by initialising the local variables. NodesX *OSMNodes The data structure of nodes to fill in. WaysX *OSMWays The data structure of ways to fill in. RelationsX *OSMRelations The data structure of relations to fill in. ++++++++++++++++++++++++++++++++++++++*/ void InitialiseParser(NodesX *OSMNodes,WaysX *OSMWays,RelationsX *OSMRelations) { /* Copy the function parameters and initialise the variables */ nodes=OSMNodes; ways=OSMWays; relations=OSMRelations; way_nodes=(node_t*)malloc(256*sizeof(node_t)); relation_nodes =(node_t *)malloc(256*sizeof(node_t)); relation_ways =(way_t *)malloc(256*sizeof(way_t)); relation_relations=(relation_t*)malloc(256*sizeof(relation_t)); } /*++++++++++++++++++++++++++++++++++++++ Clean up the memory after parsing. ++++++++++++++++++++++++++++++++++++++*/ void CleanupParser(void) { /* Free the variables */ free(way_nodes); free(relation_nodes); free(relation_ways); free(relation_relations); } /*++++++++++++++++++++++++++++++++++++++ Add node references to a way. int64_t node_id The node ID to add or zero to clear the list. ++++++++++++++++++++++++++++++++++++++*/ void AddWayRefs(int64_t node_id) { if(node_id==0) way_nnodes=0; else { node_t id; if(way_nnodes && (way_nnodes%256)==0) way_nodes=(node_t*)realloc((void*)way_nodes,(way_nnodes+256)*sizeof(node_t)); id=(node_t)node_id; logassert((int64_t)id==node_id,"Node ID too large (change node_t to 64-bits?)"); /* check node id can be stored in node_t data type. */ way_nodes[way_nnodes++]=id; } } /*++++++++++++++++++++++++++++++++++++++ Add node, way or relation references to a relation. int64_t node_id The node ID to add or zero if it is not a node. int64_t way_id The way ID to add or zero if it is not a way. int64_t relation_id The relation ID to add or zero if it is not a relation. const char *role The role played by this referenced item or NULL. If all of node_id, way_id and relation_id are zero then the list is cleared. ++++++++++++++++++++++++++++++++++++++*/ void AddRelationRefs(int64_t node_id,int64_t way_id,int64_t relation_id,const char *role) { if(node_id==0 && way_id==0 && relation_id==0) { relation_nnodes=0; relation_nways=0; relation_nrelations=0; } else if(node_id!=0) { node_t id; id=(node_t)node_id; logassert((int64_t)id==node_id,"Node ID too large (change node_t to 64-bits?)"); /* check node id can be stored in node_t data type. */ if(relation_nnodes && (relation_nnodes%256)==0) relation_nodes=(node_t*)realloc((void*)relation_nodes,(relation_nnodes+256)*sizeof(node_t)); relation_nodes[relation_nnodes++]=id; } else if(way_id!=0) { way_t id; id=(way_t)way_id; logassert((int64_t)id==way_id,"Way ID too large (change way_t to 64-bits?)"); /* check way id can be stored in way_t data type. */ if(relation_nways && (relation_nways%256)==0) relation_ways=(way_t*)realloc((void*)relation_ways,(relation_nways+256)*sizeof(way_t)); relation_ways[relation_nways++]=id; } else /* if(relation_id!=0) */ { relation_t id; id=(relation_t)relation_id; logassert((int64_t)id==relation_id,"Relation ID too large (change relation_t to 64-bits?)"); /* check relation id can be stored in relation_t data type. */ if(relation_nrelations && (relation_nrelations%256)==0) relation_relations=(relation_t*)realloc((void*)relation_relations,(relation_nrelations+256)*sizeof(relation_t)); relation_relations[relation_nrelations++]=relation_id; } } /*++++++++++++++++++++++++++++++++++++++ Process the tags associated with a node. TagList *tags The list of node tags. int64_t node_id The id of the node. double latitude The latitude of the node. double longitude The longitude of the node. int mode The mode of operation to take (create, modify, delete). ++++++++++++++++++++++++++++++++++++++*/ void ProcessNodeTags(TagList *tags,int64_t node_id,double latitude,double longitude,int mode) { node_t id; int i; /* Convert id */ id=(node_t)node_id; logassert((int64_t)id==node_id,"Node ID too large (change node_t to 64-bits?)"); /* check node id can be stored in node_t data type. */ /* Parse the tags */ for(i=0;intags;i++) { char *k=tags->k[i]; if(!strcmp(k,"fixme-finder:keep")) { DeleteTag(tags,"fixme-finder:keep"); logerror("%s\n",logerror_node(id),StringifyTag(tags)); } } /* Store the node */ AppendNodeList(nodes,id,degrees_to_radians(latitude),degrees_to_radians(longitude),0,0); } /*++++++++++++++++++++++++++++++++++++++ Process the tags associated with a way. TagList *tags The list of way tags. int64_t way_id The id of the way. int mode The mode of operation to take (create, modify, delete). ++++++++++++++++++++++++++++++++++++++*/ void ProcessWayTags(TagList *tags,int64_t way_id,int mode) { Way way={0}; way_t id; int i; /* Convert id */ id=(way_t)way_id; logassert((int64_t)id==way_id,"Way ID too large (change way_t to 64-bits?)"); /* check way id can be stored in way_t data type. */ /* Parse the tags */ for(i=0;intags;i++) { char *k=tags->k[i]; if(!strcmp(k,"fixme-finder:keep")) { DeleteTag(tags,"fixme-finder:keep"); logerror("%s\n",logerror_way(id),StringifyTag(tags)); } } /* Store the way */ AppendWayList(ways,id,&way,way_nodes,way_nnodes,""); } /*++++++++++++++++++++++++++++++++++++++ Process the tags associated with a relation. TagList *tags The list of relation tags. int64_t relation_id The id of the relation. int mode The mode of operation to take (create, modify, delete). ++++++++++++++++++++++++++++++++++++++*/ void ProcessRelationTags(TagList *tags,int64_t relation_id,int mode) { relation_t id; int i; /* Convert id */ id=(relation_t)relation_id; logassert((int64_t)id==relation_id,"Relation ID too large (change relation_t to 64-bits?)"); /* check relation id can be stored in relation_t data type. */ /* Parse the tags */ for(i=0;intags;i++) { char *k=tags->k[i]; if(!strcmp(k,"fixme-finder:keep")) { DeleteTag(tags,"fixme-finder:keep"); logerror("%s\n",logerror_relation(id),StringifyTag(tags)); } } /* Store the relation */ AppendRouteRelationList(relations,id,0, relation_nodes,relation_nnodes, relation_ways,relation_nways, relation_relations,relation_nrelations); } routino-3.0/extras/Makefile 644 233 144 2657 12313271770 11206 0# Extra files Makefile # # Part of the Routino routing software. # # This file Copyright 2013 Andrew M. Bishop # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # # All configuration is in the top-level Makefile.conf include ../Makefile.conf # Sub-directories and sub-makefiles SUBFILES=$(wildcard */Makefile) SUBDIRS=$(foreach f,$(SUBFILES),$(dir $f)) ######## all: for dir in $(SUBDIRS); do \ ( cd $$dir && $(MAKE) $@ ); \ done ######## test: for dir in $(SUBDIRS); do \ ( cd $$dir && $(MAKE) $@ ); \ done ######## install: for dir in $(SUBDIRS); do \ ( cd $$dir && $(MAKE) $@ ); \ done ######## clean: for dir in $(SUBDIRS); do \ ( cd $$dir && $(MAKE) $@ ); \ done ######## distclean: for dir in $(SUBDIRS); do \ ( cd $$dir && $(MAKE) $@ ); \ done ######## .PHONY:: all test install clean distclean routino-3.0/extras/README.txt 644 233 144 2557 12225317162 11241 0 ROUTINO EXTRAS ============== This directory contains some programs and scripts that although distributed with Routino are not necessary components of a working OSM router. They are generally either programs that use some components of Routino (i.e. they are compiled and linked with some of the Routino source code) or they are scripts to be used to process the outputs of Routino. Each program or script has its own directory which contains all of the necessary source code, documentation and/or web pages for that program or script. None of them will be installed when Routino is installed. -------------------------------------------------------------------------------- tagmodifier - A program to read an OSM XML file and process it using a Routino tagging rules file to create a modified output XML file. errorlog - Scripts for processing the error log file (created by running planetsplitter with the --errorlog option). plot-time - Plots the output of 'planetsplitter --loggable --logtime' to show how long each part of the processing takes. find-fixme - A modified version of the Routino planetsplitter and filedumper programs to scan an OSM file for "fixme" tags and create a database so that web pages provided can display them. routino-3.0/extras/errorlog/ 40755 233 144 0 12306670017 11352 5routino-3.0/extras/errorlog/summarise-log.pl 755 233 144 22600 12306670017 14532 0#!/usr/bin/perl # # Routino log summary tool. # # Part of the Routino routing software. # # This file Copyright 2011-2014 Andrew M. Bishop # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # use strict; # Command line my $verbose=0; $verbose=1 if($#ARGV==0 && $ARGV[0] eq "-v"); my $html=0; $html=1 if($#ARGV==0 && $ARGV[0] eq "-html"); die "Usage: $0 [-v | -html] < \n" if($#ARGV>0 || ($#ARGV==0 && !$verbose && !$html)); # Read in each line from the error log and store them my %errors=(); my %errorids=(); my %errortypes=(); while() { s%\r*\n%%; my $errorid=""; my $errortype=""; if(m%nodes ([0-9]+) and ([0-9]+) in way ([0-9]+)%i) # Special case pair of nodes and a way { $errorid="($1 $2 $3)"; $errortype="N2W"; s%nodes [0-9]+ and [0-9]+ in way [0-9]+%nodes and in way %; } elsif(m%node ([0-9]+) in way ([0-9]+)%i) # Special case node and a way { $errorid="($1 $2)"; $errortype="NW"; s%Node [0-9]+ in way [0-9]+%Node in way %; } elsif(m%way ([0-9]+) contains node ([0-9]+)%i) # Special case way and node { $errorid="($1 $2)"; $errortype="WN"; s%Way [0-9]+ contains node [0-9]+%Way contains node %; } elsif(m%nodes ([0-9]+) and ([0-9]+)%i) # Special case pair of nodes { $errorid="($1 $2)"; $errortype="N2"; s%nodes [0-9]+ and [0-9]+%nodes and %; } elsif(m%Segment (contains|connects) node ([0-9]+)%) # Special case node { $errorid=$2; $errortype="N"; s%node [0-9]+%node %; } elsif(m%Relation ([0-9]+).* contains Node ([0-9]+)%) # Special case relation/node { $errorid="($1 $2)"; $errortype="RN"; s%Relation [0-9]+%Relation %; s%Node [0-9]+%node %; } elsif(m%Relation ([0-9]+).* contains Way ([0-9]+)%) # Generic case relation/way { $errorid="($1 $2)"; $errortype="RW"; s%Relation [0-9]+%Relation %; s%Way [0-9]+%way %; } elsif(!m%Way ([0-9]+)% && !m%Relation ([0-9]+)% && m%Node ([0-9]+)%) # Generic node { $errorid=$1; $errortype="N"; s%Node [0-9]+%Node %; } elsif(!m%Node ([0-9]+)% && !m%Relation ([0-9]+)% && m%Way ([0-9]+)%) # Generic way { $errorid=$1; $errortype="W"; s%Way [0-9]+%Way %; } elsif(!m%Node ([0-9]+)% && !m%Way ([0-9]+)% && m%Relation ([0-9]+)%) # Generic relation { $errorid=$1; $errortype="R"; s%Relation [0-9]+%Relation %; } else { $errorid="ERROR"; $errortype="E"; warn "Unrecognised error message '$_'\n"; } $errors{$_}++; if($verbose || $html) { if(defined $errorids{$_}) { push(@{$errorids{$_}},$errorid); } else { $errorids{$_}=[$errorid]; } } if($html) { $errortypes{$_}=$errortype; } } # Print out the results as text if( ! $html ) { foreach my $error (sort { if ( $errors{$b} == $errors{$a} ) { return $errors{$a} cmp $errors{$b} } else { return $errors{$b} <=> $errors{$a} } } (keys %errors)) { printf "%9d : $error\n",$errors{$error}; if($verbose) { my @ids=sort({ return $a <=> $b } @{$errorids{$error}}); print " ".join(",",@ids)."\n"; } } } # Print out the results as HTML else { print "\n". "\n". "\n". "\n". "Routino Error Log File Summary\n". "\n". "\n". "\n". "\n". "\n". "\n". "

Routino Error Log File Summary

\n". "\n". "This HTML file contains a summary of the Routino OSM parser error log file with\n". "links to the OSM website that allow browsing each of the nodes, ways or relations\n". "that are responsible for the error messages.\n". "\n"; my %errortypeorder=( "N" , 1, "NW" , 2, "WN" , 3, "N2W" , 4, "N2" , 5, "W" , 6, "R" , 7, "RN" , 8, "RW" , 9, "E" , 10 ); my %errortypelabel=( "N" , "Nodes", "NW" , "Node in a Way", "WN" , "Way contains Node", "N2W" , "Node Pairs in a Way", "N2" , "Node Pairs", "W" , "Ways", "R" , "Relations", "RN" , "Relations/Nodes", "RW" , "Relations/Ways", "E" , "ERROR" ); my $lasterrortype=""; foreach my $error (sort { if ( $errortypes{$b} ne $errortypes{$a} ) { return $errortypeorder{$errortypes{$a}} <=> $errortypeorder{$errortypes{$b}} } elsif ( $errors{$b} == $errors{$a} ) { return $errors{$a} cmp $errors{$b} } else { return $errors{$b} <=> $errors{$a} } } (keys %errors)) { my $errorhtml=$error; $errorhtml =~ s/&/&/g; $errorhtml =~ s//>/g; if($errortypes{$error} ne $lasterrortype) { print "

$errortypelabel{$errortypes{$error}}

\n"; $lasterrortype=$errortypes{$error}; } print "

$errorhtml

\n"; if($errors{$error}>100) { print "$errors{$error} occurences (not listed).\n"; } else { my @ids=sort({ return $a <=> $b } @{$errorids{$error}}); my $first=1; foreach my $id (@ids) { if($first) { print "$errortypelabel{$errortypes{$error}}:\n"; } else { print ","; } $first=0; print "$id" if($errortypes{$error} eq "N"); print "$id" if($errortypes{$error} eq "W"); print "$id" if($errortypes{$error} eq "R"); if($errortypes{$error} eq "NW" || $errortypes{$error} eq "WN" || $errortypes{$error} eq "N2" || $errortypes{$error} eq "RN" || $errortypes{$error} eq "RW") { $id =~ m%\(([0-9]+) ([0-9]+)\)%; print "($1 $2)" if($errortypes{$error} eq "NW"); print "($1 $2)" if($errortypes{$error} eq "WN"); print "($1 $2)" if($errortypes{$error} eq "N2"); print "($1 $2)" if($errortypes{$error} eq "RN"); print "($1 $2)" if($errortypes{$error} eq "RW"); } if($errortypes{$error} eq "N2W") { $id =~ m%\(([0-9]+) ([0-9]+) ([0-9]+)\)%; print "($1 $2 $3)" if($errortypes{$error} eq "N2W"); } print "\n"; } } } print "\n". "\n". "\n". "\n"; } routino-3.0/extras/errorlog/README.txt 644 233 144 1532 12152437721 13067 0 Error Log Summariser ==================== This Perl script can be used to process the log file generated by runing 'planetsplitter --errorlog' and generate a summary of the most common types of errors. summarise-log.pl ---------------- Example usage: summarise-log.pl < error.log Generate a summary of the number of each type of error that appear in the error log file as plain text. summarise-log.pl -v < error.log Generate a verbose version of the plain text summary of errors with each error item (node, way or relation) listed. summarise-log.pl -html < error.log Generate an HTML file with a summary of the number of errors of each type with links to each of the items (node, way or relation) on the OSM website. routino-3.0/extras/plot-time/ 40755 233 144 0 12306670050 11426 5routino-3.0/extras/plot-time/README.txt 644 233 144 1001 12152440020 13117 0 Planetsplitter Execution Time Analysis ====================================== A Perl script that uses Gnuplot to plot a graph of the time taken by the planetsplitter program to run. plot-planetsplitter-time.pl --------------------------- Example usage: planetsplitter --loggable --logtime ... > planetsplitter.log plot-planetsplitter-time.pl < planetsplitter.log This will generate a file called planetsplitter.png that contains the graph of the execution time. routino-3.0/extras/plot-time/plot-planetsplitter-time.pl 755 233 144 4665 12306670050 16777 0#!/usr/bin/perl # # Routino execution log plotter. # # Part of the Routino routing software. # # This file Copyright 2013-2014 Andrew M. Bishop # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # use strict; # Read the planetsplitter log file open(SECTION ,">gnuplot.section.tmp"); open(SUBSECTION,">gnuplot.subsection.tmp"); my $count=1; my $startcount=0; my $totaltime=0; while() { s%\r*\n%%; next if(! $_); next if(m%^=%); if( m%^\[ *([0-9]+):([0-9.]+)\] ([^:]+)% && ! m%Complete$% ) { my $time=(60.0*$1)+$2; my $description=$3; print SUBSECTION "$count $time \"$description\"\n"; $totaltime+=$time; } else { if($startcount>0) { my $boxcentre=($count+$startcount+0.5)/2; my $boxwidth=$count-$startcount-1; print SECTION "$boxcentre $totaltime $boxwidth\n"; } $startcount=$count-0.5; $totaltime=0; } $count++; } close(SECTION); close(SUBSECTION); # Plot using gnuplot open(GNUPLOT,"|gnuplot"); print GNUPLOT <. ***************************************/ #include #include #include #include #include #include #include "version.h" #include "xmlparse.h" #include "tagging.h" #include "files.h" #include "uncompress.h" /* Local variables (re-initialised for each file) */ static uint64_t nnodes,nways,nrelations; TagList *current_tags; /* Local functions */ static void print_usage(int detail,const char *argerr,const char *err); /* The XML tag processing function prototypes */ static int xmlDeclaration_function(const char *_tag_,int _type_,const char *version,const char *encoding); static int osmType_function(const char *_tag_,int _type_,const char *version,const char *generator); static int relationType_function(const char *_tag_,int _type_,const char *id,const char *timestamp,const char *uid,const char *user,const char *visible,const char *version,const char *action); static int wayType_function(const char *_tag_,int _type_,const char *id,const char *timestamp,const char *uid,const char *user,const char *visible,const char *version,const char *action); static int memberType_function(const char *_tag_,int _type_,const char *type,const char *ref,const char *role); static int ndType_function(const char *_tag_,int _type_,const char *ref); static int nodeType_function(const char *_tag_,int _type_,const char *id,const char *lat,const char *lon,const char *timestamp,const char *uid,const char *user,const char *visible,const char *version,const char *action); static int tagType_function(const char *_tag_,int _type_,const char *k,const char *v); static int boundType_function(const char *_tag_,int _type_,const char *box,const char *origin); static int boundsType_function(const char *_tag_,int _type_,const char *minlat,const char *minlon,const char *maxlat,const char *maxlon,const char *origin); /* The XML tag definitions */ /*+ The boundsType type tag. +*/ static const xmltag boundsType_tag= {"bounds", 5, {"minlat","minlon","maxlat","maxlon","origin"}, boundsType_function, {NULL}}; /*+ The boundType type tag. +*/ static const xmltag boundType_tag= {"bound", 2, {"box","origin"}, boundType_function, {NULL}}; /*+ The tagType type tag. +*/ static const xmltag tagType_tag= {"tag", 2, {"k","v"}, tagType_function, {NULL}}; /*+ The nodeType type tag. +*/ static const xmltag nodeType_tag= {"node", 9, {"id","lat","lon","timestamp","uid","user","visible","version","action"}, nodeType_function, {&tagType_tag,NULL}}; /*+ The ndType type tag. +*/ static const xmltag ndType_tag= {"nd", 1, {"ref"}, ndType_function, {NULL}}; /*+ The memberType type tag. +*/ static const xmltag memberType_tag= {"member", 3, {"type","ref","role"}, memberType_function, {NULL}}; /*+ The wayType type tag. +*/ static const xmltag wayType_tag= {"way", 7, {"id","timestamp","uid","user","visible","version","action"}, wayType_function, {&ndType_tag,&tagType_tag,NULL}}; /*+ The relationType type tag. +*/ static const xmltag relationType_tag= {"relation", 7, {"id","timestamp","uid","user","visible","version","action"}, relationType_function, {&memberType_tag,&tagType_tag,NULL}}; /*+ The osmType type tag. +*/ static const xmltag osmType_tag= {"osm", 2, {"version","generator"}, osmType_function, {&boundsType_tag,&boundType_tag,&nodeType_tag,&wayType_tag,&relationType_tag,NULL}}; /*+ The xmlDeclaration type tag. +*/ static const xmltag xmlDeclaration_tag= {"xml", 2, {"version","encoding"}, xmlDeclaration_function, {NULL}}; /*+ The complete set of tags at the top level. +*/ static const xmltag *const xml_toplevel_tags[]={&xmlDeclaration_tag,&osmType_tag,NULL}; /* The XML tag processing functions */ /*++++++++++++++++++++++++++++++++++++++ The function that is called when the boundsType XSD type is seen int boundsType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *minlat The contents of the 'minlat' attribute (or NULL if not defined). const char *minlon The contents of the 'minlon' attribute (or NULL if not defined). const char *maxlat The contents of the 'maxlat' attribute (or NULL if not defined). const char *maxlon The contents of the 'maxlon' attribute (or NULL if not defined). const char *origin The contents of the 'origin' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int boundsType_function(const char *_tag_,int _type_,const char *minlat,const char *minlon,const char *maxlat,const char *maxlon,const char *origin) { printf(" <%s%s",(_type_==XMLPARSE_TAG_END)?"/":"",_tag_); if(minlat) printf(" minlat='%s'",ParseXML_Encode_Safe_XML(minlat)); if(minlon) printf(" minlon='%s'",ParseXML_Encode_Safe_XML(minlon)); if(maxlat) printf(" maxlat='%s'",ParseXML_Encode_Safe_XML(maxlat)); if(maxlon) printf(" maxlon='%s'",ParseXML_Encode_Safe_XML(maxlon)); if(origin) printf(" origin='%s'",ParseXML_Encode_Safe_XML(origin)); printf("%s>\n",(_type_==(XMLPARSE_TAG_START|XMLPARSE_TAG_END))?" /":""); return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the boundType XSD type is seen int boundType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *box The contents of the 'box' attribute (or NULL if not defined). const char *origin The contents of the 'origin' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int boundType_function(const char *_tag_,int _type_,const char *box,const char *origin) { printf(" <%s%s",(_type_==XMLPARSE_TAG_END)?"/":"",_tag_); if(box) printf(" box='%s'",ParseXML_Encode_Safe_XML(box)); if(origin) printf(" origin='%s'",ParseXML_Encode_Safe_XML(origin)); printf("%s>\n",(_type_==(XMLPARSE_TAG_START|XMLPARSE_TAG_END))?" /":""); return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the tagType XSD type is seen int tagType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *k The contents of the 'k' attribute (or NULL if not defined). const char *v The contents of the 'v' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int tagType_function(const char *_tag_,int _type_,const char *k,const char *v) { if(_type_&XMLPARSE_TAG_START) { XMLPARSE_ASSERT_STRING(_tag_,k); XMLPARSE_ASSERT_STRING(_tag_,v); AppendTag(current_tags,k,v); } return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the nodeType XSD type is seen int nodeType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *id The contents of the 'id' attribute (or NULL if not defined). const char *lat The contents of the 'lat' attribute (or NULL if not defined). const char *lon The contents of the 'lon' attribute (or NULL if not defined). const char *timestamp The contents of the 'timestamp' attribute (or NULL if not defined). const char *uid The contents of the 'uid' attribute (or NULL if not defined). const char *user The contents of the 'user' attribute (or NULL if not defined). const char *visible The contents of the 'visible' attribute (or NULL if not defined). const char *version The contents of the 'version' attribute (or NULL if not defined). const char *action The contents of the 'action' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int nodeType_function(const char *_tag_,int _type_,const char *id,const char *lat,const char *lon,const char *timestamp,const char *uid,const char *user,const char *visible,const char *version,const char *action) { static int64_t llid; /* static variable to store attributes from tag until tag */ if(_type_&XMLPARSE_TAG_START) { nnodes++; if(!(nnodes%10000)) fprintf_middle(stderr,"Reading: Lines=%"PRIu64" Nodes=%"PRIu64" Ways=%"PRIu64" Relations=%"PRIu64,ParseXML_LineNumber(),nnodes,nways,nrelations); current_tags=NewTagList(); /* Handle the node information */ XMLPARSE_ASSERT_INTEGER(_tag_,id); llid=atoll(id); /* need int64_t conversion */ } if(_type_&XMLPARSE_TAG_END) { TagList *result=ApplyNodeTaggingRules(current_tags,llid); int i; for(i=0;intags;i++) { printf(" k[i])); printf(" v='%s'",ParseXML_Encode_Safe_XML(result->v[i])); printf(" />\n"); } DeleteTagList(current_tags); DeleteTagList(result); } printf(" <%s%s",(_type_==XMLPARSE_TAG_END)?"/":"",_tag_); if(id) printf(" id='%s'",ParseXML_Encode_Safe_XML(id)); if(lat) printf(" lat='%s'",ParseXML_Encode_Safe_XML(lat)); if(lon) printf(" lon='%s'",ParseXML_Encode_Safe_XML(lon)); if(timestamp) printf(" timestamp='%s'",ParseXML_Encode_Safe_XML(timestamp)); if(uid) printf(" uid='%s'",ParseXML_Encode_Safe_XML(uid)); if(user) printf(" user='%s'",ParseXML_Encode_Safe_XML(user)); if(visible) printf(" visible='%s'",ParseXML_Encode_Safe_XML(visible)); if(version) printf(" version='%s'",ParseXML_Encode_Safe_XML(version)); if(action) printf(" action='%s'",ParseXML_Encode_Safe_XML(action)); printf("%s>\n",(_type_==(XMLPARSE_TAG_START|XMLPARSE_TAG_END))?" /":""); return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the ndType XSD type is seen int ndType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *ref The contents of the 'ref' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int ndType_function(const char *_tag_,int _type_,const char *ref) { printf(" <%s%s",(_type_==XMLPARSE_TAG_END)?"/":"",_tag_); if(ref) printf(" ref='%s'",ParseXML_Encode_Safe_XML(ref)); printf("%s>\n",(_type_==(XMLPARSE_TAG_START|XMLPARSE_TAG_END))?" /":""); return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the memberType XSD type is seen int memberType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *type The contents of the 'type' attribute (or NULL if not defined). const char *ref The contents of the 'ref' attribute (or NULL if not defined). const char *role The contents of the 'role' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int memberType_function(const char *_tag_,int _type_,const char *type,const char *ref,const char *role) { printf(" <%s%s",(_type_==XMLPARSE_TAG_END)?"/":"",_tag_); if(type) printf(" type='%s'",ParseXML_Encode_Safe_XML(type)); if(ref) printf(" ref='%s'",ParseXML_Encode_Safe_XML(ref)); if(role) printf(" role='%s'",ParseXML_Encode_Safe_XML(role)); printf("%s>\n",(_type_==(XMLPARSE_TAG_START|XMLPARSE_TAG_END))?" /":""); return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the wayType XSD type is seen int wayType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *id The contents of the 'id' attribute (or NULL if not defined). const char *timestamp The contents of the 'timestamp' attribute (or NULL if not defined). const char *uid The contents of the 'uid' attribute (or NULL if not defined). const char *user The contents of the 'user' attribute (or NULL if not defined). const char *visible The contents of the 'visible' attribute (or NULL if not defined). const char *version The contents of the 'version' attribute (or NULL if not defined). const char *action The contents of the 'action' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int wayType_function(const char *_tag_,int _type_,const char *id,const char *timestamp,const char *uid,const char *user,const char *visible,const char *version,const char *action) { static int64_t llid; /* static variable to store attributes from tag until tag */ if(_type_&XMLPARSE_TAG_START) { nways++; if(!(nways%1000)) fprintf_middle(stderr,"Reading: Lines=%"PRIu64" Nodes=%"PRIu64" Ways=%"PRIu64" Relations=%"PRIu64,ParseXML_LineNumber(),nnodes,nways,nrelations); current_tags=NewTagList(); /* Handle the way information */ XMLPARSE_ASSERT_INTEGER(_tag_,id); llid=atoll(id); /* need int64_t conversion */ } if(_type_&XMLPARSE_TAG_END) { TagList *result=ApplyWayTaggingRules(current_tags,llid); int i; for(i=0;intags;i++) { printf(" k[i])); printf(" v='%s'",ParseXML_Encode_Safe_XML(result->v[i])); printf(" />\n"); } DeleteTagList(current_tags); DeleteTagList(result); } printf(" <%s%s",(_type_==XMLPARSE_TAG_END)?"/":"",_tag_); if(id) printf(" id='%s'",ParseXML_Encode_Safe_XML(id)); if(timestamp) printf(" timestamp='%s'",ParseXML_Encode_Safe_XML(timestamp)); if(uid) printf(" uid='%s'",ParseXML_Encode_Safe_XML(uid)); if(user) printf(" user='%s'",ParseXML_Encode_Safe_XML(user)); if(visible) printf(" visible='%s'",ParseXML_Encode_Safe_XML(visible)); if(version) printf(" version='%s'",ParseXML_Encode_Safe_XML(version)); if(action) printf(" action='%s'",ParseXML_Encode_Safe_XML(action)); printf("%s>\n",(_type_==(XMLPARSE_TAG_START|XMLPARSE_TAG_END))?" /":""); return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the relationType XSD type is seen int relationType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *id The contents of the 'id' attribute (or NULL if not defined). const char *timestamp The contents of the 'timestamp' attribute (or NULL if not defined). const char *uid The contents of the 'uid' attribute (or NULL if not defined). const char *user The contents of the 'user' attribute (or NULL if not defined). const char *visible The contents of the 'visible' attribute (or NULL if not defined). const char *version The contents of the 'version' attribute (or NULL if not defined). const char *action The contents of the 'action' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int relationType_function(const char *_tag_,int _type_,const char *id,const char *timestamp,const char *uid,const char *user,const char *visible,const char *version,const char *action) { static int64_t llid; /* static variable to store attributes from tag until tag */ if(_type_&XMLPARSE_TAG_START) { nrelations++; if(!(nrelations%1000)) fprintf_middle(stderr,"Reading: Lines=%"PRIu64" Nodes=%"PRIu64" Ways=%"PRIu64" Relations=%"PRIu64,ParseXML_LineNumber(),nnodes,nways,nrelations); current_tags=NewTagList(); /* Handle the relation information */ XMLPARSE_ASSERT_INTEGER(_tag_,id); llid=atoll(id); /* need int64_t conversion */ } if(_type_&XMLPARSE_TAG_END) { TagList *result=ApplyRelationTaggingRules(current_tags,llid); int i; for(i=0;intags;i++) { printf(" k[i])); printf(" v='%s'",ParseXML_Encode_Safe_XML(result->v[i])); printf(" />\n"); } DeleteTagList(current_tags); DeleteTagList(result); } printf(" <%s%s",(_type_==XMLPARSE_TAG_END)?"/":"",_tag_); if(id) printf(" id='%s'",ParseXML_Encode_Safe_XML(id)); if(timestamp) printf(" timestamp='%s'",ParseXML_Encode_Safe_XML(timestamp)); if(uid) printf(" uid='%s'",ParseXML_Encode_Safe_XML(uid)); if(user) printf(" user='%s'",ParseXML_Encode_Safe_XML(user)); if(visible) printf(" visible='%s'",ParseXML_Encode_Safe_XML(visible)); if(version) printf(" version='%s'",ParseXML_Encode_Safe_XML(version)); if(action) printf(" action='%s'",ParseXML_Encode_Safe_XML(action)); printf("%s>\n",(_type_==(XMLPARSE_TAG_START|XMLPARSE_TAG_END))?" /":""); return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the osmType XSD type is seen int osmType_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *version The contents of the 'version' attribute (or NULL if not defined). const char *generator The contents of the 'generator' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int osmType_function(const char *_tag_,int _type_,const char *version,const char *generator) { printf("<%s%s",(_type_==XMLPARSE_TAG_END)?"/":"",_tag_); if(version) printf(" version='%s'",ParseXML_Encode_Safe_XML(version)); if(generator) printf(" generator='%s'",ParseXML_Encode_Safe_XML(generator)); printf("%s>\n",(_type_==(XMLPARSE_TAG_START|XMLPARSE_TAG_END))?" /":""); return(0); } /*++++++++++++++++++++++++++++++++++++++ The function that is called when the XML declaration is seen int xmlDeclaration_function Returns 0 if no error occured or something else otherwise. const char *_tag_ Set to the name of the element tag that triggered this function call. int _type_ Set to XMLPARSE_TAG_START at the start of a tag and/or XMLPARSE_TAG_END at the end of a tag. const char *version The contents of the 'version' attribute (or NULL if not defined). const char *encoding The contents of the 'encoding' attribute (or NULL if not defined). ++++++++++++++++++++++++++++++++++++++*/ static int xmlDeclaration_function(const char *_tag_,int _type_,const char *version,const char *encoding) { printf("\n"); return(0); } /*++++++++++++++++++++++++++++++++++++++ The main program for the tagmodifier. ++++++++++++++++++++++++++++++++++++++*/ int main(int argc,char **argv) { char *tagging=NULL,*filename=NULL,*errorlog=NULL; char *p; int fd; int arg,retval; /* Parse the command line arguments */ for(arg=1;arg=0) { fprintf(stderr, "Usage: tagmodifier [--version]\n" " [--help]\n" " [--tagging=]\n" " [--loggable] [--logtime] [--logmemory]\n" " [--errorlog[=]]\n" " " #if defined(USE_BZIP2) && USE_BZIP2 " | " #endif #if defined(USE_GZIP) && USE_GZIP " | " #endif #if defined(USE_XZ) && USE_XZ " | " #endif "\n"); if(argerr) fprintf(stderr, "\n" "Error with command line parameter: %s\n",argerr); if(err) fprintf(stderr, "\n" "Error: %s\n",err); } if(detail==1) fprintf(stderr, "\n" "--version Print the version of Routino.\n" "\n" "--help Prints this information.\n" "\n" "--tagging= The name of the XML file containing the tagging rules\n" " (defaults to 'tagging.xml' in current directory).\n" "\n" "--loggable Print progress messages suitable for logging to file.\n" "--logtime Print the elapsed time for the processing.\n" "--logmemory Print the max allocated/mapped memory for each step.\n" "--errorlog[=] Log parsing errors to 'error.log' or the given name.\n" "\n" " The name of the file to process.\n" #if defined(USE_BZIP2) && USE_BZIP2 " Filenames ending '.bz2' will be bzip2 uncompressed.\n" #endif #if defined(USE_GZIP) && USE_GZIP " Filenames ending '.gz' will be gzip uncompressed.\n" #endif #if defined(USE_XZ) && USE_XZ " Filenames ending '.xz' will be xz uncompressed.\n" #endif ); exit(!detail); } routino-3.0/extras/tagmodifier/Makefile 644 233 144 3434 12563637605 13504 0# tagmodifier Makefile # # Part of the Routino routing software. # # This file Copyright 2013-2015 Andrew M. Bishop # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # # All configuration is in the top-level Makefile.conf include ../../Makefile.conf # Compilation targets C=$(wildcard *.c) D=$(wildcard .deps/*.d) ROUTINO_SRC=../../src EXE=tagmodifier$(.EXE) ######## all: $(EXE) ######## TAGMODIFIER_OBJ=tagmodifier.o \ $(ROUTINO_SRC)/files.o $(ROUTINO_SRC)/logging.o $(ROUTINO_SRC)/logerror.o \ $(ROUTINO_SRC)/uncompress.o $(ROUTINO_SRC)/xmlparse.o $(ROUTINO_SRC)/tagging.o ifeq ($(HOST),MINGW) TAGMODIFIER_OBJ+=$(ROUTINO_SRC)/mman-win32.o endif tagmodifier$(.EXE) : $(TAGMODIFIER_OBJ) $(LD) $^ -o $@ $(LDFLAGS) ######## $(ROUTINO_SRC)/%.o : cd $(ROUTINO_SRC) && $(MAKE) $(notdir $@) %.o : %.c @[ -d .deps ] || mkdir .deps $(CC) -c $(CFLAGS) -DSLIM=0 -I$(ROUTINO_SRC) $< -o $@ -MMD -MP -MF $(addprefix .deps/,$(addsuffix .d,$(basename $@))) ######## test: ######## install: ######## clean: rm -f *~ rm -f *.o rm -f $(EXE) rm -f $(D) rm -fr .deps rm -f core ######## distclean: clean ######## include $(D) ######## .PHONY:: all test install clean distclean routino-3.0/extras/tagmodifier/README.txt 644 233 144 3213 12574075511 13527 0 Tagging Rule Tester / Tag Modifier ================================== This program is used to run the tag transformation process on an OSM XML file for test purposes. This allows it to be used to test new tagging rules or to make automatic rule-based modifications to tags within an XML file. tagmodifier ----------- Usage: tagmodifier [--version] [--help] [--tagging=] [--loggable] [--logtime] [--logmemory] [--errorlog[]] [ | | | ] --version Print the version of Routino. --help Prints out the help information. --tagging= The name of the XML file containing the tagging rules (defaults to 'tagging.xml' in the current directory). --loggable Print progress messages that are suitable for logging to a file; normally an incrementing counter is printed which is more suitable for real-time display than logging. --logtime Print the elapsed time for the processing. --logmemory Print the used memory for the processing. --errorlog[=] Log parsing errors to 'error.log' or the specified file name. Specifies the filename(s) to read data from. Filenames ending '.bz2' will be bzip2 uncompressed (if bzip2 support compiled in). Filenames ending '.gz' will be gzip uncompressed (if gzip support compiled in). Filenames ending '.xz' will be xz uncompressed (if xz support compiled in).