80 |
81 |
82 |
83 |
84 |
--------------------------------------------------------------------------------
/public/color-picker.css:
--------------------------------------------------------------------------------
1 |
2 | /*! Pickr 1.2.1 MIT | https://github.com/Simonwep/pickr */.pickr{position:relative;overflow:visible;transform:translateY(0)}.pickr *{box-sizing:border-box}.pickr .pcr-button{position:relative;height:2em;width:2em;padding:.5em;cursor:pointer;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;border-radius:.15em;background:url('data:image/svg+xml;utf8, ') no-repeat 50%;background-size:0;transition:all .3s}.pickr .pcr-button:before{background:url('data:image/svg+xml;utf8, ');background-size:.5em;z-index:-1;z-index:auto}.pickr .pcr-button:after,.pickr .pcr-button:before{position:absolute;content:"";top:0;left:0;width:100%;height:100%;border-radius:.15em}.pickr .pcr-button:after{transition:background .3s;background:currentColor}.pickr .pcr-button.clear{background-size:70%}.pickr .pcr-button.clear:before{opacity:0}.pickr .pcr-button.clear:focus{box-shadow:0 0 0 1px #f1f3f4,0 0 0 3px currentColor}.pickr .pcr-button.disabled{cursor:not-allowed}.pcr-app button,.pcr-app input,.pickr button,.pickr input{outline:none;border:none;-webkit-appearance:none}.pcr-app button:focus,.pcr-app input:focus,.pickr button:focus,.pickr input:focus{box-shadow:0 0 0 1px #f1f3f4,0 0 0 3px currentColor}.pcr-app[data-theme=nano]{position:absolute;display:flex;flex-direction:column;z-index:10000;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;box-shadow:0 .15em 1.5em 0 rgba(0,0,0,.1),0 0 1em 0 rgba(0,0,0,.03);width:14.25em;max-width:95vw;border-radius:.1em;background:#fff;opacity:0;visibility:hidden;transition:opacity .3s;left:0;top:0}.pcr-app[data-theme=nano].visible{visibility:visible;opacity:1}.pcr-app[data-theme=nano] .pcr-swatches{display:grid;align-items:center;grid-template-columns:repeat(auto-fit,1.75em);margin-top:.6em;padding:0 .6em}.pcr-app[data-theme=nano] .pcr-swatches.pcr-last{margin:0}.pcr-app[data-theme=nano] .pcr-swatches>button{font-size:1em;position:relative;width:calc(1.75em - 5px);height:calc(1.75em - 5px);border-radius:.15em;cursor:pointer;margin:2.5px;transition:all .15s;overflow:hidden;background:transparent;z-index:1}.pcr-app[data-theme=nano] .pcr-swatches>button:before{position:absolute;content:"";top:0;left:0;width:100%;height:100%;background:url('data:image/svg+xml;utf8, ');background-size:6px;border-radius:.15em;z-index:-1}.pcr-app[data-theme=nano] .pcr-swatches>button:after{content:"";position:absolute;top:0;left:0;width:100%;height:100%;background:currentColor;border:1px solid rgba(0,0,0,.05);border-radius:.15em;box-sizing:border-box}.pcr-app[data-theme=nano] .pcr-swatches>button:hover{filter:brightness(1.05)}.pcr-app[data-theme=nano] .pcr-interaction{display:flex;flex-wrap:wrap;align-items:center;margin:0 -.2em;padding:0 .6em .6em}.pcr-app[data-theme=nano] .pcr-interaction>*{margin:0 .2em}.pcr-app[data-theme=nano] .pcr-interaction input{letter-spacing:.07em;font-size:.75em;text-align:center;cursor:pointer;color:#75797e;background:#f1f3f4;border-radius:.15em;transition:all .15s;padding:.45em .5em;margin-top:.6em}.pcr-app[data-theme=nano] .pcr-interaction input:hover{filter:brightness(.975)}.pcr-app[data-theme=nano] .pcr-interaction input:focus{box-shadow:0 0 0 1px #f1f3f4,0 0 0 3px rgba(66,133,244,.75)}.pcr-app[data-theme=nano] .pcr-interaction .pcr-result{color:#75797e;text-align:left;flex:1 1 8em;min-width:8em;transition:all .2s;border-radius:.15em;background:#f1f3f4;cursor:text}.pcr-app[data-theme=nano] .pcr-interaction .pcr-result::selection{background:#4285f4;color:#fff}.pcr-app[data-theme=nano] .pcr-interaction .pcr-type.active{color:#fff;background:#4285f4}.pcr-app[data-theme=nano] .pcr-interaction .pcr-clear,.pcr-app[data-theme=nano] .pcr-interaction .pcr-save{width:auto;color:#fff}.pcr-app[data-theme=nano] .pcr-interaction .pcr-clear:hover,.pcr-app[data-theme=nano] .pcr-interaction .pcr-save:hover{filter:brightness(.925)}.pcr-app[data-theme=nano] .pcr-interaction .pcr-save{background:#4285f4}.pcr-app[data-theme=nano] .pcr-interaction .pcr-clear{background:#f44250}.pcr-app[data-theme=nano] .pcr-interaction .pcr-clear:focus{box-shadow:0 0 0 1px #f1f3f4,0 0 0 3px rgba(244,66,80,.75)}.pcr-app[data-theme=nano] .pcr-selection{display:grid;grid-gap:.6em;grid-template-columns:1fr 4fr;grid-template-rows:5fr auto auto;align-items:center;height:10.5em;width:100%;align-self:flex-start}.pcr-app[data-theme=nano] .pcr-selection .pcr-picker{position:absolute;height:18px;width:18px;border:2px solid #fff;border-radius:100%;user-select:none}.pcr-app[data-theme=nano] .pcr-selection .pcr-color-preview{grid-area:2/1/4/1;height:100%;width:100%;display:flex;flex-direction:row;justify-content:center;margin-left:.6em}.pcr-app[data-theme=nano] .pcr-selection .pcr-color-preview .pcr-last-color{display:none}.pcr-app[data-theme=nano] .pcr-selection .pcr-color-preview .pcr-current-color{position:relative;background:currentColor;width:2em;height:2em;border-radius:50em;overflow:hidden}.pcr-app[data-theme=nano] .pcr-selection .pcr-color-preview .pcr-current-color:before{position:absolute;content:"";top:0;left:0;width:100%;height:100%;background:url('data:image/svg+xml;utf8, ');background-size:.5em;border-radius:.15em;z-index:-1}.pcr-app[data-theme=nano] .pcr-selection .pcr-color-chooser,.pcr-app[data-theme=nano] .pcr-selection .pcr-color-opacity,.pcr-app[data-theme=nano] .pcr-selection .pcr-color-palette{position:relative;user-select:none;display:flex;flex-direction:column;cursor:grab;cursor:-moz-grab;cursor:-webkit-grab}.pcr-app[data-theme=nano] .pcr-selection .pcr-color-chooser:active,.pcr-app[data-theme=nano] .pcr-selection .pcr-color-opacity:active,.pcr-app[data-theme=nano] .pcr-selection .pcr-color-palette:active{cursor:grabbing;cursor:-moz-grabbing;cursor:-webkit-grabbing}.pcr-app[data-theme=nano] .pcr-selection .pcr-color-palette{grid-area:1/1/2/3;width:100%;height:100%;z-index:1}.pcr-app[data-theme=nano] .pcr-selection .pcr-color-palette .pcr-palette{border-radius:.15em;width:100%;height:100%}.pcr-app[data-theme=nano] .pcr-selection .pcr-color-palette .pcr-palette:before{position:absolute;content:"";top:0;left:0;width:100%;height:100%;background:url('data:image/svg+xml;utf8, ');background-size:.5em;border-radius:.15em;z-index:-1}.pcr-app[data-theme=nano] .pcr-selection .pcr-color-chooser{grid-area:2/2/2/2}.pcr-app[data-theme=nano] .pcr-selection .pcr-color-opacity{grid-area:3/2/3/2}.pcr-app[data-theme=nano] .pcr-selection .pcr-color-chooser,.pcr-app[data-theme=nano] .pcr-selection .pcr-color-opacity{height:.5em;margin:0 .6em}.pcr-app[data-theme=nano] .pcr-selection .pcr-color-chooser .pcr-picker,.pcr-app[data-theme=nano] .pcr-selection .pcr-color-opacity .pcr-picker{top:50%;transform:translateY(-50%)}.pcr-app[data-theme=nano] .pcr-selection .pcr-color-chooser .pcr-slider,.pcr-app[data-theme=nano] .pcr-selection .pcr-color-opacity .pcr-slider{flex-grow:1;border-radius:50em}.pcr-app[data-theme=nano] .pcr-selection .pcr-color-chooser .pcr-slider{background:linear-gradient(90deg,red,#ff0,#0f0,#0ff,#00f,#f0f,red)}.pcr-app[data-theme=nano] .pcr-selection .pcr-color-opacity .pcr-slider{background:linear-gradient(90deg,transparent,#000),url('data:image/svg+xml;utf8, ');background-size:100%,.25em}
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/public/color-picker.js:
--------------------------------------------------------------------------------
1 |
2 | /*! Pickr 1.2.1 MIT | https://github.com/Simonwep/pickr */
3 | !function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.Pickr=e():t.Pickr=e()}(window,function(){return function(t){var e={};function o(n){if(e[n])return e[n].exports;var i=e[n]={i:n,l:!1,exports:{}};return t[n].call(i.exports,i,i.exports,o),i.l=!0,i.exports}return o.m=t,o.c=e,o.d=function(t,e,n){o.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:n})},o.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},o.t=function(t,e){if(1&e&&(t=o(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var n=Object.create(null);if(o.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var i in t)o.d(n,i,function(e){return t[e]}.bind(null,i));return n},o.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return o.d(e,"a",e),e},o.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},o.p="",o(o.s=0)}([function(t,e,o){"use strict";o.r(e);var n={};function i(t){for(var e=1;et)){function o(o){const n=[.001,.01,.1][Number(o.shiftKey||2*o.ctrlKey)]*(o.deltaY<0?1:-1);let i=0,r=t.selectionStart;t.value=t.value.replace(/[\d.]+/g,(t,o)=>o<=r&&o+t.length>=r?(r=o,e(Number(t),n,i)):(i++,t)),t.focus(),t.setSelectionRange(r,r),o.preventDefault(),t.dispatchEvent(new Event("input"))}s(t,"focus",()=>s(window,"wheel",o,{passive:!1})),s(t,"blur",()=>a(window,"wheel",o))}const{min:f,max:m,floor:v,round:y}=Math;function b(t,e,o){e/=100,o/=100;let n=v(t=t/360*6),i=t-n,r=o*(1-e),s=o*(1-i*e),a=o*(1-(1-i)*e),c=n%6;return[255*[o,s,r,r,a,o][c],255*[a,o,o,s,r,r][c],255*[r,r,a,o,o,s][c]]}function g(t,e,o){let n=(2-(e/=100))*(o/=100)/2;return 0!==n&&(e=1===n?0:n<.5?e*o/(2*n):e*o/(2-2*n)),[t,100*e,100*n]}function _(t,e,o){let n,i,r;const s=f(t/=255,e/=255,o/=255),a=m(t,e,o),c=a-s;if(0===c)n=i=0;else{i=c/a;let r=((a-t)/6+c/2)/c,s=((a-e)/6+c/2)/c,l=((a-o)/6+c/2)/c;t===a?n=l-s:e===a?n=1/3+r-l:o===a&&(n=2/3+s-r),n<0?n+=1:n>1&&(n-=1)}return[360*n,100*i,100*(r=a)]}function w(t,e,o,n){return e/=100,o/=100,[..._(255*(1-f(1,(t/=100)*(1-(n/=100))+n)),255*(1-f(1,e*(1-n)+n)),255*(1-f(1,o*(1-n)+n)))]}function k(t,e,o){return e/=100,[t,2*(e*=(o/=100)<.5?o:1-o)/(o+e)*100,100*(o+e)]}function C(t){return _(...t.match(/.{2}/g).map(t=>parseInt(t,16)))}function A(t){t=t.match(/^[a-zA-Z]+$/)?function(t){if("black"===t.toLowerCase())return"#000000";const e=document.createElement("canvas").getContext("2d");return e.fillStyle=t,"#000000"===e.fillStyle?null:e.fillStyle}(t):t;const e={cmyk:/^cmyk[\D]+([\d.]+)[\D]+([\d.]+)[\D]+([\d.]+)[\D]+([\d.]+)/i,rgba:/^((rgba)|rgb)[\D]+([\d.]+)[\D]+([\d.]+)[\D]+([\d.]+)[\D]*?([\d.]+|$)/i,hsla:/^((hsla)|hsl)[\D]+([\d.]+)[\D]+([\d.]+)[\D]+([\d.]+)[\D]*?([\d.]+|$)/i,hsva:/^((hsva)|hsv)[\D]+([\d.]+)[\D]+([\d.]+)[\D]+([\d.]+)[\D]*?([\d.]+|$)/i,hexa:/^#?(([\dA-Fa-f]{3,4})|([\dA-Fa-f]{6})|([\dA-Fa-f]{8}))$/i},o=t=>t.map(t=>/^(|\d+)\.\d+|\d+$/.test(t)?Number(t):void 0);let n;t:for(const i in e){if(!(n=e[i].exec(t)))continue;const r=!!n[2];switch(i){case"cmyk":{let[,t,e,r,s]=o(n);if(t>100||e>100||r>100||s>100)break t;return{values:w(t,e,r,s),type:i}}case"rgba":{let[,,,t,e,s,a]=o(n);if(t>255||e>255||s>255||a<0||a>1||r===!a)break t;return{values:[..._(t,e,s),a],a:a,type:i}}case"hexa":{let[,t]=n;4!==t.length&&3!==t.length||(t=t.split("").map(t=>t+t).join(""));const e=t.substring(0,6);let o=t.substring(6);return o=o?parseInt(o,16)/255:void 0,{values:[...C(e),o],a:o,type:i}}case"hsla":{let[,,,t,e,s,a]=o(n);if(t>360||e>100||s>100||a<0||a>1||r===!a)break t;return{values:[...k(t,e,s),a],a:a,type:i}}case"hsva":{let[,,,t,e,s,a]=o(n);if(t>360||e>100||s>100||a<0||a>1||r===!a)break t;return{values:[t,e,s,a],a:a,type:i}}}}return{values:null,type:null}}function S(t=0,e=0,o=0,n=1){const i=(t,e)=>(o=-1)=>e(~o?t.map(t=>Number(t.toFixed(o))):t),r={h:t,s:e,v:o,a:n,toHSVA(){const t=[r.h,r.s,r.v,r.a];return t.toString=i(t,t=>"hsva(".concat(t[0],", ").concat(t[1],"%, ").concat(t[2],"%, ").concat(r.a,")")),t},toHSLA(){const t=[...g(r.h,r.s,r.v),r.a];return t.toString=i(t,t=>"hsla(".concat(t[0],", ").concat(t[1],"%, ").concat(t[2],"%, ").concat(r.a,")")),t},toRGBA(){const t=[...b(r.h,r.s,r.v),r.a];return t.toString=i(t,t=>"rgba(".concat(t[0],", ").concat(t[1],", ").concat(t[2],", ").concat(r.a,")")),t},toCMYK(){const t=function(t,e,o){const n=b(t,e,o),i=n[0]/255,r=n[1]/255,s=n[2]/255;let a,c,l,p;return[100*(c=1===(a=f(1-i,1-r,1-s))?0:(1-i-a)/(1-a)),100*(l=1===a?0:(1-r-a)/(1-a)),100*(p=1===a?0:(1-s-a)/(1-a)),100*a]}(r.h,r.s,r.v);return t.toString=i(t,t=>"cmyk(".concat(t[0],"%, ").concat(t[1],"%, ").concat(t[2],"%, ").concat(t[3],"%)")),t},toHEXA(){const t=function(t,e,o){return b(t,e,o).map(t=>y(t).toString(16).padStart(2,"0"))}(r.h,r.s,r.v),e=r.a>=1?"":Number((255*r.a).toFixed(0)).toString(16).toUpperCase().padStart(2,"0");return e&&t.push(e),t.toString=()=>"#".concat(t.join("").toUpperCase()),t},clone:()=>S(r.h,r.s,r.v,r.a)};return r}const O=t=>Math.max(Math.min(t,1),0);function L(t){const e={options:Object.assign({lock:null,onchange:()=>0},t),_tapstart(t){s(document,["mouseup","touchend","touchcancel"],e._tapstop),s(document,["mousemove","touchmove"],e._tapmove),t.preventDefault(),e._tapmove(t)},_tapmove(t){const{options:{lock:n},cache:i}=e,{element:r,wrapper:s}=o,a=s.getBoundingClientRect();let c=0,l=0;if(t){const e=t&&t.touches&&t.touches[0];c=t?(e||t).clientX:0,l=t?(e||t).clientY:0,ca.left+a.width&&(c=a.left+a.width),la.top+a.height&&(l=a.top+a.height),c-=a.left,l-=a.top}else i&&(c=i.x*a.width,l=i.y*a.height);"h"!==n&&(r.style.left="calc(".concat(c/a.width*100,"% - ").concat(r.offsetWidth/2,"px)")),"v"!==n&&(r.style.top="calc(".concat(l/a.height*100,"% - ").concat(r.offsetHeight/2,"px)")),e.cache={x:c/a.width,y:l/a.height};const p=O(c/s.offsetWidth),u=O(l/s.offsetHeight);switch(n){case"v":return o.onchange(p);case"h":return o.onchange(u);default:return o.onchange(p,u)}},_tapstop(){a(document,["mouseup","touchend","touchcancel"],e._tapstop),a(document,["mousemove","touchmove"],e._tapmove)},trigger(){e._tapmove()},update(t=0,o=0){const{left:n,top:i,width:r,height:s}=e.options.wrapper.getBoundingClientRect();"h"===e.options.lock&&(o=t),e._tapmove({clientX:n+r*t,clientY:i+s*o})},destroy(){const{options:t,_tapstart:o}=e;a([t.wrapper,t.element],"mousedown",o),a([t.wrapper,t.element],"touchstart",o,{passive:!1})}},{options:o,_tapstart:n}=e;return s([o.wrapper,o.element],"mousedown",n),s([o.wrapper,o.element],"touchstart",n,{passive:!1}),e}function j(t={}){t=Object.assign({onchange:()=>0,className:"",elements:[]},t);const e=s(t.elements,"click",e=>{t.elements.forEach(o=>o.classList[e.target===o?"add":"remove"](t.className)),t.onchange(e)});return{destroy:()=>a(...e)}}var E=({components:t,strings:e,useAsButton:o,inline:n,appClass:i,theme:r,lockOpacity:s})=>{const a=t=>t?"":'style="display:none" hidden',c=u('\n
\n\n '.concat(o?"":'','\n\n
\n
\n
\n \n \n
\n\n
\n \n \n
\n\n
\n \n \n
\n\n
\n \n \n
\n
\n\n \n\n
\n \n\n \n \n \n \n \n\n \n \n \n
\n
\n
\n ")),l=c.interaction;return l.options.find(t=>!t.hidden&&!t.classList.add("active")),l.type=()=>l.options.find(t=>t.classList.contains("active")),c};function P(t,e,o){return e in t?Object.defineProperty(t,e,{value:o,enumerable:!0,configurable:!0,writable:!0}):t[e]=o,t}class B{constructor(t){P(this,"_initializingActive",!0),P(this,"_recalc",!0),P(this,"_color",S()),P(this,"_lastColor",S()),P(this,"_swatchColors",[]),P(this,"_eventListener",{swatchselect:[],change:[],save:[],init:[]}),this.options=t=Object.assign({appClass:null,theme:"classic",useAsButton:!1,disabled:!1,comparison:!0,closeOnScroll:!1,outputPrecision:0,lockOpacity:!1,autoReposition:!0,components:{interaction:{}},strings:{},swatches:null,inline:!1,sliders:null,default:"#42445a",defaultRepresentation:null,position:"bottom-middle",adjustableNumbers:!0,showAlways:!1,closeWithKey:"Escape"},t);const{swatches:e,inline:o,components:n,theme:i,sliders:r,lockOpacity:s}=t;["nano","monolith"].includes(i)&&!r&&(t.sliders="h"),n.interaction||(n.interaction={});const{preview:a,opacity:c,hue:l,palette:p}=n;n.opacity=!s&&c,n.palette=p||a||c||l,o&&(t.showAlways=!0),this._preBuild(),this._buildComponents(),this._bindEvents(),this._finalBuild(),e&&e.length&&e.forEach(t=>this.addSwatch(t)),this._nanopop=function({el:t,reference:e,padding:o=8}){const n={start:"sme",middle:"mse",end:"ems"},i={top:"tbrl",right:"rltb",bottom:"btrl",left:"lrbt"},r=((t={})=>(e,o=t[e])=>{if(o)return o;const[n,i="middle"]=e.split("-"),r="top"===n||"bottom"===n;return t[e]={position:n,variant:i,isVertical:r}})();return{update(s){const{position:a,variant:c,isVertical:l}=r(s),p=e.getBoundingClientRect(),u=t.getBoundingClientRect(),h=(t=>{let e=0,o=0;for(;t=t.parentElement;)e+=t.scrollTop,o+=t.scrollLeft;return{top:e,left:o}})(t),d=t=>t?{t:p.top-u.height-o+h.top,b:p.bottom+o+h.top}:{r:p.right+o+h.left,l:p.left-u.width-o+h.left},f=t=>t?{s:p.left+p.width-u.width+h.left,m:-u.width/2+(p.left+p.width/2)+h.left,e:p.left+h.left}:{s:p.bottom-u.height+h.top,m:p.bottom-p.height/2-u.height/2+h.top,e:p.bottom-p.height+h.top};function m(e,o,n){const i="top"===n,r=i?u.height:u.width,s=window[i?"innerHeight":"innerWidth"]+(i?h.top:h.left);for(const a of e){const e=o[a];if(e-(i?h.top:h.left)>0&&e+r>/g).reduce((t,e,o,n)=>(t=t.querySelector(e),o{const{sliders:e}=t.options;let o="v",n="v";e&&e.match(/^[vh]+$/g)&&(e.length>1?[o,n]=e:o=n=e);const i={v:"h",h:"v"};return[i[o],i[n]]})(),i={palette:L({element:t._root.palette.picker,wrapper:t._root.palette.palette,onchange(o,n){if(!e.palette)return;const{_color:i,_root:r,options:s}=t;t._recalc&&(i.s=100*o,i.v=100-100*n,i.v<0&&(i.v=0),t._updateOutput());let a=i.toRGBA().toString(0);this.element.style.background=a,this.wrapper.style.background="\n linear-gradient(to top, rgba(0, 0, 0, ".concat(i.a,"), transparent),\n linear-gradient(to left, hsla(").concat(i.h,", 100%, 50%, ").concat(i.a,"), rgba(255, 255, 255, ").concat(i.a,"))\n "),s.comparison||(r.button.style.color=a,s.useAsButton||(r.preview.lastColor.style.color=a)),r.preview.currentColor.style.color=a,t.options.comparison||r.button.classList.remove("clear")}}),hue:L({lock:n,element:t._root.hue.picker,wrapper:t._root.hue.slider,onchange(o){e.hue&&e.palette&&(t._recalc&&(t._color.h=360*o),this.element.style.backgroundColor="hsl(".concat(t._color.h,", 100%, 50%)"),i.palette.trigger())}}),opacity:L({lock:o,element:t._root.opacity.picker,wrapper:t._root.opacity.slider,onchange(o){e.opacity&&e.palette&&(t._recalc&&(t._color.a=Math.round(100*o)/100),this.element.style.background="rgba(0, 0, 0, ".concat(t._color.a,")"),i.palette.trigger())}}),selectable:j({elements:t._root.interaction.options,className:"active",onchange(e){t._representation=e.target.getAttribute("data-type").toUpperCase(),t._updateOutput()}})};this._components=i}_bindEvents(){const{_root:t,options:e}=this,o=[s(t.interaction.clear,"click",()=>this._clearColor()),s([t.interaction.cancel,t.preview.lastColor],"click",()=>this.setHSVA(...this._lastColor.toHSVA())),s(t.interaction.save,"click",()=>{!this.applyColor()&&!e.showAlways&&this.hide()}),s(t.interaction.result,["keyup","input"],t=>{this._recalc=!1,this.setColor(t.target.value,!0)&&!this._initializingActive&&this._emit("change",this._color),t.stopImmediatePropagation()}),s([t.palette.palette,t.palette.picker,t.hue.slider,t.hue.picker,t.opacity.slider,t.opacity.picker],["mousedown","touchstart"],()=>this._recalc=!0)];if(!e.showAlways){const n=e.closeWithKey;o.push(s(t.button,"click",()=>this.isOpen()?this.hide():this.show()),s(document,"keyup",t=>this.isOpen()&&(t.key===n||t.code===n)&&this.hide()),s(document,["touchstart","mousedown"],e=>{this.isOpen()&&!h(e).some(e=>e===t.app||e===t.button)&&this.hide()},{capture:!0}))}if(e.adjustableNumbers){const e={rgba:[255,255,255,1],hsva:[360,100,100,1],hsla:[360,100,100,1],cmyk:[100,100,100,100]};d(t.interaction.result,(t,o,n)=>{const i=e[this.getColorRepresentation().toLowerCase()];if(i){const e=i[n],r=t+(e>=100?1e3*o:o);return r<=0?0:Number((r{n.isOpen()&&(e.closeOnScroll&&n.hide(),null===t?(t=setTimeout(()=>t=null,100),requestAnimationFrame(function e(){n._rePositioningPicker(),null!==t&&requestAnimationFrame(e)})):(clearTimeout(t),t=setTimeout(()=>t=null,100)))},{capture:!0}))}this._eventBindings=o}_rePositioningPicker(){const{options:t}=this;t.inline||this._nanopop.update(t.position)}_updateOutput(){const{_root:t,_color:e,options:o}=this;if(t.interaction.type()){const n="to".concat(t.interaction.type().getAttribute("data-type"));t.interaction.result.value="function"==typeof e[n]?e[n]().toString(o.outputPrecision):""}!this._initializingActive&&this._recalc&&this._emit("change",e)}_clearColor(t=!1){const{_root:e,options:o}=this;o.useAsButton||(e.button.style.color="rgba(0, 0, 0, 0.15)"),e.button.classList.add("clear"),o.showAlways||this.hide(),this._initializingActive||t||this._emit("save",null)}_emit(t,...e){this._eventListener[t].forEach(t=>t(...e,this))}_parseLocalColor(t){const{values:e,type:o,a:n}=A(t),{lockOpacity:i}=this.options,r=void 0!==n&&1!==n;return e&&3===e.length&&(e[3]=void 0),{values:!e||i&&r?null:e,type:o}}on(t,e){return"function"==typeof e&&"string"==typeof t&&t in this._eventListener&&this._eventListener[t].push(e),this}off(t,e){const o=this._eventListener[t];if(o){const t=o.indexOf(e);~t&&o.splice(t,1)}return this}addSwatch(t){const{values:e}=this._parseLocalColor(t);if(e){const{_swatchColors:t,_root:o}=this,n=S(...e),i=l(''));return o.swatches.appendChild(i),t.push({element:i,hsvaColorObject:n}),this._eventBindings.push(s(i,"click",()=>{this.setHSVA(...n.toHSVA(),!0),this._emit("swatchselect",n)})),!0}return!1}removeSwatch(t){const e=this._swatchColors[t];if(e){const{element:o}=e;return this._root.swatches.removeChild(o),this._swatchColors.splice(t,1),!0}return!1}applyColor(t=!1){const{preview:e,button:o}=this._root,n=this._color.toRGBA().toString();e.lastColor.style.color=n,this.options.useAsButton||(o.style.color=n),o.classList.remove("clear"),this._lastColor=this._color.clone(),this._initializingActive||t||this._emit("save",this._color)}destroy(){this._eventBindings.forEach(t=>a(...t)),Object.keys(this._components).forEach(t=>this._components[t].destroy())}destroyAndRemove(){this.destroy();const{root:t,app:e}=this._root;t.parentElement.removeChild(t),e.parentElement.removeChild(e),Object.keys(this).forEach(t=>this[t]=null)}hide(){return this._root.app.classList.remove("visible"),this}show(){if(!this.options.disabled)return this._root.app.classList.add("visible"),this._rePositioningPicker(),this}isOpen(){return this._root.app.classList.contains("visible")}setHSVA(t=360,e=0,o=0,n=1,i=!1){const r=this._recalc;if(this._recalc=!1,t<0||t>360||e<0||e>100||o<0||o>100||n<0||n>1)return!1;this._color=S(t,e,o,n);const{hue:s,opacity:a,palette:c}=this._components;return s.update(t/360),a.update(n),c.update(e/100,1-o/100),i||this.applyColor(),r&&this._updateOutput(),this._recalc=r,!0}setColor(t,e=!1){if(null===t)return this._clearColor(e),!0;const{values:o,type:n}=this._parseLocalColor(t);if(o){const t=n.toUpperCase(),{options:i}=this._root.interaction,r=i.find(e=>e.getAttribute("data-type")===t);if(r&&!r.hidden)for(const t of i)t.classList[t===r?"add":"remove"]("active");return this.setHSVA(...o,e)}return!1}setColorRepresentation(t){return t=t.toUpperCase(),!!this._root.interaction.options.find(e=>e.getAttribute("data-type").startsWith(t)&&!e.click())}getColorRepresentation(){return this._representation}getColor(){return this._color}getRoot(){return this._root}disable(){return this.hide(),this.options.disabled=!0,this._root.button.classList.add("disabled"),this}enable(){return this.options.disabled=!1,this._root.button.classList.remove("disabled"),this}}B.utils=n,B.create=t=>new B(t),B.version="1.2.1";e.default=B}]).default});
4 | //# sourceMappingURL=pickr.min.js.map
--------------------------------------------------------------------------------
/docs/imgs/Google-Assistant-Data-Flow.svg:
--------------------------------------------------------------------------------
1 |
2 |
174 |
--------------------------------------------------------------------------------
/services/motion/motion.conf:
--------------------------------------------------------------------------------
1 | # Rename this distribution example file to motion.conf
2 | #
3 | # This config file was generated by motion 4.0
4 |
5 |
6 | ############################################################
7 | # Daemon
8 | ############################################################
9 |
10 | # Start in daemon (background) mode and release terminal (default: off)
11 | daemon on
12 |
13 | # File to store the process ID, also called pid file. (default: not defined)
14 | process_id_file /var/run/motion/motion.pid
15 |
16 | ############################################################
17 | # Basic Setup Mode
18 | ############################################################
19 |
20 | # Start in Setup-Mode, daemon disabled. (default: off)
21 | setup_mode off
22 |
23 |
24 | # Use a file to save logs messages, if not defined stderr and syslog is used. (default: not defined)
25 | logfile /var/log/motion/motion.log
26 |
27 | # Level of log messages [1..9] (EMG, ALR, CRT, ERR, WRN, NTC, INF, DBG, ALL). (default: 6 / NTC)
28 | log_level 6
29 |
30 | # Filter to log messages by type (COR, STR, ENC, NET, DBL, EVT, TRK, VID, ALL). (default: ALL)
31 | log_type all
32 |
33 | ###########################################################
34 | # Capture device options
35 | ############################################################
36 |
37 | # Videodevice to be used for capturing (default /dev/video0)
38 | # for FreeBSD default is /dev/bktr0
39 | videodevice /dev/video0
40 |
41 | # v4l2_palette allows one to choose preferable palette to be use by motion
42 | # to capture from those supported by your videodevice. (default: 17)
43 | # E.g. if your videodevice supports both V4L2_PIX_FMT_SBGGR8 and
44 | # V4L2_PIX_FMT_MJPEG then motion will by default use V4L2_PIX_FMT_MJPEG.
45 | # Setting v4l2_palette to 2 forces motion to use V4L2_PIX_FMT_SBGGR8
46 | # instead.
47 | #
48 | # Values :
49 | # V4L2_PIX_FMT_SN9C10X : 0 'S910'
50 | # V4L2_PIX_FMT_SBGGR16 : 1 'BYR2'
51 | # V4L2_PIX_FMT_SBGGR8 : 2 'BA81'
52 | # V4L2_PIX_FMT_SPCA561 : 3 'S561'
53 | # V4L2_PIX_FMT_SGBRG8 : 4 'GBRG'
54 | # V4L2_PIX_FMT_SGRBG8 : 5 'GRBG'
55 | # V4L2_PIX_FMT_PAC207 : 6 'P207'
56 | # V4L2_PIX_FMT_PJPG : 7 'PJPG'
57 | # V4L2_PIX_FMT_MJPEG : 8 'MJPEG'
58 | # V4L2_PIX_FMT_JPEG : 9 'JPEG'
59 | # V4L2_PIX_FMT_RGB24 : 10 'RGB3'
60 | # V4L2_PIX_FMT_SPCA501 : 11 'S501'
61 | # V4L2_PIX_FMT_SPCA505 : 12 'S505'
62 | # V4L2_PIX_FMT_SPCA508 : 13 'S508'
63 | # V4L2_PIX_FMT_UYVY : 14 'UYVY'
64 | # V4L2_PIX_FMT_YUYV : 15 'YUYV'
65 | # V4L2_PIX_FMT_YUV422P : 16 '422P'
66 | # V4L2_PIX_FMT_YUV420 : 17 'YU12'
67 | #
68 | v4l2_palette 17
69 |
70 | # Tuner device to be used for capturing using tuner as source (default /dev/tuner0)
71 | # This is ONLY used for FreeBSD. Leave it commented out for Linux
72 | ; tunerdevice /dev/tuner0
73 |
74 | # The video input to be used (default: -1)
75 | # Should normally be set to 0 or 1 for video/TV cards, and -1 for USB cameras
76 | # Set to 0 for uvideo(4) on OpenBSD
77 | input -1
78 |
79 | # The video norm to use (only for video capture and TV tuner cards)
80 | # Values: 0 (PAL), 1 (NTSC), 2 (SECAM), 3 (PAL NC no colour). Default: 0 (PAL)
81 | norm 0
82 |
83 | # The frequency to set the tuner to (kHz) (only for TV tuner cards) (default: 0)
84 | frequency 0
85 |
86 | # Override the power line frequency for the webcam. (normally not necessary)
87 | # Values:
88 | # -1 : Do not modify device setting
89 | # 0 : Power line frequency Disabled
90 | # 1 : 50hz
91 | # 2 : 60hz
92 | # 3 : Auto
93 | power_line_frequency -1
94 |
95 | # Rotate image this number of degrees. The rotation affects all saved images as
96 | # well as movies. Valid values: 0 (default = no rotation), 90, 180 and 270.
97 | rotate 0
98 |
99 | # Image width (pixels). Valid range: Camera dependent, default: 352
100 | width 1280
101 |
102 | # Image height (pixels). Valid range: Camera dependent, default: 288
103 | height 720
104 |
105 | # Maximum number of frames to be captured per second.
106 | # Valid range: 2-100. Default: 100 (almost no limit).
107 | framerate 30
108 |
109 | # Minimum time in seconds between capturing picture frames from the camera.
110 | # Default: 0 = disabled - the capture rate is given by the camera framerate.
111 | # This option is used when you want to capture images at a rate lower than 2 per second.
112 | minimum_frame_time 0
113 |
114 | # URL to use if you are using a network camera, size will be autodetected (incl http:// ftp:// mjpg:// rtsp:// mjpeg:// or file:///)
115 | # Must be a URL that returns single jpeg pictures or a raw mjpeg stream. A trailing slash may be required for some cameras.
116 | # Default: Not defined
117 | ; netcam_url value
118 |
119 | # Username and password for network camera (only if required). Default: not defined
120 | # Syntax is user:password
121 | ; netcam_userpass value
122 |
123 | # The setting for keep-alive of network socket, should improve performance on compatible net cameras.
124 | # off: The historical implementation using HTTP/1.0, closing the socket after each http request.
125 | # force: Use HTTP/1.0 requests with keep alive header to reuse the same connection.
126 | # on: Use HTTP/1.1 requests that support keep alive as default.
127 | # Default: off
128 | netcam_keepalive off
129 |
130 | # URL to use for a netcam proxy server, if required, e.g. "http://myproxy".
131 | # If a port number other than 80 is needed, use "http://myproxy:1234".
132 | # Default: not defined
133 | ; netcam_proxy value
134 |
135 | # Set less strict jpeg checks for network cameras with a poor/buggy firmware.
136 | # Default: off
137 | netcam_tolerant_check off
138 |
139 | # RTSP connection uses TCP to communicate to the camera. Can prevent image corruption.
140 | # Default: on
141 | rtsp_uses_tcp on
142 |
143 | # Name of camera to use if you are using a camera accessed through OpenMax/MMAL
144 | # Default: Not defined
145 | ; mmalcam_name vc.ril.camera
146 |
147 | # Camera control parameters (see raspivid/raspistill tool documentation)
148 | # Default: Not defined
149 | ; mmalcam_control_params -hf
150 |
151 | # Let motion regulate the brightness of a video device (default: off).
152 | # The auto_brightness feature uses the brightness option as its target value.
153 | # If brightness is zero auto_brightness will adjust to average brightness value 128.
154 | # Only recommended for cameras without auto brightness
155 | auto_brightness off
156 |
157 | # Set the initial brightness of a video device.
158 | # If auto_brightness is enabled, this value defines the average brightness level
159 | # which Motion will try and adjust to.
160 | # Valid range 0-255, default 0 = disabled
161 | brightness 0
162 |
163 | # Set the contrast of a video device.
164 | # Valid range 0-255, default 0 = disabled
165 | contrast 0
166 |
167 | # Set the saturation of a video device.
168 | # Valid range 0-255, default 0 = disabled
169 | saturation 0
170 |
171 | # Set the hue of a video device (NTSC feature).
172 | # Valid range 0-255, default 0 = disabled
173 | hue 0
174 |
175 |
176 | ############################################################
177 | # Round Robin (multiple inputs on same video device name)
178 | ############################################################
179 |
180 | # Number of frames to capture in each roundrobin step (default: 1)
181 | roundrobin_frames 1
182 |
183 | # Number of frames to skip before each roundrobin step (default: 1)
184 | roundrobin_skip 1
185 |
186 | # Try to filter out noise generated by roundrobin (default: off)
187 | switchfilter off
188 |
189 |
190 | ############################################################
191 | # Motion Detection Settings:
192 | ############################################################
193 |
194 | # Threshold for number of changed pixels in an image that
195 | # triggers motion detection (default: 1500)
196 | threshold 1500
197 |
198 | # Automatically tune the threshold down if possible (default: off)
199 | threshold_tune off
200 |
201 | # Noise threshold for the motion detection (default: 32)
202 | noise_level 32
203 |
204 | # Automatically tune the noise threshold (default: on)
205 | noise_tune on
206 |
207 | # Despeckle motion image using (e)rode or (d)ilate or (l)abel (Default: not defined)
208 | # Recommended value is EedDl. Any combination (and number of) of E, e, d, and D is valid.
209 | # (l)abeling must only be used once and the 'l' must be the last letter.
210 | # Comment out to disable
211 | despeckle_filter EedDl
212 |
213 | # Detect motion in predefined areas (1 - 9). Areas are numbered like that: 1 2 3
214 | # A script (on_area_detected) is started immediately when motion is 4 5 6
215 | # detected in one of the given areas, but only once during an event. 7 8 9
216 | # One or more areas can be specified with this option. Take care: This option
217 | # does NOT restrict detection to these areas! (Default: not defined)
218 | ; area_detect value
219 |
220 | # PGM file to use as a sensitivity mask.
221 | # Full path name to. (Default: not defined)
222 | ; mask_file value
223 |
224 | # Dynamically create a mask file during operation (default: 0)
225 | # Adjust speed of mask changes from 0 (off) to 10 (fast)
226 | smart_mask_speed 0
227 |
228 | # Ignore sudden massive light intensity changes given as a percentage of the picture
229 | # area that changed intensity. Valid range: 0 - 100 , default: 0 = disabled
230 | lightswitch 0
231 |
232 | # Picture frames must contain motion at least the specified number of frames
233 | # in a row before they are detected as true motion. At the default of 1, all
234 | # motion is detected. Valid range: 1 to thousands, recommended 1-5
235 | minimum_motion_frames 1
236 |
237 | # Specifies the number of pre-captured (buffered) pictures from before motion
238 | # was detected that will be output at motion detection.
239 | # Recommended range: 0 to 5 (default: 0)
240 | # Do not use large values! Large values will cause Motion to skip video frames and
241 | # cause unsmooth movies. To smooth movies use larger values of post_capture instead.
242 | pre_capture 0
243 |
244 | # Number of frames to capture after motion is no longer detected (default: 0)
245 | post_capture 0
246 |
247 | # Event Gap is the seconds of no motion detection that triggers the end of an event.
248 | # An event is defined as a series of motion images taken within a short timeframe.
249 | # Recommended value is 60 seconds (Default). The value -1 is allowed and disables
250 | # events causing all Motion to be written to one single movie file and no pre_capture.
251 | # If set to 0, motion is running in gapless mode. Movies don't have gaps anymore. An
252 | # event ends right after no more motion is detected and post_capture is over.
253 | event_gap 60
254 |
255 | # Maximum length in seconds of a movie
256 | # When value is exceeded a new movie file is created. (Default: 0 = infinite)
257 | max_movie_time 0
258 |
259 | # Always save images even if there was no motion (default: off)
260 | emulate_motion off
261 |
262 |
263 | ############################################################
264 | # Image File Output
265 | ############################################################
266 |
267 | # Output 'normal' pictures when motion is detected (default: on)
268 | # Valid values: on, off, first, best, center
269 | # When set to 'first', only the first picture of an event is saved.
270 | # Picture with most motion of an event is saved when set to 'best'.
271 | # Picture with motion nearest center of picture is saved when set to 'center'.
272 | # Can be used as preview shot for the corresponding movie.
273 | output_pictures off
274 |
275 | # Output pictures with only the pixels moving object (ghost images) (default: off)
276 | output_debug_pictures off
277 |
278 | # The quality (in percent) to be used by the jpeg compression (default: 75)
279 | quality 90
280 |
281 | # Type of output images
282 | # Valid values: jpeg, ppm (default: jpeg)
283 | picture_type jpeg
284 |
285 | ############################################################
286 | # FFMPEG related options
287 | # Film (movies) file output, and deinterlacing of the video input
288 | # The options movie_filename and timelapse_filename are also used
289 | # by the ffmpeg feature
290 | ############################################################
291 |
292 | # Use ffmpeg to encode movies in realtime (default: off)
293 | ffmpeg_output_movies on
294 |
295 | # Use ffmpeg to make movies with only the pixels moving
296 | # object (ghost images) (default: off)
297 | ffmpeg_output_debug_movies off
298 |
299 | # Use ffmpeg to encode a timelapse movie
300 | # Default value 0 = off - else save frame every Nth second
301 | ffmpeg_timelapse 0
302 |
303 | # The file rollover mode of the timelapse video
304 | # Valid values: hourly, daily (default), weekly-sunday, weekly-monday, monthly, manual
305 | ffmpeg_timelapse_mode daily
306 |
307 | # Bitrate to be used by the ffmpeg encoder (default: 400000)
308 | # This option is ignored if ffmpeg_variable_bitrate is not 0 (disabled)
309 | ffmpeg_bps 600000
310 |
311 | # Enables and defines variable bitrate for the ffmpeg encoder.
312 | # ffmpeg_bps is ignored if variable bitrate is enabled.
313 | # Valid values: 0 (default) = fixed bitrate defined by ffmpeg_bps,
314 | # or the range 1 - 100 where 1 means worst quality and 100 is best.
315 | ffmpeg_variable_bitrate 85
316 |
317 | # Codec to used by ffmpeg for the video compression.
318 | # Timelapse videos have two options.
319 | # mpg - Creates mpg file with mpeg-2 encoding.
320 | # If motion is shutdown and restarted, new pics will be appended
321 | # to any previously created file with name indicated for timelapse.
322 | # mpeg4 - Creates avi file with the default encoding.
323 | # If motion is shutdown and restarted, new pics will create a
324 | # new file with the name indicated for timelapse.
325 | # Supported formats are:
326 | # mpeg4 or msmpeg4 - gives you files with extension .avi
327 | # msmpeg4 is recommended for use with Windows Media Player because
328 | # it requires no installation of codec on the Windows client.
329 | # swf - gives you a flash film with extension .swf
330 | # flv - gives you a flash video with extension .flv
331 | # ffv1 - FF video codec 1 for Lossless Encoding
332 | # mov - QuickTime
333 | # mp4 - MPEG-4 Part 14 H264 encoding
334 | # mkv - Matroska H264 encoding
335 | # hevc - H.265 / HEVC (High Efficiency Video Coding)
336 | ffmpeg_video_codec mp4
337 |
338 | # When creating videos, should frames be duplicated in order
339 | # to keep up with the requested frames per second
340 | # (default: true)
341 | ffmpeg_duplicate_frames true
342 |
343 | ############################################################
344 | # SDL Window
345 | ############################################################
346 |
347 | # Number of motion thread to show in SDL Window (default: 0 = disabled)
348 | #sdl_threadnr 0
349 |
350 | ############################################################
351 | # External pipe to video encoder
352 | # Replacement for FFMPEG builtin encoder for ffmpeg_output_movies only.
353 | # The options movie_filename and timelapse_filename are also used
354 | # by the ffmpeg feature
355 | #############################################################
356 |
357 | # Bool to enable or disable extpipe (default: off)
358 | use_extpipe off
359 |
360 | # External program (full path and opts) to pipe raw video to
361 | # Generally, use '-' for STDIN...
362 | ;extpipe mencoder -demuxer rawvideo -rawvideo w=%w:h=%h:i420 -ovc x264 -x264encopts bframes=4:frameref=1:subq=1:scenecut=-1:nob_adapt:threads=1:keyint=1000:8x8dct:vbv_bufsize=4000:crf=24:partitions=i8x8,i4x4:vbv_maxrate=800:no-chroma-me -vf denoise3d=16:12:48:4,pp=lb -of avi -o %f.avi - -fps %fps
363 | ;extpipe x264 - --input-res %wx%h --fps %fps --bitrate 2000 --preset ultrafast --quiet -o %f.mp4
364 | ;extpipe mencoder -demuxer rawvideo -rawvideo w=%w:h=%h:fps=%fps -ovc x264 -x264encopts preset=ultrafast -of lavf -o %f.mp4 - -fps %fps
365 | ;extpipe ffmpeg -y -f rawvideo -pix_fmt yuv420p -video_size %wx%h -framerate %fps -i pipe:0 -vcodec libx264 -preset ultrafast -f mp4 %f.mp4
366 |
367 |
368 | ############################################################
369 | # Snapshots (Traditional Periodic Webcam File Output)
370 | ############################################################
371 |
372 | # Make automated snapshot every N seconds (default: 0 = disabled)
373 | snapshot_interval 0
374 |
375 |
376 | ############################################################
377 | # Text Display
378 | # %Y = year, %m = month, %d = date,
379 | # %H = hour, %M = minute, %S = second, %T = HH:MM:SS,
380 | # %v = event, %q = frame number, %t = camera id number,
381 | # %D = changed pixels, %N = noise level, \n = new line,
382 | # %i and %J = width and height of motion area,
383 | # %K and %L = X and Y coordinates of motion center
384 | # %C = value defined by text_event - do not use with text_event!
385 | # You can put quotation marks around the text to allow
386 | # leading spaces
387 | ############################################################
388 |
389 | # Locate and draw a box around the moving object.
390 | # Valid values: on, off, preview (default: off)
391 | # Set to 'preview' will only draw a box in preview_shot pictures.
392 | locate_motion_mode off
393 |
394 | # Set the look and style of the locate box if enabled.
395 | # Valid values: box, redbox, cross, redcross (default: box)
396 | # Set to 'box' will draw the traditional box.
397 | # Set to 'redbox' will draw a red box.
398 | # Set to 'cross' will draw a little cross to mark center.
399 | # Set to 'redcross' will draw a little red cross to mark center.
400 | locate_motion_style box
401 |
402 | # Draws the timestamp using same options as C function strftime(3)
403 | # Default: %Y-%m-%d\n%T = date in ISO format and time in 24 hour clock
404 | # Text is placed in lower right corner
405 | text_right %Y-%m-%d\n%T-%q
406 |
407 | # Draw a user defined text on the images using same options as C function strftime(3)
408 | # Default: Not defined = no text
409 | # Text is placed in lower left corner
410 | ; text_left CAMERA %t
411 |
412 | # Draw the number of changed pixed on the images (default: off)
413 | # Will normally be set to off except when you setup and adjust the motion settings
414 | # Text is placed in upper right corner
415 | text_changes off
416 |
417 | # This option defines the value of the special event conversion specifier %C
418 | # You can use any conversion specifier in this option except %C. Date and time
419 | # values are from the timestamp of the first image in the current event.
420 | # Default: %Y%m%d%H%M%S
421 | # The idea is that %C can be used filenames and text_left/right for creating
422 | # a unique identifier for each event.
423 | text_event %Y%m%d%H%M%S
424 |
425 | # Draw characters at twice normal size on images. (default: off)
426 | text_double off
427 |
428 |
429 | # Text to include in a JPEG EXIF comment
430 | # May be any text, including conversion specifiers.
431 | # The EXIF timestamp is included independent of this text.
432 | ;exif_text %i%J/%K%L
433 |
434 | ############################################################
435 | # Target Directories and filenames For Images And Films
436 | # For the options snapshot_, picture_, movie_ and timelapse_filename
437 | # you can use conversion specifiers
438 | # %Y = year, %m = month, %d = date,
439 | # %H = hour, %M = minute, %S = second,
440 | # %v = event, %q = frame number, %t = camera id number,
441 | # %D = changed pixels, %N = noise level,
442 | # %i and %J = width and height of motion area,
443 | # %K and %L = X and Y coordinates of motion center
444 | # %C = value defined by text_event
445 | # Quotation marks round string are allowed.
446 | ############################################################
447 |
448 | # Target base directory for pictures and films
449 | # Recommended to use absolute path. (Default: current working directory)
450 | target_dir /home/homeauto/mi-home-api/services/motion/
451 |
452 | # File path for snapshots (jpeg or ppm) relative to target_dir
453 | # Default: %v-%Y%m%d%H%M%S-snapshot
454 | # Default value is equivalent to legacy oldlayout option
455 | # For Motion 3.0 compatible mode choose: %Y/%m/%d/%H/%M/%S-snapshot
456 | # File extension .jpg or .ppm is automatically added so do not include this.
457 | # Note: A symbolic link called lastsnap.jpg created in the target_dir will always
458 | # point to the latest snapshot, unless snapshot_filename is exactly 'lastsnap'
459 | snapshot_filename snapshot/%Y/%m/%d/%H/%v-%M%S-snapshot
460 |
461 | # File path for motion triggered images (jpeg or ppm) relative to target_dir
462 | # Default: %v-%Y%m%d%H%M%S-%q
463 | # Default value is equivalent to legacy oldlayout option
464 | # For Motion 3.0 compatible mode choose: %Y/%m/%d/%H/%M/%S-%q
465 | # File extension .jpg or .ppm is automatically added so do not include this
466 | # Set to 'preview' together with best-preview feature enables special naming
467 | # convention for preview shots. See motion guide for details
468 | picture_filename picture/%Y/%m/%d/%H/%v-%M%S-%q
469 |
470 | # File path for motion triggered ffmpeg films (movies) relative to target_dir
471 | # Default: %v-%Y%m%d%H%M%S
472 | # File extensions(.mpg .avi) are automatically added so do not include them
473 | movie_filename movie/%Y/%m/%d/%v-%Y%m%d%H%M%S
474 |
475 | # File path for timelapse movies relative to target_dir
476 | # Default: %Y%m%d-timelapse
477 | # File extensions(.mpg .avi) are automatically added so do not include them
478 | timelapse_filename timelapse/%Y%m%d-timelapse
479 |
480 | ############################################################
481 | # Global Network Options
482 | ############################################################
483 | # Enable IPv6 (default: off)
484 | ipv6_enabled off
485 |
486 | ############################################################
487 | # Live Stream Server
488 | ############################################################
489 |
490 | # The mini-http server listens to this port for requests (default: 0 = disabled)
491 | stream_port 3081
492 |
493 | # Quality of the jpeg (in percent) images produced (default: 50)
494 | stream_quality 85
495 |
496 | # Output frames at 1 fps when no motion is detected and increase to the
497 | # rate given by stream_maxrate when motion is detected (default: off)
498 | stream_motion on
499 |
500 | # Maximum framerate for stream streams (default: 1)
501 | stream_maxrate 30
502 |
503 | # Restrict stream connections to localhost only (default: on)
504 | stream_localhost off
505 |
506 | # Limits the number of images per connection (default: 0 = unlimited)
507 | # Number can be defined by multiplying actual stream rate by desired number of seconds
508 | # Actual stream rate is the smallest of the numbers framerate and stream_maxrate
509 | stream_limit 0
510 |
511 | # Set the authentication method (default: 0)
512 | # 0 = disabled
513 | # 1 = Basic authentication
514 | # 2 = MD5 digest (the safer authentication)
515 | stream_auth_method 0
516 |
517 | # Authentication for the stream. Syntax username:password
518 | # Default: not defined (Disabled)
519 | ; stream_authentication username:password
520 |
521 | # Percentage to scale the stream image for preview
522 | # Default: 25
523 | ; stream_preview_scale 25
524 |
525 | # Have stream preview image start on a new line
526 | # Default: no
527 | ; stream_preview_newline no
528 |
529 | ############################################################
530 | # HTTP Based Control
531 | ############################################################
532 |
533 | # TCP/IP port for the http server to listen on (default: 0 = disabled)
534 | webcontrol_port 3080
535 |
536 | # Restrict control connections to localhost only (default: on)
537 | webcontrol_localhost off
538 |
539 | # Output for http server, select off to choose raw text plain (default: on)
540 | webcontrol_html_output on
541 |
542 | # Authentication for the http based control. Syntax username:password
543 | # Default: not defined (Disabled)
544 | ; webcontrol_authentication username:password
545 |
546 |
547 | ############################################################
548 | # Tracking (Pan/Tilt)
549 | #############################################################
550 |
551 | # Type of tracker (0=none (default), 1=stepper, 2=iomojo, 3=pwc, 4=generic, 5=uvcvideo, 6=servo)
552 | # The generic type enables the definition of motion center and motion size to
553 | # be used with the conversion specifiers for options like on_motion_detected
554 | track_type 0
555 |
556 | # Enable auto tracking (default: off)
557 | track_auto off
558 |
559 | # Serial port of motor (default: none)
560 | ;track_port /dev/ttyS0
561 |
562 | # Motor number for x-axis (default: 0)
563 | ;track_motorx 0
564 |
565 | # Set motorx reverse (default: 0)
566 | ;track_motorx_reverse 0
567 |
568 | # Motor number for y-axis (default: 0)
569 | ;track_motory 1
570 |
571 | # Set motory reverse (default: 0)
572 | ;track_motory_reverse 0
573 |
574 | # Maximum value on x-axis (default: 0)
575 | ;track_maxx 200
576 |
577 | # Minimum value on x-axis (default: 0)
578 | ;track_minx 50
579 |
580 | # Maximum value on y-axis (default: 0)
581 | ;track_maxy 200
582 |
583 | # Minimum value on y-axis (default: 0)
584 | ;track_miny 50
585 |
586 | # Center value on x-axis (default: 0)
587 | ;track_homex 128
588 |
589 | # Center value on y-axis (default: 0)
590 | ;track_homey 128
591 |
592 | # ID of an iomojo camera if used (default: 0)
593 | track_iomojo_id 0
594 |
595 | # Angle in degrees the camera moves per step on the X-axis
596 | # with auto-track (default: 10)
597 | # Currently only used with pwc type cameras
598 | track_step_angle_x 10
599 |
600 | # Angle in degrees the camera moves per step on the Y-axis
601 | # with auto-track (default: 10)
602 | # Currently only used with pwc type cameras
603 | track_step_angle_y 10
604 |
605 | # Delay to wait for after tracking movement as number
606 | # of picture frames (default: 10)
607 | track_move_wait 10
608 |
609 | # Speed to set the motor to (stepper motor option) (default: 255)
610 | track_speed 255
611 |
612 | # Number of steps to make (stepper motor option) (default: 40)
613 | track_stepsize 40
614 |
615 |
616 | ############################################################
617 | # External Commands, Warnings and Logging:
618 | # You can use conversion specifiers for the on_xxxx commands
619 | # %Y = year, %m = month, %d = date,
620 | # %H = hour, %M = minute, %S = second,
621 | # %v = event, %q = frame number, %t = camera id number,
622 | # %D = changed pixels, %N = noise level,
623 | # %i and %J = width and height of motion area,
624 | # %K and %L = X and Y coordinates of motion center
625 | # %C = value defined by text_event
626 | # %f = filename with full path
627 | # %n = number indicating filetype
628 | # Both %f and %n are only defined for on_picture_save,
629 | # on_movie_start and on_movie_end
630 | # Quotation marks round string are allowed.
631 | ############################################################
632 |
633 | # Do not sound beeps when detecting motion (default: on)
634 | # Note: Motion never beeps when running in daemon mode.
635 | quiet on
636 |
637 | # Command to be executed when an event starts. (default: none)
638 | # An event starts at first motion detected after a period of no motion defined by event_gap
639 | ; on_event_start value
640 |
641 | # Command to be executed when an event ends after a period of no motion
642 | # (default: none). The period of no motion is defined by option event_gap.
643 | ; on_event_end value
644 |
645 | # Command to be executed when a picture (.ppm|.jpg) is saved (default: none)
646 | # To give the filename as an argument to a command append it with %f
647 | ; on_picture_save value
648 |
649 | # Command to be executed when a motion frame is detected (default: none)
650 | ; on_motion_detected wget -q -O- --header='Content-Type:application/json' --post-data='{"motion_area": {"x":"%K", "y":"%L", "width": "%i", "height":"%J"}}' http://127.0.0.1:8080/api/v1/motion/detect
651 |
652 | # Command to be executed when motion in a predefined area is detected
653 | # Check option 'area_detect'. (default: none)
654 | ; on_area_detected value
655 |
656 | # Command to be executed when a movie file (.mpg|.avi) is created. (default: none)
657 | # To give the filename as an argument to a command append it with %f
658 | on_movie_start wget -q -O- --header='Content-Type:application/json' --post-data='{"file":"%f", "action":"start", "motion_area": {"x":"%K", "y":"%L", "width": "%i", "height":"%J"}}' http://127.0.0.1:8080/api/v1/motion/movie
659 |
660 | # Command to be executed when a movie file (.mpg|.avi) is closed. (default: none)
661 | # To give the filename as an argument to a command append it with %f
662 | on_movie_end wget -q -O- --header='Content-Type:application/json' --post-data='{"file":"%f", "action":"end", "motion_area": {"x":"%K", "y":"%L", "width": "%i", "height":"%J"}}' http://127.0.0.1:8080/api/v1/motion/movie
663 |
664 | # Command to be executed when a camera can't be opened or if it is lost
665 | # NOTE: There is situations when motion don't detect a lost camera!
666 | # It depends on the driver, some drivers dosn't detect a lost camera at all
667 | # Some hangs the motion thread. Some even hangs the PC! (default: none)
668 | ; on_camera_lost value
669 |
670 | #####################################################################
671 | # Common Options for database features.
672 | # Options require database options to be active also.
673 | #####################################################################
674 |
675 | # Log to the database when creating motion triggered picture file (default: on)
676 | ; sql_log_picture on
677 |
678 | # Log to the database when creating a snapshot image file (default: on)
679 | ; sql_log_snapshot on
680 |
681 | # Log to the database when creating motion triggered movie file (default: off)
682 | ; sql_log_movie off
683 |
684 | # Log to the database when creating timelapse movies file (default: off)
685 | ; sql_log_timelapse off
686 |
687 | # SQL query string that is sent to the database
688 | # Use same conversion specifiers has for text features
689 | # Additional special conversion specifiers are
690 | # %n = the number representing the file_type
691 | # %f = filename with full path
692 | # Default value:
693 | # Create tables :
694 | ##
695 | # Mysql
696 | # CREATE TABLE security (camera int, filename char(80) not null, frame int, file_type int, time_stamp timestamp(14), event_time_stamp timestamp(14));
697 | #
698 | # Postgresql
699 | # CREATE TABLE security (camera int, filename char(80) not null, frame int, file_type int, time_stamp timestamp without time zone, event_time_stamp timestamp without time zone);
700 | #
701 | # insert into security(camera, filename, frame, file_type, time_stamp, text_event) values('%t', '%f', '%q', '%n', '%Y-%m-%d %T', '%C')
702 | ; sql_query insert into security(camera, filename, frame, file_type, time_stamp, event_time_stamp) values('%t', '%f', '%q', '%n', '%Y-%m-%d %T', '%C')
703 |
704 |
705 | ############################################################
706 | # Database Options
707 | ############################################################
708 |
709 | # database type : mysql, postgresql, sqlite3 (default : not defined)
710 | ; database_type value
711 |
712 | # database to log to (default: not defined)
713 | # for sqlite3, the full path and name for the database.
714 | ; database_dbname value
715 |
716 | # The host on which the database is located (default: localhost)
717 | ; database_host value
718 |
719 | # User account name for database (default: not defined)
720 | ; database_user value
721 |
722 | # User password for database (default: not defined)
723 | ; database_password value
724 |
725 | # Port on which the database is located
726 | # mysql 3306 , postgresql 5432 (default: not defined)
727 | ; database_port value
728 |
729 | # Database wait time in milliseconds for locked database to
730 | # be unlocked before returning database locked error (default 0)
731 | ; database_busy_timeout 0
732 |
733 |
734 |
735 | ############################################################
736 | # Video Loopback Device (vloopback project)
737 | ############################################################
738 |
739 | # Output images to a video4linux loopback device
740 | # The value '-' means next available (default: not defined)
741 | ; video_pipe value
742 |
743 | # Output motion images to a video4linux loopback device
744 | # The value '-' means next available (default: not defined)
745 | ; motion_video_pipe value
746 |
747 |
748 | ##############################################################
749 | # camera config files - One for each camera.
750 | # Except if only one camera - You only need this config file.
751 | # If you have more than one camera you MUST define one camera
752 | # config file for each camera in addition to this config file.
753 | ##############################################################
754 |
755 | # Remember: If you have more than one camera you must have one
756 | # camera file for each camera. E.g. 2 cameras requires 3 files:
757 | # This motion.conf file AND camera1.conf and camera2.conf.
758 | # Only put the options that are unique to each camera in the
759 | # camera config files.
760 | ; camera /etc/motion/camera1.conf
761 | ; camera /etc/motion/camera2.conf
762 | ; camera /etc/motion/camera3.conf
763 | ; camera /etc/motion/camera4.conf
764 |
765 |
766 | ##############################################################
767 | # Camera config directory - One for each camera.
768 | ##############################################################
769 | #
770 | ; camera_dir /etc/motion/conf.d
--------------------------------------------------------------------------------