1$(function() { 2 const sendButton = $("#sendButton"); 3 const encryptButton = $("#encryptButton"); 4 const sendButtonText = $("#sendButtonText"); 5 const socialButtons = $(".btn-social"); 6 const inputFields = $(".input-field"); 7 const nameField = $("#inputYourName"); 8 const emailField = $("#inputYourEmail"); 9 const messageField = $("#inputMessage"); 10 const captchaWrapper = $("#captchaWrapper"); 11 const badCaptchaAlert = $("#badCapchaAlert"); 12 const sendErrorAlert = $("#sendErrorAlert"); 13 const PGPKey = $("#PGPKey"); 14 15 const sendButtonIcon = function() { 16 return $("#sendButtonIcon"); 17 }; 18 19 socialButtons.mouseup(function(){ 20 $(this).blur(); 21 }); 22 PGPKey.focus(function() { 23 $(this).select(); 24 }); 25 messageField.bind('input propertychange', function() { 26 encryptButton.prop('disabled', $(this).val().length === 0); 27 }); 28 29 sendButton.click(function() { 30 badCaptchaAlert.slideUp(); 31 sendErrorAlert.slideUp(); 32 inputFields.each(function() { 33 $(this).removeClass('is-invalid'); 34 }); 35 36 let errors = 0; 37 inputFields.each(function(i) { 38 if ($(this).val().length === 0) { 39 $(this).addClass('is-invalid'); 40 if (errors === 0) { 41 $(this).focus(); 42 } 43 errors++; 44 } 45 }); 46 47 if (errors === 0 && grecaptcha.getResponse().length === 0) { 48 grecaptcha.reset(); 49 badCaptchaAlert.slideDown(); 50 errors++; 51 } 52 53 if (errors === 0) { 54 sendButton.prop('disabled', true); 55 encryptButton.prop('disabled', true); 56 sendButtonIcon().removeClass('fa-envelope').addClass('fa-spinner fa-spin'); 57 58 $.ajax({ 59 url: "api/contact/send", 60 method: "POST", 61 data: { 62 name: nameField.val(), 63 email: emailField.val(), 64 message: messageField.val(), 65 captcha: grecaptcha.getResponse() 66 }, 67 success: function(data) { 68 console.log(data); 69 70 sendButton.removeClass('btn-primary').addClass('btn-success'); 71 sendButtonIcon().removeClass('fa-spinner fa-spin').addClass('fa-check'); 72 sendButtonText.text("Thanks for your message!"); 73 captchaWrapper.slideUp(); 74 75 inputFields.each(function() { 76 $(this).val(""); 77 $(this).prop('readonly', true); 78 }); 79 80 }, 81 error: function(data) { 82 sendButton.prop('disabled', false); 83 encryptButton.prop('disabled', true); 84 sendButtonIcon().removeClass('fa-spinner fa-spin').addClass('fa-envelope'); 85 86 console.log(data);
87 if (data.responseJSON.code === "INVALID_NAME") { 88 nameField.addClass('is-invalid'); 89 nameField.focus(); 90 } 91 else if (data.responseJSON.code === "INVALID_EMAIL") { 92 emailField.addClass('is-invalid'); 93 emailField.focus(); 94 } 95 else if (data.responseJSON.code === "BAD_CAPTCHA") { 96 grecaptcha.reset(); 97 badCaptchaAlert.slideDown(); 98 } 99 else { 100 grecaptcha.reset(); 101 sendErrorAlert.slideDown(); 102 } 103 } 104 }); 105 } 106 }); 107 108 encryptButton.click(function() { 109 encryptButton.prop('disabled', true); 110 openpgp.encrypt({ 111 data: messageField.val(), 112 publicKeys: openpgp.key.readArmored($("#PGPKey").val()).keys 113 }).then(function(result) { 114 let lines = result.data.split("\n"); 115 lines.splice(1, 2); 116 let message = lines.join("\n"); 117 messageField.val(message); 118 }); 119 }); 120});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.