Browse Source

Merge 04dd0b8794c2497585c18aebf6fc2694f4501526 into 55c5c285558c410bb35ebf421245d320ab9ee9fa

dfeo 3 years ago
parent
commit
497b333b91
No account linked to committer's email
4 changed files with 59 additions and 41 deletions
  1. 3
    0
      .gitignore
  2. 7
    0
      bootstrap.css
  3. 7
    0
      bootstrap.js
  4. 42
    41
      gitstats

+ 3
- 0
.gitignore View File

1
+proyectos
2
+.idea
3
+.DS_Store

+ 7
- 0
bootstrap.css
File diff suppressed because it is too large
View File


+ 7
- 0
bootstrap.js
File diff suppressed because it is too large
View File


+ 42
- 41
gitstats View File

737
 		binarypath = os.path.dirname(os.path.abspath(__file__))
737
 		binarypath = os.path.dirname(os.path.abspath(__file__))
738
 		secondarypath = os.path.join(binarypath, '..', 'share', 'gitstats')
738
 		secondarypath = os.path.join(binarypath, '..', 'share', 'gitstats')
739
 		basedirs = [binarypath, secondarypath, '/usr/share/gitstats']
739
 		basedirs = [binarypath, secondarypath, '/usr/share/gitstats']
740
-		for file in (conf['style'], 'sortable.js', 'arrow-up.gif', 'arrow-down.gif', 'arrow-none.gif'):
740
+		for file in ('bootstrap.js','bootstrap.css','gitstats.css', 'sortable.js', 'arrow-up.gif', 'arrow-down.gif', 'arrow-none.gif'):
741
 			for base in basedirs:
741
 			for base in basedirs:
742
 				src = base + '/' + file
742
 				src = base + '/' + file
743
 				if os.path.exists(src):
743
 				if os.path.exists(src):
754
 
754
 
755
 		self.printNav(f)
755
 		self.printNav(f)
756
 
756
 
757
-		f.write('<dl>')
757
+		f.write('<div><div class="card-body"><dl>')
758
 		f.write('<dt>Project name</dt><dd>%s</dd>' % (data.projectname))
758
 		f.write('<dt>Project name</dt><dd>%s</dd>' % (data.projectname))
759
 		f.write('<dt>Generated</dt><dd>%s (in %d seconds)</dd>' % (datetime.datetime.now().strftime(format), time.time() - data.getStampCreated()))
759
 		f.write('<dt>Generated</dt><dd>%s (in %d seconds)</dd>' % (datetime.datetime.now().strftime(format), time.time() - data.getStampCreated()))
760
 		f.write('<dt>Generator</dt><dd><a href="http://gitstats.sourceforge.net/">GitStats</a> (version %s), %s, %s</dd>' % (getversion(), getgitversion(), getgnuplotversion()))
760
 		f.write('<dt>Generator</dt><dd><a href="http://gitstats.sourceforge.net/">GitStats</a> (version %s), %s, %s</dd>' % (getversion(), getgitversion(), getgnuplotversion()))
764
 		f.write('<dt>Total Lines of Code</dt><dd>%s (%d added, %d removed)</dd>' % (data.getTotalLOC(), data.total_lines_added, data.total_lines_removed))
764
 		f.write('<dt>Total Lines of Code</dt><dd>%s (%d added, %d removed)</dd>' % (data.getTotalLOC(), data.total_lines_added, data.total_lines_removed))
765
 		f.write('<dt>Total Commits</dt><dd>%s (average %.1f commits per active day, %.1f per all days)</dd>' % (data.getTotalCommits(), float(data.getTotalCommits()) / len(data.getActiveDays()), float(data.getTotalCommits()) / data.getCommitDeltaDays()))
765
 		f.write('<dt>Total Commits</dt><dd>%s (average %.1f commits per active day, %.1f per all days)</dd>' % (data.getTotalCommits(), float(data.getTotalCommits()) / len(data.getActiveDays()), float(data.getTotalCommits()) / data.getCommitDeltaDays()))
766
 		f.write('<dt>Authors</dt><dd>%s (average %.1f commits per author)</dd>' % (data.getTotalAuthors(), (1.0 * data.getTotalCommits()) / data.getTotalAuthors()))
