local_pac 0.1.13 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. data/{LICENSE.txt → LICENSE.md} +0 -0
  2. data/README.DEVELOPER.md +7 -0
  3. data/README.md +138 -2
  4. data/Rakefile +16 -8
  5. data/app/controllers/application_controller.rb +5 -3
  6. data/app/controllers/assets_controller.rb +3 -2
  7. data/app/controllers/file_serve_controller.rb +3 -6
  8. data/app/controllers/lookup_controller.rb +9 -9
  9. data/app/locales/en.yml +1 -0
  10. data/app/views/application.haml +1 -1
  11. data/bin/local_pac +49 -64
  12. data/config.ru +24 -7
  13. data/features/initializer.feature +4 -4
  14. data/features/show_status.feature +2 -2
  15. data/files/config.yaml +2 -2
  16. data/files/example-config.erb +10 -12
  17. data/files/git-hook.erb +1 -0
  18. data/lib/local_pac.rb +22 -5
  19. data/lib/local_pac/actions/create_directory.rb +2 -2
  20. data/lib/local_pac/actions/create_file.rb +8 -2
  21. data/lib/local_pac/actions/create_repository.rb +6 -8
  22. data/lib/local_pac/actions/get_system_information.rb +78 -0
  23. data/lib/local_pac/actions/print_newline.rb +19 -0
  24. data/lib/local_pac/actions/print_title.rb +41 -0
  25. data/lib/local_pac/actions/reload_configuration.rb +21 -0
  26. data/lib/local_pac/actions/reload_local_storage.rb +22 -0
  27. data/lib/local_pac/actions/send_signal.rb +32 -0
  28. data/lib/local_pac/actions/show_config.rb +10 -0
  29. data/lib/local_pac/actions/show_process_information.rb +94 -0
  30. data/lib/local_pac/application_status.rb +34 -0
  31. data/lib/local_pac/cli/helper.rb +34 -0
  32. data/lib/local_pac/cli/reload.rb +36 -0
  33. data/lib/local_pac/config.rb +15 -13
  34. data/lib/local_pac/exceptions.rb +6 -0
  35. data/lib/local_pac/file.rb +32 -0
  36. data/lib/local_pac/git.rb +20 -6
  37. data/lib/local_pac/git_repository.rb +40 -28
  38. data/lib/local_pac/git_storage.rb +60 -0
  39. data/lib/local_pac/initializer.rb +8 -5
  40. data/lib/local_pac/local_storage.rb +3 -4
  41. data/lib/local_pac/main.rb +2 -2
  42. data/lib/local_pac/{null_pac_file.rb → null_file.rb} +5 -1
  43. data/lib/local_pac/server.rb +1 -1
  44. data/lib/local_pac/spec_helper_file_server.rb +6 -5
  45. data/lib/local_pac/template_file.rb +1 -1
  46. data/lib/local_pac/template_repository.rb +3 -3
  47. data/lib/local_pac/version.rb +1 -1
  48. data/local_pac.gemspec +13 -9
  49. data/script/console +1 -1
  50. data/share/archlinux/PKGBUILD +4 -1
  51. data/share/archlinux/config.yaml +1 -1
  52. data/spec/actions/create_directory_spec.rb +3 -3
  53. data/spec/actions/create_file_spec.rb +23 -2
  54. data/spec/actions/create_repository_spec.rb +3 -3
  55. data/spec/actions/get_system_information_spec.rb +22 -0
  56. data/spec/actions/print_new_line_spec.rb +36 -0
  57. data/spec/actions/print_title_spec.rb +50 -0
  58. data/spec/actions/reload_configuration_spec.rb +38 -0
  59. data/spec/actions/reload_repository_spec.rb +35 -0
  60. data/spec/actions/send_signal_spec.rb +58 -0
  61. data/spec/actions/show_config_spec.rb +22 -0
  62. data/spec/actions/show_process_information_spec.rb +45 -0
  63. data/spec/application_status_spec.rb +40 -0
  64. data/spec/config_spec.rb +11 -11
  65. data/spec/features/fetch_proxy_pac_spec.rb +11 -10
  66. data/spec/features/lookup_proxy_spec.rb +32 -40
  67. data/spec/file_spec.rb +56 -0
  68. data/spec/git_spec.rb +13 -7
  69. data/spec/git_storage_spec.rb +64 -0
  70. data/spec/initializer_spec.rb +7 -5
  71. data/spec/{null_pac_file_spec.rb → null_file_spec.rb} +6 -6
  72. data/spec/proxy_pac/pac_result_html_stylist_spec.rb +3 -2
  73. data/spec/runner_spec.rb +1 -1
  74. data/spec/spec_helper.rb +2 -2
  75. data/spec/spec_helper_features.rb +2 -2
  76. data/spec/support/config.rb +5 -0
  77. data/spec/support/filesystem.rb +1 -1
  78. data/spec/support/git.rb +23 -2
  79. data/spec/support/helper_features.rb +23 -0
  80. data/spec/template_repository_spec.rb +2 -2
  81. metadata +113 -32
  82. data/lib/local_pac/git_file.rb +0 -18
  83. data/lib/local_pac/pac_file.rb +0 -27
  84. data/spec/git_repository_spec.rb +0 -60
  85. data/spec/pac_file_spec.rb +0 -44
