{"id":201010,"date":"2013-11-06T10:04:03","date_gmt":"2013-11-06T06:04:03","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=201010"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=201010","title":{"rendered":"<span class=\"post_title\">FileAPI 2.0: \u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0444\u0430\u0439\u043b\u043e\u0432 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440 \u0433\u043e\u0434 \u0441\u043f\u0443\u0441\u0442\u044f<\/span>"},"content":{"rendered":"<div class=\"content html_format\">   \t<img decoding=\"async\" src=\"http:\/\/habr.habrastorage.org\/post_images\/c9e\/c06\/907\/c9ec069077a789d6569e563c618cb43f.png\" alt=\"FileAPI 2.0\" align=\"right\"\/>\u041f\u0440\u0438\u0432\u0435\u0442 \u0425\u0430\u0431\u0440! \u041f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0433\u043e\u0434 \u043d\u0430\u0437\u0430\u0434 \u044f \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043b \u0432\u0430\u0448\u0435\u043c\u0443 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044e \u043f\u0435\u0440\u0432\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e <a href=\"http:\/\/habrahabr.ru\/company\/mailru\/blog\/159587\/\">open-source \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 FileAPI<\/a>, \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u0443\u044e \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0444\u0430\u0439\u043b\u0430\u043c\u0438 \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0435 \u0438 \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440.<\/p>\n<p>   \u0417\u0430 \u044d\u0442\u043e \u0432\u0440\u0435\u043c\u044f \u0431\u044b\u043b \u043f\u0440\u043e\u0439\u0434\u0435\u043d \u0434\u043e\u043b\u0433\u0438\u0439 \u043f\u0443\u0442\u044c. \u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0437\u0430\u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0430 <a href=\"https:\/\/github.com\/mailru\/FileAPI\/stargazers\">670+<\/a>&nbsp;\u0437\u0432\u0435\u0437\u0434 \u0438 <a href=\"https:\/\/github.com\/mailru\/FileAPI\/network\/members\">90+<\/a>&nbsp;\u0444\u043e\u0440\u043a\u043e\u0432. \u0421 \u043f\u043e\u043c\u043e\u0449\u044c\u044e github-\u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u0430 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u00ab\u0434\u0435\u0442\u0441\u043a\u0438\u0445\u00bb \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u0438 \u0432\u043d\u0435\u0441\u0442\u0438 \u0440\u044f\u0434 \u0443\u043b\u0443\u0447\u0448\u0435\u043d\u0438\u0439. \u0411\u044b\u043b\u043e \u0437\u0430\u043a\u0440\u044b\u0442\u043e \u0431\u043e\u043b\u0435\u0435 <a href=\"https:\/\/github.com\/mailru\/FileAPI\/issues?sort=created&amp;state=closed\">100<\/a>&nbsp;\u0442\u0430\u0441\u043a\u043e\u0432, \u0438 \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u0418\u043b\u044c\u0435 \u041b\u0435\u0431\u0435\u0434\u0435\u0432\u0443 \u0441\u0434\u0435\u043b\u0430\u043d\u0430 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0444\u0430\u0439\u043b\u043e\u0432 \u043f\u043e \u0447\u0430\u0441\u0442\u044f\u043c. \u0421\u0435\u0433\u043e\u0434\u043d\u044f \u044f \u0441 \u0433\u043e\u0440\u0434\u043e\u0441\u0442\u044c\u044e \u0445\u043e\u0447\u0443 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0432\u0430\u043c <a href=\"http:\/\/mailru.github.io\/FileAPI\/\">FileAPI 2.0<\/a>.<a name=\"habracut\"><\/a><\/p>\n<p>  \u0418\u0442\u0430\u043a, \u043f\u0435\u0440\u0432\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f \u043e\u0431\u043b\u0430\u0434\u0430\u043b\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c\u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044f\u043c\u0438:<\/p>\n<ul>\n<li>\u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0432\u044b\u0431\u043e\u0440 \u0444\u0430\u0439\u043b\u043e\u0432;<\/li>\n<li>\u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 (\u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435, \u0440\u0430\u0437\u043c\u0435\u0440 \u0438 mime-\u0442\u0438\u043f);<\/li>\n<li>\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043f\u0440\u0435\u0434\u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430 \u0434\u043e \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438;<\/li>\n<li>\u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435, \u043a\u0430\u0434\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438 \u043f\u043e\u0432\u043e\u0440\u043e\u0442 \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0435;<\/li>\n<li>\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0432\u0441\u0435\u0433\u043e, \u0447\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c, \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440 + CORS;<\/li>\n<li>\u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 \u0432\u0441\u0435\u0433\u043e \u0432\u044b\u0448\u0435\u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0432 \u0441\u0442\u0430\u0440\u044b\u0445 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430\u0445, \u0432\u043a\u043b\u044e\u0447\u0430\u044f IE6.<\/li>\n<\/ul>\n<p>  \u0414\u043b\u044f \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438 \u0441\u0442\u0430\u0440\u044b\u0445 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u043e\u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f Flash. \u0412 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u043e\u0442 \u0434\u0440\u0443\u0433\u0438\u0445 \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0445 \u0440\u0435\u0448\u0435\u043d\u0438\u0439, \u0433\u0434\u0435 \u043d\u0443\u0436\u043d\u043e \u044f\u0432\u043d\u044b\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u0437\u0430\u0434\u0430\u0442\u044c \u044d\u043b\u0435\u043c\u0435\u043d\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043a\u043d\u043e\u043f\u043a\u043e\u0439 \u00ab\u0412\u044b\u0431\u0440\u0430\u0442\u044c \u0444\u0430\u0439\u043b\u044b\u00bb, FileAPI \u043d\u0435 \u043d\u0430\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u0442 \u0442\u0430\u043a\u0438\u0445 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0439. \u0420\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0443 \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u0434\u0443\u043c\u0430\u0442\u044c \u043e \u0442\u043e\u043c, \u043a\u0430\u043a\u0443\u044e \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u044e \u0432 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 \u043a\u043e\u0434 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u043f\u0440\u0438\u0431\u043b\u0438\u0436\u0435\u043d \u043a \u043d\u0430\u0442\u0438\u0432\u043d\u043e\u043c\u0443, \u0442.\u0435. HTML5:<\/p>\n<pre><code class=\"html\">&lt;span class=&quot;js-fileapi-wrapper&quot;&gt;     &lt;input id=&quot;file&quot; type=&quot;file&quot; multiple \/&gt; &lt;\/span&gt; &lt;script&gt;     var input = document.getElementById(&quot;file&quot;);     FileAPI.event.on(input, &quot;change&quot;, function (){         var list = FileAPI.getFiles(input); \/\/ \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0441\u043f\u0438\u0441\u043e\u043a \u0444\u0430\u0439\u043b\u043e\u0432              \/\/ \u0417\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440         FileAPI.upload({              url: &quot;.\/ctrl.php&quot;,              files: { userFiles: list },              complete: function (err, xhr){ \/*...*\/ }         });     }); &lt;\/script&gt;<\/code><\/pre>\n<p>  \u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430 \u0438, \u0435\u0441\u043b\u0438 \u0447\u0435\u0433\u043e-\u0442\u043e \u043d\u0435 \u0445\u0432\u0430\u0442\u0430\u0435\u0442, \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u043d\u0430 Flash. <\/p>\n<p>  \u041f\u043e\u0447\u0442\u0438 \u0441\u0440\u0430\u0437\u0443 \u043f\u043e\u0441\u043b\u0435 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438 \u044f \u043d\u0430\u0447\u0430\u043b \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u043f\u0435\u0440\u0432\u044b\u0435 \u043e\u0442\u0437\u044b\u0432\u044b \u0438 \u043f\u043e\u0436\u0435\u043b\u0430\u043d\u0438\u044f, \u043f\u0440\u0438\u0432\u0435\u0434\u0443 \u0441\u0430\u043c\u044b\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0435 \u0438\u0437 \u043d\u0438\u0445.<\/p>\n<h5>\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u043e\u0431\u0444\u0443\u0441\u043a\u0430\u0446\u0438\u0438<\/h5>\n<p>\u0423 \u043e\u0434\u043d\u043e\u0433\u043e \u044e\u0437\u0435\u0440\u0430 \u043a\u043e\u0434 \u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u043b, \u0441\u043e\u0432\u0441\u0435\u043c. \u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0431\u044b\u043b\u0430 \u0432 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 <code>(api.expando + ++gid)<\/code>. \u041e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c, \u0435\u0433\u043e \u043e\u0431\u0444\u0443\u0441\u043a\u0430\u0442\u043e\u0440 \u043d\u0435 \u043f\u043e\u043d\u0438\u043c\u0430\u043b \u0435\u0451 \u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u0443\u0431\u0438\u0440\u0430\u043b \u043f\u0440\u043e\u0431\u0435\u043b\u044b, \u0447\u0442\u043e \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u043b\u043e \u043a \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u043e\u0448\u0438\u0431\u043a\u0435, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043a\u043e\u0434 \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u043d\u0430 <code>(++gid, api.expando + gid)<\/code>. <\/p>\n<h5>\u041e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438 \u0441 Amazon S3<\/h5>\n<p>\u041f\u0440\u0438 \u0432\u044b\u0437\u043e\u0432\u0435 \u043c\u0435\u0442\u043e\u0434\u0430 FileAPI.upload \u043a url, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0443\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441, \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0439 GET-\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440, \u0447\u0442\u043e\u0431\u044b \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u043a\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f POST-\u043f\u043e\u0441\u0442 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043d\u0430 \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u044b\u0445 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430\u0445. \u0410 \u043f\u0440\u0438 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438 \u0441 Amazon S3 \u0432\u044b\u044f\u0441\u043d\u0438\u043b\u043e\u0441\u044c, \u0447\u0442\u043e \u043e\u043d \u043d\u0435 \u0434\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u0442 GET-\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b. \u0422\u0430\u043a \u043a\u0430\u043a \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0441 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e\u0439 \u0442\u043e\u0447\u043d\u043e\u0441\u0442\u044c\u044e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u0432\u0441\u0435 \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u044b\u0435 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u043f\u043e user-agent, \u0432 upload \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0430 \u043e\u043f\u0446\u0438\u044f cache, \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043c\u043e\u0436\u043d\u043e \u0432\u043b\u0438\u044f\u0442\u044c \u043d\u0430 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0433\u043e GET-\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430.<\/p>\n<h5>\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f\u043c\u0438<\/h5>\n<p>\u0412\u0441\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043f\u0440\u0438\u043d\u0443\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043b\u0438\u0441\u044c \u0432 png, \u0447\u0442\u043e \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u043b\u043e \u043a \u0443\u0432\u043b\u0435\u0447\u0435\u043d\u0438\u044e \u0440\u0430\u0437\u043c\u0435\u0440\u0430 \u0444\u0430\u0439\u043b\u0430 \u043d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435, \u043a \u0442\u043e\u043c\u0443 \u0436\u0435 \u043c\u0435\u043d\u044f\u043b\u0441\u044f \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u0442\u0438\u043f, \u0447\u0442\u043e \u0431\u044b\u043b\u043e \u043a\u0440\u0438\u0442\u0438\u0447\u043d\u043e \u0434\u043b\u044f \u043c\u043d\u043e\u0433\u0438\u0445 \u0437\u0430\u0434\u0430\u0447. \u041f\u043e\u043c\u0438\u043c\u043e \u044d\u0442\u043e\u0433\u043e, \u0447\u0430\u0441\u0442\u043e \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432\u043e\u0434\u044f\u043d\u043e\u0439 \u0437\u043d\u0430\u043a \u0432 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c\u043e\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0438\u043b\u0438 \u0441\u0444\u043e\u0442\u043e\u0433\u0440\u0430\u0444\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u00ab\u0441\u0435\u0431\u044f\u00bb \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 WebCam.<\/p>\n<h5>\u00ab\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430\u00bb \u0431\u0435\u0437 \u0444\u0430\u0439\u043b\u043e\u0432<\/h5>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a API \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u043b\u043e\u0441\u044c \u0434\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0444\u0430\u0439\u043b\u043e\u0432, \u0442\u043e \u043c\u0435\u0442\u043e\u0434 <code>FileAPI.upload<\/code> \u0432\u044b\u0434\u0430\u0432\u0430\u043b \u043e\u0448\u0438\u0431\u043a\u0443 \u043f\u0440\u0438 \u0432\u044b\u0437\u043e\u0432\u0435 \u0435\u0433\u043e \u0431\u0435\u0437 \u0441\u0430\u043c\u0438\u0445 \u0444\u0430\u0439\u043b\u043e\u0432. \u041a\u0430\u043a \u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c, \u044d\u0442\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0447\u0430\u0441\u0442\u044b\u0439 \u0441\u043b\u0443\u0447\u0430\u0439. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043a\u043e\u0433\u0434\u0430 \u0443 \u0432\u0430\u0441 \u0435\u0441\u0442\u044c \u0444\u043e\u0440\u043c\u0430, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043f\u043e\u043b\u0435 \u00ab\u0444\u0430\u0439\u043b\u00bb \u043d\u0435\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e.<\/p>\n<p>  \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u0441\u043b\u0430\u0431\u0430\u044f \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f \u0438 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u043a\u043e\u0434\u0430 \u0432 \u043d\u0435\u0441\u0436\u0430\u0442\u043e\u043c \u0432\u0438\u0434\u0435 (\u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0438 \u0431\u044b\u043b\u0438, \u043d\u043e \u0441\u0436\u0438\u043c\u0430\u043b\u0438\u0441\u044c \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u044c \u0441\u0432\u043e\u0435\u0433\u043e \u00ab\u0432\u0435\u043b\u043e\u0441\u0438\u043f\u0435\u0434\u0430\u00bb) \u0437\u0430\u0442\u0440\u0443\u0434\u043d\u044f\u043b\u043e \u043e\u0442\u043b\u0430\u0434\u043a\u0443 \u0438 \u0432\u043d\u0435\u0441\u0435\u043d\u0438\u0435 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0445 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439. \u041e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u044e\u043d\u0438\u0442-\u0442\u0435\u0441\u0442\u043e\u0432 \u0441\u0438\u043b\u044c\u043d\u043e \u0441\u043a\u0430\u0437\u044b\u0432\u0430\u043b\u043e\u0441\u044c \u043d\u0430 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0438 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438. \u041a\u0430\u043a \u044d\u0442\u043e \u043d\u0435 \u0443\u0434\u0438\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e, \u043d\u043e \u043c\u043d\u043e\u0433\u0438\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u043d\u0438\u0437\u043a\u043e\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u043e\u0435 API \u0438 \u043a\u0430\u0436\u0434\u044b\u0439 \u0438\u0437 \u043d\u0438\u0445 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u043f\u0438\u0441\u0430\u0442\u044c \u043a\u0430\u043a\u0443\u044e-\u0442\u043e \u0441\u0432\u043e\u044e \u043e\u0431\u0435\u0440\u0442\u043a\u0443, \u0432 \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0435 \u0441\u043b\u0443\u0447\u0430\u0435\u0432 jQuery plugin. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0443\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0438\u0442\u044c \u0433\u043e\u0442\u043e\u0432\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0431\u044b \u043e\u0445\u0432\u0430\u0442\u044b\u0432\u0430\u043b\u043e \u0432\u0441\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0437\u0430\u0434\u0430\u0447\u0438.<\/p>\n<p>  \u0421\u043e\u0431\u0440\u0430\u0432 \u0438 \u043f\u0440\u043e\u0430\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0432 \u043e\u0442\u0437\u044b\u0432\u044b, \u0431\u044b\u043b \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d \u043f\u043b\u0430\u043d \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439:<\/p>\n<ul>\n<li><b>Grunt<\/b> \u2014 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0434\u043b\u044f \u0441\u0431\u043e\u0440\u043a\u0438 \u043a\u043e\u0434\u0430;<\/li>\n<li><b>QUnit<\/b> \u2014 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0433\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430 (Grunt + PhantomJS);<\/li>\n<li><b>\u0424\u0438\u0447\u0438<\/b> \u2014 \u0443\u043b\u0443\u0447\u0448\u0435\u043d\u043d\u0430\u044f \u0440\u0430\u0431\u043e\u0442\u0430 \u0441 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f\u043c\u0438 \u0438 WebCam;<\/li>\n<li><b>jQuery plugin<\/b> \u2014 \u0441\u0443\u043f\u0435\u0440-\u043f\u0443\u043f\u0435\u0440 \u043f\u043b\u0430\u0433\u0438\u043d \u0434\u043b\u044f \u0442\u0438\u043f\u043e\u0432\u044b\u0445 \u0437\u0430\u0434\u0430\u0447;<\/li>\n<li><b>\u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f<\/b> \u2014 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u0438 \u043f\u0440\u0438\u043c\u0435\u0440\u044b.<\/li>\n<\/ul>\n<p>  <\/p>\n<h3>Grunt<\/h3>\n<p>  \u041a\u0430\u043a \u044f \u0443\u0436\u0435 \u0433\u043e\u0432\u043e\u0440\u0438\u043b, \u0432 \u043f\u0435\u0440\u0432\u044b\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 js \u0441\u043e\u0431\u0438\u0440\u0430\u043b\u0441\u044f \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u0441\u043a\u0440\u0438\u043f\u0442\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u043b\u0438\u0432\u0430\u043b \u0438 \u043e\u0431\u0444\u0443\u0446\u0438\u0440\u043e\u0432\u0430\u043b 6 \u0444\u0430\u0439\u043b\u043e\u0432 \u0432 \u043e\u0434\u0438\u043d. \u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0432\u043d\u043e\u0441\u0438\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0438\u043b\u0438 \u0434\u0435\u0431\u0430\u0436\u0438\u0442\u044c \u043a\u043e\u0434, \u043d\u0443\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c 6 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u043e\u0432 \u0432 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u043c \u043f\u043e\u0440\u044f\u0434\u043a\u0435. \u042d\u0442\u043e \u043d\u0435\u0443\u0434\u043e\u0431\u043d\u043e, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043b\u0441\u044f \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0434\u043b\u044f \u0441\u0431\u043e\u0440\u043a\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430. \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0442\u0430\u043a\u043e\u0433\u043e \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430 \u0431\u044b\u043b \u0432\u044b\u0431\u0440\u0430\u043d <a href=\"http:\/\/gruntjs.com\/\">Grunt<\/a>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u0435-\u0444\u0430\u043a\u0442\u043e \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043e\u043c \u043f\u0440\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0438 \u0441\u0431\u043e\u0440\u043a\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430. \u0421 \u0435\u0433\u043e \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u044b \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u043c FileAPI, \u043d\u043e \u0438 \u043f\u0440\u043e\u0433\u043e\u043d\u044f\u0435\u043c \u0435\u0435 \u043a\u043e\u0434 \u0447\u0435\u0440\u0435\u0437 <a href=\"http:\/\/www.jshint.com\/about\/\">JSHint<\/a> \u0438 <a href=\"http:\/\/qunitjs.com\/\">QUnit<\/a>-\u0442\u0435\u0441\u0442\u044b, \u043e \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u0434\u0430\u043b\u044c\u0448\u0435. \u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043d\u0430\u0447\u0430\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Grunt, \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0434\u0432\u0430 \u0444\u0430\u0439\u043b\u0430: package.json c \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435\u043c \u043f\u0430\u043a\u0435\u0442\u0430 \u0438 Gruntfile.js \u0441 \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435\u043c \u043d\u0443\u0436\u043d\u044b\u0445 \u0442\u0430\u0441\u043a\u043e\u0432 \u0438 \u0438\u0445 \u043e\u043f\u0446\u0438\u0439.<\/p>\n<p>  \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c <a href=\"https:\/\/github.com\/mailru\/FileAPI\/blob\/dev\/Gruntfile.js#L37\">Gruntfile.js<\/a>. \u041e\u043d \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 5 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u0442\u0430\u0441\u043a\u043e\u0432:<\/p>\n<h4>jshint<\/h4>\n<p>\u042d\u0442\u043e \u043e\u0442\u0432\u0435\u0442\u0432\u043b\u0435\u043d\u0438\u0435 \u043e\u0442 <a href=\"http:\/\/www.jslint.com\/lint.html\">JSLint<\/a>, \u0432\u0430\u043b\u0438\u0434\u0430\u0442\u043e\u0440\u0430 \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0441\u0442\u0438 JavaScript-\u043a\u043e\u0434\u0430. \u0412 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u043e\u0442 \u043d\u0435\u0433\u043e, JSHint \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u043f\u043e\u0434 \u0432\u0430\u0448 \u043a\u043e\u0434, \u0447\u0442\u043e\u0431\u044b \u0441\u043b\u0435\u0434\u0438\u0442\u044c \u0437\u0430 \u0435\u0434\u0438\u043d\u044b\u043c \u0441\u0442\u0438\u043b\u0435\u043c \u043e\u0444\u043e\u0440\u043c\u043b\u0435\u043d\u0438\u044f, \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u043d\u0430 \u043f\u0440\u043e\u043f\u0443\u0449\u0435\u043d\u043d\u044b\u0435 \u0442\u043e\u0447\u043a\u0443 \u0441 \u0437\u0430\u043f\u044f\u0442\u043e\u0439, \u043b\u0438\u0448\u043d\u0438\u0435 \u0437\u0430\u043f\u044f\u0442\u044b\u0435 \u0432 \u043a\u043e\u043d\u0446\u0435 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u0438\u043b\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u0430, \u043d\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d \u043a\u043e\u0434\u0430\u043b\u0438 \u0447\u0430\u0441\u0442\u0438 \u043a\u043e\u0434\u0430.<\/p>\n<h4>concat<\/h4>\n<p>\u0421\u043e\u0431\u0438\u0440\u0430\u0435\u0442 \u0444\u0430\u0439\u043b\u044b \u0432 \u043e\u0434\u0438\u043d. \u0412 FileAPI \u044d\u0442\u0430 \u0441\u0435\u043a\u0446\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u0434\u0432\u0443\u0445 \u0447\u0430\u0441\u0442\u0435\u0439 `all` \u0438 `html5`, \u0447\u0442\u043e \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0434\u0432\u0443\u043c \u0441\u0431\u043e\u0440\u043a\u0430\u043c: c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u043e\u0439 flash \u0438 \u0431\u0435\u0437 \u043d\u0435\u0451, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u043b\u044f \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u044b\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432.<\/p>\n<h4>uglify<\/h4>\n<p>\u041e\u0431\u0444\u0443\u0441\u043a\u0430\u0446\u0438\u044f \u043a\u043e\u0434\u0430, \u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043e\u043d \u0441\u0436\u0438\u043c\u0430\u0435\u0442 \u0444\u0430\u0439\u043b\u044b, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0435 \u043f\u043e\u0441\u043b\u0435 concat.<\/p>\n<h4>watch<\/h4>\n<p>\u0422.\u043a. \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0444\u0430\u0439\u043b\u043e\u0432, \u0430 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d, \u0442\u043e \u0434\u0430\u043d\u043d\u044b\u0439 \u0442\u0430\u0441\u043a \u0441\u043b\u0435\u0434\u0438\u0442 \u0437\u0430 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f\u043c\u0438 js \u0444\u0430\u0439\u043b\u043e\u0432 \u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u0442\u0430\u0441\u043a <b>concat<\/b>.<\/p>\n<h4>qunit<\/h4>\n<p>\u041f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 <a href=\"http:\/\/phantomjs.org\/\">PhantomJS<\/a> \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 <a href=\"http:\/\/qunitjs.com\/\">QUnit<\/a> \u0442\u0435\u0441\u0442\u044b, \u0447\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u0440\u043e\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b. <\/p>\n<p>  \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c grunt \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u043e, \u043d\u043e \u043f\u0435\u0440\u0435\u0434 \u043d\u0430\u0447\u0430\u043b\u043e\u043c \u0440\u0430\u0431\u043e\u0442\u044b \u043d\u0443\u0436\u043d\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438. \u0414\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u044d\u0442\u043e \u0435\u0434\u0438\u043d\u043e\u0436\u0434\u044b, \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u044b <code>npm install<\/code>. <\/p>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0442\u0430\u0441\u043a\u0438:<br \/>  <code>$ \/FileAPI\/ &gt; grunt <\/code>\u2014 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c default \u0442\u0430\u0441\u043a (jshint + build)<br \/>  <code>$ \/FileAPI\/ &gt; grunt build<\/code> \u2014 \u0441\u0431\u043e\u0440\u043a\u0430 \u0438 \u043e\u0431\u0444\u0443\u0441\u043a\u0430\u0446\u0438\u044f (concat + uglify + qunit)<br \/>  <code>$ \/FileAPI\/ &gt; grunt watch<\/code> \u2014 \u0441\u043b\u0435\u0434\u0438\u0442\u044c \u0437\u0430 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f\u043c\u0438 \u0438, \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0438\u044f \u0442\u0430\u043a\u043e\u0432\u044b\u0445, \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c concat<\/p>\n<p>  <\/p>\n<h3>\u0422\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435<\/h3>\n<p>  \u041a\u0430\u043a \u0432\u044b \u0443\u0436\u0435 \u043f\u043e\u043d\u044f\u043b\u0438, \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f <a href=\"http:\/\/qunitjs.com\">QUnit<\/a>, \u043c\u043d\u0435 \u043e\u043d \u0432\u0441\u0435\u0433\u0434\u0430 \u043d\u0440\u0430\u0432\u0438\u043b\u0441\u044f \u0441\u0432\u043e\u0435\u0439 \u043b\u0430\u043a\u043e\u043d\u0438\u0447\u043d\u043e\u0441\u0442\u044c\u044e \u0438 \u043f\u0440\u043e\u0441\u0442\u043e\u0442\u043e\u0439. \u041a \u0442\u043e\u043c\u0443 \u0436\u0435, \u0434\u043b\u044f \u043d\u0435\u0433\u043e \u0435\u0441\u0442\u044c \u0433\u043e\u0442\u043e\u0432\u044b\u0439 <a href=\"https:\/\/github.com\/gruntjs\/grunt-contrib-qunit\">grunt-\u0442\u0430\u0441\u043a<\/a>. \u0422\u0435\u0441\u0442\u044b \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u044e\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 <a href=\"http:\/\/phantomjs.org\/\">PhantomJS<\/a>, \u0430 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0438 \u0436\u0434\u0430\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u0442\u0435\u0441\u0442\u0430.<\/p>\n<p>  <img decoding=\"async\" src=\"http:\/\/habr.habrastorage.org\/post_images\/c75\/2bf\/00a\/c752bf00a7514edd71fabd325439bb9d.png\" alt=\"FileAPI + Qunit\"\/><\/p>\n<p>  \u041d\u043e, \u043a\u0430\u043a \u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c, \u0432 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u043c grunt-\u0442\u0430\u0441\u043a\u0435 \u043d\u0435\u043b\u044c\u0437\u044f \u043f\u0440\u0438\u0432\u044f\u0437\u0430\u0442\u044c \u0444\u0430\u0439\u043b\u044b \u043a \u043d\u0443\u0436\u043d\u044b\u043c \u043c\u043d\u0435 \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u0430 \u0438\u043d\u043f\u0443\u0442\u0430\u043c. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u0435\u0433\u043e \u043d\u0435\u043c\u043d\u043e\u0433\u043e <a href=\"https:\/\/github.com\/mailru\/FileAPI\/blob\/dev\/tests\/grunt-task\/phantomjs\/grunt-lib-phantomjs-main.js#L76\">\u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c<\/a>:<\/p>\n<pre><code class=\"javascript\">qunit: {     options: {          \/\/ \u0424\u0430\u0439\u043b\u044b: \u043a\u043b\u044e\u0447 \u2014 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0438\u043d\u043f\u0443\u0442\u0430, \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u2014 \u0441\u043f\u0438\u0441\u043e\u043a \u0444\u0430\u0439\u043b\u043e\u0432          files: {              one: [&quot;foo.jpeg&quot;],              multiple: [&quot;bar.txt&quot;, &quot;baz.png&quot;, &quot;qux.zip&quot;]          }      },      all: [&quot;tests\/*.html&quot;] }<\/code><\/pre>\n<p>  \u041f\u0435\u0440\u0432\u044b\u043c\u0438 \u0442\u0435\u0441\u0442\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u043c\u0435\u0442\u043e\u0434\u044b \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0444\u0430\u0439\u043b\u0430\u043c\u0438. \u0422\u0430\u043a\u0438\u0435 \u043a\u0430\u043a \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u043c\u0435\u0442\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 (\u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435, \u0442\u0438\u043f, \u0440\u0430\u0437\u043c\u0435\u0440, exif), \u0447\u0442\u0435\u043d\u0438\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0433\u043e (DataURL, BinaryString \u0438 Text). \u0414\u0430\u043b\u0435\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430, \u0432 \u0445\u043e\u0434\u0435 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u044e\u0442\u0441\u044f \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0438 \u043e\u0442\u0432\u0435\u0442 \u043e\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u0430.<\/p>\n<p>  \u041d\u043e \u0441\u0430\u043c\u043e\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0435, \u044d\u0442\u043e \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f\u043c\u0438, \u0442\u0443\u0442 \u0432\u0441\u0451 \u0445\u0438\u0442\u0440\u0435\u0439. \u0422\u0430\u043a \u043a\u0430\u043a FileAPI \u00ab\u0438\u0437 \u043a\u043e\u0440\u043e\u0431\u043a\u0438\u00bb \u0443\u043c\u0435\u0435\u0442 \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0441\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u043c \u043f\u0440\u0430\u0432\u0438\u043b\u0430\u043c, \u0442\u043e \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c, \u0447\u0442\u043e\u0431\u044b \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u043e\u0435 \u0441\u0435\u0440\u0432\u0435\u0440\u043e\u043c, \u0431\u044b\u043b\u043e \u0438\u043c\u0435\u043d\u043d\u043e \u0442\u0435\u043c, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043d\u0443\u0436\u043d\u043e. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u0432\u0430 \u043d\u0430\u0431\u043e\u0440\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439: \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430, \u0438 \u044d\u0442\u0430\u043b\u043e\u043d\u043d\u044b\u0435, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442. \u041a\u0430\u043a \u0436\u0435 \u044d\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442? FileAPI \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0441 \u0442\u0435\u0441\u0442\u0438\u0440\u0443\u0435\u043c\u044b\u043c\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u0438 \u0432 \u043e\u0442\u0432\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 dataURL. \u0414\u0430\u043d\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u044e\u0442\u0441\u044f \u0432 assert-\u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u044e\u0442\u0441\u044f \u0432 canvas \u0438 \u043f\u043e\u043f\u0438\u043a\u0441\u0435\u043b\u044c\u043d\u043e \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u0441 \u044d\u0442\u0430\u043b\u043e\u043d\u043d\u044b\u043c \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435\u043c. \u0415\u0441\u043b\u0438 \u0440\u0430\u0441\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u0435 \u043c\u0435\u043d\u044c\u0448\u0435 &lt; 1%, \u0442\u043e \u0442\u0435\u0441\u0442 \u043f\u0440\u043e\u0439\u0434\u0435\u043d.<\/p>\n<pre><code class=\"javascript\">function imageEqual(actual\/**Image*\/, expected\/**Image*\/, message\/**String*\/){ \tactual = toCanvas(actual); \texpected = toCanvas(expected);  \tif( actual.width != expected.width ){ \t\tok(false, message + ' (width: ' + actual.width + ' != ' + expected.width + ')'); \t} \telse if( actual.height != expected.height ){ \t\tok(false, message + ' (height: ' + actual.height + ' != ' + expected.height + ')'); \t} \telse { \t\tvar actualData = actual.getContext('2d').getImageData(0, 0, actual.width, actual.height); \t\tvar expectedData = expected.getContext('2d').getImageData(0, 0, expected.width, expected.height); \t\tvar pixels = 0, failPixels = 0;  \t\tfor( var y = 0; y &lt; actualData.height; y++ ){ \t\t\tfor( var x = 0; x &lt; actualData.width; x++ ){ \t\t\t\tvar idx = (x + y * actualData.width) * 4; \t\t\t\tpixels++; \t\t\t\tif( !pixelEqual(actualData.data, expectedData.data, idx) ){ \t\t\t\t\tfailPixels++; \t\t\t\t} \t\t\t} \t\t}  \t\tok(failPixels \/ pixels &lt; .01, text + ' (fail pixels: ' + (failPixels \/ pixels) + ')'); \t} }  function pixelEqual(actual, expected, idx){ \tvar delta = 3; \/\/ \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u0430\u044f \u043f\u043e\u0433\u0440\u0435\u0448\u043d\u043e\u0441\u0442\u044c \treturn (Math.abs(actual[idx] - expected[idx]) &lt; delta) \t     && (Math.abs(actual[idx+1] - expected[idx+1]) &lt; delta)              && (Math.abs(actual[idx+2] - expected[idx+2]) &lt; delta); }<\/code><\/pre>\n<p>  \u041e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u044c \u044d\u0442\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430 \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e <a href=\"https:\/\/github.com\/mailru\/FileAPI\/tree\/dev\/tests\/files\/samples\">\u044d\u0442\u0430\u043b\u043e\u043d\u043d\u043e\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435<\/a> \u043d\u0443\u0436\u043d\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u043f\u043e\u0434 \u043a\u0430\u0436\u0434\u044b\u0439 \u0431\u0440\u0430\u0443\u0437\u0435\u0440 (Phantom, Firefox, Chrome). \u042d\u0442\u043e \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u043e c \u0442\u0435\u043c, \u0447\u0442\u043e \u0446\u0432\u0435\u0442\u043e\u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u0438 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u044b \u0441\u0436\u0430\u0442\u0438\u044f \u0432 \u043a\u0430\u0436\u0434\u043e\u043c \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435 \u0441\u0432\u043e\u0438. \u0417\u0430\u0431\u0430\u0432\u043d\u0430\u044f \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044f \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u0430 \u0441 Safari. \u0418\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u044f \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u043b \u044d\u0442\u0430\u043b\u043e\u043d\u043d\u044b\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0430\u043c\u0438 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430, \u0430 \u043d\u0435 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u0435. \u0422\u0430\u043a \u0432\u043e\u0442, \u0432 Safari \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435, \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u0435 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 dataURL \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u043d\u043e\u0435 \u0434\u0438\u0441\u043a, \u043d\u0435 \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u0435\u0442 \u0441 \u0442\u0435\u043c, \u0447\u0442\u043e \u0432\u044b \u0432\u0438\u0434\u0438\u0442\u0435 \u043d\u0430 \u044d\u043a\u0440\u0430\u043d\u0435, \u0446\u0432\u0435\u0442\u0430 \u0438\u0441\u043a\u0430\u0436\u0435\u043d\u044b.<\/p>\n<p>  \u0423\u0432\u044b, \u044d\u0442\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0435 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043e\u0447\u0435\u043d\u044c \u0441\u0438\u043b\u044c\u043d\u043e \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442, \u043d\u043e \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u0440\u0443\u0447\u043d\u043e\u0435 \u0442\u0430\u043c, \u0433\u0434\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f Flash. \u041f\u043e\u043c\u0438\u043c\u043e \u044d\u0442\u043e\u0433\u043e \u0435\u0441\u0442\u044c \u0438\u0434\u0435\u044f \u0441\u043e\u0437\u0434\u0430\u0442\u044c grunt-\u0442\u0430\u0441\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442 QUnit \u0442\u0435\u0441\u0442\u044b \u0447\u0435\u0440\u0435\u0437 Selenium, \u0432\u043e\u0442 \u0442\u043e\u0433\u0434\u0430 \u0437\u0430\u0436\u0438\u0432\u0435\u043c.<\/p>\n<p>  <\/p>\n<h3>\u0424\u0438\u0447\u0438<\/h3>\n<p>  Grunt, \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u2014 \u044d\u0442\u043e, \u043a\u043e\u043d\u0435\u0447\u043d\u043e, \u0445\u043e\u0440\u043e\u0448\u043e, \u043d\u043e \u043d\u0438\u043a\u0430\u043a \u043d\u0435 \u0442\u044f\u043d\u0435\u0442 \u043d\u0430 \u0432\u0435\u0440\u0441\u0438\u044e 2.0, \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0447\u0435\u0433\u043e-\u0442\u043e \u044d\u0434\u0430\u043a\u043e\u0433\u043e.<\/p>\n<h4>Image overlay<\/h4>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0447\u0435\u0440\u0435\u0437 \u043c\u0435\u0441\u044f\u0446 \u043f\u043e\u0441\u043b\u0435 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438, \u0443 \u043c\u0435\u043d\u044f \u0441\u043f\u0440\u043e\u0441\u0438\u043b\u0438, \u043a\u0430\u043a \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u043d\u0430\u043b\u043e\u0436\u0438\u0442\u044c watermark \u043d\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440? \u042d\u0442\u0443 \u0437\u0430\u0434\u0430\u0447\u0443 \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0440\u0435\u0448\u0438\u0442\u044c, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u0438\u0432 \u043f\u0440\u044f\u043c\u043e\u0439 \u0434\u043e\u0441\u0442\u0443\u043f \u043a canvas, \u0447\u0435\u0440\u0435\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u044f\u0442 \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 (\u043a\u0430\u043a \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u043d\u043e \u0432 <a href=\"https:\/\/github.com\/blueimp\/jQuery-File-Upload\/issues\/1300\">jQuery FileUpload<\/a>). \u041d\u043e, \u0443\u0432\u044b, \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0442 IE \u043d\u0438\u0436\u0435 10 \u0432\u0435\u0440\u0441\u0438\u0438, \u0433\u0434\u0435 \u0432\u0441\u0435 \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u0438\u0434\u0443 \u0447\u0435\u0440\u0435\u0437 Flash, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0440\u0435\u0448\u0435\u043d\u043e \u0431\u044b\u043b\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u043b \u0431\u044b \u0434\u0435\u043b\u0430\u0442\u044c \u043b\u044e\u0431\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043d\u0430\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0441 \u0433\u0438\u0431\u043a\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u043e\u0439 \u043f\u043e\u0437\u0438\u0446\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f: <\/p>\n<pre><code class=\"javascript\">FileAPI.Image(file)     .overlay([          {              x: 10, y: 5,    \/\/  \u0441\u043c\u0435\u0449\u0435\u043d\u0438\u0435              rel: FileAPI.Image.RIGHT_BOTTOM, \/\/ \u0446\u0435\u043d\u0442\u0440              opacity: 0.7, \/\/ \u0441\u0442\u0435\u043f\u0435\u043d\u044c \u043f\u0440\u043e\u0437\u0440\u0430\u0447\u043d\u043e\u0441\u0442\u0438, \u043e\u0442 0 \u0434\u043e 1              src: &quot;watermark.png&quot; \/\/ \u043d\u0430\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u043c\u043e\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435          }     ])     .get(err\/**Mixed*\/, img\/**HTMLElement*\/){ \/*__*\/  }) ;<\/code><\/pre>\n<p>  \u0422\u0430\u043a\u0436\u0435, \u043e\u0434\u043d\u043e\u0438\u043c\u0435\u043d\u043d\u043e\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0432 imageTransform:<\/p>\n<pre><code class=\"javascript\">FileAPI.upload({      imageTransform: {            overlay: {                 x: 5, y: 5,                 rel: FileAPI.Image.CENTER_TOP,                 src: &quot;watermark.png&quot; \/\/ \u043d\u0430\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u043c\u043e\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435            }      } });<\/code><\/pre>\n<p>  \u041a\u0430\u043a \u0432\u0438\u0434\u0438\u0442\u0435, \u043c\u0435\u0442\u043e\u0434 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0441\u044f \u043f\u0440\u043e\u0441\u0442\u043e\u0439, \u043d\u043e \u0433\u0438\u0431\u043a\u0438\u0439.<\/p>\n<p>  <\/p>\n<h3>WebCam<\/h3>\n<p>  \u0413\u043b\u0430\u0432\u043d\u044b\u043c \u043d\u043e\u0432\u043e\u0432\u0432\u0435\u0434\u0435\u043d\u0438\u0435\u043c \u0441\u0442\u0430\u043b\u0430 \u0440\u0430\u0431\u043e\u0442\u0430 \u0441 \u0432\u0435\u0431-\u043a\u0430\u043c\u0435\u0440\u043e\u0439. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0432 HTML5 \u043f\u043e\u044f\u0432\u0438\u043b\u0441\u044f \u043c\u0435\u0442\u043e\u0434 <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/Navigator.getUserMedia\">navigator.getUserMedia<\/a>. \u0420\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u043d\u0438\u043c \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u043e:<\/p>\n<p>  <a href=\"http:\/\/jsfiddle.net\/RubaXa\/uZhRp\/\">http:\/\/jsfiddle.net\/RubaXa\/uZhRp\/<\/a><\/p>\n<pre><code class=\"javascript\">function setWebCam(video\/**HTMLVideo*\/, doneFn\/**Function*\/) {     var navigator = window.navigator;     var getMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;      getMedia.call(navigator, {         video: true \/\/ \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u043c \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0432\u0435\u0431-\u043a\u0430\u043c\u0435\u0440\u0435     }, function (stream) {         var URL = window.URL || window.webkitURL || window.mozURL;          video.addEventListener('loadedmetadata', function () {             doneFn();         }, false);          video.src = URL.createObjectURL(stream);         video.play();     }, function () { \/* \u0432 \u0434\u043e\u0441\u0442\u0443\u043f\u0435 \u043e\u0442\u043a\u0430\u0437\u0430\u043d\u043e *\/ }); }  setWebCam(videoEl, function () {      \/\/ \u0415\u0441\u0442\u044c \u0441\u0438\u0433\u043d\u0430\u043b });<\/code><\/pre>\n<p>  \u0412\u0440\u043e\u0434\u0435 \u0432\u0441\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u043d\u043e \u0435\u0441\u043b\u0438 \u043e\u0442\u043a\u0440\u044b\u0442\u044c \u044d\u0442\u043e\u0442 \u043f\u0440\u0438\u043c\u0435\u0440 \u0432 FireFox, \u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0432\u0438\u0434\u043d\u043e, \u0447\u0442\u043e callback \u0441\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0440\u0430\u043d\u044c\u0448\u0435, \u0447\u0435\u043c \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0441\u0438\u0433\u043d\u0430\u043b\u0430 \u0447\u0435\u0440\u0435\u0437 canvas:<\/p>\n<p>  <a href=\"http:\/\/jsfiddle.net\/RubaXa\/uZhRp\/\">http:\/\/jsfiddle.net\/RubaXa\/uZhRp\/<\/a><\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u041b\u0438\u0441\u0442\u0438\u043d\u0433<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"javascript\">function setWebCam(video\/**HTMLVideo*\/, doneFn\/**Function*\/) {     function _detectVideoSignal() {         var canvas = document.createElement('canvas'), ctx, res = false;         try {             ctx = canvas.getContext('2d');             ctx.drawImage(video, 0, 0, 1, 1);             res = ctx.getImageData(0, 0, 1, 1).data[4] != 255;         } catch (e) {}         return res;     }      var navigator = window.navigator;     var getMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;      getMedia.call(navigator, { video: true  }, function (stream) {         var pid, URL = window.URL || window.webkitURL || window.mozURL;          pid = setInterval(function () {             if (_detectVideoSignal()) {                 clearTimeout(pid);                 doneFn();             }         }, 100);          \/\/ ...     }, function () { \/* \u0432 \u0434\u043e\u0441\u0442\u0443\u043f\u0435 \u043e\u0442\u043a\u0430\u0437\u0430\u043d\u043e *\/ }); }  setWebCam(videoEl, function () {     \/\/ \u0415\u0441\u0442\u044c \u0441\u0438\u0433\u043d\u0430\u043b });<\/code><\/pre>\n<\/div>\n<\/div>\n<p>  \u0423\u0432\u044b, \u043d\u043e \u043d\u0430 \u043c\u043e\u043c\u0435\u043d\u0442 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0441\u0442\u0430\u0442\u044c\u0438 \u043c\u0435\u0442\u043e\u0434 <code>navigator.getUserMedia<\/code> <a href=\"http:\/\/caniuse.com\/#search=getUserMedia\">\u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0442<\/a> \u0442\u043e\u043b\u044c\u043a\u043e FireFox \u0438 \u0421hrome, \u0447\u0442\u043e, \u043a\u043e\u043d\u0435\u0447\u043d\u043e, \u0445\u043e\u0440\u043e\u0448\u043e, \u043d\u043e \u043d\u0435 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u0441\u0434\u0435\u043b\u0430\u043b\u0438 fallback \u0432\u043e Flash, \u0447\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u043b\u043e \u0437\u0430\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0432\u0441\u0435 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u044b. \u0412 \u0438\u0442\u043e\u0433\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 API \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043a\u0430\u043c\u0435\u0440\u043e\u0439:<\/p>\n<pre><code class=\"javascript\">var el = document.getElementById('container');  \/\/ \u041f\u0443\u0431\u043b\u0438\u043a\u0443\u0435\u043c \u043a\u0443\u043c\u0435\u0440\u0443 FileAPI.Camera.publish(el, { width: 320, height: 240 }, function (err, cam\/**FileAPI.Camera*\/){       var btn = document.getElementById('shot')        \/\/ btn \u2014 \u043a\u043d\u043e\u043f\u043a\u0430, \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0434\u0435\u043b\u0430\u0435\u043c \u0441\u043a\u0440\u0438\u043d       FileAPI.event.on(btn, 'click', function (evt){            var shot = cam.shot(); \/\/ \u042d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 FileAPI.Image                        FileAPI.upload({                 url: '.\/ctrl.php',                 files: { photo: shot }            });       }); });<\/code><\/pre>\n<h4>FileAPI.Camera<\/h4>\n<ul>\n<li><b>publish(el, options, callback)<\/b> \u2014 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043c\u0435\u0442\u043e\u0434, \u0434\u043b\u044f \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438 \u043a\u0430\u043c\u0435\u0440\u044b;<\/li>\n<li><b>start(callback)<\/b> \u2014 \u043d\u0430\u0447\u0430\u0442\u044c \u0432\u0435\u0449\u0430\u043d\u0438\u0435;<\/li>\n<li><b>shot()<\/b> \u2014 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u043a\u0440\u0438\u043d\u0448\u043e\u0442, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043d\u0430\u0441\u043b\u0435\u0434\u043d\u0438\u043a\u0430 FileAPI.Image;<\/li>\n<li><b>stop()<\/b> \u2014 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043a\u0430\u043c\u0435\u0440\u0443.<\/li>\n<\/ul>\n<p>  <\/p>\n<h3>\u0424\u0438\u043b\u044c\u0442\u0440\u044b<\/h3>\n<p>  \u0421\u0434\u0435\u043b\u0430\u0432 \u0434\u0432\u0435 \u0444\u0438\u0447\u0438, \u044f \u043f\u043e\u0434\u0443\u043c\u0430\u043b, \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0447\u0442\u043e-\u0442\u043e \u0435\u0449\u0451, \u043d\u0435 \u0445\u0432\u0430\u0442\u0430\u0435\u0442 \u0432\u0430\u0443-\u044d\u0444\u0444\u0435\u043a\u0442\u0430. \u041d\u043e \u0432 \u0433\u043e\u043b\u043e\u0432\u0443 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u043b\u043e. \u0421\u043f\u0443\u0441\u0442\u044f \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0432\u0440\u0435\u043c\u044f, \u044f \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u043e \u043d\u0430\u0442\u043a\u043d\u0443\u043b\u0441\u044f \u043d\u0430 \u0437\u0430\u043c\u0435\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u0443\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 <a href=\"http:\/\/camanjs.com\/\">CamanJS<\/a>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0446\u0432\u0435\u0442\u043e\u043a\u043e\u0440\u0440\u0435\u043a\u0446\u0438\u044e, \u043d\u043e \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u043b\u043e\u0436\u043d\u044b\u0435 \u0440\u0435\u0436\u0438\u043c\u044b \u043d\u0430\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0449\u043d\u044b\u0435 \u0444\u0438\u043b\u044c\u0442\u0440\u044b \u2014 \u043e\u0447\u0435\u043d\u044c \u0441\u043e\u0432\u0435\u0442\u0443\u044e. \u042d\u0442\u043e \u0431\u044b\u043b\u043e \u0442\u043e, \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e: \u043a\u0430\u043c\u0435\u0440\u0430 \u0435\u0441\u0442\u044c, \u0440\u0430\u0431\u043e\u0442\u0430 \u0441 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f\u043c\u0438 \u0442\u043e\u0436\u0435, \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c CamanJS \u2014 \u0438 \u0441\u0432\u043e\u0439 \u00ab\u0438\u043d\u0441\u0442\u0430\u0433\u0440\u0430\u043c\u00bb \u0441 FileAPI, WebCam \u0438 \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u043c\u0438 \u0433\u043e\u0442\u043e\u0432.<\/p>\n<p>  \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u0441\u0435 \u044d\u0442\u043e \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u043e, \u0432 \u0441\u043e\u0441\u0442\u0430\u0432\u0435 CamanJS \u0438\u0434\u0443\u0442 10 \u043f\u0440\u0435\u0434\u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044b\u0445 \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432, \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0438\u0445 \u0432 \u0440\u0430\u0431\u043e\u0442\u0435 \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 <a href=\"http:\/\/camanjs.com\/examples\/\">\u0442\u0443\u0442<\/a> \u0438 <a href=\"http:\/\/mailru.github.io\/FileAPI\/examples\/caman.html\">\u0442\u0443\u0442<\/a>.  <\/p>\n<pre><code class=\"javascript\">FileAPI.Image(file)     .filter('hazyDays') \/\/ CamanJS \u0444\u0438\u043b\u044c\u0442\u0440     .get(function (err, img\/**Image*\/){         \/* ... *\/     }) ;<\/code><\/pre>\n<p>  \u041f\u043e\u043c\u0438\u043c\u043e \u044d\u0442\u043e\u0433\u043e, \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0438 \u0432 \u043d\u0435\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u044b\u0435 \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438. \u041d\u0430 \u0432\u0445\u043e\u0434 \u0431\u0443\u0434\u0443\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u044b \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 canvas \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043e\u0431\u0440\u0430\u0442\u043d\u043e\u0433\u043e \u0432\u044b\u0437\u043e\u0432\u0430.<\/p>\n<pre><code class=\"javascript\">FileAPI.Image(file)     .filter(function (canvas, callback){           \/\/ \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u0443\u0435\u043c canvas           callback();     })     .get(function (err, img\/**Image*\/){         \/* ... *\/     }) ;<\/code><\/pre>\n<p>  \u0423\u0432\u044b, \u0432\u0441\u0451 \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0438 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0435 HTML5. \u0415\u0441\u043b\u0438 \u0447\u0435\u0441\u0442\u043d\u043e, \u043e\u0447\u0435\u043d\u044c \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u0432\u044b\u0448\u0435\u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430 \u0447\u0435\u0440\u0435\u0437 Flash, \u0438 \u044d\u0442\u043e \u0434\u0430\u0436\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e: \u0432\u0441\u0435\u0433\u043e-\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 canvas \u0432\u043e Flash. \u041a\u0430\u043a-\u043d\u0438\u0431\u0443\u0434\u044c \u0432 \u0434\u0440\u0443\u0433\u043e\u0439 \u0440\u0430\u0437.<\/p>\n<p>  <\/p>\n<h3>jQuery.FileAPI<\/h3>\n<p>  \u0424\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u043c \u043d\u043e\u0432\u043e\u0432\u0432\u0435\u0434\u0435\u043d\u0438\u0435\u043c, \u0441\u0442\u0430\u043b \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u044b\u0439 \u043f\u043b\u0430\u0433\u0438\u043d \u0434\u043b\u044f jQuery. \u0412 \u043d\u0435\u043c \u044f \u043f\u043e\u0441\u0442\u0430\u0440\u0430\u043b\u0441\u044f \u0443\u0447\u0435\u0441\u0442\u044c \u0441\u0430\u043c\u044b\u0435 \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0435\u043d\u043d\u044b\u0435 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0444\u0430\u0439\u043b\u043e\u0432, \u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a:<\/p>\n<ul>\n<li><b>\u00ab\u041e\u0434\u043d\u043e\u0439 \u043a\u043d\u043e\u043f\u043a\u043e\u0439\u00bb<\/b> \u2014 \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u0438 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0444\u0430\u0439\u043b;<\/li>\n<li><b>\u00ab\u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f\u00bb<\/b> \u2014 \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439\/\u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u0440\u0430\u0437\u043c\u0435\u0440 \u043a\u0430\u043a \u0444\u0430\u0439\u043b\u0430, \u0442\u0430\u043a \u0438 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u043f\u043e \u0448\u0438\u0440\u0438\u043d\u0435 \u0438 \u0432\u044b\u0441\u043e\u0442\u0435;<\/li>\n<li><b>\u00ab\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 \u043e\u0447\u0435\u0440\u0435\u0434\u044c\u044e\u00bb<\/b> \u2014 \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0430 \u0438 \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u044f \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0444\u0430\u0439\u043b\u043e\u0432;<\/li>\n<li><b>\u00ab\u0418\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f\u00bb<\/b> \u2014 \u043f\u0440\u0435\u0434\u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440, \u043f\u043e\u0432\u043e\u0440\u043e\u0442 \u0438 \u043a\u0430\u0434\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435;<\/li>\n<li><b>\u00ab\u0418\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u00bb<\/b> \u2014 \u0433\u0438\u0431\u043a\u0430\u044f \u0438 \u043f\u0440\u043e\u0437\u0440\u0430\u0447\u043d\u0430\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430;<\/li>\n<li>\u0410 \u0442\u0430\u043a\u0436\u0435 <b>Drag\u2019n\u2019Drop<\/b> \u0438 <b>WebCam<\/b>.<\/li>\n<\/ul>\n<p>  \u041e\u0446\u0435\u043d\u0438\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043d\u0430 <a href=\"http:\/\/rubaxa.github.io\/jquery.fileapi\/\">\u0434\u0435\u043c\u043e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435<\/a>, <a href=\"https:\/\/github.com\/RubaXa\/jquery.fileapi\">github<\/a> \u0438\u043b\u0438 \u0437\u0430\u0433\u043b\u044f\u043d\u0443\u0432 \u043f\u043e\u0434 \u0441\u0432\u043e\u0439\u043b\u0435\u0440.<\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u00ab\u041e\u0434\u043d\u043e\u0439 \u043a\u043d\u043e\u043f\u043a\u043e\u0439\u00bb<\/b><\/p>\n<div class=\"spoiler_text\"><img decoding=\"async\" src=\"http:\/\/habrastorage.org\/storage3\/ca3\/268\/294\/ca3268294ac9ba4e1528397973abc3a0.gif\" alt=\"image\"\/><\/div>\n<\/div>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0430\u0432\u0430\u0442\u0430\u0440\u044b<\/b><\/p>\n<div class=\"spoiler_text\"><img decoding=\"async\" src=\"http:\/\/habrastorage.org\/storage3\/8d0\/8ba\/c99\/8d08bac995ed5edc99222ddd2f487ab7.gif\" alt=\"image\"\/><\/div>\n<\/div>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u041c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u0430\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430<\/b><\/p>\n<div class=\"spoiler_text\"><img decoding=\"async\" src=\"http:\/\/habrastorage.org\/storage3\/8dd\/b01\/edb\/8ddb01edba74ac220d0b604a91034710.gif\" alt=\"image\"\/><\/div>\n<\/div>\n<p>  \u0417\u0434\u0435\u0441\u044c \u0440\u0430\u0437\u0431\u0435\u0440\u0443 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u043f\u0440\u0438\u043c\u0435\u0440, \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u0430\u0432\u0430\u0442\u0430\u0440\u0430, \u0430 \u0438\u043c\u0435\u043d\u043d\u043e: \u0432\u044b\u0431\u043e\u0440 \u0444\u043e\u0442\u043e\u0433\u0440\u0430\u0444\u0438\u0438, \u043a\u0430\u0434\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438 \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440. \u041a\u0430\u043a \u044d\u0442\u043e \u043d\u0438 \u0443\u0434\u0438\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e, \u043d\u043e \u043d\u0438 \u043e\u0434\u043d\u043e \u0438\u0437 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0445 \u0440\u0435\u0448\u0435\u043d\u0438\u0439 \u043d\u0435 \u0434\u0430\u0435\u0442 \u0442\u0430\u043a\u043e\u0439 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438. \u041f\u043e \u044d\u0442\u043e\u0439 \u043f\u0440\u0438\u0447\u0438\u043d\u0435 \u0434\u0430\u043d\u043d\u044b\u0439 \u043a\u0435\u0439\u0441 \u0431\u044b\u043b \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d \u0432 \u043f\u0435\u0440\u0432\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c:<\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u0412\u0435\u0440\u0441\u0442\u043a\u0430<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"html\">&lt;div id=&quot;userpic&quot; class=&quot;userpic&quot;&gt;    &lt;div class=&quot;js-preview userpic__preview&quot;&gt;&lt;\/div&gt;    &lt;div class=&quot;btn btn-success js-fileapi-wrapper&quot;&gt;       &lt;div class=&quot;js-browse&quot;&gt;          &lt;span class=&quot;btn-txt&quot;&gt;Choose&lt;\/span&gt;          &lt;input type=&quot;file&quot; name=&quot;filedata&quot;&gt;       &lt;\/div&gt;       &lt;div class=&quot;js-upload&quot; style=&quot;display: none;&quot;&gt;          &lt;div class=&quot;progress progress-success&quot;&gt;&lt;div class=&quot;js-progress bar&quot;&gt;&lt;\/div&gt;&lt;\/div&gt;          &lt;span class=&quot;btn-txt&quot;&gt;Uploading&lt;\/span&gt;       &lt;\/div&gt;    &lt;\/div&gt; &lt;\/div&gt;<\/code><\/pre>\n<\/div>\n<\/div>\n<p>  <\/p>\n<pre><code class=\"javascript\">$(&quot;#userpic&quot;).fileapi({ \turl: &quot;.\/ctrl.php&quot;, \taccept: &quot;image\/*&quot;, \timageSize: { minWidth: 200, minHeight: 200 }, \telements: { \t\t\/\/ \u0415\u0441\u043b\u0438 \u0430\u043f\u043b\u043e\u0443\u0434\u0435\u0440 \u0430\u043a\u0442\u0438\u0432\u0435\u043d (\u0438\u0434\u0435\u0442 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430), \u0442\u043e \t\tactive: { \t\t\tshow: &quot;.js-upload&quot;, \/\/ \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0431\u043b\u043e\u043a \t\t\thide: &quot;.js-browse&quot; \/\/ \u0441\u043a\u0440\u044b\u0442\u044c \u0431\u043b\u043e\u043a \t\t}, \t\t\/\/ \u041a\u0443\u0434\u0430 \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u044c \u043f\u0440\u0435\u0434\u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u043e\u0433\u043e \u0438\u0437\u043b\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \t\tpreview: { \t\t\tel: &quot;.js-preview&quot;, \t\t\twidth: 200, \/\/ \u0435\u0433\u043e \u0440\u0430\u0437\u043c\u0435\u0440\u044b \t\t\theight: 200 \t\t}, \t\t\/\/ \u042d\u043b\u0435\u043c\u0435\u043d\u0442 \u043e\u0442\u0432\u0435\u0447\u0430\u044e\u0449\u0438\u0439 \u0437\u0430 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0445\u043e\u0434\u0430 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \t\tprogress: &quot;.js-progress&quot; \t}, \tonSelect: function (evt, ui){ \t\tvar image = ui.files[0]; \t\tif( image ){ \t\t\tcreateModal(function (overlay){ \t\t\t\t$(overlay).on(&quot;click&quot;, &quot;.js-upload&quot;, function (){ \t\t\t\t\tcloseModal(); \t\t\t\t\t$(&quot;#userpic&quot;).fileapi(&quot;upload&quot;); \/\/ \u0417\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c \t\t\t\t});  \t\t\t\t$(&quot;.js-img&quot;, overlay).cropper({ \t\t\t\t\t\/\/ \u0424\u0430\u0439\u043b \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \t\t\t\t\tfile: image, \t\t\t\t\t\/\/ \u0426\u0432\u0435\u0442 \u0437\u0430\u0442\u0435\u043c\u043d\u0435\u043d\u0438\u044f \t\t\t\t\tbgColor: &quot;#fff&quot;, \t\t\t\t\t\/\/ \u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0435 \u0440\u0430\u0437\u043c\u0435\u0440\u044b, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0443\u0436\u043d\u043e \u0432\u043f\u0438\u0441\u0430\u0442\u044c \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \t\t\t\t\tmaxSize: [$(window).width() - 100, $(window).height() - 100], \t\t\t\t\t\/\/ \u041c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0435 \u0440\u0430\u0437\u043c\u0435\u0440\u0430 \u043a\u0440\u043e\u043f-\u0440\u0430\u043c\u043a\u0438 \t\t\t\t\tminSize: [130, 130], \t\t\t\t\t\/\/ \u0420\u0430\u0437\u043c\u0435\u0440 \u043a\u0440\u043e\u043f-\u0440\u0430\u043c\u043a\u0438: Math.min(width*.9, height*.9) \t\t\t\t\tselection: 0.9, \/\/ \u0438\u043b\u0438 &quot;90%&quot; \t\t\t\t\t\/\/ \u0421\u043e\u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435 \u0441\u0442\u043e\u0440\u043e\u043d \u043a\u0440\u043e\u043f-\u0440\u0430\u043c\u043a\u0438 \t\t\t\t\taspectRatio: 1, \t\t\t\t\t\/\/ \u0412\u044b\u0431\u0440\u0430\u043d\u0430 \u043d\u043e\u0432\u0430\u044f \u043a\u0440\u043e\u043f-\u043e\u0431\u043b\u0430\u0441\u0442\u044c \t\t\t\t\tonSelect: function (coords\/**Object*\/){ \t\t\t\t\t\t$(&quot;#userpic&quot;).fileapi(&quot;crop&quot;, image, coords); \t\t\t\t\t} \t\t\t\t}); \t\t\t}); \t\t} \t} });<\/code><\/pre>\n<p>  \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u043f\u043b\u0430\u0433\u0438\u043d \u043e\u0431\u043b\u0430\u0434\u0430\u044e\u0442 \u043e\u0447\u0435\u043d\u044c \u0433\u0438\u0431\u043a\u0438\u043c\u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u043c\u0438 \u0432\u043d\u0435\u0448\u043d\u0435\u0433\u043e \u0432\u0438\u0434\u0430, \u0447\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u043e\u0434\u0441\u0442\u0440\u043e\u0438\u0442\u044c\u0441\u044f \u043f\u043e\u0434 \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e \u0437\u0430\u0434\u0430\u0447. \u041d\u0443, \u0430 \u0435\u0441\u043b\u0438 \u0447\u0435\u0433\u043e-\u0442\u043e \u043d\u0435 \u0445\u0432\u0430\u0442\u0430\u0435\u0442 \u0438\u043b\u0438 \u0432\u044b \u043d\u0430\u0448\u043b\u0438 \u0431\u0430\u0433, \u0442\u043e \u0432\u044b \u0432\u0441\u0435\u0433\u0434\u0430 \u043c\u043e\u0436\u0435\u0442\u0435 \u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c <a href=\"https:\/\/github.com\/RubaXa\/jquery.fileapi\/issues\">\u0442\u0438\u043a\u0435\u0442<\/a> \u043d\u0430 github, \u043b\u0438\u0431\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043c\u043d\u0435 \u2014 \u0431\u0443\u0434\u0443 \u0440\u0430\u0434 \u043f\u043e\u043c\u043e\u0447\u044c.<\/p>\n<p>  \u041f\u043e\u043c\u0438\u043c\u043e \u0441\u0430\u043c\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0438 \u043f\u043b\u0430\u0433\u0438\u043d\u0430, \u043e\u0447\u0435\u043d\u044c \u0441\u0438\u043b\u044c\u043d\u043e \u043f\u0435\u0440\u0435\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u0430 <a href=\"http:\/\/mailru.github.io\/FileAPI\/\">\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f<\/a>. \u0422\u0435\u043f\u0435\u0440\u044c \u044d\u0442\u043e \u0434\u0432\u0430 \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u044b\u0445 \u0441\u0430\u0439\u0442\u0430:<\/p>\n<ul>\n<li><b>FileAPI<\/b>: <a href=\"http:\/\/mailru.github.io\/FileAPI\/examples\/caman.html\">\u043f\u0440\u0438\u043c\u0435\u0440\u044b<\/a> &nbsp;|&nbsp; <a href=\"https:\/\/github.com\/mailru\/FileAPI\/tree\/dev\">\u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0438<\/a> &nbsp;|&nbsp; <a href=\"https:\/\/github.com\/mailru\/FileAPI\/issues?state=open\">issues<\/a><\/li>\n<li><b>jQuery.FileAPI<\/b>: <a href=\"http:\/\/rubaxa.github.io\/jquery.fileapi\/\">\u043f\u0440\u0438\u043c\u0435\u0440\u044b<\/a> &nbsp;|&nbsp; <a href=\"https:\/\/github.com\/RubaXa\/jquery.fileapi\">\u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0438<\/a> &nbsp;|&nbsp; <a href=\"https:\/\/github.com\/RubaXa\/jquery.fileapi\/issues?state=open\">issues<\/a><\/li>\n<\/ul>\n<h5>\u0422\u0430\u043a\u0436\u0435 \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0441\u043b\u0435\u0434\u0438\u0442\u044c \u0437\u0430 \u043d\u0430\u0448\u0438\u043c\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u043c\u0438 \u0447\u0435\u0440\u0435\u0437:<\/h5>\n<p><a href=\"https:\/\/github.com\/mailru\">github.com\/mailru<\/a> \u2014 FileAPI, Tarantool, Fest \u0438 \u043c\u043d\u043e\u0433\u043e\u0435 \u0434\u0440\u0443\u0433\u043e\u0435<br \/>  <a href=\"https:\/\/github.com\/rubaxa\/\">github.com\/rubaxa<\/a> \u2014 \u043c\u043e\u0439 github<br \/>  <a href=\"https:\/\/twitter.com\/ibnRubaXa\">@ibnRubaXa<\/a>      \t<\/p>\n<div class=\"clear\"><\/div>\n<\/p><\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"http:\/\/habrahabr.ru\/company\/mailru\/blog\/201010\/\"> http:\/\/habrahabr.ru\/company\/mailru\/blog\/201010\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div class=\"content html_format\">   \t<img decoding=\"async\" src=\"http:\/\/habr.habrastorage.org\/post_images\/c9e\/c06\/907\/c9ec069077a789d6569e563c618cb43f.png\" alt=\"FileAPI 2.0\" align=\"right\"\/>\u041f\u0440\u0438\u0432\u0435\u0442 \u0425\u0430\u0431\u0440! \u041f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0433\u043e\u0434 \u043d\u0430\u0437\u0430\u0434 \u044f \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043b \u0432\u0430\u0448\u0435\u043c\u0443 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044e \u043f\u0435\u0440\u0432\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e <a href=\"http:\/\/habrahabr.ru\/company\/mailru\/blog\/159587\/\">open-source \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 FileAPI<\/a>, \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u0443\u044e \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0444\u0430\u0439\u043b\u0430\u043c\u0438 \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0435 \u0438 \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440.<\/p>\n<p>   \u0417\u0430 \u044d\u0442\u043e \u0432\u0440\u0435\u043c\u044f \u0431\u044b\u043b \u043f\u0440\u043e\u0439\u0434\u0435\u043d \u0434\u043e\u043b\u0433\u0438\u0439 \u043f\u0443\u0442\u044c. \u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0437\u0430\u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0430 <a href=\"https:\/\/github.com\/mailru\/FileAPI\/stargazers\">670+<\/a>&nbsp;\u0437\u0432\u0435\u0437\u0434 \u0438 <a href=\"https:\/\/github.com\/mailru\/FileAPI\/network\/members\">90+<\/a>&nbsp;\u0444\u043e\u0440\u043a\u043e\u0432. \u0421 \u043f\u043e\u043c\u043e\u0449\u044c\u044e github-\u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u0430 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u00ab\u0434\u0435\u0442\u0441\u043a\u0438\u0445\u00bb \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u0438 \u0432\u043d\u0435\u0441\u0442\u0438 \u0440\u044f\u0434 \u0443\u043b\u0443\u0447\u0448\u0435\u043d\u0438\u0439. \u0411\u044b\u043b\u043e \u0437\u0430\u043a\u0440\u044b\u0442\u043e \u0431\u043e\u043b\u0435\u0435 <a href=\"https:\/\/github.com\/mailru\/FileAPI\/issues?sort=created&amp;state=closed\">100<\/a>&nbsp;\u0442\u0430\u0441\u043a\u043e\u0432, \u0438 \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u0418\u043b\u044c\u0435 \u041b\u0435\u0431\u0435\u0434\u0435\u0432\u0443 \u0441\u0434\u0435\u043b\u0430\u043d\u0430 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0444\u0430\u0439\u043b\u043e\u0432 \u043f\u043e \u0447\u0430\u0441\u0442\u044f\u043c. \u0421\u0435\u0433\u043e\u0434\u043d\u044f \u044f \u0441 \u0433\u043e\u0440\u0434\u043e\u0441\u0442\u044c\u044e \u0445\u043e\u0447\u0443 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0432\u0430\u043c <a href=\"http:\/\/mailru.github.io\/FileAPI\/\">FileAPI 2.0<\/a>.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-201010","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/201010","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=201010"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/201010\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=201010"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=201010"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=201010"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}