766
 		f.write('<dt>Authors</dt><dd>%s (average %.1f commits per author)</dd>' % (data.getTotalAuthors(), (1.0 * data.getTotalCommits()) / data.getTotalAuthors()))
767
-		f.write('</dl>')
767
+		f.write('</dl></div')
768
 
768
 
769
 		f.write('</body>\n</html>')
769
 		f.write('</body>\n</html>')
770
 		f.close()
770
 		f.close()
795
 			stampcur -= deltaweek
795
 			stampcur -= deltaweek
796
 
796
 
797
 		# top row: commits & bar
797
 		# top row: commits & bar
798
-		f.write('<table class="noborders"><tr>')
798
+		f.write('<div><div class="card-body"><table class="noborders"><tr>')
799
 		for i in range(0, WEEKS):
799
 		for i in range(0, WEEKS):
800
 			commits = 0
800
 			commits = 0
801
 			if weeks[i] in data.activity_by_year_week:
801
 			if weeks[i] in data.activity_by_year_week:
811
 		f.write('</tr><tr>')
811
 		f.write('</tr><tr>')
812
 		for i in range(0, WEEKS):
812
 		for i in range(0, WEEKS):
813
 			f.write('<td>%s</td>' % (WEEKS - i))
813
 			f.write('<td>%s</td>' % (WEEKS - i))
814
-		f.write('</tr></table>')
814
+		f.write('</tr></table></div>')
815
 
815
 
816
 		# Hour of Day
816
 		# Hour of Day
817
 		f.write(html_header(2, 'Hour of Day'))
817
 		f.write(html_header(2, 'Hour of Day'))
818
 		hour_of_day = data.getActivityByHourOfDay()
818
 		hour_of_day = data.getActivityByHourOfDay()
819
-		f.write('<table><tr><th>Hour</th>')
819
+		f.write('<div><div class="card-body"><table><tr><th>Hour</th>')
820
 		for i in range(0, 24):
820
 		for i in range(0, 24):
821
 			f.write('<th>%d</th>' % i)
821
 			f.write('<th>%d</th>' % i)
822
 		f.write('</tr>\n<tr><th>Commits</th>')
822
 		f.write('</tr>\n<tr><th>Commits</th>')
838
 				f.write('<td style="background-color: rgb(%d, 0, 0)">%.2f</td>' % (r, (100.0 * hour_of_day[i]) / totalcommits))
838
 				f.write('<td style="background-color: rgb(%d, 0, 0)">%.2f</td>' % (r, (100.0 * hour_of_day[i]) / totalcommits))
839
 			else:
839
 			else:
840
 				f.write('<td>0.00</td>')
840
 				f.write('<td>0.00</td>')
841
-		f.write('</tr></table>')
842
-		f.write('<img src="hour_of_day.png" alt="Hour of Day">')
841
+		f.write('</tr></table></div>')
842
+		f.write('<img src="hour_of_day.png" alt="Hour of Day" />')
843
 		fg = open(path + '/hour_of_day.dat', 'w')
843
 		fg = open(path + '/hour_of_day.dat', 'w')
844
 		for i in range(0, 24):
844
 		for i in range(0, 24):
845
 			if i in hour_of_day:
845
 			if i in hour_of_day:
872
 
872
 
873
 		# Hour of Week
873
 		# Hour of Week
874
 		f.write(html_header(2, 'Hour of Week'))
874
 		f.write(html_header(2, 'Hour of Week'))
875
-		f.write('<table>')
875
+		f.write('<div><div class="card-body"><table>')
876
 
876
 
877
 		f.write('<tr><th>Weekday</th>')
877
 		f.write('<tr><th>Weekday</th>')
878
 		for hour in range(0, 24):
878
 		for hour in range(0, 24):
895
 					f.write('<td></td>')
895
 					f.write('<td></td>')
896
 			f.write('</tr>')
896
 			f.write('</tr>')
897
 
897
 
898
-		f.write('</table>')
898
+		f.write('</table></div>')
899
 
899
 
900
 		# Month of Year
900
 		# Month of Year
901
 		f.write(html_header(2, 'Month of Year'))
901
 		f.write(html_header(2, 'Month of Year'))
938
 
938
 
939
 		# Commits by timezone
939
 		# Commits by timezone
940
 		f.write(html_header(2, 'Commits by Timezone'))
940
 		f.write(html_header(2, 'Commits by Timezone'))
