Moxie
2014-10-20 892246e3a79528c3d2c1d975686c9113a0b084d5
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'>
892246 123 <li><a href='http://dl.bintray.com/gitblit/releases/gitblit-1.6.1.zip'>Gitblit GO (Windows)</a></li>
M 124 <li><a href='http://dl.bintray.com/gitblit/releases/gitblit-1.6.1.tar.gz'>Gitblit GO (Linux/OSX)</a></li>
125 <li><a href='http://dl.bintray.com/gitblit/releases/gitblit-1.6.1.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>
892246 131 <li><a href='http://dl.bintray.com/gitblit/releases/manager-1.6.1.zip'>Gitblit Manager</a></li>
M 132 <li><a href='http://dl.bintray.com/gitblit/releases/fedclient-1.6.1.zip'>Federation Client</a></li>
48fe87 133 <li class='divider'></li>
892246 134 <li><a href='http://dl.bintray.com/gitblit/releases/gbapi-1.6.1.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>
154 <li class='divider'></li>
155 <li><a href='https://plus.google.com/+JamesMoger'>+JamesMoger</a></li>
156 <li><a href='https://twitter.com/JamesMoger'>@JamesMoger</a></li>
157 </ul></li> <!-- End Menu -->
158 <li class='divider-vertical'></li>
159 <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>
160                         </ul>
161                     </div><!--/.nav-collapse -->
162                 </div>
163             </div>
164         </div><!-- end Navigation Bar -->
165 <div class='container'>
166 <!-- Begin Markdown -->
167 <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;
168 import com.gitblit.servlet.GitblitContext;
169 import com.gitblit.manager.IRuntimeManager;
170 import com.gitblit.manager.IUserManager;
171 import com.gitblit.manager.IAuthenticationManager;
172 import com.gitblit.manager.INotificationManager;
173 import com.gitblit.manager.IRepositoryManager;
174 import com.gitblit.manager.IProjectManager;
175 import com.gitblit.manager.IFederationManager;
176 import com.gitblit.manager.IPluginManager;
177 import com.gitblit.manager.IGitblit;
178 import ro.fortsoft.pf4j.Version;
179
180 public class ExamplePlugin extends GitblitPlugin {
181
182     @Override
183     public void start() {
184         IRuntimeManager runtime = GitblitContext.getManager(IRuntimeManager.class);
185         IUserManager users = GitblitContext.getManager(IUserManager.class);
186         IAuthenticationManager auth = GitblitContext.getManager(IAuthenticationManager.class);
187         INotificationManager notifications = GitblitContext.getManager(INotificationManager.class);
188         IRepositoryManager repos = GitblitContext.getManager(IRepositoryManager.class);
189         IProjectManager projects = GitblitContext.getManager(IProjectManager.class);
190         IFederationManager federation = GitblitContext.getManager(IFederationManager.class);
191         IPluginManager plugins = GitblitContext.getManager(IPluginManager.class);
192         IGitblit gitblit = GitblitContext.getManager(IGitblit.class);
193     }
194
195     @Override
196     public void stop() {
197     }
198
199     @Override
200     public void onInstall() {
201     }
202
203     @Override
204     public void onUpgrade(Version oldVersion) {
205     }
206
207     @Override
208     public void onUninstall() {
209     }
210 }
211
212 /**
213  * You can also create Webapp plugins that register pages.
214  */
215 public class ExampleWicketPlugin extends GitblitWicketPlugin {
216     @Override
217     public void start() {
218     }
219
220     @Override
221     public void stop() {
222     }
223
224     @Override
225     public void onInstall() {
226     }
227
228     @Override
229     public void onUpgrade(Version oldVersion) {
230     }
231
232     @Override
233     public void onUninstall() {
234     }
235
236     @Override
237     protected void init(GitblitWicketApp app) {
238         app.mount(&quot;/logo&quot;, LogoPage.class);
239         app.mount(&quot;/hello&quot;, HelloWorldPage.class);
240     }
241 }
242 </pre></p>
243 <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;
244 import org.kohsuke.args4j.Option;
245 import org.slf4j.Logger;
246 import org.slf4j.LoggerFactory;
247 import com.gitblit.transport.ssh.commands.CommandMetaData;
248 import com.gitblit.transport.ssh.commands.DispatchCommand;
249 import com.gitblit.transport.ssh.commands.UsageExample;
250
251 @Extension
252 @CommandMetaData(name = &quot;mycommands&quot;, description = &quot;Sample SSH dispatcher&quot;)
253 public class MyDispatcher extends DispatchCommand {
254
255     @Override
256     protected void setup() {
257         // commands in this dispatcher
258         register(CommandA.class);
259         register(CommandB.class);
260
261         // nested dispatchers
262         register(SubDispatcher1.class);
263         register(SubDispatcher2.class);
264     }
265
266     @CommandMetaData(name = &quot;commanda&quot;, aliases = { &quot;ca&quot; }, description = &quot;description of command a&quot;)
267     @UsageExample(syntax = &quot;${cmd} --myflag&quot;, description = &quot;description of commanda with --myflag&quot;)
268     public static class CommandA extends SshCommand {
269
270         protected final Logger log = LoggerFactory.getLogger(getClass());
271
272         @Option(name = &quot;--myflag&quot;, aliases = { &quot;-m&quot; }, usage = &quot;enable myflag&quot;)
273         boolean myflag;
274
275         @Override
276         public void run() throws Failure {
277             if (myflag) {
278                 log.info(&quot;Run with --myflag&quot;);
279             } else {
280                 log.info(&quot;Run without --myflag&quot;);
281             }
282         }
283     }
284 }
285 </pre></p>
286 <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;
287 import java.util.Collection;
288 import org.eclipse.jgit.transport.ReceiveCommand;
289 import ro.fortsoft.pf4j.Extension;
290
291 @Extension
292 public class MyReceiveHook extends ReceiveHook {
293
294     @Override
295     public void onPreReceive(GitblitReceivePack receivePack, Collection&lt;ReceiveCommand&gt; commands) {
296     }
297
298     @Override
299     public void onPostReceive(GitblitReceivePack receivePack, Collection&lt;ReceiveCommand&gt; commands) {
300     }
301 }
302
303 </pre></p>
304 <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;
305 import com.gitblit.models.TicketModel;
306 import ro.fortsoft.pf4j.Extension;
307
308 @Extension
309 public class MyPatchsetHook extends PatchsetHook {
310
311     @Override
312     public void onNewPatchset(TicketModel ticket) {
313     }
314
315     @Override
316     public void onUpdatePatchset(TicketModel ticket) {
317     }
318
319     @Override
320     public void onMergePatchset(TicketModel ticket) {
321     }
322 }
323 </pre></p>
324 <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;
325 import com.gitblit.models.TicketModel;
326 import com.gitblit.models.TicketModel.Change;
327 import ro.fortsoft.pf4j.Extension;
328
329 @Extension
330 public class MyTicketHook extends TicketHook {
331
332     @Override
333     public void onNewTicket(TicketModel ticket) {
334     }
335
336     @Override
337     public void onUpdateTicket(TicketModel ticket, Change change) {
338     }
339 }
340 </pre></p>
341 <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;
342 import ro.fortsoft.pf4j.Extension;
343
344 @Extension
345 public class MyRequestFilter extends HttpRequestFilter {
346
347     @Override
348     public void doFilter(ServletRequest request, ServletResponse response,
349             FilterChain chain) throws IOException, ServletException {
350     }
351 }
352 </pre></p>
353 <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;
354 import java.util.List;
355 import ro.fortsoft.pf4j.Extension;
356 import com.gitblit.extensions.UserMenuExtension;
357 import com.gitblit.models.Menu.ExternalLinkMenuItem;
358 import com.gitblit.models.Menu.MenuItem;
359 import com.gitblit.models.UserModel;
360
361 @Extension
362 public class MyUserMenuContributor extends UserMenuExtension {
363
364     @Override
365     public List&lt;MenuItem&gt; getMenuItems(UserModel user) {
366         MenuItem item = new ExternalLinkMenuItem(&quot;Github&quot;, String.format(&quot;https://github.com/%s&quot;, user.username));
367         return Arrays.asList(item);
368     }
369 }
370 </pre></p>
371 <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;
372 import java.util.List;
373 import ro.fortsoft.pf4j.Extension;
374 import com.gitblit.extensions.NavLinkExtension;
375 import com.gitblit.models.UserModel;
376
377 @Extension
378 public class MyNavLink extends NavLinkExtension {
379
380     @Override
381     public List&lt;NavLink&gt; getNavLinks(UserModel user) {
382         NavLink link = new ExternalLinkMenuItem(&quot;Github&quot;, String.format(&quot;https://github.com/%s&quot;, user.username));
383         return Arrays.asList(link);
384     }
385 }
386 </pre></p>
387 <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;
388 import org.slf4j.LoggerFactory;
389 import ro.fortsoft.pf4j.Extension;
390 import com.gitblit.extensions.LifeCycleListener;
391
392 @Extension
393 public class MyLifeCycleListener extends LifeCycleListener {
394
395     final Logger log = LoggerFactory.getLogger(getClass());
396     
397     @Override
398     public void onStartup() {
399         log.info(&quot;Gitblit is Ready!!&quot;);
400     }
401
402     @Override
403     public void onShutdown() {
404         log.info(&quot;Gitblit is Going Down!!&quot;);
405     }
406 }
407 </pre></p>
408 <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;
409 import org.slf4j.LoggerFactory;
410 import ro.fortsoft.pf4j.Extension;
411 import com.gitblit.extensions.RepositoryLifeCycleListener;
412 import com.gitblit.models.RepositoryModel;
413
414 @Extension
415 public class MyRepoLifeCycleListener extends RepositoryLifeCycleListener {
416
417     final Logger log = LoggerFactory.getLogger(getClass());
418     
419     @Override
420     public void onCreation(RepositoryModel repo) {
421         log.info(&quot;Gitblit created {}&quot;, repo);
422     }
423
424     @Override
425     public void onDeletion(RepositoryModel repo) {
426         log.info(&quot;Gitblit deleted {}&quot;, repo);
427     }
428 }
429 </pre></p>
430 <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;
431 import org.slf4j.LoggerFactory;
432 import ro.fortsoft.pf4j.Extension;
433 import com.gitblit.extensions.UserTeamLifeCycleListener;
434 import com.gitblit.models.TeamModel;
435 import com.gitblit.models.UserModel;
436
437 @Extension
438 public class MyUserTeamLifeCycleListener extends UserTeamLifeCycleListener {
439
440     final Logger log = LoggerFactory.getLogger(getClass());
441     
442     @Override
443     public void onCreation(UserModel user) {
444         log.info(&quot;Gitblit created user {}&quot;, user);
445     }
446
447     @Override
448     public void onDeletion(UserModel user) {
449         log.info(&quot;Gitblit deleted user {}&quot;, user);
450     }
451
452     @Override
453     public void onCreation(TeamModel team) {
454         log.info(&quot;Gitblit created team {}&quot;, team);
455     }
456
457     @Override
458     public void onDeletion(TeamModel team) {
459         log.info(&quot;Gitblit deleted team {}&quot;, team);
460     }
461 }
462 </pre>
463 <!-- End Markdown -->
892246 464 <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-20</p>
48fe87 465 <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 466 </footer>
467 </div>
468 <!-- Google Analytics -->
469 <script type="text/javascript">
470     var _gaq = _gaq || [];
471     _gaq.push(['_setAccount', 'UA-24377072-1']);
472     _gaq.push(['_trackPageview']);
473
474     (function() {
475         var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
476         ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
477         var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
478     })();
479 </script>
480
481 </body>
482 </html>