1/*! Orphus.js | by Dmitry Koterov & Proger_XP | orphus.ru | proger.me */ 2// uglifyjs -c -m --comments '/^!/' --source-map --warn orphus.js -o orphus-min.js 3;(function () { 4 "use strict"; 5 6 var user = window.orphus || {} 7 var self = window.orphus = {} 8 9 self.opt = { 10 version: '6.0.23', 11 // If prefixed with '!', the value is obfuscated by swapping every second 12 // character, e.g. '[email protected]' == '[email protected]'. 13 email: '[email protected]', 14 homepage: 'https://github.com/ProgerXP/Orphus', 15 c_tag1: '<!!!>', 16 c_tag2: '<!!!>', 17 contextLength: 60, // max length of ?c_pre and ?c_suf. 18 maxSelection: 256, // max ?c_sel. 19 action: '/orphus/', 20 maxWidth: 650, // of <div id="orphusp">. 21 strings: { // localizable. 22 alt: 'ÐÑделиÑе оÑÑогÑаÑиÑеÑкÑÑ Ð¾ÑÐ¸Ð±ÐºÑ Ð¼ÑÑÑÑ Ð¸ нажмиÑе Ctrl+Enter. Сделаем наÑи ÑекÑÑÑ ÑиÑе!', 23 badbrowser: 'ÐÐ°Ñ Ð±ÑаÑÐ·ÐµÑ Ð½Ðµ поддеÑÐ¶Ð¸Ð²Ð°ÐµÑ Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑÑ Ð¿ÐµÑÐµÑ Ð²Ð°Ñа вÑделенного ÑекÑÑа или IFRAME. Ðозможно, он ÑлиÑком ÑÑаÑÑй, а, Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ, пÑоизоÑла какаÑ-нибÑÐ´Ñ Ð´ÑÑÐ³Ð°Ñ Ð¾Ñибка.', 24 toobig: 'ÐÑ Ð²ÑбÑали ÑлиÑком болÑÑой ÑÑÐ°Ð³Ð¼ÐµÐ½Ñ ÑекÑÑа.', 25 subject: 'СообÑение Ð¾Ñ Orphus', 26 intextmsg: 'ÐÑÑогÑаÑиÑеÑÐºÐ°Ñ Ð¾Ñибка в ÑÑом ÑÑагменÑе:', 27 ifsendmsg: 'ÐоÑлаÑÑ ÑообÑение об оÑибке авÑоÑам? ÐÐ°Ñ Ð±ÑаÑÐ·ÐµÑ Ð¾ÑÑанеÑÑÑ Ð½Ð° ÑÑой же ÑÑÑаниÑе.', 28 gohome: 'Ðли, можеÑ, Ð²Ñ Ñ Ð¾ÑиÑе поÑеÑиÑÑ Ð´Ð¾Ð¼Ð°ÑнÑÑ ÑÑÑаниÑÑ Orphus (в новой вкладке)?', 29 author: 'ÐмиÑÑий ÐоÑеÑов и Proger_XP', 30 send: 'ÐÑпÑавиÑÑ', 31 cancel: 'ÐÑмена', 32 entercmnt: 'ÐÐ°Ñ ÐºÐ¾Ð¼Ð¼ÐµÐ½ÑаÑий (необÑзаÑелÑно):', 33 submitex: 'ÐÑоблема пÑи оÑпÑавке ÑообÑениÑ:' 34 } 35 } 36 37 var assign = function (dest, src) { 38 for (var k in src) { 39 if (k == 'strings') { 40 assign(dest[k], src[k]) 41 } else { 42 dest[k] = src[k] 43 } 44 } 45 } 46 47 assign(self.opt, user) 48 49 var docEl = document.documentElement 50 var body = document.body 51 52 self.iframe = null 53 self.submitted = false 54 self.lastComment = '' 55 56 self.deobfuscate = function (s) { 57 if (s.substr(0, 1) == '!') { 58 s = s.substr(1).replace(/(.)(.)/g, '$2$1') 59 } 60 return s 61 } 62 63 self.run = function () { 64 document.onkeypress = self.onkeypress 65 } 66 67 self.addOffScreen = function (node) { 68 node.style.position = 'absolute' 69 node.style.top = '-10000px' 70 body.lastChild 71 ? body.insertBefore(node, body.lastChild) 72 : body.appendChild(node) 73 return node 74 } 75 76 self.createIFrame = function (name) { 77 var div = document.createElement('DIV') 78 div.innerHTML = '<iframe name="' + name + '"></iframe>' 79 return self.addOffScreen(div) 80 } 81 82 self.submit = function (refURL, sel, comment) { 83 var name = 'orphus_ifr' 84 self.iframe = self.iframe || self.createIFrame(name) 85 86 var form = document.createElement('FORM') 87 form.action = self.opt.action 88 form.method = 'post' 89 form.target = name 90 91 var query = { 92 version: self.opt.version, 93 email: self.deobfuscate(self.opt.email), 94 to: self.opt.strings.to, 95 subject: self.opt.strings.subject, 96 ref: refURL, 97 c_pre: sel.pre, 98 c_sel: sel.text, 99 c_suf: sel.suf, 100 c_pos: sel.pos, 101 c_tag1: self.opt.c_tag1, 102 c_tag2: self.opt.c_tag2, 103 charset: document.charset || document.characterSet || '', 104 comment: comment 105 } 106 107 for (var name in query) { 108 var input = document.createElement('INPUT') 109 input.type = 'hidden' 110 input.name = name 111 input.value = query[name] 112 form.appendChild(input) 113 } 114 115 self.addOffScreen(form) 116 form.submit() 117 form.parentNode.removeChild(form) 118 } 119 120 self.windowInfo = function () { 121 var width = 0 122 var height = 0 123 124 if (typeof window.innerWidth == 'number') { 125 width = window.innerWidth 126 height = window.innerHeight 127 } else if (docEl && (docEl.clientWidth || docEl.clientHeight)) { 128 width = docEl.clientWidth 129 height = docEl.clientHeight 130 } else if (body && (body.clientWidth || body.clientHeight)) { 131 width = body.clientWidth 132 height = body.clientHeight 133 } 134 135 var scrollLeft = 0 136 var scrollTop = 0 137 138 if (typeof window.pageYOffset == 'number') { 139 scrollTop = window.pageYOffset 140 scrollLeft = window.pageXOffset 141 } else if (body && (body.scrollLeft || body.scrollTop)) { 142 scrollTop = body.scrollTop 143 scrollLeft = body.scrollLeft 144 } else if (docEl && (docEl.scrollLeft || docEl.scrollTop)) { 145 scrollTop = docEl.scrollTop 146 scrollLeft = docEl.scrollLeft 147 } 148 149 return { 150 width: width, 151 height: height, 152 scrollLeft: scrollLeft, 153 scrollTop: scrollTop 154 } 155 } 156 157 self.showFor = function (context, submit) { 158 if (self.submitted) { return } 159 160 self.submitted = true 161 var div = document.createElement('DIV') 162 var width = Math.min(self.opt.maxWidth, body.clientWidth) 163 164 div.innerHTML = 165 '<div id="orphusp" style="width: ' + width + 'px">' + 166 '<a class="logo" href="' + self.opt.homepage + '" target="_blank">Orphus</a>' + 167 '<div class="legend">' + self.opt.strings.intextmsg + '</div>' + 168 '<div class="fragment">' + 169 context 170 .replace(self.opt.c_tag1, '<mark>') 171 .replace(self.opt.c_tag2, '</mark>') + 172 '</div>' + 173 '<div class="hint">' + 174 self.opt.strings.ifsendmsg.replace(/\r?\n/, '<br>') + 175 '</div>' + 176 '<form>' + 177 '<div class="comment">' + self.opt.strings.entercmnt + '</div>' + 178 '<input type="text" maxlength="250">' + 179 '<div class="buttons">' + 180 '<input type="submit" value="' + self.opt.strings.send + '">' + 181 ' ' + 182 '<input type="button" value="' + self.opt.strings.cancel + '">' + 183 '</div>' + 184 '</form>' + 185 '</div>' 186 187 self.addOffScreen(div) 188 var inputs = div.getElementsByTagName('input') 189 var forms = div.getElementsByTagName('form') 190 var commentInput = inputs[0] 191 var origOnKeyDown = null 192 193 var end = function () { 194 document.onkeydown = origOnKeyDown 195 origOnKeyDown = null 196 div.parentNode.removeChild(div) 197 self.submitted = false 198 self.lastComment = commentInput.value 199 } 200 201 setTimeout(function () { 202 var divWidth = div.clientWidth 203 var divHeight = div.clientHeight 204 var win = self.windowInfo() 205 206 var x = (win.width - divWidth) / 2 + win.scrollLeft 207 var y = (win.height - divHeight) / 2 + win.scrollTop 208 div.style.left = x + 'px' 209 div.style.top = y + 'px' 210 211 commentInput.value = self.lastComment 212 commentInput.focus() 213 commentInput.select() 214 origOnKeyDown = document.onkeydown 215 216 document.onkeydown = function (e) { 217 e = e || window.event 218 if (e.keyCode == 27) { end() } 219 } 220 221 forms[0].onsubmit = function () { 222 try { 223 submit(commentInput.value) 224 } catch (e) { 225 alert(self.opt.strings.submitex + '\n\n' + e) 226 } 227 end() 228 self.lastComment = '' 229 return false 230 } 231 232 inputs[2].onclick = end 233 }, 10) 234 } 235 236 self.cleanString = function (s) { 237 return ('' + s).replace(/[\r\n]+/g, ' ').replace(/^\s+|\s+$/g, '') 238 } 239 240 self.getSelection = function () { 241 var docSel = null 242 243 if (window.getSelection) { 244 docSel = window.getSelection() 245 } else if (document.getSelection) { 246 docSel = document.getSelection() 247 } else { 248 docSel = document.selection 249 } 250 251 if (docSel == null) { throw 'null getSelection()' } 252 253 var pre = '' 254 var text = null 255 var suf = '' 256 var pos = -1 257 258 if (docSel.getRangeAt) { 259 if (!docSel.rangeCount) { return } 260 var range = docSel.getRangeAt(0) 261 text = range.toString() 262 var newRange = document.createRange() 263 newRange.setStartBefore(range.startContainer.ownerDocument.body) 264 newRange.setEnd(range.startContainer, range.startOffset) 265 pre = newRange.toString() 266 var newRange = range.cloneRange() 267 newRange.setStart(range.endContainer, range.endOffset) 268 newRange.setEndAfter(range.endContainer.ownerDocument.body) 269 suf = newRange.toString() 270 } else if (docSel.createRange) { 271 var range = docSel.createRange() 272 text = range.text 273 var newRange = docSel.createRange() 274 newRange.moveStart('character', -self.opt.contextLength) 275 newRange.moveEnd('character', -text.length) 276 pre = newRange.text 277 var newRange = docSel.createRange() 278 newRange.moveEnd('character', self.opt.contextLength) 279 newRange.moveStart('character', text.length) 280 suf = newRange.text 281 } else { 282 text = '' + docSel 283 } 284 285 var p 286 var s = (p = text.match(/^(\s*)/)) && p[0].length 287 var e = (p = text.match(/(\s*)$/)) && p[0].length 288 pre = pre + text.substring(0, s) 289 suf = text.substring(text.length - e, text.length) + suf 290 text = text.substring(s, text.length - e) 291 292 if (text != '') { 293 return { 294 pre: pre, 295 text: text, 296 suf: suf, 297 pos: pos 298 } 299 } 300 } 301 302 self.show = function () { 303 try { 304 var sel = self.getSelection() 305 } catch (e) { 306 alert(self.opt.strings.badbrowser) 307 return 308 } 309 310 if (!sel) { 311 var msg = [ 312 self.opt.strings.name + ' v' + self.opt.version, 313 self.opt.strings.author, 314 '', 315 self.opt.strings.alt, 316 '', 317 self.opt.strings.gohome, 318 ] 319 320 if (confirm(msg.join('\n'))) { 321 window.open(self.opt.homepage, '_blank') 322 } 323 324 return 325 } 326 327 sel.pre = sel.pre.substring(sel.pre.length - self.opt.contextLength, sel.pre.length).replace(/^\S{1,10}\s+/, '') 328 sel.suf = sel.suf.substring(0, self.opt.contextLength).replace(/\s+\S{1,10}$/, '') 329 var context = self.cleanString(sel.pre + self.opt.c_tag1 + sel.text + self.opt.c_tag2 + sel.suf) 330 331 if (context.length > self.opt.maxSelection) { 332 alert(self.opt.strings.toobig) 333 } else { 334 self.showFor(context, function (comment) { 335 self.submit(document.location.href, sel, comment) 336 }) 337 } 338 } 339 340 self.onkeypress = function (e) { 341 var handle = false 342 var we = window.event 343 344 if (we) { 345 handle = we.keyCode == 10 || (we.keyCode == 13 && we.ctrlKey) 346 } else if (e) { 347 handle = (e.which == 10 && e.modifiers == 2) || 348 (e.keyCode == 0 && e.charCode == 106 && e.ctrlKey) || 349 (e.keyCode == 13 && e.ctrlKey) 350 } 351 352 if (handle) { 353 self.show() 354 return false 355 } 356 } 357 358 self.run() 359})();
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.