941
-		f.write('<table><tr>')
941
+		f.write('<div><div class="card-body"><table><tr>')
942
 		f.write('<th>Timezone</th><th>Commits</th>')
942
 		f.write('<th>Timezone</th><th>Commits</th>')
943
 		f.write('</tr>')
943
 		f.write('</tr>')
944
 		max_commits_on_tz = max(data.commits_by_timezone.values())
944
 		max_commits_on_tz = max(data.commits_by_timezone.values())
946
 			commits = data.commits_by_timezone[i]
946
 			commits = data.commits_by_timezone[i]
947
 			r = 127 + int((float(commits) / max_commits_on_tz) * 128)
947
 			r = 127 + int((float(commits) / max_commits_on_tz) * 128)
948
 			f.write('<tr><th>%s</th><td style="background-color: rgb(%d, 0, 0)">%d</td></tr>' % (i, r, commits))
948
 			f.write('<tr><th>%s</th><td style="background-color: rgb(%d, 0, 0)">%d</td></tr>' % (i, r, commits))
949
-		f.write('</table>')
950
-
949
+		f.write('</tr></table></div>')
951
 		f.write('</body></html>')
950
 		f.write('</body></html>')
952
 		f.close()
951
 		f.close()
953
 
952
 
962
 		# Authors :: List of authors
961
 		# Authors :: List of authors
963
 		f.write(html_header(2, 'List of Authors'))
962
 		f.write(html_header(2, 'List of Authors'))
964
 
963
 
965
-		f.write('<table class="authors sortable" id="authors">')
964
+		f.write('<div><div class="card-body"><table class="authors sortable" id="authors">')
966
 		f.write('<tr><th>Author</th><th>Commits (%)</th><th>+ lines</th><th>- lines</th><th>First commit</th><th>Last commit</th><th class="unsortable">Age</th><th>Active days</th><th># by commits</th></tr>')
965
 		f.write('<tr><th>Author</th><th>Commits (%)</th><th>+ lines</th><th>- lines</th><th>First commit</th><th>Last commit</th><th class="unsortable">Age</th><th>Active days</th><th># by commits</th></tr>')
967
 		for author in data.getAuthors(conf['max_authors']):
966
 		for author in data.getAuthors(conf['max_authors']):
968
 			info = data.getAuthorInfo(author)
967
 			info = data.getAuthorInfo(author)
969
 			f.write('<tr><td>%s</td><td>%d (%.2f%%)</td><td>%d</td><td>%d</td><td>%s</td><td>%s</td><td>%s</td><td>%d</td><td>%d</td></tr>' % (author, info['commits'], info['commits_frac'], info['lines_added'], info['lines_removed'], info['date_first'], info['date_last'], info['timedelta'], len(info['active_days']), info['place_by_commits']))
968
 			f.write('<tr><td>%s</td><td>%d (%.2f%%)</td><td>%d</td><td>%d</td><td>%s</td><td>%s</td><td>%s</td><td>%d</td><td>%d</td></tr>' % (author, info['commits'], info['commits_frac'], info['lines_added'], info['lines_removed'], info['date_first'], info['date_last'], info['timedelta'], len(info['active_days']), info['place_by_commits']))
970
-		f.write('</table>')
969
+		f.write('</table></div>')
971
 
970
 
972
 		allauthors = data.getAuthors()
971
 		allauthors = data.getAuthors()
973
 		if len(allauthors) > conf['max_authors']:
972
 		if len(allauthors) > conf['max_authors']:
1018
 
1017
 
1019
 		# Authors :: Author of Month
1018
 		# Authors :: Author of Month
1020
 		f.write(html_header(2, 'Author of Month'))
1019
 		f.write(html_header(2, 'Author of Month'))
1021
-		f.write('<table class="sortable" id="aom">')
1020
+		f.write('<div><div class="card-body"><table class="sortable" id="aom">')
1022
 		f.write('<tr><th>Month</th><th>Author</th><th>Commits (%%)</th><th class="unsortable">Next top %d</th><th>Number of authors</th></tr>' % conf['authors_top'])
1021
 		f.write('<tr><th>Month</th><th>Author</th><th>Commits (%%)</th><th class="unsortable">Next top %d</th><th>Number of authors</th></tr>' % conf['authors_top'])
