summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Schlaeger <chris@linux.com>2015-04-12 20:22:01 +0200
committerChris Schlaeger <chris@linux.com>2015-04-12 20:22:01 +0200
commita3bc76ca40be53a47e530ed91819e9b8483de7bb (patch)
treef4641cc5c8fc105f5e7ffda4b85f890acfee9961
parent51b6bae05765a3f012b0793588644387fda06a63 (diff)
downloadpostrunner-a3bc76ca40be53a47e530ed91819e9b8483de7bb.zip
New: Adding a personal record view including yearly records.v0.0.7
-rw-r--r--lib/postrunner/ActivitiesDB.rb21
-rw-r--r--lib/postrunner/Activity.rb3
-rw-r--r--lib/postrunner/ActivityLink.rb59
-rw-r--r--lib/postrunner/ActivityListView.rb126
-rw-r--r--lib/postrunner/ActivitySummary.rb12
-rw-r--r--lib/postrunner/ActivityView.rb124
-rw-r--r--lib/postrunner/ChartView.rb30
-rw-r--r--lib/postrunner/DeviceList.rb10
-rw-r--r--lib/postrunner/FlexiTable.rb29
-rw-r--r--lib/postrunner/HTMLBuilder.rb80
-rw-r--r--lib/postrunner/NavButtonRow.rb103
-rw-r--r--lib/postrunner/PagingButtons.rb77
-rw-r--r--lib/postrunner/PersonalRecords.rb47
-rw-r--r--lib/postrunner/RecordListPageView.rb69
-rw-r--r--lib/postrunner/TrackView.rb30
-rw-r--r--lib/postrunner/UserProfileView.rb8
-rw-r--r--lib/postrunner/View.rb97
-rw-r--r--lib/postrunner/ViewBottom.rb54
-rw-r--r--lib/postrunner/ViewButtons.rb68
-rw-r--r--lib/postrunner/ViewFrame.rb93
-rw-r--r--lib/postrunner/ViewTop.rb80
-rw-r--r--lib/postrunner/ViewWidgets.rb153
-rw-r--r--misc/icons/activities.pngbin0 -> 427 bytes
-rw-r--r--misc/icons/activities.svg1582
-rw-r--r--spec/View_spec.rb61
25 files changed, 2616 insertions, 400 deletions
diff --git a/lib/postrunner/ActivitiesDB.rb b/lib/postrunner/ActivitiesDB.rb
index f63e30a..b6516e7 100644
--- a/lib/postrunner/ActivitiesDB.rb
+++ b/lib/postrunner/ActivitiesDB.rb
@@ -18,12 +18,13 @@ require 'postrunner/BackedUpFile'
require 'postrunner/Activity'
require 'postrunner/PersonalRecords'
require 'postrunner/ActivityListView'
+require 'postrunner/ViewButtons'
module PostRunner
class ActivitiesDB
- attr_reader :db_dir, :cfg, :fit_dir, :activities, :records
+ attr_reader :db_dir, :cfg, :fit_dir, :activities, :records, :views
def initialize(db_dir, cfg)
@db_dir = db_dir
@@ -59,6 +60,14 @@ module PostRunner
sync_needed |= !a.fit_activity.nil?
end
+ # Define which View objects the HTML output will contain off. This
+ # doesn't really belong in ActivitiesDB but for now it's the best place
+ # to put it.
+ @views = ViewButtons.new([
+ NavButtonDef.new('activities.png', 'index.html'),
+ NavButtonDef.new('record.png', "records-0.html")
+ ])
+
@records = PersonalRecords.new(self)
sync if sync_needed
end
@@ -164,12 +173,12 @@ module PostRunner
def check
@records.delete_all_records
- @activities.sort! do |a1, a2|
+ @activities.sort do |a1, a2|
a1.timestamp <=> a2.timestamp
end.each { |a| a.check }
@records.sync
# Ensure that HTML index is up-to-date.
- ActivityListView.new(self).update_html_index
+ ActivityListView.new(self).update_index_pages
end
def ref_by_fit_file(fit_file)
@@ -265,7 +274,7 @@ module PostRunner
# Show the activity list in a web browser.
def show_list_in_browser
- ActivityListView.new(self).update_html_index
+ ActivityListView.new(self).update_index_pages
show_in_browser(File.join(@cfg[:html_dir], 'index.html'))
end
@@ -300,7 +309,7 @@ module PostRunner
@activities.each { |a| a.generate_html_view }
Log.info "All HTML report files have been re-generated."
# (Re-)generate index files.
- ActivityListView.new(self).update_html_index
+ ActivityListView.new(self).update_index_pages
Log.info "HTML index files have been updated."
end
@@ -332,7 +341,7 @@ module PostRunner
end
@records.sync
- ActivityListView.new(self).update_html_index
+ ActivityListView.new(self).update_index_pages
end
def create_directory(dir, name)
diff --git a/lib/postrunner/Activity.rb b/lib/postrunner/Activity.rb
index e0e1e06..b4a38f4 100644
--- a/lib/postrunner/Activity.rb
+++ b/lib/postrunner/Activity.rb
@@ -312,8 +312,7 @@ module PostRunner
def generate_html_view
@fit_activity = load_fit_file unless @fit_activity
- ActivityView.new(self, @db.cfg[:unit_system], @db.predecessor(self),
- @db.successor(self))
+ ActivityView.new(self, @db.cfg[:unit_system])
end
def activity_type
diff --git a/lib/postrunner/ActivityLink.rb b/lib/postrunner/ActivityLink.rb
new file mode 100644
index 0000000..9c368b0
--- /dev/null
+++ b/lib/postrunner/ActivityLink.rb
@@ -0,0 +1,59 @@
+#!/usr/bin/env ruby -w
+# encoding: UTF-8
+#
+# = ActivityLink.rb -- PostRunner - Manage the data from your Garmin sport devices.
+#
+# Copyright (c) 2014, 2015 by Chris Schlaeger <cs@taskjuggler.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+
+require 'postrunner/HTMLBuilder'
+
+module PostRunner
+
+ # Generates the name of an Activity with a link to the ActivityReport.
+ # Optionally, an icon can be shown for Activities that contain a current
+ # personal record.
+ class ActivityLink
+
+ def initialize(activity, show_record_icon = false)
+ @activity = activity
+ @show_record_icon = show_record_icon
+ end
+
+ # Add the ActivityLink as HTML Elements to the document.
+ # @param doc [HTMLBuilder] XML Document
+ def to_html(doc)
+ doc.unique(:activitylink_style) { doc.style(style) }
+
+ doc.a(@activity.name, { :class => 'activity_link',
+ :href => @activity.fit_file[0..-5] + '.html' })
+ if @show_record_icon && @activity.has_records?
+ doc.img(nil, { :src => 'icons/record-small.png',
+ :style => 'vertical-align:middle' })
+ end
+ end
+
+ # Convert the ActivityLink into a plain text form. Return the first 20
+ # characters of the Activity name.
+ def to_s
+ @activity.name[0..19]
+ end
+
+ private
+
+ def style
+ <<EOT
+.activity_link {
+ padding: 0px 3px 0px 3px;
+}
+EOT
+ end
+
+ end
+
+end
+
diff --git a/lib/postrunner/ActivityListView.rb b/lib/postrunner/ActivityListView.rb
index 643754b..8027cb0 100644
--- a/lib/postrunner/ActivityListView.rb
+++ b/lib/postrunner/ActivityListView.rb
@@ -14,35 +14,15 @@ require 'fit4ruby'
require 'postrunner/FlexiTable'
require 'postrunner/HTMLBuilder'
-require 'postrunner/ViewWidgets'
+require 'postrunner/ActivityLink'
module PostRunner
+ # Generates a paged list of all Activity objects in the database. HTML and
+ # plain text output are supported.
class ActivityListView
- class ActivityLink
-
- def initialize(activity)
- @activity = activity
- end
-
- def to_html(doc)
- doc.a(@activity.name, { :class => 'activity_link',
- :href => @activity.fit_file[0..-5] + '.html' })
- if @activity.has_records?
- doc.img(nil, { :src => 'icons/record-small.png',
- :style => 'vertical-align:middle' })
- end
- end
-
- def to_s
- @activity.name[0..19]
- end
-
- end
-
include Fit4Ruby::Converters
- include ViewWidgets
def initialize(db)
@db = db
@@ -52,85 +32,42 @@ module PostRunner
@last_page = (@db.activities.length - 1) / @page_size
end
- def update_html_index
+ def update_index_pages
0.upto(@last_page) do |page_no|
@page_no = page_no
- generate_html_index_page
+ generate_html_index_page(page_no)
end
end
- def to_html(doc)
- generate_table.to_html(doc)
- end
-
def to_s
generate_table.to_s
end
private
- def generate_html_index_page
- doc = HTMLBuilder.new
+ def generate_html_index_page(page_index)
+ views = @db.views
+ views.current_page = 'index.html'
- doc.html {
- head(doc)
- body(doc)
- }
-
- write_file(doc)
- end
+ pages = PagingButtons.new((0..@last_page).map do |i|
+ "index#{i == 0 ? '' : "-#{i}"}.html"
+ end)
+ pages.current_page =
+ "index#{page_index == 0 ? '' : "-#{page_index}"}.html"
+ @view = View.new("PostRunner Activities", views, pages)
- def head(doc)
- doc.head {
- doc.meta({ 'http-equiv' => 'Content-Type',
- 'content' => 'text/html; charset=utf-8' })
- doc.title("PostRunner Activities")
- style(doc)
- }
- end
+ @view.doc.head { @view.doc.style(style) }
+ body(@view.doc)
- def style(doc)
- view_widgets_style(doc)
- doc.style(<<EOT
-body {
- font-family: verdana,arial,sans-serif;
- margin: 0px;
-}
-.main {
- text-align: center;
-}
-.widget_frame {
- width: 900px;
-}
-.activity_link {
- padding: 0px 3px 0px 3px;
-}
-.ft_cell {
- height: 30px
-}
-EOT
- )
+ output_file = File.join(@db.cfg[:html_dir], pages.current_page)
+ @view.write(output_file)
end
def body(doc)
- doc.body {
- first_page = @page_no == 0 ? nil: 'index.html'
- prev_page = @page_no == 0 ? nil :
- @page_no == 1 ? 'index.html' :
- "index#{@page_no - 1}.html"
- prev_page = @page_no == 0 ? nil :
- @page_no == 1 ? 'index.html' :
- "index#{@page_no - 1}.html"
- next_page = @page_no < @last_page ? "index#{@page_no + 1}.html" : nil
- last_page = @page_no == @last_page ? nil : "index#{@last_page}.html"
- titlebar(doc, first_page, prev_page, nil, next_page, last_page)
-
+ @view.body {
doc.div({ :class => 'main' }) {
- frame(doc, 'Activities') {
- generate_table.to_html(doc)
- }
+ ViewFrame.new('Activities', 900, generate_table).to_html(doc)
}
- footer(doc)
}
end
@@ -154,7 +91,7 @@ EOT
activities.each do |a|
t.row([
i += 1,
- ActivityLink.new(a),
+ ActivityLink.new(a, true),
a.activity_type,
a.timestamp.strftime("%a, %Y %b %d %H:%M"),
local_value(a.total_distance, 'm', '%.2f',
@@ -168,14 +105,19 @@ EOT
t
end
- def write_file(doc)
- output_file = File.join(@db.cfg[:html_dir],
- "index#{@page_no == 0 ? '' : @page_no}.html")
- begin
- File.write(output_file, doc.to_html)
- rescue IOError
- Log.fatal "Cannot write activity index file '#{output_file}: #{$!}"
- end
+ def style
+ <<EOT
+body {
+ font-family: verdana,arial,sans-serif;
+ margin: 0px;
+}
+.main {
+ text-align: center;
+}
+.ft_cell {
+ height: 30px
+}
+EOT
end
def local_value(value, from_unit, format, units)
diff --git a/lib/postrunner/ActivitySummary.rb b/lib/postrunner/ActivitySummary.rb
index ab283cb..ffb0901 100644
--- a/lib/postrunner/ActivitySummary.rb
+++ b/lib/postrunner/ActivitySummary.rb
@@ -13,14 +13,13 @@
require 'fit4ruby'
require 'postrunner/FlexiTable'
-require 'postrunner/ViewWidgets'
+require 'postrunner/ViewFrame'
module PostRunner
class ActivitySummary
include Fit4Ruby::Converters
- include ViewWidgets
def initialize(fit_activity, unit_system, custom_fields)
@fit_activity = fit_activity
@@ -35,12 +34,9 @@ module PostRunner
end
def to_html(doc)
- frame(doc, "Activity: #{@name}") {
- summary.to_html(doc)
- }
- frame(doc, 'Laps') {
- laps.to_html(doc)
- }
+ width = 600
+ ViewFrame.new("Activity: #{@name}", width, summary).to_html(doc)
+ ViewFrame.new('Laps', width, laps).to_html(doc)
end
private
diff --git a/lib/postrunner/ActivityView.rb b/lib/postrunner/ActivityView.rb
index fa05e4c..bba1ec7 100644
--- a/lib/postrunner/ActivityView.rb
+++ b/lib/postrunner/ActivityView.rb
@@ -3,7 +3,7 @@
#
# = ActivityView.rb -- PostRunner - Manage the data from your Garmin sport devices.
#
-# Copyright (c) 2014 by Chris Schlaeger <cs@taskjuggler.org>
+# Copyright (c) 2014, 2015 by Chris Schlaeger <cs@taskjuggler.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of version 2 of the GNU General Public License as
@@ -12,70 +12,75 @@
require 'fit4ruby'
-require 'postrunner/HTMLBuilder'
+require 'postrunner/View'
require 'postrunner/ActivitySummary'
require 'postrunner/DeviceList'
require 'postrunner/UserProfileView'
-require 'postrunner/ViewWidgets'
require 'postrunner/TrackView'
require 'postrunner/ChartView'
module PostRunner
- class ActivityView
+ class ActivityView < View
- include ViewWidgets
-
- def initialize(activity, unit_system, predecessor, successor)
+ def initialize(activity, unit_system)
@activity = activity
+ db = @activity.db
@unit_system = unit_system
- @predecessor = predecessor
- @successor = successor
- @output_dir = activity.db.cfg[:html_dir]
- @output_file = nil
- @doc = HTMLBuilder.new
+ views = db.views
+ views.current_page = nil
+
+ # Sort activities in reverse order so the newest one is considered the
+ # last report by the pagin buttons.
+ activities = db.activities.sort do |a1, a2|
+ a1.timestamp <=> a2.timestamp
+ end
+
+ pages = PagingButtons.new(activities.map do |a|
+ "#{a.fit_file[0..-5]}.html"
+ end, false)
+ pages.current_page = "#{@activity.fit_file[0..-5]}.html"
+
+ super("PostRunner Activity: #{@activity.name}", views, pages)
generate_html(@doc)
- write_file
+ write(File.join(db.cfg[:html_dir], pages.current_page))
end
private
def generate_html(doc)
- @report = ActivitySummary.new(@activity.fit_activity, @unit_system,
- { :name => @activity.name,
- :type => @activity.activity_type,
- :sub_type => @activity.activity_sub_type
- })
- @device_list = DeviceList.new(@activity.fit_activity)
- @user_profile = UserProfileView.new(@activity.fit_activity, @unit_system)
- @track_view = TrackView.new(@activity)
- @chart_view = ChartView.new(@activity, @unit_system)
-
- doc.html {
- head(doc)
- body(doc)
- }
- end
-
- def head(doc)
- doc.head {
- doc.meta({ 'http-equiv' => 'Content-Type',
- 'content' => 'text/html; charset=utf-8' })
- doc.meta({ 'name' => 'viewport',
- 'content' => 'width=device-width, ' +
- 'initial-scale=1.0, maximum-scale=1.0, ' +
- 'user-scalable=0' })
- doc.title("PostRunner Activity: #{@activity.name}")
- view_widgets_style(doc)
- @chart_view.head(doc)
- @track_view.head(doc)
- style(doc)
+ doc.head { doc.style(style) }
+ #doc.meta({ 'name' => 'viewport',
+ # 'content' => 'width=device-width, ' +
+ # 'initial-scale=1.0, maximum-scale=1.0, ' +
+ # 'user-scalable=0' })
+
+ body {
+ doc.body({ :onload => 'init()' }) {
+ # The main area with the 2 column layout.
+ doc.div({ :class => 'main' }) {
+ doc.div({ :class => 'left_col' }) {
+ ActivitySummary.new(@activity.fit_activity, @unit_system,
+ { :name => @activity.name,
+ :type => @activity.activity_type,
+ :sub_type => @activity.activity_sub_type
+ }).to_html(doc)
+ TrackView.new(@activity).to_html(doc)
+ DeviceList.new(@activity.fit_activity).to_html(doc)
+ UserProfileView.new(@activity.fit_activity, @unit_system).
+ to_html(doc)
+ }
+ doc.div({ :class => 'right_col' }) {
+ ChartView.new(@activity, @unit_system).to_html(doc)
+ }
+ }
+ }
}
end
- def style(doc)
- doc.style(<<EOT
+ def style
+ <<EOT
body {
font-family: verdana,arial,sans-serif;
margin: 0px;
@@ -93,37 +98,6 @@ body {
width: 600px;
}
EOT
- )
- end
-
- def body(doc)
- doc.body({ :onload => 'init()' }) {
- prev_page = @predecessor ? @predecessor.fit_file[0..-5] + '.html' : nil
- next_page = @successor ? @successor.fit_file[0..-5] + '.html' : nil
- titlebar(doc, nil, prev_page, 'index.html', next_page)
- # The main area with the 2 column layout.
- doc.div({ :class => 'main' }) {
- doc.div({ :class => 'left_col' }) {
- @report.to_html(doc)
- @track_view.div(doc)
- @device_list.to_html(doc)
- @user_profile.to_html(doc)
- }
- doc.div({ :class => 'right_col' }) {
- @chart_view.div(doc)
- }
- }
- footer(doc)
- }
- end
-
- def write_file
- @output_file = File.join(@output_dir, "#{@activity.fit_file[0..-5]}.html")
- begin
- File.write(@output_file, @doc.to_html)
- rescue IOError
- Log.fatal "Cannot write activity view file '#{@output_file}: #{$!}"
- end
end
end
diff --git a/lib/postrunner/ChartView.rb b/lib/postrunner/ChartView.rb
index 1aa6039..33e413d 100644
--- a/lib/postrunner/ChartView.rb
+++ b/lib/postrunner/ChartView.rb
@@ -9,14 +9,10 @@
# published by the Free Software Foundation.
#
-require 'postrunner/ViewWidgets'
-
module PostRunner
class ChartView
- include ViewWidgets
-
def initialize(activity, unit_system)
@activity = activity
@sport = activity.fit_activity.sessions[0].sport
@@ -24,17 +20,19 @@ module PostRunner
@empty_charts = {}
end
- def head(doc)
- [ 'jquery/jquery-2.1.1.min.js', 'flot/jquery.flot.js',
- 'flot/jquery.flot.time.js' ].each do |js|
- doc.script({ 'language' => 'javascript', 'type' => 'text/javascript',
- 'src' => js })
- end
- doc.style(style)
- doc.script(java_script)
- end
+ def to_html(doc)
+ doc.unique(:chartview_style) {
+ doc.head {
+ [ 'jquery/jquery-2.1.1.min.js', 'flot/jquery.flot.js',
+ 'flot/jquery.flot.time.js' ].each do |js|
+ doc.script({ 'language' => 'javascript',
+ 'type' => 'text/javascript', 'src' => js })
+ end
+ doc.style(style)
+ }
+ }
- def div(doc)
+ doc.script(java_script)
if @sport == 'running'
chart_div(doc, 'pace', "Pace (#{select_unit('min/km')})")
else
@@ -274,9 +272,9 @@ EOT
# Don't plot frame for graph without data.
return if @empty_charts[field]
- frame(doc, title) {
+ ViewFrame.new(title) {
doc.div({ 'id' => "#{field}_chart", 'class' => 'chart-placeholder'})
- }
+ }.to_html(doc)
end
def hover_function(chart_id, y_label, y_unit)
diff --git a/lib/postrunner/DeviceList.rb b/lib/postrunner/DeviceList.rb
index 3316dde..6ab63f2 100644
--- a/lib/postrunner/DeviceList.rb
+++ b/lib/postrunner/DeviceList.rb
@@ -3,7 +3,7 @@
#
# = DeviceList.rb -- PostRunner - Manage the data from your Garmin sport devices.
#
-# Copyright (c) 2014 by Chris Schlaeger <cs@taskjuggler.org>
+# Copyright (c) 2014, 2015 by Chris Schlaeger <cs@taskjuggler.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of version 2 of the GNU General Public License as
@@ -12,22 +12,18 @@
require 'fit4ruby'
-require 'postrunner/ViewWidgets'
+require 'postrunner/ViewFrame'
module PostRunner
class DeviceList
- include ViewWidgets
-
def initialize(fit_activity)
@fit_activity = fit_activity
end
def to_html(doc)
- frame(doc, 'Devices') {
- devices.each { |d| d.to_html(doc) }
- }
+ ViewFrame.new('Devices', 600, devices).to_html(doc)
end
def to_s
diff --git a/lib/postrunner/FlexiTable.rb b/lib/postrunner/FlexiTable.rb
index 7385db7..8113cc1 100644
--- a/lib/postrunner/FlexiTable.rb
+++ b/lib/postrunner/FlexiTable.rb
@@ -3,7 +3,7 @@
#
# = FlexiTable.rb -- PostRunner - Manage the data from your Garmin sport devices.
#
-# Copyright (c) 2014 by Chris Schlaeger <cs@taskjuggler.org>
+# Copyright (c) 2014, 2015 by Chris Schlaeger <cs@taskjuggler.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of version 2 of the GNU General Public License as
@@ -252,6 +252,9 @@ module PostRunner
def to_html(doc)
index_table
+ doc.unique(:flexitable_style) {
+ doc.head { doc.style(style) }
+ }
doc.table(@html_attrs) {
@head_rows.each { |r| r.to_html(doc) }
@body_rows.each { |r| r.to_html(doc) }
@@ -318,6 +321,30 @@ module PostRunner
s + "\n"
end
+ def style
+ <<EOT
+.flexitable {
+ width: 100%;
+ border: 2px solid #545454;
+ border-collapse: collapse;
+ font-size:11pt;
+}
+.ft_head_row {
+ background-color: #DEDEDE
+}
+.ft_even_row {
+ background-color: #FCFCFC
+}
+.ft_odd_row {
+ background-color: #F1F1F1
+}
+.ft_cell {
+ border: 1px solid #CCCCCC;
+ padding: 1px 3px;
+}
+EOT
+ end
+
end
end
diff --git a/lib/postrunner/HTMLBuilder.rb b/lib/postrunner/HTMLBuilder.rb
index c9212fe..8c53f2f 100644
--- a/lib/postrunner/HTMLBuilder.rb
+++ b/lib/postrunner/HTMLBuilder.rb
@@ -19,18 +19,79 @@ module PostRunner
class HTMLBuilder
# Create a new HTMLBuilder object.
- def initialize
+ def initialize(title)
# This is the Nokogiri Document that will store all the data.
@doc = Nokogiri::HTML::Document.new
# We only need to keep a stack of the currently edited nodes so we know
# where we are in the node tree.
@node_stack = []
+ @tags = []
+
+ @html = create_node('html') {
+ @head = create_node('head') {
+ create_node('meta', { 'http-equiv' => 'Content-Type',
+ 'content' => 'text/html; charset=utf-8' })
+ create_node('title', title)
+ }
+ @body = create_node('body')
+ }
+ @node_stack << @html
+ @node_stack << @body
+ end
+
+ # Append nodes provided in block to head section of HTML document.
+ def head
+ @node_stack.push(@head)
+ yield if block_given?
+ unless @node_stack.pop == @head
+ raise ArgumentError, "node_stack corrupted in head"
+ end
+ end
+
+ # Append nodes provided in block to body section of HTML document.
+ def body(*args)
+ @node_stack.push(@body)
+ args.each do |arg|
+ if arg.is_a?(Hash)
+ arg.each { |k, v| @body[k] = v }
+ end
+ end
+ yield if block_given?
+ unless @node_stack.pop == @body
+ raise ArgumentError, "node_stack corrupted in body"
+ end
+ end
+
+ # Only execute the passed block if the provided tag has not been added
+ # yet.
+ def unique(tag)
+ unless @tags.include?(tag)
+ @tags << tag
+ yield if block_given?
+ end
end
# Any call to an undefined method will create a HTML node of the same
# name.
- def method_missing(method_name, *args)
- node = Nokogiri::XML::Node.new(method_name.to_s, @doc)
+ def method_missing(method_name, *args, &block)
+ create_node(method_name.to_s, *args, &block)
+ end
+
+ # Only needed to comply with style guides. This all calls to unknown
+ # method will be handled properly. So, we always return true.
+ def respond_to?(method)
+ true
+ end
+
+ # Dump the HTML document as HTML formatted String.
+ def to_html
+ @doc.to_html
+ end
+
+ private
+
+ def create_node(name, *args)
+ node = Nokogiri::XML::Node.new(name, @doc)
if (parent = @node_stack.last)
parent.add_child(node)
else
@@ -52,19 +113,6 @@ module PostRunner
@node_stack.pop
end
- # Only needed to comply with style guides. This all calls to unknown
- # method will be handled properly. So, we always return true.
- def respond_to?(method)
- true
- end
-
- # Dump the HTML document as HTML formatted String.
- def to_html
- @doc.to_html
- end
-
- private
-
def add_child(parent, node)
if parent
parent.add_child(node)
diff --git a/lib/postrunner/NavButtonRow.rb b/lib/postrunner/NavButtonRow.rb
new file mode 100644
index 0000000..7e1ea06
--- /dev/null
+++ b/lib/postrunner/NavButtonRow.rb
@@ -0,0 +1,103 @@
+#!/usr/bin/env ruby -w
+# encoding: UTF-8
+#
+# = NavButtonRow.rb -- PostRunner - Manage the data from your Garmin sport devices.
+#
+# Copyright (c) 2015 by Chris Schlaeger <cs@taskjuggler.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+
+require 'postrunner/HTMLBuilder'
+
+module PostRunner
+
+ # Auxilliary class that stores the name of an icon file and a URL as a
+ # String. It is used to describe a NavButtonRow button.
+ class NavButtonDef < Struct.new(:icon, :url)
+ end
+
+ # A NavButtonRow is a row of buttons used to navigate between HTML pages.
+ class NavButtonRow
+
+ # A class to store the icon and URL of a button in the NavButtonRow
+ # objects.
+ class Button
+
+ # Create a Button object.
+ # @param icon [String] File name of the icon file
+ # @param url [String] URL of the page to change to
+ def initialize(icon, url = nil)
+ @icon = icon
+ @url = url
+ end
+
+ # Add the object as HTML Elements to the document.
+ # @param doc [HTMLBuilder] XML Document
+ def to_html(doc)
+ if @url
+ doc.a({ :href => @url }) {
+ doc.img({ :src => "icons/#{@icon}", :class => 'active_button' })
+ }
+ else
+ doc.img({ :src => "icons/#{@icon}", :class => 'inactive_button' })
+ end
+ end
+
+ end
+
+ # Create a new NavButtonRow object.
+ # @param float [String, Nil] specifies if the HTML representation should
+ # be a floating object that floats left or right.
+ def initialize(float = nil)
+ unless float.nil? || %w( left right ).include?(float)
+ raise ArgumentError "float argument must be nil, 'left' or 'right'"
+ end
+
+ @float = float
+ @buttons = []
+ end
+
+ # Add a new button to the NavButtonRow object.
+ # @param icon [String] File name of the icon file
+ # @param url [String] URL of the page to change to
+ def addButton(icon, url = nil)
+ @buttons << Button.new(icon, url)
+ end
+
+ # Add the object as HTML Elements to the document.
+ # @param doc [HTMLBuilder] XML Document
+ def to_html(doc)
+ doc.unique(:nav_button_row_style) {
+ doc.head { doc.style(style) }
+ }
+ doc.div({ :class => 'nav_button_row',
+ :style => "width: #{@buttons.length * (32 + 10)}px; " +
+ "#{@float ? "float: #{@float};" :
+ 'margin-left: auto; margin-right: auto'}"}) {
+ @buttons.each { |btn| btn.to_html(doc) }
+ }
+ end
+
+ private
+
+ def style
+ <<"EOT"
+.nav_button_row {
+ padding: 3px 30px;
+}
+.active_button {
+ padding: 5px;
+}
+.inactive_button {
+ padding: 5px;
+ opacity: 0.4;
+}
+EOT
+ end
+
+ end
+
+end
diff --git a/lib/postrunner/PagingButtons.rb b/lib/postrunner/PagingButtons.rb
new file mode 100644
index 0000000..aa1f5f2
--- /dev/null
+++ b/lib/postrunner/PagingButtons.rb
@@ -0,0 +1,77 @@
+#!/usr/bin/env ruby -w
+# encoding: UTF-8
+#
+# = PagingButtons.rb -- PostRunner - Manage the data from your Garmin sport devices.
+#
+# Copyright (c) 2015 by Chris Schlaeger <cs@taskjuggler.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+
+require 'postrunner/NavButtonRow'
+
+module PostRunner
+
+ # A class to generate a set of forward/backward buttons for an HTML page. It
+ # can also include jump to first/last buttons.
+ class PagingButtons
+
+ # Create a new PagingButtons object.
+ # @param page_urls [Array of String] Sorted list of all possible pages
+ # @param end_buttons [Boolean] If true jump to first/last buttons are
+ # included
+ def initialize(page_urls, end_buttons = true)
+ if page_urls.empty?
+ raise ArgumentError.new("'page_urls' must not be empty")
+ end
+ @pages = page_urls
+ @current_page_index = 0
+ @end_buttons = end_buttons
+ end
+
+ # Return the URL of the current page
+ def current_page
+ @pages[@current_page_index]
+ end
+
+ # Set the URL for the current page. It must be included in the URL set
+ # passed at creation time. The forward/backward links will be derived from
+ # the setting of the current page.
+ # @param page_url [String] URL of the page
+ def current_page=(page_url)
+ unless (@current_page_index = @pages.index(page_url))
+ raise ArgumentError.new("URL #{page_url} is not a known page URL")
+ end
+ end
+
+ # Iterate over all buttons. A NavButtonDef object is passed to the block
+ # that contains the icon and URL for the button. If no URL is set, the
+ # button is inactive.
+ def each
+ %w( first back forward last ).each do |button_name|
+ button = NavButtonDef.new
+ button.icon = button_name + '.png'
+ button.url =
+ case button_name
+ when 'first'
+ @current_page_index == 0 || !@end_buttons ? nil : @pages.first
+ when 'back'
+ @current_page_index == 0 ? nil :
+ @pages[@current_page_index - 1]
+ when 'forward'
+ @current_page_index == @pages.length - 1 ? nil :
+ @pages[@current_page_index + 1]
+ when 'last'
+ @current_page_index == @pages.length - 1 ||
+ !@end_buttons ? nil : @pages.last
+ end
+
+ yield(button)
+ end
+ end
+
+ end
+
+end
diff --git a/lib/postrunner/PersonalRecords.rb b/lib/postrunner/PersonalRecords.rb
index aba2f6a..7f69529 100644
--- a/lib/postrunner/PersonalRecords.rb
+++ b/lib/postrunner/PersonalRecords.rb
@@ -15,6 +15,8 @@ require 'yaml'
require 'fit4ruby'
require 'postrunner/BackedUpFile'
+require 'postrunner/RecordListPageView'
+require 'postrunner/ActivityLink'
module PostRunner
@@ -89,7 +91,8 @@ module PostRunner
secsToHMS(@duration),
speedToPace(@distance / @duration) ]) +
[ @activity.db.ref_by_fit_file(@activity.fit_file),
- @activity.name, @start_time.strftime("%Y-%m-%d") ])
+ ActivityLink.new(@activity, false),
+ @start_time.strftime("%Y-%m-%d") ])
end
end
@@ -171,6 +174,16 @@ module PostRunner
def to_s
return '' if empty?
+ generate_table.to_s + "\n"
+ end
+
+ def to_html(doc)
+ generate_table.to_html(doc)
+ end
+
+ private
+
+ def generate_table
t = FlexiTable.new
t.head
t.row([ 'Record', 'Time/Dist.', 'Avg. Pace', 'Ref.', 'Activity',
@@ -192,13 +205,17 @@ module PostRunner
records.sort { |r1, r2| r1.distance <=> r2.distance }.each do |r|
r.to_table_row(t)
end
- t.to_s + "\n"
+
+ t
end
+
end
class SportRecords
+ attr_reader :sport, :all_time, :yearly
+
def initialize(sport)
@sport = sport
@all_time = RecordSet.new(@sport, nil)
@@ -251,6 +268,22 @@ module PostRunner
str
end
+ def to_html(doc)
+ return nil if empty?
+
+ doc.div {
+ doc.h3('All-time records')
+ @all_time.to_html(doc)
+ @yearly.values.sort{ |r1, r2| r2.year <=> r1.year }.each do |record|
+ puts record.year
+ unless record.empty?
+ doc.h3("Records of #{record.year}")
+ record.to_html(doc)
+ end
+ end
+ }
+ end
+
end
def initialize(activities)
@@ -286,6 +319,16 @@ module PostRunner
def sync
save_records
+
+ non_empty_records = @sport_records.select { |s, r| !r.empty? }
+ max = non_empty_records.length
+ i = 0
+ non_empty_records.each do |sport, record|
+ output_file = File.join(@activities.cfg[:html_dir],
+ "records-#{i}.html")
+ RecordListPageView.new(@activities, record, max, i).
+ write(output_file)
+ end
end
def to_s
diff --git a/lib/postrunner/RecordListPageView.rb b/lib/postrunner/RecordListPageView.rb
new file mode 100644
index 0000000..f1de004
--- /dev/null
+++ b/lib/postrunner/RecordListPageView.rb
@@ -0,0 +1,69 @@
+#!/usr/bin/env ruby -w
+# encoding: UTF-8
+#
+# = RecordListPageView.rb -- PostRunner - Manage the data from your Garmin sport devices.
+#
+# Copyright (c) 2015 by Chris Schlaeger <cs@taskjuggler.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+
+require 'fit4ruby'
+
+require 'postrunner/FlexiTable'
+require 'postrunner/View'
+require 'postrunner/ViewFrame'
+require 'postrunner/ViewButtons'
+require 'postrunner/PagingButtons'
+
+module PostRunner
+
+ # Generates an HTML page with all personal records for a particular sport
+ # type.
+ class RecordListPageView < View
+
+ include Fit4Ruby::Converters
+
+ # Create a RecordListPageView object.
+ # @param db [ActivityDB] Activity database
+ # @param records [PersonalRecords] Database with personal records
+ # @param page_count [Fixnum] Number of total pages
+ # @param page_index [Fixnum] Index of the page
+ def initialize(db, records, page_count, page_index)
+ @db = db
+ @unit_system = @db.cfg[:unit_system]
+ @records = records
+
+ views = @db.views
+ views.current_page = "records-0.html"
+
+ pages = PagingButtons.new((0..(page_count - 1)).map do |i|
+ "records-#{i}.html"
+ end)
+ pages.current_page =
+ "records-#{page_index}.html"
+
+ @sport_name = Activity::ActivityTypes[@records.sport]
+ super("#{@sport_name} Records", views, pages)
+
+ body {
+ frame_width = 800
+
+ @doc.div({ :class => 'main' }) {
+ ViewFrame.new("All-time #{@sport_name} Records",
+ frame_width, @records.all_time).to_html(@doc)
+
+ @records.yearly.each do |year, record|
+ next if record.empty?
+ ViewFrame.new("#{year} #{@sport_name} Records",
+ frame_width, record).to_html(@doc)
+ end
+ }
+ }
+ end
+
+ end
+
+end
diff --git a/lib/postrunner/TrackView.rb b/lib/postrunner/TrackView.rb
index 7171706..fc7bc21 100644
--- a/lib/postrunner/TrackView.rb
+++ b/lib/postrunner/TrackView.rb
@@ -12,37 +12,35 @@
require 'fit4ruby'
-require 'postrunner/ViewWidgets'
+require 'postrunner/ViewFrame'
module PostRunner
class TrackView
- include ViewWidgets
-
def initialize(activity)
@activity = activity
@session = @activity.fit_activity.sessions[0]
@has_geo_data = @session.has_geo_data?
end
- def head(doc)
+ def to_html(doc)
return unless @has_geo_data
- doc.link({ 'rel' => 'stylesheet',
- 'href' => 'openlayers/theme/default/style.css',
- 'type' => 'text/css' })
- doc.style(style)
- doc.script({ 'src' => 'openlayers/OpenLayers.js' })
- doc.script(java_script)
- end
-
- def div(doc)
- return unless @has_geo_data
+ doc.head {
+ doc.unique(:trackview_style) {
+ doc.style(style)
+ doc.link({ 'rel' => 'stylesheet',
+ 'href' => 'openlayers/theme/default/style.css',
+ 'type' => 'text/css' })
+ doc.script({ 'src' => 'openlayers/OpenLayers.js' })
+ }
+ doc.script(java_script)
+ }
- frame(doc, 'Map') {
+ ViewFrame.new('Map', 600) {
doc.div({ 'id' => 'map', 'class' => 'trackmap' })
- }
+ }.to_html(doc)
end
private
diff --git a/lib/postrunner/UserProfileView.rb b/lib/postrunner/UserProfileView.rb
index 3ff4341..c89216b 100644
--- a/lib/postrunner/UserProfileView.rb
+++ b/lib/postrunner/UserProfileView.rb
@@ -12,14 +12,12 @@
require 'fit4ruby'
-require 'postrunner/ViewWidgets'
+require 'postrunner/ViewFrame'
module PostRunner
class UserProfileView
- include ViewWidgets
-
def initialize(fit_activity, unit_system)
@fit_activity = fit_activity
@unit_system = unit_system
@@ -28,9 +26,7 @@ module PostRunner
def to_html(doc)
return nil if @fit_activity.user_profiles.empty?
- frame(doc, 'User Profile') {
- profile.to_html(doc)
- }
+ ViewFrame.new('User Profile', 600, profile).to_html(doc)
end
def to_s
diff --git a/lib/postrunner/View.rb b/lib/postrunner/View.rb
new file mode 100644
index 0000000..acfd258
--- /dev/null
+++ b/lib/postrunner/View.rb
@@ -0,0 +1,97 @@
+#!/usr/bin/env ruby -w
+# encoding: UTF-8
+#
+# = View.rb -- PostRunner - Manage the data from your Garmin sport devices.
+#
+# Copyright (c) 2015 by Chris Schlaeger <cs@taskjuggler.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+
+require 'postrunner/HTMLBuilder'
+require 'postrunner/ViewTop'
+require 'postrunner/ViewBottom'
+
+module PostRunner
+
+ # Base class for all generated HTML pages.
+ class View
+
+ attr_reader :doc
+
+ # Create a new View object.
+ # @param title [String] The title of the HTML page
+ # @param views [ViewButtons] List of all cross referenced View objects
+ # @param pages [PagingButtons] List of all pages of this View
+ def initialize(title, views, pages)
+ @doc = HTMLBuilder.new(title)
+ @views = views
+ @pages = pages
+
+ @doc.unique(:view_style) {
+ style
+ }
+ end
+
+ # Create the body section of the HTML document.
+ def body
+ ViewTop.new(@views, @pages).to_html(@doc)
+ yield if block_given?
+ ViewBottom.new.to_html(@doc)
+
+ self
+ end
+
+ # Convert the View into an HTML document.
+ def to_html
+ @doc.to_html
+ end
+
+ # Write the HTML document to a file
+ # @param file_name [String] Name of the file to write
+ def write(file_name)
+ begin
+ File.write(file_name, to_html)
+ rescue IOError
+ Log.fatal "Cannot write file '#{file_name}: #{$!}"
+ end
+ end
+
+ private
+
+ def style
+ @doc.head {
+ @doc.style(<<"EOT"
+body {
+ font-family: verdana,arial,sans-serif;
+ margin: 0px;
+}
+.flexitable {
+ width: 100%;
+ border: 2px solid #545454;
+ border-collapse: collapse;
+ font-size:11pt;
+}
+.ft_head_row {
+ background-color: #DEDEDE
+}
+.ft_even_row {
+ background-color: #FCFCFC
+}
+.ft_odd_row {
+ background-color: #F1F1F1
+}
+.ft_cell {
+ border: 1px solid #CCCCCC;
+ padding: 1px 3px;
+}
+EOT
+ )
+ }
+ end
+
+ end
+
+end
diff --git a/lib/postrunner/ViewBottom.rb b/lib/postrunner/ViewBottom.rb
new file mode 100644
index 0000000..3812919
--- /dev/null
+++ b/lib/postrunner/ViewBottom.rb
@@ -0,0 +1,54 @@
+#!/usr/bin/env ruby -w
+# encoding: UTF-8
+#
+# = ViewBottom.rb -- PostRunner - Manage the data from your Garmin sport devices.
+#
+# Copyright (c) 2015 by Chris Schlaeger <cs@taskjuggler.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+
+require 'postrunner/HTMLBuilder'
+require 'postrunner/version'
+
+module PostRunner
+
+ # This class generates the footer of a HTML page.
+ class ViewBottom
+
+ # Generate the HTML code to that describes the foot section.
+ # @param doc [HTMLBuilder] Reference to the HTML document to add to.
+ def to_html(doc)
+ doc.unique(:viewbottom_style) {
+ doc.head { doc.style(style) }
+ }
+ doc.div({ :class => 'footer' }){
+ doc.hr
+ doc.div({ :class => 'copyright' }) {
+ doc.text("Generated by ")
+ doc.a('PostRunner',
+ { :href => 'https://github.com/scrapper/postrunner' })
+ doc.text(" #{VERSION} on #{Time.now}")
+ }
+ }
+ end
+
+ private
+
+ def style
+ <<EOT
+.footer {
+ clear: both;
+ width: 100%;
+ height: 30px;
+ padding: 15px 0px;
+ text-align: center;
+ font-size: 9pt;
+}
+EOT
+ end
+ end
+
+end
diff --git a/lib/postrunner/ViewButtons.rb b/lib/postrunner/ViewButtons.rb
new file mode 100644
index 0000000..4c95162
--- /dev/null
+++ b/lib/postrunner/ViewButtons.rb
@@ -0,0 +1,68 @@
+#!/usr/bin/env ruby -w
+# encoding: UTF-8
+#
+# = ViewButtons.rb -- PostRunner - Manage the data from your Garmin sport devices.
+#
+# Copyright (c) 2015 by Chris Schlaeger <cs@taskjuggler.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+
+module PostRunner
+
+ # This class generates a simple icon menue to select from a set of HTML
+ # pages (called views). The current page is represented as an inactive icon.
+ # All other icons are buttons that contain links to other pages.
+ class ViewButtons
+
+ # Create a ViewButtons object.
+ # @params views [Array of NavButtonDef] icons and URLs for all pages.
+ def initialize(views)
+ if views.empty?
+ raise ArgumentError.new("'views' must not be empty")
+ end
+ @views = views
+ self.current_page = views[0].url
+ end
+
+ # Get the URL of the current page
+ # @return [String]
+ def current_page
+ @current_view_url
+ end
+
+ # Set the the current page.
+ # @param page_url [String] URL of the current page. This must either be
+ # nil or a URL in the predefined set.
+ def current_page=(page_url)
+ unless page_url
+ @current_view_url = nil
+ return
+ end
+
+ if (current = @views.find { |v| v.url == page_url })
+ @current_view_url = current.url
+ else
+ raise ArgumentError.new("#{page_url} is not a URL of a known view")
+ end
+ end
+
+ # Iterate over all buttons. A NavButtonDef object is passed to the block
+ # that contains the icon and URL for the button. If no URL is set, the
+ # button is inactive.
+ def each
+ @views.each do |view|
+ view = view.clone
+ if @current_view_url == view.url
+ view.url = nil
+ end
+ yield(view)
+ end
+
+ end
+
+ end
+
+end
diff --git a/lib/postrunner/ViewFrame.rb b/lib/postrunner/ViewFrame.rb
new file mode 100644
index 0000000..863ad2a
--- /dev/null
+++ b/lib/postrunner/ViewFrame.rb
@@ -0,0 +1,93 @@
+#!/usr/bin/env ruby -w
+# encoding: UTF-8
+#
+# = ViewFrame.rb -- PostRunner - Manage the data from your Garmin sport devices.
+#
+# Copyright (c) 2015 by Chris Schlaeger <cs@taskjuggler.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+
+module PostRunner
+
+ # Creates an HTML frame around the passed object or HTML block.
+ class ViewFrame
+
+ # Create a ViewFrame object.
+ # @param title [String] Title/heading of the framed box
+ # @param width [Fixnum or nil] Width of the frame. Use nil to set no
+ # width.
+ # @param content [Any object that respons to to_html] Object to frame
+ # @param &block [HTMLBuilder actions]
+ def initialize(title, width = 600, content = nil, &block)
+ @title = title
+ @content = content
+ @block = block
+ @width = width
+ end
+
+ # Generate the HTML code for the frame and the enclosing content.
+ # @param doc [HTMLBuilder] HTML document
+ def to_html(doc)
+ doc.unique(:viewframe_style) {
+ # Add the necessary style sheet snippets to the document head.
+ doc.head { doc.style(style) }
+ }
+
+ attr = { 'class' => 'widget_frame' }
+ attr['style'] = "width: #{@width}px" if @width
+ doc.div(attr) {
+ doc.div({ 'class' => 'widget_frame_title' }) {
+ doc.b(@title)
+ }
+ doc.div {
+ # The @content holds an object that must respond to to_html to
+ # generate the HTML code.
+ if @content
+ if @content.is_a?(Array)
+ @content.each { |c| c.to_html(doc) }
+ else
+ @content.to_html(doc)
+ end
+ end
+ # The block generates HTML code directly
+ @block.yield if @block
+ }
+ }
+ end
+
+ private
+
+ def style
+ <<EOT
+.widget_frame {
+ box-sizing: border-box;
+ padding: 10px 15px 15px 15px;
+ margin: 15px auto 15px auto;
+ border: 1px solid #ddd;
+ background: #fff;
+ background: linear-gradient(#f6f6f6 0, #fff 50px);
+ background: -o-linear-gradient(#f6f6f6 0, #fff 50px);
+ background: -ms-linear-gradient(#f6f6f6 0, #fff 50px);
+ background: -moz-linear-gradient(#f6f6f6 0, #fff 50px);
+ background: -webkit-linear-gradient(#f6f6f6 0, #fff 50px);
+ box-shadow: 0 3px 10px rgba(0,0,0,0.15);
+ -o-box-shadow: 0 3px 10px rgba(0,0,0,0.1);
+ -ms-box-shadow: 0 3px 10px rgba(0,0,0,0.1);
+ -moz-box-shadow: 0 3px 10px rgba(0,0,0,0.1);
+ -webkit-box-shadow: 0 3px 10px rgba(0,0,0,0.1);
+}
+.widget_frame_title {
+ font-size:13pt;
+ padding-bottom: 5px;
+ text-align: left;
+}
+EOT
+ end
+
+ end
+
+end
+
diff --git a/lib/postrunner/ViewTop.rb b/lib/postrunner/ViewTop.rb
new file mode 100644
index 0000000..c79d0ea
--- /dev/null
+++ b/lib/postrunner/ViewTop.rb
@@ -0,0 +1,80 @@
+#!/usr/bin/env ruby -w
+# encoding: UTF-8
+#
+# = ViewTop.rb -- PostRunner - Manage the data from your Garmin sport devices.
+#
+# Copyright (c) 2015 by Chris Schlaeger <cs@taskjuggler.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+
+require 'postrunner/HTMLBuilder'
+require 'postrunner/NavButtonRow'
+
+module PostRunner
+
+ # This class generates the top part of the HTML page. It contains the logo
+ # and the menu and navigation buttons.
+ class ViewTop
+
+ # Create a ViewTop object.
+ # @param views [Array of NavButtonDef] icons and URLs for views
+ # @param pages [Array of NavButtonDef] Full list of pages of this view.
+ def initialize(views, pages)
+ @views = views
+ @pages = pages
+ end
+
+ # Generate the HTML code to that describes the top section.
+ # @param doc [HTMLBuilder] Reference to the HTML document to add to.
+ def to_html(doc)
+ doc.unique(:viewtop_style) {
+ doc.head { doc.style(style) }
+ }
+ doc.div({ :class => 'titlebar' }) {
+ doc.div('PostRunner', { :class => 'title' })
+
+ page_selector = NavButtonRow.new('right')
+ @pages.each do |p|
+ page_selector.addButton(p.icon, p.url)
+ end
+ page_selector.to_html(doc)
+
+ view_selector = NavButtonRow.new
+ @views.each do |v|
+ view_selector.addButton(v.icon, v.url)
+ end
+ view_selector.to_html(doc)
+ }
+ end
+
+ private
+
+ def style
+ <<EOT
+.titlebar {
+ width: 100%;
+ height: 50px;
+ margin: 0px;
+ background: linear-gradient(#7FA1FF 0, #002EAC 50px);
+}
+.title {
+ float: left;
+ font-size: 24pt;
+ font-style: italic;
+ font-weight: bold;
+ color: #F8F8F8;
+ text-shadow: -1px -1px 0 #5C5C5C,
+ 1px -1px 0 #5C5C5C,
+ -1px 1px 0 #5C5C5C,
+ 1px 1px 0 #5C5C5C;
+ padding: 3px 30px;
+}
+EOT
+ end
+
+ end
+
+end
diff --git a/lib/postrunner/ViewWidgets.rb b/lib/postrunner/ViewWidgets.rb
deleted file mode 100644
index b4b4207..0000000
--- a/lib/postrunner/ViewWidgets.rb
+++ /dev/null
@@ -1,153 +0,0 @@
-#!/usr/bin/env ruby -w
-# encoding: UTF-8
-#
-# = ViewWidgets.rb -- PostRunner - Manage the data from your Garmin sport devices.
-#
-# Copyright (c) 2014 by Chris Schlaeger <cs@taskjuggler.org>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of version 2 of the GNU General Public License as
-# published by the Free Software Foundation.
-#
-
-module PostRunner
-
- module ViewWidgets
-
- def view_widgets_style(doc)
- doc.style(<<EOT
-.titlebar {
- width: 100%;
- height: 50px;
- margin: 0px;
- background: linear-gradient(#7FA1FF 0, #002EAC 50px);
-}
-.title {
- float: left;
- font-size: 24pt;
- font-style: italic;
- font-weight: bold;
- color: #F8F8F8;
- text-shadow: -1px -1px 0 #5C5C5C,
- 1px -1px 0 #5C5C5C,
- -1px 1px 0 #5C5C5C,
- 1px 1px 0 #5C5C5C;
- padding: 3px 30px;
-}
-.navigator {
- float: right;
- padding: 3px 30px;
-}
-.active_button {
- padding: 5px;
-}
-.inactive_button {
- padding: 5px;
- opacity: 0.4;
-}
-.widget_frame {
- box-sizing: border-box;
- width: 600px;
- padding: 10px 15px 15px 15px;
- margin: 15px auto 15px auto;
- border: 1px solid #ddd;
- background: #fff;
- background: linear-gradient(#f6f6f6 0, #fff 50px);
- background: -o-linear-gradient(#f6f6f6 0, #fff 50px);
- background: -ms-linear-gradient(#f6f6f6 0, #fff 50px);
- background: -moz-linear-gradient(#f6f6f6 0, #fff 50px);
- background: -webkit-linear-gradient(#f6f6f6 0, #fff 50px);
- box-shadow: 0 3px 10px rgba(0,0,0,0.15);
- -o-box-shadow: 0 3px 10px rgba(0,0,0,0.1);
- -ms-box-shadow: 0 3px 10px rgba(0,0,0,0.1);
- -moz-box-shadow: 0 3px 10px rgba(0,0,0,0.1);
- -webkit-box-shadow: 0 3px 10px rgba(0,0,0,0.1);
-}
-.widget_frame_title {
- font-size:13pt;
- padding-bottom: 5px;
- text-align: left;
-}
-.flexitable {
- width: 100%;
- border: 2px solid #545454;
- border-collapse: collapse;
- font-size:11pt;
-}
-.ft_head_row {
- background-color: #DEDEDE
-}
-.ft_even_row {
- background-color: #FCFCFC
-}
-.ft_odd_row {
- background-color: #F1F1F1
-}
-.ft_cell {
- border: 1px solid #CCCCCC;
- padding: 1px 3px;
-}
-.footer {
- clear: both;
- width: 100%;
- height: 30px;
- padding: 15px;
- text-align: center;
- font-size: 9pt;
-}
-EOT
- )
- end
-
- def frame(doc, title)
- doc.div({ 'class' => 'widget_frame' }) {
- doc.div({ 'class' => 'widget_frame_title' }) {
- doc.b(title)
- }
- doc.div {
- yield if block_given?
- }
- }
- end
-
- def titlebar(doc, first_page = nil, prev_page = nil, home_page = nil,
- next_page = nil, last_page = nil)
- # The top title bar.
- doc.div({ :class => 'titlebar' }) {
- doc.div('PostRunner', { :class => 'title' })
- doc.div({ :class => 'navigator' }) {
- button(doc, first_page, 'first.png')
- button(doc, prev_page, 'back.png')
- button(doc, home_page, 'home.png')
- button(doc, next_page, 'forward.png')
- button(doc, last_page, 'last.png')
- }
- }
- end
-
- def button(doc, link, icon)
- if link
- doc.a({ :href => link }) {
- doc.img({ :src => "icons/#{icon}", :class => 'active_button' })
- }
- else
- doc.img({ :src => "icons/#{icon}", :class => 'inactive_button' })
- end
- end
-
- def footer(doc)
- doc.div({ :class => 'footer' }){
- doc.hr
- doc.div({ :class => 'copyright' }) {
- doc.text("Generated by ")
- doc.a('PostRunner',
- { :href => 'https://github.com/scrapper/postrunner' })
- doc.text(" #{VERSION} on #{Time.now}")
- }
- }
- end
-
- end
-
-end
-
diff --git a/misc/icons/activities.png b/misc/icons/activities.png
new file mode 100644
index 0000000..87b1c38
--- /dev/null
+++ b/misc/icons/activities.png
Binary files differ
diff --git a/misc/icons/activities.svg b/misc/icons/activities.svg
new file mode 100644
index 0000000..010749a
--- /dev/null
+++ b/misc/icons/activities.svg
@@ -0,0 +1,1582 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="128"
+ height="128"
+ id="svg3669"
+ sodipodi:version="0.32"
+ inkscape:version="0.46"
+ sodipodi:docbase="/home/david/sandbox/split/dolphin file views/32x32"
+ sodipodi:docname="view-list-text.svgz"
+ version="1.0"
+ inkscape:output_extension="org.inkscape.output.svgz.inkscape"
+ inkscape:export-filename="/home/pinheiro/pics/oxygen/scalable/actions/view-list-text.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <defs
+ id="defs3671">
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3487">
+ <stop
+ style="stop-color:#535353;stop-opacity:1;"
+ offset="0"
+ id="stop3489" />
+ <stop
+ style="stop-color:#535353;stop-opacity:0;"
+ offset="1"
+ id="stop3491" />
+ </linearGradient>
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 64 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="128 : 64 : 1"
+ inkscape:persp3d-origin="64 : 42.666667 : 1"
+ id="perspective307" />
+ <linearGradient
+ id="linearGradient3437">
+ <stop
+ id="stop3439"
+ offset="0"
+ style="stop-color:#cdcdcf;stop-opacity:1" />
+ <stop
+ id="stop3441"
+ offset="1"
+ style="stop-color:#cdcdcf;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3417">
+ <stop
+ style="stop-color:#b3b3b6;stop-opacity:1;"
+ offset="0"
+ id="stop3419" />
+ <stop
+ style="stop-color:#cecece;stop-opacity:1;"
+ offset="1"
+ id="stop3421" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4711">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop4713" />
+ <stop
+ id="stop4715"
+ offset="0.49140647"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ <stop
+ style="stop-color:#dcdcdc;stop-opacity:1;"
+ offset="1"
+ id="stop4717" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient7422">
+ <stop
+ id="stop7424"
+ offset="0"
+ style="stop-color:#cbcbcd;stop-opacity:1;" />
+ <stop
+ style="stop-color:#e0e0e2;stop-opacity:1;"
+ offset="0.5"
+ id="stop7426" />
+ <stop
+ id="stop7428"
+ offset="1"
+ style="stop-color:#f2f2f2;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient7244">
+ <stop
+ style="stop-color:#6f6f6f;stop-opacity:1;"
+ offset="0"
+ id="stop7246" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop7248" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4711"
+ id="linearGradient7843"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.121457,0,0,0.1756605,195.18891,503.66043)"
+ x1="-333.0289"
+ y1="-1473.6504"
+ x2="-333.0289"
+ y2="-776.61371" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient7422"
+ id="linearGradient7912"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.121457,0,0,0.1756605,75.745932,148.34634)"
+ x1="399.77466"
+ y1="727.07941"
+ x2="399.77466"
+ y2="480.60214" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient7244"
+ id="linearGradient12912"
+ x1="1055.3002"
+ y1="-468.66934"
+ x2="1055.3002"
+ y2="-481.76657"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3437"
+ id="linearGradient3423"
+ x1="109.25784"
+ y1="260.75122"
+ x2="109.25784"
+ y2="312.87741"
+ gradientUnits="userSpaceOnUse" />
+ <filter
+ inkscape:collect="always"
+ id="filter4400">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="1.177891"
+ id="feGaussianBlur4402" />
+ </filter>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3487"
+ id="linearGradient3493"
+ x1="68"
+ y1="156"
+ x2="68"
+ y2="4"
+ gradientUnits="userSpaceOnUse" />
+ </defs>
+ <sodipodi:namedview
+ inkscape:document-units="px"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="2.8284271"
+ inkscape:cx="131.36231"
+ inkscape:cy="36.250876"
+ inkscape:current-layer="layer1"
+ id="namedview3673"
+ inkscape:window-width="937"
+ inkscape:window-height="696"
+ inkscape:window-x="1028"
+ inkscape:window-y="368"
+ showgrid="true"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ width="128px"
+ height="128px"
+ grid_units="px"
+ inkscape:grid-points="true"
+ gridtolerance="10000">
+ <inkscape:grid
+ id="GridFromPre046Settings"
+ type="xygrid"
+ originx="0px"
+ originy="0px"
+ spacingx="4px"
+ spacingy="4px"
+ color="#0000ff"
+ empcolor="#0000ff"
+ opacity="0.2"
+ empopacity="0.4"
+ empspacing="0" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata3675">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-79.62865,-236.8761)">
+ <rect
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="/home/pinheiro/Desktop/mock2.png"
+ style="opacity:0.4;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1;filter:url(#filter4400)"
+ id="rect2448"
+ width="124"
+ height="111.6"
+ x="81.628647"
+ y="239.27611"
+ inkscape:r_cx="true"
+ inkscape:r_cy="true"
+ ry="2.5302498"
+ rx="2.1433532"
+ transform="matrix(1,0,0,1.0035842,0,2.7423747)" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path2276"
+ d="M 124.00035,-57.652544 L 124.00035,-60.488828 L 124.00035,-57.652544 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path3242"
+ d="M -10.967378,-50.02293 L -10.967378,-52.859211 L -10.967378,-50.02293 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path2985"
+ d="M -170.31138,-120.69393 L -170.31138,-123.53021 L -170.31138,-120.69393 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path3206"
+ d="M -291.59132,-208.61291 L -291.59132,-211.4492 L -291.59132,-208.61291 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <g
+ id="layer4"
+ inkscape:label="box"
+ style="display:inline"
+ transform="matrix(1.0148767,0,0,1.0148767,-105.918,-61.880454)" />
+ <g
+ id="layer5"
+ inkscape:label="zip_app"
+ style="display:inline"
+ transform="matrix(1.0148767,0,0,1.0148767,-105.918,-61.880454)" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path3946"
+ d="M -41.331563,-141.87945 L -41.331563,-144.71574 L -41.331563,-141.87945 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path1561"
+ d="M -135.33391,-66.886514 L -135.33391,-68.43596 L -135.33391,-66.886514 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <rect
+ style="opacity:0.57786889;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.63199997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ id="rect1327"
+ width="1.0148762"
+ height="0"
+ x="-193.67381"
+ y="-124.32849" />
+ <rect
+ style="opacity:0.57786889;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.63199997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ id="rect2482"
+ width="1.0148762"
+ height="0"
+ x="-229.3232"
+ y="-152.26562" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path2494"
+ d="M -390.62499,-226.57087 L -390.62499,-229.40715 L -390.62499,-226.57087 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <g
+ style="opacity:0.40163933"
+ transform="matrix(-0.7946432,0,0,0.6605615,-2748.0383,470.15972)"
+ id="g4640" />
+ <g
+ id="g4646"
+ transform="matrix(-0.7946432,0,0,0.6605615,-2748.0383,470.15972)"
+ style="opacity:0.40163933" />
+ <g
+ id="g4730"
+ transform="matrix(1.0148767,0,0,0.6605615,500.54238,477.59645)"
+ style="opacity:0.40163933" />
+ <g
+ style="opacity:0.40163933"
+ transform="matrix(1.0148767,0,0,0.6605615,500.54238,477.59645)"
+ id="g4748" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path6923"
+ d="M 131.54671,109.09814 L 131.54671,106.26186 L 131.54671,109.09814 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path6925"
+ d="M -27.797286,38.427136 L -27.797286,35.59084 L -27.797286,38.427136 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path6927"
+ d="M -149.07723,-49.491843 L -149.07723,-52.328139 L -149.07723,-49.491843 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <g
+ id="g6929"
+ inkscape:label="box"
+ style="display:inline"
+ transform="matrix(1.0148767,0,0,1.0148767,36.596,97.240605)" />
+ <g
+ id="g6931"
+ inkscape:label="zip_app"
+ style="display:inline"
+ transform="matrix(1.0148767,0,0,1.0148767,36.596,97.240605)" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path6933"
+ d="M 101.18252,17.241605 L 101.18252,14.405323 L 101.18252,17.241605 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path6935"
+ d="M 7.1801708,92.234553 L 7.1801708,90.685107 L 7.1801708,92.234553 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <rect
+ style="opacity:0.57786889;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.63199997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ id="rect6937"
+ width="1.0148762"
+ height="0"
+ x="-51.159706"
+ y="34.792564" />
+ <rect
+ style="opacity:0.57786889;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.63199997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ id="rect6939"
+ width="1.0148762"
+ height="0"
+ x="-86.809097"
+ y="6.8554554" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path6941"
+ d="M -248.1109,-67.4498 L -248.1109,-70.286084 L -248.1109,-67.4498 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <g
+ style="opacity:0.40163933"
+ transform="matrix(-0.7946432,0,0,0.6605615,-2605.5245,629.28073)"
+ id="g6943" />
+ <g
+ id="g6945"
+ transform="matrix(-0.7946432,0,0,0.6605615,-2605.5245,629.28073)"
+ style="opacity:0.40163933" />
+ <g
+ id="g6947"
+ transform="matrix(1.0148767,0,0,0.6605615,643.05646,636.7176)"
+ style="opacity:0.40163933" />
+ <g
+ style="opacity:0.40163933"
+ transform="matrix(1.0148767,0,0,0.6605615,643.05646,636.7176)"
+ id="g6949" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path7559"
+ d="M 81.310335,56.324571 L 81.310335,53.48829 L 81.310335,56.324571 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path7561"
+ d="M -78.033659,-14.346435 L -78.033659,-17.182717 L -78.033659,-14.346435 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path7563"
+ d="M -199.31361,-102.26541 L -199.31361,-105.1017 L -199.31361,-102.26541 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <g
+ id="g7565"
+ inkscape:label="box"
+ style="display:inline"
+ transform="matrix(1.0148767,0,0,1.0148767,-13.640366,44.467018)" />
+ <g
+ id="g7567"
+ inkscape:label="zip_app"
+ style="display:inline"
+ transform="matrix(1.0148767,0,0,1.0148767,-13.640366,44.467018)" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path7569"
+ d="M 50.946152,-35.531953 L 50.946152,-38.368234 L 50.946152,-35.531953 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path7571"
+ d="M -43.056203,39.460982 L -43.056203,37.911535 L -43.056203,39.460982 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <rect
+ style="opacity:0.57786889;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.63199997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ id="rect7573"
+ width="1.0148762"
+ height="0"
+ x="-101.39607"
+ y="-17.980991" />
+ <rect
+ style="opacity:0.57786889;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.63199997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ id="rect7575"
+ width="1.0148762"
+ height="0"
+ x="-137.04547"
+ y="-45.918106" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path7577"
+ d="M -298.34728,-120.22337 L -298.34728,-123.05965 L -298.34728,-120.22337 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <g
+ style="opacity:0.40163933"
+ transform="matrix(-0.7946432,0,0,0.6605615,-2655.7605,576.50714)"
+ id="g7579" />
+ <g
+ id="g7581"
+ transform="matrix(-0.7946432,0,0,0.6605615,-2655.7605,576.50714)"
+ style="opacity:0.40163933" />
+ <g
+ id="g7583"
+ transform="matrix(1.0148767,0,0,0.6605615,592.81999,583.94401)"
+ style="opacity:0.40163933" />
+ <g
+ style="opacity:0.40163933"
+ transform="matrix(1.0148767,0,0,0.6605615,592.81999,583.94401)"
+ id="g7585" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path8394"
+ d="M -311.70048,181.91552 L -311.70048,179.07922 L -311.70048,181.91552 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path8396"
+ d="M -471.0445,111.2445 L -471.0445,108.40822 L -471.0445,111.2445 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path8398"
+ d="M -592.32444,23.325521 L -592.32444,20.489239 L -592.32444,23.325521 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <g
+ id="g8400"
+ inkscape:label="box"
+ style="display:inline"
+ transform="matrix(1.0148767,0,0,1.0148767,-406.65121,170.05797)" />
+ <g
+ id="g8402"
+ inkscape:label="zip_app"
+ style="display:inline"
+ transform="matrix(1.0148767,0,0,1.0148767,-406.65121,170.05797)" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path8404"
+ d="M -342.06469,90.058982 L -342.06469,87.222701 L -342.06469,90.058982 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path8406"
+ d="M -436.06704,165.05193 L -436.06704,163.50247 L -436.06704,165.05193 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <rect
+ style="opacity:0.57786889;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.63199997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ id="rect8408"
+ width="1.0148762"
+ height="0"
+ x="-494.40692"
+ y="107.60993" />
+ <rect
+ style="opacity:0.57786889;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.63199997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ id="rect8410"
+ width="1.0148762"
+ height="0"
+ x="-530.05627"
+ y="79.672829" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path8412"
+ d="M -691.35811,5.367577 L -691.35811,2.5312809 L -691.35811,5.367577 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <g
+ style="opacity:0.40163933"
+ transform="matrix(-0.7946432,0,0,0.6605615,-3048.7709,702.09809)"
+ id="g8414" />
+ <g
+ id="g8416"
+ transform="matrix(-0.7946432,0,0,0.6605615,-3048.7709,702.09809)"
+ style="opacity:0.40163933" />
+ <g
+ id="g8418"
+ transform="matrix(1.0148767,0,0,0.6605615,199.80926,709.53496)"
+ style="opacity:0.40163933" />
+ <g
+ style="opacity:0.40163933"
+ transform="matrix(1.0148767,0,0,0.6605615,199.80926,709.53496)"
+ id="g8420" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path9104"
+ d="M -55.553696,360.93168 L -55.553696,358.09539 L -55.553696,360.93168 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path9106"
+ d="M -214.89769,290.26066 L -214.89769,287.42437 L -214.89769,290.26066 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path9108"
+ d="M -336.17763,202.34167 L -336.17763,199.50539 L -336.17763,202.34167 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <g
+ id="g9110"
+ inkscape:label="box"
+ style="display:inline"
+ transform="matrix(1.0148767,0,0,1.0148767,-150.50435,349.07409)" />
+ <g
+ id="g9112"
+ inkscape:label="zip_app"
+ style="display:inline"
+ transform="matrix(1.0148767,0,0,1.0148767,-150.50435,349.07409)" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path9114"
+ d="M -85.917879,269.07514 L -85.917879,266.23885 L -85.917879,269.07514 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path9116"
+ d="M -179.92023,344.06809 L -179.92023,342.51863 L -179.92023,344.06809 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <rect
+ style="opacity:0.57786889;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.63199997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ id="rect9118"
+ width="1.0148762"
+ height="0"
+ x="-238.26013"
+ y="286.62607" />
+ <rect
+ style="opacity:0.57786889;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.63199997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ id="rect9120"
+ width="1.0148762"
+ height="0"
+ x="-273.90948"
+ y="258.68896" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path9122"
+ d="M -435.2113,184.38373 L -435.2113,181.54743 L -435.2113,184.38373 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <g
+ style="opacity:0.40163933"
+ transform="matrix(-0.7946432,0,0,0.6605615,-2792.6249,881.11422)"
+ id="g9124" />
+ <g
+ id="g9126"
+ transform="matrix(-0.7946432,0,0,0.6605615,-2792.6249,881.11422)"
+ style="opacity:0.40163933" />
+ <g
+ id="g9128"
+ transform="matrix(1.0148767,0,0,0.6605615,455.95601,888.55109)"
+ style="opacity:0.40163933" />
+ <g
+ style="opacity:0.40163933"
+ transform="matrix(1.0148767,0,0,0.6605615,455.95601,888.55109)"
+ id="g9130" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path3633"
+ d="M -157.70057,123.8935 L -157.70057,121.0572 L -157.70057,123.8935 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path3635"
+ d="M -317.04457,53.222473 L -317.04457,50.386192 L -317.04457,53.222473 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path3637"
+ d="M -438.32452,-34.696491 L -438.32452,-37.532787 L -438.32452,-34.696491 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <g
+ id="g3639"
+ inkscape:label="box"
+ style="display:inline"
+ transform="matrix(1.0148767,0,0,1.0148767,-252.6514,112.03596)" />
+ <g
+ id="g3641"
+ inkscape:label="zip_app"
+ style="display:inline"
+ transform="matrix(1.0148767,0,0,1.0148767,-252.6514,112.03596)" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path3643"
+ d="M -188.06476,32.036956 L -188.06476,29.200675 L -188.06476,32.036956 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path3645"
+ d="M -282.06711,107.02991 L -282.06711,105.48044 L -282.06711,107.02991 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <rect
+ style="opacity:0.57786889;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.63199997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ id="rect3647"
+ width="1.0148762"
+ height="0"
+ x="-340.40701"
+ y="49.587921" />
+ <rect
+ style="opacity:0.57786889;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.63199997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ id="rect3649"
+ width="1.0148762"
+ height="0"
+ x="-376.0564"
+ y="21.650791" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path3651"
+ d="M -537.35819,-52.65445 L -537.35819,-55.490731 L -537.35819,-52.65445 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <g
+ style="opacity:0.40163933"
+ transform="matrix(-0.7946432,0,0,0.6605615,-2894.7709,644.07608)"
+ id="g3653" />
+ <g
+ id="g3655"
+ transform="matrix(-0.7946432,0,0,0.6605615,-2894.7709,644.07608)"
+ style="opacity:0.40163933" />
+ <g
+ id="g3657"
+ transform="matrix(1.0148767,0,0,0.6605615,353.80908,651.51294)"
+ style="opacity:0.40163933" />
+ <g
+ style="opacity:0.40163933"
+ transform="matrix(1.0148767,0,0,0.6605615,353.80908,651.51294)"
+ id="g3659" />
+ <rect
+ rx="2.0742123"
+ ry="2.4486284"
+ inkscape:r_cy="true"
+ inkscape:r_cx="true"
+ y="244.87613"
+ x="83.628647"
+ height="107.99998"
+ width="119.99998"
+ id="rect2894"
+ style="fill:url(#linearGradient7912);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ inkscape:export-filename="/home/pinheiro/Desktop/mock2.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path10461"
+ d="M -155.66325,122.95497 L -155.66325,120.11867 L -155.66325,122.95497 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path10463"
+ d="M -315.00724,52.283945 L -315.00724,49.447664 L -315.00724,52.283945 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path10465"
+ d="M -436.28719,-35.635034 L -436.28719,-38.471315 L -436.28719,-35.635034 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <g
+ id="g10467"
+ inkscape:label="box"
+ style="display:inline"
+ transform="matrix(1.0148767,0,0,1.0148767,-250.61396,111.0974)" />
+ <g
+ id="g10469"
+ inkscape:label="zip_app"
+ style="display:inline"
+ transform="matrix(1.0148767,0,0,1.0148767,-250.61396,111.0974)" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path10471"
+ d="M -186.02744,31.098428 L -186.02744,28.262146 L -186.02744,31.098428 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path10473"
+ d="M -280.02978,106.09138 L -280.02978,104.54192 L -280.02978,106.09138 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <rect
+ style="opacity:0.57786889;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.63199997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ id="rect10475"
+ width="1.0148762"
+ height="0"
+ x="-338.36966"
+ y="48.64938" />
+ <rect
+ style="opacity:0.57786889;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.63199997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ id="rect10477"
+ width="1.0148762"
+ height="0"
+ x="-374.01904"
+ y="20.712275" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path10479"
+ d="M -535.32086,-53.592984 L -535.32086,-56.429268 L -535.32086,-53.592984 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <g
+ style="opacity:0.40163933"
+ transform="matrix(-0.7946432,0,0,0.6605615,-2892.7339,643.13752)"
+ id="g10481" />
+ <g
+ id="g10483"
+ transform="matrix(-0.7946432,0,0,0.6605615,-2892.7339,643.13752)"
+ style="opacity:0.40163933" />
+ <g
+ id="g10485"
+ transform="matrix(1.0148767,0,0,0.6605615,355.84651,650.57439)"
+ style="opacity:0.40163933" />
+ <g
+ style="opacity:0.40163933"
+ transform="matrix(1.0148767,0,0,0.6605615,355.84651,650.57439)"
+ id="g10487" />
+ <g
+ id="g10952"
+ transform="matrix(1.4999999,0,0,1.4999997,-39.814316,-120.43796)">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="/home/pinheiro/Desktop/mock2.png"
+ sodipodi:type="arc"
+ style="opacity:1;fill:url(#linearGradient12912);fill-opacity:1;stroke:none;stroke-width:3.82999992;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.1375"
+ id="path2972"
+ sodipodi:cx="1055.3002"
+ sodipodi:cy="-478.60516"
+ sodipodi:rx="5.0602889"
+ sodipodi:ry="5.0602889"
+ d="M 1060.3605 -478.60516 A 5.0602889 5.0602889 0 1 1 1050.2399,-478.60516 A 5.0602889 5.0602889 0 1 1 1060.3605 -478.60516 z"
+ transform="matrix(0.7904687,0,0,0.7904687,-678.5531,631.1985)" />
+ </g>
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path2875"
+ d="M 148.21519,68.932055 L 148.21519,66.095774 L 148.21519,68.932055 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path2879"
+ d="M 13.247467,76.561684 L 13.247467,73.725388 L 13.247467,76.561684 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path2881"
+ d="M -146.09653,5.8906629 L -146.09653,3.0543815 L -146.09653,5.8906629 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path2883"
+ d="M -267.37648,-82.028304 L -267.37648,-84.864599 L -267.37648,-82.028304 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <g
+ id="g2885"
+ inkscape:label="box"
+ style="display:inline"
+ transform="matrix(1.0148767,0,0,1.0148767,-81.703147,64.704175)" />
+ <g
+ id="g2887"
+ inkscape:label="zip_app"
+ style="display:inline"
+ transform="matrix(1.0148767,0,0,1.0148767,-81.703147,64.704175)" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path2889"
+ d="M -17.116717,-15.294854 L -17.116717,-18.131136 L -17.116717,-15.294854 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path2891"
+ d="M -111.11908,59.698095 L -111.11908,58.148648 L -111.11908,59.698095 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <rect
+ style="opacity:0.57786889;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.63199997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ id="rect2893"
+ width="1.0148762"
+ height="0"
+ x="-169.45897"
+ y="2.2560859" />
+ <rect
+ style="opacity:0.57786889;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.63199997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ id="rect2895"
+ width="1.0148762"
+ height="0"
+ x="-205.10835"
+ y="-25.681009" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path2897"
+ d="M -366.41015,-99.98626 L -366.41015,-102.82255 L -366.41015,-99.98626 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <g
+ style="opacity:0.40163933"
+ transform="matrix(-0.7946432,0,0,0.6605615,-2723.823,596.7443)"
+ id="g2899" />
+ <g
+ id="g2901"
+ transform="matrix(-0.7946432,0,0,0.6605615,-2723.823,596.7443)"
+ style="opacity:0.40163933" />
+ <g
+ id="g2903"
+ transform="matrix(1.0148767,0,0,0.6605615,524.75712,604.18101)"
+ style="opacity:0.40163933" />
+ <g
+ style="opacity:0.40163933"
+ transform="matrix(1.0148767,0,0,0.6605615,524.75712,604.18101)"
+ id="g2905" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path2907"
+ d="M 155.76156,235.68274 L 155.76156,232.84646 L 155.76156,235.68274 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path2909"
+ d="M -3.5824389,165.01172 L -3.5824389,162.17545 L -3.5824389,165.01172 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path2911"
+ d="M -124.86239,77.092757 L -124.86239,74.256475 L -124.86239,77.092757 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <g
+ id="g2913"
+ inkscape:label="box"
+ style="display:inline"
+ transform="matrix(1.0148767,0,0,1.0148767,60.810854,223.82517)" />
+ <g
+ id="g2915"
+ inkscape:label="zip_app"
+ style="display:inline"
+ transform="matrix(1.0148767,0,0,1.0148767,60.810854,223.82517)" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path2917"
+ d="M 125.39737,143.8262 L 125.39737,140.98993 L 125.39737,143.8262 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path2919"
+ d="M 31.395018,218.81915 L 31.395018,217.26971 L 31.395018,218.81915 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <rect
+ style="opacity:0.57786889;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.63199997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ id="rect2921"
+ width="1.0148762"
+ height="0"
+ x="-26.94486"
+ y="161.37717" />
+ <rect
+ style="opacity:0.57786889;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.63199997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ id="rect2923"
+ width="1.0148762"
+ height="0"
+ x="-62.594242"
+ y="133.44006" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path2925"
+ d="M -223.89606,59.134798 L -223.89606,56.298517 L -223.89606,59.134798 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <g
+ style="opacity:0.40163933"
+ transform="matrix(-0.7946432,0,0,0.6605615,-2581.3092,755.8653)"
+ id="g2927" />
+ <g
+ id="g2929"
+ transform="matrix(-0.7946432,0,0,0.6605615,-2581.3092,755.8653)"
+ style="opacity:0.40163933" />
+ <g
+ id="g2931"
+ transform="matrix(1.0148767,0,0,0.6605615,667.2712,763.30217)"
+ style="opacity:0.40163933" />
+ <g
+ style="opacity:0.40163933"
+ transform="matrix(1.0148767,0,0,0.6605615,667.2712,763.30217)"
+ id="g2933" />
+ <path
+ style="fill:url(#linearGradient7843);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ d="M 85.69115,244.87613 C 84.542036,244.87613 83.62865,245.95709 83.62865,247.31362 L 83.62865,350.4386 C 83.62865,351.79515 84.542036,352.8761 85.69115,352.8761 L 201.56615,352.8761 C 202.71528,352.8761 203.62865,351.79515 203.62865,350.4386 L 203.62865,247.31362 C 203.62865,245.95709 202.71528,244.87613 201.56615,244.87613 L 85.69115,244.87613 z M 87.0974,248.53238 L 200.1599,248.53238 C 201.25156,248.53238 202.12865,249.55644 202.12865,250.82926 L 202.12865,349.07923 C 202.12865,350.35203 201.25156,351.3761 200.1599,351.3761 L 87.0974,351.3761 C 86.005743,351.3761 85.12865,350.35203 85.12865,349.07923 L 85.12865,250.82926 C 85.12865,249.55644 86.005743,248.53238 87.0974,248.53238 z "
+ id="rect3821"
+ sodipodi:nodetypes="cccccccccccccccccc" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path4109"
+ d="M -221.04685,-183.3058 L -221.04685,-187.15627 L -221.04685,-183.3058 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path4111"
+ d="M -404.27583,-172.94801 L -404.27583,-176.79848 L -404.27583,-172.94801 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path4113"
+ d="M -620.59744,-268.8893 L -620.59744,-272.73977 L -620.59744,-268.8893 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path4115"
+ d="M -785.24423,-388.246 L -785.24423,-392.09649 L -785.24423,-388.246 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <g
+ id="g4117"
+ inkscape:label="box"
+ style="display:inline"
+ transform="matrix(1.3777714,0,0,1.3777714,-533.1785,-189.04551)" />
+ <g
+ id="g4119"
+ inkscape:label="zip_app"
+ style="display:inline"
+ transform="matrix(1.3777714,0,0,1.3777714,-533.1785,-189.04551)" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path4121"
+ d="M -445.49752,-297.65025 L -445.49752,-301.50073 L -445.49752,-297.65025 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path4123"
+ d="M -573.11289,-195.84162 L -573.11289,-197.94512 L -573.11289,-195.84162 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <rect
+ style="opacity:0.57786889;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.63199997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ id="rect4125"
+ width="1.377772"
+ height="0"
+ x="-652.31372"
+ y="-273.82349" />
+ <rect
+ style="opacity:0.57786889;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.63199997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ id="rect4127"
+ width="1.377772"
+ height="0"
+ x="-700.71045"
+ y="-311.75027" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path4129"
+ d="M -919.69,-412.62529 L -919.69,-416.47578 L -919.69,-412.62529 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <g
+ style="opacity:0.40163933"
+ transform="matrix(-1.078788,0,0,0.8967627,-4120.0585,533.23945)"
+ id="g4131" />
+ <g
+ id="g4133"
+ transform="matrix(-1.078788,0,0,0.8967627,-4120.0585,533.23945)"
+ style="opacity:0.40163933" />
+ <g
+ id="g4135"
+ transform="matrix(1.3777714,0,0,0.8967627,290.13757,543.33536)"
+ style="opacity:0.40163933" />
+ <g
+ style="opacity:0.40163933"
+ transform="matrix(1.3777714,0,0,0.8967627,290.13757,543.33536)"
+ id="g4137" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path4139"
+ d="M -210.80207,43.070976 L -210.80207,39.220511 L -210.80207,43.070976 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path4141"
+ d="M -427.1237,-52.870316 L -427.1237,-56.720788 L -427.1237,-52.870316 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path4143"
+ d="M -591.77047,-172.22704 L -591.77047,-176.07751 L -591.77047,-172.22704 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <g
+ id="g4145"
+ inkscape:label="box"
+ style="display:inline"
+ transform="matrix(1.3777714,0,0,1.3777714,-339.70493,26.973349)" />
+ <g
+ id="g4147"
+ inkscape:label="zip_app"
+ style="display:inline"
+ transform="matrix(1.3777714,0,0,1.3777714,-339.70493,26.973349)" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path4149"
+ d="M -252.02378,-81.631278 L -252.02378,-85.48175 L -252.02378,-81.631278 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path4151"
+ d="M -379.63914,20.177365 L -379.63914,18.073877 L -379.63914,20.177365 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <rect
+ style="opacity:0.57786889;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.63199997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ id="rect4153"
+ width="1.377772"
+ height="0"
+ x="-458.84"
+ y="-57.804516" />
+ <rect
+ style="opacity:0.57786889;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.63199997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ id="rect4155"
+ width="1.377772"
+ height="0"
+ x="-507.23672"
+ y="-95.731277" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path4157"
+ d="M -726.21624,-196.60632 L -726.21624,-200.4568 L -726.21624,-196.60632 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <g
+ style="opacity:0.40163933"
+ transform="matrix(-1.078788,0,0,0.8967627,-3926.5854,749.25849)"
+ id="g4159" />
+ <g
+ id="g4161"
+ transform="matrix(-1.078788,0,0,0.8967627,-3926.5854,749.25849)"
+ style="opacity:0.40163933" />
+ <g
+ id="g4163"
+ transform="matrix(1.3777714,0,0,0.8967627,483.61129,759.35456)"
+ style="opacity:0.40163933" />
+ <g
+ style="opacity:0.40163933"
+ transform="matrix(1.3777714,0,0,0.8967627,483.61129,759.35456)"
+ id="g4165" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path4167"
+ d="M -279.00178,-28.573161 L -279.00178,-32.42364 L -279.00178,-28.573161 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path4169"
+ d="M -495.32341,-124.51446 L -495.32341,-128.36493 L -495.32341,-124.51446 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path4171"
+ d="M -659.97018,-243.87117 L -659.97018,-247.72165 L -659.97018,-243.87117 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <g
+ id="g4173"
+ inkscape:label="box"
+ style="display:inline"
+ transform="matrix(1.3777714,0,0,1.3777714,-407.90465,-44.670655)" />
+ <g
+ id="g4175"
+ inkscape:label="zip_app"
+ style="display:inline"
+ transform="matrix(1.3777714,0,0,1.3777714,-407.90465,-44.670655)" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path4177"
+ d="M -320.22348,-153.27542 L -320.22348,-157.12589 L -320.22348,-153.27542 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path4179"
+ d="M -447.83885,-51.466781 L -447.83885,-53.570274 L -447.83885,-51.466781 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <rect
+ style="opacity:0.57786889;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.63199997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ id="rect4181"
+ width="1.377772"
+ height="0"
+ x="-527.03967"
+ y="-129.44864" />
+ <rect
+ style="opacity:0.57786889;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.63199997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ id="rect4184"
+ width="1.377772"
+ height="0"
+ x="-575.43646"
+ y="-167.37541" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path4186"
+ d="M -794.41595,-268.25047 L -794.41595,-272.10094 L -794.41595,-268.25047 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <g
+ style="opacity:0.40163933"
+ transform="matrix(-1.078788,0,0,0.8967627,-3994.7851,677.61424)"
+ id="g4188" />
+ <g
+ id="g4190"
+ transform="matrix(-1.078788,0,0,0.8967627,-3994.7851,677.61424)"
+ style="opacity:0.40163933" />
+ <g
+ id="g4192"
+ transform="matrix(1.3777714,0,0,0.8967627,415.41173,687.71031)"
+ style="opacity:0.40163933" />
+ <g
+ style="opacity:0.40163933"
+ transform="matrix(1.3777714,0,0,0.8967627,415.41173,687.71031)"
+ id="g4194" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path4196"
+ d="M -812.54397,141.92612 L -812.54397,138.07564 L -812.54397,141.92612 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path4198"
+ d="M -1028.8656,45.984831 L -1028.8656,42.134352 L -1028.8656,45.984831 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path4200"
+ d="M -1193.5124,-73.371901 L -1193.5124,-77.222373 L -1193.5124,-73.371901 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <g
+ id="g4202"
+ inkscape:label="box"
+ style="display:inline"
+ transform="matrix(1.3777714,0,0,1.3777714,-941.44678,125.82854)" />
+ <g
+ id="g4204"
+ inkscape:label="zip_app"
+ style="display:inline"
+ transform="matrix(1.3777714,0,0,1.3777714,-941.44678,125.82854)" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path4206"
+ d="M -853.76566,17.223876 L -853.76566,13.373397 L -853.76566,17.223876 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path4208"
+ d="M -981.38102,119.03251 L -981.38102,116.92901 L -981.38102,119.03251 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <rect
+ style="opacity:0.57786889;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.63199997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ id="rect4210"
+ width="1.377772"
+ height="0"
+ x="-1060.5818"
+ y="41.050621" />
+ <rect
+ style="opacity:0.57786889;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.63199997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ id="rect4212"
+ width="1.377772"
+ height="0"
+ x="-1108.9786"
+ y="3.1238759" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path4214"
+ d="M -1327.9581,-97.75119 L -1327.9581,-101.60167 L -1327.9581,-97.75119 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <g
+ style="opacity:0.40163933"
+ transform="matrix(-1.078788,0,0,0.8967627,-4528.3268,848.11353)"
+ id="g4216" />
+ <g
+ id="g4218"
+ transform="matrix(-1.078788,0,0,0.8967627,-4528.3268,848.11353)"
+ style="opacity:0.40163933" />
+ <g
+ id="g4220"
+ transform="matrix(1.3777714,0,0,0.8967627,-118.13056,858.20959)"
+ style="opacity:0.40163933" />
+ <g
+ style="opacity:0.40163933"
+ transform="matrix(1.3777714,0,0,0.8967627,-118.13056,858.20959)"
+ id="g4222" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path4224"
+ d="M -464.80515,384.9542 L -464.80515,381.10373 L -464.80515,384.9542 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path4226"
+ d="M -681.12676,289.01289 L -681.12676,285.16244 L -681.12676,289.01289 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path4228"
+ d="M -845.77355,169.65618 L -845.77355,165.80572 L -845.77355,169.65618 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <g
+ id="g4230"
+ inkscape:label="box"
+ style="display:inline"
+ transform="matrix(1.3777714,0,0,1.3777714,-593.70797,368.85658)" />
+ <g
+ id="g4232"
+ inkscape:label="zip_app"
+ style="display:inline"
+ transform="matrix(1.3777714,0,0,1.3777714,-593.70797,368.85658)" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path4234"
+ d="M -506.02685,260.25196 L -506.02685,256.40147 L -506.02685,260.25196 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path4236"
+ d="M -633.64221,362.06058 L -633.64221,359.95708 L -633.64221,362.06058 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <rect
+ style="opacity:0.57786889;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.63199997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ id="rect4238"
+ width="1.377772"
+ height="0"
+ x="-712.84308"
+ y="284.07864" />
+ <rect
+ style="opacity:0.57786889;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.63199997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ id="rect4240"
+ width="1.377772"
+ height="0"
+ x="-761.23975"
+ y="246.1519" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path4242"
+ d="M -980.21932,145.27689 L -980.21932,141.42643 L -980.21932,145.27689 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <g
+ style="opacity:0.40163933"
+ transform="matrix(-1.078788,0,0,0.8967627,-4180.588,1091.1417)"
+ id="g4244" />
+ <g
+ id="g4246"
+ transform="matrix(-1.078788,0,0,0.8967627,-4180.588,1091.1417)"
+ style="opacity:0.40163933" />
+ <g
+ id="g4248"
+ transform="matrix(1.3777714,0,0,0.8967627,229.60826,1101.2376)"
+ style="opacity:0.40163933" />
+ <g
+ style="opacity:0.40163933"
+ transform="matrix(1.3777714,0,0,0.8967627,229.60826,1101.2376)"
+ id="g4250" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path4252"
+ d="M -603.47732,63.156795 L -603.47732,59.306316 L -603.47732,63.156795 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path4254"
+ d="M -819.79895,-32.784494 L -819.79895,-36.634972 L -819.79895,-32.784494 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path4256"
+ d="M -984.44573,-152.14121 L -984.44573,-155.99168 L -984.44573,-152.14121 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <g
+ id="g4258"
+ inkscape:label="box"
+ style="display:inline"
+ transform="matrix(1.3777714,0,0,1.3777714,-732.38027,47.059197)" />
+ <g
+ id="g4260"
+ inkscape:label="zip_app"
+ style="display:inline"
+ transform="matrix(1.3777714,0,0,1.3777714,-732.38027,47.059197)" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path4262"
+ d="M -644.69902,-61.545463 L -644.69902,-65.395935 L -644.69902,-61.545463 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path4264"
+ d="M -772.31439,40.263185 L -772.31439,38.159681 L -772.31439,40.263185 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <rect
+ style="opacity:0.57786889;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.63199997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ id="rect4266"
+ width="1.377772"
+ height="0"
+ x="-851.51532"
+ y="-37.718704" />
+ <rect
+ style="opacity:0.57786889;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.63199997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ id="rect4268"
+ width="1.377772"
+ height="0"
+ x="-899.91205"
+ y="-75.645462" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path4270"
+ d="M -1118.8915,-176.52051 L -1118.8915,-180.37098 L -1118.8915,-176.52051 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <g
+ style="opacity:0.40163933"
+ transform="matrix(-1.078788,0,0,0.8967627,-4319.2592,769.34433)"
+ id="g4272" />
+ <g
+ id="g4274"
+ transform="matrix(-1.078788,0,0,0.8967627,-4319.2592,769.34433)"
+ style="opacity:0.40163933" />
+ <g
+ id="g4276"
+ transform="matrix(1.3777714,0,0,0.8967627,90.936098,779.4404)"
+ style="opacity:0.40163933" />
+ <g
+ style="opacity:0.40163933"
+ transform="matrix(1.3777714,0,0,0.8967627,90.936098,779.4404)"
+ id="g4278" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path4284"
+ d="M -600.7115,61.88267 L -600.7115,58.032192 L -600.7115,61.88267 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path4286"
+ d="M -817.03314,-34.058632 L -817.03314,-37.909104 L -817.03314,-34.058632 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path4288"
+ d="M -981.67991,-153.41535 L -981.67991,-157.26582 L -981.67991,-153.41535 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <g
+ id="g4290"
+ inkscape:label="box"
+ style="display:inline"
+ transform="matrix(1.3777714,0,0,1.3777714,-729.61435,45.785103)" />
+ <g
+ id="g4292"
+ inkscape:label="zip_app"
+ style="display:inline"
+ transform="matrix(1.3777714,0,0,1.3777714,-729.61435,45.785103)" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path4294"
+ d="M -641.93321,-62.819593 L -641.93321,-66.670065 L -641.93321,-62.819593 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path4296"
+ d="M -769.54857,38.98906 L -769.54857,36.885557 L -769.54857,38.98906 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <rect
+ style="opacity:0.57786889;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.63199997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ id="rect4298"
+ width="1.377772"
+ height="0"
+ x="-848.74945"
+ y="-38.992832" />
+ <rect
+ style="opacity:0.57786889;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.63199997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ id="rect4300"
+ width="1.377772"
+ height="0"
+ x="-897.14618"
+ y="-76.919586" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path4302"
+ d="M -1116.1257,-177.79464 L -1116.1257,-181.64512 L -1116.1257,-177.79464 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <g
+ style="opacity:0.40163933"
+ transform="matrix(-1.078788,0,0,0.8967627,-4316.4943,768.07009)"
+ id="g4304" />
+ <g
+ id="g4306"
+ transform="matrix(-1.078788,0,0,0.8967627,-4316.4943,768.07009)"
+ style="opacity:0.40163933" />
+ <g
+ id="g4308"
+ transform="matrix(1.3777714,0,0,0.8967627,93.701877,778.16616)"
+ style="opacity:0.40163933" />
+ <g
+ style="opacity:0.40163933"
+ transform="matrix(1.3777714,0,0,0.8967627,93.701877,778.16616)"
+ id="g4310" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path4356"
+ d="M -188.17335,-11.457543 L -188.17335,-24.027191 L -188.17335,-15.308022 L -188.17335,-11.457543 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path4358"
+ d="M -371.40232,-1.0997485 L -371.40232,-4.9502274 L -371.40232,-1.0997485 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path4360"
+ d="M -587.72396,-97.04105 L -587.72396,-100.89152 L -587.72396,-97.04105 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path4362"
+ d="M -752.37073,-216.39776 L -752.37073,-220.24824 L -752.37073,-216.39776 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <g
+ id="g4364"
+ inkscape:label="box"
+ style="display:inline"
+ transform="matrix(1.3777714,0,0,1.3777714,-500.30506,-17.197346)" />
+ <g
+ id="g4366"
+ inkscape:label="zip_app"
+ style="display:inline"
+ transform="matrix(1.3777714,0,0,1.3777714,-500.30506,-17.197346)" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path4368"
+ d="M -412.62402,-125.802 L -412.62402,-129.65248 L -412.62402,-125.802 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path4370"
+ d="M -540.23937,-23.993359 L -540.23937,-26.096862 L -540.23937,-23.993359 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <rect
+ style="opacity:0.57786889;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.63199997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ id="rect4372"
+ width="1.377772"
+ height="0"
+ x="-619.44025"
+ y="-101.97524" />
+ <rect
+ style="opacity:0.57786889;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.63199997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ id="rect4374"
+ width="1.377772"
+ height="0"
+ x="-667.83704"
+ y="-139.90201" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path4376"
+ d="M -886.81649,-240.77705 L -886.81649,-244.62753 L -886.81649,-240.77705 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <g
+ style="opacity:0.40163933"
+ transform="matrix(-1.078788,0,0,0.8967627,-4087.1854,705.08781)"
+ id="g4378" />
+ <g
+ id="g4380"
+ transform="matrix(-1.078788,0,0,0.8967627,-4087.1854,705.08781)"
+ style="opacity:0.40163933" />
+ <g
+ id="g4382"
+ transform="matrix(1.3777714,0,0,0.8967627,323.01116,715.18372)"
+ style="opacity:0.40163933" />
+ <g
+ style="opacity:0.40163933"
+ transform="matrix(1.3777714,0,0,0.8967627,323.01116,715.18372)"
+ id="g4384" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path4386"
+ d="M -177.92858,214.91924 L -177.92858,211.06876 L -177.92858,214.91924 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path4388"
+ d="M -394.2502,118.97794 L -394.2502,115.12747 L -394.2502,118.97794 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path4390"
+ d="M -558.89698,-0.3787802 L -558.89698,-4.2292443 L -558.89698,-0.3787802 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <g
+ id="g4392"
+ inkscape:label="box"
+ style="display:inline"
+ transform="matrix(1.3777714,0,0,1.3777714,-306.83133,198.82157)" />
+ <g
+ id="g4394"
+ inkscape:label="zip_app"
+ style="display:inline"
+ transform="matrix(1.3777714,0,0,1.3777714,-306.83133,198.82157)" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path4396"
+ d="M -219.15028,90.216979 L -219.15028,86.366515 L -219.15028,90.216979 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path4398"
+ d="M -346.76564,192.02563 L -346.76564,189.92213 L -346.76564,192.02563 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <rect
+ style="opacity:0.57786889;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.63199997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ id="rect4400"
+ width="1.377772"
+ height="0"
+ x="-425.96643"
+ y="114.04373" />
+ <rect
+ style="opacity:0.57786889;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.63199997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1"
+ id="rect4402"
+ width="1.377772"
+ height="0"
+ x="-474.36322"
+ y="76.116974" />
+ <path
+ sodipodi:nodetypes="ccc"
+ id="path4404"
+ d="M -693.34274,-24.758066 L -693.34274,-28.608545 L -693.34274,-24.758066 z "
+ style="fill:#ffffff;fill-opacity:0.75688076;fill-rule:nonzero;stroke:none;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:4;stroke-opacity:1" />
+ <g
+ style="opacity:0.40163933"
+ transform="matrix(-1.078788,0,0,0.8967627,-3893.7122,921.10671)"
+ id="g4406" />
+ <g
+ id="g4408"
+ transform="matrix(-1.078788,0,0,0.8967627,-3893.7122,921.10671)"
+ style="opacity:0.40163933" />
+ <g
+ id="g4410"
+ transform="matrix(1.3777714,0,0,0.8967627,516.48488,931.20277)"
+ style="opacity:0.40163933" />
+ <g
+ style="opacity:0.40163933"
+ transform="matrix(1.3777714,0,0,0.8967627,516.48488,931.20277)"
+ id="g4412" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.67876971;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:4;stroke-opacity:1"
+ d="M 83.62865,276.8761 L 203.62865,276.8761 L 203.62865,352.8761 L 83.62865,352.8761 L 83.62865,276.8761 z "
+ id="rect8568" />
+ <use
+ x="0"
+ y="0"
+ xlink:href="#g10952"
+ id="use10958"
+ transform="translate(-16,-2.4e-6)"
+ width="96"
+ height="96" />
+ <use
+ x="0"
+ y="0"
+ xlink:href="#g10952"
+ id="use10968"
+ transform="translate(-32,-2.4e-6)"
+ width="96"
+ height="96" />
+ <use
+ x="0"
+ y="0"
+ xlink:href="#g10952"
+ id="use10972"
+ transform="translate(-96,-2.4e-6)"
+ width="96"
+ height="96" />
+ <path
+ style="opacity:1;fill:url(#linearGradient3493);fill-opacity:1;stroke:none;stroke-width:1.10000001999999997;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ d="M 10 52 C 8.892 52 8.0000002 52.891999 8 54 C 8 55.108 8.8919997 55.999999 10 56 L 70 56 C 71.108 56 71.999997 55.107999 72 54 C 72 52.892 71.107997 51.999999 70 52 L 10 52 z M 86 52 C 84.892 52 83.999997 52.557499 84 53.25 L 84 54.75 C 84 55.4425 84.891997 55.999999 86 56 L 94 56 C 95.108 56 96 55.442499 96 54.75 L 96 53.25 C 96 52.5575 95.108 51.999999 94 52 L 86 52 z M 110 52 C 108.892 52 108 52.557499 108 53.25 L 108 54.75 C 108 55.4425 108.892 55.999999 110 56 L 118 56 C 119.108 56 120 55.442499 120 54.75 L 120 53.25 C 120 52.5575 119.108 51.999999 118 52 L 110 52 z M 10 68 C 8.892 68 8.0000002 68.891999 8 70 C 8 71.108 8.8919997 71.999999 10 72 L 70 72 C 71.108 72 71.999997 71.107999 72 70 C 72 68.892 71.107997 67.999999 70 68 L 10 68 z M 86 68 C 84.892 68 83.999997 68.557499 84 69.25 L 84 70.75 C 84 71.4425 84.891997 71.999999 86 72 L 94 72 C 95.108 72 96 71.442499 96 70.75 L 96 69.25 C 96 68.5575 95.108 67.999999 94 68 L 86 68 z M 110 68 C 108.892 68 108 68.557499 108 69.25 L 108 70.75 C 108 71.4425 108.892 71.999999 110 72 L 118 72 C 119.108 72 120 71.442499 120 70.75 L 120 69.25 C 120 68.5575 119.108 67.999999 118 68 L 110 68 z M 10 84 C 8.892 84 8.0000002 84.891999 8 86 C 8 87.108 8.8919997 87.999999 10 88 L 58 88 C 59.108 88 60.000001 87.107999 60 86 C 60 84.892 59.108001 83.999999 58 84 L 10 84 z M 86 84 C 84.892 84 83.999997 84.891999 84 86 C 84 87.108 84.891997 87.999999 86 88 L 90 88 C 91.108 88 92 87.107999 92 86 C 92 84.892 91.108 83.999999 90 84 L 86 84 z M 110 84 C 108.892 84 108 84.557499 108 85.25 L 108 86.75 C 108 87.4425 108.892 87.999999 110 88 L 118 88 C 119.108 88 120 87.442499 120 86.75 L 120 85.25 C 120 84.5575 119.108 83.999999 118 84 L 110 84 z M 10 100 C 8.892 100 8.0000002 100.892 8 102 C 8 103.108 8.8919997 104 10 104 L 70 104 C 71.108 104 71.999997 103.108 72 102 C 72 100.892 71.107997 99.999999 70 100 L 10 100 z M 86 100 C 84.892 100 83.999997 100.5575 84 101.25 L 84 102.75 C 84 103.4425 84.891997 104 86 104 L 94 104 C 95.108 104 96 103.4425 96 102.75 L 96 101.25 C 96 100.5575 95.108 99.999999 94 100 L 86 100 z M 110 100 C 108.892 100 108 100.5575 108 101.25 L 108 102.75 C 108 103.4425 108.892 104 110 104 L 118 104 C 119.108 104 120 103.4425 120 102.75 L 120 101.25 C 120 100.5575 119.108 99.999999 118 100 L 110 100 z "
+ transform="translate(79.62865,236.8761)"
+ id="rect2692" />
+ </g>
+</svg>
diff --git a/spec/View_spec.rb b/spec/View_spec.rb
new file mode 100644
index 0000000..7a90a01
--- /dev/null
+++ b/spec/View_spec.rb
@@ -0,0 +1,61 @@
+#!/usr/bin/env ruby -w
+# encoding: UTF-8
+#
+# = View_spec.rb -- PostRunner - Manage the data from your Garmin sport devices.
+#
+# Copyright (c) 2015 by Chris Schlaeger <cs@taskjuggler.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+
+require 'postrunner/View'
+require 'postrunner/ViewButtons'
+require 'postrunner/PagingButtons'
+
+module PostRunner
+
+ describe PostRunner::View do
+
+ before(:all) do
+ @view_names = %w( activities record )
+ delete_files
+ end
+
+ after(:all) do
+ delete_files
+ end
+
+ def delete_files
+ @view_names.each do |vn|
+ page_files(vn).each do |pf|
+ File.delete(pf) if File.exists?(pf)
+ end
+ end
+ end
+
+ def page_files(vn)
+ 1.upto(vn == 'record' ? 5 : 3).map { |i| "#{vn}-page#{i}.html" }
+ end
+
+ it 'should generate view files with multiple pages' do
+ views = ViewButtons.new(
+ @view_names.map{ |vn| NavButtonDef.
+ new("#{vn}.png", "#{vn}-page1.html") }
+ )
+ @view_names.each do |vn|
+ views.current_page = vn + '-page1.html'
+ pages = PagingButtons.new(page_files(vn))
+ page_files(vn).each do |file|
+ pages.current_page = file
+ PostRunner::View.new("Test File: #{file}", views, pages).body.
+ write(file)
+ File.exists?(file).should be true
+ end
+ end
+ end
+
+ end
+
+end