root/trunk/grails-app/views/api/index.gsp @ 2202

Revision 2202, 20.9 KB (checked in by work@…, 2 years ago)

- updated api specification
- added in-code documentation
- added try/catch block to getMeasurementDataForAssay API call to check for valid module REST implementation

Line 
1<html>
2<head>
3    <meta name="layout" content="main"/>
4    <style type="text/css">
5        .api {
6            margin-top: -40px;
7        }
8
9        .api .header {
10            color: #ffda27;
11            font-size: 24px;
12            height: 40px;
13        }
14
15        .api h1 {
16            background-color: #006DBA;
17            padding-left: 10px;
18            margin-top: 40px;
19            height: 30px;
20            padding-top: 10px;
21            color: #fff;
22            text-shadow: 0 1px 2px rgba(0, 0, 0, 0.68);
23        }
24
25        .api h2 {
26            font-size: 12px;
27            background-color: #d7e6f1;
28            padding-left: 10px;
29            margin-top: 10px;
30            height: 20px;
31            padding-top: 5px;
32            font-weight: bold;
33            color: #006DBA;
34            text-shadow: 0 1px 1px rgba(0, 0, 0, 0.28);
35        }
36
37        .api h3 {
38            font-size: 12px;
39            font-weight: bold;
40            color: #ee7624;
41            text-shadow: 0 1px 1px rgba(0, 0, 0, 0.28);
42        }
43       
44        .api li {
45            margin-left: 30px;
46        }
47    </style>
48</head>
49<body>
50<div class="api">
51<h1 class="header">API specification</h1>
52
53The API allows third party software to interface with GSCF and connected modules.
54
55<h2>prerequisites</h2>
56    <li>a valid username / password with role ROLE_CLIENT (see <a href="#authenticate">authenticate</a>)</li>
57    <li>a shared secret (used to calculate the validation md5 hash)</li>
58    <li>a deviceID / clientID (look <a href="https://github.com/4np/UIDevice-with-UniqueIdentifier-for-iOS-5" target="_new">here</a> for iOS)</li>
59
60<h2>available API calls</h2>
61    <li><a href="#authenticate">authenticate</a> - set up / synchronize client-server session</li>
62    <li><a href="#getStudies">getStudies</a> - fetch all (readable) studies</li>
63    <li><a href="#getSubjectsForStudy">getSubjectsForStudy</a> - fetch all subjects in a given study</li>
64    <li><a href="#getAssaysForStudy">getAssaysForStudy</a> - fetch all assays in a given study</li>
65    <li><a href="#getSamplesForAssay">getSamplesForAssay</a> - fetch all samples in a given assay</li>
66    <li><a href="#getMeasurementDataForAssay">getMeasurementDataForAssay</a> - fetch all measurement data for a given assay</li>
67
68<a name="authenticate"></a>
69<h1>authenticate</h1>
70<h3>url: <g:createLink controller="api" action="authenticate" absolute="true" /></h3>
71<p>
72    Authenticate a client using <a href="http://en.wikipedia.org/wiki/Basic_access_authentication" target="_new">HTTP BASIC authentication</a>.
73    This API call is used to:
74    <li>initially set up a client/server session</li>
75    <li>re-synchronise client/server sessions that become out of sync (e.g. <i>sequence</i> differences)</li>
76<p>
77
78<p>
79    After successful authentication, a session token is returned which should the client should store locally. This session token
80    should be used in all subsequent calls to calculate the validation md5 hash.
81</p>
82<p>
83    This call should also be performed whenever a client/server sessions becomes out of sync (e.g. the client's sequence count
84    differs from the server's sequence count) as the server's sequence count will be returned after successfully authenticating.
85    For security reasons this api method is designed to be called only once (or when sessions are out of sync) as HTTP BASIC authentication
86    is not really secure (if someone is able to sniff your traffic, the authentication md5 hash is easily stolen). API calls are
87    validated using the calculated md5 hash.
88</p>
89<p>
90    Every subsequent request the client does, needs to contain the validation MD5 hash, which is a MD5 sum of the concatenation of the device token,
91    the request sequence and a shared secret (e.g. <i>md5sum( token + sequence + shared secret )</i> ).<br/>
92    <i>Note that in order to be able to successfully authenticate or use the API in general, the user should have the ROLE_CLIENT assigned!</i>
93
94    <h2>Request parameters</h2>
95    <table>
96        <thead>
97            <th>argument</th>
98            <th>type</th>
99            <th>length</th>
100            <th>description</th>
101            <th>example</th>
102            <th>required</th>
103        </thead>
104        <tr>
105            <td>deviceID</td>
106            <td>string</td>
107            <td>32</td>
108            <td>a unique ID of the client device / application performing the call (<a href="https://github.com/4np/UIDevice-with-UniqueIdentifier-for-iOS-5" target="_new">iOS example</a>)</td>
109            <td>9ae87836-d38d-4b86-be6a-eff93f2b049a</td>
110            <td>yes</td>
111        </tr>
112    </table>
113
114    <h2>Reply parameters</h2>
115    <table>
116        <thead>
117            <th>argument</th>
118            <th>type</th>
119            <th>length</th>
120            <th>description</th>
121            <th>example</th>
122        </thead>
123        <tr>
124            <td>token</td>
125            <td>string</td>
126            <td>36</td>
127            <td>a unique token for setting up a client session</td>
128            <td>9ae87836-d38d-4b86-be6a-eff93f2b049a</td>
129        </tr>
130        <tr>
131            <td>sequence</td>
132            <td>int</td>
133            <td>-</td>
134            <td>the api call count for this session</td>
135            <td>231</td>
136        </tr>
137    </table>
138
139    <h2>example reply</h2>
140    <blockquote>
141        {"token":"78b070a6-e68c-436e-a81b-2db08840e809","sequence":0}
142    </blockquote>
143</p>
144
145<a name="getStudies"></a>
146<h1>getStudies</h1>
147<h3>url: <g:createLink controller="api" action="getStudies" absolute="true" /></h3>
148<p>
149    Returns the studies which are <i>readable</i> and/or <i>writable</i> for the client. If the client should get access to a particular
150    study, the client's username (used to authenticate) should be added as a reader to the study.
151
152    <h2>Request parameters</h2>
153    <table>
154        <thead>
155            <th>argument</th>
156            <th>type</th>
157            <th>length</th>
158            <th>description</th>
159            <th>example</th>
160            <th>required</th>
161        </thead>
162        <tr>
163            <td>deviceID</td>
164            <td>string</td>
165            <td>36 (max)</td>
166            <td>a unique ID of the client device / application performing the call</td>
167            <td>9ae87836-d38d-4b86-be6a-eff93f2b049a</td>
168            <td>yes</td>
169        </tr>
170        <tr>
171            <td>validation</td>
172            <td>string</td>
173            <td>-</td>
174            <td><a href="http://www.miraclesalad.com/webtools/md5.php" target="_new">md5sum</a>( token + sequence + shared secret )</td>
175            <td>9ae87836d38d4b86be6aeff93f2b049a</td>
176            <td>yes</td>
177        </tr>
178    </table>
179
180    <h2>example reply</h2>
181    <blockquote>
182        {"count":2,"studies":[{"token":"f2e085fb-9138-4ebe-a59f-82f1bdc21d7e","title":"NuGO PPS human study","description":"Human study performed at RRI; centres involved: RRI, IFR, TUM, Maastricht U.","subjects":11,"species":["Homo sapiens"],"assays":["Mass Sequencing module","SAM module for clinical data","Metabolomics module"],"events":1,"uniqueEvents":["start: 3 days, 22 hours, duration: 8 hours"],"samplingEvents":2,"uniqueSamplingEvents":["start: 0 seconds","start: 4 days, 6 hours"],"eventGroups":1,"uniqueEventGroups":["Root group"],"samples":22},{"token":"6b7e85b3-b174-492c-ba27-fbfb71ab9b8b","title":"NuGO PPS3 mouse study leptin module","description":"C57Bl/6 mice were fed a high fat (45 en%) or low fat (10 en%) diet after a four week run-in on low fat diet.","subjects":80,"species":["Mus musculus"],"assays":["SAM module for clinical data","Metabolomics module"],"events":8,"uniqueEvents":["start: 1 hour, duration: 1 week","start: 1 hour, duration: 4 weeks"],"samplingEvents":2,"uniqueSamplingEvents":["start: 1 week, 1 hour"],"eventGroups":8,"uniqueEventGroups":["10% fat + vehicle for 1 week","10% fat + leptin for 1 week","45% fat + vehicle for 1 week","45% fat + leptin for 1 week","10% fat + vehicle for 4 weeks","10% fat + leptin for 4 weeks","45% fat + vehicle for 4 weeks","45% fat + leptin for 4 weeks"],"samples":80}]}
183    </blockquote>
184</p>
185
186<a name="getSubjectsForStudy"></a>
187<h1>getSubjectsForStudy</h1>
188<h3>url: <g:createLink controller="api" action="getSubjectsForStudy" absolute="true" /></h3>
189<p>
190    Returns the subjects for a particular study
191
192    <h2>Request parameters</h2>
193    <table>
194        <thead>
195            <th>argument</th>
196            <th>type</th>
197            <th>length</th>
198            <th>description</th>
199            <th>example</th>
200            <th>required</th>
201        </thead>
202        <tr>
203            <td>deviceID</td>
204            <td>string</td>
205            <td>36 (max)</td>
206            <td>a unique ID of the client device / application performing the call</td>
207            <td>9ae87836-d38d-4b86-be6a-eff93f2b049a</td>
208            <td>yes</td>
209        </tr>
210        <tr>
211            <td>validation</td>
212            <td>string</td>
213            <td>-</td>
214            <td><a href="http://www.miraclesalad.com/webtools/md5.php" target="_new">md5sum</a>( token + sequence + shared secret )</td>
215            <td>9ae87836d38d4b86be6aeff93f2b049a</td>
216            <td>yes</td>
217        </tr>
218        <tr>
219            <td>studyToken</td>
220            <td>string</td>
221            <td>255</td>
222            <td>study token (see getStudies)</td>
223            <td>b6e0c6f4-d8db-4a43-91fa-a157d2d492f0</td>
224            <td>yes</td>
225        </tr>
226    </table>
227
228    <h2>example reply</h2>
229    <blockquote>
230        {"count":11,"subjects":[{"id":81,"name":"1","species":"Homo sapiens","Gender":"Female","Age":null,"DOB":null,"Height":null,"Weight":null,"BMI":null,"Race":null,"Waist circumference":null,"Hip circumference":null,"Systolic blood pressure":null,"Diastolic blood pressure":null,"Heart rate":null,"Run-in-food":null},{"id":82,"name":"2","species":"Homo sapiens","Gender":"Male","Age":null,"DOB":null,"Height":null,"Weight":null,"BMI":null,"Race":null,"Waist circumference":null,"Hip circumference":null,"Systolic blood pressure":null,"Diastolic blood pressure":null,"Heart rate":null,"Run-in-food":null},{"id":83,"name":"3","species":"Homo sapiens","Gender":"Female","Age":null,"DOB":null,"Height":null,"Weight":null,"BMI":null,"Race":null,"Waist circumference":null,"Hip circumference":null,"Systolic blood pressure":null,"Diastolic blood pressure":null,"Heart rate":null,"Run-in-food":null},{"id":84,"name":"4","species":"Homo sapiens","Gender":"Male","Age":null,"DOB":null,"Height":null,"Weight":null,"BMI":null,"Race":null,"Waist circumference":null,"Hip circumference":null,"Systolic blood pressure":null,"Diastolic blood pressure":null,"Heart rate":null,"Run-in-food":null},{"id":85,"name":"5","species":"Homo sapiens","Gender":"Female","Age":null,"DOB":null,"Height":null,"Weight":null,"BMI":null,"Race":null,"Waist circumference":null,"Hip circumference":null,"Systolic blood pressure":null,"Diastolic blood pressure":null,"Heart rate":null,"Run-in-food":null},{"id":86,"name":"6","species":"Homo sapiens","Gender":"Male","Age":null,"DOB":null,"Height":null,"Weight":null,"BMI":null,"Race":null,"Waist circumference":null,"Hip circumference":null,"Systolic blood pressure":null,"Diastolic blood pressure":null,"Heart rate":null,"Run-in-food":null},{"id":87,"name":"7","species":"Homo sapiens","Gender":"Male","Age":null,"DOB":null,"Height":null,"Weight":null,"BMI":null,"Race":null,"Waist circumference":null,"Hip circumference":null,"Systolic blood pressure":null,"Diastolic blood pressure":null,"Heart rate":null,"Run-in-food":null},{"id":88,"name":"8","species":"Homo sapiens","Gender":"Male","Age":null,"DOB":null,"Height":null,"Weight":null,"BMI":null,"Race":null,"Waist circumference":null,"Hip circumference":null,"Systolic blood pressure":null,"Diastolic blood pressure":null,"Heart rate":null,"Run-in-food":null},{"id":89,"name":"9","species":"Homo sapiens","Gender":"Male","Age":null,"DOB":null,"Height":null,"Weight":null,"BMI":null,"Race":null,"Waist circumference":null,"Hip circumference":null,"Systolic blood pressure":null,"Diastolic blood pressure":null,"Heart rate":null,"Run-in-food":null},{"id":90,"name":"10","species":"Homo sapiens","Gender":"Male","Age":null,"DOB":null,"Height":null,"Weight":null,"BMI":null,"Race":null,"Waist circumference":null,"Hip circumference":null,"Systolic blood pressure":null,"Diastolic blood pressure":null,"Heart rate":null,"Run-in-food":null},{"id":91,"name":"11","species":"Homo sapiens","Gender":"Female","Age":null,"DOB":null,"Height":null,"Weight":null,"BMI":null,"Race":null,"Waist circumference":null,"Hip circumference":null,"Systolic blood pressure":null,"Diastolic blood pressure":null,"Heart rate":null,"Run-in-food":null}]}
231    </blockquote>
232</p>
233
234<a name="getAssaysForStudy"></a>
235<h1>getAssaysForStudy</h1>
236<h3>url: <g:createLink controller="api" action="getAssaysForStudy" absolute="true" /></h3>
237<p>
238    Returns the assays for a particular study
239
240    <h2>Request parameters</h2>
241    <table>
242        <thead>
243        <th>argument</th>
244        <th>type</th>
245        <th>length</th>
246        <th>description</th>
247        <th>example</th>
248        <th>required</th>
249        </thead>
250        <tr>
251            <td>deviceID</td>
252            <td>string</td>
253            <td>36 (max)</td>
254            <td>a unique ID of the client device / application performing the call</td>
255            <td>9ae87836-d38d-4b86-be6a-eff93f2b049a</td>
256            <td>yes</td>
257        </tr>
258        <tr>
259            <td>validation</td>
260            <td>string</td>
261            <td>-</td>
262            <td><a href="http://www.miraclesalad.com/webtools/md5.php" target="_new">md5sum</a>( token + sequence + shared secret )</td>
263            <td>9ae87836d38d4b86be6aeff93f2b049a</td>
264            <td>yes</td>
265        </tr>
266        <tr>
267            <td>studyToken</td>
268            <td>string</td>
269            <td>255</td>
270            <td>study token (see getStudies)</td>
271            <td>b6e0c6f4-d8db-4a43-91fa-a157d2d492f0</td>
272            <td>yes</td>
273        </tr>
274    </table>
275
276    <h2>example reply</h2>
277    <blockquote>
278        {"count":6,"assays":[{"token":"253ec24f-9bac-4f2b-b9cf-f84b86376a4e","name":"16S Sequencing assay","module":"Mass Sequencing module","Description":null},{"token":"4df2f49d-1d8c-48bd-8ebd-d267164948ec","name":"18S Sequencing assay","module":"Mass Sequencing module","Description":null},{"token":"828cf2d6-d797-484b-82f9-df9933d76d77","name":"Glucose assay after","module":"SAM module for clinical data","Description":null},{"token":"d68e8fed-41ca-4408-9d8e-f3598eca9183","name":"Glucose assay before","module":"SAM module for clinical data","Description":null},{"token":"32945764-6c5e-497c-8b1e-0d5e0dfa8221","name":"Lipidomics profile after","module":"Metabolomics module","Description":null,"Spectrometry technique":"GC/MS"},{"token":"92f42f77-1c13-4b25-aa57-b444e355fbf4","name":"Lipidomics profile before","module":"Metabolomics module","Description":null,"Spectrometry technique":"GC/MS"}]}
279    </blockquote>
280</p>
281
282<a name="getSamplesForAssay"></a>
283<h1>getSamplesForAssay</h1>
284<h3>url: <g:createLink controller="api" action="getSamplesForAssay" absolute="true" /></h3>
285<p>
286    Returns the samples data for a particular assay
287
288<h2>Request parameters</h2>
289<table>
290    <thead>
291    <th>argument</th>
292    <th>type</th>
293    <th>length</th>
294    <th>description</th>
295    <th>example</th>
296    <th>required</th>
297    </thead>
298    <tr>
299        <td>deviceID</td>
300        <td>string</td>
301        <td>36 (max)</td>
302        <td>a unique ID of the client device / application performing the call</td>
303        <td>9ae87836-d38d-4b86-be6a-eff93f2b049a</td>
304        <td>yes</td>
305    </tr>
306    <tr>
307        <td>validation</td>
308        <td>string</td>
309        <td>-</td>
310        <td><a href="http://www.miraclesalad.com/webtools/md5.php" target="_new">md5sum</a>( token + sequence + shared secret )</td>
311        <td>9ae87836d38d4b86be6aeff93f2b049a</td>
312        <td>yes</td>
313    </tr>
314    <tr>
315        <td>assayToken</td>
316        <td>string</td>
317        <td>255</td>
318        <td>assay token (see getAssays)</td>
319        <td>b6e0c6f4-d8db-4a43-91fa-a157d2d492f0</td>
320        <td>yes</td>
321    </tr>
322</table>
323
324<h2>example reply</h2>
325<blockquote>
326    {
327    "count":
328    11,
329    "samples":
330    [
331    {
332    "Remarks":
333    null,
334    "Sample measured volume":
335    null,
336    "Text on vial":
337    "T58.66620961739546",
338    "material":
339    "blood plasma",
340    "name":
341    "7_A",
342    "token":
343    "c705668a-81c4-4d80-83df-96bb477aeb0b"
344    },
345    {
346    "Remarks":
347    null,
348    "Sample measured volume":
349    null,
350    "Text on vial":
351    "T39.7483280873287",
352    "material":
353    "blood plasma",
354    "name":
355    "9_A",
356    "token":
357    "d81bdda8-4684-45b9-b254-1ec4756cfc71"
358    },
359    {
360    "Remarks":
361    null,
362    "Sample measured volume":
363    null,
364    "Text on vial":
365    "T43.20628871191769",
366    "material":
367    "blood plasma",
368    "name":
369    "2_A",
370    "token":
371    "2f501b55-ffdd-4bf2-a598-dcf24d3fac63"
372    },
373    {
374    "Remarks":
375    null,
376    "Sample measured volume":
377    null,
378    "Text on vial":
379    "T88.40760089710538",
380    "material":
381    "blood plasma",
382    "name":
383    "8_A",
384    "token":
385    "f908ae2a-3df7-4eb7-be2a-0b8859c20bfc"
386    },
387    {
388    "Remarks":
389    null,
390    "Sample measured volume":
391    null,
392    "Text on vial":
393    "T58.14619508995611",
394    "material":
395    "blood plasma",
396    "name":
397    "11_A",
398    "token":
399    "6763cff4-8113-4614-85b9-ef98fb34beba"
400    },
401    {
402    "Remarks":
403    null,
404    "Sample measured volume":
405    null,
406    "Text on vial":
407    "T71.86067212685215",
408    "material":
409    "blood plasma",
410    "name":
411    "6_A",
412    "token":
413    "5a339aaa-9bb6-4a0a-9ce7-4c42ceaf5771"
414    },
415    {
416    "Remarks":
417    null,
418    "Sample measured volume":
419    null,
420    "Text on vial":
421    "T2.395117860298579",
422    "material":
423    "blood plasma",
424    "name":
425    "3_A",
426    "token":
427    "a9e73abe-aed3-4c43-8fe7-a6b3dfe6e2ed"
428    },
429    {
430    "Remarks":
431    null,
432    "Sample measured volume":
433    null,
434    "Text on vial":
435    "T98.99437236833568",
436    "material":
437    "blood plasma",
438    "name":
439    "10_A",
440    "token":
441    "3e63a493-c69d-4cd4-ba23-eeafe962b17f"
442    },
443    {
444    "Remarks":
445    null,
446    "Sample measured volume":
447    null,
448    "Text on vial":
449    "T25.420102086098005",
450    "material":
451    "blood plasma",
452    "name":
453    "4_A",
454    "token":
455    "34d5611b-7407-489a-b25a-00ad2b0d8789"
456    },
457    {
458    "Remarks":
459    null,
460    "Sample measured volume":
461    null,
462    "Text on vial":
463    "T69.55369597806298",
464    "material":
465    "blood plasma",
466    "name":
467    "1_A",
468    "token":
469    "5c9dce07-ca4d-4bcb-8ac3-c8488bd7247a"
470    },
471    {
472    "Remarks":
473    null,
474    "Sample measured volume":
475    null,
476    "Text on vial":
477    "T50.41146383561054",
478    "material":
479    "blood plasma",
480    "name":
481    "5_A",
482    "token":
483    "21a07d33-6d95-46f9-a80d-cd58d7e140d0"
484    }
485    ]
486    }
487</blockquote>
488</p>
489
490<a name="getMeasurementDataForAssay"></a>
491<h1>getMeasurementDataForAssay</h1>
492<h3>url: <g:createLink controller="api" action="getMeasurementDataForAssay" absolute="true" /></h3>
493<p>
494    Returns the measurement data for a particular assay
495
496<h2>Request parameters</h2>
497<table>
498    <thead>
499    <th>argument</th>
500    <th>type</th>
501    <th>length</th>
502    <th>description</th>
503    <th>example</th>
504    <th>required</th>
505    </thead>
506    <tr>
507        <td>deviceID</td>
508        <td>string</td>
509        <td>36 (max)</td>
510        <td>a unique ID of the client device / application performing the call</td>
511        <td>9ae87836-d38d-4b86-be6a-eff93f2b049a</td>
512        <td>yes</td>
513    </tr>
514    <tr>
515        <td>validation</td>
516        <td>string</td>
517        <td>-</td>
518        <td><a href="http://www.miraclesalad.com/webtools/md5.php" target="_new">md5sum</a>( token + sequence + shared secret )</td>
519        <td>9ae87836d38d4b86be6aeff93f2b049a</td>
520        <td>yes</td>
521    </tr>
522    <tr>
523        <td>assayToken</td>
524        <td>string</td>
525        <td>255</td>
526        <td>assay token (see getAssays)</td>
527        <td>b6e0c6f4-d8db-4a43-91fa-a157d2d492f0</td>
528        <td>yes</td>
529    </tr>
530</table>
531
532<h2>example reply</h2>
533<blockquote>
534    {
535    "count":
536    14,
537    "measurements":
538    {
539    "07378e29-3233-4e3f-b4ea-007f9f9b1317":
540    {
541    "Fat Depot":
542    310
543    },
544    "198183b1-d402-4f24-9c5a-396f79bb6a55":
545    {
546    "Fat Depot":
547    1918
548    },
549    "2c719340-eb7f-4a70-8527-c64cc74dc542":
550    {
551    "Fat Depot":
552    1039
553    },
554    "4861fc77-1320-4401-b18a-66b1cd67d2c8":
555    {
556    "Fat Depot":
557    411
558    },
559    "4edff5ad-c3af-41da-8efe-87f5a018912a":
560    {
561    "Fat Depot":
562    368
563    },
564    "6bfe2a0d-3af0-4ed8-8144-56840e934f6e":
565    {
566    "Fat Depot":
567    456
568    },
569    "775666dd-05b1-4f35-ac9c-d36f8257eb1a":
570    {
571    "Fat Depot":
572    2075
573    },
574    "7e9930bc-ec8c-4e74-bd2b-49d6c852eeda":
575    {
576    "Fat Depot":
577    945
578    },
579    "a4d16db8-49f2-4dc2-81bb-910e574c804a":
580    {
581    "Fat Depot":
582    311
583    },
584    "a556b145-dd37-4568-92f1-e3a251653276":
585    {
586    "Fat Depot":
587    1150
588    },
589    "c180d727-8d6c-4673-a5fd-1c28f04b8aaa":
590    {
591    "Fat Depot":
592    347
593    },
594    "e888b1b1-1dc8-45ed-8196-00338fa3b36f":
595    {
596    "Fat Depot":
597    1387
598    },
599    "f7392df1-a754-4957-a1d0-c98bbb91080d":
600    {
601    "Fat Depot":
602    318
603    },
604    "fc755220-b2b4-43ed-adf8-e4323fc62b55":
605    {
606    "Fat Depot":
607    1308
608    }
609    }
610    }
611</blockquote>
612</p>
613
614</div>
615</body>
616</html>
Note: See TracBrowser for help on using the browser.