Moxie
2014-10-28 584328285c5defcf59cb3fc11494f9f056be79c8
commit | author | age
48fe87 1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
M 2 <html>
3 <head>
4 <!-- Begin Header -->
5 <title>Gitblit</title>
6 <meta charset="utf-8">
7 <meta name="ROBOTS" content="INDEX">
8 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
9 <meta name="viewport" content="width=device-width, initial-scale=1.0">
10         
11 <link rel="stylesheet" href="./bootstrap/css/bootstrap.css">
12 <link rel='shortcut icon' type='image/png' href='./gitblt-favicon.png' />
13 <link rel="stylesheet" href="./prettify/prettify.css" />
14 <!-- Google Plus Profile Page -->
15 <link rel="publisher" href="https://plus.google.com/114464678392593421684" />
16 <style type="text/css"> a.gpluspage { margin-top:3px;text-decoration: none; } </style>
17
18 <!-- Google Plus One -->
19 <link rel="canonical" href="http://gitblit.com" />
20 <script type="text/javascript" src="https://apis.google.com/js/plusone.js"></script>
21 <style type="text/css"> div.gplusone { margin-top:12px; } </style>
22
23 <script src="./prettify/prettify.js"></script>
24 <script src="./bootstrap/js/jquery.js"></script>
25 <script src="./bootstrap/js/bootstrap.min.js"></script>
26 </head>
27 <body onload='prettyPrint()'>        <!-- Navigation Bar -->
28         <div class="navbar navbar-fixed-top">
29             <div class="navbar-inner">
30                 <div class="container">
31                       <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
32                         <span class="icon-bar"></span>
33                         <span class="icon-bar"></span>
34                         <span class="icon-bar"></span>
35                       </a>
36                       <a class="brand" href="./"><img src="./gitblt_25_white.png" alt="Gitblit"></img></a>
37                     <div class="nav-collapse">
38                         <ul class="nav">
39                             <li class='dropdown'> <!-- Menu -->
40 <a class='dropdown-toggle' href='#' data-toggle='dropdown'>about<b class='caret'></b></a>
41 <ul class='dropdown-menu'>
42 <li><a href='index.html'>overview</a></li>
43 <li><a href='features.html'>features</a></li>
44 <li><a href='screenshots.html'>screenshots</a></li>
45 </ul></li> <!-- End Menu -->
46 <li class='dropdown'> <!-- Menu -->
47 <a class='dropdown-toggle' href='#' data-toggle='dropdown'>documentation<b class='caret'></b></a>
48 <ul class='dropdown-menu'>
49 <li class='dropdown-submenu'> <!-- Submenu -->
50 <a tabindex='-1' href='#'>Gitblit GO</a>
51 <ul class='dropdown-menu'>
52 <li><a href='setup_go.html'>setup GO</a></li>
53 <li><a href='upgrade_go.html'>upgrade GO</a></li>
54 </ul></li> <!-- End Submenu -->
55 <li class='divider'></li>
56 <li class='dropdown-submenu'> <!-- Submenu -->
57 <a tabindex='-1' href='#'>Gitblit WAR</a>
58 <ul class='dropdown-menu'>
59 <li><a href='setup_war.html'>setup WAR</a></li>
60 <li><a href='upgrade_war.html'>upgrade WAR</a></li>
61 </ul></li> <!-- End Submenu -->
62 <li class='divider'></li>
63 <li class='dropdown-submenu'> <!-- Submenu -->
64 <a tabindex='-1' href='#'>Server Configuration</a>
65 <ul class='dropdown-menu'>
66 <li><a href='administration.html'>administration</a></li>
67 <li><a href='setup_authentication.html'>authentication</a></li>
68 <li><a href='setup_hooks.html'>push hooks</a></li>
69 <li><a href='setup_lucene.html'>lucene indexing</a></li>
70 <li><a href='setup_proxy.html'>reverse proxies</a></li>
71 <li><a href='setup_clientmenus.html'>client app menus</a></li>
72 <li><a href='setup_bugtraq.html'>bugtraq</a></li>
73 <li><a href='setup_mirrors.html'>mirrors</a></li>
74 <li><a href='setup_scaling.html'>scaling</a></li>
75 <li class='divider'></li>
76 <li><a href='setup_viewer.html'>Gitblit as a viewer</a></li>
77 </ul></li> <!-- End Submenu -->
78 <li class='divider'></li>
79 <li class='dropdown-submenu'> <!-- Submenu -->
80 <a tabindex='-1' href='#'>Client Usage</a>
81 <ul class='dropdown-menu'>
82 <li><a href='setup_transport_http.html'>using HTTP/HTTPS</a></li>
83 <li><a href='setup_transport_ssh.html'>using SSH</a></li>
84 <li><a href='eclipse_plugin.html'>using the Eclipse plugin</a></li>
85 </ul></li> <!-- End Submenu -->
86 <li class='divider'></li>
87 <li class='dropdown-submenu'> <!-- Submenu -->
88 <a tabindex='-1' href='#'>Tickets</a>
89 <ul class='dropdown-menu'>
90 <li><a href='tickets_overview.html'>overview</a></li>
91 <li><a href='tickets_using.html'>using</a></li>
92 <li><a href='tickets_barnum.html'>barnum</a></li>
93 <li><a href='tickets_setup.html'>setup</a></li>
94 <li><a href='tickets_replication.html'>replication & advanced administration</a></li>
95 </ul></li> <!-- End Submenu -->
96 <li class='divider'></li>
97 <li class='dropdown-submenu'> <!-- Submenu -->
98 <a tabindex='-1' href='#'>Plugins</a>
99 <ul class='dropdown-menu'>
100 <li><a href='plugins_overview.html'>overview</a></li>
101 <li><a href='plugins_extensions.html'>extension points</a></li>
102 </ul></li> <!-- End Submenu -->
103 <li class='divider'></li>
104 <li><a href='federation.html'>federation</a></li>
105 <li class='divider'></li>
106 <li><a href='properties.html'>settings</a></li>
107 <li><a href='faq.html'>faq</a></li>
108 <li class='divider'></li>
109 <li><a href='design.html'>design</a></li>
110 <li><a href='rpc.html'>rpc</a></li>
111 </ul></li> <!-- End Menu -->
112 <li class='dropdown'> <!-- Menu -->
113 <a class='dropdown-toggle' href='#' data-toggle='dropdown'>releases<b class='caret'></b></a>
114 <ul class='dropdown-menu'>
115 <li><a href='releasenotes.html'>release notes</a></li>
116 <li><a href='releases.html'>release history</a></li>
117 <li class='divider'></li>
118 <li><a href='roadmap.html'>roadmap</a></li>
119 </ul></li> <!-- End Menu -->
120 <li class='dropdown'> <!-- Menu -->
121 <a class='dropdown-toggle' href='#' data-toggle='dropdown'>downloads<b class='caret'></b></a>
122 <ul class='dropdown-menu'>
584328 123 <li><a href='http://dl.bintray.com/gitblit/releases/gitblit-1.6.2.zip'>Gitblit GO (Windows)</a></li>
M 124 <li><a href='http://dl.bintray.com/gitblit/releases/gitblit-1.6.2.tar.gz'>Gitblit GO (Linux/OSX)</a></li>
125 <li><a href='http://dl.bintray.com/gitblit/releases/gitblit-1.6.2.war'>Gitblit WAR</a></li>
48fe87 126 <li class='divider'></li>
M 127 <li><a href='https://registry.hub.docker.com/u/jmoger/gitblit/'>Gitblit GO (Docker)</a></li>
128 <li class='divider'></li>
129 <li><a href='http://plugins.gitblit.com'>Plugins Registry</a></li>
130 <li class='divider'></li>
584328 131 <li><a href='http://dl.bintray.com/gitblit/releases/manager-1.6.2.zip'>Gitblit Manager</a></li>
M 132 <li><a href='http://dl.bintray.com/gitblit/releases/fedclient-1.6.2.zip'>Federation Client</a></li>
48fe87 133 <li class='divider'></li>
584328 134 <li><a href='http://dl.bintray.com/gitblit/releases/gbapi-1.6.2.zip'>API Library</a></li>
48fe87 135 <li class='divider'></li>
M 136 <li><a href='https://bintray.com/gitblit/releases/gitblit'>Bintray (1.4.0+)</a></li>
137 <li><a href='https://code.google.com/p/gitblit/downloads/list?can=1'>GoogleCode (pre-1.4.0)</a></li>
138 <li class='divider'></li>
139 <li><a href='http://gitblit.github.io/gitblit-maven'>Maven Repository</a></li>
140 </ul></li> <!-- End Menu -->
141 <li class='dropdown'> <!-- Menu -->
142 <a class='dropdown-toggle' href='#' data-toggle='dropdown'>links<b class='caret'></b></a>
143 <ul class='dropdown-menu'>
144 <li><a href='https://dev.gitblit.com'>dev.gitblit.com (self-hosted)</a></li>
145 <li class='divider'></li>
146 <li><a href='http://plugins.gitblit.com'>Plugins Registry</a></li>
147 <li class='divider'></li>
148 <li><a href='https://github.com/gitblit/gitblit'>Github</a></li>
149 <li><a href='http://code.google.com/p/gitblit/issues/list'>Issues</a></li>
150 <li><a href='http://groups.google.com/group/gitblit'>Discussion</a></li>
151 <li><a href='https://plus.google.com/114464678392593421684'>Google+</a></li>
152 <li><a href='https://twitter.com/gitblit'>Twitter</a></li>
153 <li><a href='http://www.ohloh.net/p/gitblit'>Ohloh</a></li>
584328 154 <li class='divider'></li>
M 155 <li><a href='https://vimeo.com/86164723'>Gitblit Tickets screencast</a></li>
156 <li><a href='https://asciinema.org/a/9342'>Gitblit SSH and Plugin Management asciicast</a></li>
157 <li><a href='http://episodes.gitminutes.com/2014/05/gitminutes-29-james-moger-on-gitblit.html'>GitMinutes #29: James Moger on Gitblit</a></li>
48fe87 158 <li class='divider'></li>
M 159 <li><a href='https://plus.google.com/+JamesMoger'>+JamesMoger</a></li>
160 <li><a href='https://twitter.com/JamesMoger'>@JamesMoger</a></li>
161 </ul></li> <!-- End Menu -->
162 <li class='divider-vertical'></li>
163 <li><a href='https://plus.google.com/114464678392593421684?prsrc=3' class='gpluspage'><img src='https://ssl.gstatic.com/images/icons/gplus-16.png' width='16' height='16 style='order: 0;'/></a></li><li><div class='gplusone'><g:plusone size='small' href='http://gitblit.com'></g:plusone></div></li>
164                         </ul>
165                     </div><!--/.nav-collapse -->
166                 </div>
167             </div>
168         </div><!-- end Navigation Bar -->
169 <div class='container'>
170 <!-- Begin Markdown -->
171 <h2 class="section" id='H1'><a href="#H1" class="sectionlink"><i class="icon-share-alt"> </i></a>Extension Points</h2><p>Gitblit offers several extension points for enhancing and customizing it's runtime behavior.</p><p>Each available extension point has a sample implementation in the <a href="https://github.com/gitblit/gitblit-cookbook-plugin">gitblit-cookbook-plugin (Maven project)</a>.</p><p><strong>NOTE:</strong><br/>Gitblit does not yet offer a comprehensize dependency injection architecture. This will be addressed in a subsequent release. For now you may access all of Gitblit's core managers through a static singleton app context:</p><p><pre>import com.gitblit.extensions.GitblitPlugin;
172 import com.gitblit.servlet.GitblitContext;
173 import com.gitblit.manager.IRuntimeManager;
174 import com.gitblit.manager.IUserManager;
175 import com.gitblit.manager.IAuthenticationManager;
176 import com.gitblit.manager.INotificationManager;
177 import com.gitblit.manager.IRepositoryManager;
178 import com.gitblit.manager.IProjectManager;
179 import com.gitblit.manager.IFederationManager;
180 import com.gitblit.manager.IPluginManager;
181 import com.gitblit.manager.IGitblit;
182 import ro.fortsoft.pf4j.Version;
183
184 public class ExamplePlugin extends GitblitPlugin {
185
186     @Override
187     public void start() {
188         IRuntimeManager runtime = GitblitContext.getManager(IRuntimeManager.class);
189         IUserManager users = GitblitContext.getManager(IUserManager.class);
190         IAuthenticationManager auth = GitblitContext.getManager(IAuthenticationManager.class);
191         INotificationManager notifications = GitblitContext.getManager(INotificationManager.class);
192         IRepositoryManager repos = GitblitContext.getManager(IRepositoryManager.class);
193         IProjectManager projects = GitblitContext.getManager(IProjectManager.class);
194         IFederationManager federation = GitblitContext.getManager(IFederationManager.class);
195         IPluginManager plugins = GitblitContext.getManager(IPluginManager.class);
196         IGitblit gitblit = GitblitContext.getManager(IGitblit.class);
197     }
198
199     @Override
200     public void stop() {
201     }
202
203     @Override
204     public void onInstall() {
205     }
206
207     @Override
208     public void onUpgrade(Version oldVersion) {
209     }
210
211     @Override
212     public void onUninstall() {
213     }
214 }
215
216 /**
217  * You can also create Webapp plugins that register pages.
218  */
219 public class ExampleWicketPlugin extends GitblitWicketPlugin {
220     @Override
221     public void start() {
222     }
223
224     @Override
225     public void stop() {
226     }
227
228     @Override
229     public void onInstall() {
230     }
231
232     @Override
233     public void onUpgrade(Version oldVersion) {
234     }
235
236     @Override
237     public void onUninstall() {
238     }
239
240     @Override
241     protected void init(GitblitWicketApp app) {
242         app.mount(&quot;/logo&quot;, LogoPage.class);
243         app.mount(&quot;/hello&quot;, HelloWorldPage.class);
244     }
245 }
246 </pre></p>
247 <h3 class="section" id='H2'><a href="#H2" class="sectionlink"><i class="icon-share-alt"> </i></a>SSH Dispatch Command</h3><p><em>SINCE 1.5.0</em></p><p>You can provide your own custom SSH command hierarchies by subclassing the <em>DispatchCommand</em> class.</p><p><pre>import ro.fortsoft.pf4j.Extension;
248 import org.kohsuke.args4j.Option;
249 import org.slf4j.Logger;
250 import org.slf4j.LoggerFactory;
251 import com.gitblit.transport.ssh.commands.CommandMetaData;
252 import com.gitblit.transport.ssh.commands.DispatchCommand;
253 import com.gitblit.transport.ssh.commands.UsageExample;
254
255 @Extension
256 @CommandMetaData(name = &quot;mycommands&quot;, description = &quot;Sample SSH dispatcher&quot;)
257 public class MyDispatcher extends DispatchCommand {
258
259     @Override
260     protected void setup() {
261         // commands in this dispatcher
262         register(CommandA.class);
263         register(CommandB.class);
264
265         // nested dispatchers
266         register(SubDispatcher1.class);
267         register(SubDispatcher2.class);
268     }
269
270     @CommandMetaData(name = &quot;commanda&quot;, aliases = { &quot;ca&quot; }, description = &quot;description of command a&quot;)
271     @UsageExample(syntax = &quot;${cmd} --myflag&quot;, description = &quot;description of commanda with --myflag&quot;)
272     public static class CommandA extends SshCommand {
273
274         protected final Logger log = LoggerFactory.getLogger(getClass());
275
276         @Option(name = &quot;--myflag&quot;, aliases = { &quot;-m&quot; }, usage = &quot;enable myflag&quot;)
277         boolean myflag;
278
279         @Override
280         public void run() throws Failure {
281             if (myflag) {
282                 log.info(&quot;Run with --myflag&quot;);
283             } else {
284                 log.info(&quot;Run without --myflag&quot;);
285             }
286         }
287     }
288 }
289 </pre></p>
290 <h3 class="section" id='H3'><a href="#H3" class="sectionlink"><i class="icon-share-alt"> </i></a>Pre- and Post- Receive Hook</h3><p><em>SINCE 1.5.0</em></p><p>You can provide your own custom pre and/or post receive hooks by subclassing the <em>ReceiveHook</em> class.</p><p><pre>import com.gitblit.extensions.ReceiveHook;
291 import java.util.Collection;
292 import org.eclipse.jgit.transport.ReceiveCommand;
293 import ro.fortsoft.pf4j.Extension;
294
295 @Extension
296 public class MyReceiveHook extends ReceiveHook {
297
298     @Override
299     public void onPreReceive(GitblitReceivePack receivePack, Collection&lt;ReceiveCommand&gt; commands) {
300     }
301
302     @Override
303     public void onPostReceive(GitblitReceivePack receivePack, Collection&lt;ReceiveCommand&gt; commands) {
304     }
305 }
306
307 </pre></p>
308 <h3 class="section" id='H4'><a href="#H4" class="sectionlink"><i class="icon-share-alt"> </i></a>Patchset Hook</h3><p><em>SINCE 1.5.0</em></p><p>You can provide your own custom patchset hook by subclassing the <em>PatchsetHook</em> class.</p><p><pre>import com.gitblit.extensions.PatchsetHook;
309 import com.gitblit.models.TicketModel;
310 import ro.fortsoft.pf4j.Extension;
311
312 @Extension
313 public class MyPatchsetHook extends PatchsetHook {
314
315     @Override
316     public void onNewPatchset(TicketModel ticket) {
317     }
318
319     @Override
320     public void onUpdatePatchset(TicketModel ticket) {
321     }
322
323     @Override
324     public void onMergePatchset(TicketModel ticket) {
325     }
326 }
327 </pre></p>
328 <h3 class="section" id='H5'><a href="#H5" class="sectionlink"><i class="icon-share-alt"> </i></a>Ticket Hook</h3><p><em>SINCE 1.5.0</em></p><p>You can provide your own custom ticket hook by subclassing the <em>TicketHook</em> class.</p><p><pre>import com.gitblit.extensions.TicketHook;
329 import com.gitblit.models.TicketModel;
330 import com.gitblit.models.TicketModel.Change;
331 import ro.fortsoft.pf4j.Extension;
332
333 @Extension
334 public class MyTicketHook extends TicketHook {
335
336     @Override
337     public void onNewTicket(TicketModel ticket) {
338     }
339
340     @Override
341     public void onUpdateTicket(TicketModel ticket, Change change) {
342     }
343 }
344 </pre></p>
345 <h3 class="section" id='H6'><a href="#H6" class="sectionlink"><i class="icon-share-alt"> </i></a>Request Filter</h3><p><em>SINCE 1.6.0</em></p><p>You can provide your own custom request filter by subclassing the <em>HttpRequestFilter</em> class.</p><p><pre>import com.gitblit.extensions.HttpRequestFilter;
346 import ro.fortsoft.pf4j.Extension;
347
348 @Extension
349 public class MyRequestFilter extends HttpRequestFilter {
350
351     @Override
352     public void doFilter(ServletRequest request, ServletResponse response,
353             FilterChain chain) throws IOException, ServletException {
354     }
355 }
356 </pre></p>
357 <h3 class="section" id='H7'><a href="#H7" class="sectionlink"><i class="icon-share-alt"> </i></a>User Menu Items</h3><p><em>SINCE 1.6.0</em></p><p>You can provide your own user menu items by subclassing the <em>UserMenuExtension</em> class.</p><p><pre>import java.util.Arrays;
358 import java.util.List;
359 import ro.fortsoft.pf4j.Extension;
360 import com.gitblit.extensions.UserMenuExtension;
361 import com.gitblit.models.Menu.ExternalLinkMenuItem;
362 import com.gitblit.models.Menu.MenuItem;
363 import com.gitblit.models.UserModel;
364
365 @Extension
366 public class MyUserMenuContributor extends UserMenuExtension {
367
368     @Override
369     public List&lt;MenuItem&gt; getMenuItems(UserModel user) {
370         MenuItem item = new ExternalLinkMenuItem(&quot;Github&quot;, String.format(&quot;https://github.com/%s&quot;, user.username));
371         return Arrays.asList(item);
372     }
373 }
374 </pre></p>
375 <h3 class="section" id='H8'><a href="#H8" class="sectionlink"><i class="icon-share-alt"> </i></a>Navigation Links</h3><p><em>SINCE 1.6.0</em></p><p>You can provide your own top-level navigation links by subclassing the <em>NavLinkExtension</em> class.</p><p><pre>import java.util.Arrays;
376 import java.util.List;
377 import ro.fortsoft.pf4j.Extension;
378 import com.gitblit.extensions.NavLinkExtension;
379 import com.gitblit.models.UserModel;
380
381 @Extension
382 public class MyNavLink extends NavLinkExtension {
383
384     @Override
385     public List&lt;NavLink&gt; getNavLinks(UserModel user) {
386         NavLink link = new ExternalLinkMenuItem(&quot;Github&quot;, String.format(&quot;https://github.com/%s&quot;, user.username));
387         return Arrays.asList(link);
388     }
389 }
390 </pre></p>
391 <h3 class="section" id='H9'><a href="#H9" class="sectionlink"><i class="icon-share-alt"> </i></a>Server Lifecycle Listener</h3><p><em>SINCE 1.6.0</em></p><p>You can provide a lifecycle listener to be notified when Gitblit has completely started and just before Gitblit is gracefully terminated.</p><p><pre>import org.slf4j.Logger;
392 import org.slf4j.LoggerFactory;
393 import ro.fortsoft.pf4j.Extension;
394 import com.gitblit.extensions.LifeCycleListener;
395
396 @Extension
397 public class MyLifeCycleListener extends LifeCycleListener {
398
399     final Logger log = LoggerFactory.getLogger(getClass());
400     
401     @Override
402     public void onStartup() {
403         log.info(&quot;Gitblit is Ready!!&quot;);
404     }
405
406     @Override
407     public void onShutdown() {
408         log.info(&quot;Gitblit is Going Down!!&quot;);
409     }
410 }
411 </pre></p>
412 <h3 class="section" id='H10'><a href="#H10" class="sectionlink"><i class="icon-share-alt"> </i></a>Repository Lifecycle Listener</h3><p><em>SINCE 1.6.0</em></p><p>You can provide a lifecycle listener to be notified when Gitblit has created or deleted a repository.</p><p><pre>import org.slf4j.Logger;
413 import org.slf4j.LoggerFactory;
414 import ro.fortsoft.pf4j.Extension;
415 import com.gitblit.extensions.RepositoryLifeCycleListener;
416 import com.gitblit.models.RepositoryModel;
417
418 @Extension
419 public class MyRepoLifeCycleListener extends RepositoryLifeCycleListener {
420
421     final Logger log = LoggerFactory.getLogger(getClass());
422     
423     @Override
424     public void onCreation(RepositoryModel repo) {
425         log.info(&quot;Gitblit created {}&quot;, repo);
426     }
427
428     @Override
429     public void onDeletion(RepositoryModel repo) {
430         log.info(&quot;Gitblit deleted {}&quot;, repo);
431     }
432 }
433 </pre></p>
434 <h3 class="section" id='H11'><a href="#H11" class="sectionlink"><i class="icon-share-alt"> </i></a>User/Team Lifecycle Listener</h3><p><em>SINCE 1.6.0</em></p><p>You can provide a lifecycle listener to be notified when Gitblit has created or deleted a user or a team.</p><p><pre>import org.slf4j.Logger;
435 import org.slf4j.LoggerFactory;
436 import ro.fortsoft.pf4j.Extension;
437 import com.gitblit.extensions.UserTeamLifeCycleListener;
438 import com.gitblit.models.TeamModel;
439 import com.gitblit.models.UserModel;
440
441 @Extension
442 public class MyUserTeamLifeCycleListener extends UserTeamLifeCycleListener {
443
444     final Logger log = LoggerFactory.getLogger(getClass());
445     
446     @Override
447     public void onCreation(UserModel user) {
448         log.info(&quot;Gitblit created user {}&quot;, user);
449     }
450
451     @Override
452     public void onDeletion(UserModel user) {
453         log.info(&quot;Gitblit deleted user {}&quot;, user);
454     }
455
456     @Override
457     public void onCreation(TeamModel team) {
458         log.info(&quot;Gitblit created team {}&quot;, team);
459     }
460
461     @Override
462     public void onDeletion(TeamModel team) {
463         log.info(&quot;Gitblit deleted team {}&quot;, team);
464     }
465 }
466 </pre>
467 <!-- End Markdown -->
584328 468 <div ><ul class="pager"><li class="previous"><a href="plugins_overview.html">&larr; overview</a></li> </ul></div><footer class="footer"><p class="pull-right">generated 2014-10-28</p>
48fe87 469 <p>The content of this page is licensed under the <a href="http://creativecommons.org/licenses/by/3.0">Creative Commons Attribution 3.0 License</a>.</p>
M 470 </footer>
471 </div>
472 <!-- Google Analytics -->
473 <script type="text/javascript">
474     var _gaq = _gaq || [];
475     _gaq.push(['_setAccount', 'UA-24377072-1']);
476     _gaq.push(['_trackPageview']);
477
478     (function() {
479         var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
480         ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
481         var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
482     })();
483 </script>
484
485 </body>
486 </html>