1023
 		for yymm in reversed(sorted(data.author_of_month.keys())):
1022
 		for yymm in reversed(sorted(data.author_of_month.keys())):
1024
 			authordict = data.author_of_month[yymm]
1023
 			authordict = data.author_of_month[yymm]
1028
 			next = ', '.join(authors[1:conf['authors_top']+1])
1027
 			next = ', '.join(authors[1:conf['authors_top']+1])
1029
 			f.write('<tr><td>%s</td><td>%s</td><td>%d (%.2f%% of %d)</td><td>%s</td><td>%d</td></tr>' % (yymm, authors[0], commits, (100.0 * commits) / data.commits_by_month[yymm], data.commits_by_month[yymm], next, len(authors)))
1028
 			f.write('<tr><td>%s</td><td>%s</td><td>%d (%.2f%% of %d)</td><td>%s</td><td>%d</td></tr>' % (yymm, authors[0], commits, (100.0 * commits) / data.commits_by_month[yymm], data.commits_by_month[yymm], next, len(authors)))
1030
 
1029
 
1031
-		f.write('</table>')
1030
+		f.write('</table></div>')
1032
 
1031
 
1033
 		f.write(html_header(2, 'Author of Year'))
1032
 		f.write(html_header(2, 'Author of Year'))
1034
-		f.write('<table class="sortable" id="aoy"><tr><th>Year</th><th>Author</th><th>Commits (%%)</th><th class="unsortable">Next top %d</th><th>Number of authors</th></tr>' % conf['authors_top'])
1033
+		f.write('<div><div class="card-body"><table class="sortable" id="aoy"><tr><th>Year</th><th>Author</th><th>Commits (%%)</th><th class="unsortable">Next top %d</th><th>Number of authors</th></tr>' % conf['authors_top'])
1035
 		for yy in reversed(sorted(data.author_of_year.keys())):
1034
 		for yy in reversed(sorted(data.author_of_year.keys())):
1036
 			authordict = data.author_of_year[yy]
1035
 			authordict = data.author_of_year[yy]
1037
 			authors = getkeyssortedbyvalues(authordict)
1036
 			authors = getkeyssortedbyvalues(authordict)
1039
 			commits = data.author_of_year[yy][authors[0]]
1038
 			commits = data.author_of_year[yy][authors[0]]
1040
 			next = ', '.join(authors[1:conf['authors_top']+1])
1039
 			next = ', '.join(authors[1:conf['authors_top']+1])
1041
 			f.write('<tr><td>%s</td><td>%s</td><td>%d (%.2f%% of %d)</td><td>%s</td><td>%d</td></tr>' % (yy, authors[0], commits, (100.0 * commits) / data.commits_by_year[yy], data.commits_by_year[yy], next, len(authors)))
1040
 			f.write('<tr><td>%s</td><td>%s</td><td>%d (%.2f%% of %d)</td><td>%s</td><td>%d</td></tr>' % (yy, authors[0], commits, (100.0 * commits) / data.commits_by_year[yy], data.commits_by_year[yy], next, len(authors)))
1042
-		f.write('</table>')
1041
+		f.write('</table></div>')
1043
 
1042
 
1044
 		# Domains
1043
 		# Domains
1045
 		f.write(html_header(2, 'Commits by Domains'))
1044
 		f.write(html_header(2, 'Commits by Domains'))
1071
 		f.write('<h1>Files</h1>')
1070
 		f.write('<h1>Files</h1>')
1072
 		self.printNav(f)
1071
 		self.printNav(f)
1073
 
1072
 
1074
-		f.write('<dl>\n')
1073
+		f.write('<div><div class="card-body"><dl>\n')
1075
 		f.write('<dt>Total files</dt><dd>%d</dd>' % data.getTotalFiles())
1074
 		f.write('<dt>Total files</dt><dd>%d</dd>' % data.getTotalFiles())
1076
 		f.write('<dt>Total lines</dt><dd>%d</dd>' % data.getTotalLOC())
1075
 		f.write('<dt>Total lines</dt><dd>%d</dd>' % data.getTotalLOC())
1077
 		try:
1076
 		try:
1078
 			f.write('<dt>Average file size</dt><dd>%.2f bytes</dd>' % (float(data.getTotalSize()) / data.getTotalFiles()))