File without changes
@@ -11,6 +11,13 @@ Please make sure you have `phantomjs` installed.
11
11
  sudo pacman -S phantomjs
12
12
  ```
13
13
 
14
+ During testing `git` is used a lot. So please install it as well.
15
+
16
+ ```bash
17
+ # archlinux
18
+ sudo pacman -S git
19
+ ```
20
+
14
21
  ## Start
15
22
 
16
23
  ```bash
data/README.md CHANGED
@@ -5,7 +5,16 @@
5
5
  [![Coverage Status](https://coveralls.io/repos/dg-vrnetze/local_pac/badge.png?branch=master)](https://coveralls.io/r/dg-vrnetze/local_pac?branch=master)
6
6
  [![Gem Version](https://badge.fury.io/rb/local_pac.png)](http://badge.fury.io/rb/local_pac)
7
7
 
8
- Serve proxy.pac-files with ease.
8
+ `local_pac` serves to purposes:
9
+
10
+ 1. Serve proxy.pac-files compressed from a vcs repository (git).
11
+ 2. Lookup of url in proxy.pac to find out which proxy will be used.
12
+
13
+ Behind the scenes it uses a javascript compressor
14
+ ([uglifier](https://github.com/lautis/uglifier)) to make 1. and and a proxy-pac
15
+ parser ([ruby-pac](https://github.com/samuelkadolph/ruby-pac)) to make 2.
16
+ possible.
17
+
9
18
 
10
19
  ## Installation
11
20
 
@@ -21,8 +30,135 @@ Or install it yourself as:
21
30
 
22
31
  $ gem install local_pac
23
32
 
33
+ Additionally you need to install `git` because `local_pac` makes a lot of use
34
+ of it.
35
+
24
36
  ## Usage
25
37
 
38
+ ### Getting started
39
+
40
+ Make sure that you place a config file for `local_pac` in one of the following
41
+ places or let `local_pac` generate a file on default values (see below).
42
+
43
+ * `$HOME/.config/local_pac/config.yaml`
44
+ * `$HOME/.local_pac/config.yaml`
45
+ * `/etc/local_pac/config.yaml`
46
+
47
+ <table>
48
+ <caption>Table 1: Configuration values for <code>local_pac</code></caption>
49
+ <tr>
50
+ <th>
51
+ Option
52
+ </th>
53
+ <th>
54
+ Default value
55
+ </th>
56
+ <th>
57
+ Description
58
+ </th>
59
+ </tr>
60
+ <tr>
61
+ <td>
62
+ :local_storage
63
+ </td>
64
+ <td>
65
+ $HOME/.local/share/local_pac/data/storage.git
66
+ </td>
67
+ <td>
68
+ Path to git-(bare)-repository to store the proxy.pac-files. This is not for direct use!
69
+ </td>
70
+ </tr>
71
+ <tr>
72
+ <td>
73
+ :executable
74
+ </td>
75
+ <td>
76
+ /path/to/gem/bin/local_pac
77
+ </td>
78
+ <td>
79
+ Internal use only
80
+ </td>
81
+ </tr>
82
+ <tr>
83
+ <td>
84
+ :pid_file
85
+ </td>
86
+ <td>
87
+ $HOME/.local/share/local_pac/run/pid
88
+ </td>
89
+ <td>
90
+ If would do not use `systemd`, but want to run `local_pac` as a system service, you might need a pid file for your init-daemon.
91
+ </td>
92
+ </tr>
93
+ <tr>
94
+ <td>
95
+ :gem_path
96
+ </td>
97
+ <td>
98
+ `ruby -rrubygems -e 'puts Gem.path.join(", ")'`
99
+ </td>
100
+ <td>
101
+ Internal use only
102
+ </td>
103
+ </tr>
104
+ <tr>
105
+ <td>
106
+ :access_log
107
+ </td>
108
+ <td>
109
+ $HOME/home/xgvndeg/.local/share/local_pac/log/access.log
110
+ </td>
111
+ <td>
112
+ Write access to the file in production and test environment.
113
+ </td>
114
+ </tr>
115
+ <tr>
116
+ <td>
117
+ :sass_cache
118
+ </td>
119
+ <td>
120
+ $HOME/home/xgvndeg/.local/share/local_pac/cache
121
+ </td>
122
+ <td>
123
+ Cache for assets for the lookup of urls
124
+ </td>
125
+ </tr>
126
+ <tr>
127
+ <td>
128
+ :config_file
129
+ </td>
130
+ <td>
131
+ No default
132
+ </td>
133
+ <td>
134
+ Internal use only
135
+ </td>
136
+ </tr>
137
+ </table>
138
+
139
+ A config file could look like the following one:
140
+
141
+ ```yaml
142
+ :local_storage: /var/local_pac/data/storage.git
143
+ :pid_file: /run/local_pac/pid
144
+ :access_log: /var/log/local_pac/access.log
145
+ :sass_cache: /var/local_pac/cache
146
+ ```
147
+
148
+ After creating creating that file, you can check it by running `local_pac status --config-file <file>`. If your file could be parsed successfully, you can initialize the `local_pac`-environment by running `local_pac initialize --config-file <file>` or `local_pac initialize`. The latter works only if you placed your config file at one of the known paths mentioned above.
149
+
150
+ The next step is to clone the newly created repository - e.g. at `/home/<user>/.local/share/data/storage.git`.
151
+
152
+
153
+ Summary:
154
+ 1. Create a config file
155
+ 2. Check config file
156
+ 3. Initialize `local_pac`
157
+ 4. Clone `local_pac`-git-repository
158
+ 5. Add a proxy.pac to git-repository
159
+ 6. Push to `local_pac`-git-repository
160
+ 7. Restart `local_pac`-service
161
+
26
162
  ### Serving proxy.pacs
27
163
 
28
164
  You need to place your proxy.pac in one of the following directories:
@@ -101,7 +237,7 @@ To make debugging a little bit easier you can view the config values used by
101
237
  ```bash
102
238
  option | value
103
239
  -------------------- + --------------------------------------------------------------------------------
104
- log_sink | /home/user/.local/share/local_pac/log
240
+ access_log | /home/user/.local/share/local_pac/log/access.log
105
241
  local_storage | /home/user/.local/share/local_pac/data
106
242
  pid_file | /home/user/.local/share/local_pac/run/pid
107
243
  gem_path | /home/user/.gem/ruby/1.9.3, /opt/rubies/1.9.3/lib/ruby/gems/1.9.1
data/Rakefile CHANGED
@@ -13,27 +13,27 @@ def version
13
13
  end
14
14
 
15
15
  def root_directory
16
- File.expand_path('../', __FILE__)
16
+ ::File.expand_path('../', __FILE__)
17
17
  end
18
18
 
19
19
  def tar_file
20
- File.join(pkg_directory, "#{software}-#{version}.tar.gz")
20
+ ::File.join(pkg_directory, "#{software}-#{version}.tar.gz")
21
21
  end
22
22
 
23
23
  def tmp_directory
24
- File.join(root_directory, 'tmp', "#{software}-#{version}")
24
+ ::File.join(root_directory, 'tmp', "#{software}-#{version}")
25
25
  end
26
26
 
27
27
  def gem_file
28
- File.join(root_directory, 'pkg', "#{software}-#{version}.gem")
28
+ ::File.join(root_directory, 'pkg', "#{software}-#{version}.gem")
29
29
  end
30
30
 
31
31
  def pkg_directory
32
- File.join(root_directory, 'pkg')
32
+ ::File.join(root_directory, 'pkg')
33
33
  end
34
34
 
35
35
  def gem_directory
36
- File.join(root_directory, 'vendor', 'cache')
36
+ ::File.join(root_directory, 'vendor', 'cache')
37
37
  end
38
38
 
39
39
  task :default => 'gem:build'
@@ -47,10 +47,18 @@ end
47
47
  namespace :gem do
48
48
  desc 'build tar file'
49
49
  task :package => [gem_file, tmp_directory] do
50
- FileUtils.mv File.join(pkg_directory, "#{software}-#{version}.gem"), tmp_directory
50
+ FileUtils.mv ::File.join(pkg_directory, "#{software}-#{version}.gem"), tmp_directory
51
51
 
52
52
  Dir.chdir('tmp') do
53
- sh "tar -czf #{tar_file} #{File.basename tmp_directory}"
53
+ sh "tar -czf #{tar_file} #{::File.basename tmp_directory}"
54
54
  end
55
55
  end
56
56
  end
57
+
58
+ require 'coveralls/rake/task'
59
+ Coveralls::RakeTask.new
60
+
61
+ namespace :test do
62
+ desc 'Test with coveralls'
63
+ task :coveralls => ['test:rspec', 'test:cucumber', 'coveralls:push']
64
+ end
@@ -4,11 +4,13 @@ require 'i18n'
4
4
  require 'i18n/backend/fallbacks'
5
5
  require 'rack/contrib/locale'
6
6
  require 'sprockets-helpers'
7
+ require 'sass'
8
+ require 'sinatra'
7
9
 
8
10
  module LocalPac
9
11
  module App
10
12
  class ApplicationController < Sinatra::Base
11
- set :root, File.expand_path('../../', __FILE__)
13
+ set :root, ::File.expand_path('../../', __FILE__)
12
14
  set :haml, :format => :html5
13
15
 
14
16
  def local_storage
@@ -60,14 +62,14 @@ module LocalPac
60
62
 
61
63
  configure :test do
62
64
  use Rack::CommonLogger, LocalPac::NullAccessLogger.new
63
- set :raise_errors, true
65
+ set :raise_errors, false
64
66
  end
65
67
 
66
68
  configure do
67
69
  mime_type :proxy_pac_file, 'application/x-ns-proxy-autoconfig'
68
70
 
69
71
  I18n::Backend::Simple.send(:include, I18n::Backend::Fallbacks)
70
- I18n.load_path = Dir[File.join(settings.root, 'locales', '*.yml')]
72
+ I18n.load_path = Dir[::File.join(settings.root, 'locales', '*.yml')]
71
73
  I18n.backend.load_translations
72
74
 
73
75
  I18n.enforce_available_locales = true
@@ -1,5 +1,6 @@
1
1
  require 'compass'
2
2
  require 'sass'
3
+ require 'sinatra'
3
4
  require 'sprockets'
4
5
  require 'sprockets-sass'
5
6
  require 'compass'
@@ -10,12 +11,12 @@ require 'uglifier'
10
11
  module LocalPac
11
12
  module App
12
13
  class AssetsController < Sinatra::Base
13
- set :root, File.expand_path('../../', __FILE__)
14
+ set :root, ::File.expand_path('../../', __FILE__)
14
15
  set :assets, Sprockets::Environment.new(root)
15
16
  set :precompile, [ /\w+\.(?!js|css).+/, /application.(css|js)$/ ]
16
17
  set :assets_prefix, '/assets'
17
18
  set :digest_assets, false
18
- set(:assets_path) { File.join public_folder, assets_prefix }
19
+ set(:assets_path) { ::File.join public_folder, assets_prefix }
19
20
 
20
21
  configure :profile do
21
22
  require 'ruby-prof'
@@ -9,13 +9,10 @@ module LocalPac
9
9
  get '/:name' do
10
10
  content_type :proxy_pac_file
11
11
 
12
- file = local_storage.find(params[:name])
12
+ file = local_storage.find(params[:name].to_s)
13
+ fail Sinatra::NotFound, params[:name].to_s if file.nil?
13
14
 
14
- if file.nil?
15
- fail Sinatra::NotFound, "#{params[:name]}"
16
- else
17
- file.compressed_content
18
- end
15
+ file.compressed_content
19
16
  end
20
17
  end
21
18
  end
@@ -7,6 +7,9 @@ module LocalPac
7
7
  end
8
8
 
9
9
  get '/:name' do
10
+ file = local_storage.find(params[:name].to_s)
11
+ fail Sinatra::NotFound, params[:name].to_s if file.nil?
12
+
10
13
  haml :lookup, layout: :application
11
14
  end
12
15
 
@@ -14,17 +17,14 @@ module LocalPac
14
17
  @file = local_storage.find(params[:name].to_s)
15
18
  @uri = Addressable::URI.heuristic_parse(params[:url].to_s)
16
19
 
17
- if @file.nil?
18
- fail Sinatra::NotFound, params[:name]
19
- else
20
- parser = LocalPac::ProxyPac::PacParser.new(file: @file)
20
+ fail Sinatra::NotFound, params[:name].to_s if @file.nil?
21
21
 
22
- begin
23
- @result = parser.find(@uri)
24
- rescue Exceptions::PacFileInvalid
25
- fail I18n.t('errors.invalid_proxy_pac', name: params[:name] )
26
- end
22
+ parser = LocalPac::ProxyPac::PacParser.new(file: @file)
27
23
 
24
+ begin
25
+ @result = parser.find(@uri)
26
+ rescue Exceptions::PacFileInvalid
27
+ fail I18n.t('errors.invalid_proxy_pac', name: params[:name] )
28
28
  end
29
29
 
30
30
  haml :lookup_result, layout: :application
@@ -17,6 +17,7 @@ en:
17
17
  buttons:
18
18
  search: Search
19
19
  reset: Clear
20
+ title: Lookup URLs in proxy.pac-files...
20
21
  lookup:
21
22
  headline: Lookup
22
23
  lookup_result:
@@ -4,7 +4,7 @@
4
4
  %meta{:charset => "utf-8"}
5
5
  %link{ rel: 'stylesheet', href: stylesheet_path('application.css') }
6
6
  %script{ type: 'text/javascript', src: javascript_path('application.js') }
7
- %title Lookup url in proxy.pac
7
+ %title= t('views.application.title')
8
8
  %body
9
9
  .lp_container
10
10
  = yield
@@ -1,84 +1,69 @@
1
1
  #!/usr/bin/env ruby
2
2
  # encoding: utf-8
3
- require 'thor'
4
- require 'fileutils'
5
-
6
- $LOAD_PATH << File.expand_path('../../lib', __FILE__)
3
+ $LOAD_PATH <<::File.expand_path('../../lib', __FILE__)
7
4
  require 'local_pac'
8
5
 
9
- class Default < Thor
10
- class_option :config_file, type: :string, desc: 'Config file'
11
- class_option :log_level, type: :string, desc: 'Log level for ui logging'
12
- class_option :debug, type: :boolean, default: false, desc: 'Run application in debug mode'
13
-
14
- no_commands {
15
- def set_log_level(requested_level)
16
- case requested_level.to_s.to_sym
17
- when :info
18
- LocalPac.ui_logger.level = ::Logger::INFO
19
- when :debug
20
- LocalPac.ui_logger.level = ::Logger::DEBUG
21
- else
22
- LocalPac.ui_logger.level = ::Logger::WARN
23
- end
24
- end
6
+ module LocalPac
7
+ module Cli
8
+ class Main < Thor
9
+ class_option :config_file, type: :string, desc: 'Config file'
10
+ class_option :log_level, type: :string, desc: 'Log level for ui logging'
11
+ class_option :debug, type: :boolean, default: false, desc: 'Run application in debug mode'
25
12
 
26
- def set_debug(request)
27
- if request
28
- LocalPac.ui_logger.info "Activating debug mode."
13
+ no_commands {
14
+ include LocalPac::Cli::Helper
15
+ }
29
16
 
30
- require 'pry'
31
- require 'debugger'
32
- end
33
- rescue LoadError
34
- LocalPac.ui_logger.error "You tried to enable debug-mode, but either 'pry'- or 'debugger'-gem are not installed. Please fix that before using the debug-switch again."
35
- end
36
- }
17
+ desc 'serve', 'Serve pacfiles'
18
+ option :access_log, type: :string, desc: 'File to write access log to'
19
+ option :listen, type: :string, default: 'tcp://localhost:8000', desc: 'Listen for requests'
20
+ option :rack_environment, type: :string, default: 'production', desc: 'Rack environment for application'
21
+ def serve
22
+ LocalPac.config = LocalPac::Config.new(options[:config_file]) if options[:config_file]
23
+ LocalPac.config.access_log = options[:access_log] if options[:access_log]
37
24
 
38
- desc 'serve', 'Serve pacfiles'
39
- option :access_log, type: :string, desc: 'File to write access log to'
40
- option :listen, type: :string, default: 'tcp://localhost:8000', desc: 'Listen for requests'
41
- option :rack_environment, type: :string, default: 'production', desc: 'Rack environment for application'
42
- def serve
43
- LocalPac.config = LocalPac::Config.new(options[:config_file]) if options[:config_file]
44
- LocalPac.config.access_log = options[:access_log] if options[:access_log]
25
+ LocalPac.config.lock
45
26
 
46
- LocalPac.config.lock
27
+ set_log_level(options[:log_level])
28
+ set_debug(options[:debug])
47
29
 
48
- set_log_level(options[:log_level])
49
- set_debug(options[:debug])
30
+ LocalPac.ui_logger.debug('Options: ' + options.to_s)
31
+ LocalPac.ui_logger.debug("Config:\n" + LocalPac.config.to_s)
50
32
 
51
- LocalPac.ui_logger.debug('Options: ' + options.to_s)
52
- LocalPac.ui_logger.debug("Config:\n" + LocalPac.config.to_s)
33
+ Server.new(options[:listen], options[:rack_environment]).start
34
+ end
53
35
 
54
- LocalPac::Server.new(options[:listen], options[:rack_environment]).start
55
- end
36
+ desc 'init', 'Create files/directories to use local_pac in dir or $PWD'
37
+ option :force, type: :boolean, default: false, desc: 'Overwrite existing files?'
38
+ def init
39
+ LocalPac.config = LocalPac::Config.new(options[:config_file]) if options[:config_file]
40
+ LocalPac.config.lock
56
41
 
57
- desc 'init', 'Create files/directories to use local_pac in dir or $PWD'
58
- option :force, type: :boolean, default: false, desc: 'Overwrite existing files?'
59
- def init
60
- LocalPac.config = LocalPac::Config.new(options[:config_file]) if options[:config_file]
61
- LocalPac.config.lock
42
+ set_log_level(options[:log_level])
43
+ set_debug(options[:debug])
62
44
 
63
- set_log_level(options[:log_level])
64
- set_debug(options[:debug])
45
+ LocalPac.ui_logger.debug('Options: ' + options.to_s)
46
+ LocalPac.ui_logger.debug("Config:\n" + LocalPac.config.to_s)
65
47
 
66
- LocalPac.ui_logger.debug('Options: ' + options.to_s)
67
- LocalPac.ui_logger.debug("Config:\n" + LocalPac.config.to_s)
48
+ Initializer.new(force: options[:force]).run
49
+ end
68
50
 
69
- LocalPac::Initializer.new(force: options[:force]).run
70
- end
51
+ desc 'status', 'Show status of local_pac: configuration, known proxy pacs, server running etc.'
52
+ def status
53
+ LocalPac.config = LocalPac::Config.new(options[:config_file]) if options[:config_file]
54
+ LocalPac.config.lock
55
+
56
+ set_log_level(options[:log_level])
57
+ set_debug(options[:debug])
71
58
 
72
- desc 'status', 'Show status of local_pac: configuration, known proxy pacs, server running etc.'
73
- def config
74
- LocalPac.config = LocalPac::Config.new(options[:config_file]) if options[:config_file]
75
- LocalPac.config.lock
59
+ ApplicationStatus.new.show
60
+ end
76
61
 
77
- set_log_level(options[:log_level])
78
- set_debug(options[:debug])
62
+ desc 'reload', 'Reload configuration, local storage etc.'
63
+ option :pid_file, type: :string, desc: 'Pid file of daemon'
64
+ subcommand 'reload', LocalPac::Cli::Reload
65
+ end
79
66
 
80
- puts LocalPac.config
81
67
  end
82
68
  end
83
-
84
- Default.start
69
+ LocalPac::Cli::Main.start