diff --git a/public/js/cmtd.js b/public/js/cmtd.js
new file mode 100644
index 0000000..fd60796
--- /dev/null
+++ b/public/js/cmtd.js
@@ -0,0 +1,67 @@
+var base = 'http://cmtd.home.lan';
+
+$(document).ready(function(){
+ $('')
+ .attr({'href': base +'/css/main.css', 'rel': 'stylesheet'})
+ .appendTo('head');
+ $('#comments').load(base + '/comments/list', function() {
+ $('#cmtd_main a.c_add').on('click', function (e) {
+ e.preventDefault();
+ $('#cmtd_main #no_comments_notice').remove();
+ $('#cmtd_main #comment_add').remove();
+ load_comment_form(e.target);
+ });
+ });
+});
+
+
+function load_comment_form(elem) {
+ $.get(base + '/comments/add', function(content) {
+ $('#cmtd_main').append(content);
+ if (reply = $(elem).data('cid')) {
+ $('#cmtd_main form input[name=reply]').attr({'value': reply});
+ }
+ $('#cmtd_main form').attr({'action': base + '/comments/add'});
+ $('#cmtd_main form').on('submit', function(e) {
+ e.preventDefault();
+ if ($('#cmtd_captcha img').length == 0) {
+ update_captcha();
+ return;
+ }
+ var data = $(this).serialize();
+ $.ajax(base + '/comments/add', {
+ 'success': function() { location.reload() },
+ 'error': function(resp) {
+ update_captcha();
+ $('span#resp').text(resp.responseText);
+ },
+ 'type': 'POST',
+ 'data': data,
+ }); // post
+ }); // on submit
+ });
+}
+
+function update_captcha() {
+ $('#cmtd_captcha').hide().empty();
+ $.getJSON(base + '/captcha', function(data) {
+ if (!data['cid'])
+ return;
+ var img = $('')
+ .attr({'src': data['data']})
+ .appendTo('#cmtd_captcha');
+ $(img).load(function(){
+ var w = $(img).prop('width');
+ var h = $(img).prop('height');
+ $('')
+ .attr({'name': 'cid', 'type': 'hidden', 'value': data['cid']})
+ .appendTo('#cmtd_captcha');
+ $('')
+ .attr({'name': 'code', 'type': 'text'})
+ .attr({'placeholder': '<< enter this code'})
+ .css({'width': w, 'height': h, 'margin-left': '5px'})
+ .appendTo('#cmtd_captcha');
+ $('#cmtd_captcha').show();
+ }); // load()
+ }); // get captcha
+}