##// END OF EJS Templates
js-i18n: fixed wrong usage of _ngettext
marcink -
r429:98e0a07b default
parent child Browse files
Show More
@@ -1,395 +1,395 b''
1 // # Copyright (C) 2010-2016 RhodeCode GmbH
1 // # Copyright (C) 2010-2016 RhodeCode GmbH
2 // #
2 // #
3 // # This program is free software: you can redistribute it and/or modify
3 // # This program is free software: you can redistribute it and/or modify
4 // # it under the terms of the GNU Affero General Public License, version 3
4 // # it under the terms of the GNU Affero General Public License, version 3
5 // # (only), as published by the Free Software Foundation.
5 // # (only), as published by the Free Software Foundation.
6 // #
6 // #
7 // # This program is distributed in the hope that it will be useful,
7 // # This program is distributed in the hope that it will be useful,
8 // # but WITHOUT ANY WARRANTY; without even the implied warranty of
8 // # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 // # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 // # GNU General Public License for more details.
10 // # GNU General Public License for more details.
11 // #
11 // #
12 // # You should have received a copy of the GNU Affero General Public License
12 // # You should have received a copy of the GNU Affero General Public License
13 // # along with this program. If not, see <http://www.gnu.org/licenses/>.
13 // # along with this program. If not, see <http://www.gnu.org/licenses/>.
14 // #
14 // #
15 // # This program is dual-licensed. If you wish to learn more about the
15 // # This program is dual-licensed. If you wish to learn more about the
16 // # RhodeCode Enterprise Edition, including its added features, Support services,
16 // # RhodeCode Enterprise Edition, including its added features, Support services,
17 // # and proprietary license terms, please see https://rhodecode.com/licenses/
17 // # and proprietary license terms, please see https://rhodecode.com/licenses/
18
18
19 /**
19 /**
20 RhodeCode JS Files
20 RhodeCode JS Files
21 **/
21 **/
22
22
23 if (typeof console == "undefined" || typeof console.log == "undefined"){
23 if (typeof console == "undefined" || typeof console.log == "undefined"){
24 console = { log: function() {} }
24 console = { log: function() {} }
25 }
25 }
26
26
27 // TODO: move the following function to submodules
27 // TODO: move the following function to submodules
28
28
29 /**
29 /**
30 * show more
30 * show more
31 */
31 */
32 var show_more_event = function(){
32 var show_more_event = function(){
33 $('table .show_more').click(function(e) {
33 $('table .show_more').click(function(e) {
34 var cid = e.target.id.substring(1);
34 var cid = e.target.id.substring(1);
35 var button = $(this);
35 var button = $(this);
36 if (button.hasClass('open')) {
36 if (button.hasClass('open')) {
37 $('#'+cid).hide();
37 $('#'+cid).hide();
38 button.removeClass('open');
38 button.removeClass('open');
39 } else {
39 } else {
40 $('#'+cid).show();
40 $('#'+cid).show();
41 button.addClass('open one');
41 button.addClass('open one');
42 }
42 }
43 });
43 });
44 };
44 };
45
45
46 var compare_radio_buttons = function(repo_name, compare_ref_type){
46 var compare_radio_buttons = function(repo_name, compare_ref_type){
47 $('#compare_action').on('click', function(e){
47 $('#compare_action').on('click', function(e){
48 e.preventDefault();
48 e.preventDefault();
49
49
50 var source = $('input[name=compare_source]:checked').val();
50 var source = $('input[name=compare_source]:checked').val();
51 var target = $('input[name=compare_target]:checked').val();
51 var target = $('input[name=compare_target]:checked').val();
52 if(source && target){
52 if(source && target){
53 var url_data = {
53 var url_data = {
54 repo_name: repo_name,
54 repo_name: repo_name,
55 source_ref: source,
55 source_ref: source,
56 source_ref_type: compare_ref_type,
56 source_ref_type: compare_ref_type,
57 target_ref: target,
57 target_ref: target,
58 target_ref_type: compare_ref_type,
58 target_ref_type: compare_ref_type,
59 merge: 1
59 merge: 1
60 };
60 };
61 window.location = pyroutes.url('compare_url', url_data);
61 window.location = pyroutes.url('compare_url', url_data);
62 }
62 }
63 });
63 });
64 $('.compare-radio-button').on('click', function(e){
64 $('.compare-radio-button').on('click', function(e){
65 var source = $('input[name=compare_source]:checked').val();
65 var source = $('input[name=compare_source]:checked').val();
66 var target = $('input[name=compare_target]:checked').val();
66 var target = $('input[name=compare_target]:checked').val();
67 if(source && target){
67 if(source && target){
68 $('#compare_action').removeAttr("disabled");
68 $('#compare_action').removeAttr("disabled");
69 $('#compare_action').removeClass("disabled");
69 $('#compare_action').removeClass("disabled");
70 }
70 }
71 })
71 })
72 };
72 };
73
73
74 var showRepoSize = function(target, repo_name, commit_id, callback) {
74 var showRepoSize = function(target, repo_name, commit_id, callback) {
75 var container = $('#' + target);
75 var container = $('#' + target);
76 var url = pyroutes.url('repo_stats',
76 var url = pyroutes.url('repo_stats',
77 {"repo_name": repo_name, "commit_id": commit_id});
77 {"repo_name": repo_name, "commit_id": commit_id});
78
78
79 if (!container.hasClass('loaded')) {
79 if (!container.hasClass('loaded')) {
80 $.ajax({url: url})
80 $.ajax({url: url})
81 .complete(function (data) {
81 .complete(function (data) {
82 var responseJSON = data.responseJSON;
82 var responseJSON = data.responseJSON;
83 container.addClass('loaded');
83 container.addClass('loaded');
84 container.html(responseJSON.size);
84 container.html(responseJSON.size);
85 callback(responseJSON.code_stats)
85 callback(responseJSON.code_stats)
86 })
86 })
87 .fail(function (data) {
87 .fail(function (data) {
88 console.log('failed to load repo stats');
88 console.log('failed to load repo stats');
89 });
89 });
90 }
90 }
91
91
92 };
92 };
93
93
94 var showRepoStats = function(target, data){
94 var showRepoStats = function(target, data){
95 var container = $('#' + target);
95 var container = $('#' + target);
96
96
97 if (container.hasClass('loaded')) {
97 if (container.hasClass('loaded')) {
98 return
98 return
99 }
99 }
100
100
101 var total = 0;
101 var total = 0;
102 var no_data = true;
102 var no_data = true;
103 var tbl = document.createElement('table');
103 var tbl = document.createElement('table');
104 tbl.setAttribute('class', 'trending_language_tbl');
104 tbl.setAttribute('class', 'trending_language_tbl');
105
105
106 $.each(data, function(key, val){
106 $.each(data, function(key, val){
107 total += val.count;
107 total += val.count;
108 });
108 });
109
109
110 var sortedStats = [];
110 var sortedStats = [];
111 for (var obj in data){
111 for (var obj in data){
112 sortedStats.push([obj, data[obj]])
112 sortedStats.push([obj, data[obj]])
113 }
113 }
114 var sortedData = sortedStats.sort(function (a, b) {
114 var sortedData = sortedStats.sort(function (a, b) {
115 return b[1].count - a[1].count
115 return b[1].count - a[1].count
116 });
116 });
117 var cnt = 0;
117 var cnt = 0;
118 $.each(sortedData, function(idx, val){
118 $.each(sortedData, function(idx, val){
119 cnt += 1;
119 cnt += 1;
120 no_data = false;
120 no_data = false;
121
121
122 var hide = cnt > 2;
122 var hide = cnt > 2;
123 var tr = document.createElement('tr');
123 var tr = document.createElement('tr');
124 if (hide) {
124 if (hide) {
125 tr.setAttribute('style', 'display:none');
125 tr.setAttribute('style', 'display:none');
126 tr.setAttribute('class', 'stats_hidden');
126 tr.setAttribute('class', 'stats_hidden');
127 }
127 }
128
128
129 var key = val[0];
129 var key = val[0];
130 var obj = {"desc": val[1].desc, "count": val[1].count};
130 var obj = {"desc": val[1].desc, "count": val[1].count};
131
131
132 var percentage = Math.round((obj.count / total * 100), 2);
132 var percentage = Math.round((obj.count / total * 100), 2);
133
133
134 var td1 = document.createElement('td');
134 var td1 = document.createElement('td');
135 td1.width = 300;
135 td1.width = 300;
136 var trending_language_label = document.createElement('div');
136 var trending_language_label = document.createElement('div');
137 trending_language_label.innerHTML = obj.desc + " (.{0})".format(key);
137 trending_language_label.innerHTML = obj.desc + " (.{0})".format(key);
138 td1.appendChild(trending_language_label);
138 td1.appendChild(trending_language_label);
139
139
140 var td2 = document.createElement('td');
140 var td2 = document.createElement('td');
141 var trending_language = document.createElement('div');
141 var trending_language = document.createElement('div');
142 var nr_files = obj.count +" "+ _ngettext('file', 'files', obj.count);
142 var nr_files = obj.count +" "+ _ngettext('file', 'files', obj.count);
143
143
144 trending_language.title = key + " " + nr_files;
144 trending_language.title = key + " " + nr_files;
145
145
146 trending_language.innerHTML = "<span>" + percentage + "% " + nr_files
146 trending_language.innerHTML = "<span>" + percentage + "% " + nr_files
147 + "</span><b>" + percentage + "% " + nr_files + "</b>";
147 + "</span><b>" + percentage + "% " + nr_files + "</b>";
148
148
149 trending_language.setAttribute("class", 'trending_language');
149 trending_language.setAttribute("class", 'trending_language');
150 $('b', trending_language)[0].style.width = percentage + "%";
150 $('b', trending_language)[0].style.width = percentage + "%";
151 td2.appendChild(trending_language);
151 td2.appendChild(trending_language);
152
152
153 tr.appendChild(td1);
153 tr.appendChild(td1);
154 tr.appendChild(td2);
154 tr.appendChild(td2);
155 tbl.appendChild(tr);
155 tbl.appendChild(tr);
156 if (cnt == 3) {
156 if (cnt == 3) {
157 var show_more = document.createElement('tr');
157 var show_more = document.createElement('tr');
158 var td = document.createElement('td');
158 var td = document.createElement('td');
159 lnk = document.createElement('a');
159 lnk = document.createElement('a');
160
160
161 lnk.href = '#';
161 lnk.href = '#';
162 lnk.innerHTML = _ngettext('Show more');
162 lnk.innerHTML = _gettext('Show more');
163 lnk.id = 'code_stats_show_more';
163 lnk.id = 'code_stats_show_more';
164 td.appendChild(lnk);
164 td.appendChild(lnk);
165
165
166 show_more.appendChild(td);
166 show_more.appendChild(td);
167 show_more.appendChild(document.createElement('td'));
167 show_more.appendChild(document.createElement('td'));
168 tbl.appendChild(show_more);
168 tbl.appendChild(show_more);
169 }
169 }
170 });
170 });
171
171
172 $(container).html(tbl);
172 $(container).html(tbl);
173 $(container).addClass('loaded');
173 $(container).addClass('loaded');
174
174
175 $('#code_stats_show_more').on('click', function (e) {
175 $('#code_stats_show_more').on('click', function (e) {
176 e.preventDefault();
176 e.preventDefault();
177 $('.stats_hidden').each(function (idx) {
177 $('.stats_hidden').each(function (idx) {
178 $(this).css("display", "");
178 $(this).css("display", "");
179 });
179 });
180 $('#code_stats_show_more').hide();
180 $('#code_stats_show_more').hide();
181 });
181 });
182
182
183 };
183 };
184
184
185
185
186 // Toggle Collapsable Content
186 // Toggle Collapsable Content
187 function collapsableContent() {
187 function collapsableContent() {
188
188
189 $('.collapsable-content').not('.no-hide').hide();
189 $('.collapsable-content').not('.no-hide').hide();
190
190
191 $('.btn-collapse').unbind(); //in case we've been here before
191 $('.btn-collapse').unbind(); //in case we've been here before
192 $('.btn-collapse').click(function() {
192 $('.btn-collapse').click(function() {
193 var button = $(this);
193 var button = $(this);
194 var togglename = $(this).data("toggle");
194 var togglename = $(this).data("toggle");
195 $('.collapsable-content[data-toggle='+togglename+']').toggle();
195 $('.collapsable-content[data-toggle='+togglename+']').toggle();
196 if ($(this).html()=="Show Less")
196 if ($(this).html()=="Show Less")
197 $(this).html("Show More");
197 $(this).html("Show More");
198 else
198 else
199 $(this).html("Show Less");
199 $(this).html("Show Less");
200 });
200 });
201 };
201 };
202
202
203 var timeagoActivate = function() {
203 var timeagoActivate = function() {
204 $("time.timeago").timeago();
204 $("time.timeago").timeago();
205 };
205 };
206
206
207 // Formatting values in a Select2 dropdown of commit references
207 // Formatting values in a Select2 dropdown of commit references
208 var formatSelect2SelectionRefs = function(commit_ref){
208 var formatSelect2SelectionRefs = function(commit_ref){
209 var tmpl = '';
209 var tmpl = '';
210 if (!commit_ref.text || commit_ref.type === 'sha'){
210 if (!commit_ref.text || commit_ref.type === 'sha'){
211 return commit_ref.text;
211 return commit_ref.text;
212 }
212 }
213 if (commit_ref.type === 'branch'){
213 if (commit_ref.type === 'branch'){
214 tmpl = tmpl.concat('<i class="icon-branch"></i> ');
214 tmpl = tmpl.concat('<i class="icon-branch"></i> ');
215 } else if (commit_ref.type === 'tag'){
215 } else if (commit_ref.type === 'tag'){
216 tmpl = tmpl.concat('<i class="icon-tag"></i> ');
216 tmpl = tmpl.concat('<i class="icon-tag"></i> ');
217 } else if (commit_ref.type === 'book'){
217 } else if (commit_ref.type === 'book'){
218 tmpl = tmpl.concat('<i class="icon-bookmark"></i> ');
218 tmpl = tmpl.concat('<i class="icon-bookmark"></i> ');
219 }
219 }
220 return tmpl.concat(commit_ref.text);
220 return tmpl.concat(commit_ref.text);
221 };
221 };
222
222
223 // takes a given html element and scrolls it down offset pixels
223 // takes a given html element and scrolls it down offset pixels
224 function offsetScroll(element, offset){
224 function offsetScroll(element, offset){
225 setTimeout(function(){
225 setTimeout(function(){
226 console.log(element);
226 console.log(element);
227 var location = element.offset().top;
227 var location = element.offset().top;
228 // some browsers use body, some use html
228 // some browsers use body, some use html
229 $('html, body').animate({ scrollTop: (location - offset) });
229 $('html, body').animate({ scrollTop: (location - offset) });
230 }, 100);
230 }, 100);
231 }
231 }
232
232
233 /**
233 /**
234 * global hooks after DOM is loaded
234 * global hooks after DOM is loaded
235 */
235 */
236 $(document).ready(function() {
236 $(document).ready(function() {
237 firefoxAnchorFix();
237 firefoxAnchorFix();
238
238
239 $('.navigation a.menulink').on('click', function(e){
239 $('.navigation a.menulink').on('click', function(e){
240 var menuitem = $(this).parent('li');
240 var menuitem = $(this).parent('li');
241 if (menuitem.hasClass('open')) {
241 if (menuitem.hasClass('open')) {
242 menuitem.removeClass('open');
242 menuitem.removeClass('open');
243 } else {
243 } else {
244 menuitem.addClass('open');
244 menuitem.addClass('open');
245 $(document).on('click', function(event) {
245 $(document).on('click', function(event) {
246 if (!$(event.target).closest(menuitem).length) {
246 if (!$(event.target).closest(menuitem).length) {
247 menuitem.removeClass('open');
247 menuitem.removeClass('open');
248 }
248 }
249 });
249 });
250 }
250 }
251 });
251 });
252 $('.compare_view_files').on(
252 $('.compare_view_files').on(
253 'mouseenter mouseleave', 'tr.line .lineno a',function(event) {
253 'mouseenter mouseleave', 'tr.line .lineno a',function(event) {
254 if (event.type === "mouseenter") {
254 if (event.type === "mouseenter") {
255 $(this).parents('tr.line').addClass('hover');
255 $(this).parents('tr.line').addClass('hover');
256 } else {
256 } else {
257 $(this).parents('tr.line').removeClass('hover');
257 $(this).parents('tr.line').removeClass('hover');
258 }
258 }
259 });
259 });
260
260
261 $('.compare_view_files').on(
261 $('.compare_view_files').on(
262 'mouseenter mouseleave', 'tr.line .add-comment-line a',function(event){
262 'mouseenter mouseleave', 'tr.line .add-comment-line a',function(event){
263 if (event.type === "mouseenter") {
263 if (event.type === "mouseenter") {
264 $(this).parents('tr.line').addClass('commenting');
264 $(this).parents('tr.line').addClass('commenting');
265 } else {
265 } else {
266 $(this).parents('tr.line').removeClass('commenting');
266 $(this).parents('tr.line').removeClass('commenting');
267 }
267 }
268 });
268 });
269
269
270 $('.compare_view_files').on(
270 $('.compare_view_files').on(
271 'click', 'tr.line .lineno a',function(event) {
271 'click', 'tr.line .lineno a',function(event) {
272 if ($(this).text() != ""){
272 if ($(this).text() != ""){
273 $('tr.line').removeClass('selected');
273 $('tr.line').removeClass('selected');
274 $(this).parents("tr.line").addClass('selected');
274 $(this).parents("tr.line").addClass('selected');
275
275
276 // Replace URL without jumping to it if browser supports.
276 // Replace URL without jumping to it if browser supports.
277 // Default otherwise
277 // Default otherwise
278 if (history.pushState) {
278 if (history.pushState) {
279 var new_location = location.href;
279 var new_location = location.href;
280 if (location.hash){
280 if (location.hash){
281 new_location = new_location.replace(location.hash, "");
281 new_location = new_location.replace(location.hash, "");
282 }
282 }
283
283
284 // Make new anchor url
284 // Make new anchor url
285 var new_location = new_location+$(this).attr('href');
285 var new_location = new_location+$(this).attr('href');
286 history.pushState(true, document.title, new_location);
286 history.pushState(true, document.title, new_location);
287
287
288 return false;
288 return false;
289 }
289 }
290 }
290 }
291 });
291 });
292
292
293 $('.compare_view_files').on(
293 $('.compare_view_files').on(
294 'click', 'tr.line .add-comment-line a',function(event) {
294 'click', 'tr.line .add-comment-line a',function(event) {
295 var tr = $(event.currentTarget).parents('tr.line')[0];
295 var tr = $(event.currentTarget).parents('tr.line')[0];
296 injectInlineForm(tr);
296 injectInlineForm(tr);
297 return false;
297 return false;
298 });
298 });
299
299
300 $('.collapse_file').on('click', function(e) {
300 $('.collapse_file').on('click', function(e) {
301 e.stopPropagation();
301 e.stopPropagation();
302 if ($(e.target).is('a')) { return; }
302 if ($(e.target).is('a')) { return; }
303 var node = $(e.delegateTarget).first();
303 var node = $(e.delegateTarget).first();
304 var icon = $($(node.children().first()).children().first());
304 var icon = $($(node.children().first()).children().first());
305 var id = node.attr('fid');
305 var id = node.attr('fid');
306 var target = $('#'+id);
306 var target = $('#'+id);
307 var tr = $('#tr_'+id);
307 var tr = $('#tr_'+id);
308 var diff = $('#diff_'+id);
308 var diff = $('#diff_'+id);
309 if(node.hasClass('expand_file')){
309 if(node.hasClass('expand_file')){
310 node.removeClass('expand_file');
310 node.removeClass('expand_file');
311 icon.removeClass('expand_file_icon');
311 icon.removeClass('expand_file_icon');
312 node.addClass('collapse_file');
312 node.addClass('collapse_file');
313 icon.addClass('collapse_file_icon');
313 icon.addClass('collapse_file_icon');
314 diff.show();
314 diff.show();
315 tr.show();
315 tr.show();
316 target.show();
316 target.show();
317 } else {
317 } else {
318 node.removeClass('collapse_file');
318 node.removeClass('collapse_file');
319 icon.removeClass('collapse_file_icon');
319 icon.removeClass('collapse_file_icon');
320 node.addClass('expand_file');
320 node.addClass('expand_file');
321 icon.addClass('expand_file_icon');
321 icon.addClass('expand_file_icon');
322 diff.hide();
322 diff.hide();
323 tr.hide();
323 tr.hide();
324 target.hide();
324 target.hide();
325 }
325 }
326 });
326 });
327
327
328 $('#expand_all_files').click(function() {
328 $('#expand_all_files').click(function() {
329 $('.expand_file').each(function() {
329 $('.expand_file').each(function() {
330 var node = $(this);
330 var node = $(this);
331 var icon = $($(node.children().first()).children().first());
331 var icon = $($(node.children().first()).children().first());
332 var id = $(this).attr('fid');
332 var id = $(this).attr('fid');
333 var target = $('#'+id);
333 var target = $('#'+id);
334 var tr = $('#tr_'+id);
334 var tr = $('#tr_'+id);
335 var diff = $('#diff_'+id);
335 var diff = $('#diff_'+id);
336 node.removeClass('expand_file');
336 node.removeClass('expand_file');
337 icon.removeClass('expand_file_icon');
337 icon.removeClass('expand_file_icon');
338 node.addClass('collapse_file');
338 node.addClass('collapse_file');
339 icon.addClass('collapse_file_icon');
339 icon.addClass('collapse_file_icon');
340 diff.show();
340 diff.show();
341 tr.show();
341 tr.show();
342 target.show();
342 target.show();
343 });
343 });
344 });
344 });
345
345
346 $('#collapse_all_files').click(function() {
346 $('#collapse_all_files').click(function() {
347 $('.collapse_file').each(function() {
347 $('.collapse_file').each(function() {
348 var node = $(this);
348 var node = $(this);
349 var icon = $($(node.children().first()).children().first());
349 var icon = $($(node.children().first()).children().first());
350 var id = $(this).attr('fid');
350 var id = $(this).attr('fid');
351 var target = $('#'+id);
351 var target = $('#'+id);
352 var tr = $('#tr_'+id);
352 var tr = $('#tr_'+id);
353 var diff = $('#diff_'+id);
353 var diff = $('#diff_'+id);
354 node.removeClass('collapse_file');
354 node.removeClass('collapse_file');
355 icon.removeClass('collapse_file_icon');
355 icon.removeClass('collapse_file_icon');
356 node.addClass('expand_file');
356 node.addClass('expand_file');
357 icon.addClass('expand_file_icon');
357 icon.addClass('expand_file_icon');
358 diff.hide();
358 diff.hide();
359 tr.hide();
359 tr.hide();
360 target.hide();
360 target.hide();
361 });
361 });
362 });
362 });
363
363
364 // Mouse over behavior for comments and line selection
364 // Mouse over behavior for comments and line selection
365
365
366 // Select the line that comes from the url anchor
366 // Select the line that comes from the url anchor
367 // At the time of development, Chrome didn't seem to support jquery's :target
367 // At the time of development, Chrome didn't seem to support jquery's :target
368 // element, so I had to scroll manually
368 // element, so I had to scroll manually
369 if (location.hash) {
369 if (location.hash) {
370 var splitIx = location.hash.indexOf('/?/');
370 var splitIx = location.hash.indexOf('/?/');
371 if (splitIx !== -1){
371 if (splitIx !== -1){
372 var loc = location.hash.slice(0, splitIx);
372 var loc = location.hash.slice(0, splitIx);
373 var remainder = location.hash.slice(splitIx + 2);
373 var remainder = location.hash.slice(splitIx + 2);
374 }
374 }
375 else{
375 else{
376 var loc = location.hash;
376 var loc = location.hash;
377 var remainder = null;
377 var remainder = null;
378 }
378 }
379 if (loc.length > 1){
379 if (loc.length > 1){
380 var lineno = $(loc+'.lineno');
380 var lineno = $(loc+'.lineno');
381 if (lineno.length > 0){
381 if (lineno.length > 0){
382 var tr = lineno.parents('tr.line');
382 var tr = lineno.parents('tr.line');
383 tr.addClass('selected');
383 tr.addClass('selected');
384
384
385 tr[0].scrollIntoView();
385 tr[0].scrollIntoView();
386
386
387 $.Topic('/ui/plugins/code/anchor_focus').prepare({
387 $.Topic('/ui/plugins/code/anchor_focus').prepare({
388 tr:tr,
388 tr:tr,
389 remainder:remainder});
389 remainder:remainder});
390 }
390 }
391 }
391 }
392 }
392 }
393
393
394 collapsableContent();
394 collapsableContent();
395 });
395 });
General Comments 0
You need to be logged in to leave comments. Login now