1077
 			f.write('<dt>Average file size</dt><dd>%.2f bytes</dd>' % (float(data.getTotalSize()) / data.getTotalFiles()))
1079
 		except ZeroDivisionError:
1078
 		except ZeroDivisionError:
1080
 			pass
1079
 			pass
1081
-		f.write('</dl>\n')
1080
+		f.write('</dl></div>\n')
1082
 
1081
 
1083
 		# Files :: File count by date
1082
 		# Files :: File count by date
1084
 		f.write(html_header(2, 'File count by date'))
1083
 		f.write(html_header(2, 'File count by date'))
1101
 
1100
 
1102
 		# Files :: Extensions
1101
 		# Files :: Extensions
1103
 		f.write(html_header(2, 'Extensions'))
1102
 		f.write(html_header(2, 'Extensions'))
1104
-		f.write('<table class="sortable" id="ext"><tr><th>Extension</th><th>Files (%)</th><th>Lines (%)</th><th>Lines/file</th></tr>')
1103
+		f.write('<div><div class="card-body"><table class="sortable" id="ext"><tr><th>Extension</th><th>Files (%)</th><th>Lines (%)</th><th>Lines/file</th></tr>')
1105
 		for ext in sorted(data.extensions.keys()):
1104
 		for ext in sorted(data.extensions.keys()):
1106
 			files = data.extensions[ext]['files']
1105
 			files = data.extensions[ext]['files']
1107
 			lines = data.extensions[ext]['lines']
1106
 			lines = data.extensions[ext]['lines']
1110
 			except ZeroDivisionError:
1109
 			except ZeroDivisionError:
1111
 				loc_percentage = 0
1110
 				loc_percentage = 0
1112
 			f.write('<tr><td>%s</td><td>%d (%.2f%%)</td><td>%d (%.2f%%)</td><td>%d</td></tr>' % (ext, files, (100.0 * files) / data.getTotalFiles(), lines, loc_percentage, lines / files))
1111
 			f.write('<tr><td>%s</td><td>%d (%.2f%%)</td><td>%d (%.2f%%)</td><td>%d</td></tr>' % (ext, files, (100.0 * files) / data.getTotalFiles(), lines, loc_percentage, lines / files))
1113
-		f.write('</table>')
1112
+		f.write('</table></div>')
1114
 
1113
 
1115
 		f.write('</body></html>')
1114
 		f.write('</body></html>')
1116
 		f.close()
1115
 		f.close()
1122
 		f.write('<h1>Lines</h1>')
1121
 		f.write('<h1>Lines</h1>')
1123
 		self.printNav(f)
1122
 		self.printNav(f)
1124
 
1123
 
1125
-		f.write('<dl>\n')
1124
+		f.write('<div><div class="card-body"><dl>\n')
1126
 		f.write('<dt>Total lines</dt><dd>%d</dd>' % data.getTotalLOC())
1125
 		f.write('<dt>Total lines</dt><dd>%d</dd>' % data.getTotalLOC())
1127
-		f.write('</dl>\n')
1126
+		f.write('</dl></div>\n')
1128
 
1127
 
1129
 		f.write(html_header(2, 'Lines of Code'))
1128
 		f.write(html_header(2, 'Lines of Code'))
1130
 		f.write('<img src="lines_of_code.png" alt="Lines of Code">')
1129
 		f.write('<img src="lines_of_code.png" alt="Lines of Code">')
1144
 		f.write('<h1>Tags</h1>')
1143
 		f.write('<h1>Tags</h1>')
1145
 		self.printNav(f)
1144
 		self.printNav(f)
1146
 
1145
 
1147
-		f.write('<dl>')
1146
+		f.write('<div><div class="card-body"><dl>')
1148
 		f.write('<dt>Total tags</dt><dd>%d</dd>' % len(data.tags))
1147
 		f.write('<dt>Total tags</dt><dd>%d</dd>' % len(data.tags))
1149
 		if len(data.tags) > 0:
1148
 		if len(data.tags) > 0:
1150
 			f.write('<dt>Average commits per tag</dt><dd>%.2f</dd>' % (1.0 * data.getTotalCommits() / len(data.tags)))
1149
 			f.write('<dt>Average commits per tag</dt><dd>%.2f</dd>' % (1.0 * data.getTotalCommits() / len(data.tags)))
1151
-		f.write('</dl>')
1150
+		f.write('</dl></div>')
1152
 
1151
 
1153
-		f.write('<table class="tags">')
1152
+		f.write('<div><div class="card-body"><table class="tags">')
1154
 		f.write('<tr><th>Name</th><th>Date</th><th>Commits</th><th>Authors</th></tr>')
1153
 		f.write('<tr><th>Name</th><th>Date</th><th>Commits</th><th>Authors</th></tr>')
1155
 		# sort the tags by date desc
1154
 		# sort the tags by date desc
1156
 		tags_sorted_by_date_desc = map(lambda el : el[1], reversed(sorted(map(lambda el : (el[1]['date'], el[0]), data.tags.items()))))
1155
 		tags_sorted_by_date_desc = map(lambda el : el[1], reversed(sorted(map(lambda el : (el[1]['date'], el[0]), data.tags.items()))))
1160
 			for i in reversed(self.authors_by_commits):
1159
 			for i in reversed(self.authors_by_commits):
1161
 				authorinfo.append('%s (%d)' % (i, data.tags[tag]['authors'][i]))
1160
 				authorinfo.append('%s (%d)' % (i, data.tags[tag]['authors'][i]))
1162
 			f.write('<tr><td>%s</td><td>%s</td><td>%d</td><td>%s</td></tr>' % (tag, data.tags[tag]['date'], data.tags[tag]['commits'], ', '.join(authorinfo)))
1161
 			f.write('<tr><td>%s</td><td>%s</td><td>%d</td><td>%s</td></tr>' % (tag, data.tags[tag]['date'], data.tags[tag]['commits'], ', '.join(authorinfo)))
1163
-		f.write('</table>')
1162
+		f.write('</table></div>')
1164
 
1163
 
1165
 		f.write('</body></html>')
1164
 		f.write('</body></html>')
1166
 		f.close()
1165
 		f.close()
1379
 <head>
1378
 <head>
1380
 	<meta charset="UTF-8">
1379
 	<meta charset="UTF-8">
1381
 	<title>GitStats - %s</title>
1380
 	<title>GitStats - %s</title>
1382
-	<link rel="stylesheet" href="%s" type="text/css">
1383
-	<meta name="generator" content="GitStats %s">
1381
+	<link rel="stylesheet" href="%s" type="text/css" />
1382
+	<link rel="stylesheet" href="bootstrap.css" type="text/css" />
1383
+	<meta name="generator" content="GitStats %s" />
1384
 	<script type="text/javascript" src="sortable.js"></script>
1384
 	<script type="text/javascript" src="sortable.js"></script>
1385
+	<script type="text/javascript" src="bootstrap.js"></script>
1385
 </head>
1386
 </head>
1386
 <body>
1387
 <body>
1387
 """ % (self.title, conf['style'], getversion()))
1388
 """ % (self.title, conf['style'], getversion()))
1388
 
1389
 
1389
 	def printNav(self, f):
1390
 	def printNav(self, f):
1390
 		f.write("""
1391
 		f.write("""
1391
-<div class="nav">
1392
-<ul>
1393
-<li><a href="index.html">General</a></li>
1394
-<li><a href="activity.html">Activity</a></li>
1395
-<li><a href="authors.html">Authors</a></li>
1396
-<li><a href="files.html">Files</a></li>
1397
-<li><a href="lines.html">Lines</a></li>
1398
-<li><a href="tags.html">Tags</a></li>
1399
-</ul>
1400
-</div>
1392
+<nav aria-label="breadcrumb">
1393
+<ol class="breadcrumb">
1394
+ <li class="breadcrumb-item" aria-current="page"><a href="index.html">General</a></li>
1395
+ <li class="breadcrumb-item" aria-current="page"><a href="activity.html">Activity</a></li>
1396
+ <li class="breadcrumb-item" aria-current="page"><a href="authors.html">Authors</a></li>
1397
+ <li class="breadcrumb-item" aria-current="page"><a href="files.html">Files</a></li>
1398
+ <li class="breadcrumb-item" aria-current="page"><a href="lines.html">Lines</a></li>
1399
+ <li class="breadcrumb-item" aria-current="page"><a href="tags.html">Tags</a></li>
1400
+</ol>
1401
+</nav>
1401
 """)
1402
 """)
1402
 		
1403
 		
1403
 def usage():
1404
 def usage():