diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/404.html b/404.html new file mode 100644 index 0000000..460bcda --- /dev/null +++ b/404.html @@ -0,0 +1,1067 @@ + + + + + + + + + + + + + + + + + + + + + Paraizo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ +

404 - Not found

+ +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ +
+ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/assets/favicon.ico b/assets/favicon.ico new file mode 100644 index 0000000..0bd66db Binary files /dev/null and b/assets/favicon.ico differ diff --git a/assets/image.png b/assets/image.png new file mode 100644 index 0000000..a304f5d Binary files /dev/null and b/assets/image.png differ diff --git a/assets/images/favicon.png b/assets/images/favicon.png new file mode 100644 index 0000000..1cf13b9 Binary files /dev/null and b/assets/images/favicon.png differ diff --git a/assets/javascripts/bundle.56dfad97.min.js b/assets/javascripts/bundle.56dfad97.min.js new file mode 100644 index 0000000..1df62cd --- /dev/null +++ b/assets/javascripts/bundle.56dfad97.min.js @@ -0,0 +1,16 @@ +"use strict";(()=>{var Fi=Object.create;var gr=Object.defineProperty;var Wi=Object.getOwnPropertyDescriptor;var Ui=Object.getOwnPropertyNames,Vt=Object.getOwnPropertySymbols,Di=Object.getPrototypeOf,yr=Object.prototype.hasOwnProperty,io=Object.prototype.propertyIsEnumerable;var no=(e,t,r)=>t in e?gr(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,$=(e,t)=>{for(var r in t||(t={}))yr.call(t,r)&&no(e,r,t[r]);if(Vt)for(var r of Vt(t))io.call(t,r)&&no(e,r,t[r]);return e};var ao=(e,t)=>{var r={};for(var o in e)yr.call(e,o)&&t.indexOf(o)<0&&(r[o]=e[o]);if(e!=null&&Vt)for(var o of Vt(e))t.indexOf(o)<0&&io.call(e,o)&&(r[o]=e[o]);return r};var xr=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var Vi=(e,t,r,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of Ui(t))!yr.call(e,n)&&n!==r&&gr(e,n,{get:()=>t[n],enumerable:!(o=Wi(t,n))||o.enumerable});return e};var Lt=(e,t,r)=>(r=e!=null?Fi(Di(e)):{},Vi(t||!e||!e.__esModule?gr(r,"default",{value:e,enumerable:!0}):r,e));var so=(e,t,r)=>new Promise((o,n)=>{var i=p=>{try{s(r.next(p))}catch(c){n(c)}},a=p=>{try{s(r.throw(p))}catch(c){n(c)}},s=p=>p.done?o(p.value):Promise.resolve(p.value).then(i,a);s((r=r.apply(e,t)).next())});var po=xr((Er,co)=>{(function(e,t){typeof Er=="object"&&typeof co!="undefined"?t():typeof define=="function"&&define.amd?define(t):t()})(Er,function(){"use strict";function e(r){var o=!0,n=!1,i=null,a={text:!0,search:!0,url:!0,tel:!0,email:!0,password:!0,number:!0,date:!0,month:!0,week:!0,time:!0,datetime:!0,"datetime-local":!0};function s(k){return!!(k&&k!==document&&k.nodeName!=="HTML"&&k.nodeName!=="BODY"&&"classList"in k&&"contains"in k.classList)}function p(k){var ft=k.type,qe=k.tagName;return!!(qe==="INPUT"&&a[ft]&&!k.readOnly||qe==="TEXTAREA"&&!k.readOnly||k.isContentEditable)}function c(k){k.classList.contains("focus-visible")||(k.classList.add("focus-visible"),k.setAttribute("data-focus-visible-added",""))}function l(k){k.hasAttribute("data-focus-visible-added")&&(k.classList.remove("focus-visible"),k.removeAttribute("data-focus-visible-added"))}function f(k){k.metaKey||k.altKey||k.ctrlKey||(s(r.activeElement)&&c(r.activeElement),o=!0)}function u(k){o=!1}function d(k){s(k.target)&&(o||p(k.target))&&c(k.target)}function y(k){s(k.target)&&(k.target.classList.contains("focus-visible")||k.target.hasAttribute("data-focus-visible-added"))&&(n=!0,window.clearTimeout(i),i=window.setTimeout(function(){n=!1},100),l(k.target))}function M(k){document.visibilityState==="hidden"&&(n&&(o=!0),X())}function X(){document.addEventListener("mousemove",J),document.addEventListener("mousedown",J),document.addEventListener("mouseup",J),document.addEventListener("pointermove",J),document.addEventListener("pointerdown",J),document.addEventListener("pointerup",J),document.addEventListener("touchmove",J),document.addEventListener("touchstart",J),document.addEventListener("touchend",J)}function te(){document.removeEventListener("mousemove",J),document.removeEventListener("mousedown",J),document.removeEventListener("mouseup",J),document.removeEventListener("pointermove",J),document.removeEventListener("pointerdown",J),document.removeEventListener("pointerup",J),document.removeEventListener("touchmove",J),document.removeEventListener("touchstart",J),document.removeEventListener("touchend",J)}function J(k){k.target.nodeName&&k.target.nodeName.toLowerCase()==="html"||(o=!1,te())}document.addEventListener("keydown",f,!0),document.addEventListener("mousedown",u,!0),document.addEventListener("pointerdown",u,!0),document.addEventListener("touchstart",u,!0),document.addEventListener("visibilitychange",M,!0),X(),r.addEventListener("focus",d,!0),r.addEventListener("blur",y,!0),r.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&r.host?r.host.setAttribute("data-js-focus-visible",""):r.nodeType===Node.DOCUMENT_NODE&&(document.documentElement.classList.add("js-focus-visible"),document.documentElement.setAttribute("data-js-focus-visible",""))}if(typeof window!="undefined"&&typeof document!="undefined"){window.applyFocusVisiblePolyfill=e;var t;try{t=new CustomEvent("focus-visible-polyfill-ready")}catch(r){t=document.createEvent("CustomEvent"),t.initCustomEvent("focus-visible-polyfill-ready",!1,!1,{})}window.dispatchEvent(t)}typeof document!="undefined"&&e(document)})});var qr=xr((ly,Sn)=>{"use strict";/*! + * escape-html + * Copyright(c) 2012-2013 TJ Holowaychuk + * Copyright(c) 2015 Andreas Lubbe + * Copyright(c) 2015 Tiancheng "Timothy" Gu + * MIT Licensed + */var ka=/["'&<>]/;Sn.exports=Ha;function Ha(e){var t=""+e,r=ka.exec(t);if(!r)return t;var o,n="",i=0,a=0;for(i=r.index;i{/*! + * clipboard.js v2.0.11 + * https://clipboardjs.com/ + * + * Licensed MIT © Zeno Rocha + */(function(t,r){typeof It=="object"&&typeof Yr=="object"?Yr.exports=r():typeof define=="function"&&define.amd?define([],r):typeof It=="object"?It.ClipboardJS=r():t.ClipboardJS=r()})(It,function(){return function(){var e={686:function(o,n,i){"use strict";i.d(n,{default:function(){return ji}});var a=i(279),s=i.n(a),p=i(370),c=i.n(p),l=i(817),f=i.n(l);function u(V){try{return document.execCommand(V)}catch(A){return!1}}var d=function(A){var L=f()(A);return u("cut"),L},y=d;function M(V){var A=document.documentElement.getAttribute("dir")==="rtl",L=document.createElement("textarea");L.style.fontSize="12pt",L.style.border="0",L.style.padding="0",L.style.margin="0",L.style.position="absolute",L.style[A?"right":"left"]="-9999px";var F=window.pageYOffset||document.documentElement.scrollTop;return L.style.top="".concat(F,"px"),L.setAttribute("readonly",""),L.value=V,L}var X=function(A,L){var F=M(A);L.container.appendChild(F);var D=f()(F);return u("copy"),F.remove(),D},te=function(A){var L=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body},F="";return typeof A=="string"?F=X(A,L):A instanceof HTMLInputElement&&!["text","search","url","tel","password"].includes(A==null?void 0:A.type)?F=X(A.value,L):(F=f()(A),u("copy")),F},J=te;function k(V){"@babel/helpers - typeof";return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?k=function(L){return typeof L}:k=function(L){return L&&typeof Symbol=="function"&&L.constructor===Symbol&&L!==Symbol.prototype?"symbol":typeof L},k(V)}var ft=function(){var A=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},L=A.action,F=L===void 0?"copy":L,D=A.container,Y=A.target,$e=A.text;if(F!=="copy"&&F!=="cut")throw new Error('Invalid "action" value, use either "copy" or "cut"');if(Y!==void 0)if(Y&&k(Y)==="object"&&Y.nodeType===1){if(F==="copy"&&Y.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if(F==="cut"&&(Y.hasAttribute("readonly")||Y.hasAttribute("disabled")))throw new Error(`Invalid "target" attribute. You can't cut text from elements with "readonly" or "disabled" attributes`)}else throw new Error('Invalid "target" value, use a valid Element');if($e)return J($e,{container:D});if(Y)return F==="cut"?y(Y):J(Y,{container:D})},qe=ft;function Fe(V){"@babel/helpers - typeof";return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?Fe=function(L){return typeof L}:Fe=function(L){return L&&typeof Symbol=="function"&&L.constructor===Symbol&&L!==Symbol.prototype?"symbol":typeof L},Fe(V)}function Ai(V,A){if(!(V instanceof A))throw new TypeError("Cannot call a class as a function")}function oo(V,A){for(var L=0;L0&&arguments[0]!==void 0?arguments[0]:{};this.action=typeof D.action=="function"?D.action:this.defaultAction,this.target=typeof D.target=="function"?D.target:this.defaultTarget,this.text=typeof D.text=="function"?D.text:this.defaultText,this.container=Fe(D.container)==="object"?D.container:document.body}},{key:"listenClick",value:function(D){var Y=this;this.listener=c()(D,"click",function($e){return Y.onClick($e)})}},{key:"onClick",value:function(D){var Y=D.delegateTarget||D.currentTarget,$e=this.action(Y)||"copy",Dt=qe({action:$e,container:this.container,target:this.target(Y),text:this.text(Y)});this.emit(Dt?"success":"error",{action:$e,text:Dt,trigger:Y,clearSelection:function(){Y&&Y.focus(),window.getSelection().removeAllRanges()}})}},{key:"defaultAction",value:function(D){return vr("action",D)}},{key:"defaultTarget",value:function(D){var Y=vr("target",D);if(Y)return document.querySelector(Y)}},{key:"defaultText",value:function(D){return vr("text",D)}},{key:"destroy",value:function(){this.listener.destroy()}}],[{key:"copy",value:function(D){var Y=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body};return J(D,Y)}},{key:"cut",value:function(D){return y(D)}},{key:"isSupported",value:function(){var D=arguments.length>0&&arguments[0]!==void 0?arguments[0]:["copy","cut"],Y=typeof D=="string"?[D]:D,$e=!!document.queryCommandSupported;return Y.forEach(function(Dt){$e=$e&&!!document.queryCommandSupported(Dt)}),$e}}]),L}(s()),ji=Ii},828:function(o){var n=9;if(typeof Element!="undefined"&&!Element.prototype.matches){var i=Element.prototype;i.matches=i.matchesSelector||i.mozMatchesSelector||i.msMatchesSelector||i.oMatchesSelector||i.webkitMatchesSelector}function a(s,p){for(;s&&s.nodeType!==n;){if(typeof s.matches=="function"&&s.matches(p))return s;s=s.parentNode}}o.exports=a},438:function(o,n,i){var a=i(828);function s(l,f,u,d,y){var M=c.apply(this,arguments);return l.addEventListener(u,M,y),{destroy:function(){l.removeEventListener(u,M,y)}}}function p(l,f,u,d,y){return typeof l.addEventListener=="function"?s.apply(null,arguments):typeof u=="function"?s.bind(null,document).apply(null,arguments):(typeof l=="string"&&(l=document.querySelectorAll(l)),Array.prototype.map.call(l,function(M){return s(M,f,u,d,y)}))}function c(l,f,u,d){return function(y){y.delegateTarget=a(y.target,f),y.delegateTarget&&d.call(l,y)}}o.exports=p},879:function(o,n){n.node=function(i){return i!==void 0&&i instanceof HTMLElement&&i.nodeType===1},n.nodeList=function(i){var a=Object.prototype.toString.call(i);return i!==void 0&&(a==="[object NodeList]"||a==="[object HTMLCollection]")&&"length"in i&&(i.length===0||n.node(i[0]))},n.string=function(i){return typeof i=="string"||i instanceof String},n.fn=function(i){var a=Object.prototype.toString.call(i);return a==="[object Function]"}},370:function(o,n,i){var a=i(879),s=i(438);function p(u,d,y){if(!u&&!d&&!y)throw new Error("Missing required arguments");if(!a.string(d))throw new TypeError("Second argument must be a String");if(!a.fn(y))throw new TypeError("Third argument must be a Function");if(a.node(u))return c(u,d,y);if(a.nodeList(u))return l(u,d,y);if(a.string(u))return f(u,d,y);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList")}function c(u,d,y){return u.addEventListener(d,y),{destroy:function(){u.removeEventListener(d,y)}}}function l(u,d,y){return Array.prototype.forEach.call(u,function(M){M.addEventListener(d,y)}),{destroy:function(){Array.prototype.forEach.call(u,function(M){M.removeEventListener(d,y)})}}}function f(u,d,y){return s(document.body,u,d,y)}o.exports=p},817:function(o){function n(i){var a;if(i.nodeName==="SELECT")i.focus(),a=i.value;else if(i.nodeName==="INPUT"||i.nodeName==="TEXTAREA"){var s=i.hasAttribute("readonly");s||i.setAttribute("readonly",""),i.select(),i.setSelectionRange(0,i.value.length),s||i.removeAttribute("readonly"),a=i.value}else{i.hasAttribute("contenteditable")&&i.focus();var p=window.getSelection(),c=document.createRange();c.selectNodeContents(i),p.removeAllRanges(),p.addRange(c),a=p.toString()}return a}o.exports=n},279:function(o){function n(){}n.prototype={on:function(i,a,s){var p=this.e||(this.e={});return(p[i]||(p[i]=[])).push({fn:a,ctx:s}),this},once:function(i,a,s){var p=this;function c(){p.off(i,c),a.apply(s,arguments)}return c._=a,this.on(i,c,s)},emit:function(i){var a=[].slice.call(arguments,1),s=((this.e||(this.e={}))[i]||[]).slice(),p=0,c=s.length;for(p;p0&&i[i.length-1])&&(c[0]===6||c[0]===2)){r=0;continue}if(c[0]===3&&(!i||c[1]>i[0]&&c[1]=e.length&&(e=void 0),{value:e&&e[o++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")}function N(e,t){var r=typeof Symbol=="function"&&e[Symbol.iterator];if(!r)return e;var o=r.call(e),n,i=[],a;try{for(;(t===void 0||t-- >0)&&!(n=o.next()).done;)i.push(n.value)}catch(s){a={error:s}}finally{try{n&&!n.done&&(r=o.return)&&r.call(o)}finally{if(a)throw a.error}}return i}function q(e,t,r){if(r||arguments.length===2)for(var o=0,n=t.length,i;o1||p(d,M)})},y&&(n[d]=y(n[d])))}function p(d,y){try{c(o[d](y))}catch(M){u(i[0][3],M)}}function c(d){d.value instanceof nt?Promise.resolve(d.value.v).then(l,f):u(i[0][2],d)}function l(d){p("next",d)}function f(d){p("throw",d)}function u(d,y){d(y),i.shift(),i.length&&p(i[0][0],i[0][1])}}function fo(e){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var t=e[Symbol.asyncIterator],r;return t?t.call(e):(e=typeof he=="function"?he(e):e[Symbol.iterator](),r={},o("next"),o("throw"),o("return"),r[Symbol.asyncIterator]=function(){return this},r);function o(i){r[i]=e[i]&&function(a){return new Promise(function(s,p){a=e[i](a),n(s,p,a.done,a.value)})}}function n(i,a,s,p){Promise.resolve(p).then(function(c){i({value:c,done:s})},a)}}function H(e){return typeof e=="function"}function ut(e){var t=function(o){Error.call(o),o.stack=new Error().stack},r=e(t);return r.prototype=Object.create(Error.prototype),r.prototype.constructor=r,r}var zt=ut(function(e){return function(r){e(this),this.message=r?r.length+` errors occurred during unsubscription: +`+r.map(function(o,n){return n+1+") "+o.toString()}).join(` + `):"",this.name="UnsubscriptionError",this.errors=r}});function Qe(e,t){if(e){var r=e.indexOf(t);0<=r&&e.splice(r,1)}}var We=function(){function e(t){this.initialTeardown=t,this.closed=!1,this._parentage=null,this._finalizers=null}return e.prototype.unsubscribe=function(){var t,r,o,n,i;if(!this.closed){this.closed=!0;var a=this._parentage;if(a)if(this._parentage=null,Array.isArray(a))try{for(var s=he(a),p=s.next();!p.done;p=s.next()){var c=p.value;c.remove(this)}}catch(M){t={error:M}}finally{try{p&&!p.done&&(r=s.return)&&r.call(s)}finally{if(t)throw t.error}}else a.remove(this);var l=this.initialTeardown;if(H(l))try{l()}catch(M){i=M instanceof zt?M.errors:[M]}var f=this._finalizers;if(f){this._finalizers=null;try{for(var u=he(f),d=u.next();!d.done;d=u.next()){var y=d.value;try{uo(y)}catch(M){i=i!=null?i:[],M instanceof zt?i=q(q([],N(i)),N(M.errors)):i.push(M)}}}catch(M){o={error:M}}finally{try{d&&!d.done&&(n=u.return)&&n.call(u)}finally{if(o)throw o.error}}}if(i)throw new zt(i)}},e.prototype.add=function(t){var r;if(t&&t!==this)if(this.closed)uo(t);else{if(t instanceof e){if(t.closed||t._hasParent(this))return;t._addParent(this)}(this._finalizers=(r=this._finalizers)!==null&&r!==void 0?r:[]).push(t)}},e.prototype._hasParent=function(t){var r=this._parentage;return r===t||Array.isArray(r)&&r.includes(t)},e.prototype._addParent=function(t){var r=this._parentage;this._parentage=Array.isArray(r)?(r.push(t),r):r?[r,t]:t},e.prototype._removeParent=function(t){var r=this._parentage;r===t?this._parentage=null:Array.isArray(r)&&Qe(r,t)},e.prototype.remove=function(t){var r=this._finalizers;r&&Qe(r,t),t instanceof e&&t._removeParent(this)},e.EMPTY=function(){var t=new e;return t.closed=!0,t}(),e}();var Tr=We.EMPTY;function qt(e){return e instanceof We||e&&"closed"in e&&H(e.remove)&&H(e.add)&&H(e.unsubscribe)}function uo(e){H(e)?e():e.unsubscribe()}var Pe={onUnhandledError:null,onStoppedNotification:null,Promise:void 0,useDeprecatedSynchronousErrorHandling:!1,useDeprecatedNextContext:!1};var dt={setTimeout:function(e,t){for(var r=[],o=2;o0},enumerable:!1,configurable:!0}),t.prototype._trySubscribe=function(r){return this._throwIfClosed(),e.prototype._trySubscribe.call(this,r)},t.prototype._subscribe=function(r){return this._throwIfClosed(),this._checkFinalizedStatuses(r),this._innerSubscribe(r)},t.prototype._innerSubscribe=function(r){var o=this,n=this,i=n.hasError,a=n.isStopped,s=n.observers;return i||a?Tr:(this.currentObservers=null,s.push(r),new We(function(){o.currentObservers=null,Qe(s,r)}))},t.prototype._checkFinalizedStatuses=function(r){var o=this,n=o.hasError,i=o.thrownError,a=o.isStopped;n?r.error(i):a&&r.complete()},t.prototype.asObservable=function(){var r=new j;return r.source=this,r},t.create=function(r,o){return new wo(r,o)},t}(j);var wo=function(e){oe(t,e);function t(r,o){var n=e.call(this)||this;return n.destination=r,n.source=o,n}return t.prototype.next=function(r){var o,n;(n=(o=this.destination)===null||o===void 0?void 0:o.next)===null||n===void 0||n.call(o,r)},t.prototype.error=function(r){var o,n;(n=(o=this.destination)===null||o===void 0?void 0:o.error)===null||n===void 0||n.call(o,r)},t.prototype.complete=function(){var r,o;(o=(r=this.destination)===null||r===void 0?void 0:r.complete)===null||o===void 0||o.call(r)},t.prototype._subscribe=function(r){var o,n;return(n=(o=this.source)===null||o===void 0?void 0:o.subscribe(r))!==null&&n!==void 0?n:Tr},t}(g);var _r=function(e){oe(t,e);function t(r){var o=e.call(this)||this;return o._value=r,o}return Object.defineProperty(t.prototype,"value",{get:function(){return this.getValue()},enumerable:!1,configurable:!0}),t.prototype._subscribe=function(r){var o=e.prototype._subscribe.call(this,r);return!o.closed&&r.next(this._value),o},t.prototype.getValue=function(){var r=this,o=r.hasError,n=r.thrownError,i=r._value;if(o)throw n;return this._throwIfClosed(),i},t.prototype.next=function(r){e.prototype.next.call(this,this._value=r)},t}(g);var At={now:function(){return(At.delegate||Date).now()},delegate:void 0};var Ct=function(e){oe(t,e);function t(r,o,n){r===void 0&&(r=1/0),o===void 0&&(o=1/0),n===void 0&&(n=At);var i=e.call(this)||this;return i._bufferSize=r,i._windowTime=o,i._timestampProvider=n,i._buffer=[],i._infiniteTimeWindow=!0,i._infiniteTimeWindow=o===1/0,i._bufferSize=Math.max(1,r),i._windowTime=Math.max(1,o),i}return t.prototype.next=function(r){var o=this,n=o.isStopped,i=o._buffer,a=o._infiniteTimeWindow,s=o._timestampProvider,p=o._windowTime;n||(i.push(r),!a&&i.push(s.now()+p)),this._trimBuffer(),e.prototype.next.call(this,r)},t.prototype._subscribe=function(r){this._throwIfClosed(),this._trimBuffer();for(var o=this._innerSubscribe(r),n=this,i=n._infiniteTimeWindow,a=n._buffer,s=a.slice(),p=0;p0?e.prototype.schedule.call(this,r,o):(this.delay=o,this.state=r,this.scheduler.flush(this),this)},t.prototype.execute=function(r,o){return o>0||this.closed?e.prototype.execute.call(this,r,o):this._execute(r,o)},t.prototype.requestAsyncId=function(r,o,n){return n===void 0&&(n=0),n!=null&&n>0||n==null&&this.delay>0?e.prototype.requestAsyncId.call(this,r,o,n):(r.flush(this),0)},t}(gt);var Oo=function(e){oe(t,e);function t(){return e!==null&&e.apply(this,arguments)||this}return t}(yt);var kr=new Oo(So);var Mo=function(e){oe(t,e);function t(r,o){var n=e.call(this,r,o)||this;return n.scheduler=r,n.work=o,n}return t.prototype.requestAsyncId=function(r,o,n){return n===void 0&&(n=0),n!==null&&n>0?e.prototype.requestAsyncId.call(this,r,o,n):(r.actions.push(this),r._scheduled||(r._scheduled=vt.requestAnimationFrame(function(){return r.flush(void 0)})))},t.prototype.recycleAsyncId=function(r,o,n){var i;if(n===void 0&&(n=0),n!=null?n>0:this.delay>0)return e.prototype.recycleAsyncId.call(this,r,o,n);var a=r.actions;o!=null&&((i=a[a.length-1])===null||i===void 0?void 0:i.id)!==o&&(vt.cancelAnimationFrame(o),r._scheduled=void 0)},t}(gt);var Lo=function(e){oe(t,e);function t(){return e!==null&&e.apply(this,arguments)||this}return t.prototype.flush=function(r){this._active=!0;var o=this._scheduled;this._scheduled=void 0;var n=this.actions,i;r=r||n.shift();do if(i=r.execute(r.state,r.delay))break;while((r=n[0])&&r.id===o&&n.shift());if(this._active=!1,i){for(;(r=n[0])&&r.id===o&&n.shift();)r.unsubscribe();throw i}},t}(yt);var me=new Lo(Mo);var S=new j(function(e){return e.complete()});function Yt(e){return e&&H(e.schedule)}function Hr(e){return e[e.length-1]}function Xe(e){return H(Hr(e))?e.pop():void 0}function ke(e){return Yt(Hr(e))?e.pop():void 0}function Bt(e,t){return typeof Hr(e)=="number"?e.pop():t}var xt=function(e){return e&&typeof e.length=="number"&&typeof e!="function"};function Gt(e){return H(e==null?void 0:e.then)}function Jt(e){return H(e[bt])}function Xt(e){return Symbol.asyncIterator&&H(e==null?void 0:e[Symbol.asyncIterator])}function Zt(e){return new TypeError("You provided "+(e!==null&&typeof e=="object"?"an invalid object":"'"+e+"'")+" where a stream was expected. You can provide an Observable, Promise, ReadableStream, Array, AsyncIterable, or Iterable.")}function Ji(){return typeof Symbol!="function"||!Symbol.iterator?"@@iterator":Symbol.iterator}var er=Ji();function tr(e){return H(e==null?void 0:e[er])}function rr(e){return mo(this,arguments,function(){var r,o,n,i;return Nt(this,function(a){switch(a.label){case 0:r=e.getReader(),a.label=1;case 1:a.trys.push([1,,9,10]),a.label=2;case 2:return[4,nt(r.read())];case 3:return o=a.sent(),n=o.value,i=o.done,i?[4,nt(void 0)]:[3,5];case 4:return[2,a.sent()];case 5:return[4,nt(n)];case 6:return[4,a.sent()];case 7:return a.sent(),[3,2];case 8:return[3,10];case 9:return r.releaseLock(),[7];case 10:return[2]}})})}function or(e){return H(e==null?void 0:e.getReader)}function W(e){if(e instanceof j)return e;if(e!=null){if(Jt(e))return Xi(e);if(xt(e))return Zi(e);if(Gt(e))return ea(e);if(Xt(e))return _o(e);if(tr(e))return ta(e);if(or(e))return ra(e)}throw Zt(e)}function Xi(e){return new j(function(t){var r=e[bt]();if(H(r.subscribe))return r.subscribe(t);throw new TypeError("Provided object does not correctly implement Symbol.observable")})}function Zi(e){return new j(function(t){for(var r=0;r=2;return function(o){return o.pipe(e?b(function(n,i){return e(n,i,o)}):le,Te(1),r?De(t):qo(function(){return new ir}))}}function jr(e){return e<=0?function(){return S}:E(function(t,r){var o=[];t.subscribe(T(r,function(n){o.push(n),e=2,!0))}function pe(e){e===void 0&&(e={});var t=e.connector,r=t===void 0?function(){return new g}:t,o=e.resetOnError,n=o===void 0?!0:o,i=e.resetOnComplete,a=i===void 0?!0:i,s=e.resetOnRefCountZero,p=s===void 0?!0:s;return function(c){var l,f,u,d=0,y=!1,M=!1,X=function(){f==null||f.unsubscribe(),f=void 0},te=function(){X(),l=u=void 0,y=M=!1},J=function(){var k=l;te(),k==null||k.unsubscribe()};return E(function(k,ft){d++,!M&&!y&&X();var qe=u=u!=null?u:r();ft.add(function(){d--,d===0&&!M&&!y&&(f=Wr(J,p))}),qe.subscribe(ft),!l&&d>0&&(l=new at({next:function(Fe){return qe.next(Fe)},error:function(Fe){M=!0,X(),f=Wr(te,n,Fe),qe.error(Fe)},complete:function(){y=!0,X(),f=Wr(te,a),qe.complete()}}),W(k).subscribe(l))})(c)}}function Wr(e,t){for(var r=[],o=2;oe.next(document)),e}function P(e,t=document){return Array.from(t.querySelectorAll(e))}function R(e,t=document){let r=fe(e,t);if(typeof r=="undefined")throw new ReferenceError(`Missing element: expected "${e}" to be present`);return r}function fe(e,t=document){return t.querySelector(e)||void 0}function Ie(){var e,t,r,o;return(o=(r=(t=(e=document.activeElement)==null?void 0:e.shadowRoot)==null?void 0:t.activeElement)!=null?r:document.activeElement)!=null?o:void 0}var xa=O(h(document.body,"focusin"),h(document.body,"focusout")).pipe(_e(1),Q(void 0),m(()=>Ie()||document.body),G(1));function et(e){return xa.pipe(m(t=>e.contains(t)),K())}function $t(e,t){return C(()=>O(h(e,"mouseenter").pipe(m(()=>!0)),h(e,"mouseleave").pipe(m(()=>!1))).pipe(t?Ht(r=>Me(+!r*t)):le,Q(e.matches(":hover"))))}function Go(e,t){if(typeof t=="string"||typeof t=="number")e.innerHTML+=t.toString();else if(t instanceof Node)e.appendChild(t);else if(Array.isArray(t))for(let r of t)Go(e,r)}function x(e,t,...r){let o=document.createElement(e);if(t)for(let n of Object.keys(t))typeof t[n]!="undefined"&&(typeof t[n]!="boolean"?o.setAttribute(n,t[n]):o.setAttribute(n,""));for(let n of r)Go(o,n);return o}function sr(e){if(e>999){let t=+((e-950)%1e3>99);return`${((e+1e-6)/1e3).toFixed(t)}k`}else return e.toString()}function Tt(e){let t=x("script",{src:e});return C(()=>(document.head.appendChild(t),O(h(t,"load"),h(t,"error").pipe(v(()=>$r(()=>new ReferenceError(`Invalid script: ${e}`))))).pipe(m(()=>{}),_(()=>document.head.removeChild(t)),Te(1))))}var Jo=new g,Ea=C(()=>typeof ResizeObserver=="undefined"?Tt("https://unpkg.com/resize-observer-polyfill"):I(void 0)).pipe(m(()=>new ResizeObserver(e=>e.forEach(t=>Jo.next(t)))),v(e=>O(Ye,I(e)).pipe(_(()=>e.disconnect()))),G(1));function ce(e){return{width:e.offsetWidth,height:e.offsetHeight}}function ge(e){let t=e;for(;t.clientWidth===0&&t.parentElement;)t=t.parentElement;return Ea.pipe(w(r=>r.observe(t)),v(r=>Jo.pipe(b(o=>o.target===t),_(()=>r.unobserve(t)))),m(()=>ce(e)),Q(ce(e)))}function St(e){return{width:e.scrollWidth,height:e.scrollHeight}}function cr(e){let t=e.parentElement;for(;t&&(e.scrollWidth<=t.scrollWidth&&e.scrollHeight<=t.scrollHeight);)t=(e=t).parentElement;return t?e:void 0}function Xo(e){let t=[],r=e.parentElement;for(;r;)(e.clientWidth>r.clientWidth||e.clientHeight>r.clientHeight)&&t.push(r),r=(e=r).parentElement;return t.length===0&&t.push(document.documentElement),t}function Ve(e){return{x:e.offsetLeft,y:e.offsetTop}}function Zo(e){let t=e.getBoundingClientRect();return{x:t.x+window.scrollX,y:t.y+window.scrollY}}function en(e){return O(h(window,"load"),h(window,"resize")).pipe(Le(0,me),m(()=>Ve(e)),Q(Ve(e)))}function pr(e){return{x:e.scrollLeft,y:e.scrollTop}}function Ne(e){return O(h(e,"scroll"),h(window,"scroll"),h(window,"resize")).pipe(Le(0,me),m(()=>pr(e)),Q(pr(e)))}var tn=new g,wa=C(()=>I(new IntersectionObserver(e=>{for(let t of e)tn.next(t)},{threshold:0}))).pipe(v(e=>O(Ye,I(e)).pipe(_(()=>e.disconnect()))),G(1));function tt(e){return wa.pipe(w(t=>t.observe(e)),v(t=>tn.pipe(b(({target:r})=>r===e),_(()=>t.unobserve(e)),m(({isIntersecting:r})=>r))))}function rn(e,t=16){return Ne(e).pipe(m(({y:r})=>{let o=ce(e),n=St(e);return r>=n.height-o.height-t}),K())}var lr={drawer:R("[data-md-toggle=drawer]"),search:R("[data-md-toggle=search]")};function on(e){return lr[e].checked}function Je(e,t){lr[e].checked!==t&&lr[e].click()}function ze(e){let t=lr[e];return h(t,"change").pipe(m(()=>t.checked),Q(t.checked))}function Ta(e,t){switch(e.constructor){case HTMLInputElement:return e.type==="radio"?/^Arrow/.test(t):!0;case HTMLSelectElement:case HTMLTextAreaElement:return!0;default:return e.isContentEditable}}function Sa(){return O(h(window,"compositionstart").pipe(m(()=>!0)),h(window,"compositionend").pipe(m(()=>!1))).pipe(Q(!1))}function nn(){let e=h(window,"keydown").pipe(b(t=>!(t.metaKey||t.ctrlKey)),m(t=>({mode:on("search")?"search":"global",type:t.key,claim(){t.preventDefault(),t.stopPropagation()}})),b(({mode:t,type:r})=>{if(t==="global"){let o=Ie();if(typeof o!="undefined")return!Ta(o,r)}return!0}),pe());return Sa().pipe(v(t=>t?S:e))}function ye(){return new URL(location.href)}function lt(e,t=!1){if(B("navigation.instant")&&!t){let r=x("a",{href:e.href});document.body.appendChild(r),r.click(),r.remove()}else location.href=e.href}function an(){return new g}function sn(){return location.hash.slice(1)}function cn(e){let t=x("a",{href:e});t.addEventListener("click",r=>r.stopPropagation()),t.click()}function Oa(e){return O(h(window,"hashchange"),e).pipe(m(sn),Q(sn()),b(t=>t.length>0),G(1))}function pn(e){return Oa(e).pipe(m(t=>fe(`[id="${t}"]`)),b(t=>typeof t!="undefined"))}function Pt(e){let t=matchMedia(e);return ar(r=>t.addListener(()=>r(t.matches))).pipe(Q(t.matches))}function ln(){let e=matchMedia("print");return O(h(window,"beforeprint").pipe(m(()=>!0)),h(window,"afterprint").pipe(m(()=>!1))).pipe(Q(e.matches))}function Nr(e,t){return e.pipe(v(r=>r?t():S))}function zr(e,t){return new j(r=>{let o=new XMLHttpRequest;return o.open("GET",`${e}`),o.responseType="blob",o.addEventListener("load",()=>{o.status>=200&&o.status<300?(r.next(o.response),r.complete()):r.error(new Error(o.statusText))}),o.addEventListener("error",()=>{r.error(new Error("Network error"))}),o.addEventListener("abort",()=>{r.complete()}),typeof(t==null?void 0:t.progress$)!="undefined"&&(o.addEventListener("progress",n=>{var i;if(n.lengthComputable)t.progress$.next(n.loaded/n.total*100);else{let a=(i=o.getResponseHeader("Content-Length"))!=null?i:0;t.progress$.next(n.loaded/+a*100)}}),t.progress$.next(5)),o.send(),()=>o.abort()})}function je(e,t){return zr(e,t).pipe(v(r=>r.text()),m(r=>JSON.parse(r)),G(1))}function mn(e,t){let r=new DOMParser;return zr(e,t).pipe(v(o=>o.text()),m(o=>r.parseFromString(o,"text/html")),G(1))}function fn(e,t){let r=new DOMParser;return zr(e,t).pipe(v(o=>o.text()),m(o=>r.parseFromString(o,"text/xml")),G(1))}function un(){return{x:Math.max(0,scrollX),y:Math.max(0,scrollY)}}function dn(){return O(h(window,"scroll",{passive:!0}),h(window,"resize",{passive:!0})).pipe(m(un),Q(un()))}function hn(){return{width:innerWidth,height:innerHeight}}function bn(){return h(window,"resize",{passive:!0}).pipe(m(hn),Q(hn()))}function vn(){return z([dn(),bn()]).pipe(m(([e,t])=>({offset:e,size:t})),G(1))}function mr(e,{viewport$:t,header$:r}){let o=t.pipe(ee("size")),n=z([o,r]).pipe(m(()=>Ve(e)));return z([r,t,n]).pipe(m(([{height:i},{offset:a,size:s},{x:p,y:c}])=>({offset:{x:a.x-p,y:a.y-c+i},size:s})))}function Ma(e){return h(e,"message",t=>t.data)}function La(e){let t=new g;return t.subscribe(r=>e.postMessage(r)),t}function gn(e,t=new Worker(e)){let r=Ma(t),o=La(t),n=new g;n.subscribe(o);let i=o.pipe(Z(),ie(!0));return n.pipe(Z(),Re(r.pipe(U(i))),pe())}var _a=R("#__config"),Ot=JSON.parse(_a.textContent);Ot.base=`${new URL(Ot.base,ye())}`;function xe(){return Ot}function B(e){return Ot.features.includes(e)}function Ee(e,t){return typeof t!="undefined"?Ot.translations[e].replace("#",t.toString()):Ot.translations[e]}function Se(e,t=document){return R(`[data-md-component=${e}]`,t)}function ae(e,t=document){return P(`[data-md-component=${e}]`,t)}function Aa(e){let t=R(".md-typeset > :first-child",e);return h(t,"click",{once:!0}).pipe(m(()=>R(".md-typeset",e)),m(r=>({hash:__md_hash(r.innerHTML)})))}function yn(e){if(!B("announce.dismiss")||!e.childElementCount)return S;if(!e.hidden){let t=R(".md-typeset",e);__md_hash(t.innerHTML)===__md_get("__announce")&&(e.hidden=!0)}return C(()=>{let t=new g;return t.subscribe(({hash:r})=>{e.hidden=!0,__md_set("__announce",r)}),Aa(e).pipe(w(r=>t.next(r)),_(()=>t.complete()),m(r=>$({ref:e},r)))})}function Ca(e,{target$:t}){return t.pipe(m(r=>({hidden:r!==e})))}function xn(e,t){let r=new g;return r.subscribe(({hidden:o})=>{e.hidden=o}),Ca(e,t).pipe(w(o=>r.next(o)),_(()=>r.complete()),m(o=>$({ref:e},o)))}function Rt(e,t){return t==="inline"?x("div",{class:"md-tooltip md-tooltip--inline",id:e,role:"tooltip"},x("div",{class:"md-tooltip__inner md-typeset"})):x("div",{class:"md-tooltip",id:e,role:"tooltip"},x("div",{class:"md-tooltip__inner md-typeset"}))}function En(...e){return x("div",{class:"md-tooltip2",role:"tooltip"},x("div",{class:"md-tooltip2__inner md-typeset"},e))}function wn(e,t){if(t=t?`${t}_annotation_${e}`:void 0,t){let r=t?`#${t}`:void 0;return x("aside",{class:"md-annotation",tabIndex:0},Rt(t),x("a",{href:r,class:"md-annotation__index",tabIndex:-1},x("span",{"data-md-annotation-id":e})))}else return x("aside",{class:"md-annotation",tabIndex:0},Rt(t),x("span",{class:"md-annotation__index",tabIndex:-1},x("span",{"data-md-annotation-id":e})))}function Tn(e){return x("button",{class:"md-clipboard md-icon",title:Ee("clipboard.copy"),"data-clipboard-target":`#${e} > code`})}var On=Lt(qr());function Qr(e,t){let r=t&2,o=t&1,n=Object.keys(e.terms).filter(p=>!e.terms[p]).reduce((p,c)=>[...p,x("del",null,(0,On.default)(c))," "],[]).slice(0,-1),i=xe(),a=new URL(e.location,i.base);B("search.highlight")&&a.searchParams.set("h",Object.entries(e.terms).filter(([,p])=>p).reduce((p,[c])=>`${p} ${c}`.trim(),""));let{tags:s}=xe();return x("a",{href:`${a}`,class:"md-search-result__link",tabIndex:-1},x("article",{class:"md-search-result__article md-typeset","data-md-score":e.score.toFixed(2)},r>0&&x("div",{class:"md-search-result__icon md-icon"}),r>0&&x("h1",null,e.title),r<=0&&x("h2",null,e.title),o>0&&e.text.length>0&&e.text,e.tags&&e.tags.map(p=>{let c=s?p in s?`md-tag-icon md-tag--${s[p]}`:"md-tag-icon":"";return x("span",{class:`md-tag ${c}`},p)}),o>0&&n.length>0&&x("p",{class:"md-search-result__terms"},Ee("search.result.term.missing"),": ",...n)))}function Mn(e){let t=e[0].score,r=[...e],o=xe(),n=r.findIndex(l=>!`${new URL(l.location,o.base)}`.includes("#")),[i]=r.splice(n,1),a=r.findIndex(l=>l.scoreQr(l,1)),...p.length?[x("details",{class:"md-search-result__more"},x("summary",{tabIndex:-1},x("div",null,p.length>0&&p.length===1?Ee("search.result.more.one"):Ee("search.result.more.other",p.length))),...p.map(l=>Qr(l,1)))]:[]];return x("li",{class:"md-search-result__item"},c)}function Ln(e){return x("ul",{class:"md-source__facts"},Object.entries(e).map(([t,r])=>x("li",{class:`md-source__fact md-source__fact--${t}`},typeof r=="number"?sr(r):r)))}function Kr(e){let t=`tabbed-control tabbed-control--${e}`;return x("div",{class:t,hidden:!0},x("button",{class:"tabbed-button",tabIndex:-1,"aria-hidden":"true"}))}function _n(e){return x("div",{class:"md-typeset__scrollwrap"},x("div",{class:"md-typeset__table"},e))}function $a(e){var o;let t=xe(),r=new URL(`../${e.version}/`,t.base);return x("li",{class:"md-version__item"},x("a",{href:`${r}`,class:"md-version__link"},e.title,((o=t.version)==null?void 0:o.alias)&&e.aliases.length>0&&x("span",{class:"md-version__alias"},e.aliases[0])))}function An(e,t){var o;let r=xe();return e=e.filter(n=>{var i;return!((i=n.properties)!=null&&i.hidden)}),x("div",{class:"md-version"},x("button",{class:"md-version__current","aria-label":Ee("select.version")},t.title,((o=r.version)==null?void 0:o.alias)&&t.aliases.length>0&&x("span",{class:"md-version__alias"},t.aliases[0])),x("ul",{class:"md-version__list"},e.map($a)))}var Pa=0;function Ra(e){let t=z([et(e),$t(e)]).pipe(m(([o,n])=>o||n),K()),r=C(()=>Xo(e)).pipe(ne(Ne),pt(1),He(t),m(()=>Zo(e)));return t.pipe(Ae(o=>o),v(()=>z([t,r])),m(([o,n])=>({active:o,offset:n})),pe())}function Ia(e,t){let{content$:r,viewport$:o}=t,n=`__tooltip2_${Pa++}`;return C(()=>{let i=new g,a=new _r(!1);i.pipe(Z(),ie(!1)).subscribe(a);let s=a.pipe(Ht(c=>Me(+!c*250,kr)),K(),v(c=>c?r:S),w(c=>c.id=n),pe());z([i.pipe(m(({active:c})=>c)),s.pipe(v(c=>$t(c,250)),Q(!1))]).pipe(m(c=>c.some(l=>l))).subscribe(a);let p=a.pipe(b(c=>c),re(s,o),m(([c,l,{size:f}])=>{let u=e.getBoundingClientRect(),d=u.width/2;if(l.role==="tooltip")return{x:d,y:8+u.height};if(u.y>=f.height/2){let{height:y}=ce(l);return{x:d,y:-16-y}}else return{x:d,y:16+u.height}}));return z([s,i,p]).subscribe(([c,{offset:l},f])=>{c.style.setProperty("--md-tooltip-host-x",`${l.x}px`),c.style.setProperty("--md-tooltip-host-y",`${l.y}px`),c.style.setProperty("--md-tooltip-x",`${f.x}px`),c.style.setProperty("--md-tooltip-y",`${f.y}px`),c.classList.toggle("md-tooltip2--top",f.y<0),c.classList.toggle("md-tooltip2--bottom",f.y>=0)}),a.pipe(b(c=>c),re(s,(c,l)=>l),b(c=>c.role==="tooltip")).subscribe(c=>{let l=ce(R(":scope > *",c));c.style.setProperty("--md-tooltip-width",`${l.width}px`),c.style.setProperty("--md-tooltip-tail","0px")}),a.pipe(K(),ve(me),re(s)).subscribe(([c,l])=>{l.classList.toggle("md-tooltip2--active",c)}),z([a.pipe(b(c=>c)),s]).subscribe(([c,l])=>{l.role==="dialog"?(e.setAttribute("aria-controls",n),e.setAttribute("aria-haspopup","dialog")):e.setAttribute("aria-describedby",n)}),a.pipe(b(c=>!c)).subscribe(()=>{e.removeAttribute("aria-controls"),e.removeAttribute("aria-describedby"),e.removeAttribute("aria-haspopup")}),Ra(e).pipe(w(c=>i.next(c)),_(()=>i.complete()),m(c=>$({ref:e},c)))})}function mt(e,{viewport$:t},r=document.body){return Ia(e,{content$:new j(o=>{let n=e.title,i=En(n);return o.next(i),e.removeAttribute("title"),r.append(i),()=>{i.remove(),e.setAttribute("title",n)}}),viewport$:t})}function ja(e,t){let r=C(()=>z([en(e),Ne(t)])).pipe(m(([{x:o,y:n},i])=>{let{width:a,height:s}=ce(e);return{x:o-i.x+a/2,y:n-i.y+s/2}}));return et(e).pipe(v(o=>r.pipe(m(n=>({active:o,offset:n})),Te(+!o||1/0))))}function Cn(e,t,{target$:r}){let[o,n]=Array.from(e.children);return C(()=>{let i=new g,a=i.pipe(Z(),ie(!0));return i.subscribe({next({offset:s}){e.style.setProperty("--md-tooltip-x",`${s.x}px`),e.style.setProperty("--md-tooltip-y",`${s.y}px`)},complete(){e.style.removeProperty("--md-tooltip-x"),e.style.removeProperty("--md-tooltip-y")}}),tt(e).pipe(U(a)).subscribe(s=>{e.toggleAttribute("data-md-visible",s)}),O(i.pipe(b(({active:s})=>s)),i.pipe(_e(250),b(({active:s})=>!s))).subscribe({next({active:s}){s?e.prepend(o):o.remove()},complete(){e.prepend(o)}}),i.pipe(Le(16,me)).subscribe(({active:s})=>{o.classList.toggle("md-tooltip--active",s)}),i.pipe(pt(125,me),b(()=>!!e.offsetParent),m(()=>e.offsetParent.getBoundingClientRect()),m(({x:s})=>s)).subscribe({next(s){s?e.style.setProperty("--md-tooltip-0",`${-s}px`):e.style.removeProperty("--md-tooltip-0")},complete(){e.style.removeProperty("--md-tooltip-0")}}),h(n,"click").pipe(U(a),b(s=>!(s.metaKey||s.ctrlKey))).subscribe(s=>{s.stopPropagation(),s.preventDefault()}),h(n,"mousedown").pipe(U(a),re(i)).subscribe(([s,{active:p}])=>{var c;if(s.button!==0||s.metaKey||s.ctrlKey)s.preventDefault();else if(p){s.preventDefault();let l=e.parentElement.closest(".md-annotation");l instanceof HTMLElement?l.focus():(c=Ie())==null||c.blur()}}),r.pipe(U(a),b(s=>s===o),Ge(125)).subscribe(()=>e.focus()),ja(e,t).pipe(w(s=>i.next(s)),_(()=>i.complete()),m(s=>$({ref:e},s)))})}function Fa(e){return e.tagName==="CODE"?P(".c, .c1, .cm",e):[e]}function Wa(e){let t=[];for(let r of Fa(e)){let o=[],n=document.createNodeIterator(r,NodeFilter.SHOW_TEXT);for(let i=n.nextNode();i;i=n.nextNode())o.push(i);for(let i of o){let a;for(;a=/(\(\d+\))(!)?/.exec(i.textContent);){let[,s,p]=a;if(typeof p=="undefined"){let c=i.splitText(a.index);i=c.splitText(s.length),t.push(c)}else{i.textContent=s,t.push(i);break}}}}return t}function kn(e,t){t.append(...Array.from(e.childNodes))}function fr(e,t,{target$:r,print$:o}){let n=t.closest("[id]"),i=n==null?void 0:n.id,a=new Map;for(let s of Wa(t)){let[,p]=s.textContent.match(/\((\d+)\)/);fe(`:scope > li:nth-child(${p})`,e)&&(a.set(p,wn(p,i)),s.replaceWith(a.get(p)))}return a.size===0?S:C(()=>{let s=new g,p=s.pipe(Z(),ie(!0)),c=[];for(let[l,f]of a)c.push([R(".md-typeset",f),R(`:scope > li:nth-child(${l})`,e)]);return o.pipe(U(p)).subscribe(l=>{e.hidden=!l,e.classList.toggle("md-annotation-list",l);for(let[f,u]of c)l?kn(f,u):kn(u,f)}),O(...[...a].map(([,l])=>Cn(l,t,{target$:r}))).pipe(_(()=>s.complete()),pe())})}function Hn(e){if(e.nextElementSibling){let t=e.nextElementSibling;if(t.tagName==="OL")return t;if(t.tagName==="P"&&!t.children.length)return Hn(t)}}function $n(e,t){return C(()=>{let r=Hn(e);return typeof r!="undefined"?fr(r,e,t):S})}var Pn=Lt(Br());var Ua=0;function Rn(e){if(e.nextElementSibling){let t=e.nextElementSibling;if(t.tagName==="OL")return t;if(t.tagName==="P"&&!t.children.length)return Rn(t)}}function Da(e){return ge(e).pipe(m(({width:t})=>({scrollable:St(e).width>t})),ee("scrollable"))}function In(e,t){let{matches:r}=matchMedia("(hover)"),o=C(()=>{let n=new g,i=n.pipe(jr(1));n.subscribe(({scrollable:c})=>{c&&r?e.setAttribute("tabindex","0"):e.removeAttribute("tabindex")});let a=[];if(Pn.default.isSupported()&&(e.closest(".copy")||B("content.code.copy")&&!e.closest(".no-copy"))){let c=e.closest("pre");c.id=`__code_${Ua++}`;let l=Tn(c.id);c.insertBefore(l,e),B("content.tooltips")&&a.push(mt(l,{viewport$}))}let s=e.closest(".highlight");if(s instanceof HTMLElement){let c=Rn(s);if(typeof c!="undefined"&&(s.classList.contains("annotate")||B("content.code.annotate"))){let l=fr(c,e,t);a.push(ge(s).pipe(U(i),m(({width:f,height:u})=>f&&u),K(),v(f=>f?l:S)))}}return P(":scope > span[id]",e).length&&e.classList.add("md-code__content"),Da(e).pipe(w(c=>n.next(c)),_(()=>n.complete()),m(c=>$({ref:e},c)),Re(...a))});return B("content.lazy")?tt(e).pipe(b(n=>n),Te(1),v(()=>o)):o}function Va(e,{target$:t,print$:r}){let o=!0;return O(t.pipe(m(n=>n.closest("details:not([open])")),b(n=>e===n),m(()=>({action:"open",reveal:!0}))),r.pipe(b(n=>n||!o),w(()=>o=e.open),m(n=>({action:n?"open":"close"}))))}function jn(e,t){return C(()=>{let r=new g;return r.subscribe(({action:o,reveal:n})=>{e.toggleAttribute("open",o==="open"),n&&e.scrollIntoView()}),Va(e,t).pipe(w(o=>r.next(o)),_(()=>r.complete()),m(o=>$({ref:e},o)))})}var Fn=".node circle,.node ellipse,.node path,.node polygon,.node rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}marker{fill:var(--md-mermaid-edge-color)!important}.edgeLabel .label rect{fill:#0000}.label{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.label foreignObject{line-height:normal;overflow:visible}.label div .edgeLabel{color:var(--md-mermaid-label-fg-color)}.edgeLabel,.edgeLabel p,.label div .edgeLabel{background-color:var(--md-mermaid-label-bg-color)}.edgeLabel,.edgeLabel p{fill:var(--md-mermaid-label-bg-color);color:var(--md-mermaid-edge-color)}.edgePath .path,.flowchart-link{stroke:var(--md-mermaid-edge-color);stroke-width:.05rem}.edgePath .arrowheadPath{fill:var(--md-mermaid-edge-color);stroke:none}.cluster rect{fill:var(--md-default-fg-color--lightest);stroke:var(--md-default-fg-color--lighter)}.cluster span{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}g #flowchart-circleEnd,g #flowchart-circleStart,g #flowchart-crossEnd,g #flowchart-crossStart,g #flowchart-pointEnd,g #flowchart-pointStart{stroke:none}g.classGroup line,g.classGroup rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}g.classGroup text{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.classLabel .box{fill:var(--md-mermaid-label-bg-color);background-color:var(--md-mermaid-label-bg-color);opacity:1}.classLabel .label{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.node .divider{stroke:var(--md-mermaid-node-fg-color)}.relation{stroke:var(--md-mermaid-edge-color)}.cardinality{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.cardinality text{fill:inherit!important}defs #classDiagram-compositionEnd,defs #classDiagram-compositionStart,defs #classDiagram-dependencyEnd,defs #classDiagram-dependencyStart,defs #classDiagram-extensionEnd,defs #classDiagram-extensionStart{fill:var(--md-mermaid-edge-color)!important;stroke:var(--md-mermaid-edge-color)!important}defs #classDiagram-aggregationEnd,defs #classDiagram-aggregationStart{fill:var(--md-mermaid-label-bg-color)!important;stroke:var(--md-mermaid-edge-color)!important}g.stateGroup rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}g.stateGroup .state-title{fill:var(--md-mermaid-label-fg-color)!important;font-family:var(--md-mermaid-font-family)}g.stateGroup .composit{fill:var(--md-mermaid-label-bg-color)}.nodeLabel,.nodeLabel p{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}a .nodeLabel{text-decoration:underline}.node circle.state-end,.node circle.state-start,.start-state{fill:var(--md-mermaid-edge-color);stroke:none}.end-state-inner,.end-state-outer{fill:var(--md-mermaid-edge-color)}.end-state-inner,.node circle.state-end{stroke:var(--md-mermaid-label-bg-color)}.transition{stroke:var(--md-mermaid-edge-color)}[id^=state-fork] rect,[id^=state-join] rect{fill:var(--md-mermaid-edge-color)!important;stroke:none!important}.statediagram-cluster.statediagram-cluster .inner{fill:var(--md-default-bg-color)}.statediagram-cluster rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}.statediagram-state rect.divider{fill:var(--md-default-fg-color--lightest);stroke:var(--md-default-fg-color--lighter)}defs #statediagram-barbEnd{stroke:var(--md-mermaid-edge-color)}.attributeBoxEven,.attributeBoxOdd{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}.entityBox{fill:var(--md-mermaid-label-bg-color);stroke:var(--md-mermaid-node-fg-color)}.entityLabel{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.relationshipLabelBox{fill:var(--md-mermaid-label-bg-color);fill-opacity:1;background-color:var(--md-mermaid-label-bg-color);opacity:1}.relationshipLabel{fill:var(--md-mermaid-label-fg-color)}.relationshipLine{stroke:var(--md-mermaid-edge-color)}defs #ONE_OR_MORE_END *,defs #ONE_OR_MORE_START *,defs #ONLY_ONE_END *,defs #ONLY_ONE_START *,defs #ZERO_OR_MORE_END *,defs #ZERO_OR_MORE_START *,defs #ZERO_OR_ONE_END *,defs #ZERO_OR_ONE_START *{stroke:var(--md-mermaid-edge-color)!important}defs #ZERO_OR_MORE_END circle,defs #ZERO_OR_MORE_START circle{fill:var(--md-mermaid-label-bg-color)}.actor{fill:var(--md-mermaid-sequence-actor-bg-color);stroke:var(--md-mermaid-sequence-actor-border-color)}text.actor>tspan{fill:var(--md-mermaid-sequence-actor-fg-color);font-family:var(--md-mermaid-font-family)}line{stroke:var(--md-mermaid-sequence-actor-line-color)}.actor-man circle,.actor-man line{fill:var(--md-mermaid-sequence-actorman-bg-color);stroke:var(--md-mermaid-sequence-actorman-line-color)}.messageLine0,.messageLine1{stroke:var(--md-mermaid-sequence-message-line-color)}.note{fill:var(--md-mermaid-sequence-note-bg-color);stroke:var(--md-mermaid-sequence-note-border-color)}.loopText,.loopText>tspan,.messageText,.noteText>tspan{stroke:none;font-family:var(--md-mermaid-font-family)!important}.messageText{fill:var(--md-mermaid-sequence-message-fg-color)}.loopText,.loopText>tspan{fill:var(--md-mermaid-sequence-loop-fg-color)}.noteText>tspan{fill:var(--md-mermaid-sequence-note-fg-color)}#arrowhead path{fill:var(--md-mermaid-sequence-message-line-color);stroke:none}.loopLine{fill:var(--md-mermaid-sequence-loop-bg-color);stroke:var(--md-mermaid-sequence-loop-border-color)}.labelBox{fill:var(--md-mermaid-sequence-label-bg-color);stroke:none}.labelText,.labelText>span{fill:var(--md-mermaid-sequence-label-fg-color);font-family:var(--md-mermaid-font-family)}.sequenceNumber{fill:var(--md-mermaid-sequence-number-fg-color)}rect.rect{fill:var(--md-mermaid-sequence-box-bg-color);stroke:none}rect.rect+text.text{fill:var(--md-mermaid-sequence-box-fg-color)}defs #sequencenumber{fill:var(--md-mermaid-sequence-number-bg-color)!important}";var Gr,za=0;function qa(){return typeof mermaid=="undefined"||mermaid instanceof Element?Tt("https://unpkg.com/mermaid@11/dist/mermaid.min.js"):I(void 0)}function Wn(e){return e.classList.remove("mermaid"),Gr||(Gr=qa().pipe(w(()=>mermaid.initialize({startOnLoad:!1,themeCSS:Fn,sequence:{actorFontSize:"16px",messageFontSize:"16px",noteFontSize:"16px"}})),m(()=>{}),G(1))),Gr.subscribe(()=>so(this,null,function*(){e.classList.add("mermaid");let t=`__mermaid_${za++}`,r=x("div",{class:"mermaid"}),o=e.textContent,{svg:n,fn:i}=yield mermaid.render(t,o),a=r.attachShadow({mode:"closed"});a.innerHTML=n,e.replaceWith(r),i==null||i(a)})),Gr.pipe(m(()=>({ref:e})))}var Un=x("table");function Dn(e){return e.replaceWith(Un),Un.replaceWith(_n(e)),I({ref:e})}function Qa(e){let t=e.find(r=>r.checked)||e[0];return O(...e.map(r=>h(r,"change").pipe(m(()=>R(`label[for="${r.id}"]`))))).pipe(Q(R(`label[for="${t.id}"]`)),m(r=>({active:r})))}function Vn(e,{viewport$:t,target$:r}){let o=R(".tabbed-labels",e),n=P(":scope > input",e),i=Kr("prev");e.append(i);let a=Kr("next");return e.append(a),C(()=>{let s=new g,p=s.pipe(Z(),ie(!0));z([s,ge(e),tt(e)]).pipe(U(p),Le(1,me)).subscribe({next([{active:c},l]){let f=Ve(c),{width:u}=ce(c);e.style.setProperty("--md-indicator-x",`${f.x}px`),e.style.setProperty("--md-indicator-width",`${u}px`);let d=pr(o);(f.xd.x+l.width)&&o.scrollTo({left:Math.max(0,f.x-16),behavior:"smooth"})},complete(){e.style.removeProperty("--md-indicator-x"),e.style.removeProperty("--md-indicator-width")}}),z([Ne(o),ge(o)]).pipe(U(p)).subscribe(([c,l])=>{let f=St(o);i.hidden=c.x<16,a.hidden=c.x>f.width-l.width-16}),O(h(i,"click").pipe(m(()=>-1)),h(a,"click").pipe(m(()=>1))).pipe(U(p)).subscribe(c=>{let{width:l}=ce(o);o.scrollBy({left:l*c,behavior:"smooth"})}),r.pipe(U(p),b(c=>n.includes(c))).subscribe(c=>c.click()),o.classList.add("tabbed-labels--linked");for(let c of n){let l=R(`label[for="${c.id}"]`);l.replaceChildren(x("a",{href:`#${l.htmlFor}`,tabIndex:-1},...Array.from(l.childNodes))),h(l.firstElementChild,"click").pipe(U(p),b(f=>!(f.metaKey||f.ctrlKey)),w(f=>{f.preventDefault(),f.stopPropagation()})).subscribe(()=>{history.replaceState({},"",`#${l.htmlFor}`),l.click()})}return B("content.tabs.link")&&s.pipe(Ce(1),re(t)).subscribe(([{active:c},{offset:l}])=>{let f=c.innerText.trim();if(c.hasAttribute("data-md-switching"))c.removeAttribute("data-md-switching");else{let u=e.offsetTop-l.y;for(let y of P("[data-tabs]"))for(let M of P(":scope > input",y)){let X=R(`label[for="${M.id}"]`);if(X!==c&&X.innerText.trim()===f){X.setAttribute("data-md-switching",""),M.click();break}}window.scrollTo({top:e.offsetTop-u});let d=__md_get("__tabs")||[];__md_set("__tabs",[...new Set([f,...d])])}}),s.pipe(U(p)).subscribe(()=>{for(let c of P("audio, video",e))c.pause()}),Qa(n).pipe(w(c=>s.next(c)),_(()=>s.complete()),m(c=>$({ref:e},c)))}).pipe(Ke(se))}function Nn(e,{viewport$:t,target$:r,print$:o}){return O(...P(".annotate:not(.highlight)",e).map(n=>$n(n,{target$:r,print$:o})),...P("pre:not(.mermaid) > code",e).map(n=>In(n,{target$:r,print$:o})),...P("pre.mermaid",e).map(n=>Wn(n)),...P("table:not([class])",e).map(n=>Dn(n)),...P("details",e).map(n=>jn(n,{target$:r,print$:o})),...P("[data-tabs]",e).map(n=>Vn(n,{viewport$:t,target$:r})),...P("[title]",e).filter(()=>B("content.tooltips")).map(n=>mt(n,{viewport$:t})))}function Ka(e,{alert$:t}){return t.pipe(v(r=>O(I(!0),I(!1).pipe(Ge(2e3))).pipe(m(o=>({message:r,active:o})))))}function zn(e,t){let r=R(".md-typeset",e);return C(()=>{let o=new g;return o.subscribe(({message:n,active:i})=>{e.classList.toggle("md-dialog--active",i),r.textContent=n}),Ka(e,t).pipe(w(n=>o.next(n)),_(()=>o.complete()),m(n=>$({ref:e},n)))})}var Ya=0;function Ba(e,t){document.body.append(e);let{width:r}=ce(e);e.style.setProperty("--md-tooltip-width",`${r}px`),e.remove();let o=cr(t),n=typeof o!="undefined"?Ne(o):I({x:0,y:0}),i=O(et(t),$t(t)).pipe(K());return z([i,n]).pipe(m(([a,s])=>{let{x:p,y:c}=Ve(t),l=ce(t),f=t.closest("table");return f&&t.parentElement&&(p+=f.offsetLeft+t.parentElement.offsetLeft,c+=f.offsetTop+t.parentElement.offsetTop),{active:a,offset:{x:p-s.x+l.width/2-r/2,y:c-s.y+l.height+8}}}))}function qn(e){let t=e.title;if(!t.length)return S;let r=`__tooltip_${Ya++}`,o=Rt(r,"inline"),n=R(".md-typeset",o);return n.innerHTML=t,C(()=>{let i=new g;return i.subscribe({next({offset:a}){o.style.setProperty("--md-tooltip-x",`${a.x}px`),o.style.setProperty("--md-tooltip-y",`${a.y}px`)},complete(){o.style.removeProperty("--md-tooltip-x"),o.style.removeProperty("--md-tooltip-y")}}),O(i.pipe(b(({active:a})=>a)),i.pipe(_e(250),b(({active:a})=>!a))).subscribe({next({active:a}){a?(e.insertAdjacentElement("afterend",o),e.setAttribute("aria-describedby",r),e.removeAttribute("title")):(o.remove(),e.removeAttribute("aria-describedby"),e.setAttribute("title",t))},complete(){o.remove(),e.removeAttribute("aria-describedby"),e.setAttribute("title",t)}}),i.pipe(Le(16,me)).subscribe(({active:a})=>{o.classList.toggle("md-tooltip--active",a)}),i.pipe(pt(125,me),b(()=>!!e.offsetParent),m(()=>e.offsetParent.getBoundingClientRect()),m(({x:a})=>a)).subscribe({next(a){a?o.style.setProperty("--md-tooltip-0",`${-a}px`):o.style.removeProperty("--md-tooltip-0")},complete(){o.style.removeProperty("--md-tooltip-0")}}),Ba(o,e).pipe(w(a=>i.next(a)),_(()=>i.complete()),m(a=>$({ref:e},a)))}).pipe(Ke(se))}function Ga({viewport$:e}){if(!B("header.autohide"))return I(!1);let t=e.pipe(m(({offset:{y:n}})=>n),Be(2,1),m(([n,i])=>[nMath.abs(i-n.y)>100),m(([,[n]])=>n),K()),o=ze("search");return z([e,o]).pipe(m(([{offset:n},i])=>n.y>400&&!i),K(),v(n=>n?r:I(!1)),Q(!1))}function Qn(e,t){return C(()=>z([ge(e),Ga(t)])).pipe(m(([{height:r},o])=>({height:r,hidden:o})),K((r,o)=>r.height===o.height&&r.hidden===o.hidden),G(1))}function Kn(e,{header$:t,main$:r}){return C(()=>{let o=new g,n=o.pipe(Z(),ie(!0));o.pipe(ee("active"),He(t)).subscribe(([{active:a},{hidden:s}])=>{e.classList.toggle("md-header--shadow",a&&!s),e.hidden=s});let i=ue(P("[title]",e)).pipe(b(()=>B("content.tooltips")),ne(a=>qn(a)));return r.subscribe(o),t.pipe(U(n),m(a=>$({ref:e},a)),Re(i.pipe(U(n))))})}function Ja(e,{viewport$:t,header$:r}){return mr(e,{viewport$:t,header$:r}).pipe(m(({offset:{y:o}})=>{let{height:n}=ce(e);return{active:o>=n}}),ee("active"))}function Yn(e,t){return C(()=>{let r=new g;r.subscribe({next({active:n}){e.classList.toggle("md-header__title--active",n)},complete(){e.classList.remove("md-header__title--active")}});let o=fe(".md-content h1");return typeof o=="undefined"?S:Ja(o,t).pipe(w(n=>r.next(n)),_(()=>r.complete()),m(n=>$({ref:e},n)))})}function Bn(e,{viewport$:t,header$:r}){let o=r.pipe(m(({height:i})=>i),K()),n=o.pipe(v(()=>ge(e).pipe(m(({height:i})=>({top:e.offsetTop,bottom:e.offsetTop+i})),ee("bottom"))));return z([o,n,t]).pipe(m(([i,{top:a,bottom:s},{offset:{y:p},size:{height:c}}])=>(c=Math.max(0,c-Math.max(0,a-p,i)-Math.max(0,c+p-s)),{offset:a-i,height:c,active:a-i<=p})),K((i,a)=>i.offset===a.offset&&i.height===a.height&&i.active===a.active))}function Xa(e){let t=__md_get("__palette")||{index:e.findIndex(o=>matchMedia(o.getAttribute("data-md-color-media")).matches)},r=Math.max(0,Math.min(t.index,e.length-1));return I(...e).pipe(ne(o=>h(o,"change").pipe(m(()=>o))),Q(e[r]),m(o=>({index:e.indexOf(o),color:{media:o.getAttribute("data-md-color-media"),scheme:o.getAttribute("data-md-color-scheme"),primary:o.getAttribute("data-md-color-primary"),accent:o.getAttribute("data-md-color-accent")}})),G(1))}function Gn(e){let t=P("input",e),r=x("meta",{name:"theme-color"});document.head.appendChild(r);let o=x("meta",{name:"color-scheme"});document.head.appendChild(o);let n=Pt("(prefers-color-scheme: light)");return C(()=>{let i=new g;return i.subscribe(a=>{if(document.body.setAttribute("data-md-color-switching",""),a.color.media==="(prefers-color-scheme)"){let s=matchMedia("(prefers-color-scheme: light)"),p=document.querySelector(s.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");a.color.scheme=p.getAttribute("data-md-color-scheme"),a.color.primary=p.getAttribute("data-md-color-primary"),a.color.accent=p.getAttribute("data-md-color-accent")}for(let[s,p]of Object.entries(a.color))document.body.setAttribute(`data-md-color-${s}`,p);for(let s=0;sa.key==="Enter"),re(i,(a,s)=>s)).subscribe(({index:a})=>{a=(a+1)%t.length,t[a].click(),t[a].focus()}),i.pipe(m(()=>{let a=Se("header"),s=window.getComputedStyle(a);return o.content=s.colorScheme,s.backgroundColor.match(/\d+/g).map(p=>(+p).toString(16).padStart(2,"0")).join("")})).subscribe(a=>r.content=`#${a}`),i.pipe(ve(se)).subscribe(()=>{document.body.removeAttribute("data-md-color-switching")}),Xa(t).pipe(U(n.pipe(Ce(1))),ct(),w(a=>i.next(a)),_(()=>i.complete()),m(a=>$({ref:e},a)))})}function Jn(e,{progress$:t}){return C(()=>{let r=new g;return r.subscribe(({value:o})=>{e.style.setProperty("--md-progress-value",`${o}`)}),t.pipe(w(o=>r.next({value:o})),_(()=>r.complete()),m(o=>({ref:e,value:o})))})}var Jr=Lt(Br());function Za(e){e.setAttribute("data-md-copying","");let t=e.closest("[data-copy]"),r=t?t.getAttribute("data-copy"):e.innerText;return e.removeAttribute("data-md-copying"),r.trimEnd()}function Xn({alert$:e}){Jr.default.isSupported()&&new j(t=>{new Jr.default("[data-clipboard-target], [data-clipboard-text]",{text:r=>r.getAttribute("data-clipboard-text")||Za(R(r.getAttribute("data-clipboard-target")))}).on("success",r=>t.next(r))}).pipe(w(t=>{t.trigger.focus()}),m(()=>Ee("clipboard.copied"))).subscribe(e)}function Zn(e,t){return e.protocol=t.protocol,e.hostname=t.hostname,e}function es(e,t){let r=new Map;for(let o of P("url",e)){let n=R("loc",o),i=[Zn(new URL(n.textContent),t)];r.set(`${i[0]}`,i);for(let a of P("[rel=alternate]",o)){let s=a.getAttribute("href");s!=null&&i.push(Zn(new URL(s),t))}}return r}function ur(e){return fn(new URL("sitemap.xml",e)).pipe(m(t=>es(t,new URL(e))),de(()=>I(new Map)))}function ts(e,t){if(!(e.target instanceof Element))return S;let r=e.target.closest("a");if(r===null)return S;if(r.target||e.metaKey||e.ctrlKey)return S;let o=new URL(r.href);return o.search=o.hash="",t.has(`${o}`)?(e.preventDefault(),I(new URL(r.href))):S}function ei(e){let t=new Map;for(let r of P(":scope > *",e.head))t.set(r.outerHTML,r);return t}function ti(e){for(let t of P("[href], [src]",e))for(let r of["href","src"]){let o=t.getAttribute(r);if(o&&!/^(?:[a-z]+:)?\/\//i.test(o)){t[r]=t[r];break}}return I(e)}function rs(e){for(let o of["[data-md-component=announce]","[data-md-component=container]","[data-md-component=header-topic]","[data-md-component=outdated]","[data-md-component=logo]","[data-md-component=skip]",...B("navigation.tabs.sticky")?["[data-md-component=tabs]"]:[]]){let n=fe(o),i=fe(o,e);typeof n!="undefined"&&typeof i!="undefined"&&n.replaceWith(i)}let t=ei(document);for(let[o,n]of ei(e))t.has(o)?t.delete(o):document.head.appendChild(n);for(let o of t.values()){let n=o.getAttribute("name");n!=="theme-color"&&n!=="color-scheme"&&o.remove()}let r=Se("container");return Ue(P("script",r)).pipe(v(o=>{let n=e.createElement("script");if(o.src){for(let i of o.getAttributeNames())n.setAttribute(i,o.getAttribute(i));return o.replaceWith(n),new j(i=>{n.onload=()=>i.complete()})}else return n.textContent=o.textContent,o.replaceWith(n),S}),Z(),ie(document))}function ri({location$:e,viewport$:t,progress$:r}){let o=xe();if(location.protocol==="file:")return S;let n=ur(o.base);I(document).subscribe(ti);let i=h(document.body,"click").pipe(He(n),v(([p,c])=>ts(p,c)),pe()),a=h(window,"popstate").pipe(m(ye),pe());i.pipe(re(t)).subscribe(([p,{offset:c}])=>{history.replaceState(c,""),history.pushState(null,"",p)}),O(i,a).subscribe(e);let s=e.pipe(ee("pathname"),v(p=>mn(p,{progress$:r}).pipe(de(()=>(lt(p,!0),S)))),v(ti),v(rs),pe());return O(s.pipe(re(e,(p,c)=>c)),s.pipe(v(()=>e),ee("pathname"),v(()=>e),ee("hash")),e.pipe(K((p,c)=>p.pathname===c.pathname&&p.hash===c.hash),v(()=>i),w(()=>history.back()))).subscribe(p=>{var c,l;history.state!==null||!p.hash?window.scrollTo(0,(l=(c=history.state)==null?void 0:c.y)!=null?l:0):(history.scrollRestoration="auto",cn(p.hash),history.scrollRestoration="manual")}),e.subscribe(()=>{history.scrollRestoration="manual"}),h(window,"beforeunload").subscribe(()=>{history.scrollRestoration="auto"}),t.pipe(ee("offset"),_e(100)).subscribe(({offset:p})=>{history.replaceState(p,"")}),s}var oi=Lt(qr());function ni(e){let t=e.separator.split("|").map(n=>n.replace(/(\(\?[!=<][^)]+\))/g,"").length===0?"\uFFFD":n).join("|"),r=new RegExp(t,"img"),o=(n,i,a)=>`${i}${a}`;return n=>{n=n.replace(/[\s*+\-:~^]+/g," ").trim();let i=new RegExp(`(^|${e.separator}|)(${n.replace(/[|\\{}()[\]^$+*?.-]/g,"\\$&").replace(r,"|")})`,"img");return a=>(0,oi.default)(a).replace(i,o).replace(/<\/mark>(\s+)]*>/img,"$1")}}function jt(e){return e.type===1}function dr(e){return e.type===3}function ii(e,t){let r=gn(e);return O(I(location.protocol!=="file:"),ze("search")).pipe(Ae(o=>o),v(()=>t)).subscribe(({config:o,docs:n})=>r.next({type:0,data:{config:o,docs:n,options:{suggest:B("search.suggest")}}})),r}function ai({document$:e}){let t=xe(),r=je(new URL("../versions.json",t.base)).pipe(de(()=>S)),o=r.pipe(m(n=>{let[,i]=t.base.match(/([^/]+)\/?$/);return n.find(({version:a,aliases:s})=>a===i||s.includes(i))||n[0]}));r.pipe(m(n=>new Map(n.map(i=>[`${new URL(`../${i.version}/`,t.base)}`,i]))),v(n=>h(document.body,"click").pipe(b(i=>!i.metaKey&&!i.ctrlKey),re(o),v(([i,a])=>{if(i.target instanceof Element){let s=i.target.closest("a");if(s&&!s.target&&n.has(s.href)){let p=s.href;return!i.target.closest(".md-version")&&n.get(p)===a?S:(i.preventDefault(),I(p))}}return S}),v(i=>ur(new URL(i)).pipe(m(a=>{let p=ye().href.replace(t.base,i);return a.has(p.split("#")[0])?new URL(p):new URL(i)})))))).subscribe(n=>lt(n,!0)),z([r,o]).subscribe(([n,i])=>{R(".md-header__topic").appendChild(An(n,i))}),e.pipe(v(()=>o)).subscribe(n=>{var a;let i=__md_get("__outdated",sessionStorage);if(i===null){i=!0;let s=((a=t.version)==null?void 0:a.default)||"latest";Array.isArray(s)||(s=[s]);e:for(let p of s)for(let c of n.aliases.concat(n.version))if(new RegExp(p,"i").test(c)){i=!1;break e}__md_set("__outdated",i,sessionStorage)}if(i)for(let s of ae("outdated"))s.hidden=!1})}function is(e,{worker$:t}){let{searchParams:r}=ye();r.has("q")&&(Je("search",!0),e.value=r.get("q"),e.focus(),ze("search").pipe(Ae(i=>!i)).subscribe(()=>{let i=ye();i.searchParams.delete("q"),history.replaceState({},"",`${i}`)}));let o=et(e),n=O(t.pipe(Ae(jt)),h(e,"keyup"),o).pipe(m(()=>e.value),K());return z([n,o]).pipe(m(([i,a])=>({value:i,focus:a})),G(1))}function si(e,{worker$:t}){let r=new g,o=r.pipe(Z(),ie(!0));z([t.pipe(Ae(jt)),r],(i,a)=>a).pipe(ee("value")).subscribe(({value:i})=>t.next({type:2,data:i})),r.pipe(ee("focus")).subscribe(({focus:i})=>{i&&Je("search",i)}),h(e.form,"reset").pipe(U(o)).subscribe(()=>e.focus());let n=R("header [for=__search]");return h(n,"click").subscribe(()=>e.focus()),is(e,{worker$:t}).pipe(w(i=>r.next(i)),_(()=>r.complete()),m(i=>$({ref:e},i)),G(1))}function ci(e,{worker$:t,query$:r}){let o=new g,n=rn(e.parentElement).pipe(b(Boolean)),i=e.parentElement,a=R(":scope > :first-child",e),s=R(":scope > :last-child",e);ze("search").subscribe(l=>s.setAttribute("role",l?"list":"presentation")),o.pipe(re(r),Ur(t.pipe(Ae(jt)))).subscribe(([{items:l},{value:f}])=>{switch(l.length){case 0:a.textContent=f.length?Ee("search.result.none"):Ee("search.result.placeholder");break;case 1:a.textContent=Ee("search.result.one");break;default:let u=sr(l.length);a.textContent=Ee("search.result.other",u)}});let p=o.pipe(w(()=>s.innerHTML=""),v(({items:l})=>O(I(...l.slice(0,10)),I(...l.slice(10)).pipe(Be(4),Vr(n),v(([f])=>f)))),m(Mn),pe());return p.subscribe(l=>s.appendChild(l)),p.pipe(ne(l=>{let f=fe("details",l);return typeof f=="undefined"?S:h(f,"toggle").pipe(U(o),m(()=>f))})).subscribe(l=>{l.open===!1&&l.offsetTop<=i.scrollTop&&i.scrollTo({top:l.offsetTop})}),t.pipe(b(dr),m(({data:l})=>l)).pipe(w(l=>o.next(l)),_(()=>o.complete()),m(l=>$({ref:e},l)))}function as(e,{query$:t}){return t.pipe(m(({value:r})=>{let o=ye();return o.hash="",r=r.replace(/\s+/g,"+").replace(/&/g,"%26").replace(/=/g,"%3D"),o.search=`q=${r}`,{url:o}}))}function pi(e,t){let r=new g,o=r.pipe(Z(),ie(!0));return r.subscribe(({url:n})=>{e.setAttribute("data-clipboard-text",e.href),e.href=`${n}`}),h(e,"click").pipe(U(o)).subscribe(n=>n.preventDefault()),as(e,t).pipe(w(n=>r.next(n)),_(()=>r.complete()),m(n=>$({ref:e},n)))}function li(e,{worker$:t,keyboard$:r}){let o=new g,n=Se("search-query"),i=O(h(n,"keydown"),h(n,"focus")).pipe(ve(se),m(()=>n.value),K());return o.pipe(He(i),m(([{suggest:s},p])=>{let c=p.split(/([\s-]+)/);if(s!=null&&s.length&&c[c.length-1]){let l=s[s.length-1];l.startsWith(c[c.length-1])&&(c[c.length-1]=l)}else c.length=0;return c})).subscribe(s=>e.innerHTML=s.join("").replace(/\s/g," ")),r.pipe(b(({mode:s})=>s==="search")).subscribe(s=>{switch(s.type){case"ArrowRight":e.innerText.length&&n.selectionStart===n.value.length&&(n.value=e.innerText);break}}),t.pipe(b(dr),m(({data:s})=>s)).pipe(w(s=>o.next(s)),_(()=>o.complete()),m(()=>({ref:e})))}function mi(e,{index$:t,keyboard$:r}){let o=xe();try{let n=ii(o.search,t),i=Se("search-query",e),a=Se("search-result",e);h(e,"click").pipe(b(({target:p})=>p instanceof Element&&!!p.closest("a"))).subscribe(()=>Je("search",!1)),r.pipe(b(({mode:p})=>p==="search")).subscribe(p=>{let c=Ie();switch(p.type){case"Enter":if(c===i){let l=new Map;for(let f of P(":first-child [href]",a)){let u=f.firstElementChild;l.set(f,parseFloat(u.getAttribute("data-md-score")))}if(l.size){let[[f]]=[...l].sort(([,u],[,d])=>d-u);f.click()}p.claim()}break;case"Escape":case"Tab":Je("search",!1),i.blur();break;case"ArrowUp":case"ArrowDown":if(typeof c=="undefined")i.focus();else{let l=[i,...P(":not(details) > [href], summary, details[open] [href]",a)],f=Math.max(0,(Math.max(0,l.indexOf(c))+l.length+(p.type==="ArrowUp"?-1:1))%l.length);l[f].focus()}p.claim();break;default:i!==Ie()&&i.focus()}}),r.pipe(b(({mode:p})=>p==="global")).subscribe(p=>{switch(p.type){case"f":case"s":case"/":i.focus(),i.select(),p.claim();break}});let s=si(i,{worker$:n});return O(s,ci(a,{worker$:n,query$:s})).pipe(Re(...ae("search-share",e).map(p=>pi(p,{query$:s})),...ae("search-suggest",e).map(p=>li(p,{worker$:n,keyboard$:r}))))}catch(n){return e.hidden=!0,Ye}}function fi(e,{index$:t,location$:r}){return z([t,r.pipe(Q(ye()),b(o=>!!o.searchParams.get("h")))]).pipe(m(([o,n])=>ni(o.config)(n.searchParams.get("h"))),m(o=>{var a;let n=new Map,i=document.createNodeIterator(e,NodeFilter.SHOW_TEXT);for(let s=i.nextNode();s;s=i.nextNode())if((a=s.parentElement)!=null&&a.offsetHeight){let p=s.textContent,c=o(p);c.length>p.length&&n.set(s,c)}for(let[s,p]of n){let{childNodes:c}=x("span",null,p);s.replaceWith(...Array.from(c))}return{ref:e,nodes:n}}))}function ss(e,{viewport$:t,main$:r}){let o=e.closest(".md-grid"),n=o.offsetTop-o.parentElement.offsetTop;return z([r,t]).pipe(m(([{offset:i,height:a},{offset:{y:s}}])=>(a=a+Math.min(n,Math.max(0,s-i))-n,{height:a,locked:s>=i+n})),K((i,a)=>i.height===a.height&&i.locked===a.locked))}function Xr(e,o){var n=o,{header$:t}=n,r=ao(n,["header$"]);let i=R(".md-sidebar__scrollwrap",e),{y:a}=Ve(i);return C(()=>{let s=new g,p=s.pipe(Z(),ie(!0)),c=s.pipe(Le(0,me));return c.pipe(re(t)).subscribe({next([{height:l},{height:f}]){i.style.height=`${l-2*a}px`,e.style.top=`${f}px`},complete(){i.style.height="",e.style.top=""}}),c.pipe(Ae()).subscribe(()=>{for(let l of P(".md-nav__link--active[href]",e)){if(!l.clientHeight)continue;let f=l.closest(".md-sidebar__scrollwrap");if(typeof f!="undefined"){let u=l.offsetTop-f.offsetTop,{height:d}=ce(f);f.scrollTo({top:u-d/2})}}}),ue(P("label[tabindex]",e)).pipe(ne(l=>h(l,"click").pipe(ve(se),m(()=>l),U(p)))).subscribe(l=>{let f=R(`[id="${l.htmlFor}"]`);R(`[aria-labelledby="${l.id}"]`).setAttribute("aria-expanded",`${f.checked}`)}),ss(e,r).pipe(w(l=>s.next(l)),_(()=>s.complete()),m(l=>$({ref:e},l)))})}function ui(e,t){if(typeof t!="undefined"){let r=`https://api.github.com/repos/${e}/${t}`;return st(je(`${r}/releases/latest`).pipe(de(()=>S),m(o=>({version:o.tag_name})),De({})),je(r).pipe(de(()=>S),m(o=>({stars:o.stargazers_count,forks:o.forks_count})),De({}))).pipe(m(([o,n])=>$($({},o),n)))}else{let r=`https://api.github.com/users/${e}`;return je(r).pipe(m(o=>({repositories:o.public_repos})),De({}))}}function di(e,t){let r=`https://${e}/api/v4/projects/${encodeURIComponent(t)}`;return st(je(`${r}/releases/permalink/latest`).pipe(de(()=>S),m(({tag_name:o})=>({version:o})),De({})),je(r).pipe(de(()=>S),m(({star_count:o,forks_count:n})=>({stars:o,forks:n})),De({}))).pipe(m(([o,n])=>$($({},o),n)))}function hi(e){let t=e.match(/^.+github\.com\/([^/]+)\/?([^/]+)?/i);if(t){let[,r,o]=t;return ui(r,o)}if(t=e.match(/^.+?([^/]*gitlab[^/]+)\/(.+?)\/?$/i),t){let[,r,o]=t;return di(r,o)}return S}var cs;function ps(e){return cs||(cs=C(()=>{let t=__md_get("__source",sessionStorage);if(t)return I(t);if(ae("consent").length){let o=__md_get("__consent");if(!(o&&o.github))return S}return hi(e.href).pipe(w(o=>__md_set("__source",o,sessionStorage)))}).pipe(de(()=>S),b(t=>Object.keys(t).length>0),m(t=>({facts:t})),G(1)))}function bi(e){let t=R(":scope > :last-child",e);return C(()=>{let r=new g;return r.subscribe(({facts:o})=>{t.appendChild(Ln(o)),t.classList.add("md-source__repository--active")}),ps(e).pipe(w(o=>r.next(o)),_(()=>r.complete()),m(o=>$({ref:e},o)))})}function ls(e,{viewport$:t,header$:r}){return ge(document.body).pipe(v(()=>mr(e,{header$:r,viewport$:t})),m(({offset:{y:o}})=>({hidden:o>=10})),ee("hidden"))}function vi(e,t){return C(()=>{let r=new g;return r.subscribe({next({hidden:o}){e.hidden=o},complete(){e.hidden=!1}}),(B("navigation.tabs.sticky")?I({hidden:!1}):ls(e,t)).pipe(w(o=>r.next(o)),_(()=>r.complete()),m(o=>$({ref:e},o)))})}function ms(e,{viewport$:t,header$:r}){let o=new Map,n=P(".md-nav__link",e);for(let s of n){let p=decodeURIComponent(s.hash.substring(1)),c=fe(`[id="${p}"]`);typeof c!="undefined"&&o.set(s,c)}let i=r.pipe(ee("height"),m(({height:s})=>{let p=Se("main"),c=R(":scope > :first-child",p);return s+.8*(c.offsetTop-p.offsetTop)}),pe());return ge(document.body).pipe(ee("height"),v(s=>C(()=>{let p=[];return I([...o].reduce((c,[l,f])=>{for(;p.length&&o.get(p[p.length-1]).tagName>=f.tagName;)p.pop();let u=f.offsetTop;for(;!u&&f.parentElement;)f=f.parentElement,u=f.offsetTop;let d=f.offsetParent;for(;d;d=d.offsetParent)u+=d.offsetTop;return c.set([...p=[...p,l]].reverse(),u)},new Map))}).pipe(m(p=>new Map([...p].sort(([,c],[,l])=>c-l))),He(i),v(([p,c])=>t.pipe(Fr(([l,f],{offset:{y:u},size:d})=>{let y=u+d.height>=Math.floor(s.height);for(;f.length;){let[,M]=f[0];if(M-c=u&&!y)f=[l.pop(),...f];else break}return[l,f]},[[],[...p]]),K((l,f)=>l[0]===f[0]&&l[1]===f[1])))))).pipe(m(([s,p])=>({prev:s.map(([c])=>c),next:p.map(([c])=>c)})),Q({prev:[],next:[]}),Be(2,1),m(([s,p])=>s.prev.length{let i=new g,a=i.pipe(Z(),ie(!0));if(i.subscribe(({prev:s,next:p})=>{for(let[c]of p)c.classList.remove("md-nav__link--passed"),c.classList.remove("md-nav__link--active");for(let[c,[l]]of s.entries())l.classList.add("md-nav__link--passed"),l.classList.toggle("md-nav__link--active",c===s.length-1)}),B("toc.follow")){let s=O(t.pipe(_e(1),m(()=>{})),t.pipe(_e(250),m(()=>"smooth")));i.pipe(b(({prev:p})=>p.length>0),He(o.pipe(ve(se))),re(s)).subscribe(([[{prev:p}],c])=>{let[l]=p[p.length-1];if(l.offsetHeight){let f=cr(l);if(typeof f!="undefined"){let u=l.offsetTop-f.offsetTop,{height:d}=ce(f);f.scrollTo({top:u-d/2,behavior:c})}}})}return B("navigation.tracking")&&t.pipe(U(a),ee("offset"),_e(250),Ce(1),U(n.pipe(Ce(1))),ct({delay:250}),re(i)).subscribe(([,{prev:s}])=>{let p=ye(),c=s[s.length-1];if(c&&c.length){let[l]=c,{hash:f}=new URL(l.href);p.hash!==f&&(p.hash=f,history.replaceState({},"",`${p}`))}else p.hash="",history.replaceState({},"",`${p}`)}),ms(e,{viewport$:t,header$:r}).pipe(w(s=>i.next(s)),_(()=>i.complete()),m(s=>$({ref:e},s)))})}function fs(e,{viewport$:t,main$:r,target$:o}){let n=t.pipe(m(({offset:{y:a}})=>a),Be(2,1),m(([a,s])=>a>s&&s>0),K()),i=r.pipe(m(({active:a})=>a));return z([i,n]).pipe(m(([a,s])=>!(a&&s)),K(),U(o.pipe(Ce(1))),ie(!0),ct({delay:250}),m(a=>({hidden:a})))}function yi(e,{viewport$:t,header$:r,main$:o,target$:n}){let i=new g,a=i.pipe(Z(),ie(!0));return i.subscribe({next({hidden:s}){e.hidden=s,s?(e.setAttribute("tabindex","-1"),e.blur()):e.removeAttribute("tabindex")},complete(){e.style.top="",e.hidden=!0,e.removeAttribute("tabindex")}}),r.pipe(U(a),ee("height")).subscribe(({height:s})=>{e.style.top=`${s+16}px`}),h(e,"click").subscribe(s=>{s.preventDefault(),window.scrollTo({top:0})}),fs(e,{viewport$:t,main$:o,target$:n}).pipe(w(s=>i.next(s)),_(()=>i.complete()),m(s=>$({ref:e},s)))}function xi({document$:e,viewport$:t}){e.pipe(v(()=>P(".md-ellipsis")),ne(r=>tt(r).pipe(U(e.pipe(Ce(1))),b(o=>o),m(()=>r),Te(1))),b(r=>r.offsetWidth{let o=r.innerText,n=r.closest("a")||r;return n.title=o,B("content.tooltips")?mt(n,{viewport$:t}).pipe(U(e.pipe(Ce(1))),_(()=>n.removeAttribute("title"))):S})).subscribe(),B("content.tooltips")&&e.pipe(v(()=>P(".md-status")),ne(r=>mt(r,{viewport$:t}))).subscribe()}function Ei({document$:e,tablet$:t}){e.pipe(v(()=>P(".md-toggle--indeterminate")),w(r=>{r.indeterminate=!0,r.checked=!1}),ne(r=>h(r,"change").pipe(Dr(()=>r.classList.contains("md-toggle--indeterminate")),m(()=>r))),re(t)).subscribe(([r,o])=>{r.classList.remove("md-toggle--indeterminate"),o&&(r.checked=!1)})}function us(){return/(iPad|iPhone|iPod)/.test(navigator.userAgent)}function wi({document$:e}){e.pipe(v(()=>P("[data-md-scrollfix]")),w(t=>t.removeAttribute("data-md-scrollfix")),b(us),ne(t=>h(t,"touchstart").pipe(m(()=>t)))).subscribe(t=>{let r=t.scrollTop;r===0?t.scrollTop=1:r+t.offsetHeight===t.scrollHeight&&(t.scrollTop=r-1)})}function Ti({viewport$:e,tablet$:t}){z([ze("search"),t]).pipe(m(([r,o])=>r&&!o),v(r=>I(r).pipe(Ge(r?400:100))),re(e)).subscribe(([r,{offset:{y:o}}])=>{if(r)document.body.setAttribute("data-md-scrolllock",""),document.body.style.top=`-${o}px`;else{let n=-1*parseInt(document.body.style.top,10);document.body.removeAttribute("data-md-scrolllock"),document.body.style.top="",n&&window.scrollTo(0,n)}})}Object.entries||(Object.entries=function(e){let t=[];for(let r of Object.keys(e))t.push([r,e[r]]);return t});Object.values||(Object.values=function(e){let t=[];for(let r of Object.keys(e))t.push(e[r]);return t});typeof Element!="undefined"&&(Element.prototype.scrollTo||(Element.prototype.scrollTo=function(e,t){typeof e=="object"?(this.scrollLeft=e.left,this.scrollTop=e.top):(this.scrollLeft=e,this.scrollTop=t)}),Element.prototype.replaceWith||(Element.prototype.replaceWith=function(...e){let t=this.parentNode;if(t){e.length===0&&t.removeChild(this);for(let r=e.length-1;r>=0;r--){let o=e[r];typeof o=="string"?o=document.createTextNode(o):o.parentNode&&o.parentNode.removeChild(o),r?t.insertBefore(this.previousSibling,o):t.replaceChild(o,this)}}}));function ds(){return location.protocol==="file:"?Tt(`${new URL("search/search_index.js",Zr.base)}`).pipe(m(()=>__index),G(1)):je(new URL("search/search_index.json",Zr.base))}document.documentElement.classList.remove("no-js");document.documentElement.classList.add("js");var ot=Bo(),Wt=an(),Mt=pn(Wt),eo=nn(),Oe=vn(),hr=Pt("(min-width: 960px)"),Oi=Pt("(min-width: 1220px)"),Mi=ln(),Zr=xe(),Li=document.forms.namedItem("search")?ds():Ye,to=new g;Xn({alert$:to});var ro=new g;B("navigation.instant")&&ri({location$:Wt,viewport$:Oe,progress$:ro}).subscribe(ot);var Si;((Si=Zr.version)==null?void 0:Si.provider)==="mike"&&ai({document$:ot});O(Wt,Mt).pipe(Ge(125)).subscribe(()=>{Je("drawer",!1),Je("search",!1)});eo.pipe(b(({mode:e})=>e==="global")).subscribe(e=>{switch(e.type){case"p":case",":let t=fe("link[rel=prev]");typeof t!="undefined"&<(t);break;case"n":case".":let r=fe("link[rel=next]");typeof r!="undefined"&<(r);break;case"Enter":let o=Ie();o instanceof HTMLLabelElement&&o.click()}});xi({viewport$:Oe,document$:ot});Ei({document$:ot,tablet$:hr});wi({document$:ot});Ti({viewport$:Oe,tablet$:hr});var rt=Qn(Se("header"),{viewport$:Oe}),Ft=ot.pipe(m(()=>Se("main")),v(e=>Bn(e,{viewport$:Oe,header$:rt})),G(1)),hs=O(...ae("consent").map(e=>xn(e,{target$:Mt})),...ae("dialog").map(e=>zn(e,{alert$:to})),...ae("header").map(e=>Kn(e,{viewport$:Oe,header$:rt,main$:Ft})),...ae("palette").map(e=>Gn(e)),...ae("progress").map(e=>Jn(e,{progress$:ro})),...ae("search").map(e=>mi(e,{index$:Li,keyboard$:eo})),...ae("source").map(e=>bi(e))),bs=C(()=>O(...ae("announce").map(e=>yn(e)),...ae("content").map(e=>Nn(e,{viewport$:Oe,target$:Mt,print$:Mi})),...ae("content").map(e=>B("search.highlight")?fi(e,{index$:Li,location$:Wt}):S),...ae("header-title").map(e=>Yn(e,{viewport$:Oe,header$:rt})),...ae("sidebar").map(e=>e.getAttribute("data-md-type")==="navigation"?Nr(Oi,()=>Xr(e,{viewport$:Oe,header$:rt,main$:Ft})):Nr(hr,()=>Xr(e,{viewport$:Oe,header$:rt,main$:Ft}))),...ae("tabs").map(e=>vi(e,{viewport$:Oe,header$:rt})),...ae("toc").map(e=>gi(e,{viewport$:Oe,header$:rt,main$:Ft,target$:Mt})),...ae("top").map(e=>yi(e,{viewport$:Oe,header$:rt,main$:Ft,target$:Mt})))),_i=ot.pipe(v(()=>bs),Re(hs),G(1));_i.subscribe();window.document$=ot;window.location$=Wt;window.target$=Mt;window.keyboard$=eo;window.viewport$=Oe;window.tablet$=hr;window.screen$=Oi;window.print$=Mi;window.alert$=to;window.progress$=ro;window.component$=_i;})(); +//# sourceMappingURL=bundle.56dfad97.min.js.map + diff --git a/assets/javascripts/bundle.56dfad97.min.js.map b/assets/javascripts/bundle.56dfad97.min.js.map new file mode 100644 index 0000000..eb83bdb --- /dev/null +++ b/assets/javascripts/bundle.56dfad97.min.js.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": ["node_modules/focus-visible/dist/focus-visible.js", "node_modules/escape-html/index.js", "node_modules/clipboard/dist/clipboard.js", "src/templates/assets/javascripts/bundle.ts", "node_modules/tslib/tslib.es6.mjs", "node_modules/rxjs/src/internal/util/isFunction.ts", "node_modules/rxjs/src/internal/util/createErrorClass.ts", "node_modules/rxjs/src/internal/util/UnsubscriptionError.ts", "node_modules/rxjs/src/internal/util/arrRemove.ts", "node_modules/rxjs/src/internal/Subscription.ts", "node_modules/rxjs/src/internal/config.ts", "node_modules/rxjs/src/internal/scheduler/timeoutProvider.ts", "node_modules/rxjs/src/internal/util/reportUnhandledError.ts", "node_modules/rxjs/src/internal/util/noop.ts", "node_modules/rxjs/src/internal/NotificationFactories.ts", "node_modules/rxjs/src/internal/util/errorContext.ts", "node_modules/rxjs/src/internal/Subscriber.ts", "node_modules/rxjs/src/internal/symbol/observable.ts", "node_modules/rxjs/src/internal/util/identity.ts", "node_modules/rxjs/src/internal/util/pipe.ts", "node_modules/rxjs/src/internal/Observable.ts", "node_modules/rxjs/src/internal/util/lift.ts", "node_modules/rxjs/src/internal/operators/OperatorSubscriber.ts", "node_modules/rxjs/src/internal/scheduler/animationFrameProvider.ts", "node_modules/rxjs/src/internal/util/ObjectUnsubscribedError.ts", "node_modules/rxjs/src/internal/Subject.ts", "node_modules/rxjs/src/internal/BehaviorSubject.ts", "node_modules/rxjs/src/internal/scheduler/dateTimestampProvider.ts", "node_modules/rxjs/src/internal/ReplaySubject.ts", "node_modules/rxjs/src/internal/scheduler/Action.ts", "node_modules/rxjs/src/internal/scheduler/intervalProvider.ts", "node_modules/rxjs/src/internal/scheduler/AsyncAction.ts", "node_modules/rxjs/src/internal/Scheduler.ts", "node_modules/rxjs/src/internal/scheduler/AsyncScheduler.ts", "node_modules/rxjs/src/internal/scheduler/async.ts", "node_modules/rxjs/src/internal/scheduler/QueueAction.ts", "node_modules/rxjs/src/internal/scheduler/QueueScheduler.ts", "node_modules/rxjs/src/internal/scheduler/queue.ts", "node_modules/rxjs/src/internal/scheduler/AnimationFrameAction.ts", "node_modules/rxjs/src/internal/scheduler/AnimationFrameScheduler.ts", "node_modules/rxjs/src/internal/scheduler/animationFrame.ts", "node_modules/rxjs/src/internal/observable/empty.ts", "node_modules/rxjs/src/internal/util/isScheduler.ts", "node_modules/rxjs/src/internal/util/args.ts", "node_modules/rxjs/src/internal/util/isArrayLike.ts", "node_modules/rxjs/src/internal/util/isPromise.ts", "node_modules/rxjs/src/internal/util/isInteropObservable.ts", "node_modules/rxjs/src/internal/util/isAsyncIterable.ts", "node_modules/rxjs/src/internal/util/throwUnobservableError.ts", "node_modules/rxjs/src/internal/symbol/iterator.ts", "node_modules/rxjs/src/internal/util/isIterable.ts", "node_modules/rxjs/src/internal/util/isReadableStreamLike.ts", "node_modules/rxjs/src/internal/observable/innerFrom.ts", "node_modules/rxjs/src/internal/util/executeSchedule.ts", "node_modules/rxjs/src/internal/operators/observeOn.ts", "node_modules/rxjs/src/internal/operators/subscribeOn.ts", "node_modules/rxjs/src/internal/scheduled/scheduleObservable.ts", "node_modules/rxjs/src/internal/scheduled/schedulePromise.ts", "node_modules/rxjs/src/internal/scheduled/scheduleArray.ts", "node_modules/rxjs/src/internal/scheduled/scheduleIterable.ts", "node_modules/rxjs/src/internal/scheduled/scheduleAsyncIterable.ts", "node_modules/rxjs/src/internal/scheduled/scheduleReadableStreamLike.ts", "node_modules/rxjs/src/internal/scheduled/scheduled.ts", "node_modules/rxjs/src/internal/observable/from.ts", "node_modules/rxjs/src/internal/observable/of.ts", "node_modules/rxjs/src/internal/observable/throwError.ts", "node_modules/rxjs/src/internal/util/EmptyError.ts", "node_modules/rxjs/src/internal/util/isDate.ts", "node_modules/rxjs/src/internal/operators/map.ts", "node_modules/rxjs/src/internal/util/mapOneOrManyArgs.ts", "node_modules/rxjs/src/internal/util/argsArgArrayOrObject.ts", "node_modules/rxjs/src/internal/util/createObject.ts", "node_modules/rxjs/src/internal/observable/combineLatest.ts", "node_modules/rxjs/src/internal/operators/mergeInternals.ts", "node_modules/rxjs/src/internal/operators/mergeMap.ts", "node_modules/rxjs/src/internal/operators/mergeAll.ts", "node_modules/rxjs/src/internal/operators/concatAll.ts", "node_modules/rxjs/src/internal/observable/concat.ts", "node_modules/rxjs/src/internal/observable/defer.ts", "node_modules/rxjs/src/internal/observable/fromEvent.ts", "node_modules/rxjs/src/internal/observable/fromEventPattern.ts", "node_modules/rxjs/src/internal/observable/timer.ts", "node_modules/rxjs/src/internal/observable/merge.ts", "node_modules/rxjs/src/internal/observable/never.ts", "node_modules/rxjs/src/internal/util/argsOrArgArray.ts", "node_modules/rxjs/src/internal/operators/filter.ts", "node_modules/rxjs/src/internal/observable/zip.ts", "node_modules/rxjs/src/internal/operators/audit.ts", "node_modules/rxjs/src/internal/operators/auditTime.ts", "node_modules/rxjs/src/internal/operators/bufferCount.ts", "node_modules/rxjs/src/internal/operators/catchError.ts", "node_modules/rxjs/src/internal/operators/scanInternals.ts", "node_modules/rxjs/src/internal/operators/combineLatest.ts", "node_modules/rxjs/src/internal/operators/combineLatestWith.ts", "node_modules/rxjs/src/internal/operators/debounce.ts", "node_modules/rxjs/src/internal/operators/debounceTime.ts", "node_modules/rxjs/src/internal/operators/defaultIfEmpty.ts", "node_modules/rxjs/src/internal/operators/take.ts", "node_modules/rxjs/src/internal/operators/ignoreElements.ts", "node_modules/rxjs/src/internal/operators/mapTo.ts", "node_modules/rxjs/src/internal/operators/delayWhen.ts", "node_modules/rxjs/src/internal/operators/delay.ts", "node_modules/rxjs/src/internal/operators/distinctUntilChanged.ts", "node_modules/rxjs/src/internal/operators/distinctUntilKeyChanged.ts", "node_modules/rxjs/src/internal/operators/throwIfEmpty.ts", "node_modules/rxjs/src/internal/operators/endWith.ts", "node_modules/rxjs/src/internal/operators/finalize.ts", "node_modules/rxjs/src/internal/operators/first.ts", "node_modules/rxjs/src/internal/operators/takeLast.ts", "node_modules/rxjs/src/internal/operators/merge.ts", "node_modules/rxjs/src/internal/operators/mergeWith.ts", "node_modules/rxjs/src/internal/operators/repeat.ts", "node_modules/rxjs/src/internal/operators/scan.ts", "node_modules/rxjs/src/internal/operators/share.ts", "node_modules/rxjs/src/internal/operators/shareReplay.ts", "node_modules/rxjs/src/internal/operators/skip.ts", "node_modules/rxjs/src/internal/operators/skipUntil.ts", "node_modules/rxjs/src/internal/operators/startWith.ts", "node_modules/rxjs/src/internal/operators/switchMap.ts", "node_modules/rxjs/src/internal/operators/takeUntil.ts", "node_modules/rxjs/src/internal/operators/takeWhile.ts", "node_modules/rxjs/src/internal/operators/tap.ts", "node_modules/rxjs/src/internal/operators/throttle.ts", "node_modules/rxjs/src/internal/operators/throttleTime.ts", "node_modules/rxjs/src/internal/operators/withLatestFrom.ts", "node_modules/rxjs/src/internal/operators/zip.ts", "node_modules/rxjs/src/internal/operators/zipWith.ts", "src/templates/assets/javascripts/browser/document/index.ts", "src/templates/assets/javascripts/browser/element/_/index.ts", "src/templates/assets/javascripts/browser/element/focus/index.ts", "src/templates/assets/javascripts/browser/element/hover/index.ts", "src/templates/assets/javascripts/utilities/h/index.ts", "src/templates/assets/javascripts/utilities/round/index.ts", "src/templates/assets/javascripts/browser/script/index.ts", "src/templates/assets/javascripts/browser/element/size/_/index.ts", "src/templates/assets/javascripts/browser/element/size/content/index.ts", "src/templates/assets/javascripts/browser/element/offset/_/index.ts", "src/templates/assets/javascripts/browser/element/offset/content/index.ts", "src/templates/assets/javascripts/browser/element/visibility/index.ts", "src/templates/assets/javascripts/browser/toggle/index.ts", "src/templates/assets/javascripts/browser/keyboard/index.ts", "src/templates/assets/javascripts/browser/location/_/index.ts", "src/templates/assets/javascripts/browser/location/hash/index.ts", "src/templates/assets/javascripts/browser/media/index.ts", "src/templates/assets/javascripts/browser/request/index.ts", "src/templates/assets/javascripts/browser/viewport/offset/index.ts", "src/templates/assets/javascripts/browser/viewport/size/index.ts", "src/templates/assets/javascripts/browser/viewport/_/index.ts", "src/templates/assets/javascripts/browser/viewport/at/index.ts", "src/templates/assets/javascripts/browser/worker/index.ts", "src/templates/assets/javascripts/_/index.ts", "src/templates/assets/javascripts/components/_/index.ts", "src/templates/assets/javascripts/components/announce/index.ts", "src/templates/assets/javascripts/components/consent/index.ts", "src/templates/assets/javascripts/templates/tooltip/index.tsx", "src/templates/assets/javascripts/templates/annotation/index.tsx", "src/templates/assets/javascripts/templates/clipboard/index.tsx", "src/templates/assets/javascripts/templates/search/index.tsx", "src/templates/assets/javascripts/templates/source/index.tsx", "src/templates/assets/javascripts/templates/tabbed/index.tsx", "src/templates/assets/javascripts/templates/table/index.tsx", "src/templates/assets/javascripts/templates/version/index.tsx", "src/templates/assets/javascripts/components/tooltip2/index.ts", "src/templates/assets/javascripts/components/content/annotation/_/index.ts", "src/templates/assets/javascripts/components/content/annotation/list/index.ts", "src/templates/assets/javascripts/components/content/annotation/block/index.ts", "src/templates/assets/javascripts/components/content/code/_/index.ts", "src/templates/assets/javascripts/components/content/details/index.ts", "src/templates/assets/javascripts/components/content/mermaid/index.css", "src/templates/assets/javascripts/components/content/mermaid/index.ts", "src/templates/assets/javascripts/components/content/table/index.ts", "src/templates/assets/javascripts/components/content/tabs/index.ts", "src/templates/assets/javascripts/components/content/_/index.ts", "src/templates/assets/javascripts/components/dialog/index.ts", "src/templates/assets/javascripts/components/tooltip/index.ts", "src/templates/assets/javascripts/components/header/_/index.ts", "src/templates/assets/javascripts/components/header/title/index.ts", "src/templates/assets/javascripts/components/main/index.ts", "src/templates/assets/javascripts/components/palette/index.ts", "src/templates/assets/javascripts/components/progress/index.ts", "src/templates/assets/javascripts/integrations/clipboard/index.ts", "src/templates/assets/javascripts/integrations/sitemap/index.ts", "src/templates/assets/javascripts/integrations/instant/index.ts", "src/templates/assets/javascripts/integrations/search/highlighter/index.ts", "src/templates/assets/javascripts/integrations/search/worker/message/index.ts", "src/templates/assets/javascripts/integrations/search/worker/_/index.ts", "src/templates/assets/javascripts/integrations/version/index.ts", "src/templates/assets/javascripts/components/search/query/index.ts", "src/templates/assets/javascripts/components/search/result/index.ts", "src/templates/assets/javascripts/components/search/share/index.ts", "src/templates/assets/javascripts/components/search/suggest/index.ts", "src/templates/assets/javascripts/components/search/_/index.ts", "src/templates/assets/javascripts/components/search/highlight/index.ts", "src/templates/assets/javascripts/components/sidebar/index.ts", "src/templates/assets/javascripts/components/source/facts/github/index.ts", "src/templates/assets/javascripts/components/source/facts/gitlab/index.ts", "src/templates/assets/javascripts/components/source/facts/_/index.ts", "src/templates/assets/javascripts/components/source/_/index.ts", "src/templates/assets/javascripts/components/tabs/index.ts", "src/templates/assets/javascripts/components/toc/index.ts", "src/templates/assets/javascripts/components/top/index.ts", "src/templates/assets/javascripts/patches/ellipsis/index.ts", "src/templates/assets/javascripts/patches/indeterminate/index.ts", "src/templates/assets/javascripts/patches/scrollfix/index.ts", "src/templates/assets/javascripts/patches/scrolllock/index.ts", "src/templates/assets/javascripts/polyfills/index.ts"], + "sourcesContent": ["(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined' ? factory() :\n typeof define === 'function' && define.amd ? define(factory) :\n (factory());\n}(this, (function () { 'use strict';\n\n /**\n * Applies the :focus-visible polyfill at the given scope.\n * A scope in this case is either the top-level Document or a Shadow Root.\n *\n * @param {(Document|ShadowRoot)} scope\n * @see https://github.com/WICG/focus-visible\n */\n function applyFocusVisiblePolyfill(scope) {\n var hadKeyboardEvent = true;\n var hadFocusVisibleRecently = false;\n var hadFocusVisibleRecentlyTimeout = null;\n\n var inputTypesAllowlist = {\n text: true,\n search: true,\n url: true,\n tel: true,\n email: true,\n password: true,\n number: true,\n date: true,\n month: true,\n week: true,\n time: true,\n datetime: true,\n 'datetime-local': true\n };\n\n /**\n * Helper function for legacy browsers and iframes which sometimes focus\n * elements like document, body, and non-interactive SVG.\n * @param {Element} el\n */\n function isValidFocusTarget(el) {\n if (\n el &&\n el !== document &&\n el.nodeName !== 'HTML' &&\n el.nodeName !== 'BODY' &&\n 'classList' in el &&\n 'contains' in el.classList\n ) {\n return true;\n }\n return false;\n }\n\n /**\n * Computes whether the given element should automatically trigger the\n * `focus-visible` class being added, i.e. whether it should always match\n * `:focus-visible` when focused.\n * @param {Element} el\n * @return {boolean}\n */\n function focusTriggersKeyboardModality(el) {\n var type = el.type;\n var tagName = el.tagName;\n\n if (tagName === 'INPUT' && inputTypesAllowlist[type] && !el.readOnly) {\n return true;\n }\n\n if (tagName === 'TEXTAREA' && !el.readOnly) {\n return true;\n }\n\n if (el.isContentEditable) {\n return true;\n }\n\n return false;\n }\n\n /**\n * Add the `focus-visible` class to the given element if it was not added by\n * the author.\n * @param {Element} el\n */\n function addFocusVisibleClass(el) {\n if (el.classList.contains('focus-visible')) {\n return;\n }\n el.classList.add('focus-visible');\n el.setAttribute('data-focus-visible-added', '');\n }\n\n /**\n * Remove the `focus-visible` class from the given element if it was not\n * originally added by the author.\n * @param {Element} el\n */\n function removeFocusVisibleClass(el) {\n if (!el.hasAttribute('data-focus-visible-added')) {\n return;\n }\n el.classList.remove('focus-visible');\n el.removeAttribute('data-focus-visible-added');\n }\n\n /**\n * If the most recent user interaction was via the keyboard;\n * and the key press did not include a meta, alt/option, or control key;\n * then the modality is keyboard. Otherwise, the modality is not keyboard.\n * Apply `focus-visible` to any current active element and keep track\n * of our keyboard modality state with `hadKeyboardEvent`.\n * @param {KeyboardEvent} e\n */\n function onKeyDown(e) {\n if (e.metaKey || e.altKey || e.ctrlKey) {\n return;\n }\n\n if (isValidFocusTarget(scope.activeElement)) {\n addFocusVisibleClass(scope.activeElement);\n }\n\n hadKeyboardEvent = true;\n }\n\n /**\n * If at any point a user clicks with a pointing device, ensure that we change\n * the modality away from keyboard.\n * This avoids the situation where a user presses a key on an already focused\n * element, and then clicks on a different element, focusing it with a\n * pointing device, while we still think we're in keyboard modality.\n * @param {Event} e\n */\n function onPointerDown(e) {\n hadKeyboardEvent = false;\n }\n\n /**\n * On `focus`, add the `focus-visible` class to the target if:\n * - the target received focus as a result of keyboard navigation, or\n * - the event target is an element that will likely require interaction\n * via the keyboard (e.g. a text box)\n * @param {Event} e\n */\n function onFocus(e) {\n // Prevent IE from focusing the document or HTML element.\n if (!isValidFocusTarget(e.target)) {\n return;\n }\n\n if (hadKeyboardEvent || focusTriggersKeyboardModality(e.target)) {\n addFocusVisibleClass(e.target);\n }\n }\n\n /**\n * On `blur`, remove the `focus-visible` class from the target.\n * @param {Event} e\n */\n function onBlur(e) {\n if (!isValidFocusTarget(e.target)) {\n return;\n }\n\n if (\n e.target.classList.contains('focus-visible') ||\n e.target.hasAttribute('data-focus-visible-added')\n ) {\n // To detect a tab/window switch, we look for a blur event followed\n // rapidly by a visibility change.\n // If we don't see a visibility change within 100ms, it's probably a\n // regular focus change.\n hadFocusVisibleRecently = true;\n window.clearTimeout(hadFocusVisibleRecentlyTimeout);\n hadFocusVisibleRecentlyTimeout = window.setTimeout(function() {\n hadFocusVisibleRecently = false;\n }, 100);\n removeFocusVisibleClass(e.target);\n }\n }\n\n /**\n * If the user changes tabs, keep track of whether or not the previously\n * focused element had .focus-visible.\n * @param {Event} e\n */\n function onVisibilityChange(e) {\n if (document.visibilityState === 'hidden') {\n // If the tab becomes active again, the browser will handle calling focus\n // on the element (Safari actually calls it twice).\n // If this tab change caused a blur on an element with focus-visible,\n // re-apply the class when the user switches back to the tab.\n if (hadFocusVisibleRecently) {\n hadKeyboardEvent = true;\n }\n addInitialPointerMoveListeners();\n }\n }\n\n /**\n * Add a group of listeners to detect usage of any pointing devices.\n * These listeners will be added when the polyfill first loads, and anytime\n * the window is blurred, so that they are active when the window regains\n * focus.\n */\n function addInitialPointerMoveListeners() {\n document.addEventListener('mousemove', onInitialPointerMove);\n document.addEventListener('mousedown', onInitialPointerMove);\n document.addEventListener('mouseup', onInitialPointerMove);\n document.addEventListener('pointermove', onInitialPointerMove);\n document.addEventListener('pointerdown', onInitialPointerMove);\n document.addEventListener('pointerup', onInitialPointerMove);\n document.addEventListener('touchmove', onInitialPointerMove);\n document.addEventListener('touchstart', onInitialPointerMove);\n document.addEventListener('touchend', onInitialPointerMove);\n }\n\n function removeInitialPointerMoveListeners() {\n document.removeEventListener('mousemove', onInitialPointerMove);\n document.removeEventListener('mousedown', onInitialPointerMove);\n document.removeEventListener('mouseup', onInitialPointerMove);\n document.removeEventListener('pointermove', onInitialPointerMove);\n document.removeEventListener('pointerdown', onInitialPointerMove);\n document.removeEventListener('pointerup', onInitialPointerMove);\n document.removeEventListener('touchmove', onInitialPointerMove);\n document.removeEventListener('touchstart', onInitialPointerMove);\n document.removeEventListener('touchend', onInitialPointerMove);\n }\n\n /**\n * When the polfyill first loads, assume the user is in keyboard modality.\n * If any event is received from a pointing device (e.g. mouse, pointer,\n * touch), turn off keyboard modality.\n * This accounts for situations where focus enters the page from the URL bar.\n * @param {Event} e\n */\n function onInitialPointerMove(e) {\n // Work around a Safari quirk that fires a mousemove on whenever the\n // window blurs, even if you're tabbing out of the page. \u00AF\\_(\u30C4)_/\u00AF\n if (e.target.nodeName && e.target.nodeName.toLowerCase() === 'html') {\n return;\n }\n\n hadKeyboardEvent = false;\n removeInitialPointerMoveListeners();\n }\n\n // For some kinds of state, we are interested in changes at the global scope\n // only. For example, global pointer input, global key presses and global\n // visibility change should affect the state at every scope:\n document.addEventListener('keydown', onKeyDown, true);\n document.addEventListener('mousedown', onPointerDown, true);\n document.addEventListener('pointerdown', onPointerDown, true);\n document.addEventListener('touchstart', onPointerDown, true);\n document.addEventListener('visibilitychange', onVisibilityChange, true);\n\n addInitialPointerMoveListeners();\n\n // For focus and blur, we specifically care about state changes in the local\n // scope. This is because focus / blur events that originate from within a\n // shadow root are not re-dispatched from the host element if it was already\n // the active element in its own scope:\n scope.addEventListener('focus', onFocus, true);\n scope.addEventListener('blur', onBlur, true);\n\n // We detect that a node is a ShadowRoot by ensuring that it is a\n // DocumentFragment and also has a host property. This check covers native\n // implementation and polyfill implementation transparently. If we only cared\n // about the native implementation, we could just check if the scope was\n // an instance of a ShadowRoot.\n if (scope.nodeType === Node.DOCUMENT_FRAGMENT_NODE && scope.host) {\n // Since a ShadowRoot is a special kind of DocumentFragment, it does not\n // have a root element to add a class to. So, we add this attribute to the\n // host element instead:\n scope.host.setAttribute('data-js-focus-visible', '');\n } else if (scope.nodeType === Node.DOCUMENT_NODE) {\n document.documentElement.classList.add('js-focus-visible');\n document.documentElement.setAttribute('data-js-focus-visible', '');\n }\n }\n\n // It is important to wrap all references to global window and document in\n // these checks to support server-side rendering use cases\n // @see https://github.com/WICG/focus-visible/issues/199\n if (typeof window !== 'undefined' && typeof document !== 'undefined') {\n // Make the polyfill helper globally available. This can be used as a signal\n // to interested libraries that wish to coordinate with the polyfill for e.g.,\n // applying the polyfill to a shadow root:\n window.applyFocusVisiblePolyfill = applyFocusVisiblePolyfill;\n\n // Notify interested libraries of the polyfill's presence, in case the\n // polyfill was loaded lazily:\n var event;\n\n try {\n event = new CustomEvent('focus-visible-polyfill-ready');\n } catch (error) {\n // IE11 does not support using CustomEvent as a constructor directly:\n event = document.createEvent('CustomEvent');\n event.initCustomEvent('focus-visible-polyfill-ready', false, false, {});\n }\n\n window.dispatchEvent(event);\n }\n\n if (typeof document !== 'undefined') {\n // Apply the polyfill to the global document, so that no JavaScript\n // coordination is required to use the polyfill in the top-level document:\n applyFocusVisiblePolyfill(document);\n }\n\n})));\n", "/*!\n * escape-html\n * Copyright(c) 2012-2013 TJ Holowaychuk\n * Copyright(c) 2015 Andreas Lubbe\n * Copyright(c) 2015 Tiancheng \"Timothy\" Gu\n * MIT Licensed\n */\n\n'use strict';\n\n/**\n * Module variables.\n * @private\n */\n\nvar matchHtmlRegExp = /[\"'&<>]/;\n\n/**\n * Module exports.\n * @public\n */\n\nmodule.exports = escapeHtml;\n\n/**\n * Escape special characters in the given string of html.\n *\n * @param {string} string The string to escape for inserting into HTML\n * @return {string}\n * @public\n */\n\nfunction escapeHtml(string) {\n var str = '' + string;\n var match = matchHtmlRegExp.exec(str);\n\n if (!match) {\n return str;\n }\n\n var escape;\n var html = '';\n var index = 0;\n var lastIndex = 0;\n\n for (index = match.index; index < str.length; index++) {\n switch (str.charCodeAt(index)) {\n case 34: // \"\n escape = '"';\n break;\n case 38: // &\n escape = '&';\n break;\n case 39: // '\n escape = ''';\n break;\n case 60: // <\n escape = '<';\n break;\n case 62: // >\n escape = '>';\n break;\n default:\n continue;\n }\n\n if (lastIndex !== index) {\n html += str.substring(lastIndex, index);\n }\n\n lastIndex = index + 1;\n html += escape;\n }\n\n return lastIndex !== index\n ? html + str.substring(lastIndex, index)\n : html;\n}\n", "/*!\n * clipboard.js v2.0.11\n * https://clipboardjs.com/\n *\n * Licensed MIT \u00A9 Zeno Rocha\n */\n(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"ClipboardJS\"] = factory();\n\telse\n\t\troot[\"ClipboardJS\"] = factory();\n})(this, function() {\nreturn /******/ (function() { // webpackBootstrap\n/******/ \tvar __webpack_modules__ = ({\n\n/***/ 686:\n/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n\n// EXPORTS\n__webpack_require__.d(__webpack_exports__, {\n \"default\": function() { return /* binding */ clipboard; }\n});\n\n// EXTERNAL MODULE: ./node_modules/tiny-emitter/index.js\nvar tiny_emitter = __webpack_require__(279);\nvar tiny_emitter_default = /*#__PURE__*/__webpack_require__.n(tiny_emitter);\n// EXTERNAL MODULE: ./node_modules/good-listener/src/listen.js\nvar listen = __webpack_require__(370);\nvar listen_default = /*#__PURE__*/__webpack_require__.n(listen);\n// EXTERNAL MODULE: ./node_modules/select/src/select.js\nvar src_select = __webpack_require__(817);\nvar select_default = /*#__PURE__*/__webpack_require__.n(src_select);\n;// CONCATENATED MODULE: ./src/common/command.js\n/**\n * Executes a given operation type.\n * @param {String} type\n * @return {Boolean}\n */\nfunction command(type) {\n try {\n return document.execCommand(type);\n } catch (err) {\n return false;\n }\n}\n;// CONCATENATED MODULE: ./src/actions/cut.js\n\n\n/**\n * Cut action wrapper.\n * @param {String|HTMLElement} target\n * @return {String}\n */\n\nvar ClipboardActionCut = function ClipboardActionCut(target) {\n var selectedText = select_default()(target);\n command('cut');\n return selectedText;\n};\n\n/* harmony default export */ var actions_cut = (ClipboardActionCut);\n;// CONCATENATED MODULE: ./src/common/create-fake-element.js\n/**\n * Creates a fake textarea element with a value.\n * @param {String} value\n * @return {HTMLElement}\n */\nfunction createFakeElement(value) {\n var isRTL = document.documentElement.getAttribute('dir') === 'rtl';\n var fakeElement = document.createElement('textarea'); // Prevent zooming on iOS\n\n fakeElement.style.fontSize = '12pt'; // Reset box model\n\n fakeElement.style.border = '0';\n fakeElement.style.padding = '0';\n fakeElement.style.margin = '0'; // Move element out of screen horizontally\n\n fakeElement.style.position = 'absolute';\n fakeElement.style[isRTL ? 'right' : 'left'] = '-9999px'; // Move element to the same position vertically\n\n var yPosition = window.pageYOffset || document.documentElement.scrollTop;\n fakeElement.style.top = \"\".concat(yPosition, \"px\");\n fakeElement.setAttribute('readonly', '');\n fakeElement.value = value;\n return fakeElement;\n}\n;// CONCATENATED MODULE: ./src/actions/copy.js\n\n\n\n/**\n * Create fake copy action wrapper using a fake element.\n * @param {String} target\n * @param {Object} options\n * @return {String}\n */\n\nvar fakeCopyAction = function fakeCopyAction(value, options) {\n var fakeElement = createFakeElement(value);\n options.container.appendChild(fakeElement);\n var selectedText = select_default()(fakeElement);\n command('copy');\n fakeElement.remove();\n return selectedText;\n};\n/**\n * Copy action wrapper.\n * @param {String|HTMLElement} target\n * @param {Object} options\n * @return {String}\n */\n\n\nvar ClipboardActionCopy = function ClipboardActionCopy(target) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {\n container: document.body\n };\n var selectedText = '';\n\n if (typeof target === 'string') {\n selectedText = fakeCopyAction(target, options);\n } else if (target instanceof HTMLInputElement && !['text', 'search', 'url', 'tel', 'password'].includes(target === null || target === void 0 ? void 0 : target.type)) {\n // If input type doesn't support `setSelectionRange`. Simulate it. https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/setSelectionRange\n selectedText = fakeCopyAction(target.value, options);\n } else {\n selectedText = select_default()(target);\n command('copy');\n }\n\n return selectedText;\n};\n\n/* harmony default export */ var actions_copy = (ClipboardActionCopy);\n;// CONCATENATED MODULE: ./src/actions/default.js\nfunction _typeof(obj) { \"@babel/helpers - typeof\"; if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\n\n\n/**\n * Inner function which performs selection from either `text` or `target`\n * properties and then executes copy or cut operations.\n * @param {Object} options\n */\n\nvar ClipboardActionDefault = function ClipboardActionDefault() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n // Defines base properties passed from constructor.\n var _options$action = options.action,\n action = _options$action === void 0 ? 'copy' : _options$action,\n container = options.container,\n target = options.target,\n text = options.text; // Sets the `action` to be performed which can be either 'copy' or 'cut'.\n\n if (action !== 'copy' && action !== 'cut') {\n throw new Error('Invalid \"action\" value, use either \"copy\" or \"cut\"');\n } // Sets the `target` property using an element that will be have its content copied.\n\n\n if (target !== undefined) {\n if (target && _typeof(target) === 'object' && target.nodeType === 1) {\n if (action === 'copy' && target.hasAttribute('disabled')) {\n throw new Error('Invalid \"target\" attribute. Please use \"readonly\" instead of \"disabled\" attribute');\n }\n\n if (action === 'cut' && (target.hasAttribute('readonly') || target.hasAttribute('disabled'))) {\n throw new Error('Invalid \"target\" attribute. You can\\'t cut text from elements with \"readonly\" or \"disabled\" attributes');\n }\n } else {\n throw new Error('Invalid \"target\" value, use a valid Element');\n }\n } // Define selection strategy based on `text` property.\n\n\n if (text) {\n return actions_copy(text, {\n container: container\n });\n } // Defines which selection strategy based on `target` property.\n\n\n if (target) {\n return action === 'cut' ? actions_cut(target) : actions_copy(target, {\n container: container\n });\n }\n};\n\n/* harmony default export */ var actions_default = (ClipboardActionDefault);\n;// CONCATENATED MODULE: ./src/clipboard.js\nfunction clipboard_typeof(obj) { \"@babel/helpers - typeof\"; if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { clipboard_typeof = function _typeof(obj) { return typeof obj; }; } else { clipboard_typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return clipboard_typeof(obj); }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nfunction _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (clipboard_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _isNativeReflectConstruct() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\n\n\n\n\n\n/**\n * Helper function to retrieve attribute value.\n * @param {String} suffix\n * @param {Element} element\n */\n\nfunction getAttributeValue(suffix, element) {\n var attribute = \"data-clipboard-\".concat(suffix);\n\n if (!element.hasAttribute(attribute)) {\n return;\n }\n\n return element.getAttribute(attribute);\n}\n/**\n * Base class which takes one or more elements, adds event listeners to them,\n * and instantiates a new `ClipboardAction` on each click.\n */\n\n\nvar Clipboard = /*#__PURE__*/function (_Emitter) {\n _inherits(Clipboard, _Emitter);\n\n var _super = _createSuper(Clipboard);\n\n /**\n * @param {String|HTMLElement|HTMLCollection|NodeList} trigger\n * @param {Object} options\n */\n function Clipboard(trigger, options) {\n var _this;\n\n _classCallCheck(this, Clipboard);\n\n _this = _super.call(this);\n\n _this.resolveOptions(options);\n\n _this.listenClick(trigger);\n\n return _this;\n }\n /**\n * Defines if attributes would be resolved using internal setter functions\n * or custom functions that were passed in the constructor.\n * @param {Object} options\n */\n\n\n _createClass(Clipboard, [{\n key: \"resolveOptions\",\n value: function resolveOptions() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n this.action = typeof options.action === 'function' ? options.action : this.defaultAction;\n this.target = typeof options.target === 'function' ? options.target : this.defaultTarget;\n this.text = typeof options.text === 'function' ? options.text : this.defaultText;\n this.container = clipboard_typeof(options.container) === 'object' ? options.container : document.body;\n }\n /**\n * Adds a click event listener to the passed trigger.\n * @param {String|HTMLElement|HTMLCollection|NodeList} trigger\n */\n\n }, {\n key: \"listenClick\",\n value: function listenClick(trigger) {\n var _this2 = this;\n\n this.listener = listen_default()(trigger, 'click', function (e) {\n return _this2.onClick(e);\n });\n }\n /**\n * Defines a new `ClipboardAction` on each click event.\n * @param {Event} e\n */\n\n }, {\n key: \"onClick\",\n value: function onClick(e) {\n var trigger = e.delegateTarget || e.currentTarget;\n var action = this.action(trigger) || 'copy';\n var text = actions_default({\n action: action,\n container: this.container,\n target: this.target(trigger),\n text: this.text(trigger)\n }); // Fires an event based on the copy operation result.\n\n this.emit(text ? 'success' : 'error', {\n action: action,\n text: text,\n trigger: trigger,\n clearSelection: function clearSelection() {\n if (trigger) {\n trigger.focus();\n }\n\n window.getSelection().removeAllRanges();\n }\n });\n }\n /**\n * Default `action` lookup function.\n * @param {Element} trigger\n */\n\n }, {\n key: \"defaultAction\",\n value: function defaultAction(trigger) {\n return getAttributeValue('action', trigger);\n }\n /**\n * Default `target` lookup function.\n * @param {Element} trigger\n */\n\n }, {\n key: \"defaultTarget\",\n value: function defaultTarget(trigger) {\n var selector = getAttributeValue('target', trigger);\n\n if (selector) {\n return document.querySelector(selector);\n }\n }\n /**\n * Allow fire programmatically a copy action\n * @param {String|HTMLElement} target\n * @param {Object} options\n * @returns Text copied.\n */\n\n }, {\n key: \"defaultText\",\n\n /**\n * Default `text` lookup function.\n * @param {Element} trigger\n */\n value: function defaultText(trigger) {\n return getAttributeValue('text', trigger);\n }\n /**\n * Destroy lifecycle.\n */\n\n }, {\n key: \"destroy\",\n value: function destroy() {\n this.listener.destroy();\n }\n }], [{\n key: \"copy\",\n value: function copy(target) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {\n container: document.body\n };\n return actions_copy(target, options);\n }\n /**\n * Allow fire programmatically a cut action\n * @param {String|HTMLElement} target\n * @returns Text cutted.\n */\n\n }, {\n key: \"cut\",\n value: function cut(target) {\n return actions_cut(target);\n }\n /**\n * Returns the support of the given action, or all actions if no action is\n * given.\n * @param {String} [action]\n */\n\n }, {\n key: \"isSupported\",\n value: function isSupported() {\n var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ['copy', 'cut'];\n var actions = typeof action === 'string' ? [action] : action;\n var support = !!document.queryCommandSupported;\n actions.forEach(function (action) {\n support = support && !!document.queryCommandSupported(action);\n });\n return support;\n }\n }]);\n\n return Clipboard;\n}((tiny_emitter_default()));\n\n/* harmony default export */ var clipboard = (Clipboard);\n\n/***/ }),\n\n/***/ 828:\n/***/ (function(module) {\n\nvar DOCUMENT_NODE_TYPE = 9;\n\n/**\n * A polyfill for Element.matches()\n */\nif (typeof Element !== 'undefined' && !Element.prototype.matches) {\n var proto = Element.prototype;\n\n proto.matches = proto.matchesSelector ||\n proto.mozMatchesSelector ||\n proto.msMatchesSelector ||\n proto.oMatchesSelector ||\n proto.webkitMatchesSelector;\n}\n\n/**\n * Finds the closest parent that matches a selector.\n *\n * @param {Element} element\n * @param {String} selector\n * @return {Function}\n */\nfunction closest (element, selector) {\n while (element && element.nodeType !== DOCUMENT_NODE_TYPE) {\n if (typeof element.matches === 'function' &&\n element.matches(selector)) {\n return element;\n }\n element = element.parentNode;\n }\n}\n\nmodule.exports = closest;\n\n\n/***/ }),\n\n/***/ 438:\n/***/ (function(module, __unused_webpack_exports, __webpack_require__) {\n\nvar closest = __webpack_require__(828);\n\n/**\n * Delegates event to a selector.\n *\n * @param {Element} element\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @param {Boolean} useCapture\n * @return {Object}\n */\nfunction _delegate(element, selector, type, callback, useCapture) {\n var listenerFn = listener.apply(this, arguments);\n\n element.addEventListener(type, listenerFn, useCapture);\n\n return {\n destroy: function() {\n element.removeEventListener(type, listenerFn, useCapture);\n }\n }\n}\n\n/**\n * Delegates event to a selector.\n *\n * @param {Element|String|Array} [elements]\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @param {Boolean} useCapture\n * @return {Object}\n */\nfunction delegate(elements, selector, type, callback, useCapture) {\n // Handle the regular Element usage\n if (typeof elements.addEventListener === 'function') {\n return _delegate.apply(null, arguments);\n }\n\n // Handle Element-less usage, it defaults to global delegation\n if (typeof type === 'function') {\n // Use `document` as the first parameter, then apply arguments\n // This is a short way to .unshift `arguments` without running into deoptimizations\n return _delegate.bind(null, document).apply(null, arguments);\n }\n\n // Handle Selector-based usage\n if (typeof elements === 'string') {\n elements = document.querySelectorAll(elements);\n }\n\n // Handle Array-like based usage\n return Array.prototype.map.call(elements, function (element) {\n return _delegate(element, selector, type, callback, useCapture);\n });\n}\n\n/**\n * Finds closest match and invokes callback.\n *\n * @param {Element} element\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @return {Function}\n */\nfunction listener(element, selector, type, callback) {\n return function(e) {\n e.delegateTarget = closest(e.target, selector);\n\n if (e.delegateTarget) {\n callback.call(element, e);\n }\n }\n}\n\nmodule.exports = delegate;\n\n\n/***/ }),\n\n/***/ 879:\n/***/ (function(__unused_webpack_module, exports) {\n\n/**\n * Check if argument is a HTML element.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.node = function(value) {\n return value !== undefined\n && value instanceof HTMLElement\n && value.nodeType === 1;\n};\n\n/**\n * Check if argument is a list of HTML elements.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.nodeList = function(value) {\n var type = Object.prototype.toString.call(value);\n\n return value !== undefined\n && (type === '[object NodeList]' || type === '[object HTMLCollection]')\n && ('length' in value)\n && (value.length === 0 || exports.node(value[0]));\n};\n\n/**\n * Check if argument is a string.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.string = function(value) {\n return typeof value === 'string'\n || value instanceof String;\n};\n\n/**\n * Check if argument is a function.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.fn = function(value) {\n var type = Object.prototype.toString.call(value);\n\n return type === '[object Function]';\n};\n\n\n/***/ }),\n\n/***/ 370:\n/***/ (function(module, __unused_webpack_exports, __webpack_require__) {\n\nvar is = __webpack_require__(879);\nvar delegate = __webpack_require__(438);\n\n/**\n * Validates all params and calls the right\n * listener function based on its target type.\n *\n * @param {String|HTMLElement|HTMLCollection|NodeList} target\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listen(target, type, callback) {\n if (!target && !type && !callback) {\n throw new Error('Missing required arguments');\n }\n\n if (!is.string(type)) {\n throw new TypeError('Second argument must be a String');\n }\n\n if (!is.fn(callback)) {\n throw new TypeError('Third argument must be a Function');\n }\n\n if (is.node(target)) {\n return listenNode(target, type, callback);\n }\n else if (is.nodeList(target)) {\n return listenNodeList(target, type, callback);\n }\n else if (is.string(target)) {\n return listenSelector(target, type, callback);\n }\n else {\n throw new TypeError('First argument must be a String, HTMLElement, HTMLCollection, or NodeList');\n }\n}\n\n/**\n * Adds an event listener to a HTML element\n * and returns a remove listener function.\n *\n * @param {HTMLElement} node\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listenNode(node, type, callback) {\n node.addEventListener(type, callback);\n\n return {\n destroy: function() {\n node.removeEventListener(type, callback);\n }\n }\n}\n\n/**\n * Add an event listener to a list of HTML elements\n * and returns a remove listener function.\n *\n * @param {NodeList|HTMLCollection} nodeList\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listenNodeList(nodeList, type, callback) {\n Array.prototype.forEach.call(nodeList, function(node) {\n node.addEventListener(type, callback);\n });\n\n return {\n destroy: function() {\n Array.prototype.forEach.call(nodeList, function(node) {\n node.removeEventListener(type, callback);\n });\n }\n }\n}\n\n/**\n * Add an event listener to a selector\n * and returns a remove listener function.\n *\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listenSelector(selector, type, callback) {\n return delegate(document.body, selector, type, callback);\n}\n\nmodule.exports = listen;\n\n\n/***/ }),\n\n/***/ 817:\n/***/ (function(module) {\n\nfunction select(element) {\n var selectedText;\n\n if (element.nodeName === 'SELECT') {\n element.focus();\n\n selectedText = element.value;\n }\n else if (element.nodeName === 'INPUT' || element.nodeName === 'TEXTAREA') {\n var isReadOnly = element.hasAttribute('readonly');\n\n if (!isReadOnly) {\n element.setAttribute('readonly', '');\n }\n\n element.select();\n element.setSelectionRange(0, element.value.length);\n\n if (!isReadOnly) {\n element.removeAttribute('readonly');\n }\n\n selectedText = element.value;\n }\n else {\n if (element.hasAttribute('contenteditable')) {\n element.focus();\n }\n\n var selection = window.getSelection();\n var range = document.createRange();\n\n range.selectNodeContents(element);\n selection.removeAllRanges();\n selection.addRange(range);\n\n selectedText = selection.toString();\n }\n\n return selectedText;\n}\n\nmodule.exports = select;\n\n\n/***/ }),\n\n/***/ 279:\n/***/ (function(module) {\n\nfunction E () {\n // Keep this empty so it's easier to inherit from\n // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3)\n}\n\nE.prototype = {\n on: function (name, callback, ctx) {\n var e = this.e || (this.e = {});\n\n (e[name] || (e[name] = [])).push({\n fn: callback,\n ctx: ctx\n });\n\n return this;\n },\n\n once: function (name, callback, ctx) {\n var self = this;\n function listener () {\n self.off(name, listener);\n callback.apply(ctx, arguments);\n };\n\n listener._ = callback\n return this.on(name, listener, ctx);\n },\n\n emit: function (name) {\n var data = [].slice.call(arguments, 1);\n var evtArr = ((this.e || (this.e = {}))[name] || []).slice();\n var i = 0;\n var len = evtArr.length;\n\n for (i; i < len; i++) {\n evtArr[i].fn.apply(evtArr[i].ctx, data);\n }\n\n return this;\n },\n\n off: function (name, callback) {\n var e = this.e || (this.e = {});\n var evts = e[name];\n var liveEvents = [];\n\n if (evts && callback) {\n for (var i = 0, len = evts.length; i < len; i++) {\n if (evts[i].fn !== callback && evts[i].fn._ !== callback)\n liveEvents.push(evts[i]);\n }\n }\n\n // Remove event from queue to prevent memory leak\n // Suggested by https://github.com/lazd\n // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910\n\n (liveEvents.length)\n ? e[name] = liveEvents\n : delete e[name];\n\n return this;\n }\n};\n\nmodule.exports = E;\nmodule.exports.TinyEmitter = E;\n\n\n/***/ })\n\n/******/ \t});\n/************************************************************************/\n/******/ \t// The module cache\n/******/ \tvar __webpack_module_cache__ = {};\n/******/ \t\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(__webpack_module_cache__[moduleId]) {\n/******/ \t\t\treturn __webpack_module_cache__[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = __webpack_module_cache__[moduleId] = {\n/******/ \t\t\t// no module.id needed\n/******/ \t\t\t// no module.loaded needed\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/ \t\n/******/ \t\t// Execute the module function\n/******/ \t\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n/******/ \t\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/ \t\n/************************************************************************/\n/******/ \t/* webpack/runtime/compat get default export */\n/******/ \t!function() {\n/******/ \t\t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t\t__webpack_require__.n = function(module) {\n/******/ \t\t\tvar getter = module && module.__esModule ?\n/******/ \t\t\t\tfunction() { return module['default']; } :\n/******/ \t\t\t\tfunction() { return module; };\n/******/ \t\t\t__webpack_require__.d(getter, { a: getter });\n/******/ \t\t\treturn getter;\n/******/ \t\t};\n/******/ \t}();\n/******/ \t\n/******/ \t/* webpack/runtime/define property getters */\n/******/ \t!function() {\n/******/ \t\t// define getter functions for harmony exports\n/******/ \t\t__webpack_require__.d = function(exports, definition) {\n/******/ \t\t\tfor(var key in definition) {\n/******/ \t\t\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n/******/ \t\t\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n/******/ \t\t\t\t}\n/******/ \t\t\t}\n/******/ \t\t};\n/******/ \t}();\n/******/ \t\n/******/ \t/* webpack/runtime/hasOwnProperty shorthand */\n/******/ \t!function() {\n/******/ \t\t__webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }\n/******/ \t}();\n/******/ \t\n/************************************************************************/\n/******/ \t// module exports must be returned from runtime so entry inlining is disabled\n/******/ \t// startup\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(686);\n/******/ })()\n.default;\n});", "/*\n * Copyright (c) 2016-2024 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport \"focus-visible\"\n\nimport {\n EMPTY,\n NEVER,\n Observable,\n Subject,\n defer,\n delay,\n filter,\n map,\n merge,\n mergeWith,\n shareReplay,\n switchMap\n} from \"rxjs\"\n\nimport { configuration, feature } from \"./_\"\nimport {\n at,\n getActiveElement,\n getOptionalElement,\n requestJSON,\n setLocation,\n setToggle,\n watchDocument,\n watchKeyboard,\n watchLocation,\n watchLocationTarget,\n watchMedia,\n watchPrint,\n watchScript,\n watchViewport\n} from \"./browser\"\nimport {\n getComponentElement,\n getComponentElements,\n mountAnnounce,\n mountBackToTop,\n mountConsent,\n mountContent,\n mountDialog,\n mountHeader,\n mountHeaderTitle,\n mountPalette,\n mountProgress,\n mountSearch,\n mountSearchHiglight,\n mountSidebar,\n mountSource,\n mountTableOfContents,\n mountTabs,\n watchHeader,\n watchMain\n} from \"./components\"\nimport {\n SearchIndex,\n setupClipboardJS,\n setupInstantNavigation,\n setupVersionSelector\n} from \"./integrations\"\nimport {\n patchEllipsis,\n patchIndeterminate,\n patchScrollfix,\n patchScrolllock\n} from \"./patches\"\nimport \"./polyfills\"\n\n/* ----------------------------------------------------------------------------\n * Functions - @todo refactor\n * ------------------------------------------------------------------------- */\n\n/**\n * Fetch search index\n *\n * @returns Search index observable\n */\nfunction fetchSearchIndex(): Observable {\n if (location.protocol === \"file:\") {\n return watchScript(\n `${new URL(\"search/search_index.js\", config.base)}`\n )\n .pipe(\n // @ts-ignore - @todo fix typings\n map(() => __index),\n shareReplay(1)\n )\n } else {\n return requestJSON(\n new URL(\"search/search_index.json\", config.base)\n )\n }\n}\n\n/* ----------------------------------------------------------------------------\n * Application\n * ------------------------------------------------------------------------- */\n\n/* Yay, JavaScript is available */\ndocument.documentElement.classList.remove(\"no-js\")\ndocument.documentElement.classList.add(\"js\")\n\n/* Set up navigation observables and subjects */\nconst document$ = watchDocument()\nconst location$ = watchLocation()\nconst target$ = watchLocationTarget(location$)\nconst keyboard$ = watchKeyboard()\n\n/* Set up media observables */\nconst viewport$ = watchViewport()\nconst tablet$ = watchMedia(\"(min-width: 960px)\")\nconst screen$ = watchMedia(\"(min-width: 1220px)\")\nconst print$ = watchPrint()\n\n/* Retrieve search index, if search is enabled */\nconst config = configuration()\nconst index$ = document.forms.namedItem(\"search\")\n ? fetchSearchIndex()\n : NEVER\n\n/* Set up Clipboard.js integration */\nconst alert$ = new Subject()\nsetupClipboardJS({ alert$ })\n\n/* Set up progress indicator */\nconst progress$ = new Subject()\n\n/* Set up instant navigation, if enabled */\nif (feature(\"navigation.instant\"))\n setupInstantNavigation({ location$, viewport$, progress$ })\n .subscribe(document$)\n\n/* Set up version selector */\nif (config.version?.provider === \"mike\")\n setupVersionSelector({ document$ })\n\n/* Always close drawer and search on navigation */\nmerge(location$, target$)\n .pipe(\n delay(125)\n )\n .subscribe(() => {\n setToggle(\"drawer\", false)\n setToggle(\"search\", false)\n })\n\n/* Set up global keyboard handlers */\nkeyboard$\n .pipe(\n filter(({ mode }) => mode === \"global\")\n )\n .subscribe(key => {\n switch (key.type) {\n\n /* Go to previous page */\n case \"p\":\n case \",\":\n const prev = getOptionalElement(\"link[rel=prev]\")\n if (typeof prev !== \"undefined\")\n setLocation(prev)\n break\n\n /* Go to next page */\n case \"n\":\n case \".\":\n const next = getOptionalElement(\"link[rel=next]\")\n if (typeof next !== \"undefined\")\n setLocation(next)\n break\n\n /* Expand navigation, see https://bit.ly/3ZjG5io */\n case \"Enter\":\n const active = getActiveElement()\n if (active instanceof HTMLLabelElement)\n active.click()\n }\n })\n\n/* Set up patches */\npatchEllipsis({ viewport$, document$ })\npatchIndeterminate({ document$, tablet$ })\npatchScrollfix({ document$ })\npatchScrolllock({ viewport$, tablet$ })\n\n/* Set up header and main area observable */\nconst header$ = watchHeader(getComponentElement(\"header\"), { viewport$ })\nconst main$ = document$\n .pipe(\n map(() => getComponentElement(\"main\")),\n switchMap(el => watchMain(el, { viewport$, header$ })),\n shareReplay(1)\n )\n\n/* Set up control component observables */\nconst control$ = merge(\n\n /* Consent */\n ...getComponentElements(\"consent\")\n .map(el => mountConsent(el, { target$ })),\n\n /* Dialog */\n ...getComponentElements(\"dialog\")\n .map(el => mountDialog(el, { alert$ })),\n\n /* Header */\n ...getComponentElements(\"header\")\n .map(el => mountHeader(el, { viewport$, header$, main$ })),\n\n /* Color palette */\n ...getComponentElements(\"palette\")\n .map(el => mountPalette(el)),\n\n /* Progress bar */\n ...getComponentElements(\"progress\")\n .map(el => mountProgress(el, { progress$ })),\n\n /* Search */\n ...getComponentElements(\"search\")\n .map(el => mountSearch(el, { index$, keyboard$ })),\n\n /* Repository information */\n ...getComponentElements(\"source\")\n .map(el => mountSource(el))\n)\n\n/* Set up content component observables */\nconst content$ = defer(() => merge(\n\n /* Announcement bar */\n ...getComponentElements(\"announce\")\n .map(el => mountAnnounce(el)),\n\n /* Content */\n ...getComponentElements(\"content\")\n .map(el => mountContent(el, { viewport$, target$, print$ })),\n\n /* Search highlighting */\n ...getComponentElements(\"content\")\n .map(el => feature(\"search.highlight\")\n ? mountSearchHiglight(el, { index$, location$ })\n : EMPTY\n ),\n\n /* Header title */\n ...getComponentElements(\"header-title\")\n .map(el => mountHeaderTitle(el, { viewport$, header$ })),\n\n /* Sidebar */\n ...getComponentElements(\"sidebar\")\n .map(el => el.getAttribute(\"data-md-type\") === \"navigation\"\n ? at(screen$, () => mountSidebar(el, { viewport$, header$, main$ }))\n : at(tablet$, () => mountSidebar(el, { viewport$, header$, main$ }))\n ),\n\n /* Navigation tabs */\n ...getComponentElements(\"tabs\")\n .map(el => mountTabs(el, { viewport$, header$ })),\n\n /* Table of contents */\n ...getComponentElements(\"toc\")\n .map(el => mountTableOfContents(el, {\n viewport$, header$, main$, target$\n })),\n\n /* Back-to-top button */\n ...getComponentElements(\"top\")\n .map(el => mountBackToTop(el, { viewport$, header$, main$, target$ }))\n))\n\n/* Set up component observables */\nconst component$ = document$\n .pipe(\n switchMap(() => content$),\n mergeWith(control$),\n shareReplay(1)\n )\n\n/* Subscribe to all components */\ncomponent$.subscribe()\n\n/* ----------------------------------------------------------------------------\n * Exports\n * ------------------------------------------------------------------------- */\n\nwindow.document$ = document$ /* Document observable */\nwindow.location$ = location$ /* Location subject */\nwindow.target$ = target$ /* Location target observable */\nwindow.keyboard$ = keyboard$ /* Keyboard observable */\nwindow.viewport$ = viewport$ /* Viewport observable */\nwindow.tablet$ = tablet$ /* Media tablet observable */\nwindow.screen$ = screen$ /* Media screen observable */\nwindow.print$ = print$ /* Media print observable */\nwindow.alert$ = alert$ /* Alert subject */\nwindow.progress$ = progress$ /* Progress indicator subject */\nwindow.component$ = component$ /* Component observable */\n", "/******************************************************************************\nCopyright (c) Microsoft Corporation.\n\nPermission to use, copy, modify, and/or distribute this software for any\npurpose with or without fee is hereby granted.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\nPERFORMANCE OF THIS SOFTWARE.\n***************************************************************************** */\n/* global Reflect, Promise, SuppressedError, Symbol, Iterator */\n\nvar extendStatics = function(d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n};\n\nexport function __extends(d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n}\n\nexport var __assign = function() {\n __assign = Object.assign || function __assign(t) {\n for (var s, i = 1, n = arguments.length; i < n; i++) {\n s = arguments[i];\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\n }\n return t;\n }\n return __assign.apply(this, arguments);\n}\n\nexport function __rest(s, e) {\n var t = {};\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\n t[p] = s[p];\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\n t[p[i]] = s[p[i]];\n }\n return t;\n}\n\nexport function __decorate(decorators, target, key, desc) {\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\n return c > 3 && r && Object.defineProperty(target, key, r), r;\n}\n\nexport function __param(paramIndex, decorator) {\n return function (target, key) { decorator(target, key, paramIndex); }\n}\n\nexport function __esDecorate(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {\n function accept(f) { if (f !== void 0 && typeof f !== \"function\") throw new TypeError(\"Function expected\"); return f; }\n var kind = contextIn.kind, key = kind === \"getter\" ? \"get\" : kind === \"setter\" ? \"set\" : \"value\";\n var target = !descriptorIn && ctor ? contextIn[\"static\"] ? ctor : ctor.prototype : null;\n var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});\n var _, done = false;\n for (var i = decorators.length - 1; i >= 0; i--) {\n var context = {};\n for (var p in contextIn) context[p] = p === \"access\" ? {} : contextIn[p];\n for (var p in contextIn.access) context.access[p] = contextIn.access[p];\n context.addInitializer = function (f) { if (done) throw new TypeError(\"Cannot add initializers after decoration has completed\"); extraInitializers.push(accept(f || null)); };\n var result = (0, decorators[i])(kind === \"accessor\" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);\n if (kind === \"accessor\") {\n if (result === void 0) continue;\n if (result === null || typeof result !== \"object\") throw new TypeError(\"Object expected\");\n if (_ = accept(result.get)) descriptor.get = _;\n if (_ = accept(result.set)) descriptor.set = _;\n if (_ = accept(result.init)) initializers.unshift(_);\n }\n else if (_ = accept(result)) {\n if (kind === \"field\") initializers.unshift(_);\n else descriptor[key] = _;\n }\n }\n if (target) Object.defineProperty(target, contextIn.name, descriptor);\n done = true;\n};\n\nexport function __runInitializers(thisArg, initializers, value) {\n var useValue = arguments.length > 2;\n for (var i = 0; i < initializers.length; i++) {\n value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);\n }\n return useValue ? value : void 0;\n};\n\nexport function __propKey(x) {\n return typeof x === \"symbol\" ? x : \"\".concat(x);\n};\n\nexport function __setFunctionName(f, name, prefix) {\n if (typeof name === \"symbol\") name = name.description ? \"[\".concat(name.description, \"]\") : \"\";\n return Object.defineProperty(f, \"name\", { configurable: true, value: prefix ? \"\".concat(prefix, \" \", name) : name });\n};\n\nexport function __metadata(metadataKey, metadataValue) {\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\n}\n\nexport function __awaiter(thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n}\n\nexport function __generator(thisArg, body) {\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === \"function\" ? Iterator : Object).prototype);\n return g.next = verb(0), g[\"throw\"] = verb(1), g[\"return\"] = verb(2), typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\n function verb(n) { return function (v) { return step([n, v]); }; }\n function step(op) {\n if (f) throw new TypeError(\"Generator is already executing.\");\n while (g && (g = 0, op[0] && (_ = 0)), _) try {\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\n if (y = 0, t) op = [op[0] & 2, t.value];\n switch (op[0]) {\n case 0: case 1: t = op; break;\n case 4: _.label++; return { value: op[1], done: false };\n case 5: _.label++; y = op[1]; op = [0]; continue;\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\n default:\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\n if (t[2]) _.ops.pop();\n _.trys.pop(); continue;\n }\n op = body.call(thisArg, _);\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\n }\n}\n\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n});\n\nexport function __exportStar(m, o) {\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\n}\n\nexport function __values(o) {\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\n if (m) return m.call(o);\n if (o && typeof o.length === \"number\") return {\n next: function () {\n if (o && i >= o.length) o = void 0;\n return { value: o && o[i++], done: !o };\n }\n };\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\n}\n\nexport function __read(o, n) {\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\n if (!m) return o;\n var i = m.call(o), r, ar = [], e;\n try {\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\n }\n catch (error) { e = { error: error }; }\n finally {\n try {\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\n }\n finally { if (e) throw e.error; }\n }\n return ar;\n}\n\n/** @deprecated */\nexport function __spread() {\n for (var ar = [], i = 0; i < arguments.length; i++)\n ar = ar.concat(__read(arguments[i]));\n return ar;\n}\n\n/** @deprecated */\nexport function __spreadArrays() {\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\n r[k] = a[j];\n return r;\n}\n\nexport function __spreadArray(to, from, pack) {\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\n if (ar || !(i in from)) {\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\n ar[i] = from[i];\n }\n }\n return to.concat(ar || Array.prototype.slice.call(from));\n}\n\nexport function __await(v) {\n return this instanceof __await ? (this.v = v, this) : new __await(v);\n}\n\nexport function __asyncGenerator(thisArg, _arguments, generator) {\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\n return i = Object.create((typeof AsyncIterator === \"function\" ? AsyncIterator : Object).prototype), verb(\"next\"), verb(\"throw\"), verb(\"return\", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i;\n function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; }\n function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } }\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\n function fulfill(value) { resume(\"next\", value); }\n function reject(value) { resume(\"throw\", value); }\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\n}\n\nexport function __asyncDelegator(o) {\n var i, p;\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; } : f; }\n}\n\nexport function __asyncValues(o) {\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n var m = o[Symbol.asyncIterator], i;\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\n}\n\nexport function __makeTemplateObject(cooked, raw) {\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\n return cooked;\n};\n\nvar __setModuleDefault = Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n};\n\nexport function __importStar(mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n}\n\nexport function __importDefault(mod) {\n return (mod && mod.__esModule) ? mod : { default: mod };\n}\n\nexport function __classPrivateFieldGet(receiver, state, kind, f) {\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\n}\n\nexport function __classPrivateFieldSet(receiver, state, value, kind, f) {\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\n}\n\nexport function __classPrivateFieldIn(state, receiver) {\n if (receiver === null || (typeof receiver !== \"object\" && typeof receiver !== \"function\")) throw new TypeError(\"Cannot use 'in' operator on non-object\");\n return typeof state === \"function\" ? receiver === state : state.has(receiver);\n}\n\nexport function __addDisposableResource(env, value, async) {\n if (value !== null && value !== void 0) {\n if (typeof value !== \"object\" && typeof value !== \"function\") throw new TypeError(\"Object expected.\");\n var dispose, inner;\n if (async) {\n if (!Symbol.asyncDispose) throw new TypeError(\"Symbol.asyncDispose is not defined.\");\n dispose = value[Symbol.asyncDispose];\n }\n if (dispose === void 0) {\n if (!Symbol.dispose) throw new TypeError(\"Symbol.dispose is not defined.\");\n dispose = value[Symbol.dispose];\n if (async) inner = dispose;\n }\n if (typeof dispose !== \"function\") throw new TypeError(\"Object not disposable.\");\n if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };\n env.stack.push({ value: value, dispose: dispose, async: async });\n }\n else if (async) {\n env.stack.push({ async: true });\n }\n return value;\n}\n\nvar _SuppressedError = typeof SuppressedError === \"function\" ? SuppressedError : function (error, suppressed, message) {\n var e = new Error(message);\n return e.name = \"SuppressedError\", e.error = error, e.suppressed = suppressed, e;\n};\n\nexport function __disposeResources(env) {\n function fail(e) {\n env.error = env.hasError ? new _SuppressedError(e, env.error, \"An error was suppressed during disposal.\") : e;\n env.hasError = true;\n }\n var r, s = 0;\n function next() {\n while (r = env.stack.pop()) {\n try {\n if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);\n if (r.dispose) {\n var result = r.dispose.call(r.value);\n if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });\n }\n else s |= 1;\n }\n catch (e) {\n fail(e);\n }\n }\n if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();\n if (env.hasError) throw env.error;\n }\n return next();\n}\n\nexport default {\n __extends,\n __assign,\n __rest,\n __decorate,\n __param,\n __metadata,\n __awaiter,\n __generator,\n __createBinding,\n __exportStar,\n __values,\n __read,\n __spread,\n __spreadArrays,\n __spreadArray,\n __await,\n __asyncGenerator,\n __asyncDelegator,\n __asyncValues,\n __makeTemplateObject,\n __importStar,\n __importDefault,\n __classPrivateFieldGet,\n __classPrivateFieldSet,\n __classPrivateFieldIn,\n __addDisposableResource,\n __disposeResources,\n};\n", "/**\n * Returns true if the object is a function.\n * @param value The value to check\n */\nexport function isFunction(value: any): value is (...args: any[]) => any {\n return typeof value === 'function';\n}\n", "/**\n * Used to create Error subclasses until the community moves away from ES5.\n *\n * This is because compiling from TypeScript down to ES5 has issues with subclassing Errors\n * as well as other built-in types: https://github.com/Microsoft/TypeScript/issues/12123\n *\n * @param createImpl A factory function to create the actual constructor implementation. The returned\n * function should be a named function that calls `_super` internally.\n */\nexport function createErrorClass(createImpl: (_super: any) => any): T {\n const _super = (instance: any) => {\n Error.call(instance);\n instance.stack = new Error().stack;\n };\n\n const ctorFunc = createImpl(_super);\n ctorFunc.prototype = Object.create(Error.prototype);\n ctorFunc.prototype.constructor = ctorFunc;\n return ctorFunc;\n}\n", "import { createErrorClass } from './createErrorClass';\n\nexport interface UnsubscriptionError extends Error {\n readonly errors: any[];\n}\n\nexport interface UnsubscriptionErrorCtor {\n /**\n * @deprecated Internal implementation detail. Do not construct error instances.\n * Cannot be tagged as internal: https://github.com/ReactiveX/rxjs/issues/6269\n */\n new (errors: any[]): UnsubscriptionError;\n}\n\n/**\n * An error thrown when one or more errors have occurred during the\n * `unsubscribe` of a {@link Subscription}.\n */\nexport const UnsubscriptionError: UnsubscriptionErrorCtor = createErrorClass(\n (_super) =>\n function UnsubscriptionErrorImpl(this: any, errors: (Error | string)[]) {\n _super(this);\n this.message = errors\n ? `${errors.length} errors occurred during unsubscription:\n${errors.map((err, i) => `${i + 1}) ${err.toString()}`).join('\\n ')}`\n : '';\n this.name = 'UnsubscriptionError';\n this.errors = errors;\n }\n);\n", "/**\n * Removes an item from an array, mutating it.\n * @param arr The array to remove the item from\n * @param item The item to remove\n */\nexport function arrRemove(arr: T[] | undefined | null, item: T) {\n if (arr) {\n const index = arr.indexOf(item);\n 0 <= index && arr.splice(index, 1);\n }\n}\n", "import { isFunction } from './util/isFunction';\nimport { UnsubscriptionError } from './util/UnsubscriptionError';\nimport { SubscriptionLike, TeardownLogic, Unsubscribable } from './types';\nimport { arrRemove } from './util/arrRemove';\n\n/**\n * Represents a disposable resource, such as the execution of an Observable. A\n * Subscription has one important method, `unsubscribe`, that takes no argument\n * and just disposes the resource held by the subscription.\n *\n * Additionally, subscriptions may be grouped together through the `add()`\n * method, which will attach a child Subscription to the current Subscription.\n * When a Subscription is unsubscribed, all its children (and its grandchildren)\n * will be unsubscribed as well.\n *\n * @class Subscription\n */\nexport class Subscription implements SubscriptionLike {\n /** @nocollapse */\n public static EMPTY = (() => {\n const empty = new Subscription();\n empty.closed = true;\n return empty;\n })();\n\n /**\n * A flag to indicate whether this Subscription has already been unsubscribed.\n */\n public closed = false;\n\n private _parentage: Subscription[] | Subscription | null = null;\n\n /**\n * The list of registered finalizers to execute upon unsubscription. Adding and removing from this\n * list occurs in the {@link #add} and {@link #remove} methods.\n */\n private _finalizers: Exclude[] | null = null;\n\n /**\n * @param initialTeardown A function executed first as part of the finalization\n * process that is kicked off when {@link #unsubscribe} is called.\n */\n constructor(private initialTeardown?: () => void) {}\n\n /**\n * Disposes the resources held by the subscription. May, for instance, cancel\n * an ongoing Observable execution or cancel any other type of work that\n * started when the Subscription was created.\n * @return {void}\n */\n unsubscribe(): void {\n let errors: any[] | undefined;\n\n if (!this.closed) {\n this.closed = true;\n\n // Remove this from it's parents.\n const { _parentage } = this;\n if (_parentage) {\n this._parentage = null;\n if (Array.isArray(_parentage)) {\n for (const parent of _parentage) {\n parent.remove(this);\n }\n } else {\n _parentage.remove(this);\n }\n }\n\n const { initialTeardown: initialFinalizer } = this;\n if (isFunction(initialFinalizer)) {\n try {\n initialFinalizer();\n } catch (e) {\n errors = e instanceof UnsubscriptionError ? e.errors : [e];\n }\n }\n\n const { _finalizers } = this;\n if (_finalizers) {\n this._finalizers = null;\n for (const finalizer of _finalizers) {\n try {\n execFinalizer(finalizer);\n } catch (err) {\n errors = errors ?? [];\n if (err instanceof UnsubscriptionError) {\n errors = [...errors, ...err.errors];\n } else {\n errors.push(err);\n }\n }\n }\n }\n\n if (errors) {\n throw new UnsubscriptionError(errors);\n }\n }\n }\n\n /**\n * Adds a finalizer to this subscription, so that finalization will be unsubscribed/called\n * when this subscription is unsubscribed. If this subscription is already {@link #closed},\n * because it has already been unsubscribed, then whatever finalizer is passed to it\n * will automatically be executed (unless the finalizer itself is also a closed subscription).\n *\n * Closed Subscriptions cannot be added as finalizers to any subscription. Adding a closed\n * subscription to a any subscription will result in no operation. (A noop).\n *\n * Adding a subscription to itself, or adding `null` or `undefined` will not perform any\n * operation at all. (A noop).\n *\n * `Subscription` instances that are added to this instance will automatically remove themselves\n * if they are unsubscribed. Functions and {@link Unsubscribable} objects that you wish to remove\n * will need to be removed manually with {@link #remove}\n *\n * @param teardown The finalization logic to add to this subscription.\n */\n add(teardown: TeardownLogic): void {\n // Only add the finalizer if it's not undefined\n // and don't add a subscription to itself.\n if (teardown && teardown !== this) {\n if (this.closed) {\n // If this subscription is already closed,\n // execute whatever finalizer is handed to it automatically.\n execFinalizer(teardown);\n } else {\n if (teardown instanceof Subscription) {\n // We don't add closed subscriptions, and we don't add the same subscription\n // twice. Subscription unsubscribe is idempotent.\n if (teardown.closed || teardown._hasParent(this)) {\n return;\n }\n teardown._addParent(this);\n }\n (this._finalizers = this._finalizers ?? []).push(teardown);\n }\n }\n }\n\n /**\n * Checks to see if a this subscription already has a particular parent.\n * This will signal that this subscription has already been added to the parent in question.\n * @param parent the parent to check for\n */\n private _hasParent(parent: Subscription) {\n const { _parentage } = this;\n return _parentage === parent || (Array.isArray(_parentage) && _parentage.includes(parent));\n }\n\n /**\n * Adds a parent to this subscription so it can be removed from the parent if it\n * unsubscribes on it's own.\n *\n * NOTE: THIS ASSUMES THAT {@link _hasParent} HAS ALREADY BEEN CHECKED.\n * @param parent The parent subscription to add\n */\n private _addParent(parent: Subscription) {\n const { _parentage } = this;\n this._parentage = Array.isArray(_parentage) ? (_parentage.push(parent), _parentage) : _parentage ? [_parentage, parent] : parent;\n }\n\n /**\n * Called on a child when it is removed via {@link #remove}.\n * @param parent The parent to remove\n */\n private _removeParent(parent: Subscription) {\n const { _parentage } = this;\n if (_parentage === parent) {\n this._parentage = null;\n } else if (Array.isArray(_parentage)) {\n arrRemove(_parentage, parent);\n }\n }\n\n /**\n * Removes a finalizer from this subscription that was previously added with the {@link #add} method.\n *\n * Note that `Subscription` instances, when unsubscribed, will automatically remove themselves\n * from every other `Subscription` they have been added to. This means that using the `remove` method\n * is not a common thing and should be used thoughtfully.\n *\n * If you add the same finalizer instance of a function or an unsubscribable object to a `Subscription` instance\n * more than once, you will need to call `remove` the same number of times to remove all instances.\n *\n * All finalizer instances are removed to free up memory upon unsubscription.\n *\n * @param teardown The finalizer to remove from this subscription\n */\n remove(teardown: Exclude): void {\n const { _finalizers } = this;\n _finalizers && arrRemove(_finalizers, teardown);\n\n if (teardown instanceof Subscription) {\n teardown._removeParent(this);\n }\n }\n}\n\nexport const EMPTY_SUBSCRIPTION = Subscription.EMPTY;\n\nexport function isSubscription(value: any): value is Subscription {\n return (\n value instanceof Subscription ||\n (value && 'closed' in value && isFunction(value.remove) && isFunction(value.add) && isFunction(value.unsubscribe))\n );\n}\n\nfunction execFinalizer(finalizer: Unsubscribable | (() => void)) {\n if (isFunction(finalizer)) {\n finalizer();\n } else {\n finalizer.unsubscribe();\n }\n}\n", "import { Subscriber } from './Subscriber';\nimport { ObservableNotification } from './types';\n\n/**\n * The {@link GlobalConfig} object for RxJS. It is used to configure things\n * like how to react on unhandled errors.\n */\nexport const config: GlobalConfig = {\n onUnhandledError: null,\n onStoppedNotification: null,\n Promise: undefined,\n useDeprecatedSynchronousErrorHandling: false,\n useDeprecatedNextContext: false,\n};\n\n/**\n * The global configuration object for RxJS, used to configure things\n * like how to react on unhandled errors. Accessible via {@link config}\n * object.\n */\nexport interface GlobalConfig {\n /**\n * A registration point for unhandled errors from RxJS. These are errors that\n * cannot were not handled by consuming code in the usual subscription path. For\n * example, if you have this configured, and you subscribe to an observable without\n * providing an error handler, errors from that subscription will end up here. This\n * will _always_ be called asynchronously on another job in the runtime. This is because\n * we do not want errors thrown in this user-configured handler to interfere with the\n * behavior of the library.\n */\n onUnhandledError: ((err: any) => void) | null;\n\n /**\n * A registration point for notifications that cannot be sent to subscribers because they\n * have completed, errored or have been explicitly unsubscribed. By default, next, complete\n * and error notifications sent to stopped subscribers are noops. However, sometimes callers\n * might want a different behavior. For example, with sources that attempt to report errors\n * to stopped subscribers, a caller can configure RxJS to throw an unhandled error instead.\n * This will _always_ be called asynchronously on another job in the runtime. This is because\n * we do not want errors thrown in this user-configured handler to interfere with the\n * behavior of the library.\n */\n onStoppedNotification: ((notification: ObservableNotification, subscriber: Subscriber) => void) | null;\n\n /**\n * The promise constructor used by default for {@link Observable#toPromise toPromise} and {@link Observable#forEach forEach}\n * methods.\n *\n * @deprecated As of version 8, RxJS will no longer support this sort of injection of a\n * Promise constructor. If you need a Promise implementation other than native promises,\n * please polyfill/patch Promise as you see appropriate. Will be removed in v8.\n */\n Promise?: PromiseConstructorLike;\n\n /**\n * If true, turns on synchronous error rethrowing, which is a deprecated behavior\n * in v6 and higher. This behavior enables bad patterns like wrapping a subscribe\n * call in a try/catch block. It also enables producer interference, a nasty bug\n * where a multicast can be broken for all observers by a downstream consumer with\n * an unhandled error. DO NOT USE THIS FLAG UNLESS IT'S NEEDED TO BUY TIME\n * FOR MIGRATION REASONS.\n *\n * @deprecated As of version 8, RxJS will no longer support synchronous throwing\n * of unhandled errors. All errors will be thrown on a separate call stack to prevent bad\n * behaviors described above. Will be removed in v8.\n */\n useDeprecatedSynchronousErrorHandling: boolean;\n\n /**\n * If true, enables an as-of-yet undocumented feature from v5: The ability to access\n * `unsubscribe()` via `this` context in `next` functions created in observers passed\n * to `subscribe`.\n *\n * This is being removed because the performance was severely problematic, and it could also cause\n * issues when types other than POJOs are passed to subscribe as subscribers, as they will likely have\n * their `this` context overwritten.\n *\n * @deprecated As of version 8, RxJS will no longer support altering the\n * context of next functions provided as part of an observer to Subscribe. Instead,\n * you will have access to a subscription or a signal or token that will allow you to do things like\n * unsubscribe and test closed status. Will be removed in v8.\n */\n useDeprecatedNextContext: boolean;\n}\n", "import type { TimerHandle } from './timerHandle';\ntype SetTimeoutFunction = (handler: () => void, timeout?: number, ...args: any[]) => TimerHandle;\ntype ClearTimeoutFunction = (handle: TimerHandle) => void;\n\ninterface TimeoutProvider {\n setTimeout: SetTimeoutFunction;\n clearTimeout: ClearTimeoutFunction;\n delegate:\n | {\n setTimeout: SetTimeoutFunction;\n clearTimeout: ClearTimeoutFunction;\n }\n | undefined;\n}\n\nexport const timeoutProvider: TimeoutProvider = {\n // When accessing the delegate, use the variable rather than `this` so that\n // the functions can be called without being bound to the provider.\n setTimeout(handler: () => void, timeout?: number, ...args) {\n const { delegate } = timeoutProvider;\n if (delegate?.setTimeout) {\n return delegate.setTimeout(handler, timeout, ...args);\n }\n return setTimeout(handler, timeout, ...args);\n },\n clearTimeout(handle) {\n const { delegate } = timeoutProvider;\n return (delegate?.clearTimeout || clearTimeout)(handle as any);\n },\n delegate: undefined,\n};\n", "import { config } from '../config';\nimport { timeoutProvider } from '../scheduler/timeoutProvider';\n\n/**\n * Handles an error on another job either with the user-configured {@link onUnhandledError},\n * or by throwing it on that new job so it can be picked up by `window.onerror`, `process.on('error')`, etc.\n *\n * This should be called whenever there is an error that is out-of-band with the subscription\n * or when an error hits a terminal boundary of the subscription and no error handler was provided.\n *\n * @param err the error to report\n */\nexport function reportUnhandledError(err: any) {\n timeoutProvider.setTimeout(() => {\n const { onUnhandledError } = config;\n if (onUnhandledError) {\n // Execute the user-configured error handler.\n onUnhandledError(err);\n } else {\n // Throw so it is picked up by the runtime's uncaught error mechanism.\n throw err;\n }\n });\n}\n", "/* tslint:disable:no-empty */\nexport function noop() { }\n", "import { CompleteNotification, NextNotification, ErrorNotification } from './types';\n\n/**\n * A completion object optimized for memory use and created to be the\n * same \"shape\" as other notifications in v8.\n * @internal\n */\nexport const COMPLETE_NOTIFICATION = (() => createNotification('C', undefined, undefined) as CompleteNotification)();\n\n/**\n * Internal use only. Creates an optimized error notification that is the same \"shape\"\n * as other notifications.\n * @internal\n */\nexport function errorNotification(error: any): ErrorNotification {\n return createNotification('E', undefined, error) as any;\n}\n\n/**\n * Internal use only. Creates an optimized next notification that is the same \"shape\"\n * as other notifications.\n * @internal\n */\nexport function nextNotification(value: T) {\n return createNotification('N', value, undefined) as NextNotification;\n}\n\n/**\n * Ensures that all notifications created internally have the same \"shape\" in v8.\n *\n * TODO: This is only exported to support a crazy legacy test in `groupBy`.\n * @internal\n */\nexport function createNotification(kind: 'N' | 'E' | 'C', value: any, error: any) {\n return {\n kind,\n value,\n error,\n };\n}\n", "import { config } from '../config';\n\nlet context: { errorThrown: boolean; error: any } | null = null;\n\n/**\n * Handles dealing with errors for super-gross mode. Creates a context, in which\n * any synchronously thrown errors will be passed to {@link captureError}. Which\n * will record the error such that it will be rethrown after the call back is complete.\n * TODO: Remove in v8\n * @param cb An immediately executed function.\n */\nexport function errorContext(cb: () => void) {\n if (config.useDeprecatedSynchronousErrorHandling) {\n const isRoot = !context;\n if (isRoot) {\n context = { errorThrown: false, error: null };\n }\n cb();\n if (isRoot) {\n const { errorThrown, error } = context!;\n context = null;\n if (errorThrown) {\n throw error;\n }\n }\n } else {\n // This is the general non-deprecated path for everyone that\n // isn't crazy enough to use super-gross mode (useDeprecatedSynchronousErrorHandling)\n cb();\n }\n}\n\n/**\n * Captures errors only in super-gross mode.\n * @param err the error to capture\n */\nexport function captureError(err: any) {\n if (config.useDeprecatedSynchronousErrorHandling && context) {\n context.errorThrown = true;\n context.error = err;\n }\n}\n", "import { isFunction } from './util/isFunction';\nimport { Observer, ObservableNotification } from './types';\nimport { isSubscription, Subscription } from './Subscription';\nimport { config } from './config';\nimport { reportUnhandledError } from './util/reportUnhandledError';\nimport { noop } from './util/noop';\nimport { nextNotification, errorNotification, COMPLETE_NOTIFICATION } from './NotificationFactories';\nimport { timeoutProvider } from './scheduler/timeoutProvider';\nimport { captureError } from './util/errorContext';\n\n/**\n * Implements the {@link Observer} interface and extends the\n * {@link Subscription} class. While the {@link Observer} is the public API for\n * consuming the values of an {@link Observable}, all Observers get converted to\n * a Subscriber, in order to provide Subscription-like capabilities such as\n * `unsubscribe`. Subscriber is a common type in RxJS, and crucial for\n * implementing operators, but it is rarely used as a public API.\n *\n * @class Subscriber\n */\nexport class Subscriber extends Subscription implements Observer {\n /**\n * A static factory for a Subscriber, given a (potentially partial) definition\n * of an Observer.\n * @param next The `next` callback of an Observer.\n * @param error The `error` callback of an\n * Observer.\n * @param complete The `complete` callback of an\n * Observer.\n * @return A Subscriber wrapping the (partially defined)\n * Observer represented by the given arguments.\n * @nocollapse\n * @deprecated Do not use. Will be removed in v8. There is no replacement for this\n * method, and there is no reason to be creating instances of `Subscriber` directly.\n * If you have a specific use case, please file an issue.\n */\n static create(next?: (x?: T) => void, error?: (e?: any) => void, complete?: () => void): Subscriber {\n return new SafeSubscriber(next, error, complete);\n }\n\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n protected isStopped: boolean = false;\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n protected destination: Subscriber | Observer; // this `any` is the escape hatch to erase extra type param (e.g. R)\n\n /**\n * @deprecated Internal implementation detail, do not use directly. Will be made internal in v8.\n * There is no reason to directly create an instance of Subscriber. This type is exported for typings reasons.\n */\n constructor(destination?: Subscriber | Observer) {\n super();\n if (destination) {\n this.destination = destination;\n // Automatically chain subscriptions together here.\n // if destination is a Subscription, then it is a Subscriber.\n if (isSubscription(destination)) {\n destination.add(this);\n }\n } else {\n this.destination = EMPTY_OBSERVER;\n }\n }\n\n /**\n * The {@link Observer} callback to receive notifications of type `next` from\n * the Observable, with a value. The Observable may call this method 0 or more\n * times.\n * @param {T} [value] The `next` value.\n * @return {void}\n */\n next(value?: T): void {\n if (this.isStopped) {\n handleStoppedNotification(nextNotification(value), this);\n } else {\n this._next(value!);\n }\n }\n\n /**\n * The {@link Observer} callback to receive notifications of type `error` from\n * the Observable, with an attached `Error`. Notifies the Observer that\n * the Observable has experienced an error condition.\n * @param {any} [err] The `error` exception.\n * @return {void}\n */\n error(err?: any): void {\n if (this.isStopped) {\n handleStoppedNotification(errorNotification(err), this);\n } else {\n this.isStopped = true;\n this._error(err);\n }\n }\n\n /**\n * The {@link Observer} callback to receive a valueless notification of type\n * `complete` from the Observable. Notifies the Observer that the Observable\n * has finished sending push-based notifications.\n * @return {void}\n */\n complete(): void {\n if (this.isStopped) {\n handleStoppedNotification(COMPLETE_NOTIFICATION, this);\n } else {\n this.isStopped = true;\n this._complete();\n }\n }\n\n unsubscribe(): void {\n if (!this.closed) {\n this.isStopped = true;\n super.unsubscribe();\n this.destination = null!;\n }\n }\n\n protected _next(value: T): void {\n this.destination.next(value);\n }\n\n protected _error(err: any): void {\n try {\n this.destination.error(err);\n } finally {\n this.unsubscribe();\n }\n }\n\n protected _complete(): void {\n try {\n this.destination.complete();\n } finally {\n this.unsubscribe();\n }\n }\n}\n\n/**\n * This bind is captured here because we want to be able to have\n * compatibility with monoid libraries that tend to use a method named\n * `bind`. In particular, a library called Monio requires this.\n */\nconst _bind = Function.prototype.bind;\n\nfunction bind any>(fn: Fn, thisArg: any): Fn {\n return _bind.call(fn, thisArg);\n}\n\n/**\n * Internal optimization only, DO NOT EXPOSE.\n * @internal\n */\nclass ConsumerObserver implements Observer {\n constructor(private partialObserver: Partial>) {}\n\n next(value: T): void {\n const { partialObserver } = this;\n if (partialObserver.next) {\n try {\n partialObserver.next(value);\n } catch (error) {\n handleUnhandledError(error);\n }\n }\n }\n\n error(err: any): void {\n const { partialObserver } = this;\n if (partialObserver.error) {\n try {\n partialObserver.error(err);\n } catch (error) {\n handleUnhandledError(error);\n }\n } else {\n handleUnhandledError(err);\n }\n }\n\n complete(): void {\n const { partialObserver } = this;\n if (partialObserver.complete) {\n try {\n partialObserver.complete();\n } catch (error) {\n handleUnhandledError(error);\n }\n }\n }\n}\n\nexport class SafeSubscriber extends Subscriber {\n constructor(\n observerOrNext?: Partial> | ((value: T) => void) | null,\n error?: ((e?: any) => void) | null,\n complete?: (() => void) | null\n ) {\n super();\n\n let partialObserver: Partial>;\n if (isFunction(observerOrNext) || !observerOrNext) {\n // The first argument is a function, not an observer. The next\n // two arguments *could* be observers, or they could be empty.\n partialObserver = {\n next: (observerOrNext ?? undefined) as (((value: T) => void) | undefined),\n error: error ?? undefined,\n complete: complete ?? undefined,\n };\n } else {\n // The first argument is a partial observer.\n let context: any;\n if (this && config.useDeprecatedNextContext) {\n // This is a deprecated path that made `this.unsubscribe()` available in\n // next handler functions passed to subscribe. This only exists behind a flag\n // now, as it is *very* slow.\n context = Object.create(observerOrNext);\n context.unsubscribe = () => this.unsubscribe();\n partialObserver = {\n next: observerOrNext.next && bind(observerOrNext.next, context),\n error: observerOrNext.error && bind(observerOrNext.error, context),\n complete: observerOrNext.complete && bind(observerOrNext.complete, context),\n };\n } else {\n // The \"normal\" path. Just use the partial observer directly.\n partialObserver = observerOrNext;\n }\n }\n\n // Wrap the partial observer to ensure it's a full observer, and\n // make sure proper error handling is accounted for.\n this.destination = new ConsumerObserver(partialObserver);\n }\n}\n\nfunction handleUnhandledError(error: any) {\n if (config.useDeprecatedSynchronousErrorHandling) {\n captureError(error);\n } else {\n // Ideal path, we report this as an unhandled error,\n // which is thrown on a new call stack.\n reportUnhandledError(error);\n }\n}\n\n/**\n * An error handler used when no error handler was supplied\n * to the SafeSubscriber -- meaning no error handler was supplied\n * do the `subscribe` call on our observable.\n * @param err The error to handle\n */\nfunction defaultErrorHandler(err: any) {\n throw err;\n}\n\n/**\n * A handler for notifications that cannot be sent to a stopped subscriber.\n * @param notification The notification being sent\n * @param subscriber The stopped subscriber\n */\nfunction handleStoppedNotification(notification: ObservableNotification, subscriber: Subscriber) {\n const { onStoppedNotification } = config;\n onStoppedNotification && timeoutProvider.setTimeout(() => onStoppedNotification(notification, subscriber));\n}\n\n/**\n * The observer used as a stub for subscriptions where the user did not\n * pass any arguments to `subscribe`. Comes with the default error handling\n * behavior.\n */\nexport const EMPTY_OBSERVER: Readonly> & { closed: true } = {\n closed: true,\n next: noop,\n error: defaultErrorHandler,\n complete: noop,\n};\n", "/**\n * Symbol.observable or a string \"@@observable\". Used for interop\n *\n * @deprecated We will no longer be exporting this symbol in upcoming versions of RxJS.\n * Instead polyfill and use Symbol.observable directly *or* use https://www.npmjs.com/package/symbol-observable\n */\nexport const observable: string | symbol = (() => (typeof Symbol === 'function' && Symbol.observable) || '@@observable')();\n", "/**\n * This function takes one parameter and just returns it. Simply put,\n * this is like `(x: T): T => x`.\n *\n * ## Examples\n *\n * This is useful in some cases when using things like `mergeMap`\n *\n * ```ts\n * import { interval, take, map, range, mergeMap, identity } from 'rxjs';\n *\n * const source$ = interval(1000).pipe(take(5));\n *\n * const result$ = source$.pipe(\n * map(i => range(i)),\n * mergeMap(identity) // same as mergeMap(x => x)\n * );\n *\n * result$.subscribe({\n * next: console.log\n * });\n * ```\n *\n * Or when you want to selectively apply an operator\n *\n * ```ts\n * import { interval, take, identity } from 'rxjs';\n *\n * const shouldLimit = () => Math.random() < 0.5;\n *\n * const source$ = interval(1000);\n *\n * const result$ = source$.pipe(shouldLimit() ? take(5) : identity);\n *\n * result$.subscribe({\n * next: console.log\n * });\n * ```\n *\n * @param x Any value that is returned by this function\n * @returns The value passed as the first parameter to this function\n */\nexport function identity(x: T): T {\n return x;\n}\n", "import { identity } from './identity';\nimport { UnaryFunction } from '../types';\n\nexport function pipe(): typeof identity;\nexport function pipe(fn1: UnaryFunction): UnaryFunction;\nexport function pipe(fn1: UnaryFunction, fn2: UnaryFunction): UnaryFunction;\nexport function pipe(fn1: UnaryFunction, fn2: UnaryFunction, fn3: UnaryFunction): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction,\n fn6: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction,\n fn6: UnaryFunction,\n fn7: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction,\n fn6: UnaryFunction,\n fn7: UnaryFunction,\n fn8: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction,\n fn6: UnaryFunction,\n fn7: UnaryFunction,\n fn8: UnaryFunction,\n fn9: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction,\n fn6: UnaryFunction,\n fn7: UnaryFunction,\n fn8: UnaryFunction,\n fn9: UnaryFunction,\n ...fns: UnaryFunction[]\n): UnaryFunction;\n\n/**\n * pipe() can be called on one or more functions, each of which can take one argument (\"UnaryFunction\")\n * and uses it to return a value.\n * It returns a function that takes one argument, passes it to the first UnaryFunction, and then\n * passes the result to the next one, passes that result to the next one, and so on. \n */\nexport function pipe(...fns: Array>): UnaryFunction {\n return pipeFromArray(fns);\n}\n\n/** @internal */\nexport function pipeFromArray(fns: Array>): UnaryFunction {\n if (fns.length === 0) {\n return identity as UnaryFunction;\n }\n\n if (fns.length === 1) {\n return fns[0];\n }\n\n return function piped(input: T): R {\n return fns.reduce((prev: any, fn: UnaryFunction) => fn(prev), input as any);\n };\n}\n", "import { Operator } from './Operator';\nimport { SafeSubscriber, Subscriber } from './Subscriber';\nimport { isSubscription, Subscription } from './Subscription';\nimport { TeardownLogic, OperatorFunction, Subscribable, Observer } from './types';\nimport { observable as Symbol_observable } from './symbol/observable';\nimport { pipeFromArray } from './util/pipe';\nimport { config } from './config';\nimport { isFunction } from './util/isFunction';\nimport { errorContext } from './util/errorContext';\n\n/**\n * A representation of any set of values over any amount of time. This is the most basic building block\n * of RxJS.\n *\n * @class Observable\n */\nexport class Observable implements Subscribable {\n /**\n * @deprecated Internal implementation detail, do not use directly. Will be made internal in v8.\n */\n source: Observable | undefined;\n\n /**\n * @deprecated Internal implementation detail, do not use directly. Will be made internal in v8.\n */\n operator: Operator | undefined;\n\n /**\n * @constructor\n * @param {Function} subscribe the function that is called when the Observable is\n * initially subscribed to. This function is given a Subscriber, to which new values\n * can be `next`ed, or an `error` method can be called to raise an error, or\n * `complete` can be called to notify of a successful completion.\n */\n constructor(subscribe?: (this: Observable, subscriber: Subscriber) => TeardownLogic) {\n if (subscribe) {\n this._subscribe = subscribe;\n }\n }\n\n // HACK: Since TypeScript inherits static properties too, we have to\n // fight against TypeScript here so Subject can have a different static create signature\n /**\n * Creates a new Observable by calling the Observable constructor\n * @owner Observable\n * @method create\n * @param {Function} subscribe? the subscriber function to be passed to the Observable constructor\n * @return {Observable} a new observable\n * @nocollapse\n * @deprecated Use `new Observable()` instead. Will be removed in v8.\n */\n static create: (...args: any[]) => any = (subscribe?: (subscriber: Subscriber) => TeardownLogic) => {\n return new Observable(subscribe);\n };\n\n /**\n * Creates a new Observable, with this Observable instance as the source, and the passed\n * operator defined as the new observable's operator.\n * @method lift\n * @param operator the operator defining the operation to take on the observable\n * @return a new observable with the Operator applied\n * @deprecated Internal implementation detail, do not use directly. Will be made internal in v8.\n * If you have implemented an operator using `lift`, it is recommended that you create an\n * operator by simply returning `new Observable()` directly. See \"Creating new operators from\n * scratch\" section here: https://rxjs.dev/guide/operators\n */\n lift(operator?: Operator): Observable {\n const observable = new Observable();\n observable.source = this;\n observable.operator = operator;\n return observable;\n }\n\n subscribe(observerOrNext?: Partial> | ((value: T) => void)): Subscription;\n /** @deprecated Instead of passing separate callback arguments, use an observer argument. Signatures taking separate callback arguments will be removed in v8. Details: https://rxjs.dev/deprecations/subscribe-arguments */\n subscribe(next?: ((value: T) => void) | null, error?: ((error: any) => void) | null, complete?: (() => void) | null): Subscription;\n /**\n * Invokes an execution of an Observable and registers Observer handlers for notifications it will emit.\n *\n * Use it when you have all these Observables, but still nothing is happening.\n *\n * `subscribe` is not a regular operator, but a method that calls Observable's internal `subscribe` function. It\n * might be for example a function that you passed to Observable's constructor, but most of the time it is\n * a library implementation, which defines what will be emitted by an Observable, and when it be will emitted. This means\n * that calling `subscribe` is actually the moment when Observable starts its work, not when it is created, as it is often\n * the thought.\n *\n * Apart from starting the execution of an Observable, this method allows you to listen for values\n * that an Observable emits, as well as for when it completes or errors. You can achieve this in two\n * of the following ways.\n *\n * The first way is creating an object that implements {@link Observer} interface. It should have methods\n * defined by that interface, but note that it should be just a regular JavaScript object, which you can create\n * yourself in any way you want (ES6 class, classic function constructor, object literal etc.). In particular, do\n * not attempt to use any RxJS implementation details to create Observers - you don't need them. Remember also\n * that your object does not have to implement all methods. If you find yourself creating a method that doesn't\n * do anything, you can simply omit it. Note however, if the `error` method is not provided and an error happens,\n * it will be thrown asynchronously. Errors thrown asynchronously cannot be caught using `try`/`catch`. Instead,\n * use the {@link onUnhandledError} configuration option or use a runtime handler (like `window.onerror` or\n * `process.on('error)`) to be notified of unhandled errors. Because of this, it's recommended that you provide\n * an `error` method to avoid missing thrown errors.\n *\n * The second way is to give up on Observer object altogether and simply provide callback functions in place of its methods.\n * This means you can provide three functions as arguments to `subscribe`, where the first function is equivalent\n * of a `next` method, the second of an `error` method and the third of a `complete` method. Just as in case of an Observer,\n * if you do not need to listen for something, you can omit a function by passing `undefined` or `null`,\n * since `subscribe` recognizes these functions by where they were placed in function call. When it comes\n * to the `error` function, as with an Observer, if not provided, errors emitted by an Observable will be thrown asynchronously.\n *\n * You can, however, subscribe with no parameters at all. This may be the case where you're not interested in terminal events\n * and you also handled emissions internally by using operators (e.g. using `tap`).\n *\n * Whichever style of calling `subscribe` you use, in both cases it returns a Subscription object.\n * This object allows you to call `unsubscribe` on it, which in turn will stop the work that an Observable does and will clean\n * up all resources that an Observable used. Note that cancelling a subscription will not call `complete` callback\n * provided to `subscribe` function, which is reserved for a regular completion signal that comes from an Observable.\n *\n * Remember that callbacks provided to `subscribe` are not guaranteed to be called asynchronously.\n * It is an Observable itself that decides when these functions will be called. For example {@link of}\n * by default emits all its values synchronously. Always check documentation for how given Observable\n * will behave when subscribed and if its default behavior can be modified with a `scheduler`.\n *\n * #### Examples\n *\n * Subscribe with an {@link guide/observer Observer}\n *\n * ```ts\n * import { of } from 'rxjs';\n *\n * const sumObserver = {\n * sum: 0,\n * next(value) {\n * console.log('Adding: ' + value);\n * this.sum = this.sum + value;\n * },\n * error() {\n * // We actually could just remove this method,\n * // since we do not really care about errors right now.\n * },\n * complete() {\n * console.log('Sum equals: ' + this.sum);\n * }\n * };\n *\n * of(1, 2, 3) // Synchronously emits 1, 2, 3 and then completes.\n * .subscribe(sumObserver);\n *\n * // Logs:\n * // 'Adding: 1'\n * // 'Adding: 2'\n * // 'Adding: 3'\n * // 'Sum equals: 6'\n * ```\n *\n * Subscribe with functions ({@link deprecations/subscribe-arguments deprecated})\n *\n * ```ts\n * import { of } from 'rxjs'\n *\n * let sum = 0;\n *\n * of(1, 2, 3).subscribe(\n * value => {\n * console.log('Adding: ' + value);\n * sum = sum + value;\n * },\n * undefined,\n * () => console.log('Sum equals: ' + sum)\n * );\n *\n * // Logs:\n * // 'Adding: 1'\n * // 'Adding: 2'\n * // 'Adding: 3'\n * // 'Sum equals: 6'\n * ```\n *\n * Cancel a subscription\n *\n * ```ts\n * import { interval } from 'rxjs';\n *\n * const subscription = interval(1000).subscribe({\n * next(num) {\n * console.log(num)\n * },\n * complete() {\n * // Will not be called, even when cancelling subscription.\n * console.log('completed!');\n * }\n * });\n *\n * setTimeout(() => {\n * subscription.unsubscribe();\n * console.log('unsubscribed!');\n * }, 2500);\n *\n * // Logs:\n * // 0 after 1s\n * // 1 after 2s\n * // 'unsubscribed!' after 2.5s\n * ```\n *\n * @param {Observer|Function} observerOrNext (optional) Either an observer with methods to be called,\n * or the first of three possible handlers, which is the handler for each value emitted from the subscribed\n * Observable.\n * @param {Function} error (optional) A handler for a terminal event resulting from an error. If no error handler is provided,\n * the error will be thrown asynchronously as unhandled.\n * @param {Function} complete (optional) A handler for a terminal event resulting from successful completion.\n * @return {Subscription} a subscription reference to the registered handlers\n * @method subscribe\n */\n subscribe(\n observerOrNext?: Partial> | ((value: T) => void) | null,\n error?: ((error: any) => void) | null,\n complete?: (() => void) | null\n ): Subscription {\n const subscriber = isSubscriber(observerOrNext) ? observerOrNext : new SafeSubscriber(observerOrNext, error, complete);\n\n errorContext(() => {\n const { operator, source } = this;\n subscriber.add(\n operator\n ? // We're dealing with a subscription in the\n // operator chain to one of our lifted operators.\n operator.call(subscriber, source)\n : source\n ? // If `source` has a value, but `operator` does not, something that\n // had intimate knowledge of our API, like our `Subject`, must have\n // set it. We're going to just call `_subscribe` directly.\n this._subscribe(subscriber)\n : // In all other cases, we're likely wrapping a user-provided initializer\n // function, so we need to catch errors and handle them appropriately.\n this._trySubscribe(subscriber)\n );\n });\n\n return subscriber;\n }\n\n /** @internal */\n protected _trySubscribe(sink: Subscriber): TeardownLogic {\n try {\n return this._subscribe(sink);\n } catch (err) {\n // We don't need to return anything in this case,\n // because it's just going to try to `add()` to a subscription\n // above.\n sink.error(err);\n }\n }\n\n /**\n * Used as a NON-CANCELLABLE means of subscribing to an observable, for use with\n * APIs that expect promises, like `async/await`. You cannot unsubscribe from this.\n *\n * **WARNING**: Only use this with observables you *know* will complete. If the source\n * observable does not complete, you will end up with a promise that is hung up, and\n * potentially all of the state of an async function hanging out in memory. To avoid\n * this situation, look into adding something like {@link timeout}, {@link take},\n * {@link takeWhile}, or {@link takeUntil} amongst others.\n *\n * #### Example\n *\n * ```ts\n * import { interval, take } from 'rxjs';\n *\n * const source$ = interval(1000).pipe(take(4));\n *\n * async function getTotal() {\n * let total = 0;\n *\n * await source$.forEach(value => {\n * total += value;\n * console.log('observable -> ' + value);\n * });\n *\n * return total;\n * }\n *\n * getTotal().then(\n * total => console.log('Total: ' + total)\n * );\n *\n * // Expected:\n * // 'observable -> 0'\n * // 'observable -> 1'\n * // 'observable -> 2'\n * // 'observable -> 3'\n * // 'Total: 6'\n * ```\n *\n * @param next a handler for each value emitted by the observable\n * @return a promise that either resolves on observable completion or\n * rejects with the handled error\n */\n forEach(next: (value: T) => void): Promise;\n\n /**\n * @param next a handler for each value emitted by the observable\n * @param promiseCtor a constructor function used to instantiate the Promise\n * @return a promise that either resolves on observable completion or\n * rejects with the handled error\n * @deprecated Passing a Promise constructor will no longer be available\n * in upcoming versions of RxJS. This is because it adds weight to the library, for very\n * little benefit. If you need this functionality, it is recommended that you either\n * polyfill Promise, or you create an adapter to convert the returned native promise\n * to whatever promise implementation you wanted. Will be removed in v8.\n */\n forEach(next: (value: T) => void, promiseCtor: PromiseConstructorLike): Promise;\n\n forEach(next: (value: T) => void, promiseCtor?: PromiseConstructorLike): Promise {\n promiseCtor = getPromiseCtor(promiseCtor);\n\n return new promiseCtor((resolve, reject) => {\n const subscriber = new SafeSubscriber({\n next: (value) => {\n try {\n next(value);\n } catch (err) {\n reject(err);\n subscriber.unsubscribe();\n }\n },\n error: reject,\n complete: resolve,\n });\n this.subscribe(subscriber);\n }) as Promise;\n }\n\n /** @internal */\n protected _subscribe(subscriber: Subscriber): TeardownLogic {\n return this.source?.subscribe(subscriber);\n }\n\n /**\n * An interop point defined by the es7-observable spec https://github.com/zenparsing/es-observable\n * @method Symbol.observable\n * @return {Observable} this instance of the observable\n */\n [Symbol_observable]() {\n return this;\n }\n\n /* tslint:disable:max-line-length */\n pipe(): Observable;\n pipe(op1: OperatorFunction): Observable;\n pipe(op1: OperatorFunction, op2: OperatorFunction): Observable;\n pipe(op1: OperatorFunction, op2: OperatorFunction, op3: OperatorFunction): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction,\n op6: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction,\n op6: OperatorFunction,\n op7: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction,\n op6: OperatorFunction,\n op7: OperatorFunction,\n op8: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction,\n op6: OperatorFunction,\n op7: OperatorFunction,\n op8: OperatorFunction,\n op9: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction,\n op6: OperatorFunction,\n op7: OperatorFunction,\n op8: OperatorFunction,\n op9: OperatorFunction,\n ...operations: OperatorFunction[]\n ): Observable;\n /* tslint:enable:max-line-length */\n\n /**\n * Used to stitch together functional operators into a chain.\n * @method pipe\n * @return {Observable} the Observable result of all of the operators having\n * been called in the order they were passed in.\n *\n * ## Example\n *\n * ```ts\n * import { interval, filter, map, scan } from 'rxjs';\n *\n * interval(1000)\n * .pipe(\n * filter(x => x % 2 === 0),\n * map(x => x + x),\n * scan((acc, x) => acc + x)\n * )\n * .subscribe(x => console.log(x));\n * ```\n */\n pipe(...operations: OperatorFunction[]): Observable {\n return pipeFromArray(operations)(this);\n }\n\n /* tslint:disable:max-line-length */\n /** @deprecated Replaced with {@link firstValueFrom} and {@link lastValueFrom}. Will be removed in v8. Details: https://rxjs.dev/deprecations/to-promise */\n toPromise(): Promise;\n /** @deprecated Replaced with {@link firstValueFrom} and {@link lastValueFrom}. Will be removed in v8. Details: https://rxjs.dev/deprecations/to-promise */\n toPromise(PromiseCtor: typeof Promise): Promise;\n /** @deprecated Replaced with {@link firstValueFrom} and {@link lastValueFrom}. Will be removed in v8. Details: https://rxjs.dev/deprecations/to-promise */\n toPromise(PromiseCtor: PromiseConstructorLike): Promise;\n /* tslint:enable:max-line-length */\n\n /**\n * Subscribe to this Observable and get a Promise resolving on\n * `complete` with the last emission (if any).\n *\n * **WARNING**: Only use this with observables you *know* will complete. If the source\n * observable does not complete, you will end up with a promise that is hung up, and\n * potentially all of the state of an async function hanging out in memory. To avoid\n * this situation, look into adding something like {@link timeout}, {@link take},\n * {@link takeWhile}, or {@link takeUntil} amongst others.\n *\n * @method toPromise\n * @param [promiseCtor] a constructor function used to instantiate\n * the Promise\n * @return A Promise that resolves with the last value emit, or\n * rejects on an error. If there were no emissions, Promise\n * resolves with undefined.\n * @deprecated Replaced with {@link firstValueFrom} and {@link lastValueFrom}. Will be removed in v8. Details: https://rxjs.dev/deprecations/to-promise\n */\n toPromise(promiseCtor?: PromiseConstructorLike): Promise {\n promiseCtor = getPromiseCtor(promiseCtor);\n\n return new promiseCtor((resolve, reject) => {\n let value: T | undefined;\n this.subscribe(\n (x: T) => (value = x),\n (err: any) => reject(err),\n () => resolve(value)\n );\n }) as Promise;\n }\n}\n\n/**\n * Decides between a passed promise constructor from consuming code,\n * A default configured promise constructor, and the native promise\n * constructor and returns it. If nothing can be found, it will throw\n * an error.\n * @param promiseCtor The optional promise constructor to passed by consuming code\n */\nfunction getPromiseCtor(promiseCtor: PromiseConstructorLike | undefined) {\n return promiseCtor ?? config.Promise ?? Promise;\n}\n\nfunction isObserver(value: any): value is Observer {\n return value && isFunction(value.next) && isFunction(value.error) && isFunction(value.complete);\n}\n\nfunction isSubscriber(value: any): value is Subscriber {\n return (value && value instanceof Subscriber) || (isObserver(value) && isSubscription(value));\n}\n", "import { Observable } from '../Observable';\nimport { Subscriber } from '../Subscriber';\nimport { OperatorFunction } from '../types';\nimport { isFunction } from './isFunction';\n\n/**\n * Used to determine if an object is an Observable with a lift function.\n */\nexport function hasLift(source: any): source is { lift: InstanceType['lift'] } {\n return isFunction(source?.lift);\n}\n\n/**\n * Creates an `OperatorFunction`. Used to define operators throughout the library in a concise way.\n * @param init The logic to connect the liftedSource to the subscriber at the moment of subscription.\n */\nexport function operate(\n init: (liftedSource: Observable, subscriber: Subscriber) => (() => void) | void\n): OperatorFunction {\n return (source: Observable) => {\n if (hasLift(source)) {\n return source.lift(function (this: Subscriber, liftedSource: Observable) {\n try {\n return init(liftedSource, this);\n } catch (err) {\n this.error(err);\n }\n });\n }\n throw new TypeError('Unable to lift unknown Observable type');\n };\n}\n", "import { Subscriber } from '../Subscriber';\n\n/**\n * Creates an instance of an `OperatorSubscriber`.\n * @param destination The downstream subscriber.\n * @param onNext Handles next values, only called if this subscriber is not stopped or closed. Any\n * error that occurs in this function is caught and sent to the `error` method of this subscriber.\n * @param onError Handles errors from the subscription, any errors that occur in this handler are caught\n * and send to the `destination` error handler.\n * @param onComplete Handles completion notification from the subscription. Any errors that occur in\n * this handler are sent to the `destination` error handler.\n * @param onFinalize Additional teardown logic here. This will only be called on teardown if the\n * subscriber itself is not already closed. This is called after all other teardown logic is executed.\n */\nexport function createOperatorSubscriber(\n destination: Subscriber,\n onNext?: (value: T) => void,\n onComplete?: () => void,\n onError?: (err: any) => void,\n onFinalize?: () => void\n): Subscriber {\n return new OperatorSubscriber(destination, onNext, onComplete, onError, onFinalize);\n}\n\n/**\n * A generic helper for allowing operators to be created with a Subscriber and\n * use closures to capture necessary state from the operator function itself.\n */\nexport class OperatorSubscriber extends Subscriber {\n /**\n * Creates an instance of an `OperatorSubscriber`.\n * @param destination The downstream subscriber.\n * @param onNext Handles next values, only called if this subscriber is not stopped or closed. Any\n * error that occurs in this function is caught and sent to the `error` method of this subscriber.\n * @param onError Handles errors from the subscription, any errors that occur in this handler are caught\n * and send to the `destination` error handler.\n * @param onComplete Handles completion notification from the subscription. Any errors that occur in\n * this handler are sent to the `destination` error handler.\n * @param onFinalize Additional finalization logic here. This will only be called on finalization if the\n * subscriber itself is not already closed. This is called after all other finalization logic is executed.\n * @param shouldUnsubscribe An optional check to see if an unsubscribe call should truly unsubscribe.\n * NOTE: This currently **ONLY** exists to support the strange behavior of {@link groupBy}, where unsubscription\n * to the resulting observable does not actually disconnect from the source if there are active subscriptions\n * to any grouped observable. (DO NOT EXPOSE OR USE EXTERNALLY!!!)\n */\n constructor(\n destination: Subscriber,\n onNext?: (value: T) => void,\n onComplete?: () => void,\n onError?: (err: any) => void,\n private onFinalize?: () => void,\n private shouldUnsubscribe?: () => boolean\n ) {\n // It's important - for performance reasons - that all of this class's\n // members are initialized and that they are always initialized in the same\n // order. This will ensure that all OperatorSubscriber instances have the\n // same hidden class in V8. This, in turn, will help keep the number of\n // hidden classes involved in property accesses within the base class as\n // low as possible. If the number of hidden classes involved exceeds four,\n // the property accesses will become megamorphic and performance penalties\n // will be incurred - i.e. inline caches won't be used.\n //\n // The reasons for ensuring all instances have the same hidden class are\n // further discussed in this blog post from Benedikt Meurer:\n // https://benediktmeurer.de/2018/03/23/impact-of-polymorphism-on-component-based-frameworks-like-react/\n super(destination);\n this._next = onNext\n ? function (this: OperatorSubscriber, value: T) {\n try {\n onNext(value);\n } catch (err) {\n destination.error(err);\n }\n }\n : super._next;\n this._error = onError\n ? function (this: OperatorSubscriber, err: any) {\n try {\n onError(err);\n } catch (err) {\n // Send any errors that occur down stream.\n destination.error(err);\n } finally {\n // Ensure finalization.\n this.unsubscribe();\n }\n }\n : super._error;\n this._complete = onComplete\n ? function (this: OperatorSubscriber) {\n try {\n onComplete();\n } catch (err) {\n // Send any errors that occur down stream.\n destination.error(err);\n } finally {\n // Ensure finalization.\n this.unsubscribe();\n }\n }\n : super._complete;\n }\n\n unsubscribe() {\n if (!this.shouldUnsubscribe || this.shouldUnsubscribe()) {\n const { closed } = this;\n super.unsubscribe();\n // Execute additional teardown if we have any and we didn't already do so.\n !closed && this.onFinalize?.();\n }\n }\n}\n", "import { Subscription } from '../Subscription';\n\ninterface AnimationFrameProvider {\n schedule(callback: FrameRequestCallback): Subscription;\n requestAnimationFrame: typeof requestAnimationFrame;\n cancelAnimationFrame: typeof cancelAnimationFrame;\n delegate:\n | {\n requestAnimationFrame: typeof requestAnimationFrame;\n cancelAnimationFrame: typeof cancelAnimationFrame;\n }\n | undefined;\n}\n\nexport const animationFrameProvider: AnimationFrameProvider = {\n // When accessing the delegate, use the variable rather than `this` so that\n // the functions can be called without being bound to the provider.\n schedule(callback) {\n let request = requestAnimationFrame;\n let cancel: typeof cancelAnimationFrame | undefined = cancelAnimationFrame;\n const { delegate } = animationFrameProvider;\n if (delegate) {\n request = delegate.requestAnimationFrame;\n cancel = delegate.cancelAnimationFrame;\n }\n const handle = request((timestamp) => {\n // Clear the cancel function. The request has been fulfilled, so\n // attempting to cancel the request upon unsubscription would be\n // pointless.\n cancel = undefined;\n callback(timestamp);\n });\n return new Subscription(() => cancel?.(handle));\n },\n requestAnimationFrame(...args) {\n const { delegate } = animationFrameProvider;\n return (delegate?.requestAnimationFrame || requestAnimationFrame)(...args);\n },\n cancelAnimationFrame(...args) {\n const { delegate } = animationFrameProvider;\n return (delegate?.cancelAnimationFrame || cancelAnimationFrame)(...args);\n },\n delegate: undefined,\n};\n", "import { createErrorClass } from './createErrorClass';\n\nexport interface ObjectUnsubscribedError extends Error {}\n\nexport interface ObjectUnsubscribedErrorCtor {\n /**\n * @deprecated Internal implementation detail. Do not construct error instances.\n * Cannot be tagged as internal: https://github.com/ReactiveX/rxjs/issues/6269\n */\n new (): ObjectUnsubscribedError;\n}\n\n/**\n * An error thrown when an action is invalid because the object has been\n * unsubscribed.\n *\n * @see {@link Subject}\n * @see {@link BehaviorSubject}\n *\n * @class ObjectUnsubscribedError\n */\nexport const ObjectUnsubscribedError: ObjectUnsubscribedErrorCtor = createErrorClass(\n (_super) =>\n function ObjectUnsubscribedErrorImpl(this: any) {\n _super(this);\n this.name = 'ObjectUnsubscribedError';\n this.message = 'object unsubscribed';\n }\n);\n", "import { Operator } from './Operator';\nimport { Observable } from './Observable';\nimport { Subscriber } from './Subscriber';\nimport { Subscription, EMPTY_SUBSCRIPTION } from './Subscription';\nimport { Observer, SubscriptionLike, TeardownLogic } from './types';\nimport { ObjectUnsubscribedError } from './util/ObjectUnsubscribedError';\nimport { arrRemove } from './util/arrRemove';\nimport { errorContext } from './util/errorContext';\n\n/**\n * A Subject is a special type of Observable that allows values to be\n * multicasted to many Observers. Subjects are like EventEmitters.\n *\n * Every Subject is an Observable and an Observer. You can subscribe to a\n * Subject, and you can call next to feed values as well as error and complete.\n */\nexport class Subject extends Observable implements SubscriptionLike {\n closed = false;\n\n private currentObservers: Observer[] | null = null;\n\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n observers: Observer[] = [];\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n isStopped = false;\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n hasError = false;\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n thrownError: any = null;\n\n /**\n * Creates a \"subject\" by basically gluing an observer to an observable.\n *\n * @nocollapse\n * @deprecated Recommended you do not use. Will be removed at some point in the future. Plans for replacement still under discussion.\n */\n static create: (...args: any[]) => any = (destination: Observer, source: Observable): AnonymousSubject => {\n return new AnonymousSubject(destination, source);\n };\n\n constructor() {\n // NOTE: This must be here to obscure Observable's constructor.\n super();\n }\n\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n lift(operator: Operator): Observable {\n const subject = new AnonymousSubject(this, this);\n subject.operator = operator as any;\n return subject as any;\n }\n\n /** @internal */\n protected _throwIfClosed() {\n if (this.closed) {\n throw new ObjectUnsubscribedError();\n }\n }\n\n next(value: T) {\n errorContext(() => {\n this._throwIfClosed();\n if (!this.isStopped) {\n if (!this.currentObservers) {\n this.currentObservers = Array.from(this.observers);\n }\n for (const observer of this.currentObservers) {\n observer.next(value);\n }\n }\n });\n }\n\n error(err: any) {\n errorContext(() => {\n this._throwIfClosed();\n if (!this.isStopped) {\n this.hasError = this.isStopped = true;\n this.thrownError = err;\n const { observers } = this;\n while (observers.length) {\n observers.shift()!.error(err);\n }\n }\n });\n }\n\n complete() {\n errorContext(() => {\n this._throwIfClosed();\n if (!this.isStopped) {\n this.isStopped = true;\n const { observers } = this;\n while (observers.length) {\n observers.shift()!.complete();\n }\n }\n });\n }\n\n unsubscribe() {\n this.isStopped = this.closed = true;\n this.observers = this.currentObservers = null!;\n }\n\n get observed() {\n return this.observers?.length > 0;\n }\n\n /** @internal */\n protected _trySubscribe(subscriber: Subscriber): TeardownLogic {\n this._throwIfClosed();\n return super._trySubscribe(subscriber);\n }\n\n /** @internal */\n protected _subscribe(subscriber: Subscriber): Subscription {\n this._throwIfClosed();\n this._checkFinalizedStatuses(subscriber);\n return this._innerSubscribe(subscriber);\n }\n\n /** @internal */\n protected _innerSubscribe(subscriber: Subscriber) {\n const { hasError, isStopped, observers } = this;\n if (hasError || isStopped) {\n return EMPTY_SUBSCRIPTION;\n }\n this.currentObservers = null;\n observers.push(subscriber);\n return new Subscription(() => {\n this.currentObservers = null;\n arrRemove(observers, subscriber);\n });\n }\n\n /** @internal */\n protected _checkFinalizedStatuses(subscriber: Subscriber) {\n const { hasError, thrownError, isStopped } = this;\n if (hasError) {\n subscriber.error(thrownError);\n } else if (isStopped) {\n subscriber.complete();\n }\n }\n\n /**\n * Creates a new Observable with this Subject as the source. You can do this\n * to create custom Observer-side logic of the Subject and conceal it from\n * code that uses the Observable.\n * @return {Observable} Observable that the Subject casts to\n */\n asObservable(): Observable {\n const observable: any = new Observable();\n observable.source = this;\n return observable;\n }\n}\n\n/**\n * @class AnonymousSubject\n */\nexport class AnonymousSubject extends Subject {\n constructor(\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n public destination?: Observer,\n source?: Observable\n ) {\n super();\n this.source = source;\n }\n\n next(value: T) {\n this.destination?.next?.(value);\n }\n\n error(err: any) {\n this.destination?.error?.(err);\n }\n\n complete() {\n this.destination?.complete?.();\n }\n\n /** @internal */\n protected _subscribe(subscriber: Subscriber): Subscription {\n return this.source?.subscribe(subscriber) ?? EMPTY_SUBSCRIPTION;\n }\n}\n", "import { Subject } from './Subject';\nimport { Subscriber } from './Subscriber';\nimport { Subscription } from './Subscription';\n\n/**\n * A variant of Subject that requires an initial value and emits its current\n * value whenever it is subscribed to.\n *\n * @class BehaviorSubject\n */\nexport class BehaviorSubject extends Subject {\n constructor(private _value: T) {\n super();\n }\n\n get value(): T {\n return this.getValue();\n }\n\n /** @internal */\n protected _subscribe(subscriber: Subscriber): Subscription {\n const subscription = super._subscribe(subscriber);\n !subscription.closed && subscriber.next(this._value);\n return subscription;\n }\n\n getValue(): T {\n const { hasError, thrownError, _value } = this;\n if (hasError) {\n throw thrownError;\n }\n this._throwIfClosed();\n return _value;\n }\n\n next(value: T): void {\n super.next((this._value = value));\n }\n}\n", "import { TimestampProvider } from '../types';\n\ninterface DateTimestampProvider extends TimestampProvider {\n delegate: TimestampProvider | undefined;\n}\n\nexport const dateTimestampProvider: DateTimestampProvider = {\n now() {\n // Use the variable rather than `this` so that the function can be called\n // without being bound to the provider.\n return (dateTimestampProvider.delegate || Date).now();\n },\n delegate: undefined,\n};\n", "import { Subject } from './Subject';\nimport { TimestampProvider } from './types';\nimport { Subscriber } from './Subscriber';\nimport { Subscription } from './Subscription';\nimport { dateTimestampProvider } from './scheduler/dateTimestampProvider';\n\n/**\n * A variant of {@link Subject} that \"replays\" old values to new subscribers by emitting them when they first subscribe.\n *\n * `ReplaySubject` has an internal buffer that will store a specified number of values that it has observed. Like `Subject`,\n * `ReplaySubject` \"observes\" values by having them passed to its `next` method. When it observes a value, it will store that\n * value for a time determined by the configuration of the `ReplaySubject`, as passed to its constructor.\n *\n * When a new subscriber subscribes to the `ReplaySubject` instance, it will synchronously emit all values in its buffer in\n * a First-In-First-Out (FIFO) manner. The `ReplaySubject` will also complete, if it has observed completion; and it will\n * error if it has observed an error.\n *\n * There are two main configuration items to be concerned with:\n *\n * 1. `bufferSize` - This will determine how many items are stored in the buffer, defaults to infinite.\n * 2. `windowTime` - The amount of time to hold a value in the buffer before removing it from the buffer.\n *\n * Both configurations may exist simultaneously. So if you would like to buffer a maximum of 3 values, as long as the values\n * are less than 2 seconds old, you could do so with a `new ReplaySubject(3, 2000)`.\n *\n * ### Differences with BehaviorSubject\n *\n * `BehaviorSubject` is similar to `new ReplaySubject(1)`, with a couple of exceptions:\n *\n * 1. `BehaviorSubject` comes \"primed\" with a single value upon construction.\n * 2. `ReplaySubject` will replay values, even after observing an error, where `BehaviorSubject` will not.\n *\n * @see {@link Subject}\n * @see {@link BehaviorSubject}\n * @see {@link shareReplay}\n */\nexport class ReplaySubject extends Subject {\n private _buffer: (T | number)[] = [];\n private _infiniteTimeWindow = true;\n\n /**\n * @param bufferSize The size of the buffer to replay on subscription\n * @param windowTime The amount of time the buffered items will stay buffered\n * @param timestampProvider An object with a `now()` method that provides the current timestamp. This is used to\n * calculate the amount of time something has been buffered.\n */\n constructor(\n private _bufferSize = Infinity,\n private _windowTime = Infinity,\n private _timestampProvider: TimestampProvider = dateTimestampProvider\n ) {\n super();\n this._infiniteTimeWindow = _windowTime === Infinity;\n this._bufferSize = Math.max(1, _bufferSize);\n this._windowTime = Math.max(1, _windowTime);\n }\n\n next(value: T): void {\n const { isStopped, _buffer, _infiniteTimeWindow, _timestampProvider, _windowTime } = this;\n if (!isStopped) {\n _buffer.push(value);\n !_infiniteTimeWindow && _buffer.push(_timestampProvider.now() + _windowTime);\n }\n this._trimBuffer();\n super.next(value);\n }\n\n /** @internal */\n protected _subscribe(subscriber: Subscriber): Subscription {\n this._throwIfClosed();\n this._trimBuffer();\n\n const subscription = this._innerSubscribe(subscriber);\n\n const { _infiniteTimeWindow, _buffer } = this;\n // We use a copy here, so reentrant code does not mutate our array while we're\n // emitting it to a new subscriber.\n const copy = _buffer.slice();\n for (let i = 0; i < copy.length && !subscriber.closed; i += _infiniteTimeWindow ? 1 : 2) {\n subscriber.next(copy[i] as T);\n }\n\n this._checkFinalizedStatuses(subscriber);\n\n return subscription;\n }\n\n private _trimBuffer() {\n const { _bufferSize, _timestampProvider, _buffer, _infiniteTimeWindow } = this;\n // If we don't have an infinite buffer size, and we're over the length,\n // use splice to truncate the old buffer values off. Note that we have to\n // double the size for instances where we're not using an infinite time window\n // because we're storing the values and the timestamps in the same array.\n const adjustedBufferSize = (_infiniteTimeWindow ? 1 : 2) * _bufferSize;\n _bufferSize < Infinity && adjustedBufferSize < _buffer.length && _buffer.splice(0, _buffer.length - adjustedBufferSize);\n\n // Now, if we're not in an infinite time window, remove all values where the time is\n // older than what is allowed.\n if (!_infiniteTimeWindow) {\n const now = _timestampProvider.now();\n let last = 0;\n // Search the array for the first timestamp that isn't expired and\n // truncate the buffer up to that point.\n for (let i = 1; i < _buffer.length && (_buffer[i] as number) <= now; i += 2) {\n last = i;\n }\n last && _buffer.splice(0, last + 1);\n }\n }\n}\n", "import { Scheduler } from '../Scheduler';\nimport { Subscription } from '../Subscription';\nimport { SchedulerAction } from '../types';\n\n/**\n * A unit of work to be executed in a `scheduler`. An action is typically\n * created from within a {@link SchedulerLike} and an RxJS user does not need to concern\n * themselves about creating and manipulating an Action.\n *\n * ```ts\n * class Action extends Subscription {\n * new (scheduler: Scheduler, work: (state?: T) => void);\n * schedule(state?: T, delay: number = 0): Subscription;\n * }\n * ```\n *\n * @class Action\n */\nexport class Action extends Subscription {\n constructor(scheduler: Scheduler, work: (this: SchedulerAction, state?: T) => void) {\n super();\n }\n /**\n * Schedules this action on its parent {@link SchedulerLike} for execution. May be passed\n * some context object, `state`. May happen at some point in the future,\n * according to the `delay` parameter, if specified.\n * @param {T} [state] Some contextual data that the `work` function uses when\n * called by the Scheduler.\n * @param {number} [delay] Time to wait before executing the work, where the\n * time unit is implicit and defined by the Scheduler.\n * @return {void}\n */\n public schedule(state?: T, delay: number = 0): Subscription {\n return this;\n }\n}\n", "import type { TimerHandle } from './timerHandle';\ntype SetIntervalFunction = (handler: () => void, timeout?: number, ...args: any[]) => TimerHandle;\ntype ClearIntervalFunction = (handle: TimerHandle) => void;\n\ninterface IntervalProvider {\n setInterval: SetIntervalFunction;\n clearInterval: ClearIntervalFunction;\n delegate:\n | {\n setInterval: SetIntervalFunction;\n clearInterval: ClearIntervalFunction;\n }\n | undefined;\n}\n\nexport const intervalProvider: IntervalProvider = {\n // When accessing the delegate, use the variable rather than `this` so that\n // the functions can be called without being bound to the provider.\n setInterval(handler: () => void, timeout?: number, ...args) {\n const { delegate } = intervalProvider;\n if (delegate?.setInterval) {\n return delegate.setInterval(handler, timeout, ...args);\n }\n return setInterval(handler, timeout, ...args);\n },\n clearInterval(handle) {\n const { delegate } = intervalProvider;\n return (delegate?.clearInterval || clearInterval)(handle as any);\n },\n delegate: undefined,\n};\n", "import { Action } from './Action';\nimport { SchedulerAction } from '../types';\nimport { Subscription } from '../Subscription';\nimport { AsyncScheduler } from './AsyncScheduler';\nimport { intervalProvider } from './intervalProvider';\nimport { arrRemove } from '../util/arrRemove';\nimport { TimerHandle } from './timerHandle';\n\nexport class AsyncAction extends Action {\n public id: TimerHandle | undefined;\n public state?: T;\n // @ts-ignore: Property has no initializer and is not definitely assigned\n public delay: number;\n protected pending: boolean = false;\n\n constructor(protected scheduler: AsyncScheduler, protected work: (this: SchedulerAction, state?: T) => void) {\n super(scheduler, work);\n }\n\n public schedule(state?: T, delay: number = 0): Subscription {\n if (this.closed) {\n return this;\n }\n\n // Always replace the current state with the new state.\n this.state = state;\n\n const id = this.id;\n const scheduler = this.scheduler;\n\n //\n // Important implementation note:\n //\n // Actions only execute once by default, unless rescheduled from within the\n // scheduled callback. This allows us to implement single and repeat\n // actions via the same code path, without adding API surface area, as well\n // as mimic traditional recursion but across asynchronous boundaries.\n //\n // However, JS runtimes and timers distinguish between intervals achieved by\n // serial `setTimeout` calls vs. a single `setInterval` call. An interval of\n // serial `setTimeout` calls can be individually delayed, which delays\n // scheduling the next `setTimeout`, and so on. `setInterval` attempts to\n // guarantee the interval callback will be invoked more precisely to the\n // interval period, regardless of load.\n //\n // Therefore, we use `setInterval` to schedule single and repeat actions.\n // If the action reschedules itself with the same delay, the interval is not\n // canceled. If the action doesn't reschedule, or reschedules with a\n // different delay, the interval will be canceled after scheduled callback\n // execution.\n //\n if (id != null) {\n this.id = this.recycleAsyncId(scheduler, id, delay);\n }\n\n // Set the pending flag indicating that this action has been scheduled, or\n // has recursively rescheduled itself.\n this.pending = true;\n\n this.delay = delay;\n // If this action has already an async Id, don't request a new one.\n this.id = this.id ?? this.requestAsyncId(scheduler, this.id, delay);\n\n return this;\n }\n\n protected requestAsyncId(scheduler: AsyncScheduler, _id?: TimerHandle, delay: number = 0): TimerHandle {\n return intervalProvider.setInterval(scheduler.flush.bind(scheduler, this), delay);\n }\n\n protected recycleAsyncId(_scheduler: AsyncScheduler, id?: TimerHandle, delay: number | null = 0): TimerHandle | undefined {\n // If this action is rescheduled with the same delay time, don't clear the interval id.\n if (delay != null && this.delay === delay && this.pending === false) {\n return id;\n }\n // Otherwise, if the action's delay time is different from the current delay,\n // or the action has been rescheduled before it's executed, clear the interval id\n if (id != null) {\n intervalProvider.clearInterval(id);\n }\n\n return undefined;\n }\n\n /**\n * Immediately executes this action and the `work` it contains.\n * @return {any}\n */\n public execute(state: T, delay: number): any {\n if (this.closed) {\n return new Error('executing a cancelled action');\n }\n\n this.pending = false;\n const error = this._execute(state, delay);\n if (error) {\n return error;\n } else if (this.pending === false && this.id != null) {\n // Dequeue if the action didn't reschedule itself. Don't call\n // unsubscribe(), because the action could reschedule later.\n // For example:\n // ```\n // scheduler.schedule(function doWork(counter) {\n // /* ... I'm a busy worker bee ... */\n // var originalAction = this;\n // /* wait 100ms before rescheduling the action */\n // setTimeout(function () {\n // originalAction.schedule(counter + 1);\n // }, 100);\n // }, 1000);\n // ```\n this.id = this.recycleAsyncId(this.scheduler, this.id, null);\n }\n }\n\n protected _execute(state: T, _delay: number): any {\n let errored: boolean = false;\n let errorValue: any;\n try {\n this.work(state);\n } catch (e) {\n errored = true;\n // HACK: Since code elsewhere is relying on the \"truthiness\" of the\n // return here, we can't have it return \"\" or 0 or false.\n // TODO: Clean this up when we refactor schedulers mid-version-8 or so.\n errorValue = e ? e : new Error('Scheduled action threw falsy error');\n }\n if (errored) {\n this.unsubscribe();\n return errorValue;\n }\n }\n\n unsubscribe() {\n if (!this.closed) {\n const { id, scheduler } = this;\n const { actions } = scheduler;\n\n this.work = this.state = this.scheduler = null!;\n this.pending = false;\n\n arrRemove(actions, this);\n if (id != null) {\n this.id = this.recycleAsyncId(scheduler, id, null);\n }\n\n this.delay = null!;\n super.unsubscribe();\n }\n }\n}\n", "import { Action } from './scheduler/Action';\nimport { Subscription } from './Subscription';\nimport { SchedulerLike, SchedulerAction } from './types';\nimport { dateTimestampProvider } from './scheduler/dateTimestampProvider';\n\n/**\n * An execution context and a data structure to order tasks and schedule their\n * execution. Provides a notion of (potentially virtual) time, through the\n * `now()` getter method.\n *\n * Each unit of work in a Scheduler is called an `Action`.\n *\n * ```ts\n * class Scheduler {\n * now(): number;\n * schedule(work, delay?, state?): Subscription;\n * }\n * ```\n *\n * @class Scheduler\n * @deprecated Scheduler is an internal implementation detail of RxJS, and\n * should not be used directly. Rather, create your own class and implement\n * {@link SchedulerLike}. Will be made internal in v8.\n */\nexport class Scheduler implements SchedulerLike {\n public static now: () => number = dateTimestampProvider.now;\n\n constructor(private schedulerActionCtor: typeof Action, now: () => number = Scheduler.now) {\n this.now = now;\n }\n\n /**\n * A getter method that returns a number representing the current time\n * (at the time this function was called) according to the scheduler's own\n * internal clock.\n * @return {number} A number that represents the current time. May or may not\n * have a relation to wall-clock time. May or may not refer to a time unit\n * (e.g. milliseconds).\n */\n public now: () => number;\n\n /**\n * Schedules a function, `work`, for execution. May happen at some point in\n * the future, according to the `delay` parameter, if specified. May be passed\n * some context object, `state`, which will be passed to the `work` function.\n *\n * The given arguments will be processed an stored as an Action object in a\n * queue of actions.\n *\n * @param {function(state: ?T): ?Subscription} work A function representing a\n * task, or some unit of work to be executed by the Scheduler.\n * @param {number} [delay] Time to wait before executing the work, where the\n * time unit is implicit and defined by the Scheduler itself.\n * @param {T} [state] Some contextual data that the `work` function uses when\n * called by the Scheduler.\n * @return {Subscription} A subscription in order to be able to unsubscribe\n * the scheduled work.\n */\n public schedule(work: (this: SchedulerAction, state?: T) => void, delay: number = 0, state?: T): Subscription {\n return new this.schedulerActionCtor(this, work).schedule(state, delay);\n }\n}\n", "import { Scheduler } from '../Scheduler';\nimport { Action } from './Action';\nimport { AsyncAction } from './AsyncAction';\nimport { TimerHandle } from './timerHandle';\n\nexport class AsyncScheduler extends Scheduler {\n public actions: Array> = [];\n /**\n * A flag to indicate whether the Scheduler is currently executing a batch of\n * queued actions.\n * @type {boolean}\n * @internal\n */\n public _active: boolean = false;\n /**\n * An internal ID used to track the latest asynchronous task such as those\n * coming from `setTimeout`, `setInterval`, `requestAnimationFrame`, and\n * others.\n * @type {any}\n * @internal\n */\n public _scheduled: TimerHandle | undefined;\n\n constructor(SchedulerAction: typeof Action, now: () => number = Scheduler.now) {\n super(SchedulerAction, now);\n }\n\n public flush(action: AsyncAction): void {\n const { actions } = this;\n\n if (this._active) {\n actions.push(action);\n return;\n }\n\n let error: any;\n this._active = true;\n\n do {\n if ((error = action.execute(action.state, action.delay))) {\n break;\n }\n } while ((action = actions.shift()!)); // exhaust the scheduler queue\n\n this._active = false;\n\n if (error) {\n while ((action = actions.shift()!)) {\n action.unsubscribe();\n }\n throw error;\n }\n }\n}\n", "import { AsyncAction } from './AsyncAction';\nimport { AsyncScheduler } from './AsyncScheduler';\n\n/**\n *\n * Async Scheduler\n *\n * Schedule task as if you used setTimeout(task, duration)\n *\n * `async` scheduler schedules tasks asynchronously, by putting them on the JavaScript\n * event loop queue. It is best used to delay tasks in time or to schedule tasks repeating\n * in intervals.\n *\n * If you just want to \"defer\" task, that is to perform it right after currently\n * executing synchronous code ends (commonly achieved by `setTimeout(deferredTask, 0)`),\n * better choice will be the {@link asapScheduler} scheduler.\n *\n * ## Examples\n * Use async scheduler to delay task\n * ```ts\n * import { asyncScheduler } from 'rxjs';\n *\n * const task = () => console.log('it works!');\n *\n * asyncScheduler.schedule(task, 2000);\n *\n * // After 2 seconds logs:\n * // \"it works!\"\n * ```\n *\n * Use async scheduler to repeat task in intervals\n * ```ts\n * import { asyncScheduler } from 'rxjs';\n *\n * function task(state) {\n * console.log(state);\n * this.schedule(state + 1, 1000); // `this` references currently executing Action,\n * // which we reschedule with new state and delay\n * }\n *\n * asyncScheduler.schedule(task, 3000, 0);\n *\n * // Logs:\n * // 0 after 3s\n * // 1 after 4s\n * // 2 after 5s\n * // 3 after 6s\n * ```\n */\n\nexport const asyncScheduler = new AsyncScheduler(AsyncAction);\n\n/**\n * @deprecated Renamed to {@link asyncScheduler}. Will be removed in v8.\n */\nexport const async = asyncScheduler;\n", "import { AsyncAction } from './AsyncAction';\nimport { Subscription } from '../Subscription';\nimport { QueueScheduler } from './QueueScheduler';\nimport { SchedulerAction } from '../types';\nimport { TimerHandle } from './timerHandle';\n\nexport class QueueAction extends AsyncAction {\n constructor(protected scheduler: QueueScheduler, protected work: (this: SchedulerAction, state?: T) => void) {\n super(scheduler, work);\n }\n\n public schedule(state?: T, delay: number = 0): Subscription {\n if (delay > 0) {\n return super.schedule(state, delay);\n }\n this.delay = delay;\n this.state = state;\n this.scheduler.flush(this);\n return this;\n }\n\n public execute(state: T, delay: number): any {\n return delay > 0 || this.closed ? super.execute(state, delay) : this._execute(state, delay);\n }\n\n protected requestAsyncId(scheduler: QueueScheduler, id?: TimerHandle, delay: number = 0): TimerHandle {\n // If delay exists and is greater than 0, or if the delay is null (the\n // action wasn't rescheduled) but was originally scheduled as an async\n // action, then recycle as an async action.\n\n if ((delay != null && delay > 0) || (delay == null && this.delay > 0)) {\n return super.requestAsyncId(scheduler, id, delay);\n }\n\n // Otherwise flush the scheduler starting with this action.\n scheduler.flush(this);\n\n // HACK: In the past, this was returning `void`. However, `void` isn't a valid\n // `TimerHandle`, and generally the return value here isn't really used. So the\n // compromise is to return `0` which is both \"falsy\" and a valid `TimerHandle`,\n // as opposed to refactoring every other instanceo of `requestAsyncId`.\n return 0;\n }\n}\n", "import { AsyncScheduler } from './AsyncScheduler';\n\nexport class QueueScheduler extends AsyncScheduler {\n}\n", "import { QueueAction } from './QueueAction';\nimport { QueueScheduler } from './QueueScheduler';\n\n/**\n *\n * Queue Scheduler\n *\n * Put every next task on a queue, instead of executing it immediately\n *\n * `queue` scheduler, when used with delay, behaves the same as {@link asyncScheduler} scheduler.\n *\n * When used without delay, it schedules given task synchronously - executes it right when\n * it is scheduled. However when called recursively, that is when inside the scheduled task,\n * another task is scheduled with queue scheduler, instead of executing immediately as well,\n * that task will be put on a queue and wait for current one to finish.\n *\n * This means that when you execute task with `queue` scheduler, you are sure it will end\n * before any other task scheduled with that scheduler will start.\n *\n * ## Examples\n * Schedule recursively first, then do something\n * ```ts\n * import { queueScheduler } from 'rxjs';\n *\n * queueScheduler.schedule(() => {\n * queueScheduler.schedule(() => console.log('second')); // will not happen now, but will be put on a queue\n *\n * console.log('first');\n * });\n *\n * // Logs:\n * // \"first\"\n * // \"second\"\n * ```\n *\n * Reschedule itself recursively\n * ```ts\n * import { queueScheduler } from 'rxjs';\n *\n * queueScheduler.schedule(function(state) {\n * if (state !== 0) {\n * console.log('before', state);\n * this.schedule(state - 1); // `this` references currently executing Action,\n * // which we reschedule with new state\n * console.log('after', state);\n * }\n * }, 0, 3);\n *\n * // In scheduler that runs recursively, you would expect:\n * // \"before\", 3\n * // \"before\", 2\n * // \"before\", 1\n * // \"after\", 1\n * // \"after\", 2\n * // \"after\", 3\n *\n * // But with queue it logs:\n * // \"before\", 3\n * // \"after\", 3\n * // \"before\", 2\n * // \"after\", 2\n * // \"before\", 1\n * // \"after\", 1\n * ```\n */\n\nexport const queueScheduler = new QueueScheduler(QueueAction);\n\n/**\n * @deprecated Renamed to {@link queueScheduler}. Will be removed in v8.\n */\nexport const queue = queueScheduler;\n", "import { AsyncAction } from './AsyncAction';\nimport { AnimationFrameScheduler } from './AnimationFrameScheduler';\nimport { SchedulerAction } from '../types';\nimport { animationFrameProvider } from './animationFrameProvider';\nimport { TimerHandle } from './timerHandle';\n\nexport class AnimationFrameAction extends AsyncAction {\n constructor(protected scheduler: AnimationFrameScheduler, protected work: (this: SchedulerAction, state?: T) => void) {\n super(scheduler, work);\n }\n\n protected requestAsyncId(scheduler: AnimationFrameScheduler, id?: TimerHandle, delay: number = 0): TimerHandle {\n // If delay is greater than 0, request as an async action.\n if (delay !== null && delay > 0) {\n return super.requestAsyncId(scheduler, id, delay);\n }\n // Push the action to the end of the scheduler queue.\n scheduler.actions.push(this);\n // If an animation frame has already been requested, don't request another\n // one. If an animation frame hasn't been requested yet, request one. Return\n // the current animation frame request id.\n return scheduler._scheduled || (scheduler._scheduled = animationFrameProvider.requestAnimationFrame(() => scheduler.flush(undefined)));\n }\n\n protected recycleAsyncId(scheduler: AnimationFrameScheduler, id?: TimerHandle, delay: number = 0): TimerHandle | undefined {\n // If delay exists and is greater than 0, or if the delay is null (the\n // action wasn't rescheduled) but was originally scheduled as an async\n // action, then recycle as an async action.\n if (delay != null ? delay > 0 : this.delay > 0) {\n return super.recycleAsyncId(scheduler, id, delay);\n }\n // If the scheduler queue has no remaining actions with the same async id,\n // cancel the requested animation frame and set the scheduled flag to\n // undefined so the next AnimationFrameAction will request its own.\n const { actions } = scheduler;\n if (id != null && actions[actions.length - 1]?.id !== id) {\n animationFrameProvider.cancelAnimationFrame(id as number);\n scheduler._scheduled = undefined;\n }\n // Return undefined so the action knows to request a new async id if it's rescheduled.\n return undefined;\n }\n}\n", "import { AsyncAction } from './AsyncAction';\nimport { AsyncScheduler } from './AsyncScheduler';\n\nexport class AnimationFrameScheduler extends AsyncScheduler {\n public flush(action?: AsyncAction): void {\n this._active = true;\n // The async id that effects a call to flush is stored in _scheduled.\n // Before executing an action, it's necessary to check the action's async\n // id to determine whether it's supposed to be executed in the current\n // flush.\n // Previous implementations of this method used a count to determine this,\n // but that was unsound, as actions that are unsubscribed - i.e. cancelled -\n // are removed from the actions array and that can shift actions that are\n // scheduled to be executed in a subsequent flush into positions at which\n // they are executed within the current flush.\n const flushId = this._scheduled;\n this._scheduled = undefined;\n\n const { actions } = this;\n let error: any;\n action = action || actions.shift()!;\n\n do {\n if ((error = action.execute(action.state, action.delay))) {\n break;\n }\n } while ((action = actions[0]) && action.id === flushId && actions.shift());\n\n this._active = false;\n\n if (error) {\n while ((action = actions[0]) && action.id === flushId && actions.shift()) {\n action.unsubscribe();\n }\n throw error;\n }\n }\n}\n", "import { AnimationFrameAction } from './AnimationFrameAction';\nimport { AnimationFrameScheduler } from './AnimationFrameScheduler';\n\n/**\n *\n * Animation Frame Scheduler\n *\n * Perform task when `window.requestAnimationFrame` would fire\n *\n * When `animationFrame` scheduler is used with delay, it will fall back to {@link asyncScheduler} scheduler\n * behaviour.\n *\n * Without delay, `animationFrame` scheduler can be used to create smooth browser animations.\n * It makes sure scheduled task will happen just before next browser content repaint,\n * thus performing animations as efficiently as possible.\n *\n * ## Example\n * Schedule div height animation\n * ```ts\n * // html:
\n * import { animationFrameScheduler } from 'rxjs';\n *\n * const div = document.querySelector('div');\n *\n * animationFrameScheduler.schedule(function(height) {\n * div.style.height = height + \"px\";\n *\n * this.schedule(height + 1); // `this` references currently executing Action,\n * // which we reschedule with new state\n * }, 0, 0);\n *\n * // You will see a div element growing in height\n * ```\n */\n\nexport const animationFrameScheduler = new AnimationFrameScheduler(AnimationFrameAction);\n\n/**\n * @deprecated Renamed to {@link animationFrameScheduler}. Will be removed in v8.\n */\nexport const animationFrame = animationFrameScheduler;\n", "import { Observable } from '../Observable';\nimport { SchedulerLike } from '../types';\n\n/**\n * A simple Observable that emits no items to the Observer and immediately\n * emits a complete notification.\n *\n * Just emits 'complete', and nothing else.\n *\n * ![](empty.png)\n *\n * A simple Observable that only emits the complete notification. It can be used\n * for composing with other Observables, such as in a {@link mergeMap}.\n *\n * ## Examples\n *\n * Log complete notification\n *\n * ```ts\n * import { EMPTY } from 'rxjs';\n *\n * EMPTY.subscribe({\n * next: () => console.log('Next'),\n * complete: () => console.log('Complete!')\n * });\n *\n * // Outputs\n * // Complete!\n * ```\n *\n * Emit the number 7, then complete\n *\n * ```ts\n * import { EMPTY, startWith } from 'rxjs';\n *\n * const result = EMPTY.pipe(startWith(7));\n * result.subscribe(x => console.log(x));\n *\n * // Outputs\n * // 7\n * ```\n *\n * Map and flatten only odd numbers to the sequence `'a'`, `'b'`, `'c'`\n *\n * ```ts\n * import { interval, mergeMap, of, EMPTY } from 'rxjs';\n *\n * const interval$ = interval(1000);\n * const result = interval$.pipe(\n * mergeMap(x => x % 2 === 1 ? of('a', 'b', 'c') : EMPTY),\n * );\n * result.subscribe(x => console.log(x));\n *\n * // Results in the following to the console:\n * // x is equal to the count on the interval, e.g. (0, 1, 2, 3, ...)\n * // x will occur every 1000ms\n * // if x % 2 is equal to 1, print a, b, c (each on its own)\n * // if x % 2 is not equal to 1, nothing will be output\n * ```\n *\n * @see {@link Observable}\n * @see {@link NEVER}\n * @see {@link of}\n * @see {@link throwError}\n */\nexport const EMPTY = new Observable((subscriber) => subscriber.complete());\n\n/**\n * @param scheduler A {@link SchedulerLike} to use for scheduling\n * the emission of the complete notification.\n * @deprecated Replaced with the {@link EMPTY} constant or {@link scheduled} (e.g. `scheduled([], scheduler)`). Will be removed in v8.\n */\nexport function empty(scheduler?: SchedulerLike) {\n return scheduler ? emptyScheduled(scheduler) : EMPTY;\n}\n\nfunction emptyScheduled(scheduler: SchedulerLike) {\n return new Observable((subscriber) => scheduler.schedule(() => subscriber.complete()));\n}\n", "import { SchedulerLike } from '../types';\nimport { isFunction } from './isFunction';\n\nexport function isScheduler(value: any): value is SchedulerLike {\n return value && isFunction(value.schedule);\n}\n", "import { SchedulerLike } from '../types';\nimport { isFunction } from './isFunction';\nimport { isScheduler } from './isScheduler';\n\nfunction last(arr: T[]): T | undefined {\n return arr[arr.length - 1];\n}\n\nexport function popResultSelector(args: any[]): ((...args: unknown[]) => unknown) | undefined {\n return isFunction(last(args)) ? args.pop() : undefined;\n}\n\nexport function popScheduler(args: any[]): SchedulerLike | undefined {\n return isScheduler(last(args)) ? args.pop() : undefined;\n}\n\nexport function popNumber(args: any[], defaultValue: number): number {\n return typeof last(args) === 'number' ? args.pop()! : defaultValue;\n}\n", "export const isArrayLike = ((x: any): x is ArrayLike => x && typeof x.length === 'number' && typeof x !== 'function');", "import { isFunction } from \"./isFunction\";\n\n/**\n * Tests to see if the object is \"thennable\".\n * @param value the object to test\n */\nexport function isPromise(value: any): value is PromiseLike {\n return isFunction(value?.then);\n}\n", "import { InteropObservable } from '../types';\nimport { observable as Symbol_observable } from '../symbol/observable';\nimport { isFunction } from './isFunction';\n\n/** Identifies an input as being Observable (but not necessary an Rx Observable) */\nexport function isInteropObservable(input: any): input is InteropObservable {\n return isFunction(input[Symbol_observable]);\n}\n", "import { isFunction } from './isFunction';\n\nexport function isAsyncIterable(obj: any): obj is AsyncIterable {\n return Symbol.asyncIterator && isFunction(obj?.[Symbol.asyncIterator]);\n}\n", "/**\n * Creates the TypeError to throw if an invalid object is passed to `from` or `scheduled`.\n * @param input The object that was passed.\n */\nexport function createInvalidObservableTypeError(input: any) {\n // TODO: We should create error codes that can be looked up, so this can be less verbose.\n return new TypeError(\n `You provided ${\n input !== null && typeof input === 'object' ? 'an invalid object' : `'${input}'`\n } where a stream was expected. You can provide an Observable, Promise, ReadableStream, Array, AsyncIterable, or Iterable.`\n );\n}\n", "export function getSymbolIterator(): symbol {\n if (typeof Symbol !== 'function' || !Symbol.iterator) {\n return '@@iterator' as any;\n }\n\n return Symbol.iterator;\n}\n\nexport const iterator = getSymbolIterator();\n", "import { iterator as Symbol_iterator } from '../symbol/iterator';\nimport { isFunction } from './isFunction';\n\n/** Identifies an input as being an Iterable */\nexport function isIterable(input: any): input is Iterable {\n return isFunction(input?.[Symbol_iterator]);\n}\n", "import { ReadableStreamLike } from '../types';\nimport { isFunction } from './isFunction';\n\nexport async function* readableStreamLikeToAsyncGenerator(readableStream: ReadableStreamLike): AsyncGenerator {\n const reader = readableStream.getReader();\n try {\n while (true) {\n const { value, done } = await reader.read();\n if (done) {\n return;\n }\n yield value!;\n }\n } finally {\n reader.releaseLock();\n }\n}\n\nexport function isReadableStreamLike(obj: any): obj is ReadableStreamLike {\n // We don't want to use instanceof checks because they would return\n // false for instances from another Realm, like an

+ +
+
+

Unidade 3

+

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/estudos-de-caso/pbb/index.html b/estudos-de-caso/pbb/index.html new file mode 100644 index 0000000..801c016 --- /dev/null +++ b/estudos-de-caso/pbb/index.html @@ -0,0 +1,1631 @@ + + + + + + + + + + + + + + + + + + + + + + + + + Product Backlog Building - Paraizo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

Product Backlog Building (PBB)

+
+Histórico de Revisão + + + + + + + + + + + + + + + + + +
DataVersãoDescriçãoAutor
20/011.0Documentação do PBBPedro Miguel M. de O. dos Santos
+
+

Introdução

+

Marsicano (2024) fala que Product Backlog Building (PBB) um método e um Canvas para +a elaboração e a criação de um Product Backlog. Tem como objetivo ajudar na construção e no refinamento do Product Backlog de forma colaborativa – construindo um entendimento compartilhado e levando todos os envolvidos à compreensão do produto – e na preparação do backlog para o time começar a trabalhar de modo +ágil e eficaz.

+

Estudo de Caso

+

Nesse caso iremos tratar de uma empresa de tecnologia chamada TechFix que opera serviços de reparo de equipamentos para clientes corporativos e deseja facilitar o agendamento e o acompanhamento dos serviços.

+

Resolução

+
+ +
+

Product Backlog Building - TechFix

+
+
+

Fonte: Erick Miranda Santos, Maykon Júnio dos Santos Soares, Marllon Fausto Cardoso, Pedro Miguel M. de O. dos Santos e Henrique Martins Alencar

+

Backlog produzido

+

Vale lembrar que cada PBI gerou uma história de usuário numa regra de 1 por 1.

+

Tabela 1 - Backlog feito com base nos PBIs

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
História de UsuárioÉpico
US01Eu, como técnico, desejo realizar agendamento de serviço para centralizar agendamentosGerenciar solicitações e agendamentos dos clientes
US02Eu, como técnico, desejo editar agendamento de serviço para manter os dados atualizados da agendaGerenciar solicitações e agendamentos dos clientes
US03Eu, como técnico, desejo confirmar ou recusar solicitação de serviço para repassar a agenda aos clientes rapidamenteGerenciar solicitações e agendamentos dos clientes
US04Eu, como técnico, desejo acessar meus agendamentos para manter uma agenda únicaGerenciar solicitações e agendamentos dos clientes
US05Eu, como técnico, desejo cadastrar cliente para manter seus dados centralizadosGerenciar solicitações e agendamentos dos clientes
US06Eu, como técnico, desejo editar cliente para manter seus dados atualizadosGerenciar solicitações e agendamentos dos clientes
US07Eu, como técnico, desejo excluir cliente para manter a base de dados atualizadaGerenciar solicitações e agendamentos dos clientes
US08Eu, como técnico, desejo enviar mensagem para o cliente a fim de tratar sobre o serviçoGerenciar solicitações e agendamentos dos clientes
US09Eu, como atendente, desejo cadastrar informações do equipamento para conseguir acessá-los depoisReparo de equipamentos
US10Eu, como atendente, registrar resultado do atendimento para averiguar o desempenho geralReparo de equipamentos
US11Eu, como atendente, registrar recursos utilizados para a realização do atendimento a fim de obter histórico dos recursosReparo de equipamentos
US12Eu, como atendente, relatar funcionamento dos recursos usados durante o atendimento a fim de manter o controle dos recursosReparo de equipamentos
US13Eu, como atendente, desejo adicionar informações do cliente a fim de manter a base de dados atualizadaReparo de equipamentos
US14Eu, como atendente, desejo solicitar comentário do cliente sobre atendimento a fim de obter retorno do serviço prestadoReparo de equipamentos
US15Eu, como atendente, desejo relatar comentário sobre atendimento a fim de relatar ocorrênciasReparo de equipamentos
US16Eu, como atendente, desejo gerar agenda com meus serviços para facilitar a execuçãoReparo de equipamentos
US17Eu, como operações, desejo consultar dados de um serviço solicitado para acompanhar o andamentoRelatórios dos serviços
US18Eu, como operações, desejo consultar informações do comentário do cliente para entender seu contextoRelatórios dos serviços
US19Eu, como operações, desejo comparar dados sobre os serviços prestados a fim de propor melhoriasRelatórios dos serviços
US20Eu, como operações, desejo gerar histórico de comentário dos clientes a fim de analisar os serviçosRelatórios dos serviços
US21Eu, como operações, desejo filtrar informações financeiras do estabelecimento por tempo para entender seu impacto na empresaRelatórios dos serviços
US22Eu, como corporativo, desejo solicitar serviço para resolver um problema da diretoriaSolicitação de serviços
US23Eu, como corporativo, desejo editar um serviço solicitado para que atenda realmente o que precisoSolicitação de serviços
US24Eu, como corporativo, desejo cancelar um serviço solicitado para que não atenda sem necessidadeSolicitação de serviços
US25Eu, como corporativo, desejo gerar um histórico dos serviços prestados pelo estabelecimento para verificar todo seu alcanceSolicitação de serviços
US26Eu, como corporativo, desejo listar todas as solicitações realizadas de serviços para acompanhar meus pedidosSolicitação de serviços
US27Eu, como operações, desejo listar as atividades das equipes a fim de acompanhar suas tarefasSupervisão das equipes
US28Eu, como operações, desejo cadastrar atendente ou técnico nas equipes a fim de manter controle sobre suas atividades por equipeSupervisão das equipes
US29Eu, como operações, desejo editar cadastro do atendente ou técnico nas equipes a fim de manter controle sobre suas atividades por equipeSupervisão das equipes
US30Eu, como operações, desejo remover cadastro do atendente ou técnico nas equipes a fim de manter controle sobre suas atividades por equipeSupervisão das equipes
US31Eu, como operações, gerar relatório das atividades por área para acompanhar o andamento em cada setorSupervisão das equipes
US32Eu, como operações, gerar relatório das atividades por equipe para acompanhar o andamento em cada equipeSupervisão das equipes
+

Fonte: Pedro Miguel M. de O. dos Santos

+

Critérios de aceitação

+

Tabela 2 - Critérios de aceitação de 15 USs

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
História de UsuárioCritérios de Aceitação
US01Eu, como técnico, desejo realizar agendamento de serviço para centralizar agendamentos- Selecionar data e horário disponíveis
- Validar conflitos de horários
- Associar cliente ao agendamento
US03Eu, como técnico, desejo confirmar ou recusar solicitação de serviço para repassar a agenda aos clientes rapidamente- Visualizar solicitações pendentes
- Confirmar ou recusar solicitação
- Notificar cliente por e-mail ou SMS
US05Eu, como técnico, desejo cadastrar cliente para manter seus dados centralizados- Cadastrar nome, telefone, e-mail e endereço
- Validar campos obrigatórios
- Impedir cadastro duplicado
US06Eu, como técnico, desejo editar cliente para manter seus dados atualizados- Editar dados do cliente cadastrado
- Validar campos alterados
- Atualizar informações corretamente
US08Eu, como técnico, desejo enviar mensagem para o cliente a fim de tratar sobre o serviço- Selecionar cliente para envio
- Enviar mensagem via e-mail ou SMS
- Armazenar histórico de mensagens
US09Eu, como atendente, desejo cadastrar informações do equipamento para conseguir acessá-los depois- Cadastrar modelo, número de série e descrição
- Validar campos obrigatórios
- Consultar informações cadastradas
US11Eu, como atendente, registrar recursos utilizados para a realização do atendimento- Selecionar recursos utilizados
- Adicionar quantidade utilizada
- Registrar corretamente
US14Eu, como atendente, desejo solicitar comentário do cliente sobre atendimento- Enviar solicitação de feedback
- Cliente pode responder por link
- Armazenar respostas
US17Eu, como operações, desejo consultar dados de um serviço solicitado- Buscar serviço por protocolo ou data
- Exibir status atual
- Mostrar detalhes de técnico e cliente
US19Eu, como operações, desejo comparar dados sobre os serviços prestados- Gerar relatórios comparativos
- Exibir métricas como tempo médio
- Exportar em PDF ou Excel
US22Eu, como corporativo, desejo solicitar serviço para resolver um problema da diretoria- Selecionar tipo de serviço
- Anexar documentos
- Gerar número de protocolo único
US23Eu, como corporativo, desejo editar um serviço solicitado para que atenda realmente o que preciso- Editar detalhes da solicitação
- Alterar data e tipo
- Registrar alterações no histórico
US26Eu, como corporativo, desejo listar todas as solicitações realizadas de serviços- Visualizar todas as solicitações
- Filtrar por data e tipo
- Exportar em PDF ou Excel
US27Eu, como operações, desejo listar as atividades das equipes- Visualizar atividades por equipe e data
- Filtrar por status
- Acessível apenas para usuários autorizados
US30Eu, como operações, desejo remover cadastro do atendente ou técnico nas equipes- Buscar atendente pelo nome ou ID
- Confirmar remoção antes de concluir
- Registrar data e responsável
+

Fonte: Pedro Miguel M. de O. dos Santos

+

BDDs

+

US01 - Eu, como técnico, desejo realizar agendamento de serviço para centralizar agendamentos

+

Cenário: Técnico realiza um novo agendamento com sucesso
+Dado que o técnico está na página de agendamento
+e existem horários disponíveis na agenda
+Quando o técnico seleciona uma data e horário
+e informa os dados do cliente corretamente
+e confirma o agendamento
+Então o agendamento é realizado com sucesso
+e o sistema exibe uma mensagem "Agendamento realizado com sucesso"
+e o agendamento aparece na lista de compromissos do técnico

+

Cenário: Técnico tenta agendar em um horário já ocupado
+Dado que o técnico está na página de agendamento
+e o horário desejado já está ocupado na agenda
+Quando o técnico tenta realizar o agendamento
+Então o agendamento não é realizado
+e o sistema exibe uma mensagem de erro "Horário indisponível"
+e a agenda permanece inalterada

+
+

US09 - Eu, como atendente, desejo cadastrar informações do equipamento para conseguir acessá-los depois

+

Cenário: Atendente cadastra um novo equipamento com sucesso
+Dado que o atendente está na página de cadastro de equipamentos
+e preenche todos os campos obrigatórios corretamente
+Quando confirma o cadastro
+Então o equipamento é salvo no sistema
+e o sistema exibe a mensagem "Equipamento cadastrado com sucesso"
+e o equipamento aparece na lista de equipamentos registrados

+

Cenário: Atendente tenta cadastrar um equipamento sem preencher os campos obrigatórios
+Dado que o atendente está na página de cadastro de equipamentos
+e não preenche todos os campos obrigatórios
+Quando tenta confirmar o cadastro
+Então o cadastro não é realizado
+e o sistema exibe a mensagem de erro "Preencha todos os campos obrigatórios"
+e o equipamento não aparece na lista de equipamentos registrados

+
+

US14 - Eu, como atendente, desejo solicitar comentário do cliente sobre atendimento a fim de obter retorno do serviço prestado

+

Cenário: Envio de solicitação de feedback com sucesso
+Dado que o atendimento foi finalizado
+e o cliente possui um e-mail cadastrado no sistema
+Quando o atendente solicita o feedback
+Então a solicitação de feedback é enviada com sucesso
+e o sistema exibe a mensagem "Solicitação de feedback enviada com sucesso"
+e o cliente recebe um e-mail com o link de feedback

+

Cenário: Cliente tenta enviar feedback sem atendimento finalizado
+Dado que o atendimento ainda não foi finalizado
+Quando o atendente tenta solicitar o feedback
+Então a solicitação não é enviada
+e o sistema exibe a mensagem de erro "Atendimento ainda em andamento"

+
+

US17 - Eu, como operações, desejo consultar dados de um serviço solicitado para acompanhar o andamento

+

Cenário: Consulta de serviço por número de protocolo válido
+Dado que o usuário de operações está na página de consulta de serviços
+e existe um serviço cadastrado com o número de protocolo "12345"
+Quando ele informa o número de protocolo "12345"
+Então o sistema exibe os detalhes do serviço correspondente
+e o status atual do serviço é exibido

+

Cenário: Consulta de serviço por número de protocolo inexistente
+Dado que o usuário de operações está na página de consulta de serviços
+e não existe um serviço com o número de protocolo "99999"
+Quando ele informa o número de protocolo "99999"
+Então o sistema exibe uma mensagem de erro "Serviço não encontrado"
+e nenhum detalhe de serviço é exibido

+
+

US30 - Eu, como operações, desejo remover cadastro do atendente ou técnico nas equipes a fim de manter controle sobre suas atividades por equipe

+

Cenário: Remoção bem-sucedida de técnico
+Dado que o usuário de operações está na página de gerenciamento de equipes
+e o técnico "João Silva" está cadastrado na equipe de manutenção
+Quando o usuário seleciona o técnico "João Silva"
+e confirma a remoção
+Então o sistema remove o técnico da equipe
+e exibe a mensagem "Técnico removido com sucesso"
+e o técnico não aparece mais na lista de equipe

+

Cenário: Tentativa de remoção sem confirmação
+Dado que o usuário de operações está na página de gerenciamento de equipes
+e o técnico "João Silva" está cadastrado na equipe de manutenção
+Quando o usuário seleciona o técnico "João Silva"
+e cancela a remoção
+Então o técnico continua cadastrado na equipe
+e o sistema não exibe mensagens de erro

+

Fonte: Pedro Miguel M. de O. dos Santos

+ + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ +
+ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/estudos-de-caso/usm/index.html b/estudos-de-caso/usm/index.html new file mode 100644 index 0000000..b9bde89 --- /dev/null +++ b/estudos-de-caso/usm/index.html @@ -0,0 +1,2196 @@ + + + + + + + + + + + + + + + + + + + + + + + + + User Story Mapping - Paraizo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

User Story Mapping (USM)

+
+Histórico de Revisão + + + + + + + + + + + + + + + + + +
DataVersãoDescriçãoAutor
20/011.0Criação do tópico de USMHenrique Martins Alencar
+
+

Introdução

+

+A técnica de User Story Mapping é uma abordagem colaborativa e visual para o planejamento e desenvolvimento de produtos, focada em garantir que o trabalho atenda às necessidades dos usuários e alcance os objetivos do negócio. Essa técnica organiza histórias de usuários em um formato de mapa que permite visualizar a jornada do usuário, as funcionalidades principais e as tarefas associadas. Esse mapeamento ajuda equipes a priorizarem entregas incrementais, identificarem lacunas no entendimento do produto e criarem um roadmap mais claro e alinhado às expectativas dos stakeholders.

+ +

Estudo de Caso

+

+Para a realização da tarefa, utilizamos como base a empresa fictícia "EduConnect" que busca transformar a forma como instituições educacionais gerenciam projetos interdisciplinares e atividades extracurriculares. A visão é criar um sistema educacional onde professores alunos e a comunidade escolar possam colaborar efetivamente em projetos que promovam aprendizagem significativa e desenvolvimento de habilidades práticas. O mapa realizado pode ser conferido a seguir: +

+ +
+ +
+

User Story Mapping - EduConnect

+
+
+

Organização

+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
IDDescrição
[PS01]Professor coordenador
[PS02]Professor participante
[PS03]Coordenador pedagógico
[PS04]Pais/Responsáveis
[PS05]Alunos
[PS06]Especialista Externo
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
IDDescriçãoUsuários
[AT01]Organizar evento interdisciplinar[PS01],[PS02],[PS03]
[AT02]Gerir evento interdisciplinar[PS01],[PS02],[PS03]
[AT03]Analisar evento interdisciplinar[PS01],[PS02],[PS03]
[AT04]Acompanhar progresso dos filhos[PS04]
[AT05]Comunicar-se com os professores[PS04]
[AT06]Participar de projetos[PS05]
[AT07]Visualizar materiais e instruções[PS05]
[AT08]Comunicar-se com colegas e professores[PS05]
[AT09]Monitorar projetos e alunos[PS06]
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
IDDescriçãoAtividades
[BB01]Cadastrar novo evento[AT01]
[BB02]Criar planejamento do evento[AT01]
[BB03]Cadastrar encontros importantes do evento[AT01]
[BB04]Divulgar evento[AT01]
[BB05]Realizar/executar evento[AT02]
[BB06]Analisar projetos/atividades dos participantes[AT02]
[BB07]Finalizar evento[AT02]
[BB08]Visualizar resultados do evento[AT03]
[BB10]Visualizar projetos em andamento[AT04]
[BB11]Visualizar atividades dos filhos[AT04]
[BB12]Manter comunicação com professores[AT05]
[BB13]Acompanhar progresso[AT06]
[BB14]Participar de atividades[AT06]
[BB15]Visualizar informações sobre os projetos[AT07]
[BB16]Acessar instruções sobre as ferramentas[AT07]
[BB17]Enviar mensagens[AT08]
[BB18]Acessar projetos e materiais[AT09]
[BB19]Comunicar-se com professores e alunos[AT09]
+
+
+
+

Backlog

+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
IDDescriçãoAtividades
[TA01]Cadastrar informações básicas de um novo evento[BB01]
[TA02]Editar informações básicas de um novo evento[BB01]
[TA03]Cadastrar disciplinas envolvidas no evento[BB01]
[TA04]Editar disciplinas envolvidas no evento[BB01]
[TA05]Informar objetivos e espectativas do evento[BB01]
[TA06]Editar objetivos e espectativas do evento[BB01]
[TA07]Adicionar outros coordenadores ou professor(es) participante(es) no evento[BB01]
[TA08]Editar lista de coordenadores ou professor(es) participante(es) no evento[BB01]
[TA10]Inserir critérios de avaliação para o evento[BB01]
[TA11]Editar critérios de avaliação para o evento[BB01]
[TA13]Definir datas de início e fim do evento[BB02]
[TA14]Edtar datas de início e fim do evento[BB02]
[TA15]Definir data e horários de encontros importantes do evento[BB02]
[TA16]Editar data e horários de encontros importantes do evento[BB02]
[TA17]Inserir data de início e fim para as atividades de organização pré-evento[BB02]
[TA18]Inserir materiais necessários para realização do evento[BB02]
[TA19]Excluir materiais necessários para realização do evento[BB02]
[TA20]Editar lista de materiais necessários para realização do evento[BB02]
[TA21]Cadastrar encontros importantes[BB02]
[TA22]Editar encontros importantes[BB02]
[TA23]Excluir encontros importantes[BB02]
[TA25]Adicionar descrição do encontro[BB03]
[TA26]Editar descrição do encontro[BB03]
[TA27]Adicionar roteiro para o encontro[BB03]
[TA28]Editar roteiro do encontro[BB03]
[TA29]Adicionar materiais necessários para realização do encontro[BB03]
[TA30]Editar lista de materiais necessários para realização do encontro[BB03]
[TA31]Adicionar outros membros para ajudar na organização do encontro[BB03]
[TA32]Editar lista de membros para ajudar na organização do encontro[BB03]
[TA33]Adicionar materiais dos professores e/ou Especialistas Externos[BB03]
[TA34]Editar materiais dos professores e/ou Especialistas Externos[BB03]
[TA35]Adicionar descrição de projetos e/ou atividades a serem feitas pelos participantes[BB03]
[TA36]Editar descrição de projetos e/ou atividades a serem feitas pelos participantes[BB03]
[TA37]Cadastrar atividades para serem realizadas[BB03]
[TA38]Editar atividades para serem realizadas[BB03]
[TA39]Excluir atividades para serem realizadas[BB03]
[TA40]Inserir um ou mais responsáveis para cada atividade do encontro[BB03]
[TA41]Inserir campo para postágem dos entregáveis do encontro por parte dos participantes[BB03]
[TA44]Inserir texto para divulgação do evento para participantes e seus responsáveis[BB04]
[TA45]Editar texto para divulgação do evento para participantes e seus responsáveis[BB04]
[TA46]Inserir texto com os profissionais que participarão do evento[BB04]
[TA47]Editar texto com os profissionais que participarão do evento[BB04]
[TA48]Inserir imagens e/ou vídeos de divulgação do evento[BB04]
[TA49]Editar imagens e/ou vídeos de divulgação do evento[BB04]
[TA50]Excluir imagens e/ou vídeos de divulgação do evento[BB04]
[TA51]Adicionar participantes do evento manualmente[BB04]
[TA52]Editar lista de participantes do evento manualmente[BB04]
[TA53]Retirar um membro da lista de participantes do evento manualmente[BB04]
[TA54]Criar formulário para inscrição no evento[BB04]
[TA55]Gerar link de compartilhamento do formulário de inscrição[BB04]
[TA56]Visualizar programação dos encontros importantes[BB05]
[TA57]Enviar mensagem a outro colaborador[BB05]
[TA58]Visualizar mensagens enviadas por outro colaborador ou grupo[BB05]
[TA59]Criar chat de mensagens de texto com outros dois ou mais colaboradores[BB05]
[TA60]Adicionar ou excluir outros colabores do chat de mensagens de texto[BB05]
[TA61]Editar informações dos encontros importantes do evento[BB05]
[TA62]Marcar encontro importante como concluido[BB05]
[TA63]Marcar atividades de um encontro importante como concluida[BB05]
[TA64]Registrar texto sobre o andamento de uma atividade do encontro[BB05]
[TA65]Editar lista de mateirais envolvidos na realização da atividade do encontro[BB05]
[TA66]Enviar mensagens de textos para pais ou responsáveis[BB05]
[TA67]Visualizar mensagens enviadas por pais ou responsáveis[BB05]
[TA68]Criar chat de mensagens de texto com outros dois ou mais pais ou responsáveis[BB05]
[TA69]Adicionar ou excluir outros pais ou responsáveis do chat de mensagens de texto[BB05]
[TA70]Criar grupos de participantes para realização de atividades[BB05]
[TA71]Editar grupos de participantes para realização de atividades[BB05]
[TA72]Adicionar texto sobre os resultados do encontro[BB05]
[TA73]Adicionar texto sobre os resultados do evento[BB05]
[TA78]Visualizar arquivos enviados pelos participantes ou por grupos de participantes[BB06]
[TA79]Enviar feedback em texto para os participantes ou por grupos de participantes[BB06]
[TA80]Compartilhar feedback das atividades para os pais ou responsáveis[BB06]
[TA81]Marcar evento como concluido[BB07]
[TA82]Relatar feedback final sobre o evento em texto[BB07]
[TA83]Divulgar texto, imagens e/ou vídeos de finalização do evento para os colaboradores[BB07]
[TA84]Divulgar texto, imagens e/ou vídeos de finalização do evento para os participantes[BB07]
[TA85]Divulgar texto, imagens e/ou vídeos de finalização do evento para os pais ou responsáveis[BB07]
[TA86]Visualizar lista de participantes do evento[BB08]
[TA87]Visualizar relatórios de todas as atividades do evento[BB08]
[TA88]Visualizar informações gerais do evento[BB08]
[TA89]Visualizar todos os feedbacks do evento[BB08]
[TA90]Excluir evento da lista de eventos realizados[BB08]
[TA91]Visualizar informações e detalhes do projeto[BB09]
[TA92]Receber notificações sobre projetos e eventos[BB09]
[TA93]Acessar materiais relacionados ao projeto[BB09]
[TA94]Visualizar relatórios sobre desempenho dos filhos[BB10]
[TA95]Visualizar participação dos filhos em atividades[BB10]
[TA96]Receber notificações sobre o desempenho dos filhos[BB11]
[TA97]Enviar mensagens diretas para os professores[BB11]
[TA98]Receber mensagens diretas de professores[BB12]
[TA99]Agendar reuniões com professores[BB12]
[TA100]Fornecer feedbacks sobre os projetos[BB12]
[TA101]Participar de reuniões[BB12]
[TA102]Visualizar relatórios sobre desempenho e notas[BB12]
[TA103]Visualizar participações (entregas e atividades realizadas)[BB13]
[TA104]Visualizar atividades pendentes[BB13]
[TA105]Receber notificações sobre o projeto[BB13]
[TA106]Visualizar feedbacks recebidos[BB13]
[TA107]Enviar atividades (pesquisas, trabalhos)[BB13]
[TA108]Editar envio de atividades[BB14]
[TA109]Participar de reuniões e debates[BB14]
[TA110]Participar de grupos de trabalho[BB14]
[TA111]Visualizar informações detalhadas do projeto[BB14]
[TA112]Visualizar prazos e cronograma[BB15]
[TA113]Visualizar materiais relacionados[BB15]
[TA114]Acessar tutoriais de uso da plataforma[BB15]
[TA115]Visualizar recomendações sobre ferramentas relacionadas[BB16]
[TA116]Enviar mensagens diretas para os professores[BB16]
[TA117]Receber mensagens diretas dos professores[BB17]
[TA118]Enviar mensagens diretas para os colegas[BB17]
[TA119]Receber mensagens diretas dos colegas[BB17]
[TA120]Enviar mensagens diretas para os grupos de trabalho[BB17]
[TA121]Receber mensagens diretas dos grupos de trabalho[BB17]
[TA122]Acessar materiais do projeto[BB18]
[TA123]Compartilhar materiais com alunos e professores[BB18]
[TA124]Visualizar detalhes sobre o projeto[BB18]
[TA125]Visualizar relatórios gerais sobre o andamento do projeto[BB18]
[TA126]Fornecer feedbacks sobre o andamento do projeto[BB19]
[TA127]Agendar reuniões e eventos[BB19]
[TA128]Participar de reuniões e eventos[BB19]
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
IDDescriçãoAtividades
[TA12]Inserir metas de porcentágem de parcitipantes ativos e atividades entregues[BB01]
[TA24]Inserir gasto previsto para realização do evento[BB02]
[TA42]Inserir gasto previsto para realização do encontro[BB03]
[TA43]Inserir gasto previsto para realização das atividades do encontro[BB03]
[TA74]Visualizar poncentágem de participantes que participaram do encontro[BB05]
[TA75]Inserir informações de gasto real com as atividades do encontro[BB05]
[TA76]Inserir informações de gasto real com todo o encontro[BB05]
[TA129]Visualizar poncentágem de participantes que realizaram a entrega[BB06]
[TA130]Visualizar comparação entre as porcentágens de participantes ativos e atividades entregues com suas respectivas metas[BB07]
[TA131]Visualizar comparação entre gastos previstos e gastos reais de todo o evento[BB07]
[TA132]Visualizar informações sobre todos os gastos reais do evento[BB07]
[TA133]Filtrar informações sobre todos os gastos reais do evento por encontro[BB07]
[TA134]Filtrar informações sobre todos os gastos reais do evento por data[BB07]
[TA135]Filtrar informações sobre todos os gastos reais do evento por colaboradores[BB07]
[TA136]Visualizar informações sobre gastos do evento[BB08]
+
+
+
+

Critérios de Aceitação

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Tarefa do usuárioCritérios de Aceitação
[TA13]O sistema deve emitir um alerta caso o usuário tente inserir uma data anterior ao dia em que está realizando essa atividade; O sistema deve mostrar ao usuário a duração, em dias, do evento ao ser informado as datas de início e fim do mesmo; O sistema deve impedir que o usuário defina uma data que seja um feriado ou ponto facultativo; O sistema deve impedir que o usuário defina uma data que ocorra concomitante à outro evento com mesma equipe de coordenadores;
[TA17]O sistema deve impedir que o usuário defina uma data fora o período de duração do evento; O sistema deve emitir um alerta caso o usuário tente inserir uma data anterior ao dia em que está realizando essa atividade;
[TA21]O sistema deve impedir que o usuário tente cadastrar o encontro caso não tenha inserido as informações obrigatórias; O sistema deve permitir que o usuário cadastre um novo encontro importante se, e somente se, ele inserir as seguintes informações: Data, horário, descrição, lista de organizadores e lista de materiais; O sistema deve impedir que usuário que não sejam da equipe de coordenadores tentem cadastrar um encontro importante;
[TA31]O sistema deve impedir que o usuário tente adicionar um membro que não esteja na equipe do evento; O sistema deve impedir que o usuário tente adicionar um membro que já esteja presente em outra equipe de um encontro importante que ocorrerá na mesma data e horário; O sistema deve impedir que o usuário tente adicionar um membro já presente na lista.
[TA48]O sistema deve impedir que o usuário tente adicionar imagens que não sejam de extensões .png e .jpeg; O sistema deve impedir que o usuário tente inserir uma imagem que exceda o tamanho de 5mb; O sistema deve impedir que o usuário tente inserir um vídeo que não seja de extensão .mp4; O sistema deve impedir que o usuário tente inserir um vídeo que exceda o tamanho de 100mb;
[TA56]O sistema deve permitir que o usuário visualize todas as informações do encontro em uma só interface; O sistema deve apresentar um design de interface responsivo, permitindo que todas as informações sejam visíveis para qualquer tamanho de tela.
[TA77]O sistema deve permitir que o usuário visualize os arquivos enviados pelos participantes dentro do próprio sistema; O sistema deve permitir que o usuário exporte os arquivos enviados pelos participantes para seu próprio computador.
[TA91]- O sistema deve exibir informações detalhadas sobre cada projeto.
- Os pais devem poder acessar essas informações de forma intuitiva no painel.
[TA92]- Notificações devem ser enviadas por e-mail e/ou aplicativo.
- As notificações devem conter informações claras sobre datas e objetivos.
[TA94]- Relatórios devem apresentar gráficos e dados quantitativos.
- Deve haver a opção de baixar os relatórios em PDF.
[TA95]- O sistema deve exibir uma lista de atividades realizadas pelos filhos.
- Deve incluir datas e observações sobre a participação.
[TA108]- O sistema deve permitir envio de mensagens via chat.
- As mensagens devem ser recebidas pelo professor em tempo real.
[TA97]- Alunos devem ser notificados ao receber uma mensagem.
- O sistema deve permitir responder diretamente à mensagem.
[TA103]- O painel do aluno deve exibir todas as entregas realizadas com status (ex.: "Entregue", "Pendente").
- Deve ser possível filtrar atividades por período ou tipo.
[TA105]- Alunos devem ser notificados sobre alterações de prazos ou adição de novas tarefas.
- Notificações devem incluir links diretos para as atividades afetadas.
+ + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ +
+ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..1d8b9fc --- /dev/null +++ b/index.html @@ -0,0 +1,1241 @@ + + + + + + + + + + + + + + + + + + + + + + + + + Home - Paraizo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + + + + + + + + + + + + + Solid Template + + + + + + + +
+
+
+
+
+
+

Equipe Torcicolo

+

Um time de desenvolvedores multidisciplinares da Universidade de + Brasília.

+ +
+
+ + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+ Feature 01 +
+

CI/CD

+

CI/CD preenche as lacunas entre as atividades e equipes de + desenvolvimento e operação, reforçando a automação na compilação, teste e + implantação de aplicativos.

+
+
+
+
+
+ Feature 02 +
+

DevOps

+

DevOps é a união de pessoas, processos e tecnologias para + fornecer continuamente valor aos clientes.

+
+
+
+
+
+ Feature 03 +
+

Automação

+

Automação é a aplicação de tecnologia, programas, robótica + ou processos para alcançar resultados com o mínimo de input humano.

+
+
+
+
+
+
+ +
+
+
+
+

Nosso Time

+

+ Dedique-se as grandes ideias, deixe conosco o trabalho de torna-las possível. +

+
+
+
+
+
+
+ +
+

Maykon Júnio dos Santos Soares

+

Líder

+
+
+
+
+
+ +
+

Erick Miranda Santos

+

Desenvolvedor

+
+
+
+
+
+ +
+

Marllon Fausto Cardoso

+

Desenvolvedor

+
+
+
+
+
+ +
+

Henrique Martins Alencar

+

Desenvolvedor

+
+
+
+
+
+ +
+

Pedro Miguel Martins de Oliveira dos Santos

+

Desenvolvedor

+
+
+
+
+
+
+
+ + +
+
+ + + + + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ +
+
+ + + + + +
+ + + +
+ +
+
+
+
+ +
+ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/iteracoes/index.html b/iteracoes/index.html new file mode 100644 index 0000000..dc6dbcd --- /dev/null +++ b/iteracoes/index.html @@ -0,0 +1,2334 @@ + + + + + + + + + + + + + + + + + + + + + + + + + Iterações - Paraizo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

Iterações

+
+Histórico de Revisão + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DataVersãoDescriçãoAutor
08/111.0Criação das seção de Processo de desenvolvimento de softwareErick Miranda Santos
Maykon Júnio dos Santos Soares
Marllon Fausto Cardoso
10/111.1Adicionando informações sobre iteração 01Erick Miranda Santos
14/111.2Adicionando informações sobre iteração 02Maykon Júnio dos Santos Soares
23/111.3Adicionando informações sobre iteração 02Maykon Júnio dos Santos Soares
06/121.4Adicionando informações sobre iteração 03Maykon Júnio dos Santos Soares
13/121.4Adicionando informações sobre iteração 03Maykon Júnio dos Santos Soares
+
+
+
+
+
+

Iteração 0

+
+

📅 Período

+
+

data: 22/10/2023 - 04/11/2023

+
+
+

🔑 Principais Decisões

+
+

Primeiros passos

+

Durante esta Iteração, o grupo tomou decisões cruciais para o início do projeto, estabelecendo as bases para o desenvolvimento e organização.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
DecisãoDescrição
Primeira ReuniãoRealizada para alinhar objetivos e expectativas do time.
Tecnologias DefinidasEscolha das tecnologias a serem utilizadas no projeto, levando em conta os requisitos e a escalabilidade.
Distribuição de PapéisDefinição de responsabilidades para cada membro do time, promovendo eficiência no desenvolvimento.
Uso do MiroDecisão de utilizar o Miro como ferramenta para organização visual das tarefas e brainstorming colaborativo.
+
+

🎯 Entregas Realizadas

+
+

Boas decisões

+

As entregas desta Iteração garantiram o início sólido do projeto, com definições importantes e progresso substancial nas primeiras atividades.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
EntregaDescrição
Definição do ProdutoEstabelecimento do conceito e do objetivo principal do produto.
Definição do ProblemaIdentificação e definição clara do problema a ser solucionado pelo produto.
Início do GitPagesCriação do repositório GitPages para o gerenciamento do projeto e versionamento do conteúdo.
Conclusão da Ideia do ProdutoA ideia do produto foi discutida e fechada, com um consenso sobre a proposta final.
Visão de Produto e ProjetoDocumentação da visão do produto e definição do escopo do projeto, com objetivos e metas claros.
Processo de Desenvolvimento de SoftwareDefinição do processo e metodologia de desenvolvimento a ser seguido durante o projeto.
+
+

🧐 Iteração Retrospective

+
+

Ponto de reflexão

+

A retrospectiva foi realizada para refletir sobre os pontos fortes e áreas de melhoria da Iteração, promovendo aprendizado contínuo.

+
+
    +
  • Tópicos discutidos: Durante a retrospectiva, foram abordados os desafios encontrados e os processos que funcionaram bem.
  • +
  • Conclusão: Todas as entregas foram realizadas dentro do prazo, e o time expressou satisfação com o andamento do projeto, com sugestões de melhorias para a próxima Iteração.
  • +
+
+

🏆 Conquistas da Iteração

+
+

Vale comemorar

+
    +
  • Entregas dentro do prazo.
  • +
  • Ajustes realizados conforme feedback.
  • +
  • Equipe alinhada e motivada para as próximas fases.
  • +
+
+
+

📌 Próximos Passos

+
+

Foco na execução da próxima Iteração com a continuidade das entregas e integração das tecnologias escolhidas.

+
+
+

🤝 Reuniões

+
+
+
+

Conversa Inicial com Cliente

+
+

Detalhes do Encontro

+
    +
  • +

    Data: 02/11/2024

    +
  • +
  • +

    Horário: 08:00

    +
  • +
  • +

    Modalidade: Videoconferência (Teams)

    +
  • +
  • +

    Participantes: Equipe e Cliente

    +
  • +
+
+
+

Propósito

+

Esta reunião inicial teve como objetivo alinhar expectativas e definir as bases de colaboração para o projeto Paraizo. Foram discutidas as principais entregas, o escopo e o papel de cada Integrante, além dos próximos passos para o desenvolvimento do MVP.

+
+Gravação da Reunião +

+
+
+

Principais Tópicos

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
#Tópico
1Apresentação dos membros da equipe
2Contextualização da disciplina e entendimento do propósito do projeto
3Definição de ferramenta de comunicação da equipe
4Definição de ferramenta organizacional da equipe
5Definição e esclarecimento sobre o escopo do MVP 1
6Definição e esclarecimento sobre o escopo do MVP 2
+
+

Decisões Críticas

+
+

Atenção

+

Durante a reunião, foram tomadas as seguintes decisões que impactam o andamento e a comunicação do projeto:

+
    +
  • Escopo inicial do projeto
  • +
  • Definido que reuniões com cliente serão a cada 2 semanas sabádo 08 horas
  • +
  • Definido ferramenta para Reuniões sendo o Temas
  • +
  • Definido ferramenta organizacional sendo o Figma
  • +
+
+
+

Observações Adicionais

+
+

Atenção

+

Nota: Nem todos os membros da equipe puderam estar presentes.

+
+
+
+

Planejamento de Entrega da Unidade

+
+

Detalhes do Encontro

+
    +
  • +

    Data: 05/11/2024

    +
  • +
  • +

    Horário: 20:00

    +
  • +
  • +

    Modalidade: Videoconferência (Teams)

    +
  • +
  • +

    Participantes: Equipe

    +
  • +
+
+
+

Propósito

+

Essa reunião teve como premissa a divisão de atividades presentes na entrega da Unidade 1, bem como a definição de prazos. Dessa maneira a reunião buscou revisar tudo que já tinha sido até o momento, tópicos 1, 2 e 3. E também estabelecer os prazos para a construção dos tópicos 4 e 5.

+
+Gravação da Reunião +

+
+
+

Principais Tópicos

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
#Tópico
1Revisão de documentação anterior
2Transferência de documentação do google docs para o gitpages
3Definição de Tecnologias a serem utilizadas
4Definição de papeis dentro da equipe
5Definição de prazos para entregas dos tópicos 4 e 5
6Bate papo inicial sobre escolha de processo processo de desenvolvimento
+
+

Decisões Críticas

+
+

Atenção

+

Durante a reunião, foram tomadas as seguintes decisões que impactam o andamento do projeto:

+
    +
  • Definido o dia 10/11/2024 como dia limite para inclusão dos tópicos 4 e 5
  • +
  • Definido as tecnologias para desevolvimento e comunicação bem como suas versões
  • +
  • Definido os papeis dentro da equipe
  • +
+
+
+

Observações Adicionais

+
+

Atenção

+

Nota: Nem todos os membros da equipe puderam estar presentes.

+
+
+
+

Atualização sobre entrega da Unidade

+
+

Detalhes do Encontro

+
    +
  • +

    Data: 10/11/2024

    +
  • +
  • +

    Horário: 14:00

    +
  • +
  • +

    Modalidade: Videoconferência (Teams)

    +
  • +
  • +

    Participantes: Equipe

    +
  • +
+
+
+

Propósito

+

A reunião em questão teve o objetivo de listar todos os tópicos desenvolvidos até o momento e checar seus prazos para conclusão. Além disso foi definido o tipo de processo de desenvolvimento de software e a metodologia.

+
+Gravação da Reunião +

+
+
+

Principais Tópicos

+ + + + + + + + + + + + + + + + + + + + + + + + + +
#Tópico
1Revisão de documentação já criada
2Finalização da transferência de documentação do google docs para o gitpages
3Definição de Abordagem, Ciclo de Vida e Processo de Desenvolvimento
4Definição do dia para a gravação do vídeo de entrega da unidade
+
+

Decisões Críticas

+
+

Atenção

+

Durante a reunião, foram tomadas as seguintes decisões que impactam o andamento projeto:

+
    +
  • Definição da abordagem sendo agil, o ciclo de vida sendo RAD e o processo de Desenvolvimento sendo dual
  • +
  • Definido o dia 11/11 como dia limite para a gravação do vídeo de entrega unidade e a finalização de todas as alterações para a entrega da Unidade 1
  • +
+
+
+

Observações Adicionais

+
+

Atenção

+

Nota: Sem notas adicionais.

+
+
+
+
+
+
+

Iteração 1

+
+

📅 Período

+
+

Data: 05/11/2023 - 18/11/2023

+
+
+

🔑 Principais Decisões

+
+

Primeiros passos

+

Durante esta Iteração, o grupo buscou estabelecer uma primeira relação com os requisitos e corrigir alguns débitos da iteração anterior, como ajustes na visão do produto, refinamento do projeto e pequenos ajustes operacionais.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
DecisãoDescrição
Escopo inicial de requisitosA equipe se reuniu para identificar, nos documentos disponíveis, oportunidades para definição de requisitos.
Definição de escopo para MVP1Com base na primeira versão dos requisitos, foi determinado o que poderia compor o MVP1.
Conversa com cliente para alinhar expectativasApós a proposta inicial do escopo, a equipe reuniu-se com o cliente para ajustar a lista de requisitos.
Priorização de MVP1Realizada a primeira priorização do escopo definido para o MVP1, considerando os interesses da equipe e do cliente.
+
+

🎯 Entregas Realizadas

+
+

Boas decisões

+

As entregas da Iteração 1 garantiram um bom início para a criação e priorização do backlog, fortalecendo o alinhamento com o cliente.

+
+ + + + + + + + + + + + + + + + + + + + + +
EntregaDescrição
Primeira lista de requisitosEstabelecimento de uma lista básica de requisitos.
Definição inicial de escopo para MVP1Identificação do escopo inicial para o MVP1, alinhado com os objetivos da equipe e do cliente.
Definição inicial de priorizaçãoPriorização inicial do MVP1 baseada nos interesses do cliente e da equipe.
+
+

🧐 Retrospectiva da Iteração

+
+

Ponto de reflexão

+

A retrospectiva foi realizada para avaliar os pontos fortes e as áreas de melhoria, promovendo aprendizado contínuo.

+
+
    +
  • Tópicos discutidos: Durante a retrospectiva, foram analisadas oportunidades de melhoria para as próximas entregas.
  • +
  • Conclusão: Todas as entregas foram realizadas dentro do prazo, mas foi identificado que uma melhor comunicação interna poderia trazer maior harmonia à equipe.
  • +
+
+

🏆 Conquistas da Iteração

+
+

Vale comemorar

+
    +
  • Entregas realizadas dentro do prazo.
  • +
  • Ajustes implementados conforme o feedback do cliente.
  • +
+
+
+

📌 Próximos Passos

+
+

O foco será a definição do escopo para o MVP2 e a priorização inicial de suas entregas.

+
+
+

🤝 Reuniões

+
+
+
+
+
+

Alinhamento interno da equipe

+
+

Detalhes do Encontro

+
    +
  • Data: 13/11/2024
  • +
  • Horário: 08:00
  • +
  • Modalidade: Videoconferência (Teams)
  • +
  • Participantes: Equipe
  • +
+
+
+

Propósito

+

Esta reunião teve como objetivo elicitar uma primeira versão do backlog.

+
+Gravação da Reunião +

A reunião não foi gravada.

+
+
+

Principais Tópicos

+ + + + + + + + + + + + + + + + + + + + + +
#Tópico
1Busca de documentos relevantes.
2Alinhamento sobre as entregas planejadas.
3Divisão de tarefas entre os membros.
+
+

Decisões Críticas

+
+

Atenção

+

Durante a reunião, foram tomadas decisões importantes para o andamento e comunicação do projeto:

+
    +
  • Determinação dos documentos que serviriam como base.
  • +
  • Alinhamento sobre as datas limites das entregas.
  • +
  • Definição das tarefas para a entrega da lista inicial de requisitos.
  • +
+
+
+

Observações Adicionais

+
+

Atenção

+

Nota: Nem todos os membros da equipe puderam estar presentes.

+
+
+
+

Iteração 2

+
+

📅 Período

+
+

Data: 19/11/2024 - 02/12/2024

+
+
+

🔑 Principais Decisões

+
+

Avanço nos requisitos

+

Durante esta Iteração, a equipe focou no levantamento inicial e na análise detalhada dos requisitos, além de avançar na priorização e estruturação de um backlog inicial.

+
+ + + + + + + + + + + + + + + + + + + + + +
DecisãoDescrição
Planejamento dos RequisitosFoi realizada a análise inicial dos requisitos levantados na Iteração anterior, ajustando e refinando detalhes técnicos e funcionais.
Priorização inicial de requisitosCom base nos requisitos identificados, a equipe definiu prioridades para orientar o planejamento do projeto.
Levantamento de backlog inicialA partir das prioridades estabelecidas, foi estruturado um backlog inicial, alinhado às entregas futuras.
+
+

🎯 Entregas Realizadas

+
+

Evolução contínua

+

As entregas desta Iteração consolidaram a base para um planejamento mais claro e direcionado, garantindo avanços no desenvolvimento do projeto.

+
+ + + + + + + + + + + + + + + + + + + + + +
EntregaDescrição
Levantamento inicial de requisitosIdentificação e análise de requisitos detalhados para direcionar as próximas etapas do projeto.
Priorização inicial de backlogEstabelecimento de uma lista de prioridades com base nos objetivos do cliente e da equipe.
Backlog inicial estruturadoCriação de um backlog contendo as principais tarefas e entregas para nortear o desenvolvimento.
+
+

🧐 Retrospectiva da Iteração

+
+

Ponto de reflexão

+

A retrospectiva da Iteração 2 destacou os avanços obtidos e os desafios enfrentados na análise e priorização de requisitos.

+
+
    +
  • Tópicos discutidos: Melhorias no processo de levantamento e priorização de requisitos, além da necessidade de maior clareza na documentação.
  • +
  • Conclusão: Apesar do progresso significativo, foi identificado que uma melhor organização das reuniões e registros poderia acelerar o processo de planejamento.
  • +
+
+

🏆 Conquistas da Iteração

+
+

Vale comemorar

+
    +
  • Backlog inicial estruturado com sucesso.
  • +
  • Análise inicial de requisitos concluída dentro do prazo.
  • +
  • Consolidação do escopo para as próximas iterações.
  • +
+
+
+

📌 Próximos Passos

+
+

Trabalhar no detalhamento do backlog inicial, refinando os requisitos e começando a planejar a implementação do MVP2.

+
+
+

🤝 Reuniões

+
+
+
+
+
+

Planejamento de requisitos e alinhamento inicial

+
+

Detalhes do Encontro

+
    +
  • Data: 23/11/2024
  • +
  • Horário: 09:00
  • +
  • Modalidade: Videoconferência (Teams)
  • +
  • Participantes: Equipe
  • +
+
+
+

Propósito

+

Esta reunião teve como objetivo revisar os requisitos levantados e iniciar a priorização e estruturação do backlog.

+
+Gravação da Reunião +

A reunião não foi gravada.

+
+
+

Principais Tópicos

+ + + + + + + + + + + + + + + + + + + + + +
#Tópico
1Revisão dos requisitos levantados na Iteração 1.
2Priorização inicial de requisitos e tarefas.
3Estruturação do backlog inicial.
+
+

Decisões Críticas

+
+

Atenção

+

Durante a reunião, foram tomadas decisões importantes para o planejamento do projeto:

+
    +
  • Ajustes nos requisitos levantados anteriormente.
  • +
  • Priorização de funcionalidades e tarefas.
  • +
  • Definição das entregas prioritárias para o MVP2.
  • +
+
+
+

Observações Adicionais

+
+

Atenção

+

Nota: Nem todos os requisitos foram completamente detalhados durante a Iteração, sendo necessário complementar nas próximas reuniões.

+
+
+
+

Iteração 3

+
+

📅 Período

+
+

Data: 03/12/2024 - 16/12/2024

+
+
+

🔑 Principais Decisões

+
+

Avanços no planejamento

+

Durante esta Iteração, a equipe focou no refinamento do backlog, priorização das tarefas e na definição de critérios essenciais para garantir a entrega de valor contínuo.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
DecisãoDescrição
Refinamento e priorização de backlogA equipe revisou e detalhou o backlog existente, definindo as tarefas e funcionalidades essenciais para os MVPs.
Definição de DoR (Definition of Ready)Estabelecimento de critérios claros para garantir que as tarefas estejam prontas para desenvolvimento.
Definição de DoD (Definition of Done)Definição dos critérios de conclusão das tarefas para garantir entregas de alta qualidade.
Definição de critérios de aceitaçãoA equipe detalhou os critérios específicos de aceitação para cada funcionalidade do backlog.
+
+

🎯 Entregas Realizadas

+
+

Planejamento consolidado

+

As entregas desta Iteração garantiram a preparação detalhada dos MVPs, com uma visão clara das expectativas e dos requisitos para os próximos passos.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
EntregaDescrição
Backlog detalhado para MVP1 e MVP2O backlog foi refinado e detalhado, com funcionalidades e prioridades bem definidas para os dois MVPs.
Definição de DoR (Definition of Ready)Estabelecimento de critérios claros para garantir que as tarefas estejam prontas para o desenvolvimento.
Definição de DoD (Definition of Done)Definição dos critérios de aceitação e conclusão das tarefas, assegurando a entrega de funcionalidades completas e testadas.
Critérios de aceitação definidosPara cada tarefa do backlog, foram estabelecidos critérios claros de aceitação, garantindo que as funcionalidades atendam aos requisitos do cliente.
+
+

🧐 Retrospectiva da Iteração

+
+

Ponto de reflexão

+

A retrospectiva da Iteração 3 destacou os avanços na definição dos requisitos, mas também revelou oportunidades de melhorar a comunicação sobre as expectativas de qualidade e aceitação.

+
+
    +
  • Tópicos discutidos: A necessidade de maior alinhamento entre a equipe sobre a definição dos critérios de aceitação e as expectativas de qualidade.
  • +
  • Conclusão: Embora as entregas tenham avançado conforme o planejado, o alinhamento dos critérios de aceitação foi considerado um ponto de melhoria para garantir que todos os membros da equipe compreendam as expectativas de forma clara e consistente.
  • +
+
+

🏆 Conquistas da Iteração

+
+

Conquistas importantes

+
    +
  • Backlog detalhado para MVP1 e MVP2 concluído.
  • +
  • Definição de critérios claros de DoR e DoD.
  • +
  • Estabelecimento de critérios de aceitação para funcionalidades.
  • +
+
+
+

📌 Próximos Passos

+
+

Refinamento final do backlog, foco na implementação das funcionalidades de maior prioridade para o MVP1 e alinhamento da equipe quanto aos critérios de aceitação.

+
+
+

🤝 Reuniões

+
+
+
+
+
+

Planejamento detalhado e definição de critérios

+
+

Detalhes do Encontro

+
    +
  • Data: 05/12/2024
  • +
  • Horário: 10:00
  • +
  • Modalidade: Videoconferência (Teams)
  • +
  • Participantes: Equipe
  • +
+
+
+

Propósito

+

Esta reunião teve como objetivo refinar o backlog e definir claramente os critérios de aceitação, DoR e DoD para garantir a execução eficiente das entregas futuras.

+
+Gravação da Reunião +

A reunião não foi gravada.

+
+
+

Principais Tópicos

+ + + + + + + + + + + + + + + + + + + + + +
#Tópico
1Refinamento e priorização do backlog.
2Definição dos critérios de DoR e DoD.
3Estabelecimento dos critérios de aceitação para as funcionalidades.
+
+

Decisões Críticas

+
+

Atenção

+

Durante a reunião, as seguintes decisões críticas foram tomadas para garantir o progresso do projeto:

+
    +
  • Refinamento do backlog com base nas prioridades dos MVPs.
  • +
  • Definição clara dos critérios de DoR e DoD para garantir o alinhamento de qualidade.
  • +
  • Estabelecimento de critérios de aceitação para todas as tarefas do backlog.
  • +
+
+
+

Observações Adicionais

+
+

Atenção

+

Nota: A equipe deve garantir que os critérios de aceitação sejam revisados continuamente para alinhá-los com as expectativas do cliente e com as mudanças no escopo.

+
+
+
+
+ + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ +
+ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/javascripts/mathjax.js b/javascripts/mathjax.js new file mode 100644 index 0000000..ee3e6eb --- /dev/null +++ b/javascripts/mathjax.js @@ -0,0 +1,19 @@ +window.MathJax = { + tex: { + inlineMath: [["\\(", "\\)"]], + displayMath: [["\\[", "\\]"]], + processEscapes: true, + processEnvironments: true + }, + options: { + ignoreHtmlClass: ".*|", + processHtmlClass: "arithmatex" + } +}; + +document$.subscribe(() => { + MathJax.startup.output.clearCache() + MathJax.typesetClear() + MathJax.texReset() + MathJax.typesetPromise() +}) \ No newline at end of file diff --git a/javascripts/removeCredits.js b/javascripts/removeCredits.js new file mode 100644 index 0000000..b8aa38a --- /dev/null +++ b/javascripts/removeCredits.js @@ -0,0 +1,8 @@ +document.addEventListener("DOMContentLoaded", function() { + removeCredits(); +}); + +function removeCredits(){ + document.querySelectorAll('.md-footer')[0].getElementsByClassName("md-footer-meta")[0].remove(); + document.querySelectorAll('.md-footer-meta')[0].childNodes[1].remove(); +} \ No newline at end of file diff --git a/javascripts/termynal.js b/javascripts/termynal.js new file mode 100644 index 0000000..05aa402 --- /dev/null +++ b/javascripts/termynal.js @@ -0,0 +1,264 @@ +/** + * termynal.js + * A lightweight, modern and extensible animated terminal window, using + * async/await. + * + * @author Ines Montani + * @version 0.0.1 + * @license MIT + */ + +'use strict'; + +/** Generate a terminal widget. */ +class Termynal { + /** + * Construct the widget's settings. + * @param {(string|Node)=} container - Query selector or container element. + * @param {Object=} options - Custom settings. + * @param {string} options.prefix - Prefix to use for data attributes. + * @param {number} options.startDelay - Delay before animation, in ms. + * @param {number} options.typeDelay - Delay between each typed character, in ms. + * @param {number} options.lineDelay - Delay between each line, in ms. + * @param {number} options.progressLength - Number of characters displayed as progress bar. + * @param {string} options.progressChar – Character to use for progress bar, defaults to █. + * @param {number} options.progressPercent - Max percent of progress. + * @param {string} options.cursor – Character to use for cursor, defaults to ▋. + * @param {Object[]} lineData - Dynamically loaded line data objects. + * @param {boolean} options.noInit - Don't initialise the animation. + */ + constructor(container = '#termynal', options = {}) { + this.container = (typeof container === 'string') ? document.querySelector(container) : container; + this.pfx = `data-${options.prefix || 'ty'}`; + this.originalStartDelay = this.startDelay = options.startDelay + || parseFloat(this.container.getAttribute(`${this.pfx}-startDelay`)) || 600; + this.originalTypeDelay = this.typeDelay = options.typeDelay + || parseFloat(this.container.getAttribute(`${this.pfx}-typeDelay`)) || 90; + this.originalLineDelay = this.lineDelay = options.lineDelay + || parseFloat(this.container.getAttribute(`${this.pfx}-lineDelay`)) || 1500; + this.progressLength = options.progressLength + || parseFloat(this.container.getAttribute(`${this.pfx}-progressLength`)) || 40; + this.progressChar = options.progressChar + || this.container.getAttribute(`${this.pfx}-progressChar`) || '█'; + this.progressPercent = options.progressPercent + || parseFloat(this.container.getAttribute(`${this.pfx}-progressPercent`)) || 100; + this.cursor = options.cursor + || this.container.getAttribute(`${this.pfx}-cursor`) || '▋'; + this.lineData = this.lineDataToElements(options.lineData || []); + this.loadLines() + if (!options.noInit) this.init() + } + + loadLines() { + // Load all the lines and create the container so that the size is fixed + // Otherwise it would be changing and the user viewport would be constantly + // moving as she/he scrolls + const finish = this.generateFinish() + finish.style.visibility = 'hidden' + this.container.appendChild(finish) + // Appends dynamically loaded lines to existing line elements. + this.lines = [...this.container.querySelectorAll(`[${this.pfx}]`)].concat(this.lineData); + for (let line of this.lines) { + line.style.visibility = 'hidden' + this.container.appendChild(line) + } + const restart = this.generateRestart() + restart.style.visibility = 'hidden' + this.container.appendChild(restart) + this.container.setAttribute('data-termynal', ''); + } + + /** + * Initialise the widget, get lines, clear container and start animation. + */ + init() { + /** + * Calculates width and height of Termynal container. + * If container is empty and lines are dynamically loaded, defaults to browser `auto` or CSS. + */ + const containerStyle = getComputedStyle(this.container); + this.container.style.width = containerStyle.width !== '0px' ? + containerStyle.width : undefined; + this.container.style.minHeight = containerStyle.height !== '0px' ? + containerStyle.height : undefined; + + this.container.setAttribute('data-termynal', ''); + this.container.innerHTML = ''; + for (let line of this.lines) { + line.style.visibility = 'visible' + } + this.start(); + } + + /** + * Start the animation and rener the lines depending on their data attributes. + */ + async start() { + this.addFinish() + await this._wait(this.startDelay); + + for (let line of this.lines) { + const type = line.getAttribute(this.pfx); + const delay = line.getAttribute(`${this.pfx}-delay`) || this.lineDelay; + + if (type == 'input') { + line.setAttribute(`${this.pfx}-cursor`, this.cursor); + await this.type(line); + await this._wait(delay); + } + + else if (type == 'progress') { + await this.progress(line); + await this._wait(delay); + } + + else { + this.container.appendChild(line); + await this._wait(delay); + } + + line.removeAttribute(`${this.pfx}-cursor`); + } + this.addRestart() + this.finishElement.style.visibility = 'hidden' + this.lineDelay = this.originalLineDelay + this.typeDelay = this.originalTypeDelay + this.startDelay = this.originalStartDelay + } + + generateRestart() { + const restart = document.createElement('a') + restart.onclick = (e) => { + e.preventDefault() + this.container.innerHTML = '' + this.init() + } + restart.href = '#' + restart.setAttribute('data-terminal-control', '') + restart.innerHTML = "restart ↻" + return restart + } + + generateFinish() { + const finish = document.createElement('a') + finish.onclick = (e) => { + e.preventDefault() + this.lineDelay = 0 + this.typeDelay = 0 + this.startDelay = 0 + } + finish.href = '#' + finish.setAttribute('data-terminal-control', '') + finish.innerHTML = "fast →" + this.finishElement = finish + return finish + } + + addRestart() { + const restart = this.generateRestart() + this.container.appendChild(restart) + } + + addFinish() { + const finish = this.generateFinish() + this.container.appendChild(finish) + } + + /** + * Animate a typed line. + * @param {Node} line - The line element to render. + */ + async type(line) { + const chars = [...line.textContent]; + line.textContent = ''; + this.container.appendChild(line); + + for (let char of chars) { + const delay = line.getAttribute(`${this.pfx}-typeDelay`) || this.typeDelay; + await this._wait(delay); + line.textContent += char; + } + } + + /** + * Animate a progress bar. + * @param {Node} line - The line element to render. + */ + async progress(line) { + const progressLength = line.getAttribute(`${this.pfx}-progressLength`) + || this.progressLength; + const progressChar = line.getAttribute(`${this.pfx}-progressChar`) + || this.progressChar; + const chars = progressChar.repeat(progressLength); + const progressPercent = line.getAttribute(`${this.pfx}-progressPercent`) + || this.progressPercent; + line.textContent = ''; + this.container.appendChild(line); + + for (let i = 1; i < chars.length + 1; i++) { + await this._wait(this.typeDelay); + const percent = Math.round(i / chars.length * 100); + line.textContent = `${chars.slice(0, i)} ${percent}%`; + if (percent > progressPercent) { + break; + } + } + } + + /** + * Helper function for animation delays, called with `await`. + * @param {number} time - Timeout, in ms. + */ + _wait(time) { + return new Promise(resolve => setTimeout(resolve, time)); + } + + /** + * Converts line data objects into line elements. + * + * @param {Object[]} lineData - Dynamically loaded lines. + * @param {Object} line - Line data object. + * @returns {Element[]} - Array of line elements. + */ + lineDataToElements(lineData) { + return lineData.map(line => { + let div = document.createElement('div'); + div.innerHTML = `${line.value || ''}`; + + return div.firstElementChild; + }); + } + + /** + * Helper function for generating attributes string. + * + * @param {Object} line - Line data object. + * @returns {string} - String of attributes. + */ + _attributes(line) { + let attrs = ''; + for (let prop in line) { + // Custom add class + if (prop === 'class') { + attrs += ` class=${line[prop]} ` + continue + } + if (prop === 'type') { + attrs += `${this.pfx}="${line[prop]}" ` + } else if (prop !== 'value') { + attrs += `${this.pfx}-${prop}="${line[prop]}" ` + } + } + + return attrs; + } +} + +/** +* HTML API: If current script has container(s) specified, initialise Termynal. +*/ +if (document.currentScript.hasAttribute('data-termynal-container')) { + const containers = document.currentScript.getAttribute('data-termynal-container'); + containers.split('|') + .forEach(container => new Termynal(container)) +} \ No newline at end of file diff --git a/licoes-aprendidas/index.html b/licoes-aprendidas/index.html new file mode 100644 index 0000000..319757b --- /dev/null +++ b/licoes-aprendidas/index.html @@ -0,0 +1,1395 @@ + + + + + + + + + + + + + + + + + + + + + + + + + Lições Aprendidas - Paraizo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

Lições aprendidas

+
+Histórico de Revisão + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DataVersãoDescriçãoAutor
08/111.0Criação do tópico de lições aprendidasMaykon Júnio dos Santos Soares
15/121.1Adição de lições aprendidas da unidade 2Henrique Martins Alencar
20/011.2Adição de lições aprendidas da unidade 3Erick Miranda Santos
+
+
+
+
+
+

Unidade 1

+
+

Introdução ao Desenvolvimento de Projetos

+

Na sala de aula, começamos nossa jornada de aprendizado com o desenvolvimento de habilidades práticas voltadas para projetos. Este foi apenas o início, mas crucial para entendermos as metodologias que guiarão nosso trabalho.

+
+

Metodologias de Desenvolvimento

+

Exploramos as principais metodologias de desenvolvimento de software, compreendendo suas diferenças e como escolher entre elas com base no **triângulo de ferro:

+
    +
  • Metodologias orientadas a plano: Estruturadas e detalhadas, com foco no planejamento rigoroso.
  • +
  • Metodologias ágeis: Flexíveis e adaptáveis, favorecendo a colaboração e a entrega contínua de valor.
  • +
+

Dessa forma, conseguimos avaliar as vantagens e limitações de cada abordagem e definir qual delas é mais apropriada para diferentes tipos de projeto.

+
+

Ferramentas Ágeis no Mercado

+

Nos aprofundamos em duas das metodologias ágeis mais populares e suas práticas específicas:

+
    +
  • Scrum: Uma abordagem iterativa que organiza o trabalho em ciclos curtos, chamados de "sprints", para melhorar a produtividade e a entrega.
  • +
  • eXtreme Programming (XP): Focado em garantir a qualidade do código através de práticas como testes automatizados e programação em par.
  • +
+

Essas ferramentas, ricas em processos e práticas, fornecem uma base sólida para o desenvolvimento de software de alto padrão.

+
+

Novas Ferramentas e Tecnologias

+

Além das metodologias, a equipe teve a oportunidade de explorar novas ferramentas que facilitarão o desenvolvimento do projeto:

+
    +
  • GitHub Pages: Plataforma gratuita de hospedagem que a equipe utilizará para **documentar o projeto de forma clara e acessível, garantindo que todos os membros estejam alinhados quanto aos processos e etapas.
  • +
+
+
+
+

Unidade 2

+
+

Processo de Engenharia de Requisitos

+

Aprendemos a importância de compreender profundamente as necessidades dos stakeholders e transformá-las em requisitos claros e definidos, pois nos ajudam a organizar e priorizar as etapas do desenvolvimento, trazendo um trabalho eficaz. A comunicação efetiva entre os principais interessados e a equipe de desenvolvimento é crucial para minimizar a ambiguidade e o retrabalho.

+

Requisitos Funcionais e não funcionais

+

Compreendemos que os requisitos funcionais definem o que o sistema deve fazer, enquanto os não funcionais especificam como o sistema deve funcionar. Aprendemos que ignorar requisitos não funcionais, como desempenho, segurança e usabilidade, pode comprometer a qualidade final do produto. Um desafio foi compreender quais são cada um desses requisitos de forma alinhada com os objetivos do projeto.

+

Elaboração de Backlog

+

Durante a elaboração do backlog, aprendemos que a clareza das tarefas são cruciais para o sucesso da equipe. Organizar os requisitos separando-os por temas e épicos e atribuindo histórias de usuário nos ajudou a compreender melhor o que exatamente desenvolver para o cumprimento dos requisitos, com o objetivo de entregar um produto de maior qualidade.

+

Priorização do Backlog

+

A priorização do backlog nos ensinou a equilibrar as necessidades do negócio com as restrições técnicas e de tempo. A utilização de critérios de prioridade com pesos atribuídos, como valor de negócio, complexidade, criticidade e independência, nos ajudou a definir que requisitos tinham maior importância em nosso projeto, o que nos permite ter uma melhor organização, possibilitando entregas que estejam mais alinhadas com os objetivos do projeto.

+

Definição de MVP

+

A definição do MVP (Minimum Viable Product) foi um exercício valioso para aprender a entregar valor rápido com recursos limitados. A definição do que é essencial nos permite focar nas funcionalidades mais críticas e de maior valor para o produto, garantindo que as necessidades principais sejam entregues dentro do prazo determinado.

+
+
+
+

Unidade 3

+
+

Product Backlog Building (PBB)

+
+
+
+

Durante o Product Backlog Building (PBB), aprendemos que o sucesso de um projeto ágil depende da clareza e da evolução constante do backlog. O processo de revisar e refinar o backlog periodicamente é essencial para ajustar as prioridades e garantir que os itens mais importantes sejam tratados primeiro, permitindo entregas contínuas de valor ao cliente.

+
    +
  • +

    Lição Aprendida: A construção de um backlog bem estruturado e a revisão constante do mesmo são cruciais para o sucesso de um projeto ágil. Adaptar as prioridades de acordo com o progresso do projeto e as necessidades do cliente ajuda a mitigar riscos e a garantir que o trabalho esteja sempre alinhado com os objetivos do produto.

    +

    User Story Mapping (USM)

    +

    O User Story Mapping é uma técnica essencial para visualizar as funcionalidades do produto de maneira estruturada e alinhada com as necessidades do usuário. Durante esta unidade, aprendemos a importância de mapear histórias de usuário para garantir que todas as funcionalidades necessárias para atender ao objetivo do projeto sejam contempladas de forma clara. Essa técnica permite uma melhor comunicação entre a equipe e facilita o planejamento das entregas de acordo com o valor de cada história.

    +
      +
    • Lição Aprendida: O uso de User Story Mapping proporciona uma visão clara das funcionalidades do sistema e facilita a priorização das tarefas com base no valor que elas agregam ao produto. É fundamental garantir que todas as histórias de usuário estejam bem definidas e alinhadas com os objetivos do projeto.
    • +
    +
    +

    Integração de PBB e USM

    +

    Durante o processo de integração entre Product Backlog Building (PBB) e User Story Mapping (USM), percebemos como essas duas metodologias se complementam. O PBB ajuda a organizar o trabalho de maneira eficiente, enquanto o USM oferece uma visão detalhada das funcionalidades, permitindo que a equipe foque nas histórias mais relevantes para o produto. A integração de ambas as técnicas é essencial para garantir que o backlog esteja bem estruturado e alinhado com as necessidades do usuário.

    +
      +
    • Lição Aprendida: A integração de PBB e USM deve ser feita de forma cuidadosa, garantindo que o planejamento estratégico do projeto seja complementado pela visão detalhada das histórias de usuário. Isso permite que o trabalho seja executado de forma mais eficiente e alinhada com os objetivos do produto.
    • +
    +
  • +
+ + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ +
+ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/morse/css/style.css b/morse/css/style.css new file mode 100644 index 0000000..afbc84e --- /dev/null +++ b/morse/css/style.css @@ -0,0 +1,1637 @@ +/* html{ + line-height:1.15; + -ms-text-size-adjust:100%; + -webkit-text-size-adjust:100% +} */ +body { + margin: 0; +} +article, +aside, +footer, +header, +nav, +section { + display: block; +} +h1 { + font-size: 2em; + margin: 0.67em 0; +} +figcaption, +figure, +main { + display: block; +} +figure { + margin: 1em 40px; +} +hr { + box-sizing: content-box; + height: 0; + overflow: visible; +} +pre { + font-family: monospace, monospace; + font-size: 1em; +} +/* a{ + background-color:transparent; + -webkit-text-decoration-skip:objects +} */ +/* abbr[title]{ + border-bottom:none; + text-decoration:underline; + -webkit-text-decoration:underline dotted; + text-decoration:underline dotted +} */ +b, +strong { + font-weight: inherit; +} +b, +strong { + font-weight: bolder; +} +code, +kbd, +samp { + font-family: monospace, monospace; + font-size: 1em; +} +dfn { + font-style: italic; +} +mark { + background-color: #ff0; + color: #000; +} +small { + font-size: 80%; +} +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} +sub { + bottom: -0.25em; +} +sup { + top: -0.5em; +} +audio, +video { + display: inline-block; +} +audio:not([controls]) { + display: none; + height: 0; +} +img { + border-style: none; +} +svg:not(:root) { + overflow: hidden; +} +button, +input, +optgroup, +select, +textarea { + font-family: sans-serif; + font-size: 100%; + line-height: 1.15; + margin: 0; +} +button, +input { + overflow: visible; +} +button, +select { + text-transform: none; +} +button, +html [type="button"], +[type="reset"], +[type="submit"] { + -webkit-appearance: button; +} +button::-moz-focus-inner, +[type="button"]::-moz-focus-inner, +[type="reset"]::-moz-focus-inner, +[type="submit"]::-moz-focus-inner { + border-style: none; + padding: 0; +} +button:-moz-focusring, +[type="button"]:-moz-focusring, +[type="reset"]:-moz-focusring, +[type="submit"]:-moz-focusring { + outline: 1px dotted ButtonText; +} +fieldset { + padding: 0.35em 0.75em 0.625em; +} +legend { + box-sizing: border-box; + color: inherit; + display: table; + max-width: 100%; + padding: 0; + white-space: normal; +} +progress { + display: inline-block; + vertical-align: baseline; +} +textarea { + overflow: auto; +} +[type="checkbox"], +[type="radio"] { + box-sizing: border-box; + padding: 0; +} +[type="number"]::-webkit-inner-spin-button, +[type="number"]::-webkit-outer-spin-button { + height: auto; +} +[type="search"] { + -webkit-appearance: textfield; + outline-offset: -2px; +} +[type="search"]::-webkit-search-cancel-button, +[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} +::-webkit-file-upload-button { + -webkit-appearance: button; + font: inherit; +} +details, +menu { + display: block; +} +summary { + display: list-item; +} +canvas { + display: inline-block; +} +template { + display: none; +} +[hidden] { + display: none; +} +html { + box-sizing: border-box; +} +*, +*:before, +*:after { + box-sizing: inherit; +} +body { + background: #1d2026; + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; +} +hr { + border: 0; + display: block; + height: 1px; + background: #242830; + margin-top: 24px; + margin-bottom: 24px; +} +ul, +ol { + margin-top: 0; + margin-bottom: 24px; + padding-left: 24px; +} +ul { + list-style: disc; +} +ol { + list-style: decimal; +} +li > ul, +li > ol { + margin-bottom: 0; +} +dl { + margin-top: 0; + margin-bottom: 24px; +} +dt { + font-weight: 600; +} +dd { + margin-left: 24px; + margin-bottom: 24px; +} +img { + height: auto; + max-width: 100%; + vertical-align: middle; +} +figure { + margin: 24px 0; +} +figcaption { + font-size: 16px; + line-height: 24px; + padding: 8px 0; +} +img, +svg { + display: block; +} +table { + border-collapse: collapse; + margin-bottom: 24px; + width: 100%; +} +tr { + border-bottom: 1px solid #242830; +} +th { + text-align: left; +} +th, +td { + padding: 10px 16px; +} +th:first-child, +td:first-child { + padding-left: 0; +} +th:last-child, +td:last-child { + padding-right: 0; +} +html { + font-size: 20px; + line-height: 30px; +} +body { + color: #8a94a7; + font-size: 1rem; +} +body, +button, +input, +select, +textarea { + font-family: "IBM Plex Sans", sans-serif; +} +/* a{ + color:#8A94A7; + text-decoration:underline +} */ +a:hover, +a:active { + outline: 0; + text-decoration: none; +} +h1, +h2, +h3, +h4, +h5, +h6, +.h1, +.h2, +.h3, +.h4, +.h5, +.h6 { + clear: both; + color: #fff; + font-weight: 600; +} +h1, +.h1 { + font-size: 38px; + line-height: 48px; + letter-spacing: 0px; +} +@media (min-width: 641px) { + h1, + .h1 { + font-size: 44px; + line-height: 54px; + letter-spacing: 0px; + } +} +h2, +.h2 { + font-size: 32px; + line-height: 42px; + letter-spacing: 0px; +} +@media (min-width: 641px) { + h2, + .h2 { + font-size: 38px; + line-height: 48px; + letter-spacing: 0px; + } +} +h3, +.h3, +blockquote { + font-size: 24px; + line-height: 34px; + letter-spacing: 0px; +} +@media (min-width: 641px) { + h3, + .h3, + blockquote { + font-size: 32px; + line-height: 42px; + letter-spacing: 0px; + } +} +h4, +h5, +h6, +.h4, +.h5, +.h6 { + font-size: 20px; + line-height: 30px; + letter-spacing: -0.1px; +} +@media (min-width: 641px) { + h4, + h5, + h6, + .h4, + .h5, + .h6 { + font-size: 24px; + line-height: 34px; + letter-spacing: 0px; + } +} +@media (max-width: 640px) { + .h1-mobile { + font-size: 38px; + line-height: 48px; + letter-spacing: 0px; + } + .h2-mobile { + font-size: 32px; + line-height: 42px; + letter-spacing: 0px; + } + .h3-mobile { + font-size: 24px; + line-height: 34px; + letter-spacing: 0px; + } + .h4-mobile, + .h5-mobile, + .h6-mobile { + font-size: 20px; + line-height: 30px; + letter-spacing: -0.1px; + } +} +.text-light h1, +.text-light h2, +.text-light h3, +.text-light h4, +.text-light h5, +.text-light h6, +.text-light .h1, +.text-light .h2, +.text-light .h3, +.text-light .h4, +.text-light .h5, +.text-light .h6 { + color: !important; +} +.text-sm { + font-size: 18px; + line-height: 28px; + letter-spacing: -0.1px; +} +.text-xs { + font-size: 16px; + line-height: 24px; + letter-spacing: -0.1px; +} +h1, +h2, +.h1, +.h2 { + margin-top: 48px; + margin-bottom: 16px; +} +h3, +.h3 { + margin-top: 36px; + margin-bottom: 12px; +} +h4, +h5, +h6, +.h4, +.h5, +.h6 { + margin-top: 24px; + margin-bottom: 4px; +} +p { + margin-top: 0; + margin-bottom: 24px; +} +dfn, +cite, +em, +i { + font-style: italic; +} +blockquote { + color: #3b404c; + font-style: italic; + margin-top: 24px; + margin-bottom: 24px; + margin-left: 24px; +} +blockquote::before { + content: "\201C"; +} +blockquote::after { + content: "\201D"; +} +blockquote p { + display: inline; +} +address { + color: #8a94a7; + border-width: 1px 0; + border-style: solid; + border-color: #242830; + padding: 24px 0; + margin: 0 0 24px; +} +pre, +pre h1, +pre h2, +pre h3, +pre h4, +pre h5, +pre h6, +pre .h1, +pre .h2, +pre .h3, +pre .h4, +pre .h5, +pre .h6 { + font-family: "Courier 10 Pitch", Courier, monospace; +} +pre, +code, +kbd, +tt, +var { + background: #1d2026; +} +pre { + font-size: 16px; + line-height: 24px; + margin-bottom: 1.6em; + max-width: 100%; + overflow: auto; + padding: 24px; + margin-top: 24px; + margin-bottom: 24px; +} +code, +kbd, +tt, +var { + font-family: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; + font-size: 16px; + padding: 2px 4px; +} +abbr, +acronym { + cursor: help; +} +mark, +ins { + text-decoration: none; +} +small { + font-size: 18px; + line-height: 28px; + letter-spacing: -0.1px; +} +b, +strong { + font-weight: 600; +} +button, +input, +select, +textarea, +label { + font-size: 20px; + line-height: 30px; +} +.container, +.container-sm { + width: 100%; + margin: 0 auto; + padding-left: 16px; + padding-right: 16px; +} +@media (min-width: 481px) { + .container, + .container-sm { + padding-left: 24px; + padding-right: 24px; + } +} +.container { + max-width: 1128px; +} +.container-sm { + max-width: 848px; +} +.container .container-sm { + max-width: 800px; + padding-left: 0; + padding-right: 0; +} +.screen-reader-text { + clip: rect(1px, 1px, 1px, 1px); + position: absolute !important; + height: 1px; + width: 1px; + overflow: hidden; + word-wrap: normal !important; +} +.screen-reader-text:focus { + border-radius: 2px; + box-shadow: 0 0 2px 2px rgba(0, 0, 0, 0.6); + clip: auto !important; + display: block; + font-size: 14px; + letter-spacing: 0px; + font-weight: 600; + line-height: 16px; + text-decoration: none; + text-transform: uppercase; + background-color: #1d2026; + color: #0270d7 !important; + border: none; + height: auto; + left: 8px; + padding: 16px 32px; + top: 8px; + width: auto; + z-index: 100000; +} +.list-reset { + list-style: none; + padding: 0; +} +.text-left { + text-align: left; +} +.text-center { + text-align: center; +} +.text-right { + text-align: right; +} +.text-primary { + color: #0270d7; +} +.has-top-divider { + position: relative; +} +.has-top-divider::before { + content: ""; + position: absolute; + top: 0; + left: 0; + width: 100%; + display: block; + height: 1px; + background: #242830; +} +.has-bottom-divider { + position: relative; +} +.has-bottom-divider::after { + content: ""; + position: absolute; + bottom: 0; + left: 0; + width: 100%; + display: block; + height: 1px; + background: #242830; +} +.m-0 { + margin: 0; +} +.mt-0 { + margin-top: 0; +} +.mr-0 { + margin-right: 0; +} +.mb-0 { + margin-bottom: 0; +} +.ml-0 { + margin-left: 0; +} +.m-8 { + margin: 8px; +} +.mt-8 { + margin-top: 8px; +} +.mr-8 { + margin-right: 8px; +} +.mb-8 { + margin-bottom: 8px; +} +.ml-8 { + margin-left: 8px; +} +.m-16 { + margin: 16px; +} +.mt-16 { + margin-top: 16px; +} +.mr-16 { + margin-right: 16px; +} +.mb-16 { + margin-bottom: 16px; +} +.ml-16 { + margin-left: 16px; +} +.m-24 { + margin: 24px; +} +.mt-24 { + margin-top: 24px; +} +.mr-24 { + margin-right: 24px; +} +.mb-24 { + margin-bottom: 24px; +} +.ml-24 { + margin-left: 24px; +} +.m-32 { + margin: 32px; +} +.mt-32 { + margin-top: 32px; +} +.mr-32 { + margin-right: 32px; +} +.mb-32 { + margin-bottom: 32px; +} +.ml-32 { + margin-left: 32px; +} +.m-40 { + margin: 40px; +} +.mt-40 { + margin-top: 40px; +} +.mr-40 { + margin-right: 40px; +} +.mb-40 { + margin-bottom: 40px; +} +.ml-40 { + margin-left: 40px; +} +.m-48 { + margin: 48px; +} +.mt-48 { + margin-top: 48px; +} +.mr-48 { + margin-right: 48px; +} +.mb-48 { + margin-bottom: 48px; +} +.ml-48 { + margin-left: 48px; +} +.m-56 { + margin: 56px; +} +.mt-56 { + margin-top: 56px; +} +.mr-56 { + margin-right: 56px; +} +.mb-56 { + margin-bottom: 56px; +} +.ml-56 { + margin-left: 56px; +} +.m-64 { + margin: 64px; +} +.mt-64 { + margin-top: 64px; +} +.mr-64 { + margin-right: 64px; +} +.mb-64 { + margin-bottom: 64px; +} +.ml-64 { + margin-left: 64px; +} +.p-0 { + padding: 0; +} +.pt-0 { + padding-top: 0; +} +.pr-0 { + padding-right: 0; +} +.pb-0 { + padding-bottom: 0; +} +.pl-0 { + padding-left: 0; +} +.p-8 { + padding: 8px; +} +.pt-8 { + padding-top: 8px; +} +.pr-8 { + padding-right: 8px; +} +.pb-8 { + padding-bottom: 8px; +} +.pl-8 { + padding-left: 8px; +} +.p-16 { + padding: 16px; +} +.pt-16 { + padding-top: 16px; +} +.pr-16 { + padding-right: 16px; +} +.pb-16 { + padding-bottom: 16px; +} +.pl-16 { + padding-left: 16px; +} +.p-24 { + padding: 24px; +} +.pt-24 { + padding-top: 24px; +} +.pr-24 { + padding-right: 24px; +} +.pb-24 { + padding-bottom: 24px; +} +.pl-24 { + padding-left: 24px; +} +.p-32 { + padding: 32px; +} +.pt-32 { + padding-top: 32px; +} +.pr-32 { + padding-right: 32px; +} +.pb-32 { + padding-bottom: 32px; +} +.pl-32 { + padding-left: 32px; +} +.p-40 { + padding: 40px; +} +.pt-40 { + padding-top: 40px; +} +.pr-40 { + padding-right: 40px; +} +.pb-40 { + padding-bottom: 40px; +} +.pl-40 { + padding-left: 40px; +} +.p-48 { + padding: 48px; +} +.pt-48 { + padding-top: 48px; +} +.pr-48 { + padding-right: 48px; +} +.pb-48 { + padding-bottom: 48px; +} +.pl-48 { + padding-left: 48px; +} +.p-56 { + padding: 56px; +} +.pt-56 { + padding-top: 56px; +} +.pr-56 { + padding-right: 56px; +} +.pb-56 { + padding-bottom: 56px; +} +.pl-56 { + padding-left: 56px; +} +.p-64 { + padding: 64px; +} +.pt-64 { + padding-top: 64px; +} +.pr-64 { + padding-right: 64px; +} +.pb-64 { + padding-bottom: 64px; +} +.pl-64 { + padding-left: 64px; +} +/* .sr .has-animations .is-revealing{ + visibility:hidden +} +.has-animations .anime-element{ + visibility:hidden +} +.anime-ready .has-animations .anime-element{ + visibility:visible +} */ +.input, +.textarea { + background-color: #fff; + border-width: 1px; + border-style: solid; + border-color: #242830; + border-radius: 2px; + color: #8a94a7; + max-width: 100%; + width: 100%; +} +.input::-moz-placeholder, +.textarea::-moz-placeholder { + color: #3b404c; +} +.input::placeholder, +.textarea::placeholder { + color: #3b404c; +} +.input::-ms-input-placeholder, +.textarea::-ms-input-placeholder { + color: #3b404c; +} +.input:-ms-input-placeholder, +.textarea:-ms-input-placeholder { + color: #3b404c; +} +.input:hover, +.textarea:hover { + border-color: #191c21; +} +.input:active, +.input:focus, +.textarea:active, +.textarea:focus { + outline: none; + border-color: #242830; +} +.input[disabled], +.textarea[disabled] { + cursor: not-allowed; + background-color: #1d2026; + border-color: #1d2026; +} +.input { + -moz-appearance: none; + -webkit-appearance: none; + font-size: 16px; + letter-spacing: -0.1px; + line-height: 20px; + padding: 13px 16px; + height: 48px; + box-shadow: none; +} +.input .inline-input { + display: inline; + width: auto; +} +.textarea { + display: block; + min-width: 100%; + resize: vertical; +} +.textarea .inline-textarea { + display: inline; + width: auto; +} +.field-grouped > .control:not(:last-child) { + margin-bottom: 8px; +} +@media (min-width: 641px) { + .field-grouped { + display: flex; + } + .field-grouped > .control { + flex-shrink: 0; + } + .field-grouped > .control.control-expanded { + flex-grow: 1; + flex-shrink: 1; + } + .field-grouped > .control:not(:last-child) { + margin-bottom: 0; + margin-right: 8px; + } +} +.button { + display: inline-flex; + font-size: 14px; + letter-spacing: 0px; + font-weight: 600; + line-height: 16px; + text-decoration: none !important; + text-transform: uppercase; + background-color: #242830; + color: #fff !important; + border: none; + border-radius: 2px; + cursor: pointer; + justify-content: center; + padding: 16px 32px; + height: 48px; + text-align: center; + white-space: nowrap; +} +.button:hover { + background: #262a33; +} +.button:active { + outline: 0; +} +.button::before { + border-radius: 2px; +} +.button-sm { + padding: 8px 24px; + height: 32px; +} +.button-primary { + background: #097dea; + background: linear-gradient(65deg, #0270d7 0, #0f8afd 100%); +} +.button-primary:hover { + background: #0982f4; + background: linear-gradient(65deg, #0275e1 0, #198ffd 100%); +} +.button-block { + display: flex; +} +.button-block { + display: flex; + width: 100%; +} +@media (max-width: 640px) { + .button-wide-mobile { + width: 100%; + max-width: 280px; + } +} +.site-header { + padding: 24px 0; +} +.site-header-inner { + position: relative; + display: flex; + justify-content: space-between; + align-items: center; +} +.header-links { + display: inline-flex; +} +.header-links li { + display: inline-flex; +} +.header-links a:not(.button) { + font-size: 16px; + line-height: 24px; + letter-spacing: -0.1px; + font-weight: 600; + color: #8a94a7; + text-transform: uppercase; + text-decoration: none; + line-height: 16px; + padding: 8px 24px; +} +@media (min-width: 641px) { + .site-header { + position: relative; + } + .site-header::before { + content: ""; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 700px; + background: #242830; + background: linear-gradient( + 80deg, + rgba(36, 40, 48, 0.5) 0%, + rgba(36, 40, 48, 0) 100% + ); + transform-origin: 0; + transform: skewY(-12deg); + } +} +.hero { + text-align: center; + padding-top: 48px; + padding-bottom: 88px; +} +.hero-copy { + position: relative; + z-index: 1; +} +.hero-cta { + margin-bottom: 40px; +} +.hero-figure { + position: relative; +} +.hero-figure svg { + width: 100%; + height: auto; +} +.hero-figure::before, +.hero-figure::after { + content: ""; + position: absolute; + background-repeat: no-repeat; + background-size: 100%; +} +.has-animations .hero-figure::before, +.has-animations .hero-figure::after { + opacity: 0; + transition: opacity 2s ease; +} +.anime-ready .has-animations .hero-figure::before, +.anime-ready .has-animations .hero-figure::after { + opacity: 1; +} +.hero-figure::before { + top: -57.8%; + left: -1.3%; + width: 152.84%; + height: 178.78%; + background-image: url("../images/hero-back-illustration.svg"); +} +.hero-figure::after { + top: -35.6%; + left: 99.6%; + width: 57.2%; + height: 87.88%; + background-image: url("../images/hero-top-illustration.svg"); +} +.hero-figure-box { + position: absolute; + top: 0; + will-change: transform; +} +.hero-figure-box-01, +.hero-figure-box-02, +.hero-figure-box-03, +.hero-figure-box-04, +.hero-figure-box-08, +.hero-figure-box-09 { + overflow: hidden; +} +.hero-figure-box-01::before, +.hero-figure-box-02::before, +.hero-figure-box-03::before, +.hero-figure-box-04::before, +.hero-figure-box-08::before, +.hero-figure-box-09::before { + content: ""; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + transform-origin: 100% 100%; +} +.hero-figure-box-01 { + left: 103.2%; + top: 41.9%; + width: 28.03%; + height: 37.37%; + background: linear-gradient(to left top, #00bffb, rgba(0, 191, 251, 0)); + transform: rotateZ(45deg); +} +.hero-figure-box-01::before { + background: linear-gradient(to left, #15181d 0%, rgba(21, 24, 29, 0) 60%); + transform: rotateZ(45deg) scale(1.5); +} +.hero-figure-box-02 { + left: 61.3%; + top: 64.1%; + width: 37.87%; + height: 50.5%; + background: linear-gradient(to left top, #0270d7, rgba(2, 112, 215, 0)); + transform: rotateZ(-45deg); +} +.hero-figure-box-02::before { + background: linear-gradient(to top, #15181d 0%, rgba(21, 24, 29, 0) 60%); + transform: rotateZ(-45deg) scale(1.5); +} +.hero-figure-box-03 { + left: 87.7%; + top: -56.8%; + width: 56.81%; + height: 75.75%; + background: linear-gradient(to left top, #00bffb, rgba(0, 191, 251, 0)); +} +.hero-figure-box-03::before { + background: linear-gradient(to left, #15181d 0%, rgba(21, 24, 29, 0) 60%); + transform: rotateZ(45deg) scale(1.5); +} +.hero-figure-box-04 { + left: 54.9%; + top: -8%; + width: 45.45%; + height: 60.6%; + background: linear-gradient(to left top, #0270d7, rgba(2, 112, 215, 0)); + transform: rotateZ(-135deg); +} +.hero-figure-box-04::before { + background: linear-gradient( + to top, + rgba(255, 255, 255, 0.24) 0%, + rgba(255, 255, 255, 0) 60% + ); + transform: rotateZ(-45deg) scale(1.5); +} +.hero-figure-box-05, +.hero-figure-box-06, +.hero-figure-box-07 { + background-color: #242830; + box-shadow: -20px 32px 64px rgba(0, 0, 0, 0.25); +} +.hero-figure-box-05 { + left: 17.4%; + top: 13.3%; + width: 64%; + height: 73.7%; + transform: perspective(500px) rotateY(-15deg) rotateX(8deg) rotateZ(-1deg); +} +.hero-figure-box-06 { + left: 65.5%; + top: 6.3%; + width: 30.3%; + height: 40.4%; + transform: rotateZ(20deg); +} +.hero-figure-box-07 { + left: 1.9%; + top: 42.4%; + width: 12.12%; + height: 16.16%; + transform: rotateZ(20deg); +} +.hero-figure-box-08 { + left: 27.1%; + top: 81.6%; + width: 19.51%; + height: 26.01%; + background: #0270d7; + transform: rotateZ(-22deg); +} +.hero-figure-box-08::before { + background: linear-gradient( + to left, + rgba(255, 255, 255, 0) 0%, + rgba(255, 255, 255, 0.48) 100% + ); + transform: rotateZ(45deg) scale(1.5); +} +.hero-figure-box-09 { + left: 42.6%; + top: -17.9%; + width: 6.63%; + height: 8.83%; + background: #00bffb; + transform: rotateZ(-52deg); +} +.hero-figure-box-09::before { + background: linear-gradient( + to left, + rgba(255, 255, 255, 0) 0%, + rgba(255, 255, 255, 0.64) 100% + ); + transform: rotateZ(45deg) scale(1.5); +} +.hero-figure-box-10 { + left: -3.8%; + top: 4.3%; + width: 3.03%; + height: 4.04%; + background: rgba(0, 191, 251, 0.32); + transform: rotateZ(-50deg); +} +@media (max-width: 640px) { + .hero-cta { + max-width: 280px; + margin-left: auto; + margin-right: auto; + } + .hero-cta .button { + display: flex; + } + .hero-cta .button + .button { + margin-top: 16px; + } + .hero-figure::after, + .hero-figure-box-03, + .hero-figure-box-04, + .hero-figure-box-09 { + display: none; + } +} +@media (min-width: 641px) { + .hero { + text-align: left; + padding-top: 64px; + padding-bottom: 88px; + } + .hero-inner { + display: flex; + justify-content: space-between; + align-items: center; + } + .hero-copy { + padding-right: 64px; + min-width: 552px; + width: 552px; + } + .hero-cta { + margin: 0; + } + .hero-cta .button { + min-width: 170px; + } + .hero-cta .button:first-child { + margin-right: 16px; + } + .hero-figure svg { + width: auto; + } +} +.features-wrap { + display: flex; + flex-wrap: wrap; + justify-content: space-evenly; + margin-right: -32px; + margin-left: -32px; +} +.features-wrap:first-of-type { + margin-top: -16px; +} +.features-wrap:last-of-type { + margin-bottom: -16px; +} +.feature { + padding: 16px 32px; + width: 380px; + max-width: 380px; + flex-grow: 1; +} +.feature-inner { + height: 100%; +} +.feature-icon { + display: flex; + justify-content: center; +} +@media (min-width: 641px) { + .features-wrap:first-of-type { + margin-top: -24px; + } + .features-wrap:last-of-type { + margin-bottom: -24px; + } + .feature { + padding: 32px 32px; + } +} +.pricing-header { +} +.pricing-tables-wrap { + display: flex; + flex-wrap: wrap; + justify-content: center; + margin-right: -12px; + margin-left: -12px; +} +.pricing-tables-wrap:first-child { + margin-top: -12px; +} +.pricing-tables-wrap:last-child { + margin-bottom: -12px; +} +.pricing-table { + position: relative; + padding: 12px; + width: 368px; + max-width: 368px; + flex-grow: 1; +} +.pricing-table::before { + content: ""; + position: absolute; + left: 50%; + width: 200%; + max-width: 200%; + height: 435px; + background-repeat: no-repeat; + background-position: center; + background-size: 100%; + bottom: 18.8%; + transform: translateX(-50%); + background-image: url("../images/pricing-illustration.svg"); +} +.pricing-table-header, +.pricing-table-features-title, +.pricing-table-features li { + border-bottom: 1px solid rgba(138, 148, 167, 0.24); +} +.pricing-table-inner { + position: relative; + display: flex; + flex-wrap: wrap; + background: #2c3039; + padding: 24px; + height: 100%; +} +.pricing-table-inner > * { + position: relative; + width: 100%; +} +.pricing-table-inner::before { + content: ""; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + box-shadow: 0 24px 48px rgba(21, 24, 29, 0.24); + mix-blend-mode: multiply; +} +.pricing-table-price-currency { + color: #8a94a7; +} +.pricing-table-features-title { + color: #fff; + font-weight: 700; +} +.pricing-table-features li { + display: flex; + align-items: center; + padding: 14px 0; +} +.pricing-table-features li::before { + content: ""; + width: 16px; + height: 12px; + margin-right: 16px; + background-image: url(data:image/svg+xml; + base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTIiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTUuNiA2LjRMMS42IDQgMCA1LjYgNS42IDEyIDE2IDEuNiAxNC40IDB6IiBmaWxsPSIjMDJDQkIxIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiLz48L3N2Zz4=); + background-repeat: no-repeat; +} +.pricing-table-cta { + align-self: flex-end; +} +@media (min-width: 641px) { + .pricing .section-paragraph { + padding-left: 90px; + padding-right: 90px; + } + /* .pricing-header{ + margin-bottom:52px + } */ +} +.cta { + text-align: center; +} +.cta .section-inner { + padding: 48px 16px; +} +.cta .section-title { + margin-bottom: 40px; +} +.cta-inner { + position: relative; + background: #15181d; + overflow: hidden; +} +.cta-inner::before { + content: ""; + position: absolute; + right: 98px; + top: -117px; + width: 160px; + height: 187px; + background-image: url("../images/cta-illustration.svg"); + background-repeat: no-repeat; +} +.cta-inner > * { + position: relative; +} +@media (min-width: 641px) { + .cta { + text-align: left; + } + .cta .section-inner { + padding: 64px 32px; + } + .cta .section-title { + margin-bottom: 0; + padding-right: 24px; + } + .cta-inner { + display: flex; + align-items: center; + justify-content: space-between; + } +} +.is-boxed { + background: #242830; +} +.body-wrap { + background: #1d2026; + overflow: hidden; + display: flex; + flex-direction: column; + min-height: 100vh; +} +.boxed-container { + max-width: 1440px; + margin: 0 auto; + box-shadow: 0 24px 48px rgba(21, 24, 29, 0.24); + mix-blend-mode: multiply; + mix-blend-mode: normal; +} +main { + flex: 1 0 auto; +} +.section-inner { + position: relative; + padding-top: 48px; + padding-bottom: 48px; +} +@media (min-width: 641px) { + .section-inner { + /* padding-top:88px; */ + padding-bottom: 88px; + } +} +.site-footer { + font-size: 14px; + line-height: 22px; + letter-spacing: 0px; +} +.site-footer a { + color: #8a94a7; + text-decoration: none; +} +.site-footer a:hover, +.site-footer a:active { + text-decoration: underline; +} +.site-footer-inner { + position: relative; + display: flex; + flex-wrap: wrap; + padding-top: 48px; + padding-bottom: 48px; +} +.footer-brand, +.footer-links, +.footer-social-links, +.footer-copyright { + flex: none; + width: 100%; + display: inline-flex; + justify-content: center; +} +.footer-brand, +.footer-links, +.footer-social-links { + margin-bottom: 24px; +} +.footer-social-links li { + display: inline-flex; +} +.footer-social-links li + li { + margin-left: 16px; +} +.footer-social-links li a { + padding: 8px; +} +.footer-links li + li { + margin-left: 24px; +} +@media (min-width: 641px) { + .site-footer { + margin-top: 20px; + } + .site-footer-inner { + justify-content: space-between; + padding-top: 64px; + padding-bottom: 64px; + } + .footer-brand, + .footer-links, + .footer-social-links, + .footer-copyright { + flex: 50%; + } + .footer-brand, + .footer-copyright { + justify-content: flex-start; + } + .footer-links, + .footer-social-links { + justify-content: flex-end; + } + .footer-links { + order: 1; + margin-bottom: 0; + } +} diff --git a/morse/images/cta-illustration.svg b/morse/images/cta-illustration.svg new file mode 100644 index 0000000..c46d2f3 --- /dev/null +++ b/morse/images/cta-illustration.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/morse/images/feature-icon-01.svg b/morse/images/feature-icon-01.svg new file mode 100644 index 0000000..6054299 --- /dev/null +++ b/morse/images/feature-icon-01.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/morse/images/feature-icon-02.svg b/morse/images/feature-icon-02.svg new file mode 100644 index 0000000..62b1193 --- /dev/null +++ b/morse/images/feature-icon-02.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/morse/images/feature-icon-03.svg b/morse/images/feature-icon-03.svg new file mode 100644 index 0000000..ab7bbaa --- /dev/null +++ b/morse/images/feature-icon-03.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/morse/images/feature-icon-04.svg b/morse/images/feature-icon-04.svg new file mode 100644 index 0000000..1ca34e7 --- /dev/null +++ b/morse/images/feature-icon-04.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/morse/images/feature-icon-05.svg b/morse/images/feature-icon-05.svg new file mode 100644 index 0000000..43b4904 --- /dev/null +++ b/morse/images/feature-icon-05.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/morse/images/feature-icon-06.svg b/morse/images/feature-icon-06.svg new file mode 100644 index 0000000..3a0c70d --- /dev/null +++ b/morse/images/feature-icon-06.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/morse/images/hero-back-illustration.svg b/morse/images/hero-back-illustration.svg new file mode 100644 index 0000000..8f0d151 --- /dev/null +++ b/morse/images/hero-back-illustration.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/morse/images/hero-top-illustration.svg b/morse/images/hero-top-illustration.svg new file mode 100644 index 0000000..3eec102 --- /dev/null +++ b/morse/images/hero-top-illustration.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/morse/images/logo.svg b/morse/images/logo.svg new file mode 100644 index 0000000..e2e655c --- /dev/null +++ b/morse/images/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/morse/images/pricing-illustration.svg b/morse/images/pricing-illustration.svg new file mode 100644 index 0000000..982f983 --- /dev/null +++ b/morse/images/pricing-illustration.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/morse/js/main.min.js b/morse/js/main.min.js new file mode 100644 index 0000000..71f079b --- /dev/null +++ b/morse/js/main.min.js @@ -0,0 +1 @@ +!function(){window;const e=document.documentElement;if(e.classList.remove("no-js"),e.classList.add("js"),document.body.classList.contains("has-animations")){(window.sr=ScrollReveal()).reveal(".feature, .pricing-table-inner",{duration:600,distance:"20px",easing:"cubic-bezier(0.5, -0.01, 0, 1.005)",origin:"bottom",interval:100}),e.classList.add("anime-ready"),anime.timeline({targets:".hero-figure-box-05"}).add({duration:400,easing:"easeInOutExpo",scaleX:[.05,.05],scaleY:[0,1],perspective:"500px",delay:anime.random(0,400)}).add({duration:400,easing:"easeInOutExpo",scaleX:1}).add({duration:800,rotateY:"-15deg",rotateX:"8deg",rotateZ:"-1deg"}),anime.timeline({targets:".hero-figure-box-06, .hero-figure-box-07"}).add({duration:400,easing:"easeInOutExpo",scaleX:[.05,.05],scaleY:[0,1],perspective:"500px",delay:anime.random(0,400)}).add({duration:400,easing:"easeInOutExpo",scaleX:1}).add({duration:800,rotateZ:"20deg"}),anime({targets:".hero-figure-box-01, .hero-figure-box-02, .hero-figure-box-03, .hero-figure-box-04, .hero-figure-box-08, .hero-figure-box-09, .hero-figure-box-10",duration:anime.random(600,800),delay:anime.random(600,800),rotate:[anime.random(-360,360),function(e){return e.getAttribute("data-rotation")}],scale:[.7,1],opacity:[0,1],easing:"easeInOutExpo"})}}(); \ No newline at end of file diff --git a/paraizo/favicon.ico b/paraizo/favicon.ico new file mode 100644 index 0000000..0bd66db Binary files /dev/null and b/paraizo/favicon.ico differ diff --git a/paraizo/foto-erick.png b/paraizo/foto-erick.png new file mode 100644 index 0000000..9ba2b2f Binary files /dev/null and b/paraizo/foto-erick.png differ diff --git a/paraizo/foto-henrique.jpg b/paraizo/foto-henrique.jpg new file mode 100644 index 0000000..bee5b42 Binary files /dev/null and b/paraizo/foto-henrique.jpg differ diff --git a/paraizo/foto-marllon.png b/paraizo/foto-marllon.png new file mode 100644 index 0000000..889e565 Binary files /dev/null and b/paraizo/foto-marllon.png differ diff --git a/paraizo/foto-maykon.png b/paraizo/foto-maykon.png new file mode 100644 index 0000000..f27750f Binary files /dev/null and b/paraizo/foto-maykon.png differ diff --git a/paraizo/foto-pedro.png b/paraizo/foto-pedro.png new file mode 100644 index 0000000..4f0658b Binary files /dev/null and b/paraizo/foto-pedro.png differ diff --git a/paraizo/maykon.jpeg b/paraizo/maykon.jpeg new file mode 100644 index 0000000..238c719 Binary files /dev/null and b/paraizo/maykon.jpeg differ diff --git a/paraizo/paraizo.png b/paraizo/paraizo.png new file mode 100644 index 0000000..da3e464 Binary files /dev/null and b/paraizo/paraizo.png differ diff --git a/recursos/instalando/index.html b/recursos/instalando/index.html new file mode 100644 index 0000000..d0a5471 --- /dev/null +++ b/recursos/instalando/index.html @@ -0,0 +1,1250 @@ + + + + + + + + + + + + + + + + + + + + + + + Instalando - Paraizo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

Recursos

+
+Histórico de Revisão + + + + + + + + + + + + + + + + + +
DataVersãoDescriçãoAutor
08/111.0Criação do tópico de DocumentaçãoMaykon Júnio dos Santos Soares
+
+
+

Prepando ambiente virtural

+

Requisitos

+
    +
  • Python 3.12.3 (Latest)
  • +
  • pip 24.3.1
  • +
+

Instalando virtualenv

+
python -m pip install --user virtualenv
+ +

Criando ambiente virtual

+
virtualenv venv
+ +

Ativando ambiente virtual

+
source venv/Scripts/activate
+ +

Instalando pacotes

+
pip install -r requirements.txt
+ +

Iniciando localmente

+
mkdocs serve
+ + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ +
+ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/search/search_index.json b/search/search_index.json new file mode 100644 index 0000000..82d75f6 --- /dev/null +++ b/search/search_index.json @@ -0,0 +1 @@ +{"config":{"lang":["pt"],"separator":"[\\s\\-,:!=\\[\\]()\"`/]+|\\.(?!\\d)|&[lg]t;|(?!\\b)(?=[A-Z][a-z])","pipeline":["stopWordFilter"]},"docs":[{"location":"backlog-produto/backlog/dor-e-dod/","title":"Definition of Ready (DoR) e Definition of Done (DoD)","text":"Hist\u00f3rico de Revis\u00e3o Data Vers\u00e3o Descri\u00e7\u00e3o Autor 01/11 1.0 Cria\u00e7\u00e3o do t\u00f3pico de Backlog do Produto Maykon J\u00fanio dos Santos Soares 15/12 2.0 Adi\u00e7\u00e3o dos artefatos Pedro Miguel M. de O. dos Santos, Maykon J\u00fanio dos Santos Soares Definition of Ready (DoR)Definition of Done (DoD)

Sobre

O DoR \u00e9 um conjunto de crit\u00e9rios que fala sobre quando um item, independente de ser uma hist\u00f3ria, tarefa ou \u00e9pico, est\u00e1 pronto para a equipe de desenvolvimento trabalhar nela ou outro grupo no projeto. O que significa que \u00e9 um acordo feito entre as partes interessadas \u2013 Product Owner, equipe de desenvolvimento, stakeholders, etc. o qual garante clareza, alinhamento e pr\u00e9-requisitos para o trabalho poder ser feito. Os crit\u00e9rios para realiza\u00e7\u00e3o do DoR ser\u00e3o listados abaixo:

Crit\u00e9rio Descri\u00e7\u00e3o Clareza A descri\u00e7\u00e3o da hist\u00f3ria deve estar clara e bem compreendida. Deve seguir o formato \u201cEu como\u2026 quero\u2026 para\u2026\u201d com detalhes suficientes para a equipe entender o que precisa ser feito. Crit\u00e9rios de Aceita\u00e7\u00e3o Os crit\u00e9rios de aceita\u00e7\u00e3o devem estar definidos para garantir que os objetivos do requisito sejam entendidos. Prioriza\u00e7\u00e3o O requisito deve ter sido priorizado e ter um valor definido para o neg\u00f3cio, alinhado com os objetivos do projeto. Depend\u00eancia Todas as depend\u00eancias do requisito precisam ser identificadas e tratadas para que o desenvolvimento possa prosseguir. Valida\u00e7\u00e3o O requisito deve ser analisado e aprovado pelo Product Owner para garantir que est\u00e1 alinhado com as necessidades dele. Tamanho O item precisa ter um tamanho adequado para ser completado dentro de uma sprint ou per\u00edodo estipulado.

Sobre

O Definition of Done (DoD) \u00e9 usado para garantir a qualidade e a consist\u00eancia do trabalho entregue pela equipe a partir de uma defini\u00e7\u00e3o clara e objetiva de crit\u00e9rios que precisam ser atendidos para que um item do backlog (User Story) seja considerado como conclu\u00eddo. A seguir, ser\u00e1 apresentado os crit\u00e9rios escolhidos pela equipe para composi\u00e7\u00e3o do DoD:

Crit\u00e9rio Descri\u00e7\u00e3o C\u00f3digo segue os padr\u00f5es do projeto O c\u00f3digo deve respeitar os padr\u00f5es estabelecidos pela equipe, como padroniza\u00e7\u00e3o de tecnologias, bibliotecas, nomenclaturas e coment\u00e1rios de c\u00f3digo. C\u00f3digo submetido a testes O c\u00f3digo deve passar por testes unit\u00e1rios, de integra\u00e7\u00e3o e end to end. Respeitar os crit\u00e9rios de aceite da User Story O c\u00f3digo deve atender aos crit\u00e9rios de aceita\u00e7\u00e3o espec\u00edficos da User Story. C\u00f3digo aprovado pelo QA O c\u00f3digo deve passar por uma revis\u00e3o de QA e ser aprovado antes da entrega. Entrega segue os padr\u00f5es definidos no prot\u00f3tipo O c\u00f3digo deve estar conforme o design prototipado, ser responsivo e seguir as diretrizes de acessibilidade da WCAG. C\u00f3digo da User Story deve estar documentado A nova funcionalidade deve ser documentada para facilitar manuten\u00e7\u00e3o futura. C\u00f3digo deve estar livre de bugs O c\u00f3digo deve ser verificado para garantir que n\u00e3o tenha bugs de qualquer severidade."},{"location":"backlog-produto/backlog/funcionais/","title":"Requisitos Funcionais","text":"Hist\u00f3rico de Revis\u00e3o Data Vers\u00e3o Descri\u00e7\u00e3o Autor 01/11 1.0 Cria\u00e7\u00e3o do t\u00f3pico de Backlog do Produto Maykon J\u00fanio dos Santos Soares 15/12 2.0 Adi\u00e7\u00e3o dos artefatos Pedro Miguel M. de O. dos Santos, Maykon J\u00fanio dos Santos Soares 03/01 2.2 Corre\u00e7\u00e3o da lista de requisitos e separa\u00e7\u00e3o dos arquivos Pedro Miguel M. de O. dos Santos"},{"location":"backlog-produto/backlog/funcionais/#requisitos","title":"Requisitos","text":"\u00cdndice Requisitos Funcionais RF01 Cadastrar depoimento RF02 Aprovar depoimento RF03 Consultar depoimento RF04 Editar depoimento RF05 Excluir depoimento RF06 Cadastrar atendimento na agenda RF07 Editar atendimento na agenda RF08 Excluir atendimento na agenda RF09 Consultar atendimento na agenda RF10 Cadastrar perfil usu\u00e1rio administrador RF11 Editar perfil usu\u00e1rio administrador RF12 Excluir perfil usu\u00e1rio administrador RF13 Consultar perfil usu\u00e1rio administrador RF14 Cadastrar perfil usu\u00e1rio paciente RF15 Editar perfil usu\u00e1rio paciente RF16 Excluir perfil usu\u00e1rio paciente RF17 Consultar perfil usu\u00e1rio paciente RF18 Autenticar perfil RF19 Recuperar senha RF20 Cadastrar ficha do paciente RF21 Editar ficha do paciente RF22 Excluir ficha do paciente RF23 Consultar ficha do paciente RF24 Cadastrar relat\u00f3rio de avalia\u00e7\u00e3o RF25 Editar relat\u00f3rio de avalia\u00e7\u00e3o RF26 Excluir relat\u00f3rio de avalia\u00e7\u00e3o RF27 Visualizar relat\u00f3rios de avalia\u00e7\u00e3o RF28 Salvar relat\u00f3rio de avalia\u00e7\u00e3o do paciente RF29 Visualizar relat\u00f3rio de avalia\u00e7\u00e3o do paciente"},{"location":"backlog-produto/backlog/historias-de-usuario/","title":"Hist\u00f3rias de Usu\u00e1rio","text":"Hist\u00f3rico de Revis\u00e3o Data Vers\u00e3o Descri\u00e7\u00e3o Autor 01/11 1.0 Cria\u00e7\u00e3o do t\u00f3pico de Backlog do Produto Maykon J\u00fanio dos Santos Soares 15/12 2.0 Adi\u00e7\u00e3o dos artefatos Pedro Miguel M. de O. dos Santos, Maykon J\u00fanio dos Santos Soares 03/01 2.2 Separa\u00e7\u00e3o do arquivo incluso em requisitos funcionais para esse daqui Pedro Miguel M. de O. dos Santos"},{"location":"backlog-produto/backlog/historias-de-usuario/#organizacao","title":"Organiza\u00e7\u00e3o","text":"Temas\u00c9picosHist\u00f3rias de Usu\u00e1rio Temas \u00c9picos [TM01] Gest\u00e3o de Depoimentos [EP01] [TM02] Gest\u00e3o de Atendimento [EP02] [TM03] Gest\u00e3o de Usu\u00e1rio [EP03], [EP04], [EP05] [TM04] Gest\u00e3o de Documentos [EP06], [EP07], [EP08] \u00c9picos Hist\u00f3rias de Usu\u00e1rio [EP01] Gest\u00e3o de Depoimentos [US01], [US02], [US03], [US04], [US05] [EP02] Gest\u00e3o de Atendimento [US06], [US07], [US08], [US09] [EP03] Gest\u00e3o de Administradores [US10], [US11], [US12], [US13] [EP04] Gest\u00e3o do Cliente [US14], [US15], [US16], [US17] [EP05] Autentica\u00e7\u00e3o do Usu\u00e1rio [US18], [US19] [EP06] Gest\u00e3o da Ficha do Cliente [US20], [US21], [US22], [US23] [EP07] Gest\u00e3o de Relat\u00f3rio do Cliente [US24], [US25], [US26], [US27] [EP08] Visualiza\u00e7\u00e3o e Salvamento Relat\u00f3rios [US28], [US29] Temas \u00c9picos Hist\u00f3rias de Usu\u00e1rio [TM01] Gest\u00e3o de Depoimentos [EP01] Gest\u00e3o de Depoimentos [US01] Eu, como usu\u00e1rio, desejo registrar depoimentos para relatar minha experi\u00eancia. [TM01] Gest\u00e3o de Depoimentos [EP01] Gest\u00e3o de Depoimentos [US02] Eu, como administrador, desejo aprovar depoimentos para manter o controle sobre os relatos. [TM01] Gest\u00e3o de Depoimentos [EP01] Gest\u00e3o de Depoimentos [US03] Eu, como administrador, desejo consultar depoimentos para manter o controle dos relatos. [TM01] Gest\u00e3o de Depoimentos [EP01] Gest\u00e3o de Depoimentos [US04] Eu, como administrador, desejo editar depoimentos para manter o controle dos relatos. [TM01] Gest\u00e3o de Depoimentos [EP01] Gest\u00e3o de Depoimentos [US05] Eu, como administrador, desejo excluir depoimentos para manter o controle dos relatos. [TM02] Gest\u00e3o de Atendimento [EP02] Gest\u00e3o de Atendimento [US06] Eu, como usu\u00e1rio, desejo cadastrar um hor\u00e1rio de atendimento em qualquer modalidade oferecida. [TM02] Gest\u00e3o de Atendimento [EP02] Gest\u00e3o de Atendimento [US07] Eu, como usu\u00e1rio, desejo editar um hor\u00e1rio de atendimento em qualquer modalidade oferecida. [TM02] Gest\u00e3o de Atendimento [EP02] Gest\u00e3o de Atendimento [US08] Eu, como usu\u00e1rio, desejo excluir um hor\u00e1rio de atendimento em qualquer modalidade oferecida. [TM02] Gest\u00e3o de Atendimento [EP02] Gest\u00e3o de Atendimento [US09] Eu, como usu\u00e1rio, desejo consultar um hor\u00e1rio de atendimento em qualquer modalidade oferecida. [TM03] Gest\u00e3o de Usu\u00e1rio [EP03] Gest\u00e3o de Administradores [US10] Eu, como administrador, desejo me cadastrar no sistema para utilizar funcionalidades. [TM03] Gest\u00e3o de Usu\u00e1rio [EP03] Gest\u00e3o de Administradores [US11] Eu, como administrador, desejo editar meu perfil para corrigir informa\u00e7\u00f5es. [TM03] Gest\u00e3o de Usu\u00e1rio [EP03] Gest\u00e3o de Administradores [US12] Eu, como administrador, devo excluir meu perfil para remover qualquer v\u00ednculo com o sistema. [TM03] Gest\u00e3o de Usu\u00e1rio [EP03] Gest\u00e3o de Administradores [US13] Eu, como administrador, desejo consultar meu pr\u00f3prio perfil para verificar minhas informa\u00e7\u00f5es. [TM03] Gest\u00e3o de Usu\u00e1rio [EP04] Gest\u00e3o do Cliente [US14] Eu, como cliente, desejo me cadastrar no sistema para acessar funcionalidades de cliente. [TM03] Gest\u00e3o de Usu\u00e1rio [EP04] Gest\u00e3o do Cliente [US15] Eu, como cliente, desejo editar meu perfil para corrigir informa\u00e7\u00f5es incorretas. [TM03] Gest\u00e3o de Usu\u00e1rio [EP04] Gest\u00e3o do Cliente [US16] Eu, como cliente, desejo excluir meu perfil para remover qualquer v\u00ednculo com o site. [TM03] Gest\u00e3o de Usu\u00e1rio [EP04] Gest\u00e3o do Cliente [US17] Eu, como cliente, desejo consultar meu perfil para verificar minhas informa\u00e7\u00f5es. [TM03] Gest\u00e3o de Usu\u00e1rio [EP05] Autentica\u00e7\u00e3o do Usu\u00e1rio [US18] Eu, como usu\u00e1rio, desejo autenticar meu perfil para acessar funcionalidades. [TM03] Gest\u00e3o de Usu\u00e1rio [EP05] Autentica\u00e7\u00e3o do Usu\u00e1rio [US19] Eu, como usu\u00e1rio, desejo recuperar minha senha para voltar a acessar meu perfil. [TM04] Gest\u00e3o de Documentos [EP06] Gest\u00e3o da Ficha do Cliente [US20] Eu, como administrador, desejo cadastrar a ficha do paciente para preencher seus dados. [TM04] Gest\u00e3o de Documentos [EP06] Gest\u00e3o da Ficha do Cliente [US21] Eu, como administrador, desejo editar a ficha do paciente para alterar dados m\u00e9dicos. [TM04] Gest\u00e3o de Documentos [EP06] Gest\u00e3o da Ficha do Cliente [US22] Eu, como administrador, desejo excluir a ficha do paciente para manter dados atualizados. [TM04] Gest\u00e3o de Documentos [EP06] Gest\u00e3o da Ficha do Cliente [US23] Eu, como administrador, desejo consultar a ficha do paciente para verificar seus dados. [TM04] Gest\u00e3o de Documentos [EP07] Gest\u00e3o de Relat\u00f3rio do Cliente [US24] Eu, como administrador, desejo criar um relat\u00f3rio de avalia\u00e7\u00e3o de um paciente. [TM04] Gest\u00e3o de Documentos [EP07] Gest\u00e3o de Relat\u00f3rio do Cliente [US25] Eu, como administrador, desejo editar os relat\u00f3rios de avalia\u00e7\u00e3o dos pacientes. [TM04] Gest\u00e3o de Documentos [EP07] Gest\u00e3o de Relat\u00f3rio do Cliente [US26] Eu, como administrador, desejo excluir um relat\u00f3rio de avalia\u00e7\u00e3o de um paciente. [TM04] Gest\u00e3o de Documentos [EP07] Gest\u00e3o de Relat\u00f3rio do Cliente [US27] Eu, como administrador, desejo visualizar os relat\u00f3rios de avalia\u00e7\u00e3o dos pacientes. [TM04] Gest\u00e3o de Documentos [EP08] Visualiza\u00e7\u00e3o e Salvamento Relat\u00f3rios [US28] Eu, como usu\u00e1rio, desejo salvar meu relat\u00f3rio de avalia\u00e7\u00e3o no formato .pdf. [TM04] Gest\u00e3o de Documentos [EP08] Visualiza\u00e7\u00e3o e Salvamento Relat\u00f3rios [US29] Eu, como usu\u00e1rio, desejo visualizar meus relat\u00f3rios de avalia\u00e7\u00e3o."},{"location":"backlog-produto/backlog/historias-de-usuario/#criterios-de-aceitacao","title":"Crit\u00e9rios de Aceita\u00e7\u00e3o","text":"Hist\u00f3ria de Usu\u00e1rio Crit\u00e9rios de Aceita\u00e7\u00e3o [US01] Eu, como usu\u00e1rio, desejo registrar depoimentos para relatar minha experi\u00eancia - O sistema deve disponibilizar uma \u00e1rea voltada para pacientes, para que o usu\u00e1rio possa colocar um depoimento.- O sistema deve garantir que seja poss\u00edvel colocar depoimentos em texto, fotos e v\u00eddeos.- O sistema deve disponibilizar uma escala de 0 a 5 onde o paciente classificar\u00e1 o atendimento prestado pela cl\u00ednica. [US02] Eu, como administrador, desejo aprovar depoimentos para manter o controle sobre os relatos apresentados. - O sistema deve ter uma \u00e1rea dispon\u00edvel para administradores, onde a rela\u00e7\u00e3o de depoimentos que est\u00e3o aparecendo na landing page.- O sistema deve garantir que seja poss\u00edvel ver depoimentos pendentes de aprova\u00e7\u00e3o.- O sistema deve garantir que administradores possam aprovar ou excluir depoimentos.- O sistema deve garantir que tenha um alerta de confirma\u00e7\u00e3o de escolha antes da aprova\u00e7\u00e3o de qualquer depoimento. [US03] Eu, como administrador, desejo consultar depoimentos para manter o controle sobre os relatos apresentados. - O sistema deve disponibilizar uma \u00e1rea na landing page para que sejam apresentados os depoimentos aprovados previamente pelo administrador.- O sistema deve garantir uma \u00e1rea restrita para visualizar depoimentos feitos pelos pacientes.- O sistema deve garantir uma \u00e1rea com todos os depoimentos de todos os pacientes dispon\u00edveis para o administrador visualizar. [US04] Eu, como administrador, desejo editar depoimentos para manter o controle sobre os relatos apresentados. - O sistema deve garantir que o usu\u00e1rio, ap\u00f3s postar um novo depoimento, tamb\u00e9m possa fazer a edi\u00e7\u00e3o de seu conte\u00fado (textos, fotos e v\u00eddeos), necessitando de aprova\u00e7\u00e3o posterior de um administrador.- O sistema deve garantir que tenha um alerta de confirma\u00e7\u00e3o de escolha antes da edi\u00e7\u00e3o de qualquer depoimento. [US05] Eu, como administrador, desejo excluir depoimentos para manter o controle sobre os relatos apresentados. - O sistema deve garantir que o paciente possa excluir seus depoimentos.- O sistema deve garantir que administradores possam excluir qualquer depoimento.- O sistema deve garantir que tenha um alerta de confirma\u00e7\u00e3o de escolha antes da exclus\u00e3o de qualquer depoimento. [US06] Eu, como usu\u00e1rio, desejo cadastrar um hor\u00e1rio de atendimento em qualquer modalidade oferecida. - O sistema deve exibir uma lista das modalidades dispon\u00edveis, como Fisioterapia, Personal Trainer, Treinamento em Grupo, entre outras, para que o usu\u00e1rio selecione a modalidade desejada antes de cadastrar o hor\u00e1rio de atendimento.- O sistema deve permitir que o usu\u00e1rio informe a data de in\u00edcio e fim (ou uma \u00fanica data para atendimentos pontuais), al\u00e9m da hora de in\u00edcio e t\u00e9rmino do atendimento. [US07] Eu, como usu\u00e1rio, desejo editar um hor\u00e1rio de atendimento em qualquer modalidade oferecida. - O sistema deve permitir que o usu\u00e1rio selecione um hor\u00e1rio de atendimento previamente cadastrado para edi\u00e7\u00e3o.- O sistema deve permitir que o usu\u00e1rio altere a data, hor\u00e1rio, profissional ou local do atendimento.- O sistema deve exibir uma mensagem confirmando que as altera\u00e7\u00f5es foram salvas com sucesso. [US08] Eu, como usu\u00e1rio, desejo excluir um hor\u00e1rio de atendimento em qualquer modalidade oferecida. - O sistema deve permitir que o usu\u00e1rio selecione um hor\u00e1rio de atendimento previamente cadastrado para exclus\u00e3o.- O sistema deve solicitar a confirma\u00e7\u00e3o do usu\u00e1rio antes de excluir o hor\u00e1rio, exibindo uma mensagem como: \"Tem certeza de que deseja excluir este hor\u00e1rio?\".- Ap\u00f3s a exclus\u00e3o, o sistema deve exibir uma mensagem clara confirmando que o hor\u00e1rio foi exclu\u00eddo com sucesso. [US09] Eu, como usu\u00e1rio, desejo consultar um hor\u00e1rio de atendimento em qualquer modalidade oferecida. - O sistema deve permitir que o usu\u00e1rio filtre os hor\u00e1rios de atendimento por modalidade (ex.: Fisioterapia, Personal Trainer, etc.).- O sistema deve permitir que o usu\u00e1rio filtre os hor\u00e1rios por data espec\u00edfica, intervalo de datas ou hor\u00e1rio.- O sistema deve exibir os hor\u00e1rios encontrados de forma clara e organizada, incluindo informa\u00e7\u00f5es como data, hor\u00e1rio, profissional respons\u00e1vel e local (presencial ou remoto).- O sistema deve permitir que o usu\u00e1rio busque hor\u00e1rios associados a um profissional ou cliente espec\u00edfico. [US10] Eu, como administrador, desejo me cadastrar no sistema, para conseguir utilizar as funcionalidades de administrador. - O sistema deve disponibilizar um formul\u00e1rio onde o administrador possa preencher as informa\u00e7\u00f5es necess\u00e1rias, como nome, e-mail, senha e, se aplic\u00e1vel, cargo ou organiza\u00e7\u00e3o.- O sistema deve validar os campos obrigat\u00f3rios e exibir mensagens claras caso alguma informa\u00e7\u00e3o esteja incorreta ou ausente.- O sistema deve exigir uma senha com crit\u00e9rios m\u00ednimos de seguran\u00e7a (ex.: pelo menos 8 caracteres, incluindo letras mai\u00fasculas, min\u00fasculas, n\u00fameros e caracteres especiais).- Ap\u00f3s completar o cadastro com sucesso, o sistema deve exibir uma mensagem confirmando que o administrador foi registrado e orientando sobre os pr\u00f3ximos passos, como ativa\u00e7\u00e3o do e-mail. [US11] Eu, como administrador, desejo editar meu perfil para alterar informa\u00e7\u00f5es que estejam incorretas. - O sistema deve permitir que o administrador acesse uma p\u00e1gina ou se\u00e7\u00e3o dedicada para edi\u00e7\u00e3o de perfil.- O sistema deve permitir que o administrador altere informa\u00e7\u00f5es como nome, e-mail, senha e outros dados pessoais ou profissionais cadastrados.- O sistema deve validar os campos editados e exibir mensagens claras caso alguma informa\u00e7\u00e3o esteja incorreta ou n\u00e3o atenda aos crit\u00e9rios (ex.: e-mail inv\u00e1lido, senha insegura).- Para altera\u00e7\u00f5es sens\u00edveis, como senha ou e-mail, o sistema deve solicitar a senha atual para confirmar a identidade do administrador. [US12] Eu, como administrador, devo excluir meu perfil do sistema para remover qualquer v\u00ednculo com o site. - O administrador deve ter acesso \u00e0 op\u00e7\u00e3o de excluir seu perfil.- O sistema deve exibir uma confirma\u00e7\u00e3o de exclus\u00e3o.- O sistema deve apresentar uma mensagem de que o perfil foi exclu\u00eddo.- O sistema deve remover o perfil e todas as suas associa\u00e7\u00f5es ap\u00f3s a exclus\u00e3o. [US13] Eu, como administrador, desejo consultar meu pr\u00f3prio perfil para verificar minhas informa\u00e7\u00f5es. - O administrador deve ter acesso \u00e0 op\u00e7\u00e3o de exibir seu perfil.- O sistema deve exibir todas as informa\u00e7\u00f5es associadas, como nome, e-mail, etc. [US14] Eu, como cliente, desejo me cadastrar no sistema para conseguir utilizar as funcionalidades correspondentes ao n\u00edvel do cliente. - O sistema deve disponibilizar um formul\u00e1rio para o usu\u00e1rio preencher suas informa\u00e7\u00f5es, como nome, e-mail e senha.- O sistema deve validar campos obrigat\u00f3rios e exibir mensagens claras caso alguma informa\u00e7\u00e3o esteja incorreta ou ausente.- O sistema deve exigir uma senha com crit\u00e9rios m\u00ednimos de seguran\u00e7a (ex.: pelo menos 8 caracteres, incluindo letras mai\u00fasculas, min\u00fasculas, n\u00fameros e caracteres especiais).- O sistema deve exibir uma mensagem de confirma\u00e7\u00e3o ap\u00f3s o cadastro. [US15] Eu, como cliente, desejo editar meu perfil para alterar informa\u00e7\u00f5es que estejam incorretas. - O paciente deve ter acesso \u00e0 op\u00e7\u00e3o de editar seu perfil.- O sistema deve disponibilizar campos de preenchimento nas informa\u00e7\u00f5es edit\u00e1veis como nome e senha.- O sistema deve exibir uma mensagem de confirma\u00e7\u00e3o de edi\u00e7\u00f5es.- O sistema deve validar e salvar as altera\u00e7\u00f5es realizadas. [US16] Eu, como cliente, desejo excluir meu perfil do sistema para remover qualquer v\u00ednculo com o site. - O paciente deve ter acesso \u00e0 op\u00e7\u00e3o de excluir seu perfil.- O sistema deve exibir uma confirma\u00e7\u00e3o de exclus\u00e3o.- O sistema deve apresentar uma mensagem de que o perfil foi exclu\u00eddo.- O sistema deve remover o perfil e todas as suas associa\u00e7\u00f5es ap\u00f3s a exclus\u00e3o. [US17] Eu, como cliente, desejo consultar meu pr\u00f3prio perfil para verificar minhas informa\u00e7\u00f5es. - O paciente deve ter acesso \u00e0 op\u00e7\u00e3o de exibir seu perfil.- O sistema deve exibir todas as informa\u00e7\u00f5es associadas, como nome, e-mail, etc. [US18] Eu, como usu\u00e1rio, desejo autenticar meu perfil para acessar funcionalidades correspondentes ao n\u00edvel do usu\u00e1rio. - O sistema deve apresentar uma tela de login com campos para \"Usu\u00e1rio\" e \"Senha\".- O usu\u00e1rio deve ser redirecionado para a tela correspondente ao seu n\u00edvel de acesso ap\u00f3s login bem-sucedido.- Caso o usu\u00e1rio insira dados inv\u00e1lidos, o sistema deve exibir uma mensagem de erro: \"Usu\u00e1rio ou senha inv\u00e1lidos\".- O sistema deve permitir ao usu\u00e1rio tentar novamente ou acessar a op\u00e7\u00e3o de \"Recuperar senha\". [US19] Eu, como usu\u00e1rio, desejo recuperar minha senha para voltar a acessar meu perfil. - O sistema deve oferecer uma op\u00e7\u00e3o \"Esqueci minha senha\" na tela de login.- O sistema deve solicitar o e-mail cadastrado para recupera\u00e7\u00e3o de senha.- O sistema deve enviar um link seguro para redefinir a senha ao e-mail informado.- O link de redefini\u00e7\u00e3o de senha deve expirar em 24 horas por quest\u00f5es de seguran\u00e7a.- Ap\u00f3s a redefini\u00e7\u00e3o, a nova senha deve ser v\u00e1lida para login.- O sistema deve exibir uma mensagem de sucesso ap\u00f3s a senha ser alterada: \"Sua senha foi redefinida com sucesso.\" [US20] Eu, como administrador, desejo cadastrar a ficha do paciente para preencher seus dados m\u00e9dicos, consultas e tratamentos. - O sistema deve permitir cadastrar uma nova ficha com os seguintes campos obrigat\u00f3rios: - Nome completo do paciente - CPF - Data de nascimento - Contato (telefone e e-mail) - Dados m\u00e9dicos iniciais (diagn\u00f3stico, tratamentos recomendados).- O sistema deve validar se o CPF j\u00e1 existe para evitar duplica\u00e7\u00f5es.- O sistema deve notificar o sucesso do cadastro com a mensagem: \"Ficha cadastrada com sucesso.\"- O sistema deve permitir que o administrador visualize a ficha logo ap\u00f3s o cadastro. [US21] Eu, como administrador, desejo editar a ficha do paciente a fim de adicionar ou remover dados m\u00e9dicos, tratamentos e consultas. - O sistema deve permitir editar qualquer campo da ficha do paciente.- O sistema deve validar as altera\u00e7\u00f5es e evitar campos obrigat\u00f3rios vazios.- O sistema deve registrar a data e o hor\u00e1rio da \u00faltima edi\u00e7\u00e3o.- O sistema deve apresentar um resumo das altera\u00e7\u00f5es feitas.- O sistema deve exibir uma mensagem de sucesso ap\u00f3s a edi\u00e7\u00e3o: \"Ficha atualizada com sucesso.\" [US22] Eu, como administrador, desejo excluir a ficha do paciente para manter somente os pacientes ativos em minha lista. - O sistema deve solicitar uma confirma\u00e7\u00e3o de exclus\u00e3o antes de apagar a ficha do paciente.- A ficha exclu\u00edda deve ser removida da lista principal de pacientes ativos.- O sistema deve registrar um hist\u00f3rico da exclus\u00e3o com os seguintes dados: - Nome do paciente - Data e hor\u00e1rio da exclus\u00e3o - Usu\u00e1rio respons\u00e1vel pela exclus\u00e3o.- O sistema deve impedir a exclus\u00e3o de fichas vinculadas a tratamentos ativos.- O sistema deve exibir a mensagem: \"Ficha exclu\u00edda com sucesso.\" [US23] Eu, como administrador, desejo consultar a ficha do paciente para verificar seus dados cadastrados. - O sistema deve permitir buscar fichas de pacientes usando os seguintes crit\u00e9rios: - Nome completo - CPF - Data de nascimento.- O sistema deve exibir os dados completos da ficha, incluindo: - Dados pessoais do paciente (nome, CPF, contato, etc.) - Hist\u00f3rico de consultas e tratamentos - Diagn\u00f3stico atual.- O sistema deve permitir filtrar registros por data de cadastro ou \u00faltima atualiza\u00e7\u00e3o.- O sistema deve exibir uma mensagem caso nenhum registro seja encontrado: \"Nenhuma ficha encontrada para os crit\u00e9rios informados.\" [US24] Eu, como administrador, desejo criar um relat\u00f3rio de avalia\u00e7\u00e3o de um paciente para documentar o andamento do tratamento do mesmo. - O relat\u00f3rio deve conter todos os campos existentes nos documentos fornecidos pela cliente.- O usu\u00e1rio deve poder criar tr\u00eas tipos de relat\u00f3rio diferentes: de RPG, de Pilates, de Avalia\u00e7\u00e3o Neurol\u00f3gica ou de Avalia\u00e7\u00e3o Uroginecol\u00f3gica.- Cada relat\u00f3rio deve conter as informa\u00e7\u00f5es espec\u00edficas do paciente e as informa\u00e7\u00f5es espec\u00edficas do tipo de relat\u00f3rio.- O relat\u00f3rio criado pelo administrador deve ser associado a um usu\u00e1rio, de forma que o paciente seja capaz de visualizar seu relat\u00f3rio em sua conta de usu\u00e1rio.- O relat\u00f3rio criado deve ser devidamente adicionado ao banco de dados. [US25] Eu, como administrador, desejo editar os relat\u00f3rios de avalia\u00e7\u00e3o dos pacientes. - As edi\u00e7\u00f5es feitas no relat\u00f3rio devem ser salvas no banco de dados.- As p\u00e1ginas envolvidas nessa User Story devem respeitar o design definido no prot\u00f3tipo.- As p\u00e1ginas envolvidas nessa User Story devem respeitar o design responsivo.- As p\u00e1ginas envolvidas nessa User Story devem respeitar as diretrizes de acessibilidade da WCAG. [US26] Eu, como administrador, desejo excluir um relat\u00f3rio de avalia\u00e7\u00e3o de um paciente. - O relat\u00f3rio exclu\u00eddo n\u00e3o deve ser apagado do banco de dados, mas sim marcado como \"inativo\".- As p\u00e1ginas envolvidas nessa User Story devem respeitar o design definido no prot\u00f3tipo.- As p\u00e1ginas envolvidas nessa User Story devem respeitar o design responsivo.- As p\u00e1ginas envolvidas nessa User Story devem respeitar as diretrizes de acessibilidade da WCAG.- O paciente e o administrador n\u00e3o devem ser capazes de visualizar um relat\u00f3rio exclu\u00eddo. [US27] Eu, como administrador, desejo visualizar os relat\u00f3rios de avalia\u00e7\u00e3o dos pacientes. - O administrador deve ser capaz de visualizar todos os relat\u00f3rios de avalia\u00e7\u00e3o.- O administrador deve ser capaz de identificar a qual usu\u00e1rio o relat\u00f3rio est\u00e1 vinculado.- As p\u00e1ginas envolvidas nessa User Story devem respeitar o design definido no prot\u00f3tipo.- As p\u00e1ginas envolvidas nessa User Story devem respeitar o design responsivo.- As p\u00e1ginas envolvidas nessa User Story devem respeitar as diretrizes de acessibilidade da WCAG. [US28] Eu, como usu\u00e1rio, desejo salvar meu relat\u00f3rio de avalia\u00e7\u00e3o no formato .pdf. - O relat\u00f3rio salvo pelo paciente deve seguir o template fornecido pela cliente.- O paciente deve poder exportar qualquer tipo de relat\u00f3rio (de RPG, de Pilates, de Avalia\u00e7\u00e3o Neurol\u00f3gica ou de Avalia\u00e7\u00e3o Uroginecol\u00f3gica).- O relat\u00f3rio deve conter as informa\u00e7\u00f5es registradas pelo administrador ao ter criado e/ou editado o relat\u00f3rio.- O paciente n\u00e3o deve ser capaz de exportar um relat\u00f3rio exclu\u00eddo pelo administrador.- As p\u00e1ginas envolvidas nessa User Story devem respeitar o design definido no prot\u00f3tipo.- As p\u00e1ginas envolvidas nessa User Story devem respeitar o design responsivo.- As p\u00e1ginas envolvidas nessa User Story devem respeitar as diretrizes de acessibilidade da WCAG.- O relat\u00f3rio poder\u00e1 ser exportado quantas vezes forem necess\u00e1rias. [US29] Eu, como usu\u00e1rio, desejo visualizar meus relat\u00f3rios de avalia\u00e7\u00e3o. - O paciente deve ser capaz de visualizar todos os relat\u00f3rios vinculados \u00e0 sua conta de usu\u00e1rio.- O usu\u00e1rio deve ser capaz de visualizar seus relat\u00f3rios sem a necessidade de exportar o documento em formato .pdf.- As p\u00e1ginas envolvidas nessa User Story devem respeitar o design definido no prot\u00f3tipo.- As p\u00e1ginas envolvidas nessa User Story devem respeitar o design responsivo.- As p\u00e1ginas envolvidas nessa User Story devem respeitar as diretrizes de acessibilidade da WCAG."},{"location":"backlog-produto/backlog/nao-funcionais/","title":"Requisitos N\u00e3o Funcionais","text":"Hist\u00f3rico de Revis\u00e3o Data Vers\u00e3o Descri\u00e7\u00e3o Autor 01/11 -0 Cria\u00e7\u00e3o do t\u00f3pico de Backlog do Produto Maykon J\u00fanio dos Santos Soares 15/12 -0 Adi\u00e7\u00e3o dos artefatos Pedro Miguel M. de O. dos Santos, Maykon J\u00fanio dos Santos Soares"},{"location":"backlog-produto/backlog/nao-funcionais/#requisitos","title":"Requisitos","text":"Requisito URPS+ [RNF01] Oferecer uma interface responsiva Usabilidade [RNF02] Oferecer n\u00edvel de acessibilidade AA (WCAG -2) Usabilidade [RNF03] Implementar SEO Suportabilidade [RNF04] Implementar protocolo HTTPS Suportabilidade [RNF05] Otimizar v\u00eddeos e imagens Performance"},{"location":"backlog-produto/backlog/nao-funcionais/#criterios-de-aceitacao","title":"Crit\u00e9rios de Aceita\u00e7\u00e3o","text":"Requisito Crit\u00e9rios de Aceita\u00e7\u00e3o [RNF01] Oferecer uma interface responsiva - A interface deve ajustar seu layout para uma largura de tela variando de 320px a 1920px. - O layout deve manter a funcionalidade completa em dispositivos m\u00f3veis (smartphones e tablets), incluindo navega\u00e7\u00e3o e intera\u00e7\u00e3o com elementos. - O layout deve funcionar de forma consistente nos navegadores Chrome, Firefox e Safari, com o mesmo comportamento e apresenta\u00e7\u00e3o visual. [RNF02] Oferecer n\u00edvel de acessibilidade AA (WCAG -2) - O site deve permitir navega\u00e7\u00e3o completa utilizando apenas o teclado, sem a necessidade de interagir com o mouse. - Todo texto no site deve ter um contraste m\u00ednimo de 4.5:1 em rela\u00e7\u00e3o ao fundo, conforme as diretrizes WCAG. - Todo conte\u00fado multim\u00eddia, como v\u00eddeos e \u00e1udios, deve ter legendas ou transcri\u00e7\u00f5es dispon\u00edveis para garantir que usu\u00e1rios com defici\u00eancia auditiva possam acessar as informa\u00e7\u00f5es. [RNF03] Implementar SEO - O site deve conter meta tags apropriadas em todas as p\u00e1ginas, como t\u00edtulo, descri\u00e7\u00e3o e palavras-chave, para melhorar a indexa\u00e7\u00e3o nos motores de busca. - As URLs devem ser curtas, descritivas e utilizar palavras-chave relevantes. - O conte\u00fado das p\u00e1ginas deve ser relevante para o p\u00fablico-alvo e incluir palavras-chave relacionadas ao neg\u00f3cio e temas de interesse. [RNF04] Implementar protocolo HTTPS - O site deve ser carregado exclusivamente via HTTPS, com redirecionamento autom\u00e1tico de qualquer requisi\u00e7\u00e3o HTTP para HTTPS. - O certificado SSL do site deve ser v\u00e1lido e configurado para renova\u00e7\u00e3o autom\u00e1tica antes de expirar. - O navegador deve exibir o \u00edcone de cadeado verde na barra de endere\u00e7o para indicar uma conex\u00e3o segura. [RNF05] Otimizar v\u00eddeos e imagens - Os v\u00eddeos devem ser otimizados para garantir que sejam carregados rapidamente, com tamanho de arquivo reduzido sem perda de qualidade percept\u00edvel. - O tempo total de carregamento das p\u00e1ginas que cont\u00eam conte\u00fado multim\u00eddia n\u00e3o deve exceder 3 segundos ap\u00f3s a requisi\u00e7\u00e3o da p\u00e1gina."},{"location":"backlog-produto/entregas/","title":"Entregas","text":"Hist\u00f3rico de Revis\u00e3o Data Vers\u00e3o Descri\u00e7\u00e3o Autor 16/12 1.0 Cria\u00e7\u00e3o do t\u00f3pico MVP Henrique Martins Alencar"},{"location":"backlog-produto/entregas/#mvp","title":"MVP","text":"User Story Justificativa [US01] Cadastrar ficha do paciente [US04] Editar ficha do paciente [US05] Consultar ficha do paciente [US08] Excluir ficha do paciente [US06] Autenticar usu\u00e1rio O administrador deve conseguir criar e gerenciar fichas dos pacientes para a realiza\u00e7\u00e3o dos atendimentos. [US13] Exluir perfil usu\u00e1rio administrador [US02] Cadastrar perfil usu\u00e1rio administrador [US07] Cadastrar perfil usu\u00e1rio paciente [US16] Editar perfil usu\u00e1rio administrador [US17] Editar perfil usu\u00e1rio paciente [US18] Recuperar senha [US19] Consultar perfil usu\u00e1rio administrador [US20] Consultar perfil usu\u00e1rio paciente [US24] Exluir perfil usu\u00e1rio paciente Os usu\u00e1rios devem conseguir se cadastrar e gerencias suas contas para conseguir utilizar o sistema. [US09] Cadastrar atendimento na agenda [US10] Excluir atendimento na agenda [US11] Editar atendimento na agenda [US14] Consultar atendimento na agenda Os clientes devem conseguir agendar uma consulta para a realiza\u00e7\u00e3o dos atendimentos. Ordem Requisitos N\u00e3o-funcionais Categoria 1 Exibir informa\u00e7\u00f5es do neg\u00f3cio como dados de contato, equipe de servi\u00e7o e servi\u00e7os prestados Usabilidade 2 Implementar SEO Suportabilidade 3 Oferecer uma interface responsiva Usabilidade 4 Otimizar v\u00eddeos e imagens Performance 5 Oferecer n\u00edvel de acessibilidade AA (WCAG 2.2) Usabilidade 6 Implementar protocolo HTTPS Suportabilidade"},{"location":"backlog-produto/entregas/#release-2","title":"Release 2","text":"User Story Justificativa [US25] Aprovar depoimento [US26] Consultar depoimento [US27] Cadastrar depoimento [US28] Editar depoimento [US29] Excluir depoimento O cliente deve conseguir registrar seu depoimento e o administrador deve aprov\u00e1-lo e gerenci\u00e1-lo. [US03] Cadastrar relat\u00f3rio de avalia\u00e7\u00e3o [US12] Editar relat\u00f3rio de avalia\u00e7\u00e3o [US15] Visualizar relat\u00f3rio de avalia\u00e7\u00e3o [US21] Visualizar relat\u00f3rio de avalia\u00e7\u00e3o do paciente [US22] Excluir relat\u00f3rio de avalia\u00e7\u00e3o [US23] Salvar relat\u00f3rio de avalia\u00e7\u00e3o do paciente O administrador deve conseguir criar relat\u00f3rios para informar o andamento dos pacientes e os clientes devem conseguir visualiz\u00e1-los."},{"location":"backlog-produto/priorizacao/","title":"Prioriza\u00e7\u00e3o","text":""},{"location":"backlog-produto/priorizacao/#escala-likert-e-pesos","title":"Escala Likert e Pesos","text":"Crit\u00e9rio Descri\u00e7\u00e3o Peso Valor de Neg\u00f3cio O valor de retorno para o neg\u00f3cio do cliente 4 Complexidade T\u00e9cnica Complexidade t\u00e9cnica, ou seja, n\u00edvel de dificuldade para programar cada requisito -1 Criticidade O risco cr\u00edtico baseado na perda das fun\u00e7\u00f5es no sistema e quanto isso pode afetar o sistema total 2 Independ\u00eancia Rela\u00e7\u00e3o entre cada requisito e sua interdepend\u00eancia 3"},{"location":"backlog-produto/priorizacao/#escala-de-valores","title":"Escala de Valores","text":"Valor Valor de Neg\u00f3cio Complexidade T\u00e9cnica Criticidade Independ\u00eancia 5 \ud83d\udd34 Muito importante \ud83d\udd34 Muito complexo \ud83d\udd34 Muito cr\u00edtico \ud83d\udd34 Independente 4 \ud83d\udfe0 Importante \ud83d\udfe0 Complexo \ud83d\udfe0 Cr\u00edtico \ud83d\udfe0 Pouco independente 3 \ud83d\udfe1 Moderado \ud83d\udfe1 M\u00e9dio \ud83d\udfe1 \u00c0s vezes cr\u00edtico \ud83d\udfe1 \u00c0s vezes dependente 2 \ud83d\udfe2 Pouco importante \ud83d\udfe2 Pouco complexo \ud83d\udfe2 Pouco cr\u00edtico \ud83d\udfe2 Dependente 1 \ud83d\udfe3 N\u00e3o \u00e9 importante \ud83d\udfe3 N\u00e3o \u00e9 complexo \ud83d\udfe3 N\u00e3o \u00e9 cr\u00edtico \ud83d\udfe3 Muito dependente

F\u00f3rmula

\\[ \\frac{(Vn \\cdot 4 + Com \\cdot (-1) + Crit \\cdot 2 + Indep \\cdot 3)}{9} \\] Prioriza\u00e7\u00e3o de cada membro da equipe MaykonMarllonErickHenrriquePedro Requisitos FuncionaisRequisitos N\u00e3o Funcionais Temas \u00c9picos Hist\u00f3ria de Usu\u00e1rio Valor de Neg\u00f3cio (4) Complexidade (-1) Criticidade (2) Independ\u00eancia (3) Total [TM01] Gest\u00e3o de Depoimentos [EP01] Gest\u00e3o de Depoimentos [US01] Eu, como usu\u00e1rio, desejo registrar depoimentos para relatar minha experi\u00eancia 3 3 2 1 2.2 \ud83d\udfe2 [TM01] Gest\u00e3o de Depoimentos [EP01] Gest\u00e3o de Depoimentos [US02] Eu, como administrador, desejo aprovar depoimentos para manter o controle sobre os relatos apresentados. 3 3 2 1 2.2 \ud83d\udfe2 [TM01] Gest\u00e3o de Depoimentos [EP01] Gest\u00e3o de Depoimentos [US03] Eu, como administrador, desejo consultar depoimentos para manter o controle sobre os relatos apresentados. 3 3 2 1 2.2 \ud83d\udfe2 [TM01] Gest\u00e3o de Depoimentos [EP01] Gest\u00e3o de Depoimentos [US04] Eu, como administrador, desejo editar depoimentos para manter o controle sobre os relatos apresentados. 3 3 2 1 2.2 \ud83d\udfe2 [TM01] Gest\u00e3o de Depoimentos [EP01] Gest\u00e3o de Depoimentos [US05] Eu, como administrador, desejo excluir depoimentos para manter o controle sobre os relatos apresentados. 3 3 2 1 2.2 \ud83d\udfe2 [TM02] Gest\u00e3o de Atendimento [EP02] Gest\u00e3o de Atendimento [US06] Eu, como usu\u00e1rio, desejo cadastrar um hor\u00e1rio de atendimento em qualquer modalidade oferecida 4 4 3 3 3.5 \ud83d\udfe0 [TM02] Gest\u00e3o de Atendimento [EP02] Gest\u00e3o de Atendimento [US07] Eu, como usu\u00e1rio, desejo editar um hor\u00e1rio de atendimento em qualquer modalidade oferecida 4 4 3 3 3.5 \ud83d\udfe0 [TM02] Gest\u00e3o de Atendimento [EP02] Gest\u00e3o de Atendimento [US08] Eu, como usu\u00e1rio, desejo excluir um hor\u00e1rio de atendimento em qualquer modalidade oferecida 4 4 3 3 3.5 \ud83d\udfe0 [TM02] Gest\u00e3o de Atendimento [EP02] Gest\u00e3o de Atendimento [US09] Eu, como usu\u00e1rio, desejo consultar um hor\u00e1rio de atendimento em qualquer modalidade oferecida 4 4 3 3 3.5 \ud83d\udfe0 [TM03] Gest\u00e3o de usu\u00e1rio [EP03] Gest\u00e3o de Administradores [US10] Eu, como administrador, desejo me cadastrar no sistema, para conseguir utilizar as funcionalidades de administrador 5 5 4 4 4.5 \ud83d\udfe0 [TM03] Gest\u00e3o de usu\u00e1rio [EP03] Gest\u00e3o de Administradores [US11] Eu, como administrador, desejo editar meu perfil para alterar informa\u00e7\u00f5es que estejam incorretas. 4 4 3 3 3.5 \ud83d\udfe0 [TM03] Gest\u00e3o de usu\u00e1rio [EP03] Gest\u00e3o de Administradores [US12] Eu, como administrador, devo excluir meu perfil do sistema para remover qualquer v\u00ednculo com o site. 5 5 5 5 5 \ud83d\udfe0 [TM03] Gest\u00e3o de usu\u00e1rio [EP03] Gest\u00e3o de Administradores [US13] Eu, como administrador, desejo consultar meu pr\u00f3prio perfil para verificar minhas informa\u00e7\u00f5es. 5 5 5 3 4.4 \ud83d\udfe0 [TM04] Gest\u00e3o de usu\u00e1rio [EP04] Gest\u00e3o do Cliente [US14] Eu, como cliente, desejo me cadastrar no sistema para conseguir utilizar as funcionalidades correspondentes ao n\u00edvel do cliente 5 5 3 3 4 \ud83d\udfe0 [TM04] Gest\u00e3o de usu\u00e1rio [EP04] Gest\u00e3o do Cliente [US15] Eu, como cliente, desejo editar meu perfil para alterar informa\u00e7\u00f5es que estejam incorretas. 4 4 3 3 3.5 \ud83d\udfe0 [TM04] Gest\u00e3o de usu\u00e1rio [EP04] Gest\u00e3o do Cliente [US16] Eu, como cliente, desejo excluir meu perfil do sistema para remover qualquer v\u00ednculo com o site. 3 3 2 2 2.5 \ud83d\udfe1 [TM04] Gest\u00e3o de usu\u00e1rio [EP04] Gest\u00e3o do Cliente [US17] Eu, como cliente, desejo consultar meu pr\u00f3prio perfil para verificar minhas informa\u00e7\u00f5es. 4 4 3 3 3.5 \ud83d\udfe0 [TM03] Gest\u00e3o de usu\u00e1rio [EP02] Autentica\u00e7\u00e3o do usu\u00e1rio [US18] Eu, como usu\u00e1rio, desejo autenticar meu perfil para acessar funcionalidades correspondentes ao n\u00edvel do usu\u00e1rio 5 5 5 3 4.4 \ud83d\udfe0 [TM03] Gest\u00e3o de usu\u00e1rio [EP02] Autentica\u00e7\u00e3o do usu\u00e1rio [US19] Eu, como usu\u00e1rio, desejo recuperar minha senha para voltar a acessar meu perfil 4 3 2 1 2.6 \ud83d\udfe1 [TM05] Gest\u00e3o de documentos [EP05] Gest\u00e3o da Ficha do Cliente [US20] Eu, como administrador, desejo cadastrar a ficha do paciente para preencher seus dados m\u00e9dicos, consultas e tratamentos 5 5 5 5 5 \ud83d\udfe0 [TM05] Gest\u00e3o de documentos [EP05] Gest\u00e3o da Ficha do Cliente [US21] Eu, como administrador, desejo editar a ficha do paciente a fim de adicionar ou remover dados m\u00e9dicos, tratamentos e consultas 4 4 4 4 4 \ud83d\udfe0 [TM05] Gest\u00e3o de documentos [EP05] Gest\u00e3o da Ficha do Cliente [US22] Eu, como administrador, desejo excluir a ficha do paciente para manter somente os pacientes ativos em minha lista 4 4 3 3 3.5 \ud83d\udfe0 [TM05] Gest\u00e3o de documentos [EP05] Gest\u00e3o da Ficha do Cliente [US23] Eu, como administrador, desejo consultar a ficha do paciente para verificar seus dados cadastrados 4 4 4 4 4 \ud83d\udfe0 [TM05] Gest\u00e3o de documentos [EP05] Gest\u00e3o de relat\u00f3rio do Cliente [US24] Eu, como administrador, desejo criar um relat\u00f3rio de avalia\u00e7\u00e3o de um paciente para documentar o andamento do tratamento do mesmo 3 3 3 3 3 \ud83d\udfe1 [TM05] Gest\u00e3o de documentos [EP05] Gest\u00e3o de relat\u00f3rio do Cliente [US25] Eu, como administrador, desejo editar os relat\u00f3rios de avalia\u00e7\u00e3o dos pacientes 2 2 2 2 2 \ud83d\udfe1 [TM05] Gest\u00e3o de documentos [EP05] Gest\u00e3o de relat\u00f3rio do Cliente [US26] Eu, como administrador, desejo excluir um relat\u00f3rio de avalia\u00e7\u00e3o de um paciente 1 1 1 1 1 \ud83d\udfe2 [TM05] Gest\u00e3o de documentos [EP05] Gest\u00e3o de relat\u00f3rio do Cliente [US27] Eu, como administrador, desejo visualizar os relat\u00f3rios de avalia\u00e7\u00e3o dos pacientes 2 2 1 1 1.5 \ud83d\udfe1 [TM05] Gest\u00e3o de documentos [EP05] Gest\u00e3o de relat\u00f3rio do Cliente [US28] Eu, como usu\u00e1rio, desejo salvar meu relat\u00f3rio de avalia\u00e7\u00e3o no formato .pdf 1 1 1 1 1 \ud83d\udfe2 [TM05] Gest\u00e3o de documentos [EP05] Gest\u00e3o de relat\u00f3rio do Cliente [US29] Eu, como usu\u00e1rio, desejo visualizar meus relat\u00f3rios de avalia\u00e7\u00e3o 3 3 3 3 3 \ud83d\udfe0 URPS+ Requisito Valor de Neg\u00f3cio (4) Complexidade (-1) Criticidade (2) Independ\u00eancia (3) Total Suportabilidade [RNF03] Implementar SEO 5 2 3 4 3.11 \ud83d\udfe0 Usabilidade [RNF01] Oferecer uma interface responsiva 3 4 4 2 2.78 \ud83d\udfe0 Performance [RNF05] Otimizar v\u00eddeos e imagens 4 3 2 3 2.78 \ud83d\udfe0 Usabilidade [RNF02] Oferecer n\u00edvel de acessibilidade AA (WCAG 2.2) 2 3 3 4 2.44 \ud83d\udfe1 Suportabilidade [RNF04] Implementar protocolo HTTPS 3 2 4 3 2.78 \ud83d\udfe0 Requisitos FuncionaisRequisitos N\u00e3o Funcionais Temas \u00c9picos Hist\u00f3ria de Usu\u00e1rio Valor de Neg\u00f3cio (4) Complexidade (-1) Criticidade (2) Independ\u00eancia (3) Total [TM01] Gest\u00e3o de Depoimentos [EP01] Gest\u00e3o de Depoimentos [US01] Eu, como usu\u00e1rio, desejo registrar depoimentos para relatar minha experi\u00eancia 5 2 2 2 3.2 \ud83d\udfe2 [TM01] Gest\u00e3o de Depoimentos [EP01] Gest\u00e3o de Depoimentos [US02] Eu, como administrador, desejo aprovar depoimentos para manter o controle sobre os relatos apresentados. 2 3 1 2 1.9 \ud83d\udfe1 [TM01] Gest\u00e3o de Depoimentos [EP01] Gest\u00e3o de Depoimentos [US03] Eu, como administrador, desejo consultar depoimentos para manter o controle sobre os relatos apresentados. 3 2 1 2 2.2 \ud83d\udfe2 [TM01] Gest\u00e3o de Depoimentos [EP01] Gest\u00e3o de Depoimentos [US04] Eu, como administrador, desejo editar depoimentos para manter o controle sobre os relatos apresentados. 3 2 1 2 2.2 \ud83d\udfe2 [TM01] Gest\u00e3o de Depoimentos [EP01] Gest\u00e3o de Depoimentos [US05] Eu, como administrador, desejo excluir depoimentos para manter o controle sobre os relatos apresentados. 2 2 1 2 1.8 \ud83d\udfe1 [TM02] Gest\u00e3o de Atendimento [EP02] Gest\u00e3o de Atendimento [US06] Eu, como usu\u00e1rio, desejo cadastrar um hor\u00e1rio de atendimento em qualquer modalidade oferecida 4 3 4 4 3.9 \ud83d\udfe0 [TM02] Gest\u00e3o de Atendimento [EP02] Gest\u00e3o de Atendimento [US07] Eu, como usu\u00e1rio, desejo editar um hor\u00e1rio de atendimento em qualquer modalidade oferecida 4 3 4 4 3.9 \ud83d\udfe0 [TM02] Gest\u00e3o de Atendimento [EP02] Gest\u00e3o de Atendimento [US08] Eu, como usu\u00e1rio, desejo excluir um hor\u00e1rio de atendimento em qualquer modalidade oferecida 4 3 4 4 3.9 \ud83d\udfe0 [TM02] Gest\u00e3o de Atendimento [EP02] Gest\u00e3o de Atendimento [US09] Eu, como usu\u00e1rio, desejo consultar um hor\u00e1rio de atendimento em qualquer modalidade oferecida 4 2 4 4 3.8 \ud83d\udfe0 [TM03] Gest\u00e3o de usu\u00e1rio [EP03] Gest\u00e3o de Administradores [US10] Eu, como administrador, desejo me cadastrar no sistema, para conseguir utilizar as funcionalidades de administrador 5 3 5 5 4.8 \ud83d\udfe0 [TM03] Gest\u00e3o de usu\u00e1rio [EP03] Gest\u00e3o de Administradores [US11] Eu, como administrador, desejo editar meu perfil para alterar informa\u00e7\u00f5es que estejam incorretas. 1 3 1 1 1.2 \ud83d\udfe1 [TM03] Gest\u00e3o de usu\u00e1rio [EP03] Gest\u00e3o de Administradores [US12] Eu, como administrador, devo excluir meu perfil do sistema para remover qualquer v\u00ednculo com o site. 1 3 1 1 1.2 \ud83d\udfe1 [TM03] Gest\u00e3o de usu\u00e1rio [EP03] Gest\u00e3o de Administradores [US13] Eu, como administrador, desejo consultar meu pr\u00f3prio perfil para verificar minhas informa\u00e7\u00f5es. 1 3 1 1 1.2 \ud83d\udfe1 [TM04] Gest\u00e3o de usu\u00e1rio [EP04] Gest\u00e3o do Cliente [US14] Eu, como cliente, desejo me cadastrar no sistema para conseguir utilizar as funcionalidades correspondentes ao n\u00edvel do cliente 4 3 2 5 3.8 \ud83d\udfe0 [TM04] Gest\u00e3o de usu\u00e1rio [EP04] Gest\u00e3o do Cliente [US15] Eu, como cliente, desejo editar meu perfil para alterar informa\u00e7\u00f5es que estejam incorretas. 4 3 2 1 2.6 \ud83d\udfe0 [TM04] Gest\u00e3o de usu\u00e1rio [EP04] Gest\u00e3o do Cliente [US16] Eu, como cliente, desejo excluir meu perfil do sistema para remover qualquer v\u00ednculo com o site. 2 3 2 1 1.8 \ud83d\udfe1 [TM04] Gest\u00e3o de usu\u00e1rio [EP04] Gest\u00e3o do Cliente [US17] Eu, como cliente, desejo consultar meu pr\u00f3prio perfil para verificar minhas informa\u00e7\u00f5es. 4 3 2 1 2.6 \ud83d\udfe0 [TM03] Gest\u00e3o de usu\u00e1rio [EP02] Autentica\u00e7\u00e3o do usu\u00e1rio [US18] Eu, como usu\u00e1rio, desejo autenticar meu perfil para acessar funcionalidades correspondentes ao n\u00edvel do usu\u00e1rio 4 3 2 5 3.8 \ud83d\udfe0 [TM03] Gest\u00e3o de usu\u00e1rio [EP02] Autentica\u00e7\u00e3o do usu\u00e1rio [US19] Eu, como usu\u00e1rio, desejo recuperar minha senha para voltar a acessar meu perfil 5 4 5 1 3.7 \ud83d\udfe0 [TM05] Gest\u00e3o de documentos [EP05] Gest\u00e3o da Ficha do Cliente [US20] Eu, como administrador, desejo cadastrar a ficha do paciente para preencher seus dados m\u00e9dicos, consultas e tratamentos 5 4 5 5 4.9 \ud83d\udfe0 [TM05] Gest\u00e3o de documentos [EP05] Gest\u00e3o da Ficha do Cliente [US21] Eu, como administrador, desejo editar a ficha do paciente a fim de adicionar ou remover dados m\u00e9dicos, tratamentos e consultas 5 4 5 1 3.7 \ud83d\udfe0 [TM05] Gest\u00e3o de documentos [EP05] Gest\u00e3o da Ficha do Cliente [US22] Eu, como administrador, desejo excluir a ficha do paciente para manter somente os pacientes ativos em minha lista 5 4 5 1 3.7 \ud83d\udfe0 [TM05] Gest\u00e3o de documentos [EP05] Gest\u00e3o da Ficha do Cliente [US23] Eu, como administrador, desejo consultar a ficha do paciente para verificar seus dados cadastrados 5 5 5 1 3.8 \ud83d\udfe0 [TM05] Gest\u00e3o de documentos [EP05] Gest\u00e3o de relat\u00f3rio do Cliente [US24] Eu, como administrador, desejo criar um relat\u00f3rio de avalia\u00e7\u00e3o de um paciente para documentar o andamento do tratamento do mesmo 5 5 5 5 5 \ud83d\udfe0 [TM05] Gest\u00e3o de documentos [EP05] Gest\u00e3o de relat\u00f3rio do Cliente [US25] Eu, como administrador, desejo editar os relat\u00f3rios de avalia\u00e7\u00e3o dos pacientes 5 5 5 1 3.8 \ud83d\udfe0 [TM05] Gest\u00e3o de documentos [EP05] Gest\u00e3o de relat\u00f3rio do Cliente [US26] Eu, como administrador, desejo excluir um relat\u00f3rio de avalia\u00e7\u00e3o de um paciente 5 5 5 1 3.8 \ud83d\udfe0 [TM05] Gest\u00e3o de documentos [EP05] Gest\u00e3o de relat\u00f3rio do Cliente [US27] Eu, como administrador, desejo visualizar os relat\u00f3rios de avalia\u00e7\u00e3o dos pacientes 5 5 5 1 3.8 \ud83d\udfe0 [TM05] Gest\u00e3o de documentos [EP05] Gest\u00e3o de relat\u00f3rio do Cliente [US28] Eu, como usu\u00e1rio, desejo salvar meu relat\u00f3rio de avalia\u00e7\u00e3o no formato .pdf 5 5 5 1 3.8 \ud83d\udfe0 [TM05] Gest\u00e3o de documentos [EP05] Gest\u00e3o de relat\u00f3rio do Cliente [US29] Eu, como usu\u00e1rio, desejo visualizar meus relat\u00f3rios de avalia\u00e7\u00e3o 5 5 5 1 3.8 \ud83d\udfe0 URPS+ Requisito Valor de Neg\u00f3cio (4) Complexidade (-1) Criticidade (2) Independ\u00eancia (3) Total Suportabilidade [RNF03] Implementar SEO 4 3 4 3 3.00 \ud83d\udfe0 Usabilidade [RNF01] Oferecer uma interface responsiva 5 2 3 3 3.11 \ud83d\udfe0 Performance [RNF05] Otimizar v\u00eddeos e imagens 3 3 3 4 3.00 \ud83d\udfe0 Usabilidade [RNF02] Oferecer n\u00edvel de acessibilidade AA (WCAG 2.2) 4 2 3 2 2.89 \ud83d\udfe0 Suportabilidade [RNF04] Implementar protocolo HTTPS 3 4 2 4 2.78 \ud83d\udfe0 Requisitos FuncionaisRequisitos N\u00e3o Funcionais Temas \u00c9picos Hist\u00f3ria de Usu\u00e1rio Valor de Neg\u00f3cio (4) Complexidade (-1) Criticidade (2) Independ\u00eancia (3) Total [TM01] Gest\u00e3o de Depoimentos [EP01] Gest\u00e3o de Depoimentos [US01] Eu, como usu\u00e1rio, desejo registrar depoimentos para relatar minha experi\u00eancia 1 1 1 1 1 \ud83d\udfe2 [TM01] Gest\u00e3o de Depoimentos [EP01] Gest\u00e3o de Depoimentos [US02] Eu, como administrador, desejo aprovar depoimentos para manter o controle sobre os relatos apresentados. 1 1 1 2 1.3 \ud83d\udfe2 [TM01] Gest\u00e3o de Depoimentos [EP01] Gest\u00e3o de Depoimentos [US03] Eu, como administrador, desejo consultar depoimentos para manter o controle sobre os relatos apresentados. 1 1 2 2 1.5 \ud83d\udfe2 [TM01] Gest\u00e3o de Depoimentos [EP01] Gest\u00e3o de Depoimentos [US04] Eu, como administrador, desejo editar depoimentos para manter o controle sobre os relatos apresentados. 1 1 1 2 1.3 \ud83d\udfe2 [TM01] Gest\u00e3o de Depoimentos [EP01] Gest\u00e3o de Depoimentos [US05] Eu, como administrador, desejo excluir depoimentos para manter o controle sobre os relatos apresentados. 1 1 1 2 1.3 \ud83d\udfe2 [TM02] Gest\u00e3o de Atendimento [EP02] Gest\u00e3o de Atendimento [US06] Eu, como usu\u00e1rio, desejo cadastrar um hor\u00e1rio de atendimento em qualquer modalidade oferecida 4 3 4 2 3.3 \ud83d\udfe0 [TM02] Gest\u00e3o de Atendimento [EP02] Gest\u00e3o de Atendimento [US07] Eu, como usu\u00e1rio, desejo editar um hor\u00e1rio de atendimento em qualquer modalidade oferecida 4 2 4 3 3.5 \ud83d\udfe0 [TM02] Gest\u00e3o de Atendimento [EP02] Gest\u00e3o de Atendimento [US08] Eu, como usu\u00e1rio, desejo excluir um hor\u00e1rio de atendimento em qualquer modalidade oferecida 4 2 4 3 3.5 \ud83d\udfe0 [TM02] Gest\u00e3o de Atendimento [EP02] Gest\u00e3o de Atendimento [US09] Eu, como usu\u00e1rio, desejo consultar um hor\u00e1rio de atendimento em qualquer modalidade oferecida 3 2 4 2 2.8 \ud83d\udfe0 [TM03] Gest\u00e3o de usu\u00e1rio [EP03] Gest\u00e3o de Administradores [US10] Eu, como administrador, desejo me cadastrar no sistema, para conseguir utilizar as funcionalidades de administrador 4 2 4 2 3.2 \ud83d\udfe0 [TM03] Gest\u00e3o de usu\u00e1rio [EP03] Gest\u00e3o de Administradores [US11] Eu, como administrador, desejo editar meu perfil para alterar informa\u00e7\u00f5es que estejam incorretas. 4 2 5 2 3.4 \ud83d\udfe0 [TM03] Gest\u00e3o de usu\u00e1rio [EP03] Gest\u00e3o de Administradores [US12] Eu, como administrador, devo excluir meu perfil do sistema para remover qualquer v\u00ednculo com o site. 4 2 5 2 3.4 \ud83d\udfe0 [TM03] Gest\u00e3o de usu\u00e1rio [EP03] Gest\u00e3o de Administradores [US13] Eu, como administrador, desejo consultar meu pr\u00f3prio perfil para verificar minhas informa\u00e7\u00f5es. 4 2 4 2 3.2 \ud83d\udfe0 [TM04] Gest\u00e3o de usu\u00e1rio [EP04] Gest\u00e3o do Cliente [US14] Eu, como cliente, desejo me cadastrar no sistema para conseguir utilizar as funcionalidades correspondentes ao n\u00edvel do cliente 4 2 5 2 3.4 \ud83d\udfe0 [TM04] Gest\u00e3o de usu\u00e1rio [EP04] Gest\u00e3o do Cliente [US15] Eu, como cliente, desejo editar meu perfil para alterar informa\u00e7\u00f5es que estejam incorretas. 4 2 3 2 3 \ud83d\udfe0 [TM04] Gest\u00e3o de usu\u00e1rio [EP04] Gest\u00e3o do Cliente [US16] Eu, como cliente, desejo excluir meu perfil do sistema para remover qualquer v\u00ednculo com o site. 4 2 2 2 2.8 \ud83d\udfe1 [TM04] Gest\u00e3o de usu\u00e1rio [EP04] Gest\u00e3o do Cliente [US17] Eu, como cliente, desejo consultar meu pr\u00f3prio perfil para verificar minhas informa\u00e7\u00f5es. 5 2 4 2 3.6 \ud83d\udfe0 [TM03] Gest\u00e3o de usu\u00e1rio [EP02] Autentica\u00e7\u00e3o do usu\u00e1rio [US18] Eu, como usu\u00e1rio, desejo autenticar meu perfil para acessar funcionalidades correspondentes ao n\u00edvel do usu\u00e1rio 4 2 5 2 3.4 \ud83d\udfe0 [TM03] Gest\u00e3o de usu\u00e1rio [EP02] Autentica\u00e7\u00e3o do usu\u00e1rio [US19] Eu, como usu\u00e1rio, desejo recuperar minha senha para voltar a acessar meu perfil 3 2 3 2 2.6 \ud83d\udfe1 [TM05] Gest\u00e3o de documentos [EP05] Gest\u00e3o da Ficha do Cliente [US20] Eu, como administrador, desejo cadastrar a ficha do paciente para preencher seus dados m\u00e9dicos, consultas e tratamentos 5 2 5 2 3.8 \ud83d\udfe0 [TM05] Gest\u00e3o de documentos [EP05] Gest\u00e3o da Ficha do Cliente [US21] Eu, como administrador, desejo editar a ficha do paciente a fim de adicionar ou remover dados m\u00e9dicos, tratamentos e consultas 5 2 5 2 3.8 \ud83d\udfe0 [TM05] Gest\u00e3o de documentos [EP05] Gest\u00e3o da Ficha do Cliente [US22] Eu, como administrador, desejo excluir a ficha do paciente para manter somente os pacientes ativos em minha lista 3 2 4 2 2.8 \ud83d\udfe0 [TM05] Gest\u00e3o de documentos [EP05] Gest\u00e3o da Ficha do Cliente [US23] Eu, como administrador, desejo consultar a ficha do paciente para verificar seus dados cadastrados 4 3 5 3 3.8 \ud83d\udfe0 [TM05] Gest\u00e3o de documentos [EP05] Gest\u00e3o de relat\u00f3rio do Cliente [US24] Eu, como administrador, desejo criar um relat\u00f3rio de avalia\u00e7\u00e3o de um paciente para documentar o andamento do tratamento do mesmo 5 3 5 2 3.9 \ud83d\udfe0 [TM05] Gest\u00e3o de documentos [EP05] Gest\u00e3o de relat\u00f3rio do Cliente [US25] Eu, como administrador, desejo editar os relat\u00f3rios de avalia\u00e7\u00e3o dos pacientes 4 3 5 3 3.8 \ud83d\udfe0 [TM05] Gest\u00e3o de documentos [EP05] Gest\u00e3o de relat\u00f3rio do Cliente [US26] Eu, como administrador, desejo excluir um relat\u00f3rio de avalia\u00e7\u00e3o de um paciente 4 3 4 4 3.9 \ud83d\udfe0 [TM05] Gest\u00e3o de documentos [EP05] Gest\u00e3o de relat\u00f3rio do Cliente [US27] Eu, como administrador, desejo visualizar os relat\u00f3rios de avalia\u00e7\u00e3o dos pacientes 5 2 3 2 3.4 \ud83d\udfe0 [TM05] Gest\u00e3o de documentos [EP05] Gest\u00e3o de relat\u00f3rio do Cliente [US28] Eu, como usu\u00e1rio, desejo salvar meu relat\u00f3rio de avalia\u00e7\u00e3o no formato .pdf 3 2 2 3 2.7 \ud83d\udfe1 [TM05] Gest\u00e3o de documentos [EP05] Gest\u00e3o de relat\u00f3rio do Cliente [US29] Eu, como usu\u00e1rio, desejo visualizar meus relat\u00f3rios de avalia\u00e7\u00e3o 2 2 2 2 2 \ud83d\udfe1 URPS+ Requisito Valor de Neg\u00f3cio (4) Complexidade (-1) Criticidade (2) Independ\u00eancia (3) Total Suportabilidade [RNF03] Implementar SEO 4 3 2 2 2.44 \ud83d\udfe1 Usabilidade [RNF01] Oferecer uma interface responsiva 3 3 4 2 2.67 \ud83d\udfe1 Performance [RNF05] Otimizar v\u00eddeos e imagens 4 4 3 3 3.00 \ud83d\udfe0 Usabilidade [RNF02] Oferecer n\u00edvel de acessibilidade AA (WCAG 2.2) 2 4 4 3 2.67 \ud83d\udfe1 Suportabilidade [RNF04] Implementar protocolo HTTPS 3 2 2 4 2.44 \ud83d\udfe1 Requisitos FuncionaisRequisitos N\u00e3o Funcionais Temas \u00c9picos Hist\u00f3ria de Usu\u00e1rio Valor de Neg\u00f3cio (4) Complexidade (-1) Criticidade (2) Independ\u00eancia (3) Total [TM01] Gest\u00e3o de Depoimentos [EP01] Gest\u00e3o de Depoimentos [US01] Eu, como usu\u00e1rio, desejo registrar depoimentos para relatar minha experi\u00eancia 2 2 1 1 1.5 \ud83d\udfe1 [TM01] Gest\u00e3o de Depoimentos [EP01] Gest\u00e3o de Depoimentos [US02] Eu, como administrador, desejo aprovar depoimentos para manter o controle sobre os relatos apresentados. 3 3 1 2 2.3 \ud83d\udfe0 [TM01] Gest\u00e3o de Depoimentos [EP01] Gest\u00e3o de Depoimentos [US03] Eu, como administrador, desejo consultar depoimentos para manter o controle sobre os relatos apresentados. 2 1 2 2 1.9 \ud83d\udfe1 [TM01] Gest\u00e3o de Depoimentos [EP01] Gest\u00e3o de Depoimentos [US04] Eu, como administrador, desejo editar depoimentos para manter o controle sobre os relatos apresentados. 3 2 1 2 2.2 \ud83d\udfe0 [TM01] Gest\u00e3o de Depoimentos [EP01] Gest\u00e3o de Depoimentos [US05] Eu, como administrador, desejo excluir depoimentos para manter o controle sobre os relatos apresentados. 3 2 1 2 2.2 \ud83d\udfe0 [TM02] Gest\u00e3o de Atendimento [EP02] Gest\u00e3o de Atendimento [US06] Eu, como usu\u00e1rio, desejo cadastrar um hor\u00e1rio de atendimento em qualquer modalidade oferecida 4 3 4 2 3.3 \ud83d\udfe0 [TM02] Gest\u00e3o de Atendimento [EP02] Gest\u00e3o de Atendimento [US07] Eu, como usu\u00e1rio, desejo editar um hor\u00e1rio de atendimento em qualquer modalidade oferecida 3 3 4 3 3.2 \ud83d\udfe0 [TM02] Gest\u00e3o de Atendimento [EP02] Gest\u00e3o de Atendimento [US08] Eu, como usu\u00e1rio, desejo excluir um hor\u00e1rio de atendimento em qualquer modalidade oferecida 3 3 4 3 3.2 \ud83d\udfe0 [TM02] Gest\u00e3o de Atendimento [EP02] Gest\u00e3o de Atendimento [US09] Eu, como usu\u00e1rio, desejo consultar um hor\u00e1rio de atendimento em qualquer modalidade oferecida 2 1 4 2 2.3 \ud83d\udfe1 [TM03] Gest\u00e3o de usu\u00e1rio [EP03] Gest\u00e3o de Administradores [US10] Eu, como administrador, desejo me cadastrar no sistema, para conseguir utilizar as funcionalidades de administrador 5 2 4 4 4.2 \ud83d\udfe0 [TM03] Gest\u00e3o de usu\u00e1rio [EP03] Gest\u00e3o de Administradores [US11] Eu, como administrador, desejo editar meu perfil para alterar informa\u00e7\u00f5es que estejam incorretas. 3 2 5 2 3 \ud83d\udfe0 [TM03] Gest\u00e3o de usu\u00e1rio [EP03] Gest\u00e3o de Administradores [US12] Eu, como administrador, devo excluir meu perfil do sistema para remover qualquer v\u00ednculo com o site. 3 2 5 2 3 \ud83d\udfe0 [TM03] Gest\u00e3o de usu\u00e1rio [EP03] Gest\u00e3o de Administradores [US13] Eu, como administrador, desejo consultar meu pr\u00f3prio perfil para verificar minhas informa\u00e7\u00f5es. 2 1 4 2 2.3 \ud83d\udfe1 [TM04] Gest\u00e3o de usu\u00e1rio [EP04] Gest\u00e3o do Cliente [US14] Eu, como cliente, desejo me cadastrar no sistema para conseguir utilizar as funcionalidades correspondentes ao n\u00edvel do cliente 5 2 5 4 4.4 \ud83d\udfe0 [TM04] Gest\u00e3o de usu\u00e1rio [EP04] Gest\u00e3o do Cliente [US15] Eu, como cliente, desejo editar meu perfil para alterar informa\u00e7\u00f5es que estejam incorretas. 3 2 3 2 2.6 \ud83d\udfe1 [TM04] Gest\u00e3o de usu\u00e1rio [EP04] Gest\u00e3o do Cliente [US16] Eu, como cliente, desejo excluir meu perfil do sistema para remover qualquer v\u00ednculo com o site. 3 2 2 2 2.4 \ud83d\udfe1 [TM04] Gest\u00e3o de usu\u00e1rio [EP04] Gest\u00e3o do Cliente [US17] Eu, como cliente, desejo consultar meu pr\u00f3prio perfil para verificar minhas informa\u00e7\u00f5es. 2 2 4 2 2.4 \ud83d\udfe1 [TM03] Gest\u00e3o de usu\u00e1rio [EP02] Autentica\u00e7\u00e3o do usu\u00e1rio [US18] Eu, como usu\u00e1rio, desejo autenticar meu perfil para acessar funcionalidades correspondentes ao n\u00edvel do usu\u00e1rio 5 2 5 2 3.8 \ud83d\udfe0 [TM03] Gest\u00e3o de usu\u00e1rio [EP02] Autentica\u00e7\u00e3o do usu\u00e1rio [US19] Eu, como usu\u00e1rio, desejo recuperar minha senha para voltar a acessar meu perfil 4 3 3 2 3.1 \ud83d\udfe0 [TM05] Gest\u00e3o de documentos [EP05] Gest\u00e3o da Ficha do Cliente [US20] Eu, como administrador, desejo cadastrar a ficha do paciente para preencher seus dados m\u00e9dicos, consultas e tratamentos 5 2 5 3 4.1 \ud83d\udfe0 [TM05] Gest\u00e3o de documentos [EP05] Gest\u00e3o da Ficha do Cliente [US21] Eu, como administrador, desejo editar a ficha do paciente a fim de adicionar ou remover dados m\u00e9dicos, tratamentos e consultas 5 3 5 2 3.9 \ud83d\udfe0 [TM05] Gest\u00e3o de documentos [EP05] Gest\u00e3o da Ficha do Cliente [US22] Eu, como administrador, desejo excluir a ficha do paciente para manter somente os pacientes ativos em minha lista 5 3 4 2 3.7 \ud83d\udfe0 [TM05] Gest\u00e3o de documentos [EP05] Gest\u00e3o da Ficha do Cliente [US23] Eu, como administrador, desejo consultar a ficha do paciente para verificar seus dados cadastrados 5 3 4 2 3.7 \ud83d\udfe0 [TM05] Gest\u00e3o de documentos [EP05] Gest\u00e3o de relat\u00f3rio do Cliente [US24] Eu, como administrador, desejo criar um relat\u00f3rio de avalia\u00e7\u00e3o de um paciente para documentar o andamento do tratamento do mesmo 5 3 4 4 4.3 \ud83d\udfe0 [TM05] Gest\u00e3o de documentos [EP05] Gest\u00e3o de relat\u00f3rio do Cliente [US25] Eu, como administrador, desejo editar os relat\u00f3rios de avalia\u00e7\u00e3o dos pacientes 4 3 3 2 3.1 \ud83d\udfe0 [TM05] Gest\u00e3o de documentos [EP05] Gest\u00e3o de relat\u00f3rio do Cliente [US26] Eu, como administrador, desejo excluir um relat\u00f3rio de avalia\u00e7\u00e3o de um paciente 4 3 3 2 3.1 \ud83d\udfe0 [TM05] Gest\u00e3o de documentos [EP05] Gest\u00e3o de relat\u00f3rio do Cliente [US27] Eu, como administrador, desejo visualizar os relat\u00f3rios de avalia\u00e7\u00e3o dos pacientes 5 2 2 2 3.2 \ud83d\udfe0 [TM05] Gest\u00e3o de documentos [EP05] Gest\u00e3o de relat\u00f3rio do Cliente [US28] Eu, como usu\u00e1rio, desejo salvar meu relat\u00f3rio de avalia\u00e7\u00e3o no formato .pdf 2 2 3 3 2.5 \ud83d\udfe1 [TM05] Gest\u00e3o de documentos [EP05] Gest\u00e3o de relat\u00f3rio do Cliente [US29] Eu, como usu\u00e1rio, desejo visualizar meus relat\u00f3rios de avalia\u00e7\u00e3o 3 2 1 3 2.5 \ud83d\udfe1 URPS+ Requisito Valor de Neg\u00f3cio (4) Complexidade (-1) Criticidade (2) Independ\u00eancia (3) Total Suportabilidade [RNF03] Implementar SEO 3 4 3 3 2.78 \ud83d\udfe0 Usabilidade [RNF01] Oferecer uma interface responsiva 5 2 4 4 3.33 \ud83d\udfe0 Performance [RNF05] Otimizar v\u00eddeos e imagens 4 3 4 2 3.00 \ud83d\udfe0 Usabilidade [RNF02] Oferecer n\u00edvel de acessibilidade AA (WCAG 2.2) 2 2 2 4 2.44 \ud83d\udfe1 Suportabilidade [RNF04] Implementar protocolo HTTPS 3 3 3 3 2.67 \ud83d\udfe1 Requisitos FuncionaisRequisitos N\u00e3o Funcionais Temas \u00c9picos Hist\u00f3ria de Usu\u00e1rio Valor de Neg\u00f3cio (4) Complexidade (-1) Criticidade (2) Independ\u00eancia (3) Total [TM01] Gest\u00e3o de Depoimentos [EP01] Gest\u00e3o de Depoimentos [US01] Eu, como usu\u00e1rio, desejo registrar depoimentos para relatar minha experi\u00eancia 1 3 1 1 1.2 \ud83d\udfe1 [TM01] Gest\u00e3o de Depoimentos [EP01] Gest\u00e3o de Depoimentos [US02] Eu, como administrador, desejo aprovar depoimentos para manter o controle sobre os relatos apresentados. 1 3 1 3 1.8 \ud83d\udfe0 [TM01] Gest\u00e3o de Depoimentos [EP01] Gest\u00e3o de Depoimentos [US03] Eu, como administrador, desejo consultar depoimentos para manter o controle sobre os relatos apresentados. 1 3 1 2 1.5 \ud83d\udfe1 [TM01] Gest\u00e3o de Depoimentos [EP01] Gest\u00e3o de Depoimentos [US04] Eu, como administrador, desejo editar depoimentos para manter o controle sobre os relatos apresentados. 1 3 1 1 1.2 \ud83d\udfe1 [TM01] Gest\u00e3o de Depoimentos [EP01] Gest\u00e3o de Depoimentos [US05] Eu, como administrador, desejo excluir depoimentos para manter o controle sobre os relatos apresentados. 1 1 1 3 1.6 \ud83d\udfe1 [TM02] Gest\u00e3o de Atendimento [EP02] Gest\u00e3o de Atendimento [US06] Eu, como usu\u00e1rio, desejo cadastrar um hor\u00e1rio de atendimento em qualquer modalidade oferecida 3 2 3 3 2.9 \ud83d\udfe0 [TM02] Gest\u00e3o de Atendimento [EP02] Gest\u00e3o de Atendimento [US07] Eu, como usu\u00e1rio, desejo editar um hor\u00e1rio de atendimento em qualquer modalidade oferecida 2 3 3 2 2.3 \ud83d\udfe1 [TM02] Gest\u00e3o de Atendimento [EP02] Gest\u00e3o de Atendimento [US08] Eu, como usu\u00e1rio, desejo excluir um hor\u00e1rio de atendimento em qualquer modalidade oferecida 3 2 2 2 2.4 \ud83d\udfe1 [TM02] Gest\u00e3o de Atendimento [EP02] Gest\u00e3o de Atendimento [US09] Eu, como usu\u00e1rio, desejo consultar um hor\u00e1rio de atendimento em qualquer modalidade oferecida 3 1 3 2 2.5 \ud83d\udfe1 [TM03] Gest\u00e3o de usu\u00e1rio [EP03] Gest\u00e3o de Administradores [US10] Eu, como administrador, desejo me cadastrar no sistema, para conseguir utilizar as funcionalidades de administrador 4 2 5 5 4.3 \ud83d\udfe0 [TM03] Gest\u00e3o de usu\u00e1rio [EP03] Gest\u00e3o de Administradores [US11] Eu, como administrador, desejo editar meu perfil para alterar informa\u00e7\u00f5es que estejam incorretas. 4 3 4 3 3.6 \ud83d\udfe0 [TM03] Gest\u00e3o de usu\u00e1rio [EP03] Gest\u00e3o de Administradores [US12] Eu, como administrador, devo excluir meu perfil do sistema para remover qualquer v\u00ednculo com o site. 4 1 2 3 3 \ud83d\udfe0 [TM03] Gest\u00e3o de usu\u00e1rio [EP03] Gest\u00e3o de Administradores [US13] Eu, como administrador, desejo consultar meu pr\u00f3prio perfil para verificar minhas informa\u00e7\u00f5es. 4 2 2 3 3.1 \ud83d\udfe0 [TM04] Gest\u00e3o de usu\u00e1rio [EP04] Gest\u00e3o do Cliente [US14] Eu, como cliente, desejo me cadastrar no sistema para conseguir utilizar as funcionalidades correspondentes ao n\u00edvel do cliente 3 2 2 5 3.3 \ud83d\udfe0 [TM04] Gest\u00e3o de usu\u00e1rio [EP04] Gest\u00e3o do Cliente [US15] Eu, como cliente, desejo editar meu perfil para alterar informa\u00e7\u00f5es que estejam incorretas. 3 3 3 2 2.7 \ud83d\udfe1 [TM04] Gest\u00e3o de usu\u00e1rio [EP04] Gest\u00e3o do Cliente [US16] Eu, como cliente, desejo excluir meu perfil do sistema para remover qualquer v\u00ednculo com o site. 3 1 2 3 2.6 \ud83d\udfe1 [TM04] Gest\u00e3o de usu\u00e1rio [EP04] Gest\u00e3o do Cliente [US17] Eu, como cliente, desejo consultar meu pr\u00f3prio perfil para verificar minhas informa\u00e7\u00f5es. 3 2 2 1 2.1 \ud83d\udfe1 [TM03] Gest\u00e3o de usu\u00e1rio [EP02] Autentica\u00e7\u00e3o do usu\u00e1rio [US18] Eu, como usu\u00e1rio, desejo autenticar meu perfil para acessar funcionalidades correspondentes ao n\u00edvel do usu\u00e1rio 4 3 4 3 3.6 \ud83d\udfe0 [TM03] Gest\u00e3o de usu\u00e1rio [EP02] Autentica\u00e7\u00e3o do usu\u00e1rio [US19] Eu, como usu\u00e1rio, desejo recuperar minha senha para voltar a acessar meu perfil 2 3 3 2 2.3 \ud83d\udfe1 [TM05] Gest\u00e3o de documentos [EP05] Gest\u00e3o da Ficha do Cliente [US20] Eu, como administrador, desejo cadastrar a ficha do paciente para preencher seus dados m\u00e9dicos, consultas e tratamentos 5 1 5 4 4.3 \ud83d\udfe0 [TM05] Gest\u00e3o de documentos [EP05] Gest\u00e3o da Ficha do Cliente [US21] Eu, como administrador, desejo editar a ficha do paciente a fim de adicionar ou remover dados m\u00e9dicos, tratamentos e consultas 5 2 5 3 4.1 \ud83d\udfe0 [TM05] Gest\u00e3o de documentos [EP05] Gest\u00e3o da Ficha do Cliente [US22] Eu, como administrador, desejo excluir a ficha do paciente para manter somente os pacientes ativos em minha lista 5 1 5 4 4.3 \ud83d\udfe0 [TM05] Gest\u00e3o de documentos [EP05] Gest\u00e3o da Ficha do Cliente [US23] Eu, como administrador, desejo consultar a ficha do paciente para verificar seus dados cadastrados 5 1 5 3 4 \ud83d\udfe0 [TM05] Gest\u00e3o de documentos [EP05] Gest\u00e3o de relat\u00f3rio do Cliente [US24] Eu, como administrador, desejo criar um relat\u00f3rio de avalia\u00e7\u00e3o de um paciente para documentar o andamento do tratamento do mesmo 5 3 4 4 4.3 \ud83d\udfe0 [TM05] Gest\u00e3o de documentos [EP05] Gest\u00e3o de relat\u00f3rio do Cliente [US25] Eu, como administrador, desejo editar os relat\u00f3rios de avalia\u00e7\u00e3o dos pacientes 3 3 3 3 3 \ud83d\udfe0 [TM05] Gest\u00e3o de documentos [EP05] Gest\u00e3o de relat\u00f3rio do Cliente [US26] Eu, como administrador, desejo excluir um relat\u00f3rio de avalia\u00e7\u00e3o de um paciente 1 2 1 3 1.7 \ud83d\udfe1 [TM05] Gest\u00e3o de documentos [EP05] Gest\u00e3o de relat\u00f3rio do Cliente [US27] Eu, como administrador, desejo visualizar os relat\u00f3rios de avalia\u00e7\u00e3o dos pacientes 4 2 3 2 3 \ud83d\udfe0 [TM05] Gest\u00e3o de documentos [EP05] Gest\u00e3o de relat\u00f3rio do Cliente [US28] Eu, como usu\u00e1rio, desejo salvar meu relat\u00f3rio de avalia\u00e7\u00e3o no formato .pdf 5 2 3 2 3.4 \ud83d\udfe0 [TM05] Gest\u00e3o de documentos [EP05] Gest\u00e3o de relat\u00f3rio do Cliente [US29] Eu, como usu\u00e1rio, desejo visualizar meus relat\u00f3rios de avalia\u00e7\u00e3o 3 2 3 3 2.9 \ud83d\udfe0 URPS+ Requisito Valor de Neg\u00f3cio (4) Complexidade (-1) Criticidade (2) Independ\u00eancia (3) Total Suportabilidade [RNF03] Implementar SEO 3 3 3 2 2.67 \ud83d\udfe1 Usabilidade [RNF01] Oferecer uma interface responsiva 4 4 2 4 3.00 \ud83d\udfe0 Performance [RNF05] Otimizar v\u00eddeos e imagens 4 2 3 5 3.11 \ud83d\udfe0 Usabilidade [RNF02] Oferecer n\u00edvel de acessibilidade AA (WCAG 2.2) 2 3 3 3 2.67 \ud83d\udfe1 Suportabilidade [RNF04] Implementar protocolo HTTPS 3 3 4 3 2.89 \ud83d\udfe0"},{"location":"backlog-produto/priorizacao/#legenda","title":"Legenda","text":"
  • \\( Vn \\): Valor de Neg\u00f3cio
  • \\( Com \\): Complexidade
  • \\( Crit \\): Criticidade
  • \\( Indep \\): Independ\u00eancia
"},{"location":"backlog-produto/priorizacao/#priorizacao-final","title":"Prioriza\u00e7\u00e3o (Final)","text":"Requisitos FuncionaisRequisitos N\u00e3o Funcionais Temas \u00c9picos Hist\u00f3ria de Usu\u00e1rio Valor de Neg\u00f3cio (4) Complexidade (-1) Criticidade (2) Independ\u00eancia (3) Total [TM05] Gest\u00e3o de documentos [EP05] Gest\u00e3o da Ficha do Cliente [US20] Eu, como administrador, desejo cadastrar a ficha do paciente para preencher seus dados m\u00e9dicos, consultas e tratamentos 5 2.8 5 3.8 4.29 \ud83d\udd34 [TM03] Gest\u00e3o de usu\u00e1rio [EP03] Gest\u00e3o de Administradores [US10] Eu, como administrador, desejo me cadastrar no sistema, para conseguir utilizar as funcionalidades de administrador 4.6 2.8 4.4 4 4.04 \ud83d\udfe0 [TM05] Gest\u00e3o de documentos [EP05] Gest\u00e3o de relat\u00f3rio do Cliente [US24] Eu, como administrador, desejo criar um relat\u00f3rio de avalia\u00e7\u00e3o de um paciente para documentar o andamento do tratamento do mesmo 4.6 3.4 4.2 3.6 3.80 \ud83d\udfe0 [TM05] Gest\u00e3o de documentos [EP05] Gest\u00e3o da Ficha do Cliente [US21] Eu, como administrador, desejo editar a ficha do paciente a fim de adicionar ou remover dados m\u00e9dicos, tratamentos e consultas 4.8 3 4.8 2.4 3.67 \ud83d\udfe0 [TM04] Gest\u00e3o de usu\u00e1rio [EP04] Gest\u00e3o do Cliente [US14] Eu, como cliente, desejo me cadastrar no sistema para conseguir utilizar as funcionalidades correspondentes ao n\u00edvel do cliente. 4.2 2.8 3.4 3.8 3.58 \ud83d\udfe0 [TM05] Gest\u00e3o de documentos [EP05] Gest\u00e3o da Ficha do Cliente [US23] Eu, como administrador, desejo consultar a ficha do paciente para verificar seus dados cadastrados 4.6 3.2 4.6 2.6 3.58 \ud83d\udfe0 [TM03] Gest\u00e3o de usu\u00e1rio [EP02] Autentica\u00e7\u00e3o do usu\u00e1rio [US07] Eu, como usu\u00e1rio, desejo autenticar meu perfil para acessar funcionalidades correspondentes ao n\u00edvel do usu\u00e1rio 4.4 3 4.2 3 3.56 \ud83d\udfe0 [TM05] Gest\u00e3o de documentos [EP05] Gest\u00e3o da Ficha do Cliente [US22] Eu, como administrador, desejo excluir a ficha do paciente para manter somente os pacientes ativos em minha lista 4.4 2.8 4.2 2.4 3.38 \ud83d\udfe0 [TM02] Gest\u00e3o de Atendimento [EP02] Gest\u00e3o de Atendimento [US06] Eu, como usu\u00e1rio, desejo cadastrar um hor\u00e1rio de atendimento em qualquer modalidade oferecida 3.8 3 3.6 2.8 3.09 \ud83d\udfe1 [TM02] Gest\u00e3o de Atendimento [EP02] Gest\u00e3o de Atendimento [US11] Eu, como usu\u00e1rio, desejo excluir um hor\u00e1rio de atendimento em qualquer modalidade oferecida 3.6 2.8 3.4 3 3.04 \ud83d\udfe1 [TM02] Gest\u00e3o de Atendimento [EP02] Gest\u00e3o de Atendimento [US07] Eu, como usu\u00e1rio, desejo editar um hor\u00e1rio de atendimento em qualquer modalidade oferecida 3.4 3 3.6 3 2.98 \ud83d\udfe1 [TM03] Gest\u00e3o de usu\u00e1rio [EP03] Gest\u00e3o de Administradores [US12] Eu, como administrador, devo excluir meu perfil do sistema para remover qualquer v\u00ednculo com o site. 3.4 2.6 3.6 2.6 2.89 \ud83d\udfe1 [TM02] Gest\u00e3o de Atendimento [EP02] Gest\u00e3o de Atendimento [US09] Eu, como usu\u00e1rio, desejo consultar um hor\u00e1rio de atendimento em qualquer modalidade oferecida 3.2 2 3.6 2.6 2.87 \ud83d\udfe1 [TM05] Gest\u00e3o de documentos [EP05] Gest\u00e3o de relat\u00f3rio do Cliente [US25] Eu, como administrador, desejo editar os relat\u00f3rios de avalia\u00e7\u00e3o dos pacientes 3.6 3.2 3.6 2.2 2.78 \ud83d\udfe1 [TM05] Gest\u00e3o de documentos [EP05] Gest\u00e3o de relat\u00f3rio do Cliente [US27] Eu, como administrador, desejo visualizar os relat\u00f3rios de avalia\u00e7\u00e3o dos pacientes 4.2 2.6 2.8 1.6 2.73 \ud83d\udfe1 [TM03] Gest\u00e3o de usu\u00e1rio [EP03] Gest\u00e3o de Administradores [US13] Eu, como administrador, desejo editar meu perfil para alterar informa\u00e7\u00f5es que estejam incorretas. 3.2 2.8 3.6 2.2 2.64 \ud83d\udfe1 [TM03] Gest\u00e3o de usu\u00e1rio [EP03] Gest\u00e3o de Administradores [US14] Eu, como administrador, desejo consultar meu pr\u00f3prio perfil para verificar minhas informa\u00e7\u00f5es. 3.2 2.6 3.2 2.2 2.58 \ud83d\udfe1 [TM04] Gest\u00e3o de usu\u00e1rio [EP04] Gest\u00e3o do Cliente [US16] Eu, como cliente, desejo editar meu perfil para alterar informa\u00e7\u00f5es que estejam incorretas. 3.6 2.8 2.8 2 2.58 \ud83d\udfe1 [TM04] Gest\u00e3o de usu\u00e1rio [EP04] Gest\u00e3o do Cliente [US17] Eu, como cliente, desejo consultar meu pr\u00f3prio perfil para verificar minhas informa\u00e7\u00f5es. 3.6 2.6 3 1.8 2.58 \ud83d\udfe1 [TM05] Gest\u00e3o de documentos [EP05] Gest\u00e3o de relat\u00f3rio do Cliente [US29] Eu, como usu\u00e1rio, desejo visualizar meus relat\u00f3rios de avalia\u00e7\u00e3o 3.2 2.8 2.8 2.4 2.53 \ud83d\udfe1 [TM03] Gest\u00e3o de usu\u00e1rio [EP02] Autentica\u00e7\u00e3o do usu\u00e1rio [US06] Eu, como usu\u00e1rio, desejo recuperar minha senha para voltar a acessar meu perfil 3.6 3 3.2 1.6 2.51 \ud83d\udfe1 [TM05] Gest\u00e3o de documentos [EP05] Gest\u00e3o de relat\u00f3rio do Cliente [US28] Eu, como usu\u00e1rio, desejo salvar meu relat\u00f3rio de avalia\u00e7\u00e3o no formato .pdf 3.2 2.4 2.8 2 2.44 \ud83d\udfe1 [TM05] Gest\u00e3o de documentos [EP05] Gest\u00e3o de relat\u00f3rio do Cliente [US26] Eu, como administrador, desejo excluir um relat\u00f3rio de avalia\u00e7\u00e3o de um paciente 3 2.8 2.8 2.2 2.38 \ud83d\udfe1 [TM04] Gest\u00e3o de usu\u00e1rio [EP04] Gest\u00e3o do Cliente [US18] Eu, como cliente, desejo excluir meu perfil do sistema para remover qualquer v\u00ednculo com o site. 3 2.2 2 2 2.20 \ud83d\udfe1 [TM01] Gest\u00e3o de Depoimentos [EP01] Gest\u00e3o de Depoimentos [US01] Eu, como administrador, desejo consultar depoimentos para manter o controle sobre os relatos apresentados. 2 2 1.6 1.8 1.62 \ud83d\udfe2 [TM01] Gest\u00e3o de Depoimentos [EP01] Gest\u00e3o de Depoimentos [US02] Eu, como administrador, desejo excluir depoimentos para manter o controle sobre os relatos apresentados. 2 1.8 1.2 2 1.62 \ud83d\udfe2 [TM01] Gest\u00e3o de Depoimentos [EP01] Gest\u00e3o de Depoimentos [US03] Eu, como usu\u00e1rio, desejo registrar depoimentos para relatar minha experi\u00eancia 2.4 2.2 1.4 1.2 1.53 \ud83d\udfe2 [TM01] Gest\u00e3o de Depoimentos [EP01] Gest\u00e3o de Depoimentos [US04] Eu, como administrador, desejo aprovar depoimentos para manter o controle sobre os relatos apresentados. 2 2.6 1.2 2 1.53 \ud83d\udfe2 [TM01] Gest\u00e3o de Depoimentos [EP01] Gest\u00e3o de Depoimentos [US05] Eu, como administrador, desejo editar depoimentos para manter o controle sobre os relatos apresentados. 2.2 2.2 1.2 1.6 1.53 \ud83d\udfe2 URPS+ Requisito Valor de Neg\u00f3cio (4) Complexidade (-1) Criticidade (2) Independ\u00eancia (3) Total Performance [RNF05] Otimizar v\u00eddeos e imagens 4.00 3.20 3.00 3.80 3.00 \ud83d\udfe0 Usabilidade [RNF01] Oferecer uma interface responsiva 4.20 3.00 3.80 3.00 2.98 \ud83d\udfe0 Suportabilidade [RNF03] Implementar SEO 4.00 2.80 3.20 3.20 2.98 \ud83d\udfe0 Usabilidade [RNF02] Oferecer n\u00edvel de acessibilidade AA (WCAG 2.2) 2.40 3.00 3.20 3.40 2.61 \ud83d\udfe1 Suportabilidade [RNF04] Implementar protocolo HTTPS 3.00 3.00 3.20 3.40 2.71 \ud83d\udfe1"},{"location":"entregas/","title":"Entregas","text":"Hist\u00f3rico de Revis\u00e3o Data Vers\u00e3o Descri\u00e7\u00e3o Autor 08/11 1.0 Cria\u00e7\u00e3o do t\u00f3pico de Entregas Maykon J\u00fanio dos Santos Soares 14/12 1.1 Cria\u00e7\u00e3o da Unidade 2 Erick Miranda Santos 15/12 1.2 Adi\u00e7\u00e3o do DoR Henrique Martins Alencar"},{"location":"entregas/#videos-de-apresentacao","title":"V\u00eddeos de Apresenta\u00e7\u00e3o","text":"Unidade 1Unidade 2Unidade 3"},{"location":"entregas/#unidade-1","title":"Unidade 1","text":""},{"location":"entregas/#unidade-2","title":"Unidade 2","text":""},{"location":"entregas/#unidade-3","title":"Unidade 3","text":""},{"location":"estudos-de-caso/pbb/","title":"Product Backlog Building (PBB)","text":"Hist\u00f3rico de Revis\u00e3o Data Vers\u00e3o Descri\u00e7\u00e3o Autor 20/01 1.0 Documenta\u00e7\u00e3o do PBB Pedro Miguel M. de O. dos Santos"},{"location":"estudos-de-caso/pbb/#introducao","title":"Introdu\u00e7\u00e3o","text":"

Marsicano (2024) fala que Product Backlog Building (PBB) um m\u00e9todo e um Canvas para a elabora\u00e7\u00e3o e a cria\u00e7\u00e3o de um Product Backlog. Tem como objetivo ajudar na constru\u00e7\u00e3o e no refinamento do Product Backlog de forma colaborativa \u2013 construindo um entendimento compartilhado e levando todos os envolvidos \u00e0 compreens\u00e3o do produto \u2013 e na prepara\u00e7\u00e3o do backlog para o time come\u00e7ar a trabalhar de modo \u00e1gil e eficaz.

"},{"location":"estudos-de-caso/pbb/#estudo-de-caso","title":"Estudo de Caso","text":"

Nesse caso iremos tratar de uma empresa de tecnologia chamada TechFix que opera servi\u00e7os de reparo de equipamentos para clientes corporativos e deseja facilitar o agendamento e o acompanhamento dos servi\u00e7os.

"},{"location":"estudos-de-caso/pbb/#resolucao","title":"Resolu\u00e7\u00e3o","text":"

Product Backlog Building - TechFix

Fonte: Erick Miranda Santos, Maykon J\u00fanio dos Santos Soares, Marllon Fausto Cardoso, Pedro Miguel M. de O. dos Santos e Henrique Martins Alencar

"},{"location":"estudos-de-caso/pbb/#backlog-produzido","title":"Backlog produzido","text":"

Vale lembrar que cada PBI gerou uma hist\u00f3ria de usu\u00e1rio numa regra de 1 por 1.

Tabela 1 - Backlog feito com base nos PBIs

N\u00ba Hist\u00f3ria de Usu\u00e1rio \u00c9pico US01 Eu, como t\u00e9cnico, desejo realizar agendamento de servi\u00e7o para centralizar agendamentos Gerenciar solicita\u00e7\u00f5es e agendamentos dos clientes US02 Eu, como t\u00e9cnico, desejo editar agendamento de servi\u00e7o para manter os dados atualizados da agenda Gerenciar solicita\u00e7\u00f5es e agendamentos dos clientes US03 Eu, como t\u00e9cnico, desejo confirmar ou recusar solicita\u00e7\u00e3o de servi\u00e7o para repassar a agenda aos clientes rapidamente Gerenciar solicita\u00e7\u00f5es e agendamentos dos clientes US04 Eu, como t\u00e9cnico, desejo acessar meus agendamentos para manter uma agenda \u00fanica Gerenciar solicita\u00e7\u00f5es e agendamentos dos clientes US05 Eu, como t\u00e9cnico, desejo cadastrar cliente para manter seus dados centralizados Gerenciar solicita\u00e7\u00f5es e agendamentos dos clientes US06 Eu, como t\u00e9cnico, desejo editar cliente para manter seus dados atualizados Gerenciar solicita\u00e7\u00f5es e agendamentos dos clientes US07 Eu, como t\u00e9cnico, desejo excluir cliente para manter a base de dados atualizada Gerenciar solicita\u00e7\u00f5es e agendamentos dos clientes US08 Eu, como t\u00e9cnico, desejo enviar mensagem para o cliente a fim de tratar sobre o servi\u00e7o Gerenciar solicita\u00e7\u00f5es e agendamentos dos clientes US09 Eu, como atendente, desejo cadastrar informa\u00e7\u00f5es do equipamento para conseguir acess\u00e1-los depois Reparo de equipamentos US10 Eu, como atendente, registrar resultado do atendimento para averiguar o desempenho geral Reparo de equipamentos US11 Eu, como atendente, registrar recursos utilizados para a realiza\u00e7\u00e3o do atendimento a fim de obter hist\u00f3rico dos recursos Reparo de equipamentos US12 Eu, como atendente, relatar funcionamento dos recursos usados durante o atendimento a fim de manter o controle dos recursos Reparo de equipamentos US13 Eu, como atendente, desejo adicionar informa\u00e7\u00f5es do cliente a fim de manter a base de dados atualizada Reparo de equipamentos US14 Eu, como atendente, desejo solicitar coment\u00e1rio do cliente sobre atendimento a fim de obter retorno do servi\u00e7o prestado Reparo de equipamentos US15 Eu, como atendente, desejo relatar coment\u00e1rio sobre atendimento a fim de relatar ocorr\u00eancias Reparo de equipamentos US16 Eu, como atendente, desejo gerar agenda com meus servi\u00e7os para facilitar a execu\u00e7\u00e3o Reparo de equipamentos US17 Eu, como opera\u00e7\u00f5es, desejo consultar dados de um servi\u00e7o solicitado para acompanhar o andamento Relat\u00f3rios dos servi\u00e7os US18 Eu, como opera\u00e7\u00f5es, desejo consultar informa\u00e7\u00f5es do coment\u00e1rio do cliente para entender seu contexto Relat\u00f3rios dos servi\u00e7os US19 Eu, como opera\u00e7\u00f5es, desejo comparar dados sobre os servi\u00e7os prestados a fim de propor melhorias Relat\u00f3rios dos servi\u00e7os US20 Eu, como opera\u00e7\u00f5es, desejo gerar hist\u00f3rico de coment\u00e1rio dos clientes a fim de analisar os servi\u00e7os Relat\u00f3rios dos servi\u00e7os US21 Eu, como opera\u00e7\u00f5es, desejo filtrar informa\u00e7\u00f5es financeiras do estabelecimento por tempo para entender seu impacto na empresa Relat\u00f3rios dos servi\u00e7os US22 Eu, como corporativo, desejo solicitar servi\u00e7o para resolver um problema da diretoria Solicita\u00e7\u00e3o de servi\u00e7os US23 Eu, como corporativo, desejo editar um servi\u00e7o solicitado para que atenda realmente o que preciso Solicita\u00e7\u00e3o de servi\u00e7os US24 Eu, como corporativo, desejo cancelar um servi\u00e7o solicitado para que n\u00e3o atenda sem necessidade Solicita\u00e7\u00e3o de servi\u00e7os US25 Eu, como corporativo, desejo gerar um hist\u00f3rico dos servi\u00e7os prestados pelo estabelecimento para verificar todo seu alcance Solicita\u00e7\u00e3o de servi\u00e7os US26 Eu, como corporativo, desejo listar todas as solicita\u00e7\u00f5es realizadas de servi\u00e7os para acompanhar meus pedidos Solicita\u00e7\u00e3o de servi\u00e7os US27 Eu, como opera\u00e7\u00f5es, desejo listar as atividades das equipes a fim de acompanhar suas tarefas Supervis\u00e3o das equipes US28 Eu, como opera\u00e7\u00f5es, desejo cadastrar atendente ou t\u00e9cnico nas equipes a fim de manter controle sobre suas atividades por equipe Supervis\u00e3o das equipes US29 Eu, como opera\u00e7\u00f5es, desejo editar cadastro do atendente ou t\u00e9cnico nas equipes a fim de manter controle sobre suas atividades por equipe Supervis\u00e3o das equipes US30 Eu, como opera\u00e7\u00f5es, desejo remover cadastro do atendente ou t\u00e9cnico nas equipes a fim de manter controle sobre suas atividades por equipe Supervis\u00e3o das equipes US31 Eu, como opera\u00e7\u00f5es, gerar relat\u00f3rio das atividades por \u00e1rea para acompanhar o andamento em cada setor Supervis\u00e3o das equipes US32 Eu, como opera\u00e7\u00f5es, gerar relat\u00f3rio das atividades por equipe para acompanhar o andamento em cada equipe Supervis\u00e3o das equipes

Fonte: Pedro Miguel M. de O. dos Santos

"},{"location":"estudos-de-caso/pbb/#criterios-de-aceitacao","title":"Crit\u00e9rios de aceita\u00e7\u00e3o","text":"

Tabela 2 - Crit\u00e9rios de aceita\u00e7\u00e3o de 15 USs

N\u00ba Hist\u00f3ria de Usu\u00e1rio Crit\u00e9rios de Aceita\u00e7\u00e3o US01 Eu, como t\u00e9cnico, desejo realizar agendamento de servi\u00e7o para centralizar agendamentos - Selecionar data e hor\u00e1rio dispon\u00edveis - Validar conflitos de hor\u00e1rios - Associar cliente ao agendamento US03 Eu, como t\u00e9cnico, desejo confirmar ou recusar solicita\u00e7\u00e3o de servi\u00e7o para repassar a agenda aos clientes rapidamente - Visualizar solicita\u00e7\u00f5es pendentes - Confirmar ou recusar solicita\u00e7\u00e3o - Notificar cliente por e-mail ou SMS US05 Eu, como t\u00e9cnico, desejo cadastrar cliente para manter seus dados centralizados - Cadastrar nome, telefone, e-mail e endere\u00e7o - Validar campos obrigat\u00f3rios - Impedir cadastro duplicado US06 Eu, como t\u00e9cnico, desejo editar cliente para manter seus dados atualizados - Editar dados do cliente cadastrado - Validar campos alterados - Atualizar informa\u00e7\u00f5es corretamente US08 Eu, como t\u00e9cnico, desejo enviar mensagem para o cliente a fim de tratar sobre o servi\u00e7o - Selecionar cliente para envio - Enviar mensagem via e-mail ou SMS - Armazenar hist\u00f3rico de mensagens US09 Eu, como atendente, desejo cadastrar informa\u00e7\u00f5es do equipamento para conseguir acess\u00e1-los depois - Cadastrar modelo, n\u00famero de s\u00e9rie e descri\u00e7\u00e3o - Validar campos obrigat\u00f3rios - Consultar informa\u00e7\u00f5es cadastradas US11 Eu, como atendente, registrar recursos utilizados para a realiza\u00e7\u00e3o do atendimento - Selecionar recursos utilizados - Adicionar quantidade utilizada - Registrar corretamente US14 Eu, como atendente, desejo solicitar coment\u00e1rio do cliente sobre atendimento - Enviar solicita\u00e7\u00e3o de feedback - Cliente pode responder por link - Armazenar respostas US17 Eu, como opera\u00e7\u00f5es, desejo consultar dados de um servi\u00e7o solicitado - Buscar servi\u00e7o por protocolo ou data - Exibir status atual - Mostrar detalhes de t\u00e9cnico e cliente US19 Eu, como opera\u00e7\u00f5es, desejo comparar dados sobre os servi\u00e7os prestados - Gerar relat\u00f3rios comparativos - Exibir m\u00e9tricas como tempo m\u00e9dio - Exportar em PDF ou Excel US22 Eu, como corporativo, desejo solicitar servi\u00e7o para resolver um problema da diretoria - Selecionar tipo de servi\u00e7o - Anexar documentos - Gerar n\u00famero de protocolo \u00fanico US23 Eu, como corporativo, desejo editar um servi\u00e7o solicitado para que atenda realmente o que preciso - Editar detalhes da solicita\u00e7\u00e3o - Alterar data e tipo - Registrar altera\u00e7\u00f5es no hist\u00f3rico US26 Eu, como corporativo, desejo listar todas as solicita\u00e7\u00f5es realizadas de servi\u00e7os - Visualizar todas as solicita\u00e7\u00f5es - Filtrar por data e tipo - Exportar em PDF ou Excel US27 Eu, como opera\u00e7\u00f5es, desejo listar as atividades das equipes - Visualizar atividades por equipe e data - Filtrar por status - Acess\u00edvel apenas para usu\u00e1rios autorizados US30 Eu, como opera\u00e7\u00f5es, desejo remover cadastro do atendente ou t\u00e9cnico nas equipes - Buscar atendente pelo nome ou ID - Confirmar remo\u00e7\u00e3o antes de concluir - Registrar data e respons\u00e1vel

Fonte: Pedro Miguel M. de O. dos Santos

"},{"location":"estudos-de-caso/pbb/#bdds","title":"BDDs","text":""},{"location":"estudos-de-caso/pbb/#us01-eu-como-tecnico-desejo-realizar-agendamento-de-servico-para-centralizar-agendamentos","title":"US01 - Eu, como t\u00e9cnico, desejo realizar agendamento de servi\u00e7o para centralizar agendamentos","text":"

Cen\u00e1rio: T\u00e9cnico realiza um novo agendamento com sucesso Dado que o t\u00e9cnico est\u00e1 na p\u00e1gina de agendamento e existem hor\u00e1rios dispon\u00edveis na agenda Quando o t\u00e9cnico seleciona uma data e hor\u00e1rio e informa os dados do cliente corretamente e confirma o agendamento Ent\u00e3o o agendamento \u00e9 realizado com sucesso e o sistema exibe uma mensagem \"Agendamento realizado com sucesso\" e o agendamento aparece na lista de compromissos do t\u00e9cnico

Cen\u00e1rio: T\u00e9cnico tenta agendar em um hor\u00e1rio j\u00e1 ocupado Dado que o t\u00e9cnico est\u00e1 na p\u00e1gina de agendamento e o hor\u00e1rio desejado j\u00e1 est\u00e1 ocupado na agenda Quando o t\u00e9cnico tenta realizar o agendamento Ent\u00e3o o agendamento n\u00e3o \u00e9 realizado e o sistema exibe uma mensagem de erro \"Hor\u00e1rio indispon\u00edvel\" e a agenda permanece inalterada

"},{"location":"estudos-de-caso/pbb/#us09-eu-como-atendente-desejo-cadastrar-informacoes-do-equipamento-para-conseguir-acessa-los-depois","title":"US09 - Eu, como atendente, desejo cadastrar informa\u00e7\u00f5es do equipamento para conseguir acess\u00e1-los depois","text":"

Cen\u00e1rio: Atendente cadastra um novo equipamento com sucesso Dado que o atendente est\u00e1 na p\u00e1gina de cadastro de equipamentos e preenche todos os campos obrigat\u00f3rios corretamente Quando confirma o cadastro Ent\u00e3o o equipamento \u00e9 salvo no sistema e o sistema exibe a mensagem \"Equipamento cadastrado com sucesso\" e o equipamento aparece na lista de equipamentos registrados

Cen\u00e1rio: Atendente tenta cadastrar um equipamento sem preencher os campos obrigat\u00f3rios Dado que o atendente est\u00e1 na p\u00e1gina de cadastro de equipamentos e n\u00e3o preenche todos os campos obrigat\u00f3rios Quando tenta confirmar o cadastro Ent\u00e3o o cadastro n\u00e3o \u00e9 realizado e o sistema exibe a mensagem de erro \"Preencha todos os campos obrigat\u00f3rios\" e o equipamento n\u00e3o aparece na lista de equipamentos registrados

"},{"location":"estudos-de-caso/pbb/#us14-eu-como-atendente-desejo-solicitar-comentario-do-cliente-sobre-atendimento-a-fim-de-obter-retorno-do-servico-prestado","title":"US14 - Eu, como atendente, desejo solicitar coment\u00e1rio do cliente sobre atendimento a fim de obter retorno do servi\u00e7o prestado","text":"

Cen\u00e1rio: Envio de solicita\u00e7\u00e3o de feedback com sucesso Dado que o atendimento foi finalizado e o cliente possui um e-mail cadastrado no sistema Quando o atendente solicita o feedback Ent\u00e3o a solicita\u00e7\u00e3o de feedback \u00e9 enviada com sucesso e o sistema exibe a mensagem \"Solicita\u00e7\u00e3o de feedback enviada com sucesso\" e o cliente recebe um e-mail com o link de feedback

Cen\u00e1rio: Cliente tenta enviar feedback sem atendimento finalizado Dado que o atendimento ainda n\u00e3o foi finalizado Quando o atendente tenta solicitar o feedback Ent\u00e3o a solicita\u00e7\u00e3o n\u00e3o \u00e9 enviada e o sistema exibe a mensagem de erro \"Atendimento ainda em andamento\"

"},{"location":"estudos-de-caso/pbb/#us17-eu-como-operacoes-desejo-consultar-dados-de-um-servico-solicitado-para-acompanhar-o-andamento","title":"US17 - Eu, como opera\u00e7\u00f5es, desejo consultar dados de um servi\u00e7o solicitado para acompanhar o andamento","text":"

Cen\u00e1rio: Consulta de servi\u00e7o por n\u00famero de protocolo v\u00e1lido Dado que o usu\u00e1rio de opera\u00e7\u00f5es est\u00e1 na p\u00e1gina de consulta de servi\u00e7os e existe um servi\u00e7o cadastrado com o n\u00famero de protocolo \"12345\" Quando ele informa o n\u00famero de protocolo \"12345\" Ent\u00e3o o sistema exibe os detalhes do servi\u00e7o correspondente e o status atual do servi\u00e7o \u00e9 exibido

Cen\u00e1rio: Consulta de servi\u00e7o por n\u00famero de protocolo inexistente Dado que o usu\u00e1rio de opera\u00e7\u00f5es est\u00e1 na p\u00e1gina de consulta de servi\u00e7os e n\u00e3o existe um servi\u00e7o com o n\u00famero de protocolo \"99999\" Quando ele informa o n\u00famero de protocolo \"99999\" Ent\u00e3o o sistema exibe uma mensagem de erro \"Servi\u00e7o n\u00e3o encontrado\" e nenhum detalhe de servi\u00e7o \u00e9 exibido

"},{"location":"estudos-de-caso/pbb/#us30-eu-como-operacoes-desejo-remover-cadastro-do-atendente-ou-tecnico-nas-equipes-a-fim-de-manter-controle-sobre-suas-atividades-por-equipe","title":"US30 - Eu, como opera\u00e7\u00f5es, desejo remover cadastro do atendente ou t\u00e9cnico nas equipes a fim de manter controle sobre suas atividades por equipe","text":"

Cen\u00e1rio: Remo\u00e7\u00e3o bem-sucedida de t\u00e9cnico Dado que o usu\u00e1rio de opera\u00e7\u00f5es est\u00e1 na p\u00e1gina de gerenciamento de equipes e o t\u00e9cnico \"Jo\u00e3o Silva\" est\u00e1 cadastrado na equipe de manuten\u00e7\u00e3o Quando o usu\u00e1rio seleciona o t\u00e9cnico \"Jo\u00e3o Silva\" e confirma a remo\u00e7\u00e3o Ent\u00e3o o sistema remove o t\u00e9cnico da equipe e exibe a mensagem \"T\u00e9cnico removido com sucesso\" e o t\u00e9cnico n\u00e3o aparece mais na lista de equipe

Cen\u00e1rio: Tentativa de remo\u00e7\u00e3o sem confirma\u00e7\u00e3o Dado que o usu\u00e1rio de opera\u00e7\u00f5es est\u00e1 na p\u00e1gina de gerenciamento de equipes e o t\u00e9cnico \"Jo\u00e3o Silva\" est\u00e1 cadastrado na equipe de manuten\u00e7\u00e3o Quando o usu\u00e1rio seleciona o t\u00e9cnico \"Jo\u00e3o Silva\" e cancela a remo\u00e7\u00e3o Ent\u00e3o o t\u00e9cnico continua cadastrado na equipe e o sistema n\u00e3o exibe mensagens de erro

Fonte: Pedro Miguel M. de O. dos Santos

"},{"location":"estudos-de-caso/usm/","title":"User Story Mapping (USM)","text":"Hist\u00f3rico de Revis\u00e3o Data Vers\u00e3o Descri\u00e7\u00e3o Autor 20/01 1.0 Cria\u00e7\u00e3o do t\u00f3pico de USM Henrique Martins Alencar"},{"location":"estudos-de-caso/usm/#introducao","title":"Introdu\u00e7\u00e3o","text":"

A t\u00e9cnica de User Story Mapping \u00e9 uma abordagem colaborativa e visual para o planejamento e desenvolvimento de produtos, focada em garantir que o trabalho atenda \u00e0s necessidades dos usu\u00e1rios e alcance os objetivos do neg\u00f3cio. Essa t\u00e9cnica organiza hist\u00f3rias de usu\u00e1rios em um formato de mapa que permite visualizar a jornada do usu\u00e1rio, as funcionalidades principais e as tarefas associadas. Esse mapeamento ajuda equipes a priorizarem entregas incrementais, identificarem lacunas no entendimento do produto e criarem um roadmap mais claro e alinhado \u00e0s expectativas dos stakeholders.

"},{"location":"estudos-de-caso/usm/#estudo-de-caso","title":"Estudo de Caso","text":"

Para a realiza\u00e7\u00e3o da tarefa, utilizamos como base a empresa fict\u00edcia \"EduConnect\" que busca transformar a forma como institui\u00e7\u00f5es educacionais gerenciam projetos interdisciplinares e atividades extracurriculares. A vis\u00e3o \u00e9 criar um sistema educacional onde professores alunos e a comunidade escolar possam colaborar efetivamente em projetos que promovam aprendizagem significativa e desenvolvimento de habilidades pr\u00e1ticas. O mapa realizado pode ser conferido a seguir:

User Story Mapping - EduConnect

"},{"location":"estudos-de-caso/usm/#organizacao","title":"Organiza\u00e7\u00e3o","text":"PersonasAtividadesBackbone ID Descri\u00e7\u00e3o [PS01] Professor coordenador [PS02] Professor participante [PS03] Coordenador pedag\u00f3gico [PS04] Pais/Respons\u00e1veis [PS05] Alunos [PS06] Especialista Externo ID Descri\u00e7\u00e3o Usu\u00e1rios [AT01] Organizar evento interdisciplinar [PS01],[PS02],[PS03] [AT02] Gerir evento interdisciplinar [PS01],[PS02],[PS03] [AT03] Analisar evento interdisciplinar [PS01],[PS02],[PS03] [AT04] Acompanhar progresso dos filhos [PS04] [AT05] Comunicar-se com os professores [PS04] [AT06] Participar de projetos [PS05] [AT07] Visualizar materiais e instru\u00e7\u00f5es [PS05] [AT08] Comunicar-se com colegas e professores [PS05] [AT09] Monitorar projetos e alunos [PS06] ID Descri\u00e7\u00e3o Atividades [BB01] Cadastrar novo evento [AT01] [BB02] Criar planejamento do evento [AT01] [BB03] Cadastrar encontros importantes do evento [AT01] [BB04] Divulgar evento [AT01] [BB05] Realizar/executar evento [AT02] [BB06] Analisar projetos/atividades dos participantes [AT02] [BB07] Finalizar evento [AT02] [BB08] Visualizar resultados do evento [AT03] [BB10] Visualizar projetos em andamento [AT04] [BB11] Visualizar atividades dos filhos [AT04] [BB12] Manter comunica\u00e7\u00e3o com professores [AT05] [BB13] Acompanhar progresso [AT06] [BB14] Participar de atividades [AT06] [BB15] Visualizar informa\u00e7\u00f5es sobre os projetos [AT07] [BB16] Acessar instru\u00e7\u00f5es sobre as ferramentas [AT07] [BB17] Enviar mensagens [AT08] [BB18] Acessar projetos e materiais [AT09] [BB19] Comunicar-se com professores e alunos [AT09]"},{"location":"estudos-de-caso/usm/#backlog","title":"Backlog","text":"MVPRelease 2 ID Descri\u00e7\u00e3o Atividades [TA01] Cadastrar informa\u00e7\u00f5es b\u00e1sicas de um novo evento [BB01] [TA02] Editar informa\u00e7\u00f5es b\u00e1sicas de um novo evento [BB01] [TA03] Cadastrar disciplinas envolvidas no evento [BB01] [TA04] Editar disciplinas envolvidas no evento [BB01] [TA05] Informar objetivos e espectativas do evento [BB01] [TA06] Editar objetivos e espectativas do evento [BB01] [TA07] Adicionar outros coordenadores ou professor(es) participante(es) no evento [BB01] [TA08] Editar lista de coordenadores ou professor(es) participante(es) no evento [BB01] [TA10] Inserir crit\u00e9rios de avalia\u00e7\u00e3o para o evento [BB01] [TA11] Editar crit\u00e9rios de avalia\u00e7\u00e3o para o evento [BB01] [TA13] Definir datas de in\u00edcio e fim do evento [BB02] [TA14] Edtar datas de in\u00edcio e fim do evento [BB02] [TA15] Definir data e hor\u00e1rios de encontros importantes do evento [BB02] [TA16] Editar data e hor\u00e1rios de encontros importantes do evento [BB02] [TA17] Inserir data de in\u00edcio e fim para as atividades de organiza\u00e7\u00e3o pr\u00e9-evento [BB02] [TA18] Inserir materiais necess\u00e1rios para realiza\u00e7\u00e3o do evento [BB02] [TA19] Excluir materiais necess\u00e1rios para realiza\u00e7\u00e3o do evento [BB02] [TA20] Editar lista de materiais necess\u00e1rios para realiza\u00e7\u00e3o do evento [BB02] [TA21] Cadastrar encontros importantes [BB02] [TA22] Editar encontros importantes [BB02] [TA23] Excluir encontros importantes [BB02] [TA25] Adicionar descri\u00e7\u00e3o do encontro [BB03] [TA26] Editar descri\u00e7\u00e3o do encontro [BB03] [TA27] Adicionar roteiro para o encontro [BB03] [TA28] Editar roteiro do encontro [BB03] [TA29] Adicionar materiais necess\u00e1rios para realiza\u00e7\u00e3o do encontro [BB03] [TA30] Editar lista de materiais necess\u00e1rios para realiza\u00e7\u00e3o do encontro [BB03] [TA31] Adicionar outros membros para ajudar na organiza\u00e7\u00e3o do encontro [BB03] [TA32] Editar lista de membros para ajudar na organiza\u00e7\u00e3o do encontro [BB03] [TA33] Adicionar materiais dos professores e/ou\u00a0Especialistas Externos [BB03] [TA34] Editar materiais dos professores e/ou\u00a0Especialistas Externos [BB03] [TA35] Adicionar descri\u00e7\u00e3o de projetos e/ou atividades a serem feitas pelos participantes [BB03] [TA36] Editar descri\u00e7\u00e3o de projetos e/ou atividades a serem feitas pelos participantes [BB03] [TA37] Cadastrar atividades para serem realizadas [BB03] [TA38] Editar atividades para serem realizadas [BB03] [TA39] Excluir atividades para serem realizadas [BB03] [TA40] Inserir um ou mais respons\u00e1veis para cada atividade do encontro [BB03] [TA41] Inserir campo para post\u00e1gem dos entreg\u00e1veis do encontro por parte dos participantes [BB03] [TA44] Inserir texto para divulga\u00e7\u00e3o do evento para participantes e seus respons\u00e1veis [BB04] [TA45] Editar texto para divulga\u00e7\u00e3o do evento para participantes e seus respons\u00e1veis [BB04] [TA46] Inserir texto com os profissionais que participar\u00e3o do evento [BB04] [TA47] Editar texto com os profissionais que participar\u00e3o do evento [BB04] [TA48] Inserir imagens e/ou v\u00eddeos de divulga\u00e7\u00e3o do evento [BB04] [TA49] Editar imagens e/ou v\u00eddeos de divulga\u00e7\u00e3o do evento [BB04] [TA50] Excluir imagens e/ou v\u00eddeos de divulga\u00e7\u00e3o do evento [BB04] [TA51] Adicionar participantes do evento manualmente [BB04] [TA52] Editar lista de participantes do evento manualmente [BB04] [TA53] Retirar um membro da lista de participantes do evento manualmente [BB04] [TA54] Criar formul\u00e1rio para inscri\u00e7\u00e3o no evento [BB04] [TA55] Gerar link de compartilhamento do formul\u00e1rio de inscri\u00e7\u00e3o [BB04] [TA56] Visualizar programa\u00e7\u00e3o dos encontros importantes [BB05] [TA57] Enviar mensagem a outro colaborador [BB05] [TA58] Visualizar mensagens enviadas por outro colaborador ou grupo [BB05] [TA59] Criar chat de mensagens de texto com outros dois ou mais colaboradores [BB05] [TA60] Adicionar ou excluir outros colabores do chat de mensagens de texto [BB05] [TA61] Editar informa\u00e7\u00f5es dos encontros importantes do evento [BB05] [TA62] Marcar encontro importante como concluido [BB05] [TA63] Marcar atividades de um encontro importante como concluida [BB05] [TA64] Registrar texto sobre o andamento de uma atividade do encontro [BB05] [TA65] Editar lista de mateirais envolvidos na realiza\u00e7\u00e3o da atividade do encontro [BB05] [TA66] Enviar mensagens de textos para pais ou respons\u00e1veis [BB05] [TA67] Visualizar mensagens enviadas por pais ou respons\u00e1veis [BB05] [TA68] Criar chat de mensagens de texto com outros dois ou mais pais ou respons\u00e1veis [BB05] [TA69] Adicionar ou excluir outros pais ou respons\u00e1veis do chat de mensagens de texto [BB05] [TA70] Criar grupos de participantes para realiza\u00e7\u00e3o de atividades [BB05] [TA71] Editar grupos de participantes para realiza\u00e7\u00e3o de atividades [BB05] [TA72] Adicionar texto sobre os resultados do encontro [BB05] [TA73] Adicionar texto sobre os resultados do evento [BB05] [TA78] Visualizar arquivos enviados pelos participantes ou por grupos de participantes [BB06] [TA79] Enviar feedback em texto para os participantes\u00a0ou por grupos de participantes [BB06] [TA80] Compartilhar feedback das atividades para os pais ou respons\u00e1veis [BB06] [TA81] Marcar evento como concluido [BB07] [TA82] Relatar feedback final sobre o evento em texto [BB07] [TA83] Divulgar texto, imagens e/ou v\u00eddeos de finaliza\u00e7\u00e3o do evento para os colaboradores [BB07] [TA84] Divulgar texto, imagens e/ou v\u00eddeos de finaliza\u00e7\u00e3o do evento para os participantes [BB07] [TA85] Divulgar texto, imagens e/ou v\u00eddeos de finaliza\u00e7\u00e3o do evento para os pais ou respons\u00e1veis [BB07] [TA86] Visualizar lista de participantes do evento [BB08] [TA87] Visualizar relat\u00f3rios de todas as atividades do evento [BB08] [TA88] Visualizar informa\u00e7\u00f5es gerais do evento [BB08] [TA89] Visualizar todos os feedbacks do evento [BB08] [TA90] Excluir evento da lista de eventos realizados [BB08] [TA91] Visualizar informa\u00e7\u00f5es e detalhes do projeto [BB09] [TA92] Receber notifica\u00e7\u00f5es sobre projetos e eventos [BB09] [TA93] Acessar materiais relacionados ao projeto [BB09] [TA94] Visualizar relat\u00f3rios sobre desempenho dos filhos [BB10] [TA95] Visualizar participa\u00e7\u00e3o dos filhos em atividades [BB10] [TA96] Receber notifica\u00e7\u00f5es sobre o desempenho dos filhos [BB11] [TA97] Enviar mensagens diretas para os professores [BB11] [TA98] Receber mensagens diretas de professores [BB12] [TA99] Agendar reuni\u00f5es com professores [BB12] [TA100] Fornecer feedbacks sobre os projetos [BB12] [TA101] Participar de reuni\u00f5es [BB12] [TA102] Visualizar relat\u00f3rios sobre desempenho e notas [BB12] [TA103] Visualizar participa\u00e7\u00f5es (entregas e atividades realizadas) [BB13] [TA104] Visualizar atividades pendentes [BB13] [TA105] Receber notifica\u00e7\u00f5es sobre o projeto [BB13] [TA106] Visualizar feedbacks recebidos [BB13] [TA107] Enviar atividades (pesquisas, trabalhos) [BB13] [TA108] Editar envio de atividades [BB14] [TA109] Participar de reuni\u00f5es e debates [BB14] [TA110] Participar de grupos de trabalho [BB14] [TA111] Visualizar informa\u00e7\u00f5es detalhadas do projeto [BB14] [TA112] Visualizar prazos e cronograma [BB15] [TA113] Visualizar materiais relacionados [BB15] [TA114] Acessar tutoriais de uso da plataforma [BB15] [TA115] Visualizar recomenda\u00e7\u00f5es sobre ferramentas relacionadas [BB16] [TA116] Enviar mensagens diretas para os professores [BB16] [TA117] Receber mensagens diretas dos professores [BB17] [TA118] Enviar mensagens diretas para os colegas [BB17] [TA119] Receber mensagens diretas dos colegas [BB17] [TA120] Enviar mensagens diretas para os grupos de trabalho [BB17] [TA121] Receber mensagens diretas dos grupos de trabalho [BB17] [TA122] Acessar materiais do projeto [BB18] [TA123] Compartilhar materiais com alunos e professores [BB18] [TA124] Visualizar detalhes sobre o projeto [BB18] [TA125] Visualizar relat\u00f3rios gerais sobre o andamento do projeto [BB18] [TA126] Fornecer feedbacks sobre o andamento do projeto [BB19] [TA127] Agendar reuni\u00f5es e eventos [BB19] [TA128] Participar de reuni\u00f5es e eventos [BB19] ID Descri\u00e7\u00e3o Atividades [TA12] Inserir metas de porcent\u00e1gem de parcitipantes ativos e atividades entregues [BB01] [TA24] Inserir gasto previsto para realiza\u00e7\u00e3o do evento [BB02] [TA42] Inserir gasto previsto para realiza\u00e7\u00e3o do encontro [BB03] [TA43] Inserir gasto previsto para realiza\u00e7\u00e3o das atividades do encontro [BB03] [TA74] Visualizar poncent\u00e1gem de participantes que participaram do encontro [BB05] [TA75] Inserir informa\u00e7\u00f5es de gasto real com as atividades do encontro [BB05] [TA76] Inserir informa\u00e7\u00f5es de gasto real com todo o encontro [BB05] [TA129] Visualizar poncent\u00e1gem de participantes que realizaram a entrega [BB06] [TA130] Visualizar compara\u00e7\u00e3o entre as porcent\u00e1gens de participantes ativos e atividades entregues com suas respectivas metas [BB07] [TA131] Visualizar compara\u00e7\u00e3o entre gastos previstos e gastos reais de todo o evento [BB07] [TA132] Visualizar informa\u00e7\u00f5es sobre todos os gastos reais do evento [BB07] [TA133] Filtrar informa\u00e7\u00f5es sobre todos os gastos reais do evento por encontro [BB07] [TA134] Filtrar informa\u00e7\u00f5es sobre todos os gastos reais do evento por data [BB07] [TA135] Filtrar informa\u00e7\u00f5es sobre todos os gastos reais do evento por colaboradores [BB07] [TA136] Visualizar informa\u00e7\u00f5es sobre gastos do evento [BB08]"},{"location":"estudos-de-caso/usm/#criterios-de-aceitacao","title":"Crit\u00e9rios de Aceita\u00e7\u00e3o","text":"Tarefa do usu\u00e1rio Crit\u00e9rios de Aceita\u00e7\u00e3o [TA13] O sistema deve emitir um alerta caso o usu\u00e1rio tente inserir uma data anterior ao dia em que est\u00e1 realizando essa atividade; O sistema deve mostrar ao usu\u00e1rio a dura\u00e7\u00e3o, em dias, do evento ao ser informado as datas de in\u00edcio e fim do mesmo; O sistema deve impedir que o usu\u00e1rio defina uma data que seja um feriado ou ponto facultativo; O sistema deve impedir que o usu\u00e1rio defina uma data que ocorra concomitante \u00e0 outro evento com mesma equipe de coordenadores; [TA17] O sistema deve impedir que o usu\u00e1rio defina uma data fora o per\u00edodo de dura\u00e7\u00e3o do evento; O sistema deve emitir um alerta caso o usu\u00e1rio tente inserir uma data anterior ao dia em que est\u00e1 realizando essa atividade; [TA21] O sistema deve impedir que o usu\u00e1rio tente cadastrar o encontro caso n\u00e3o tenha inserido as informa\u00e7\u00f5es obrigat\u00f3rias; O sistema deve permitir que o usu\u00e1rio cadastre um novo encontro importante se, e somente se, ele inserir as seguintes informa\u00e7\u00f5es: Data, hor\u00e1rio, descri\u00e7\u00e3o, lista de organizadores e lista de materiais; O sistema deve impedir que usu\u00e1rio que n\u00e3o sejam da equipe de coordenadores tentem cadastrar um encontro importante; [TA31] O sistema deve impedir que o usu\u00e1rio tente adicionar um membro que n\u00e3o esteja na equipe do evento; O sistema deve impedir que o usu\u00e1rio tente adicionar um membro que j\u00e1 esteja presente em outra equipe de um encontro importante que ocorrer\u00e1 na mesma data e hor\u00e1rio; O sistema deve impedir que o usu\u00e1rio tente adicionar um membro j\u00e1 presente na lista. [TA48] O sistema deve impedir que o usu\u00e1rio tente adicionar imagens que n\u00e3o sejam de extens\u00f5es .png e .jpeg; O sistema deve impedir que o usu\u00e1rio tente inserir uma imagem que exceda o tamanho de 5mb; O sistema deve impedir que o usu\u00e1rio tente inserir um v\u00eddeo que n\u00e3o seja de extens\u00e3o .mp4; O sistema deve impedir que o usu\u00e1rio tente inserir um v\u00eddeo que exceda o tamanho de 100mb; [TA56] O sistema deve permitir que o usu\u00e1rio visualize todas as informa\u00e7\u00f5es do encontro em uma s\u00f3 interface; O sistema deve apresentar um design de interface responsivo, permitindo que todas as informa\u00e7\u00f5es sejam vis\u00edveis para qualquer tamanho de tela. [TA77] O sistema deve permitir que o usu\u00e1rio visualize os arquivos enviados pelos participantes dentro do pr\u00f3prio sistema; O sistema deve permitir que o usu\u00e1rio exporte os arquivos enviados pelos participantes para seu pr\u00f3prio computador. [TA91] - O sistema deve exibir informa\u00e7\u00f5es detalhadas sobre cada projeto. - Os pais devem poder acessar essas informa\u00e7\u00f5es de forma intuitiva no painel. [TA92] - Notifica\u00e7\u00f5es devem ser enviadas por e-mail e/ou aplicativo. - As notifica\u00e7\u00f5es devem conter informa\u00e7\u00f5es claras sobre datas e objetivos. [TA94] - Relat\u00f3rios devem apresentar gr\u00e1ficos e dados quantitativos. - Deve haver a op\u00e7\u00e3o de baixar os relat\u00f3rios em PDF. [TA95] - O sistema deve exibir uma lista de atividades realizadas pelos filhos. - Deve incluir datas e observa\u00e7\u00f5es sobre a participa\u00e7\u00e3o. [TA108] - O sistema deve permitir envio de mensagens via chat. - As mensagens devem ser recebidas pelo professor em tempo real. [TA97] - Alunos devem ser notificados ao receber uma mensagem. - O sistema deve permitir responder diretamente \u00e0 mensagem. [TA103] - O painel do aluno deve exibir todas as entregas realizadas com status (ex.: \"Entregue\", \"Pendente\"). - Deve ser poss\u00edvel filtrar atividades por per\u00edodo ou tipo. [TA105] - Alunos devem ser notificados sobre altera\u00e7\u00f5es de prazos ou adi\u00e7\u00e3o de novas tarefas. - Notifica\u00e7\u00f5es devem incluir links diretos para as atividades afetadas."},{"location":"iteracoes/","title":"Itera\u00e7\u00f5es","text":"Hist\u00f3rico de Revis\u00e3o Data Vers\u00e3o Descri\u00e7\u00e3o Autor 08/11 1.0 Cria\u00e7\u00e3o das se\u00e7\u00e3o de Processo de desenvolvimento de software Erick Miranda Santos Maykon J\u00fanio dos Santos Soares Marllon Fausto Cardoso 10/11 1.1 Adicionando informa\u00e7\u00f5es sobre itera\u00e7\u00e3o 01 Erick Miranda Santos 14/11 1.2 Adicionando informa\u00e7\u00f5es sobre itera\u00e7\u00e3o 02 Maykon J\u00fanio dos Santos Soares 23/11 1.3 Adicionando informa\u00e7\u00f5es sobre itera\u00e7\u00e3o 02 Maykon J\u00fanio dos Santos Soares 06/12 1.4 Adicionando informa\u00e7\u00f5es sobre itera\u00e7\u00e3o 03 Maykon J\u00fanio dos Santos Soares 13/12 1.4 Adicionando informa\u00e7\u00f5es sobre itera\u00e7\u00e3o 03 Maykon J\u00fanio dos Santos Soares Itera\u00e7\u00e3o 0Itera\u00e7\u00e3o 1Itera\u00e7\u00e3o 2Itera\u00e7\u00e3o 3"},{"location":"iteracoes/#iteracao-0","title":"Itera\u00e7\u00e3o 0","text":""},{"location":"iteracoes/#periodo","title":"\ud83d\udcc5 Per\u00edodo","text":"

data: 22/10/2023 - 04/11/2023

"},{"location":"iteracoes/#principais-decisoes","title":"\ud83d\udd11 Principais Decis\u00f5es","text":"

Primeiros passos

Durante esta Itera\u00e7\u00e3o, o grupo tomou decis\u00f5es cruciais para o in\u00edcio do projeto, estabelecendo as bases para o desenvolvimento e organiza\u00e7\u00e3o.

Decis\u00e3o Descri\u00e7\u00e3o Primeira Reuni\u00e3o Realizada para alinhar objetivos e expectativas do time. Tecnologias Definidas Escolha das tecnologias a serem utilizadas no projeto, levando em conta os requisitos e a escalabilidade. Distribui\u00e7\u00e3o de Pap\u00e9is Defini\u00e7\u00e3o de responsabilidades para cada membro do time, promovendo efici\u00eancia no desenvolvimento. Uso do Miro Decis\u00e3o de utilizar o Miro como ferramenta para organiza\u00e7\u00e3o visual das tarefas e brainstorming colaborativo."},{"location":"iteracoes/#entregas-realizadas","title":"\ud83c\udfaf Entregas Realizadas","text":"

Boas decis\u00f5es

As entregas desta Itera\u00e7\u00e3o garantiram o in\u00edcio s\u00f3lido do projeto, com defini\u00e7\u00f5es importantes e progresso substancial nas primeiras atividades.

Entrega Descri\u00e7\u00e3o Defini\u00e7\u00e3o do Produto Estabelecimento do conceito e do objetivo principal do produto. Defini\u00e7\u00e3o do Problema Identifica\u00e7\u00e3o e defini\u00e7\u00e3o clara do problema a ser solucionado pelo produto. In\u00edcio do GitPages Cria\u00e7\u00e3o do reposit\u00f3rio GitPages para o gerenciamento do projeto e versionamento do conte\u00fado. Conclus\u00e3o da Ideia do Produto A ideia do produto foi discutida e fechada, com um consenso sobre a proposta final. Vis\u00e3o de Produto e Projeto Documenta\u00e7\u00e3o da vis\u00e3o do produto e defini\u00e7\u00e3o do escopo do projeto, com objetivos e metas claros. Processo de Desenvolvimento de Software Defini\u00e7\u00e3o do processo e metodologia de desenvolvimento a ser seguido durante o projeto."},{"location":"iteracoes/#iteracao-retrospective","title":"\ud83e\uddd0 Itera\u00e7\u00e3o Retrospective","text":"

Ponto de reflex\u00e3o

A retrospectiva foi realizada para refletir sobre os pontos fortes e \u00e1reas de melhoria da Itera\u00e7\u00e3o, promovendo aprendizado cont\u00ednuo.

  • T\u00f3picos discutidos: Durante a retrospectiva, foram abordados os desafios encontrados e os processos que funcionaram bem.
  • Conclus\u00e3o: Todas as entregas foram realizadas dentro do prazo, e o time expressou satisfa\u00e7\u00e3o com o andamento do projeto, com sugest\u00f5es de melhorias para a pr\u00f3xima Itera\u00e7\u00e3o.
"},{"location":"iteracoes/#conquistas-da-iteracao","title":"\ud83c\udfc6 Conquistas da Itera\u00e7\u00e3o","text":"

Vale comemorar

  • Entregas dentro do prazo.
  • Ajustes realizados conforme feedback.
  • Equipe alinhada e motivada para as pr\u00f3ximas fases.
"},{"location":"iteracoes/#proximos-passos","title":"\ud83d\udccc Pr\u00f3ximos Passos","text":"

Foco na execu\u00e7\u00e3o da pr\u00f3xima Itera\u00e7\u00e3o com a continuidade das entregas e integra\u00e7\u00e3o das tecnologias escolhidas.

"},{"location":"iteracoes/#reunioes","title":"\ud83e\udd1d Reuni\u00f5es","text":"1\u00b0 Reuni\u00e3o2\u00b0 Reuni\u00e3o3\u00b0 Reuni\u00e3o

Conversa Inicial com Cliente

Detalhes do Encontro

  • Data: 02/11/2024

  • Hor\u00e1rio: 08:00

  • Modalidade: Videoconfer\u00eancia (Teams)

  • Participantes: Equipe e Cliente

Prop\u00f3sito

Esta reuni\u00e3o inicial teve como objetivo alinhar expectativas e definir as bases de colabora\u00e7\u00e3o para o projeto Paraizo. Foram discutidas as principais entregas, o escopo e o papel de cada Integrante, al\u00e9m dos pr\u00f3ximos passos para o desenvolvimento do MVP.

Grava\u00e7\u00e3o da Reuni\u00e3o

Principais T\u00f3picos

# T\u00f3pico 1 Apresenta\u00e7\u00e3o dos membros da equipe 2 Contextualiza\u00e7\u00e3o da disciplina e entendimento do prop\u00f3sito do projeto 3 Defini\u00e7\u00e3o de ferramenta de comunica\u00e7\u00e3o da equipe 4 Defini\u00e7\u00e3o de ferramenta organizacional da equipe 5 Defini\u00e7\u00e3o e esclarecimento sobre o escopo do MVP 1 6 Defini\u00e7\u00e3o e esclarecimento sobre o escopo do MVP 2

Decis\u00f5es Cr\u00edticas

Aten\u00e7\u00e3o

Durante a reuni\u00e3o, foram tomadas as seguintes decis\u00f5es que impactam o andamento e a comunica\u00e7\u00e3o do projeto:

  • Escopo inicial do projeto
  • Definido que reuni\u00f5es com cliente ser\u00e3o a cada 2 semanas sab\u00e1do 08 horas
  • Definido ferramenta para Reuni\u00f5es sendo o Temas
  • Definido ferramenta organizacional sendo o Figma

Observa\u00e7\u00f5es Adicionais

Aten\u00e7\u00e3o

Nota: Nem todos os membros da equipe puderam estar presentes.

Planejamento de Entrega da Unidade

Detalhes do Encontro

  • Data: 05/11/2024

  • Hor\u00e1rio: 20:00

  • Modalidade: Videoconfer\u00eancia (Teams)

  • Participantes: Equipe

Prop\u00f3sito

Essa reuni\u00e3o teve como premissa a divis\u00e3o de atividades presentes na entrega da Unidade 1, bem como a defini\u00e7\u00e3o de prazos. Dessa maneira a reuni\u00e3o buscou revisar tudo que j\u00e1 tinha sido at\u00e9 o momento, t\u00f3picos 1, 2 e 3. E tamb\u00e9m estabelecer os prazos para a constru\u00e7\u00e3o dos t\u00f3picos 4 e 5.

Grava\u00e7\u00e3o da Reuni\u00e3o

Principais T\u00f3picos

# T\u00f3pico 1 Revis\u00e3o de documenta\u00e7\u00e3o anterior 2 Transfer\u00eancia de documenta\u00e7\u00e3o do google docs para o gitpages 3 Defini\u00e7\u00e3o de Tecnologias a serem utilizadas 4 Defini\u00e7\u00e3o de papeis dentro da equipe 5 Defini\u00e7\u00e3o de prazos para entregas dos t\u00f3picos 4 e 5 6 Bate papo inicial sobre escolha de processo processo de desenvolvimento

Decis\u00f5es Cr\u00edticas

Aten\u00e7\u00e3o

Durante a reuni\u00e3o, foram tomadas as seguintes decis\u00f5es que impactam o andamento do projeto:

  • Definido o dia 10/11/2024 como dia limite para inclus\u00e3o dos t\u00f3picos 4 e 5
  • Definido as tecnologias para desevolvimento e comunica\u00e7\u00e3o bem como suas vers\u00f5es
  • Definido os papeis dentro da equipe

Observa\u00e7\u00f5es Adicionais

Aten\u00e7\u00e3o

Nota: Nem todos os membros da equipe puderam estar presentes.

Atualiza\u00e7\u00e3o sobre entrega da Unidade

Detalhes do Encontro

  • Data: 10/11/2024

  • Hor\u00e1rio: 14:00

  • Modalidade: Videoconfer\u00eancia (Teams)

  • Participantes: Equipe

Prop\u00f3sito

A reuni\u00e3o em quest\u00e3o teve o objetivo de listar todos os t\u00f3picos desenvolvidos at\u00e9 o momento e checar seus prazos para conclus\u00e3o. Al\u00e9m disso foi definido o tipo de processo de desenvolvimento de software e a metodologia.

Grava\u00e7\u00e3o da Reuni\u00e3o

Principais T\u00f3picos

# T\u00f3pico 1 Revis\u00e3o de documenta\u00e7\u00e3o j\u00e1 criada 2 Finaliza\u00e7\u00e3o da transfer\u00eancia de documenta\u00e7\u00e3o do google docs para o gitpages 3 Defini\u00e7\u00e3o de Abordagem, Ciclo de Vida e Processo de Desenvolvimento 4 Defini\u00e7\u00e3o do dia para a grava\u00e7\u00e3o do v\u00eddeo de entrega da unidade

Decis\u00f5es Cr\u00edticas

Aten\u00e7\u00e3o

Durante a reuni\u00e3o, foram tomadas as seguintes decis\u00f5es que impactam o andamento projeto:

  • Defini\u00e7\u00e3o da abordagem sendo agil, o ciclo de vida sendo RAD e o processo de Desenvolvimento sendo dual
  • Definido o dia 11/11 como dia limite para a grava\u00e7\u00e3o do v\u00eddeo de entrega unidade e a finaliza\u00e7\u00e3o de todas as altera\u00e7\u00f5es para a entrega da Unidade 1

Observa\u00e7\u00f5es Adicionais

Aten\u00e7\u00e3o

Nota: Sem notas adicionais.

"},{"location":"iteracoes/#iteracao-1","title":"Itera\u00e7\u00e3o 1","text":""},{"location":"iteracoes/#periodo_1","title":"\ud83d\udcc5 Per\u00edodo","text":"

Data: 05/11/2023 - 18/11/2023

"},{"location":"iteracoes/#principais-decisoes_1","title":"\ud83d\udd11 Principais Decis\u00f5es","text":"

Primeiros passos

Durante esta Itera\u00e7\u00e3o, o grupo buscou estabelecer uma primeira rela\u00e7\u00e3o com os requisitos e corrigir alguns d\u00e9bitos da itera\u00e7\u00e3o anterior, como ajustes na vis\u00e3o do produto, refinamento do projeto e pequenos ajustes operacionais.

Decis\u00e3o Descri\u00e7\u00e3o Escopo inicial de requisitos A equipe se reuniu para identificar, nos documentos dispon\u00edveis, oportunidades para defini\u00e7\u00e3o de requisitos. Defini\u00e7\u00e3o de escopo para MVP1 Com base na primeira vers\u00e3o dos requisitos, foi determinado o que poderia compor o MVP1. Conversa com cliente para alinhar expectativas Ap\u00f3s a proposta inicial do escopo, a equipe reuniu-se com o cliente para ajustar a lista de requisitos. Prioriza\u00e7\u00e3o de MVP1 Realizada a primeira prioriza\u00e7\u00e3o do escopo definido para o MVP1, considerando os interesses da equipe e do cliente."},{"location":"iteracoes/#entregas-realizadas_1","title":"\ud83c\udfaf Entregas Realizadas","text":"

Boas decis\u00f5es

As entregas da Itera\u00e7\u00e3o 1 garantiram um bom in\u00edcio para a cria\u00e7\u00e3o e prioriza\u00e7\u00e3o do backlog, fortalecendo o alinhamento com o cliente.

Entrega Descri\u00e7\u00e3o Primeira lista de requisitos Estabelecimento de uma lista b\u00e1sica de requisitos. Defini\u00e7\u00e3o inicial de escopo para MVP1 Identifica\u00e7\u00e3o do escopo inicial para o MVP1, alinhado com os objetivos da equipe e do cliente. Defini\u00e7\u00e3o inicial de prioriza\u00e7\u00e3o Prioriza\u00e7\u00e3o inicial do MVP1 baseada nos interesses do cliente e da equipe."},{"location":"iteracoes/#retrospectiva-da-iteracao","title":"\ud83e\uddd0 Retrospectiva da Itera\u00e7\u00e3o","text":"

Ponto de reflex\u00e3o

A retrospectiva foi realizada para avaliar os pontos fortes e as \u00e1reas de melhoria, promovendo aprendizado cont\u00ednuo.

  • T\u00f3picos discutidos: Durante a retrospectiva, foram analisadas oportunidades de melhoria para as pr\u00f3ximas entregas.
  • Conclus\u00e3o: Todas as entregas foram realizadas dentro do prazo, mas foi identificado que uma melhor comunica\u00e7\u00e3o interna poderia trazer maior harmonia \u00e0 equipe.
"},{"location":"iteracoes/#conquistas-da-iteracao_1","title":"\ud83c\udfc6 Conquistas da Itera\u00e7\u00e3o","text":"

Vale comemorar

  • Entregas realizadas dentro do prazo.
  • Ajustes implementados conforme o feedback do cliente.
"},{"location":"iteracoes/#proximos-passos_1","title":"\ud83d\udccc Pr\u00f3ximos Passos","text":"

O foco ser\u00e1 a defini\u00e7\u00e3o do escopo para o MVP2 e a prioriza\u00e7\u00e3o inicial de suas entregas.

"},{"location":"iteracoes/#reunioes_1","title":"\ud83e\udd1d Reuni\u00f5es","text":"1\u00aa Reuni\u00e3o

Alinhamento interno da equipe

Detalhes do Encontro

  • Data: 13/11/2024
  • Hor\u00e1rio: 08:00
  • Modalidade: Videoconfer\u00eancia (Teams)
  • Participantes: Equipe

Prop\u00f3sito

Esta reuni\u00e3o teve como objetivo elicitar uma primeira vers\u00e3o do backlog.

Grava\u00e7\u00e3o da Reuni\u00e3o

A reuni\u00e3o n\u00e3o foi gravada.

Principais T\u00f3picos

# T\u00f3pico 1 Busca de documentos relevantes. 2 Alinhamento sobre as entregas planejadas. 3 Divis\u00e3o de tarefas entre os membros.

Decis\u00f5es Cr\u00edticas

Aten\u00e7\u00e3o

Durante a reuni\u00e3o, foram tomadas decis\u00f5es importantes para o andamento e comunica\u00e7\u00e3o do projeto:

  • Determina\u00e7\u00e3o dos documentos que serviriam como base.
  • Alinhamento sobre as datas limites das entregas.
  • Defini\u00e7\u00e3o das tarefas para a entrega da lista inicial de requisitos.

Observa\u00e7\u00f5es Adicionais

Aten\u00e7\u00e3o

Nota: Nem todos os membros da equipe puderam estar presentes.

"},{"location":"iteracoes/#iteracao-2","title":"Itera\u00e7\u00e3o 2","text":""},{"location":"iteracoes/#periodo_2","title":"\ud83d\udcc5 Per\u00edodo","text":"

Data: 19/11/2024 - 02/12/2024

"},{"location":"iteracoes/#principais-decisoes_2","title":"\ud83d\udd11 Principais Decis\u00f5es","text":"

Avan\u00e7o nos requisitos

Durante esta Itera\u00e7\u00e3o, a equipe focou no levantamento inicial e na an\u00e1lise detalhada dos requisitos, al\u00e9m de avan\u00e7ar na prioriza\u00e7\u00e3o e estrutura\u00e7\u00e3o de um backlog inicial.

Decis\u00e3o Descri\u00e7\u00e3o Planejamento dos Requisitos Foi realizada a an\u00e1lise inicial dos requisitos levantados na Itera\u00e7\u00e3o anterior, ajustando e refinando detalhes t\u00e9cnicos e funcionais. Prioriza\u00e7\u00e3o inicial de requisitos Com base nos requisitos identificados, a equipe definiu prioridades para orientar o planejamento do projeto. Levantamento de backlog inicial A partir das prioridades estabelecidas, foi estruturado um backlog inicial, alinhado \u00e0s entregas futuras."},{"location":"iteracoes/#entregas-realizadas_2","title":"\ud83c\udfaf Entregas Realizadas","text":"

Evolu\u00e7\u00e3o cont\u00ednua

As entregas desta Itera\u00e7\u00e3o consolidaram a base para um planejamento mais claro e direcionado, garantindo avan\u00e7os no desenvolvimento do projeto.

Entrega Descri\u00e7\u00e3o Levantamento inicial de requisitos Identifica\u00e7\u00e3o e an\u00e1lise de requisitos detalhados para direcionar as pr\u00f3ximas etapas do projeto. Prioriza\u00e7\u00e3o inicial de backlog Estabelecimento de uma lista de prioridades com base nos objetivos do cliente e da equipe. Backlog inicial estruturado Cria\u00e7\u00e3o de um backlog contendo as principais tarefas e entregas para nortear o desenvolvimento."},{"location":"iteracoes/#retrospectiva-da-iteracao_1","title":"\ud83e\uddd0 Retrospectiva da Itera\u00e7\u00e3o","text":"

Ponto de reflex\u00e3o

A retrospectiva da Itera\u00e7\u00e3o 2 destacou os avan\u00e7os obtidos e os desafios enfrentados na an\u00e1lise e prioriza\u00e7\u00e3o de requisitos.

  • T\u00f3picos discutidos: Melhorias no processo de levantamento e prioriza\u00e7\u00e3o de requisitos, al\u00e9m da necessidade de maior clareza na documenta\u00e7\u00e3o.
  • Conclus\u00e3o: Apesar do progresso significativo, foi identificado que uma melhor organiza\u00e7\u00e3o das reuni\u00f5es e registros poderia acelerar o processo de planejamento.
"},{"location":"iteracoes/#conquistas-da-iteracao_2","title":"\ud83c\udfc6 Conquistas da Itera\u00e7\u00e3o","text":"

Vale comemorar

  • Backlog inicial estruturado com sucesso.
  • An\u00e1lise inicial de requisitos conclu\u00edda dentro do prazo.
  • Consolida\u00e7\u00e3o do escopo para as pr\u00f3ximas itera\u00e7\u00f5es.
"},{"location":"iteracoes/#proximos-passos_2","title":"\ud83d\udccc Pr\u00f3ximos Passos","text":"

Trabalhar no detalhamento do backlog inicial, refinando os requisitos e come\u00e7ando a planejar a implementa\u00e7\u00e3o do MVP2.

"},{"location":"iteracoes/#reunioes_2","title":"\ud83e\udd1d Reuni\u00f5es","text":"1\u00aa Reuni\u00e3o

Planejamento de requisitos e alinhamento inicial

Detalhes do Encontro

  • Data: 23/11/2024
  • Hor\u00e1rio: 09:00
  • Modalidade: Videoconfer\u00eancia (Teams)
  • Participantes: Equipe

Prop\u00f3sito

Esta reuni\u00e3o teve como objetivo revisar os requisitos levantados e iniciar a prioriza\u00e7\u00e3o e estrutura\u00e7\u00e3o do backlog.

Grava\u00e7\u00e3o da Reuni\u00e3o

A reuni\u00e3o n\u00e3o foi gravada.

Principais T\u00f3picos

# T\u00f3pico 1 Revis\u00e3o dos requisitos levantados na Itera\u00e7\u00e3o 1. 2 Prioriza\u00e7\u00e3o inicial de requisitos e tarefas. 3 Estrutura\u00e7\u00e3o do backlog inicial.

Decis\u00f5es Cr\u00edticas

Aten\u00e7\u00e3o

Durante a reuni\u00e3o, foram tomadas decis\u00f5es importantes para o planejamento do projeto:

  • Ajustes nos requisitos levantados anteriormente.
  • Prioriza\u00e7\u00e3o de funcionalidades e tarefas.
  • Defini\u00e7\u00e3o das entregas priorit\u00e1rias para o MVP2.

Observa\u00e7\u00f5es Adicionais

Aten\u00e7\u00e3o

Nota: Nem todos os requisitos foram completamente detalhados durante a Itera\u00e7\u00e3o, sendo necess\u00e1rio complementar nas pr\u00f3ximas reuni\u00f5es.

"},{"location":"iteracoes/#iteracao-3","title":"Itera\u00e7\u00e3o 3","text":""},{"location":"iteracoes/#periodo_3","title":"\ud83d\udcc5 Per\u00edodo","text":"

Data: 03/12/2024 - 16/12/2024

"},{"location":"iteracoes/#principais-decisoes_3","title":"\ud83d\udd11 Principais Decis\u00f5es","text":"

Avan\u00e7os no planejamento

Durante esta Itera\u00e7\u00e3o, a equipe focou no refinamento do backlog, prioriza\u00e7\u00e3o das tarefas e na defini\u00e7\u00e3o de crit\u00e9rios essenciais para garantir a entrega de valor cont\u00ednuo.

Decis\u00e3o Descri\u00e7\u00e3o Refinamento e prioriza\u00e7\u00e3o de backlog A equipe revisou e detalhou o backlog existente, definindo as tarefas e funcionalidades essenciais para os MVPs. Defini\u00e7\u00e3o de DoR (Definition of Ready) Estabelecimento de crit\u00e9rios claros para garantir que as tarefas estejam prontas para desenvolvimento. Defini\u00e7\u00e3o de DoD (Definition of Done) Defini\u00e7\u00e3o dos crit\u00e9rios de conclus\u00e3o das tarefas para garantir entregas de alta qualidade. Defini\u00e7\u00e3o de crit\u00e9rios de aceita\u00e7\u00e3o A equipe detalhou os crit\u00e9rios espec\u00edficos de aceita\u00e7\u00e3o para cada funcionalidade do backlog."},{"location":"iteracoes/#entregas-realizadas_3","title":"\ud83c\udfaf Entregas Realizadas","text":"

Planejamento consolidado

As entregas desta Itera\u00e7\u00e3o garantiram a prepara\u00e7\u00e3o detalhada dos MVPs, com uma vis\u00e3o clara das expectativas e dos requisitos para os pr\u00f3ximos passos.

Entrega Descri\u00e7\u00e3o Backlog detalhado para MVP1 e MVP2 O backlog foi refinado e detalhado, com funcionalidades e prioridades bem definidas para os dois MVPs. Defini\u00e7\u00e3o de DoR (Definition of Ready) Estabelecimento de crit\u00e9rios claros para garantir que as tarefas estejam prontas para o desenvolvimento. Defini\u00e7\u00e3o de DoD (Definition of Done) Defini\u00e7\u00e3o dos crit\u00e9rios de aceita\u00e7\u00e3o e conclus\u00e3o das tarefas, assegurando a entrega de funcionalidades completas e testadas. Crit\u00e9rios de aceita\u00e7\u00e3o definidos Para cada tarefa do backlog, foram estabelecidos crit\u00e9rios claros de aceita\u00e7\u00e3o, garantindo que as funcionalidades atendam aos requisitos do cliente."},{"location":"iteracoes/#retrospectiva-da-iteracao_2","title":"\ud83e\uddd0 Retrospectiva da Itera\u00e7\u00e3o","text":"

Ponto de reflex\u00e3o

A retrospectiva da Itera\u00e7\u00e3o 3 destacou os avan\u00e7os na defini\u00e7\u00e3o dos requisitos, mas tamb\u00e9m revelou oportunidades de melhorar a comunica\u00e7\u00e3o sobre as expectativas de qualidade e aceita\u00e7\u00e3o.

  • T\u00f3picos discutidos: A necessidade de maior alinhamento entre a equipe sobre a defini\u00e7\u00e3o dos crit\u00e9rios de aceita\u00e7\u00e3o e as expectativas de qualidade.
  • Conclus\u00e3o: Embora as entregas tenham avan\u00e7ado conforme o planejado, o alinhamento dos crit\u00e9rios de aceita\u00e7\u00e3o foi considerado um ponto de melhoria para garantir que todos os membros da equipe compreendam as expectativas de forma clara e consistente.
"},{"location":"iteracoes/#conquistas-da-iteracao_3","title":"\ud83c\udfc6 Conquistas da Itera\u00e7\u00e3o","text":"

Conquistas importantes

  • Backlog detalhado para MVP1 e MVP2 conclu\u00eddo.
  • Defini\u00e7\u00e3o de crit\u00e9rios claros de DoR e DoD.
  • Estabelecimento de crit\u00e9rios de aceita\u00e7\u00e3o para funcionalidades.
"},{"location":"iteracoes/#proximos-passos_3","title":"\ud83d\udccc Pr\u00f3ximos Passos","text":"

Refinamento final do backlog, foco na implementa\u00e7\u00e3o das funcionalidades de maior prioridade para o MVP1 e alinhamento da equipe quanto aos crit\u00e9rios de aceita\u00e7\u00e3o.

"},{"location":"iteracoes/#reunioes_3","title":"\ud83e\udd1d Reuni\u00f5es","text":"1\u00aa Reuni\u00e3o

Planejamento detalhado e defini\u00e7\u00e3o de crit\u00e9rios

Detalhes do Encontro

  • Data: 05/12/2024
  • Hor\u00e1rio: 10:00
  • Modalidade: Videoconfer\u00eancia (Teams)
  • Participantes: Equipe

Prop\u00f3sito

Esta reuni\u00e3o teve como objetivo refinar o backlog e definir claramente os crit\u00e9rios de aceita\u00e7\u00e3o, DoR e DoD para garantir a execu\u00e7\u00e3o eficiente das entregas futuras.

Grava\u00e7\u00e3o da Reuni\u00e3o

A reuni\u00e3o n\u00e3o foi gravada.

Principais T\u00f3picos

# T\u00f3pico 1 Refinamento e prioriza\u00e7\u00e3o do backlog. 2 Defini\u00e7\u00e3o dos crit\u00e9rios de DoR e DoD. 3 Estabelecimento dos crit\u00e9rios de aceita\u00e7\u00e3o para as funcionalidades.

Decis\u00f5es Cr\u00edticas

Aten\u00e7\u00e3o

Durante a reuni\u00e3o, as seguintes decis\u00f5es cr\u00edticas foram tomadas para garantir o progresso do projeto:

  • Refinamento do backlog com base nas prioridades dos MVPs.
  • Defini\u00e7\u00e3o clara dos crit\u00e9rios de DoR e DoD para garantir o alinhamento de qualidade.
  • Estabelecimento de crit\u00e9rios de aceita\u00e7\u00e3o para todas as tarefas do backlog.

Observa\u00e7\u00f5es Adicionais

Aten\u00e7\u00e3o

Nota: A equipe deve garantir que os crit\u00e9rios de aceita\u00e7\u00e3o sejam revisados continuamente para alinh\u00e1-los com as expectativas do cliente e com as mudan\u00e7as no escopo.

"},{"location":"licoes-aprendidas/","title":"Li\u00e7\u00f5es aprendidas","text":"Hist\u00f3rico de Revis\u00e3o Data Vers\u00e3o Descri\u00e7\u00e3o Autor 08/11 1.0 Cria\u00e7\u00e3o do t\u00f3pico de li\u00e7\u00f5es aprendidas Maykon J\u00fanio dos Santos Soares 15/12 1.1 Adi\u00e7\u00e3o de li\u00e7\u00f5es aprendidas da unidade 2 Henrique Martins Alencar 20/01 1.2 Adi\u00e7\u00e3o de li\u00e7\u00f5es aprendidas da unidade 3 Erick Miranda Santos Unidade 1Unidade 2Unidade 3

Durante o Product Backlog Building (PBB), aprendemos que o sucesso de um projeto \u00e1gil depende da clareza e da evolu\u00e7\u00e3o constante do backlog. O processo de revisar e refinar o backlog periodicamente \u00e9 essencial para ajustar as prioridades e garantir que os itens mais importantes sejam tratados primeiro, permitindo entregas cont\u00ednuas de valor ao cliente.

  • Li\u00e7\u00e3o Aprendida: A constru\u00e7\u00e3o de um backlog bem estruturado e a revis\u00e3o constante do mesmo s\u00e3o cruciais para o sucesso de um projeto \u00e1gil. Adaptar as prioridades de acordo com o progresso do projeto e as necessidades do cliente ajuda a mitigar riscos e a garantir que o trabalho esteja sempre alinhado com os objetivos do produto.

"},{"location":"licoes-aprendidas/#unidade-1","title":"Unidade 1","text":""},{"location":"licoes-aprendidas/#introducao-ao-desenvolvimento-de-projetos","title":"Introdu\u00e7\u00e3o ao Desenvolvimento de Projetos","text":"

Na sala de aula, come\u00e7amos nossa jornada de aprendizado com o desenvolvimento de habilidades pr\u00e1ticas voltadas para projetos. Este foi apenas o in\u00edcio, mas crucial para entendermos as metodologias que guiar\u00e3o nosso trabalho.

"},{"location":"licoes-aprendidas/#metodologias-de-desenvolvimento","title":"Metodologias de Desenvolvimento","text":"

Exploramos as principais metodologias de desenvolvimento de software, compreendendo suas diferen\u00e7as e como escolher entre elas com base no **tri\u00e2ngulo de ferro:

  • Metodologias orientadas a plano: Estruturadas e detalhadas, com foco no planejamento rigoroso.
  • Metodologias \u00e1geis: Flex\u00edveis e adapt\u00e1veis, favorecendo a colabora\u00e7\u00e3o e a entrega cont\u00ednua de valor.

Dessa forma, conseguimos avaliar as vantagens e limita\u00e7\u00f5es de cada abordagem e definir qual delas \u00e9 mais apropriada para diferentes tipos de projeto.

"},{"location":"licoes-aprendidas/#ferramentas-ageis-no-mercado","title":"Ferramentas \u00c1geis no Mercado","text":"

Nos aprofundamos em duas das metodologias \u00e1geis mais populares e suas pr\u00e1ticas espec\u00edficas:

  • Scrum: Uma abordagem iterativa que organiza o trabalho em ciclos curtos, chamados de \"sprints\", para melhorar a produtividade e a entrega.
  • eXtreme Programming (XP): Focado em garantir a qualidade do c\u00f3digo atrav\u00e9s de pr\u00e1ticas como testes automatizados e programa\u00e7\u00e3o em par.

Essas ferramentas, ricas em processos e pr\u00e1ticas, fornecem uma base s\u00f3lida para o desenvolvimento de software de alto padr\u00e3o.

"},{"location":"licoes-aprendidas/#novas-ferramentas-e-tecnologias","title":"Novas Ferramentas e Tecnologias","text":"

Al\u00e9m das metodologias, a equipe teve a oportunidade de explorar novas ferramentas que facilitar\u00e3o o desenvolvimento do projeto:

  • GitHub Pages: Plataforma gratuita de hospedagem que a equipe utilizar\u00e1 para **documentar o projeto de forma clara e acess\u00edvel, garantindo que todos os membros estejam alinhados quanto aos processos e etapas.
"},{"location":"licoes-aprendidas/#unidade-2","title":"Unidade 2","text":""},{"location":"licoes-aprendidas/#processo-de-engenharia-de-requisitos","title":"Processo de Engenharia de Requisitos","text":"

Aprendemos a import\u00e2ncia de compreender profundamente as necessidades dos stakeholders e transform\u00e1-las em requisitos claros e definidos, pois nos ajudam a organizar e priorizar as etapas do desenvolvimento, trazendo um trabalho eficaz. A comunica\u00e7\u00e3o efetiva entre os principais interessados e a equipe de desenvolvimento \u00e9 crucial para minimizar a ambiguidade e o retrabalho.

"},{"location":"licoes-aprendidas/#requisitos-funcionais-e-nao-funcionais","title":"Requisitos Funcionais e n\u00e3o funcionais","text":"

Compreendemos que os requisitos funcionais definem o que o sistema deve fazer, enquanto os n\u00e3o funcionais especificam como o sistema deve funcionar. Aprendemos que ignorar requisitos n\u00e3o funcionais, como desempenho, seguran\u00e7a e usabilidade, pode comprometer a qualidade final do produto. Um desafio foi compreender quais s\u00e3o cada um desses requisitos de forma alinhada com os objetivos do projeto.

"},{"location":"licoes-aprendidas/#elaboracao-de-backlog","title":"Elabora\u00e7\u00e3o de Backlog","text":"

Durante a elabora\u00e7\u00e3o do backlog, aprendemos que a clareza das tarefas s\u00e3o cruciais para o sucesso da equipe. Organizar os requisitos separando-os por temas e \u00e9picos e atribuindo hist\u00f3rias de usu\u00e1rio nos ajudou a compreender melhor o que exatamente desenvolver para o cumprimento dos requisitos, com o objetivo de entregar um produto de maior qualidade.

"},{"location":"licoes-aprendidas/#priorizacao-do-backlog","title":"Prioriza\u00e7\u00e3o do Backlog","text":"

A prioriza\u00e7\u00e3o do backlog nos ensinou a equilibrar as necessidades do neg\u00f3cio com as restri\u00e7\u00f5es t\u00e9cnicas e de tempo. A utiliza\u00e7\u00e3o de crit\u00e9rios de prioridade com pesos atribu\u00eddos, como valor de neg\u00f3cio, complexidade, criticidade e independ\u00eancia, nos ajudou a definir que requisitos tinham maior import\u00e2ncia em nosso projeto, o que nos permite ter uma melhor organiza\u00e7\u00e3o, possibilitando entregas que estejam mais alinhadas com os objetivos do projeto.

"},{"location":"licoes-aprendidas/#definicao-de-mvp","title":"Defini\u00e7\u00e3o de MVP","text":"

A defini\u00e7\u00e3o do MVP (Minimum Viable Product) foi um exerc\u00edcio valioso para aprender a entregar valor r\u00e1pido com recursos limitados. A defini\u00e7\u00e3o do que \u00e9 essencial nos permite focar nas funcionalidades mais cr\u00edticas e de maior valor para o produto, garantindo que as necessidades principais sejam entregues dentro do prazo determinado.

"},{"location":"licoes-aprendidas/#unidade-3","title":"Unidade 3","text":""},{"location":"licoes-aprendidas/#product-backlog-building-pbb","title":"Product Backlog Building (PBB)","text":""},{"location":"licoes-aprendidas/#user-story-mapping-usm","title":"User Story Mapping (USM)","text":"

O User Story Mapping \u00e9 uma t\u00e9cnica essencial para visualizar as funcionalidades do produto de maneira estruturada e alinhada com as necessidades do usu\u00e1rio. Durante esta unidade, aprendemos a import\u00e2ncia de mapear hist\u00f3rias de usu\u00e1rio para garantir que todas as funcionalidades necess\u00e1rias para atender ao objetivo do projeto sejam contempladas de forma clara. Essa t\u00e9cnica permite uma melhor comunica\u00e7\u00e3o entre a equipe e facilita o planejamento das entregas de acordo com o valor de cada hist\u00f3ria.

  • Li\u00e7\u00e3o Aprendida: O uso de User Story Mapping proporciona uma vis\u00e3o clara das funcionalidades do sistema e facilita a prioriza\u00e7\u00e3o das tarefas com base no valor que elas agregam ao produto. \u00c9 fundamental garantir que todas as hist\u00f3rias de usu\u00e1rio estejam bem definidas e alinhadas com os objetivos do projeto.
"},{"location":"licoes-aprendidas/#integracao-de-pbb-e-usm","title":"Integra\u00e7\u00e3o de PBB e USM","text":"

Durante o processo de integra\u00e7\u00e3o entre Product Backlog Building (PBB) e User Story Mapping (USM), percebemos como essas duas metodologias se complementam. O PBB ajuda a organizar o trabalho de maneira eficiente, enquanto o USM oferece uma vis\u00e3o detalhada das funcionalidades, permitindo que a equipe foque nas hist\u00f3rias mais relevantes para o produto. A integra\u00e7\u00e3o de ambas as t\u00e9cnicas \u00e9 essencial para garantir que o backlog esteja bem estruturado e alinhado com as necessidades do usu\u00e1rio.

  • Li\u00e7\u00e3o Aprendida: A integra\u00e7\u00e3o de PBB e USM deve ser feita de forma cuidadosa, garantindo que o planejamento estrat\u00e9gico do projeto seja complementado pela vis\u00e3o detalhada das hist\u00f3rias de usu\u00e1rio. Isso permite que o trabalho seja executado de forma mais eficiente e alinhada com os objetivos do produto.
"},{"location":"recursos/instalando/","title":"Recursos","text":"Hist\u00f3rico de Revis\u00e3o Data Vers\u00e3o Descri\u00e7\u00e3o Autor 08/11 1.0 Cria\u00e7\u00e3o do t\u00f3pico de Documenta\u00e7\u00e3o Maykon J\u00fanio dos Santos Soares"},{"location":"recursos/instalando/#prepando-ambiente-virtural","title":"Prepando ambiente virtural","text":""},{"location":"recursos/instalando/#requisitos","title":"Requisitos","text":"
  • Python 3.12.3 (Latest)
  • pip 24.3.1
"},{"location":"recursos/instalando/#instalando-virtualenv","title":"Instalando virtualenv","text":"python -m pip install --user virtualenv"},{"location":"recursos/instalando/#criando-ambiente-virtual","title":"Criando ambiente virtual","text":"virtualenv venv"},{"location":"recursos/instalando/#ativando-ambiente-virtual","title":"Ativando ambiente virtual","text":"source venv/Scripts/activate"},{"location":"recursos/instalando/#instalando-pacotes","title":"Instalando pacotes","text":"pip install -r requirements.txt"},{"location":"recursos/instalando/#iniciando-localmente","title":"Iniciando localmente","text":"mkdocs serve"},{"location":"visao-produto-projeto/processo-desenvolvimento-software/","title":"Processo de Desenvolvimento de Software","text":"Hist\u00f3rico de Revis\u00e3o Data Vers\u00e3o Descri\u00e7\u00e3o Autor 08/11 1.0 Cria\u00e7\u00e3o das se\u00e7\u00e3o de Processo de desenvolvimento de software Erick Miranda Santos Maykon J\u00fanio dos Santos Soares Marllon Fausto Cardoso Pedro Miguel M. de O. dos Santos 10/11 1.1 Especifica\u00e7\u00e3o do processo de desenvolvimento Erick Miranda Santos 24/11 1.2 Altera\u00e7\u00e3o do processo de desenvolvimento (remo\u00e7\u00e3o do Dual Track Agile) Erick Miranda Santos 06/12 1.3 Altera\u00e7\u00e3o do processo de desenvolvimento (remo\u00e7\u00e3o do Kanban) Erick Miranda Santos"},{"location":"visao-produto-projeto/processo-desenvolvimento-software/#etapas-do-rad","title":"Etapas do RAD","text":""},{"location":"visao-produto-projeto/processo-desenvolvimento-software/#etapa-1-planejamento-dos-requisitos","title":"Etapa 1 - Planejamento dos requisitos","text":"

Na etapa de planejamento dos requisitos, fazemos uma an\u00e1lise completa do cen\u00e1rio e elicitamos os requisitos, nesse projeto n\u00f3s seguimos o material do Professor George Marsicano(2023)[4], por isso n\u00f3s seguimos os pontos, Descoberta e elicita\u00e7\u00e3o de requisitos, An\u00e1lise e consenso de requisitos, Declara\u00e7\u00e3o de requisitos, Verifica\u00e7\u00e3o e Valida\u00e7\u00e3o e por \u00faltimo a Organiza\u00e7\u00e3o e atualiza\u00e7\u00e3o.

Atividade M\u00e9todo Ferramenta Entrega Descoberta e elicita\u00e7\u00e3o de requisitos Diagrama de causa e 5 porqu\u00eas Trello Backlog de requisitos n\u00e3o validado An\u00e1lise e consenso de requisitos An\u00e1lise de viabilidade Teams Backlog de requisitos n\u00e3o validado Declara\u00e7\u00e3o \u00c9picos, Features e User Stories Trello User Stories n\u00e3o validado Verifica\u00e7\u00e3o e Valida\u00e7\u00e3o Feedback Google Meet User Stories validados Organiza\u00e7\u00e3o e Atualiza\u00e7\u00e3o MoSCoW e Kanban Trello Defini\u00e7\u00e3o de prioridades(MVP1 e MVP2)"},{"location":"visao-produto-projeto/processo-desenvolvimento-software/#etapa-2-user-design","title":"Etapa 2 - User Design","text":"

Na etapa de User Design, \u00e9 feito a prototipa\u00e7\u00e3o da aplica\u00e7\u00e3o, no caso \u00e9 feito o prot\u00f3tipo equivalente aos User Stories relacionados ao MVP1 na terceira unidade e ao MVP2 na quarta unidade.

Etapa M\u00e9todo Ferramenta Entregas Prototipa\u00e7\u00e3o Mock-up digital Figma Prot\u00f3tipo de alta fidelidade"},{"location":"visao-produto-projeto/processo-desenvolvimento-software/#etapa-3-desenvolvimento","title":"Etapa 3 - Desenvolvimento","text":"

Na etapa de desenvolvimento \u00e9 onde \u00e9 feito o projeto e seu c\u00f3digo \u00e9 desenvolvido, esta etapa ir\u00e1 ocorrer ap\u00f3s a etapa de User Design e Prototipa\u00e7\u00e3o.

"},{"location":"visao-produto-projeto/processo-desenvolvimento-software/#etapa-4-testes","title":"Etapa 4 - Testes","text":"

Na etapa de testagem ser\u00e1 feito os testes de todas as funcionalidades da aplica\u00e7\u00e3o

Etapa M\u00e9todo Ferramenta Entregas Testagem Testes Unit\u00e1rios, Testes End-to-end Jest, Pytest, Cypress Produto testado"},{"location":"visao-produto-projeto/processo-desenvolvimento-software/#engenharia-de-requisitos-e-o-rad","title":"Engenharia de Requisitos e o RAD","text":"Fases do RAD Atividades da Engenharia de Requisitos (ER) Pr\u00e1tica T\u00e9cnica Resultados Esperados Planejamento dos Requisitos Elicita\u00e7\u00e3o e Descoberta Levantamento de Requisitos An\u00e1lise Documental, Brainstorming, Entrevista, An\u00e1lise de Concorrentes Identificar todos os requisitos de alto n\u00edvel do projeto An\u00e1lise e Consenso An\u00e1lise de depend\u00eancia entre os requisitos e eliminar ambiguidades Brainstorming, Entrevista, An\u00e1lise de Objetivos de Dom\u00ednio Lista de requisitos bem definidos; Defini\u00e7\u00e3o dos crit\u00e9rios de prioridade dos requisitos Declara\u00e7\u00e3o Apontamento dos requisitos levantados User Story Estabelecimento de todos os requisitos Organiza\u00e7\u00e3o e Atualiza\u00e7\u00e3o Elencar os requisitos levantados de acordo com os crit\u00e9rios de prioridade Backlog de Requisitos, Crit\u00e9rios (pontua\u00e7\u00e3o, prioriza\u00e7\u00e3o), Lista de Requisitos (RF's e RNF's) Lista de requisitos organizada com o grau de prioridade Verifica\u00e7\u00e3o e Valida\u00e7\u00e3o Verificar e validar os requisitos levantados User Story, DoD e DoR, pontua\u00e7\u00e3o Backlog validado com a equipe de desenvolvimento e com o cliente; Definir DoR e DoD User Design Representa\u00e7\u00e3o Elabora\u00e7\u00e3o do design do produto Prototipagem e Mockup Finaliza\u00e7\u00e3o de prot\u00f3tipo de alta fidelidade Verifica\u00e7\u00e3o e Valida\u00e7\u00e3o Verificar e validar os requisitos atualizados e/ou novos requisitos Revis\u00e3o, DoD e DoR, testes com usu\u00e1rio Design validado com o cliente Constru\u00e7\u00e3o Representa\u00e7\u00e3o Desenvolvimento dos requisitos Discuss\u00f5es em Equipe, An\u00e1lise de Tarefas Requisito desenvolvido Verifica\u00e7\u00e3o e Valida\u00e7\u00e3o Teste dos requisitos DoR, testes de sistema Requisito devidamente testado Finaliza\u00e7\u00e3o e Entrega Verifica\u00e7\u00e3o e Valida\u00e7\u00e3o Testes de Aceita\u00e7\u00e3o Testes com usu\u00e1rio Requisitos devidamente validados com o cliente Organiza\u00e7\u00e3o e Atualiza\u00e7\u00e3o Fechamento do Backlog Revis\u00e3o da itera\u00e7\u00e3o Retrospectiva do backlog, acertos e erros"},{"location":"visao-produto-projeto/processo-desenvolvimento-software/#engenharia-de-requisitos","title":"Engenharia de Requisitos","text":""},{"location":"visao-produto-projeto/processo-desenvolvimento-software/#atividades-e-tecnicas-de-er","title":"Atividades e T\u00e9cnicas de ER","text":""},{"location":"visao-produto-projeto/processo-desenvolvimento-software/#elicitacao-e-descoberta","title":"Elicita\u00e7\u00e3o e Descoberta:","text":"
  • An\u00e1lise Documental: Ser\u00e1 utilizada para levantar quest\u00f5es t\u00e9cnicas necess\u00e1rias para o projeto, como fichas dos pacientes e relat\u00f3rios m\u00e9dicos.

  • Brainstorming: Ser\u00e1 realizada uma reuni\u00e3o em grupo para discutir e levantar ideias a respeito do projeto.

  • Entrevista: Ser\u00e1 conduzida junto ao cliente, direcionando para o entendimento do neg\u00f3cio e do problema enfrentado.

  • An\u00e1lise de Concorrentes: Ser\u00e1 realizada uma pesquisa mercadol\u00f3gica, buscando produtos j\u00e1 existentes que se assemelhem em alguns pontos \u00e0 solu\u00e7\u00e3o de software proposta.

  • An\u00e1lise e Consenso: O entendimento da equipe ser\u00e1 alinhado junto ao cliente.

  • An\u00e1lise de Objetivos de Dom\u00ednio: Ser\u00e1 feita para identificar e consolidar os principais objetivos relacionados ao dom\u00ednio do projeto.

Declara\u00e7\u00e3o de Requisitos:

  • User Story: Ser\u00e1 feita uma constru\u00e7\u00e3o dos requisitos atrav\u00e9s dessa t\u00e9cnica, onde ser\u00e1 poss\u00edvel destrinchar os requisitos em temas, \u00e9picos, hist\u00f3rias e tarefas.
"},{"location":"visao-produto-projeto/processo-desenvolvimento-software/#representacao-de-requisitos","title":"Representa\u00e7\u00e3o de Requisitos:","text":"
  • Prototipagem: Ser\u00e1 criado um prot\u00f3tipo do sistema, com fluxo de usu\u00e1rio para futura valida\u00e7\u00e3o do cliente.

  • Mockup: Ser\u00e1 uma representa\u00e7\u00e3o que simular\u00e1 o projeto final, permitindo visualizar e testar conceitos de um projeto.

  • Discuss\u00f5es em Equipe: Ser\u00e3o levantadas discuss\u00f5es para o alinhamento do entendimento dos requisitos trabalhados.

  • An\u00e1lise de Tarefas: Ser\u00e1 constru\u00edda uma estrat\u00e9gia que permita dividir uma tarefa mais complexa em tarefas mais simples.

"},{"location":"visao-produto-projeto/processo-desenvolvimento-software/#verificacao-e-validacao-de-requisitos","title":"Verifica\u00e7\u00e3o e Valida\u00e7\u00e3o de Requisitos:","text":"
  • User Story: Ser\u00e1 validado o User Story constru\u00eddo, para evitar redund\u00e2ncia e a possibilidade de um requisito ausente.

  • DoR: Ser\u00e3o definidos crit\u00e9rios para aprovar que um requisito esteja pronto para ser constru\u00eddo ou entrar no backlog.

  • DoD: Ser\u00e3o definidos crit\u00e9rios para atestar que o requisito esteja feito por completo, sem nenhuma defici\u00eancia t\u00e9cnica e funcional.

  • Pontua\u00e7\u00e3o: Ser\u00e3o definidos pontos com base na complexidade, criticidade, independ\u00eancia e no valor de neg\u00f3cio; essa pontua\u00e7\u00e3o ser\u00e1 usada para prioriza\u00e7\u00e3o dos requisitos.

  • Testes de Sistema: Ser\u00e3o realizados testes no sistema para garantir que ele atenda aos crit\u00e9rios de aceita\u00e7\u00e3o e esteja com o m\u00ednimo de falhas poss\u00edvel.

  • Testes com Usu\u00e1rio: Ser\u00e3o realizados testes diretamente com o usu\u00e1rio, onde o mesmo poder\u00e1 navegar pelo sistema para validar a funcionalidade implementada.

"},{"location":"visao-produto-projeto/processo-desenvolvimento-software/#organizacao-e-atualizacao-de-requisitos","title":"Organiza\u00e7\u00e3o e Atualiza\u00e7\u00e3o de Requisitos:","text":"
  • Backlog de Requisitos: Ser\u00e3o definidos os poss\u00edveis requisitos do sistema.

  • Crit\u00e9rios (Pontua\u00e7\u00e3o, Prioriza\u00e7\u00e3o): Ser\u00e3o definidos os crit\u00e9rios de aceita\u00e7\u00e3o, assim como seus valores para pontua\u00e7\u00e3o e respectiva prioriza\u00e7\u00e3o dos requisitos.

  • Lista de Requisitos (RF's e RNF's): Ser\u00e3o definidos e filtrados os requisitos, distinguindo-os entre funcionais e n\u00e3o funcionais.

  • Revis\u00e3o da Itera\u00e7\u00e3o: Ser\u00e1 feita uma revis\u00e3o da itera\u00e7\u00e3o, onde ser\u00e3o abordados os acertos, erros e dificuldades enfrentadas, para melhor entendimento entre os membros da equipe.

"},{"location":"visao-produto-projeto/visao-produto/","title":"Vis\u00e3o Geral do Produto","text":"Hist\u00f3rico de Revis\u00e3o Data Vers\u00e3o Descri\u00e7\u00e3o Autor 08/11 1.0 Cria\u00e7\u00e3o das se\u00e7\u00e3o de vis\u00e3o geral do produto Erick Miranda Santos Maykon J\u00fanio dos Santos Soares Marllon Fausto Cardoso Pedro Miguel M. de O. dos Santos Henrique Martins Alencar 10/11 1.1 Especifica\u00e7\u00e3o do processo de desenvolvimento Erick Miranda Santos e Henrique Martins Alencar"},{"location":"visao-produto-projeto/visao-produto/#cenario-atual-do-cliente-e-do-negocio","title":"Cen\u00e1rio atual do cliente e do neg\u00f3cio","text":""},{"location":"visao-produto-projeto/visao-produto/#introducao-ao-negocio-e-contexto","title":"Introdu\u00e7\u00e3o ao neg\u00f3cio e contexto","text":"

O Espa\u00e7o Janayna Paraizo \u00e9 uma cl\u00ednica de fisioterapia no Gama, Distrito Federal, fundada em meados de 2020 pela fisioterapeuta Janayna Paraizo. A cl\u00ednica oferece servi\u00e7os como Kinesio Taping, Acupuntura, Dry Needling, Ventosaterapia, RPG, entre outros, com foco no tratamento integrado de todo o corpo para melhorar a qualidade de vida dos pacientes. Operando atualmente de ter\u00e7a a quinta, o Espa\u00e7o Janayna Paraizo planeja expandir seu atendimento.

No entanto, a cl\u00ednica enfrenta desafios em divulgar seus servi\u00e7os, organizar e armazenar os dados dos pacientes (atualmente geridos manualmente em documentos manuscritos ou dispositivos de uma \u00fanica funcion\u00e1ria) e agendar sess\u00f5es, o que dificulta o crescimento do atendimento e sobrecarrega a equipe. Esses problemas resultam em baixa efici\u00eancia e limita\u00e7\u00e3o na capacidade de expans\u00e3o e promo\u00e7\u00e3o do estabelecimento.

"},{"location":"visao-produto-projeto/visao-produto/#identificacao-da-oportunidade-ou-problema","title":"Identifica\u00e7\u00e3o da Oportunidade ou Problema","text":"

As oportunidades para a cl\u00ednica Espa\u00e7o Janayna Paraizo giram em torno de aumentar sua visibilidade e efici\u00eancia operacional. A cria\u00e7\u00e3o de um website seria essencial para atrair potenciais clientes, permitindo que as pessoas conhe\u00e7am melhor os servi\u00e7os oferecidos, o perfil dos profissionais, os diferenciais da cl\u00ednica e os resultados obtidos com os tratamentos. Isso traria uma presen\u00e7a digital estrat\u00e9gica, facilitando a divulga\u00e7\u00e3o da cl\u00ednica.

Al\u00e9m disso, a implanta\u00e7\u00e3o de uma aplica\u00e7\u00e3o web centralizada reduziria significativamente o tempo gasto no registro, busca e visualiza\u00e7\u00e3o das informa\u00e7\u00f5es dos pacientes. Com isso, todos os funcion\u00e1rios teriam acesso f\u00e1cil e organizado aos dados dos pacientes, o que descentralizaria as tarefas e aliviaria a carga de trabalho de uma \u00fanica pessoa.

Outra oportunidade importante \u00e9 a implementa\u00e7\u00e3o de uma agenda integrada \u00e0 aplica\u00e7\u00e3o web, permitindo o registro de hor\u00e1rios livres e ocupados para sess\u00f5es. Isso daria tanto aos funcion\u00e1rios quanto aos clientes uma vis\u00e3o clara dos hor\u00e1rios dispon\u00edveis, permitindo que os clientes agendem suas sess\u00f5es de forma aut\u00f4noma, sem a necessidade de interven\u00e7\u00e3o direta da equipe, otimizando o fluxo de trabalho e oferecendo mais conveni\u00eancia aos pacientes.

Para melhor compreens\u00e3o do problema identificado, foi elaborado um diagrama de Ishikawa, que apresenta as principais causas e fatores relacionados ao problema.

Diagrama de Ishikawa - Espa\u00e7o Janayna Paraizo.

"},{"location":"visao-produto-projeto/visao-produto/#desafios-do-projeto","title":"Desafios do Projeto","text":"

Os principais desafios do projeto incluem o desenvolvimento de uma solu\u00e7\u00e3o web capaz de registrar todas as informa\u00e7\u00f5es essenciais sobre os pacientes, como dados t\u00e9cnicos, hist\u00f3rico cl\u00ednico, h\u00e1bitos de vida, tratamentos realizados, uso de medicamentos e localiza\u00e7\u00f5es de dores, al\u00e9m das classifica\u00e7\u00f5es e tipos de disfun\u00e7\u00f5es de movimento tratadas na fisioterapia.

Outro desafio importante \u00e9 a cria\u00e7\u00e3o de uma interface que n\u00e3o apenas facilite as opera\u00e7\u00f5es com os dados dos pacientes, mas tamb\u00e9m torne essas atividades mais r\u00e1pidas e organizadas em compara\u00e7\u00e3o ao registro manual em papel ou em documentos de texto.

"},{"location":"visao-produto-projeto/visao-produto/#segmentacao-de-clientes","title":"Segmenta\u00e7\u00e3o de Clientes","text":"

O Espa\u00e7o Janayna Paraizo atende tr\u00eas segmentos principais de clientes. O primeiro grupo \u00e9 composto por idosos entre 65 e 85 anos, que representam a maior parte dos clientes recorrentes da cl\u00ednica, buscando melhorar sua qualidade de vida e lidar com problemas de sa\u00fade relacionados ao envelhecimento e, com isso, necessitam de acompanhamento constante, al\u00e9m de uma documenta\u00e7\u00e3o detalhada de suas evolu\u00e7\u00f5es ao longo das se\u00e7\u00f5es, uma vez que rotineiramente precisam apresnetar essas informa\u00e7\u00f5es em encontros com outros profissionais da sa\u00fade. O segundo grupo inclui os acompanhantes desses idosos, geralmente jovens e adultos entre 19 e 50 anos, que s\u00e3o parentes ou amigos pr\u00f3ximos respons\u00e1veis por agendar, transportar e acompanhar os idosos durante as sess\u00f5es, atuando como o principal canal de comunica\u00e7\u00e3o entre os pacientes idosos e a cl\u00ednica. O terceiro grupo abrange pacientes de diferentes idades com problemas espor\u00e1dicos, que procuram atendimento para dist\u00farbios pontuais de curto ou m\u00e9dio prazo, constituindo uma fonte de receita adicional para a cl\u00ednica, ao contr\u00e1rio dos idosos que requerem acompanhamento cont\u00ednuo.

"},{"location":"visao-produto-projeto/visao-produto/#solucao-proposta","title":"Solu\u00e7\u00e3o proposta","text":""},{"location":"visao-produto-projeto/visao-produto/#objetivos-do-produto","title":"Objetivos do Produto","text":"

O objetivo do produto Paraizo \u00e9 viabilizar a amplia\u00e7\u00e3o da quantidade de clientes da cl\u00ednica. Para isso, faz-se necess\u00e1rio a redu\u00e7\u00e3o do tempo demandado na execu\u00e7\u00e3o de atividades relacionadas \u00e0 documenta\u00e7\u00e3o e agendamento de consultas, possibilitando assim a realiza\u00e7\u00e3o dessas atividades com um n\u00famero maior de clientes, e facilitar a divulga\u00e7\u00e3o e marketing do estabelecimento. Para tanto, este produto ir\u00e1, por meio de uma \u00fanica plataforma web:

Aprimorar o cadatro e consulta de dados dos pacientes, como dados t\u00e9cnicos (informa\u00e7\u00f5es refer\u00eantes a seus disturbios e problemas f\u00edsicos), hist\u00f3rico cl\u00ednico, h\u00e1bitos de vida, tratamentos realizados, uso de medicamentos e localiza\u00e7\u00f5es de dores, substituindo processos manuais e informais, como registros em planilhas e locais tempor\u00e1rios, que j\u00e1 n\u00e3o atendem \u00e0s necessidades da organiza\u00e7\u00e3o por conta do tempo significativo que esse processo exige atualmente e tamb\u00e9m pela centraliza\u00e7\u00e3o deste trabalho em uma s\u00f3 funcion\u00e1ria.

Fornecer um local de compartilhamento, acessado por meio de login, que re\u00fana os resultados dos pacientes, facilitando a avalia\u00e7\u00e3o dos tratamentos realizados e o acompanhamento dos resultados por parte dos mesmos. Vale ressaltar que para isso o sistema dever\u00e1 ser uma solu\u00e7\u00e3o web com a capacidade de ser reproduzida em diferentes tamanhos de tela.

Ter uma landing page, que divulgar\u00e1 informa\u00e7\u00f5es da cl\u00ednica, como servi\u00e7os, quadro de funcion\u00e1rios, avalia\u00e7\u00f5es e resultados, promovendo maior credibilidade a cl\u00ednica no mercado, ao passo que auxiliar\u00e1 com a prospec\u00e7\u00e3o de novos clientes.

Possibilitar o cadastro e a visualiza\u00e7\u00e3o de agendamentos de consultas, com integra\u00e7\u00e3o ao Google Agenda, facilitando a gest\u00e3o dos hor\u00e1rios por parte da equipe da cl\u00ednica.

"},{"location":"visao-produto-projeto/visao-produto/#caracteristicas-da-solucao","title":"Caracter\u00edsticas da solu\u00e7\u00e3o","text":"

Segue o conjunto preliminar das caracter\u00edsticas deste produto:

  • O sistema dever\u00e1 ter a Centraliza\u00e7\u00e3o dos dados dos pacientes, como dados t\u00e9cnicos, hist\u00f3rico cl\u00ednico, h\u00e1bitos de vida, tratamentos realizados, uso de medicamentos e localiza\u00e7\u00f5es de dores;
  • O Sistema dever\u00e1 ter um local de compartilhamento com login para pacientes, reunindo os resultados de consultas e facilitando a avalia\u00e7\u00e3o dos tratamentos realizados;
  • O sistema dever\u00e1 ter uma Landing page para divulga\u00e7\u00e3o de informa\u00e7\u00f5es da cl\u00ednica, como servi\u00e7os, quadro de funcion\u00e1rios, avalia\u00e7\u00f5es e resultados;
  • O Sistema dever\u00e1 possuir uma ferramenta de cadastro e visualiza\u00e7\u00e3o de agendamentos de consultas para o cliente e seus pacientes, fazendo com que pacientes possam marcar consultas sem a interven\u00e7\u00e3o direta de funcion\u00e1rios;
  • Integra\u00e7\u00e3o com o Google Agenda para a cl\u00ednica, resultando em uma visualiza\u00e7\u00e3o mais ampla de hor\u00e1rios dispon\u00edveis; e
  • O sistema dever\u00e1 ser implementado em uma plataforma web, podendo ser utilizada em diferentes dispositivos.
"},{"location":"visao-produto-projeto/visao-produto/#pesquisa-de-mercado-e-analise-competitiva","title":"Pesquisa de Mercado e An\u00e1lise Competitiva","text":"

Existem outras solu\u00e7\u00f5es no mercado que visam melhorar a gest\u00e3o cl\u00ednica, como, por exemplo:

  • Plena Vittae: O sistema de agendamento \u00e9 realizado apenas atrav\u00e9s do contato com o profissional via WhatsApp. N\u00e3o possui sistema de login para visualiza\u00e7\u00e3o das informa\u00e7\u00f5es dos pacientes;
  • CETFISIO: Tamb\u00e9m se limita apenas ao contato e agendamento via WhatsApp, al\u00e9m de n\u00e3o apresentar detalhes sobre o pr\u00f3prio estabelecimento e seus servi\u00e7os, como, por exemplo, informa\u00e7\u00f5es sobre o quadro de funcion\u00e1rios, hist\u00f3rico de atendimento da cl\u00ednica, tipos de servi\u00e7os prestados e a quem eles s\u00e3o indicados e hor\u00e1rios de funcionamento;
  • Rede D\u2019OR S\u00e3o Luiz: Novamente, este sistema tamb\u00e9m n\u00e3o oferece formas dos pacientes visualizarem suas pr\u00f3prias informa\u00e7\u00f5es e o sistema de contato e agendamento apresenta as mesmas caracter\u00edsticas dos anteriores.

Vale ressaltar

O produto Paraizo se destaca, principalmente, pela forma com que ele diminui a carga de trabalho dos funcion\u00e1rios da cl\u00ednica, uma vez que o sistema de agendamento e o login para visualiza\u00e7\u00e3o das infoma\u00e7\u00f5es do paciente descentraliza a responsabilidade dessas atividades, permitindo que, sem a necessidade de contato com algum representante da cl\u00ednica, uma consulta seja marcada ou que algum documento desejado pelo paciente seja obtido.

"},{"location":"visao-produto-projeto/visao-produto/#analise-de-viabilidade","title":"An\u00e1lise de Viabilidade","text":"

A respeito da viabilidade t\u00e9cnica do projeto, a equipe de desenvolvimento \u00e9 dividida com rela\u00e7\u00e3o \u00e0 familiaridade com as tecnologias a serem utilizadas (segue abaixo a tabela com as tecnologias utilizadas), permitindo que aqueles com mais experi\u00eancia e familiaridade auxiliem os demais quando julgarem necess\u00e1rio. Al\u00e9m disso, apesar de parte da equipe n\u00e3o apresentar muita familiaridade e experi\u00eancia com as tecnologias usadas, todos possuem conhecimento com o desenvolvimento que envolvem funcionalidades que tamb\u00e9m ser\u00e3o desenvolvidas neste projeto (como a integra\u00e7\u00e3o com o google agendas, sistema de autentica\u00e7\u00e3o e valida\u00e7\u00e3o de contas de usu\u00e1rio e banco de dados), tornando o projeto vi\u00e1vel tecnicamente. Com re\u00e7\u00e3o ao tempo de desenvolvimento, o projeto ser\u00e1 realizado durante 6 meses, organizado em itenra\u00e7\u00f5es que, ao final, ser\u00e3o entregues partes do projeto, como o prot\u00f3tipo de alta fidelidade, implementa\u00e7\u00e3o de funcionalidades ou incremento de outras.

"},{"location":"visao-produto-projeto/visao-produto/#tecnologias-utilizadas","title":"Tecnologias utilizadas","text":"Tecnologia Descri\u00e7\u00e3o \u00c1rea de Aplica\u00e7\u00e3o React.js Biblioteca JavaScript para constru\u00e7\u00e3o de interfaces Frontend Next.js Framework para React com renderiza\u00e7\u00e3o do lado do servidor Frontend, SSR Tailwind CSS Framework de CSS para estiliza\u00e7\u00e3o r\u00e1pida e responsiva Frontend Flask Framework minimalista em Python para desenvolvimento web Backend MongoDB Banco de dados NoSQL orientado a documentos Banco de Dados Firebase Plataforma para autentica\u00e7\u00e3o, armazenamento e deploy Autentica\u00e7\u00e3o, Hospedagem Google Calendar API API para integra\u00e7\u00e3o de agendas Integra\u00e7\u00e3o com Google Calendar GitHub Reposit\u00f3rio para versionamento e colabora\u00e7\u00e3o Controle de Vers\u00e3o Jest Framework de testes para JavaScript Testes PyTest Framework de testes para Python Testes Microsoft Teams Plataforma para comunica\u00e7\u00e3o e reuni\u00f5es internas Comunica\u00e7\u00e3o Google Meet Plataforma para reuni\u00f5es com o cliente Comunica\u00e7\u00e3o WhatsApp Comunica\u00e7\u00e3o ass\u00edncrona para suporte r\u00e1pido Comunica\u00e7\u00e3o"},{"location":"visao-produto-projeto/visao-produto/#impacto-da-solucao","title":"Impacto da Solu\u00e7\u00e3o","text":"

Com a cria\u00e7\u00e3o do software PARAIZO, espera-se um impacto significativo no que se refere ao tempo destinado nas atividades referentes \u00e0s documenta\u00e7\u00f5es e manejamento de dados, al\u00e9m de possibilitar uma melhora no processo de divulga\u00e7\u00e3o dos servi\u00e7os da cl\u00ednica. Nesse sentido, conclui-se o produto afetaria a cl\u00ednica das seguintes formas:

Benef\u00edcios

  • Redu\u00e7\u00e3o no tempo destinado \u00e0s atividades de visualiza\u00e7\u00e3o e edi\u00e7\u00e3o de dados de clientes, uma vez que n\u00e3o ser\u00e1 mais necess\u00e1rio procurar manualmente o papel onde est\u00e1 estes registros;
  • Redu\u00e7\u00e3o no tempo destinado \u00e0s atividades relacionadas \u00e0 organiza\u00e7\u00e3o e procura dos arquivos nos espa\u00e7os f\u00edsicos da cl\u00ednica;
  • Permitir\u00e1 que outros funcion\u00e1rios preencham os dados ou confeccionem documentos exigidos, diminuindo a sobrecarga de trabalho que se concentra em uma \u00fanica funcion\u00e1ria;
  • Proporcionar a visualiza\u00e7\u00e3o do hist\u00f3rico de evolu\u00e7\u00e3o dos pacientes poder\u00e1 acarretar em uma taxa maior de fideliza\u00e7\u00e3o de clientes ao estabelecimento;
  • Com o desenvolvimento de um site com as informa\u00e7\u00f5es sobre os servi\u00e7os prestados, avalia\u00e7\u00f5es de seus clientes e quadro de funcion\u00e1rios, ajudar\u00e1 os respons\u00e1veis com o trabalho de divulga\u00e7\u00e3o e marketing do estabelecimento.
"},{"location":"visao-produto-projeto/visao-produto/#estrategias-de-engenharia-de-software","title":"Estrat\u00e9gias de Engenharia de Software","text":""},{"location":"visao-produto-projeto/visao-produto/#estrategia-priorizada","title":"Estrat\u00e9gia Priorizada","text":"
  • Abordagem: \u00c1gil

  • Ciclo de vida: \u00c1gil

  • Processo: RAD

"},{"location":"visao-produto-projeto/visao-produto/#quadro-comparativo","title":"Quadro Comparativo","text":"

O quadro a seguir compara os processos de desenvolvimento RAD e ScrumXP em diversas caracter\u00edsticas, com o objetivo de auxiliar na justificativa para a escolha do processo mais adequado a este projeto.

Caracter\u00edsticas RAD ScrumXP Abordagem Geral Desenvolvimento r\u00e1pido e iterativo focado em prot\u00f3tipos e entregas r\u00e1pidas Desenvolvimento incremental e iterativo, com \u00eanfase na agilidade e na qualidade do c\u00f3digo. Foco em Arquitetura Menor foco inicial em arquitetura; \u00eanfase em prot\u00f3tipos Alto; arquitetura emergente \u00e9 planejada e ajustada para garantir flexibilidade e qualidade. Estrutura de Processos Estrutura flex\u00edvel, com itera\u00e7\u00f5es r\u00e1pidas e prototipagem Bem definida, com sprints baseados em Scrum e pr\u00e1ticas de engenharia do XP, como TDD e integra\u00e7\u00e3o cont\u00ednua. Flexibilidade de Requisitos Alta; requisitos podem ser alterados durante o desenvolvimento Moderada; mudan\u00e7as s\u00e3o bem-vindas, mas priorizadas e organizadas no backlog do produto. Colabora\u00e7\u00e3o com Clientes Intensa; cliente envolvido em feedback frequente e revis\u00e3o de prot\u00f3tipos Muito alta; cliente \u00e9 frequentemente envolvido em testes e feedback cont\u00ednuos. Complexidade do Processo Baixa a moderada; processos adapt\u00e1veis e menos formais Moderada a alta; requer dom\u00ednio t\u00e9cnico devido \u00e0s pr\u00e1ticas avan\u00e7adas de desenvolvimento. Qualidade T\u00e9cnica Foco em funcionalidade; qualidade t\u00e9cnica pode ser sacrificada pela velocidade Alta; qualidade \u00e9 garantida por pr\u00e1ticas como TDD, refatora\u00e7\u00e3o cont\u00ednua e c\u00f3digo coletivo. Pr\u00e1ticas de Desenvolvimento Prototipagem r\u00e1pida, foco em entrega de funcionalidades principais Desenvolvimento \u00e1gil com pr\u00e1ticas t\u00e9cnicas rigorosas (TDD, pair programming, etc.). Adapta\u00e7\u00e3o ao Projeto Ideal para projetos com escopo indefinido ou mudan\u00e7as constantes Adequado para projetos complexos, que exigem alta qualidade e entregas regulares. Documenta\u00e7\u00e3o Documenta\u00e7\u00e3o m\u00ednima, foco em prot\u00f3tipos e entregas r\u00e1pidas M\u00ednima, mas suficiente para suportar o desenvolvimento e garantir rastreabilidade. Controle de Qualidade Controle mais b\u00e1sico, com \u00eanfase em entregas r\u00e1pidas e testes do usu\u00e1rio final Rigoroso; inclui testes automatizados, integra\u00e7\u00e3o cont\u00ednua e revis\u00f5es de c\u00f3digo. Escalabilidade Limitada, mais indicada para projetos pequenos e m\u00e9dios Alta, pode ser aplicado a equipes maiores com coordena\u00e7\u00e3o eficaz. Suporte a Equipes de Desenvolvimento Moderado; dependente mais do feedback do cliente e prot\u00f3tipos r\u00e1pidos Alto, suporte t\u00e9cnico e organizacional robusto por meio de pap\u00e9is claros e pr\u00e1ticas \u00e1geis."},{"location":"visao-produto-projeto/visao-produto/#bibliografia","title":"Bibliografia","text":"
  1. BECKER, ALICE: Entenda o que \u00e9 o Rapid Application Delivery (RAD) e sua Rela\u00e7\u00e3o com os M\u00e9todos \u00c1geis. Dispon\u00edvel em: https://voitto.com.br/blog/artigo/rapid-application-delivery-rad

  2. CASA DO DESENVOLVEDOR: XP e Scrum: qual m\u00e9todo utilizar para gerir seus projetos de software? Dispon\u00edvel em: https://blog.casadodesenvolvedor.com.br/xp-scrum/

"},{"location":"visao-produto-projeto/visao-produto/#justificativa","title":"Justificativa","text":""},{"location":"visao-produto-projeto/visao-produto/#gupta","title":"GUPTA","text":"

Com o intuito de escolher a melhor abord\u00e1gem de desenvolvimento de software para o desenvolvimento desse projeto, ser\u00e1 utilizado o m\u00e9todo GUPTA, que estabelece crit\u00e9rios importantes para essa defini\u00e7\u00e3o. A seguir, ser\u00e3o apresentados as an\u00e1lises feitas pela equipe com rela\u00e7\u00e3o \u00e0s Caracter\u00edsticas dos Requisitos, Status da Equipe de Desenvolvimento, Envolvimento do Usu\u00e1rio e Tipo de Projeto e Risco Associado.

Vale ressaltar

As perguntas com respostas marcadas com referen-se a resposta que a equipe julgou mais adequada para o projeto. Por exemplo, em \"Os requisitos s\u00e3o f\u00e1ceis de entender e definir?\", a respostas mais adequada \u00e9 \"N\u00e3o\".

Requisitos Waterfall Prot\u00f3tipo Iterativo Evolucion\u00e1rio Espiral RAD Os requisitos s\u00e3o f\u00e1ceis de entender e definir? Sim N\u00e3o N\u00e3o N\u00e3o N\u00e3o Sim Mudamos os requisitos com bastante frequ\u00eancia? N\u00e3o Sim N\u00e3o N\u00e3o Sim N\u00e3o Podemos definir os requisitos no in\u00edcio do ciclo? Sim N\u00e3o Sim Sim N\u00e3o Sim Os requisitos indicam um sistema complexo a ser constru\u00eddo? N\u00e3o Sim Sim Sim Sim N\u00e3o Total 3 1 3 3 1 3

A partir das respostas da tabela acima, abstrai-se que os requisitos n\u00e3o s\u00e3o todos bem definidos, mas que ainda podem ser totalmente definidos no in\u00edcio do projeto. Isso decorre, sumariamente, em rela\u00e7\u00e3o aos requisitos relacionado \u00e0s informa\u00e7\u00f5es t\u00e9cnicas que devem estar presentes nas fichas dos pacientes.

Equipe de Desenvolvimento Waterfall Prot\u00f3tipo Iterativo Evolucion\u00e1rio Espiral RAD Pouca experi\u00eancia em projetos similares N\u00e3o Sim N\u00e3o N\u00e3o Sim N\u00e3o Pouco conhecimento de dom\u00ednio (novidade na tecnologia) Sim N\u00e3o Sim Sim Sim N\u00e3o Pouca experi\u00eancia com as ferramentas a serem usadas Sim N\u00e3o N\u00e3o N\u00e3o Sim N\u00e3o Disponibilidade de treinamento, se necess\u00e1rio N\u00e3o N\u00e3o Sim Sim N\u00e3o Sim Total 1 2 3 3 0 4

A partir das respostas da tabela acima, abstrai-se que a equipe n\u00e3o tem tanta experi\u00eancia com projetos semelhantes, mas que ainda apresenta conhecimento com as tecnologias e ferramentas usadas. Vale ressaltar que, como descrito em \"An\u00e1lise de Viabilidade\", parte da equipe n\u00e3o \u00e9 t\u00e3o habilidosa, entretanto est\u00e3o dispostos a participar de treinamentos caso necess\u00e1rio.

Envolvimento dos usu\u00e1rios Waterfall Prot\u00f3tipo Iterativo Evolucion\u00e1rio Espiral RAD Envolvimento dos usu\u00e1rios em todas as fases N\u00e3o Sim N\u00e3o N\u00e3o N\u00e3o Sim Participa\u00e7\u00e3o limitada do usu\u00e1rio Sim N\u00e3o Sim Sim Sim N\u00e3o Usu\u00e1rio sem experi\u00eancia anterior de participa\u00e7\u00e3o em projetos similares N\u00e3o Sim Sim Sim Sim N\u00e3o Usu\u00e1rios s\u00e3o especialistas no dom\u00ednio do problema N\u00e3o Sim N\u00e3o N\u00e3o N\u00e3o Sim Total 1 3 1 0 0 4

A partir das respostas da tabela acima, abstrai-se que o projeto ter\u00e1 muito envolvimento dos usu\u00e1rios, sumariamente a pr\u00f3pria cliente, al\u00e9m de ser especialista no assunto, podendo auxiliar a equipe quando necess\u00e1rio.

Tipo de Projeto e Risco Waterfall Prot\u00f3tipo Iterativo Evolucion\u00e1rio Espiral RAD O projeto \u00e9 uma melhoria de um sistema existente N\u00e3o N\u00e3o Sim Sim N\u00e3o Sim O financiamento \u00e9 est\u00e1vel para o projeto Sim Sim N\u00e3o N\u00e3o N\u00e3o Sim Altos requisitos de confiabilidade N\u00e3o N\u00e3o Sim Sim Sim N\u00e3o Cronograma apertado do projeto N\u00e3o Sim Sim Sim Sim Sim Uso de componentes reutiliz\u00e1veis N\u00e3o Sim N\u00e3o N\u00e3o Sim Sim Os recursos (tempo, dinheiro, pessoas, etc.) s\u00e3o escassos? N\u00e3o Sim N\u00e3o N\u00e3o Sim N\u00e3o Total 2 5 2 2 5 3

A partir das respostas da tabela acima, abstrai-se que o projeto tem cronograma curto, al\u00e9m da aus\u00eancia de financiamento. Por\u00e9m, os requisitos n\u00e3o s\u00e3o de alta confiabilidade e n\u00e3o \u00e9 uma melhoria de um sistema existente.

Conclus\u00e3o Waterfall Prot\u00f3tipo Iterativo Evolucion\u00e1rio Espiral RAD Requisitos 3 1 3 3 1 3 Equipe de Desenvolvimento 1 2 3 3 0 4 Envolvimento dos usu\u00e1rios 1 3 1 0 0 4 Tipo de Projeto e Risco 2 5 2 2 5 3 Total 7 11 9 8 6 14

Por fim, a tabela acima busca evidenciar quais processos mais se alinham com o projeto em pauta, atrav\u00e9s de uma soma das respostas em cada um dos 4 segmentos.

Baseado na an\u00e1lise comparativa entre os processos RAD e Scrum, junto com a an\u00e1lise atrav\u00e9s do m\u00e9todo GUPTA, o processo escolhido foi o RAD, pois ele prioriza rapidez e flexibilidade, caracter\u00edsticas essenciais em caso de mudan\u00e7a de requisitos, que pode ser um t\u00f3pico abordado com a cliente em reuni\u00f5es futuras. O RAD permite prototipagem r\u00e1pida e intera\u00e7\u00e3o cont\u00ednua com a cliente, garantindo que os feedbacks sejam incorporados de forma \u00e1gil ao longo do desenvolvimento. Com uma estrutura mais leve e menos formal do que outros m\u00e9todos, o RAD ser\u00e1 ideal para o projeto, j\u00e1 que ele tem uma menor complexidade, onde a \u00eanfase est\u00e1 em obter resultados pr\u00e1ticos e adapt\u00e1veis em um curto espa\u00e7o de tempo.

Representa\u00e7\u00e3o gr\u00e1fica ciclo de vida RAD.

Caracter\u00edsticas

  • \u00c9 considera uma abordagem \u00e1gil, centrada no usu\u00e1rio e design do produto
  • Fortemente baseado no feedback do usu\u00e1rio
  • Os requisitos do produto s\u00e3o tratados como vari\u00e1veis
"},{"location":"visao-produto-projeto/visao-projeto/","title":"Vis\u00e3o do Projeto","text":"Hist\u00f3rico de Revis\u00e3o Data Vers\u00e3o Descri\u00e7\u00e3o Autor 08/11 1.0 Cria\u00e7\u00e3o das se\u00e7\u00e3o de vis\u00e3o geral do projeto Erick Miranda Santos Maykon J\u00fanio dos Santos Soares Marllon Fausto Cardoso Pedro Miguel M. de O. dos Santos 24/11 1.1 O planejamento do quadro e das itera\u00e7\u00f5es est\u00e1 sendo ajustado para promover maior clareza e efici\u00eancia no fluxo de trabalho. Erick Miranda Santos 15/12 1.1 Revis\u00e3o de cronograma de entregas. Maykon J\u00fanio dos Santos Soares"},{"location":"visao-produto-projeto/visao-projeto/#interacao-entre-equipe-e-cliente","title":"Intera\u00e7\u00e3o entre equipe e cliente","text":""},{"location":"visao-produto-projeto/visao-projeto/#composicao-da-equipe","title":"Composi\u00e7\u00e3o da Equipe","text":"Papel Descri\u00e7\u00e3o Respons\u00e1vel Participantes Gerente do Projeto Coordena o projeto, garante a comunica\u00e7\u00e3o entre cliente e equipe, controla prazos e entregas. Maykon J\u00fanio dos Santos Soares Marllon Fausto Desenvolvedor Frontend Respons\u00e1vel pela interface do usu\u00e1rio, design e implementa\u00e7\u00e3o das funcionalidades no lado do cliente. Marllon Fausto Henrique Martins, Pedro Miguel Desenvolvedor Backend Implementa a l\u00f3gica de neg\u00f3cios, integra\u00e7\u00e3o com banco de dados e APIs. Erick Miranda Maykon J\u00fanio dos Santos Soares, Marllon Fausto Analista de QA Garante a qualidade do produto, executando testes de funcionalidade, performance e usabilidade. Pedro Miguel Martins Erick Miranda Analista de Requisitos Define os requisitos funcionais e n\u00e3o funcionais do sistema e garante que eles sejam atendidos. Henrique Martins Pedro Miguel, Maykon J\u00fanio dos Santos Soares, Marllon Fausto, Erick Miranda"},{"location":"visao-produto-projeto/visao-projeto/#matriz-de-comunicacao","title":"Matriz de Comunica\u00e7\u00e3o","text":"Ferramenta Objetivo Frequ\u00eancia Microsoft Teams Reuni\u00f5es semanais entre a equipe de desenvolvimento para planejamento, alinhamentos e feedbacks. Semanal Google Meet Reuni\u00f5es entre a equipe de desenvolvimento e o cliente para relatar andamento, validar entregas e tirar d\u00favidas. Conforme necess\u00e1rio (reuni\u00f5es com o cliente) WhatsApp Comunica\u00e7\u00e3o ass\u00edncrona entre equipe e cliente para sanar d\u00favidas ou realizar comunica\u00e7\u00f5es r\u00e1pidas. Conforme necess\u00e1rio (intera\u00e7\u00f5es informais)"},{"location":"visao-produto-projeto/visao-projeto/#metodos-e-frequencia-de-reunioes","title":"M\u00e9todos e Frequ\u00eancia de Reuni\u00f5es","text":"Reuni\u00e3o Objetivo Frequ\u00eancia Reuni\u00e3o de planejamento e revis\u00e3o de Itera\u00e7\u00e3o Planejamento e revis\u00e3o do progresso das Itera\u00e7\u00f5es, alinhamento da equipe. Semanal"},{"location":"visao-produto-projeto/visao-projeto/#frequencia-de-interacoes-com-o-cliente","title":"Frequ\u00eancia de Intera\u00e7\u00f5es com o Cliente","text":"Intera\u00e7\u00e3o Objetivo Frequ\u00eancia Revis\u00f5es de Itera\u00e7\u00e3o Cliente valida entregas e fornece feedback. A cada 2 semanas Intera\u00e7\u00f5es espor\u00e1dicas via WhatsApp Comunica\u00e7\u00e3o r\u00e1pida para d\u00favidas ou ajustes imediatos. Conforme necess\u00e1rio"},{"location":"visao-produto-projeto/visao-projeto/#planejamento-das-fases-eou-iteracoes-do-projeto","title":"Planejamento das Fases e/ou Itera\u00e7\u00f5es do Projeto","text":"Itera\u00e7\u00e3o Fase RAD Processo de Engenharia Produto (Entrega) Data In\u00edcio Data Fim Dias 0 Planejamento dos Requisitos Defini\u00e7\u00e3o do produtoDefini\u00e7\u00e3o do ProblemaLevantamento inicial e an\u00e1lise de requisitos Documento de vis\u00e3o inicial do produto 22/10/2024 04/11/2024 14 1 Planejamento dos Requisitos Levantamento inicial e an\u00e1lise de requisitos Levantamento de backlog incial 05/11/2024 18/11/2024 14 2 Planejamento dos Requisitos Levantamento inicial e an\u00e1lise de requisitosPrioriza\u00e7\u00e3o incial de requisitos Levantamento de backlog incial 19/11/2024 02/12/2024 14 3 Planejamento dos Requisitos Refinamento e prioriza\u00e7\u00e3o de backlogDefini\u00e7\u00e3o de DoR e DoDDefini\u00e7\u00e3o de crit\u00e9rios de aceita\u00e7\u00e3o Backlog detalhado para MVP1 e MVP2 03/12/2024 16/12/2024 14 4 User Design Prototipa\u00e7\u00e3o detalhada de [US01], [US04], [US05], [US08], [US06], [US13], [US02], [US07], [US16], [US17], [US18], [US19], [US20], [US24], [US09], [US10], [US11] e [US14] Feedback de usu\u00e1riosAjustes com base no feedback Prot\u00f3tipos para entregas parciais 17/12/2024 30/12/2024 14 Pausa - Recesso de Fim de Ano - 31/12/2024 07/01/2025 8 5 Desenvolvimento e Testes Desenvolvimento iterativo e testes para [US01], [US04], [US05], [US08] e [US06] Entrega parcial 1 - MVP 08/01/2025 21/01/2025 14 6 Desenvolvimento e Testes Desenvolvimento iterativo e testes para [US13], [US02], [US07], [US16], [US17], [US18], [US19], [US20] e [US24] Entrega parcial 2 - MVP 22/01/2025 04/02/2025 14 7 Desenvolvimento e Testes Desenvolvimento iterativo e testes para [US09], [US10], [US11] e [US14] Entrega parcial 3 - MVP 05/02/2025 18/02/2025 14"}]} \ No newline at end of file diff --git a/sitemap.xml b/sitemap.xml new file mode 100644 index 0000000..0f8724e --- /dev/null +++ b/sitemap.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/sitemap.xml.gz b/sitemap.xml.gz new file mode 100644 index 0000000..8ddcf7d Binary files /dev/null and b/sitemap.xml.gz differ diff --git a/stylesheets/extra.css b/stylesheets/extra.css new file mode 100644 index 0000000..03652e0 --- /dev/null +++ b/stylesheets/extra.css @@ -0,0 +1,39 @@ +[data-md-color-scheme="slate"] { + --md-primary-fg-color: #31353d; + --md-primary-fg-color--light: rgb(0, 0, 0); + --md-primary-fg-color--dark: rgb(0, 0, 0); + --md-default-bg-color: #202121; +} + +[data-md-color-scheme="slate"] .md-typeset h1, +[data-md-color-scheme="slate"] .md-typeset h2, +[data-md-color-scheme="slate"] .md-typeset h3, +[data-md-color-scheme="slate"] .md-typeset h4, +[data-md-color-scheme="slate"] .md-typeset h5, +[data-md-color-scheme="slate"] .md-typeset h6 { + color: #f7f7f7; +} + +[data-md-color-scheme="default"] { + --md-primary-fg-color: #31353d; + --md-primary-fg-color--light: #31353d; + --md-primary-fg-color--dark: #31353d; + --md-default-bg-color: #f7f7f7; +} + +[data-md-color-scheme="default"] .md-typeset h1, +[data-md-color-scheme="default"] .md-typeset h2, +[data-md-color-scheme="default"] .md-typeset h3, +[data-md-color-scheme="default"] .md-typeset h4, +[data-md-color-scheme="default"] .md-typeset h5, +[data-md-color-scheme="default"] .md-typeset h6 { + color: #31353d; +} + +.md-footer-meta .md-typeset { + visibility: hidden; +} + +.md-nav__item .md-nav__link--active { + color: #0270d7 !important ; +} diff --git a/stylesheets/termynal.css b/stylesheets/termynal.css new file mode 100644 index 0000000..7d3bd38 --- /dev/null +++ b/stylesheets/termynal.css @@ -0,0 +1,111 @@ +/** + * termynal.js + * + * @author Ines Montani + * @version 0.0.1 + * @license MIT + */ + +:root { + --color-bg: #252a33; + --color-text: #eee; + --color-text-subtle: #a2a2a2; +} + +[data-termynal] { + width: 750px; + max-width: 100%; + background: var(--color-bg); + color: var(--color-text); + /* font-size: 18px; */ + font-size: 15px; + /* font-family: 'Fira Mono', Consolas, Menlo, Monaco, 'Courier New', Courier, monospace; */ + font-family: "Roboto Mono", "Fira Mono", Consolas, Menlo, Monaco, + "Courier New", Courier, monospace; + border-radius: 4px; + padding: 75px 45px 35px; + position: relative; + -webkit-box-sizing: border-box; + box-sizing: border-box; + /* Custom line-height */ + line-height: 1.2; +} + +[data-termynal]:before { + content: ""; + position: absolute; + top: 15px; + left: 15px; + display: inline-block; + width: 15px; + height: 15px; + border-radius: 50%; + /* A little hack to display the window buttons in one pseudo element. */ + background: #d9515d; + -webkit-box-shadow: 25px 0 0 #f4c025, 50px 0 0 #3ec930; + box-shadow: 25px 0 0 #f4c025, 50px 0 0 #3ec930; +} + +[data-termynal]:after { + content: "bash"; + position: absolute; + color: var(--color-text-subtle); + top: 5px; + left: 0; + width: 100%; + text-align: center; +} + +a[data-terminal-control] { + text-align: right; + display: block; + color: #aebbff; +} + +[data-ty] { + display: block; + line-height: 2; +} + +[data-ty]:before { + /* Set up defaults and ensure empty lines are displayed. */ + content: ""; + display: inline-block; + vertical-align: middle; +} + +[data-ty="input"]:before, +[data-ty-prompt]:before { + margin-right: 0.75em; + color: var(--color-text-subtle); +} + +[data-ty="input"]:before { + content: "$"; +} + +[data-ty][data-ty-prompt]:before { + content: attr(data-ty-prompt); +} + +[data-ty-cursor]:after { + content: attr(data-ty-cursor); + font-family: monospace; + margin-left: 0.5em; + -webkit-animation: blink 1s infinite; + animation: blink 1s infinite; +} + +/* Cursor animation */ + +@-webkit-keyframes blink { + 50% { + opacity: 0; + } +} + +@keyframes blink { + 50% { + opacity: 0; + } +} diff --git a/termynal.css b/termynal.css new file mode 100644 index 0000000..75db531 --- /dev/null +++ b/termynal.css @@ -0,0 +1,133 @@ +/** + * termynal.js + * + * @author Ines Montani + * @version 0.0.1 + * @license MIT + */ + + :root { + --color-bg: #252a33; + --color-text: #eee; + --color-text-subtle: #a2a2a2; +} + +[data-termynal] { + max-width: 100%; + overflow-x: auto; + background: var(--color-bg); + color: var(--color-text); + font-size: 15px; + font-family: 'Roboto Mono', 'Fira Mono', Consolas, Menlo, Monaco, 'Courier New', Courier, monospace; + border-radius: 4px; + padding: 75px 45px 35px; + position: relative; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +[data-termynal][data-ty-macos]:before { + content: ''; + position: absolute; + top: 15px; + left: 15px; + display: inline-block; + width: 15px; + height: 15px; + border-radius: 50%; + /* A little hack to display the window buttons in one pseudo element. */ + background: #d9515d; + -webkit-box-shadow: 25px 0 0 #f4c025, 50px 0 0 #3ec930; + box-shadow: 25px 0 0 #f4c025, 50px 0 0 #3ec930; +} + +[data-termynal][data-ty-windows]:before { + content: ''; + position: absolute; + top: 15px; + right: 15px; + display: inline-block; + width: 15px; + height: 15px; + /* A little hack to display the window buttons in one pseudo element. */ + background: #d9515d; + -webkit-box-shadow: -25px 0 0 #e6e6e6, -50px 0 0 #e6e6e6; + box-shadow: -25px 0 0 #e6e6e6, -50px 0 0 #e6e6e6; +} + +[data-termynal]:after { + content: 'bash'; + position: absolute; + color: var(--color-text-subtle); + top: 5px; + left: 0; + width: 100%; + text-align: center; +} + +[data-termynal][data-ty-title]:after { + content: attr(data-ty-title); +} + +a[data-terminal-control] { + text-align: right; + display: block; + color: #aebbff; +} + +[data-ty] { + display: block; + line-height: 2; + white-space: pre; +} + +[data-ty]:before { + /* Set up defaults and ensure empty lines are displayed. */ + content: ''; + display: inline-block; + vertical-align: middle; +} + +[data-ty="input"]:before, +[data-ty-prompt]:before { + margin-right: 0.75em; + color: var(--color-text-subtle); +} + +[data-ty="input"]:before { + content: '$'; +} + +[data-ty][data-ty-prompt]:before { + content: attr(data-ty-prompt); +} + +[data-ty-cursor]:after { + content: attr(data-ty-cursor); + font-family: monospace; + margin-left: 0.5em; + -webkit-animation: blink 1s infinite; + animation: blink 1s infinite; +} + + +/* Cursor animation */ + +@-webkit-keyframes blink { + 50% { + opacity: 0; + } +} + +@keyframes blink { + 50% { + opacity: 0; + } +} + + +.termynal-comment { + color: #4a968f; + font-style: italic; + display: block; +} diff --git a/termynal.js b/termynal.js new file mode 100644 index 0000000..c28512a --- /dev/null +++ b/termynal.js @@ -0,0 +1,275 @@ +/** + * termynal.js + * A lightweight, modern and extensible animated terminal window, using + * async/await. + * + * @author Ines Montani + * @version 0.0.1 + * @license MIT + */ + +'use strict'; + +/** Generate a terminal widget. */ +class Termynal { + /** + * Construct the widget's settings. + * @param {(string|Node)=} container - Query selector or container element. + * @param {Object=} options - Custom settings. + * @param {string} options.prefix - Prefix to use for data attributes. + * @param {number} options.startDelay - Delay before animation, in ms. + * @param {number} options.typeDelay - Delay between each typed character, in ms. + * @param {number} options.lineDelay - Delay between each line, in ms. + * @param {number} options.progressLength - Number of characters displayed as progress bar. + * @param {string} options.progressChar – Character to use for progress bar, defaults to █. + * @param {number} options.progressPercent - Max percent of progress. + * @param {string} options.cursor – Character to use for cursor, defaults to ▋. + * @param {Object[]} lineData - Dynamically loaded line data objects. + * @param {boolean} options.noInit - Don't initialise the animation. + */ + constructor(container = '#termynal', options = {}) { + this.container = (typeof container === 'string') ? document.querySelector(container) : container; + this.pfx = `data-${options.prefix || 'ty'}`; + this.originalStartDelay = this.startDelay = options.startDelay + || parseFloat(this.container.getAttribute(`${this.pfx}-startDelay`)) || 600; + this.originalTypeDelay = this.typeDelay = options.typeDelay + || parseFloat(this.container.getAttribute(`${this.pfx}-typeDelay`)) || 90; + this.originalLineDelay = this.lineDelay = options.lineDelay + || parseFloat(this.container.getAttribute(`${this.pfx}-lineDelay`)) || 1500; + this.progressLength = options.progressLength + || parseFloat(this.container.getAttribute(`${this.pfx}-progressLength`)) || 40; + this.progressChar = options.progressChar + || this.container.getAttribute(`${this.pfx}-progressChar`) || '█'; + this.progressPercent = options.progressPercent + || parseFloat(this.container.getAttribute(`${this.pfx}-progressPercent`)) || 100; + this.cursor = options.cursor + || this.container.getAttribute(`${this.pfx}-cursor`) || '▋'; + this.lineData = this.lineDataToElements(options.lineData || []); + this.loadLines() + if (!options.noInit) this.init() + } + + loadLines() { + // Load all the lines and create the container so that the size is fixed + // Otherwise it would be changing and the user viewport would be constantly + // moving as she/he scrolls + const finish = this.generateFinish() + finish.style.visibility = 'hidden' + this.container.appendChild(finish) + // Appends dynamically loaded lines to existing line elements. + this.lines = [...this.container.querySelectorAll(`[${this.pfx}]`)].concat(this.lineData); + for (let line of this.lines) { + line.style.visibility = 'hidden' + this.container.appendChild(line) + } + const restart = this.generateRestart() + restart.style.visibility = 'hidden' + this.container.appendChild(restart) + this.container.setAttribute('data-termynal', ''); + } + + /** + * Initialise the widget, get lines, clear container and start animation. + */ + init() { + /** + * Calculates width and height of Termynal container. + * If container is empty and lines are dynamically loaded, defaults to browser `auto` or CSS. + */ + const containerStyle = getComputedStyle(this.container); + this.container.style.width = containerStyle.width !== '0px' ? + containerStyle.width : undefined; + this.container.style.minHeight = containerStyle.height !== '0px' ? + containerStyle.height : undefined; + + this.container.setAttribute('data-termynal', ''); + this.container.innerHTML = ''; + for (let line of this.lines) { + line.style.visibility = 'visible' + } + this.start(); + } + + /** + * Start the animation and rener the lines depending on their data attributes. + */ + async start() { + this.addFinish() + await this._wait(this.startDelay); + + for (let line of this.lines) { + const type = line.getAttribute(this.pfx); + const delay = line.getAttribute(`${this.pfx}-delay`) || this.lineDelay; + + if (type == 'input') { + line.setAttribute(`${this.pfx}-cursor`, this.cursor); + await this.type(line); + await this._wait(delay); + } + + else if (type == 'progress') { + await this.progress(line); + await this._wait(delay); + } + + else { + this.container.appendChild(line); + await this._wait(delay); + } + + line.removeAttribute(`${this.pfx}-cursor`); + } + this.addRestart() + this.finishElement.style.visibility = 'hidden' + this.lineDelay = this.originalLineDelay + this.typeDelay = this.originalTypeDelay + this.startDelay = this.originalStartDelay + } + + generateRestart() { + const restart = document.createElement('a') + restart.onclick = (e) => { + e.preventDefault() + this.container.innerHTML = '' + this.init() + } + restart.href = '#' + restart.setAttribute('data-terminal-control', '') + restart.innerHTML = "restart ↻" + return restart + } + + generateFinish() { + const finish = document.createElement('a') + finish.onclick = (e) => { + e.preventDefault() + this.lineDelay = 0 + this.typeDelay = 0 + this.startDelay = 0 + } + finish.href = '#' + finish.setAttribute('data-terminal-control', '') + finish.innerHTML = "fast →" + this.finishElement = finish + return finish + } + + addRestart() { + const restart = this.generateRestart() + this.container.appendChild(restart) + } + + addFinish() { + const finish = this.generateFinish() + this.container.appendChild(finish) + } + + /** + * Animate a typed line. + * @param {Node} line - The line element to render. + */ + async type(line) { + const chars = [...line.textContent]; + line.textContent = ''; + this.container.appendChild(line); + + for (let char of chars) { + const delay = line.getAttribute(`${this.pfx}-typeDelay`) || this.typeDelay; + await this._wait(delay); + line.textContent += char; + } + } + + /** + * Animate a progress bar. + * @param {Node} line - The line element to render. + */ + async progress(line) { + const progressLength = line.getAttribute(`${this.pfx}-progressLength`) + || this.progressLength; + const progressChar = line.getAttribute(`${this.pfx}-progressChar`) + || this.progressChar; + const chars = progressChar.repeat(progressLength); + const progressPercent = line.getAttribute(`${this.pfx}-progressPercent`) + || this.progressPercent; + line.textContent = ''; + this.container.appendChild(line); + + for (let i = 1; i < chars.length + 1; i++) { + await this._wait(this.typeDelay); + const percent = Math.round(i / chars.length * 100); + line.textContent = `${chars.slice(0, i)} ${percent}%`; + if (percent>progressPercent) { + break; + } + } + } + + /** + * Helper function for animation delays, called with `await`. + * @param {number} time - Timeout, in ms. + */ + _wait(time) { + return new Promise(resolve => setTimeout(resolve, time)); + } + + /** + * Converts line data objects into line elements. + * + * @param {Object[]} lineData - Dynamically loaded lines. + * @param {Object} line - Line data object. + * @returns {Element[]} - Array of line elements. + */ + lineDataToElements(lineData) { + return lineData.map(line => { + let div = document.createElement('div'); + div.innerHTML = `${line.value || ''}`; + + return div.firstElementChild; + }); + } + + /** + * Helper function for generating attributes string. + * + * @param {Object} line - Line data object. + * @returns {string} - String of attributes. + */ + _attributes(line) { + let attrs = ''; + for (let prop in line) { + // Custom add class + if (prop === 'class') { + attrs += ` class=${line[prop]} ` + continue + } + if (prop === 'type') { + attrs += `${this.pfx}="${line[prop]}" ` + } else if (prop !== 'value') { + attrs += `${this.pfx}-${prop}="${line[prop]}" ` + } + } + + return attrs; + } +} + +/** +* HTML API: If current script has container(s) specified, initialise Termynal. +*/ +if (document.currentScript.hasAttribute('data-termynal-container')) { + const containers = document.currentScript.getAttribute('data-termynal-container'); + containers.split('|') + .forEach(container => new Termynal(container)) +} + + +(function(){ + document + .querySelectorAll('.termy') + .forEach(node => { + new Termynal(node, { + lineDelay: 500 + }); + }); +})() diff --git a/visao-produto-projeto/processo-desenvolvimento-software/index.html b/visao-produto-projeto/processo-desenvolvimento-software/index.html new file mode 100644 index 0000000..a96be0e --- /dev/null +++ b/visao-produto-projeto/processo-desenvolvimento-software/index.html @@ -0,0 +1,1592 @@ + + + + + + + + + + + + + + + + + + + + + + + + + Processo de desenvolvimento de software - Paraizo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

Processo de Desenvolvimento de Software

+
+Histórico de Revisão + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DataVersãoDescriçãoAutor
08/111.0Criação das seção de Processo de desenvolvimento de softwareErick Miranda Santos
Maykon Júnio dos Santos Soares
Marllon Fausto Cardoso
Pedro Miguel M. de O. dos Santos
10/111.1Especificação do processo de desenvolvimentoErick Miranda Santos
24/111.2Alteração do processo de desenvolvimento (remoção do Dual Track Agile)Erick Miranda Santos
06/121.3Alteração do processo de desenvolvimento (remoção do Kanban)Erick Miranda Santos
+
+
+

Etapas do RAD

+

Etapa 1 - Planejamento dos requisitos

+

Na etapa de planejamento dos requisitos, fazemos uma análise completa do cenário e elicitamos os requisitos, nesse projeto nós seguimos o material do Professor George Marsicano(2023)[4], por isso nós seguimos os pontos, Descoberta e elicitação de requisitos, Análise e consenso de requisitos, Declaração de requisitos, Verificação e Validação e por último a Organização e atualização.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AtividadeMétodoFerramentaEntrega
Descoberta e elicitação de requisitosDiagrama de causa e 5 porquêsTrelloBacklog de requisitos não validado
Análise e consenso de requisitosAnálise de viabilidadeTeamsBacklog de requisitos não validado
DeclaraçãoÉpicos, Features e User StoriesTrelloUser Stories não validado
Verificação e ValidaçãoFeedbackGoogle MeetUser Stories validados
Organização e AtualizaçãoMoSCoW e KanbanTrelloDefinição de prioridades(MVP1 e MVP2)
+
+

Etapa 2 - User Design

+

Na etapa de User Design, é feito a prototipação da aplicação, no caso é feito o protótipo equivalente aos User Stories relacionados ao MVP1 na terceira unidade e ao MVP2 na quarta unidade.

+ + + + + + + + + + + + + + + + + + +
EtapaMétodoFerramentaEntregas
PrototipaçãoMock-up digitalFigmaProtótipo de alta fidelidade
+
+

Etapa 3 - Desenvolvimento

+

Na etapa de desenvolvimento é onde é feito o projeto e seu código é desenvolvido, esta etapa irá ocorrer após a etapa de User Design e Prototipação.

+ +
+

Etapa 4 - Testes

+

Na etapa de testagem será feito os testes de todas as funcionalidades da aplicação

+ + + + + + + + + + + + + + + + + + +
EtapaMétodoFerramentaEntregas
TestagemTestes Unitários, Testes End-to-endJest, Pytest, CypressProduto testado
+
+

Engenharia de Requisitos e o RAD

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Fases do RADAtividades da Engenharia de Requisitos (ER)PráticaTécnicaResultados Esperados
Planejamento dos RequisitosElicitação e DescobertaLevantamento de RequisitosAnálise Documental, Brainstorming, Entrevista, Análise de ConcorrentesIdentificar todos os requisitos de alto nível do projeto
Análise e ConsensoAnálise de dependência entre os requisitos e eliminar ambiguidadesBrainstorming, Entrevista, Análise de Objetivos de DomínioLista de requisitos bem definidos; Definição dos critérios de prioridade dos requisitos
DeclaraçãoApontamento dos requisitos levantadosUser StoryEstabelecimento de todos os requisitos
Organização e AtualizaçãoElencar os requisitos levantados de acordo com os critérios de prioridadeBacklog de Requisitos, Critérios (pontuação, priorização), Lista de Requisitos (RF's e RNF's)Lista de requisitos organizada com o grau de prioridade
Verificação e ValidaçãoVerificar e validar os requisitos levantadosUser Story, DoD e DoR, pontuaçãoBacklog validado com a equipe de desenvolvimento e com o cliente; Definir DoR e DoD
User DesignRepresentaçãoElaboração do design do produtoPrototipagem e MockupFinalização de protótipo de alta fidelidade
Verificação e ValidaçãoVerificar e validar os requisitos atualizados e/ou novos requisitosRevisão, DoD e DoR, testes com usuárioDesign validado com o cliente
ConstruçãoRepresentaçãoDesenvolvimento dos requisitosDiscussões em Equipe, Análise de TarefasRequisito desenvolvido
Verificação e ValidaçãoTeste dos requisitosDoR, testes de sistemaRequisito devidamente testado
Finalização e EntregaVerificação e ValidaçãoTestes de AceitaçãoTestes com usuárioRequisitos devidamente validados com o cliente
Organização e AtualizaçãoFechamento do BacklogRevisão da iteraçãoRetrospectiva do backlog, acertos e erros
+

Engenharia de Requisitos

+

Atividades e Técnicas de ER

+

Elicitação e Descoberta:

+
    +
  • +

    Análise Documental: Será utilizada para levantar questões técnicas necessárias para o projeto, como fichas dos pacientes e relatórios médicos.

    +
  • +
  • +

    Brainstorming: Será realizada uma reunião em grupo para discutir e levantar ideias a respeito do projeto.

    +
  • +
  • +

    Entrevista: Será conduzida junto ao cliente, direcionando para o entendimento do negócio e do problema enfrentado.

    +
  • +
  • +

    Análise de Concorrentes: Será realizada uma pesquisa mercadológica, buscando produtos já existentes que se assemelhem em alguns pontos à solução de software proposta.

    +
  • +
  • +

    Análise e Consenso: O entendimento da equipe será alinhado junto ao cliente.

    +
  • +
  • +

    Análise de Objetivos de Domínio: Será feita para identificar e consolidar os principais objetivos relacionados ao domínio do projeto.

    +
  • +
+

Declaração de Requisitos:

+
    +
  • User Story: Será feita uma construção dos requisitos através dessa técnica, onde será possível destrinchar os requisitos em temas, épicos, histórias e tarefas.
  • +
+

Representação de Requisitos:

+
    +
  • +

    Prototipagem: Será criado um protótipo do sistema, com fluxo de usuário para futura validação do cliente.

    +
  • +
  • +

    Mockup: Será uma representação que simulará o projeto final, permitindo visualizar e testar conceitos de um projeto.

    +
  • +
  • +

    Discussões em Equipe: Serão levantadas discussões para o alinhamento do entendimento dos requisitos trabalhados.

    +
  • +
  • +

    Análise de Tarefas: Será construída uma estratégia que permita dividir uma tarefa mais complexa em tarefas mais simples.

    +
  • +
+

Verificação e Validação de Requisitos:

+
    +
  • +

    User Story: Será validado o User Story construído, para evitar redundância e a possibilidade de um requisito ausente.

    +
  • +
  • +

    DoR: Serão definidos critérios para aprovar que um requisito esteja pronto para ser construído ou entrar no backlog.

    +
  • +
  • +

    DoD: Serão definidos critérios para atestar que o requisito esteja feito por completo, sem nenhuma deficiência técnica e funcional.

    +
  • +
  • +

    Pontuação: Serão definidos pontos com base na complexidade, criticidade, independência e no valor de negócio; essa pontuação será usada para priorização dos requisitos.

    +
  • +
  • +

    Testes de Sistema: Serão realizados testes no sistema para garantir que ele atenda aos critérios de aceitação e esteja com o mínimo de falhas possível.

    +
  • +
  • +

    Testes com Usuário: Serão realizados testes diretamente com o usuário, onde o mesmo poderá navegar pelo sistema para validar a funcionalidade implementada.

    +
  • +
+

Organização e Atualização de Requisitos:

+
    +
  • +

    Backlog de Requisitos: Serão definidos os possíveis requisitos do sistema.

    +
  • +
  • +

    Critérios (Pontuação, Priorização): Serão definidos os critérios de aceitação, assim como seus valores para pontuação e respectiva priorização dos requisitos.

    +
  • +
  • +

    Lista de Requisitos (RF's e RNF's): Serão definidos e filtrados os requisitos, distinguindo-os entre funcionais e não funcionais.

    +
  • +
  • +

    Revisão da Iteração: Será feita uma revisão da iteração, onde serão abordados os acertos, erros e dificuldades enfrentadas, para melhor entendimento entre os membros da equipe.

    +
  • +
+ + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ +
+ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/visao-produto-projeto/visao-produto/index.html b/visao-produto-projeto/visao-produto/index.html new file mode 100644 index 0000000..25a64c7 --- /dev/null +++ b/visao-produto-projeto/visao-produto/index.html @@ -0,0 +1,1995 @@ + + + + + + + + + + + + + + + + + + + + + + + + + Visão do Produto - Paraizo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

Visão Geral do Produto

+
+Histórico de Revisão + + + + + + + + + + + + + + + + + + + + + + + +
DataVersãoDescriçãoAutor
08/111.0Criação das seção de visão geral do produtoErick Miranda Santos
Maykon Júnio dos Santos Soares
Marllon Fausto Cardoso
Pedro Miguel M. de O. dos Santos
Henrique Martins Alencar
10/111.1Especificação do processo de desenvolvimentoErick Miranda Santos e Henrique Martins Alencar
+
+
+

Cenário atual do cliente e do negócio

+

Introdução ao negócio e contexto

+

+O Espaço Janayna Paraizo é uma clínica de fisioterapia no Gama, Distrito Federal, fundada em meados de 2020 pela fisioterapeuta Janayna Paraizo. A clínica oferece serviços como Kinesio Taping, Acupuntura, Dry Needling, Ventosaterapia, RPG, entre outros, com foco no tratamento integrado de todo o corpo para melhorar a qualidade de vida dos pacientes. Operando atualmente de terça a quinta, o Espaço Janayna Paraizo planeja expandir seu atendimento.

+

+No entanto, a clínica enfrenta desafios em divulgar seus serviços, organizar e armazenar os dados dos pacientes (atualmente geridos manualmente em documentos manuscritos ou dispositivos de uma única funcionária) e agendar sessões, o que dificulta o crescimento do atendimento e sobrecarrega a equipe. Esses problemas resultam em baixa eficiência e limitação na capacidade de expansão e promoção do estabelecimento.

+ +

Identificação da Oportunidade ou Problema

+

As oportunidades para a clínica Espaço Janayna Paraizo giram em torno de aumentar sua visibilidade e eficiência operacional. A criação de um website seria essencial para atrair potenciais clientes, permitindo que as pessoas conheçam melhor os serviços oferecidos, o perfil dos profissionais, os diferenciais da clínica e os resultados obtidos com os tratamentos. Isso traria uma presença digital estratégica, facilitando a divulgação da clínica.

+

Além disso, a implantação de uma aplicação web centralizada reduziria significativamente o tempo gasto no registro, busca e visualização das informações dos pacientes. Com isso, todos os funcionários teriam acesso fácil e organizado aos dados dos pacientes, o que descentralizaria as tarefas e aliviaria a carga de trabalho de uma única pessoa.

+

Outra oportunidade importante é a implementação de uma agenda integrada à aplicação web, permitindo o registro de horários livres e ocupados para sessões. Isso daria tanto aos funcionários quanto aos clientes uma visão clara dos horários disponíveis, permitindo que os clientes agendem suas sessões de forma autônoma, sem a necessidade de intervenção direta da equipe, otimizando o fluxo de trabalho e oferecendo mais conveniência aos pacientes.

+ +

Para melhor compreensão do problema identificado, foi elaborado um diagrama de Ishikawa, que apresenta as principais causas e fatores relacionados ao problema.

+ +
+ +
+

Diagrama de Ishikawa - Espaço Janayna Paraizo.

+
+
+

Desafios do Projeto

+

Os principais desafios do projeto incluem o desenvolvimento de uma solução web capaz de registrar todas as informações essenciais sobre os pacientes, como dados técnicos, histórico clínico, hábitos de vida, tratamentos realizados, uso de medicamentos e localizações de dores, além das classificações e tipos de disfunções de movimento tratadas na fisioterapia.

+

Outro desafio importante é a criação de uma interface que não apenas facilite as operações com os dados dos pacientes, mas também torne essas atividades mais rápidas e organizadas em comparação ao registro manual em papel ou em documentos de texto.

+ +

Segmentação de Clientes

+

O Espaço Janayna Paraizo atende três segmentos principais de clientes. O primeiro grupo é composto por idosos entre 65 e 85 anos, que representam a maior parte dos clientes recorrentes da clínica, buscando melhorar sua qualidade de vida e lidar com problemas de saúde relacionados ao envelhecimento e, com isso, necessitam de acompanhamento constante, além de uma documentação detalhada de suas evoluções ao longo das seções, uma vez que rotineiramente precisam apresnetar essas informações em encontros com outros profissionais da saúde. O segundo grupo inclui os acompanhantes desses idosos, geralmente jovens e adultos entre 19 e 50 anos, que são parentes ou amigos próximos responsáveis por agendar, transportar e acompanhar os idosos durante as sessões, atuando como o principal canal de comunicação entre os pacientes idosos e a clínica. O terceiro grupo abrange pacientes de diferentes idades com problemas esporádicos, que procuram atendimento para distúrbios pontuais de curto ou médio prazo, constituindo uma fonte de receita adicional para a clínica, ao contrário dos idosos que requerem acompanhamento contínuo.

+ +
+

Solução proposta

+

Objetivos do Produto

+

O objetivo do produto Paraizo é viabilizar a ampliação da quantidade de clientes da clínica. Para isso, faz-se necessário a redução do tempo demandado na execução de atividades relacionadas à documentação e agendamento de consultas, possibilitando assim a realização dessas atividades com um número maior de clientes, e facilitar a divulgação e marketing do estabelecimento. Para tanto, este produto irá, por meio de uma única plataforma web:

+ +

Aprimorar o cadatro e consulta de dados dos pacientes, como dados técnicos (informações referêntes a seus disturbios e problemas físicos), histórico clínico, hábitos de vida, tratamentos realizados, uso de medicamentos e localizações de dores, substituindo processos manuais e informais, como registros em planilhas e locais temporários, que já não atendem às necessidades da organização por conta do tempo significativo que esse processo exige atualmente e também pela centralização deste trabalho em uma só funcionária.

+ +

Fornecer um local de compartilhamento, acessado por meio de login, que reúna os resultados dos pacientes, facilitando a avaliação dos tratamentos realizados e o acompanhamento dos resultados por parte dos mesmos. Vale ressaltar que para isso o sistema deverá ser uma solução web com a capacidade de ser reproduzida em diferentes tamanhos de tela.

+ +

Ter uma landing page, que divulgará informações da clínica, como serviços, quadro de funcionários, avaliações e resultados, promovendo maior credibilidade a clínica no mercado, ao passo que auxiliará com a prospecção de novos clientes.

+ +

Possibilitar o cadastro e a visualização de agendamentos de consultas, com integração ao Google Agenda, facilitando a gestão dos horários por parte da equipe da clínica.

+ +

Características da solução

+

Segue o conjunto preliminar das características deste produto:

+
    +
  • O sistema deverá ter a Centralização dos dados dos pacientes, como dados técnicos, histórico clínico, hábitos de vida, tratamentos realizados, uso de medicamentos e localizações de dores;
  • +
  • O Sistema deverá ter um local de compartilhamento com login para pacientes, reunindo os resultados de consultas e facilitando a avaliação dos tratamentos realizados;
  • +
  • O sistema deverá ter uma Landing page para divulgação de informações da clínica, como serviços, quadro de funcionários, avaliações e resultados;
  • +
  • O Sistema deverá possuir uma ferramenta de cadastro e visualização de agendamentos de consultas para o cliente e seus pacientes, fazendo com que pacientes possam marcar consultas sem a intervenção direta de funcionários;
  • +
  • Integração com o Google Agenda para a clínica, resultando em uma visualização mais ampla de horários disponíveis; e
  • +
  • O sistema deverá ser implementado em uma plataforma web, podendo ser utilizada em diferentes dispositivos.
  • +
+

Pesquisa de Mercado e Análise Competitiva

+

Existem outras soluções no mercado que visam melhorar a gestão clínica, como, por exemplo:

+
    +
  • Plena Vittae: O sistema de agendamento é realizado apenas através do contato com o profissional via WhatsApp. Não possui sistema de login para visualização das informações dos pacientes;
  • +
  • CETFISIO: Também se limita apenas ao contato e agendamento via WhatsApp, além de não apresentar detalhes sobre o próprio estabelecimento e seus serviços, como, por exemplo, informações sobre o quadro de funcionários, histórico de atendimento da clínica, tipos de serviços prestados e a quem eles são indicados e horários de funcionamento;
  • +
  • Rede D’OR São Luiz: Novamente, este sistema também não oferece formas dos pacientes visualizarem suas próprias informações e o sistema de contato e agendamento apresenta as mesmas características dos anteriores.
  • +
+
+

Vale ressaltar

+

O produto Paraizo se destaca, principalmente, pela forma com que ele diminui a carga de trabalho dos funcionários da clínica, uma vez que o sistema de agendamento e o login para visualização das infomações do paciente descentraliza a responsabilidade dessas atividades, permitindo que, sem a necessidade de contato com algum representante da clínica, uma consulta seja marcada ou que algum documento desejado pelo paciente seja obtido.

+
+

Análise de Viabilidade

+

+A respeito da viabilidade técnica do projeto, a equipe de desenvolvimento é dividida com relação à familiaridade com as tecnologias a serem utilizadas (segue abaixo a tabela com as tecnologias utilizadas), permitindo que aqueles com mais experiência e familiaridade auxiliem os demais quando julgarem necessário. Além disso, apesar de parte da equipe não apresentar muita familiaridade e experiência com as tecnologias usadas, todos possuem conhecimento com o desenvolvimento que envolvem funcionalidades que também serão desenvolvidas neste projeto (como a integração com o google agendas, sistema de autenticação e validação de contas de usuário e banco de dados), tornando o projeto viável tecnicamente. Com reção ao tempo de desenvolvimento, o projeto será realizado durante 6 meses, organizado em itenrações que, ao final, serão entregues partes do projeto, como o protótipo de alta fidelidade, implementação de funcionalidades ou incremento de outras. +

+ +

Tecnologias utilizadas

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TecnologiaDescriçãoÁrea de Aplicação
React.jsBiblioteca JavaScript para construção de interfacesFrontend
Next.jsFramework para React com renderização do lado do servidorFrontend, SSR
Tailwind CSSFramework de CSS para estilização rápida e responsivaFrontend
FlaskFramework minimalista em Python para desenvolvimento webBackend
MongoDBBanco de dados NoSQL orientado a documentosBanco de Dados
FirebasePlataforma para autenticação, armazenamento e deployAutenticação, Hospedagem
Google Calendar APIAPI para integração de agendasIntegração com Google Calendar
GitHubRepositório para versionamento e colaboraçãoControle de Versão
JestFramework de testes para JavaScriptTestes
PyTestFramework de testes para PythonTestes
Microsoft TeamsPlataforma para comunicação e reuniões internasComunicação
Google MeetPlataforma para reuniões com o clienteComunicação
WhatsAppComunicação assíncrona para suporte rápidoComunicação
+

Impacto da Solução

+

+Com a criação do software PARAIZO, espera-se um impacto significativo no que se refere ao tempo destinado nas atividades referentes às documentações e manejamento de dados, além de possibilitar uma melhora no processo de divulgação dos serviços da clínica. Nesse sentido, conclui-se o produto afetaria a clínica das seguintes formas:

+ +
+

Benefícios

+
    +
  • Redução no tempo destinado às atividades de visualização e edição de dados de clientes, uma vez que não será mais necessário procurar manualmente o papel onde está estes registros;
  • +
  • Redução no tempo destinado às atividades relacionadas à organização e procura dos arquivos nos espaços físicos da clínica;
  • +
  • Permitirá que outros funcionários preencham os dados ou confeccionem documentos exigidos, diminuindo a sobrecarga de trabalho que se concentra em uma única funcionária;
  • +
  • Proporcionar a visualização do histórico de evolução dos pacientes poderá acarretar em uma taxa maior de fidelização de clientes ao estabelecimento;
  • +
  • Com o desenvolvimento de um site com as informações sobre os serviços prestados, avaliações de seus clientes e quadro de funcionários, ajudará os responsáveis com o trabalho de divulgação e marketing do estabelecimento.
  • +
+
+
+

Estratégias de Engenharia de Software

+

Estratégia Priorizada

+
    +
  • +

    Abordagem: Ágil

    +
  • +
  • +

    Ciclo de vida: Ágil

    +
  • +
  • +

    Processo: RAD

    +
  • +
+

Quadro Comparativo

+

+O quadro a seguir compara os processos de desenvolvimento RAD e ScrumXP em diversas características, com o objetivo de auxiliar na justificativa para a escolha do processo mais adequado a este projeto. +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CaracterísticasRADScrumXP
Abordagem GeralDesenvolvimento rápido e iterativo focado em protótipos e entregas rápidasDesenvolvimento incremental e iterativo, com ênfase na agilidade e na qualidade do código.
Foco em ArquiteturaMenor foco inicial em arquitetura; ênfase em protótiposAlto; arquitetura emergente é planejada e ajustada para garantir flexibilidade e qualidade.
Estrutura de ProcessosEstrutura flexível, com iterações rápidas e prototipagemBem definida, com sprints baseados em Scrum e práticas de engenharia do XP, como TDD e integração contínua.
Flexibilidade de RequisitosAlta; requisitos podem ser alterados durante o desenvolvimentoModerada; mudanças são bem-vindas, mas priorizadas e organizadas no backlog do produto.
Colaboração com ClientesIntensa; cliente envolvido em feedback frequente e revisão de protótiposMuito alta; cliente é frequentemente envolvido em testes e feedback contínuos.
Complexidade do ProcessoBaixa a moderada; processos adaptáveis e menos formaisModerada a alta; requer domínio técnico devido às práticas avançadas de desenvolvimento.
Qualidade TécnicaFoco em funcionalidade; qualidade técnica pode ser sacrificada pela velocidadeAlta; qualidade é garantida por práticas como TDD, refatoração contínua e código coletivo.
Práticas de DesenvolvimentoPrototipagem rápida, foco em entrega de funcionalidades principaisDesenvolvimento ágil com práticas técnicas rigorosas (TDD, pair programming, etc.).
Adaptação ao ProjetoIdeal para projetos com escopo indefinido ou mudanças constantesAdequado para projetos complexos, que exigem alta qualidade e entregas regulares.
DocumentaçãoDocumentação mínima, foco em protótipos e entregas rápidasMínima, mas suficiente para suportar o desenvolvimento e garantir rastreabilidade.
Controle de QualidadeControle mais básico, com ênfase em entregas rápidas e testes do usuário finalRigoroso; inclui testes automatizados, integração contínua e revisões de código.
EscalabilidadeLimitada, mais indicada para projetos pequenos e médiosAlta, pode ser aplicado a equipes maiores com coordenação eficaz.
Suporte a Equipes de DesenvolvimentoModerado; dependente mais do feedback do cliente e protótipos rápidosAlto, suporte técnico e organizacional robusto por meio de papéis claros e práticas ágeis.
+

Bibliografia

+
+
    +
  1. +

    BECKER, ALICE: Entenda o que é o Rapid Application Delivery (RAD) e sua Relação com os Métodos Ágeis. Disponível em: https://voitto.com.br/blog/artigo/rapid-application-delivery-rad

    +
  2. +
  3. +

    CASA DO DESENVOLVEDOR: XP e Scrum: qual método utilizar para gerir seus projetos de software? Disponível em: https://blog.casadodesenvolvedor.com.br/xp-scrum/

    +
  4. +
+
+

Justificativa

+

GUPTA

+

+Com o intuito de escolher a melhor abordágem de desenvolvimento de software para o desenvolvimento desse projeto, será utilizado o método GUPTA, que estabelece critérios importantes para essa definição. A seguir, serão apresentados as análises feitas pela equipe com relação às Características dos Requisitos, Status da Equipe de Desenvolvimento, Envolvimento do Usuário e Tipo de Projeto e Risco Associado. +

+ +
+

Vale ressaltar

+

As perguntas com respostas marcadas com ✅ referen-se a resposta que a equipe julgou mais adequada para o projeto. Por exemplo, em "Os requisitos são fáceis de entender e definir?", a respostas mais adequada é "Não".

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
RequisitosWaterfallProtótipoIterativoEvolucionárioEspiralRAD
Os requisitos são fáceis de entender e definir?❌ Sim✅ Não✅ Não✅ Não✅ Não❌ Sim
Mudamos os requisitos com bastante frequência?✅ Não❌ Sim✅ Não✅ Não❌ Sim✅ Não
Podemos definir os requisitos no início do ciclo?✅ Sim❌ Não✅ Sim✅ Sim❌ Não✅ Sim
Os requisitos indicam um sistema complexo a ser construído?✅ Não❌ Sim❌ Sim❌ Sim❌ Sim✅ Não
Total313313
+

+A partir das respostas da tabela acima, abstrai-se que os requisitos não são todos bem definidos, mas que ainda podem ser totalmente definidos no início do projeto. Isso decorre, sumariamente, em relação aos requisitos relacionado às informações técnicas que devem estar presentes nas fichas dos pacientes. +

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Equipe de DesenvolvimentoWaterfallProtótipoIterativoEvolucionárioEspiralRAD
Pouca experiência em projetos similares✅ Não❌ Sim✅ Não✅ Não❌ Sim✅ Não
Pouco conhecimento de domínio (novidade na tecnologia)❌ Sim✅ Não❌ Sim❌ Sim❌ Sim✅ Não
Pouca experiência com as ferramentas a serem usadas❌ Sim✅ Não✅ Não✅ Não❌ Sim✅ Não
Disponibilidade de treinamento, se necessário❌ Não❌ Não✅ Sim✅ Sim❌ Não✅ Sim
Total123304
+

+A partir das respostas da tabela acima, abstrai-se que a equipe não tem tanta experiência com projetos semelhantes, mas que ainda apresenta conhecimento com as tecnologias e ferramentas usadas. Vale ressaltar que, como descrito em "Análise de Viabilidade", parte da equipe não é tão habilidosa, entretanto estão dispostos a participar de treinamentos caso necessário. +

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Envolvimento dos usuáriosWaterfallProtótipoIterativoEvolucionárioEspiralRAD
Envolvimento dos usuários em todas as fases❌ Não✅ Sim❌ Não❌ Não❌ Não✅ Sim
Participação limitada do usuário❌ Sim✅ Não❌ Sim❌ Sim❌ Sim✅ Não
Usuário sem experiência anterior de participação em projetos similares✅ Não❌ Sim❌ Sim❌ Sim❌ Sim✅ Não
Usuários são especialistas no domínio do problema❌ Não✅ Sim✅ Não❌ Não❌ Não✅ Sim
Total131004
+

+A partir das respostas da tabela acima, abstrai-se que o projeto terá muito envolvimento dos usuários, sumariamente a própria cliente, além de ser especialista no assunto, podendo auxiliar a equipe quando necessário. +

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Tipo de Projeto e RiscoWaterfallProtótipoIterativoEvolucionárioEspiralRAD
O projeto é uma melhoria de um sistema existente✅ Não✅ Não❌ Sim❌ Sim✅ Não❌ Sim
O financiamento é estável para o projeto✅ Sim✅ Sim❌ Não❌ Não❌ Não✅ Sim
Altos requisitos de confiabilidade❌ Não❌ Não✅ Sim✅ Sim✅ Sim❌ Não
Cronograma apertado do projeto❌ Não✅ Sim✅ Sim✅ Sim✅ Sim✅ Sim
Uso de componentes reutilizáveis❌ Não✅ Sim❌ Não❌ Não✅ Sim✅ Sim
Os recursos (tempo, dinheiro, pessoas, etc.) são escassos?❌ Não✅ Sim❌ Não❌ Não✅ Sim❌ Não
Total252253
+

+A partir das respostas da tabela acima, abstrai-se que o projeto tem cronograma curto, além da ausência de financiamento. Porém, os requisitos não são de alta confiabilidade e não é uma melhoria de um sistema existente. +

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ConclusãoWaterfallProtótipoIterativoEvolucionárioEspiralRAD
Requisitos313313
Equipe de Desenvolvimento123304
Envolvimento dos usuários131004
Tipo de Projeto e Risco252253
Total❌ 7❌ 11❌ 9❌ 8❌ 6✅ 14
+

+Por fim, a tabela acima busca evidenciar quais processos mais se alinham com o projeto em pauta, através de uma soma das respostas em cada um dos 4 segmentos. +

+ +
+

+Baseado na análise comparativa entre os processos RAD e Scrum, junto com a análise através do método GUPTA, o processo escolhido foi o RAD, pois ele prioriza rapidez e flexibilidade, características essenciais em caso de mudança de requisitos, que pode ser um tópico abordado com a cliente em reuniões futuras. O RAD permite prototipagem rápida e interação contínua com a cliente, garantindo que os feedbacks sejam incorporados de forma ágil ao longo do desenvolvimento. Com uma estrutura mais leve e menos formal do que outros métodos, o RAD será ideal para o projeto, já que ele tem uma menor complexidade, onde a ênfase está em obter resultados práticos e adaptáveis em um curto espaço de tempo. +

+ +
+

alt text

+
+

Representação gráfica ciclo de vida RAD.

+
+
+
+

Características

+
    +
  • É considera uma abordagem ágil, centrada no usuário e design do produto
  • +
  • Fortemente baseado no feedback do usuário
  • +
  • Os requisitos do produto são tratados como variáveis
  • +
+
+ + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ +
+ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/visao-produto-projeto/visao-projeto/index.html b/visao-produto-projeto/visao-projeto/index.html new file mode 100644 index 0000000..142d75e --- /dev/null +++ b/visao-produto-projeto/visao-projeto/index.html @@ -0,0 +1,1460 @@ + + + + + + + + + + + + + + + + + + + + + + + + + Visão do Projeto - Paraizo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + +
+ + + + + + + +
+ +
+ + + + +
+
+ + + +
+
+
+ + + + + + + + + +
+
+
+ + + + +
+
+ + + + + + + +

Visão do Projeto

+
+Histórico de Revisão + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DataVersãoDescriçãoAutor
08/111.0Criação das seção de visão geral do projetoErick Miranda Santos
Maykon Júnio dos Santos Soares
Marllon Fausto Cardoso
Pedro Miguel M. de O. dos Santos
24/111.1O planejamento do quadro e das iterações está sendo ajustado para promover maior clareza e eficiência no fluxo de trabalho.Erick Miranda Santos
15/121.1Revisão de cronograma de entregas.Maykon Júnio dos Santos Soares
+
+
+

Interação entre equipe e cliente

+

Composição da Equipe

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PapelDescriçãoResponsávelParticipantes
Gerente do ProjetoCoordena o projeto, garante a comunicação entre cliente e equipe, controla prazos e entregas.Maykon Júnio dos Santos SoaresMarllon Fausto
Desenvolvedor FrontendResponsável pela interface do usuário, design e implementação das funcionalidades no lado do cliente.Marllon FaustoHenrique Martins, Pedro Miguel
Desenvolvedor BackendImplementa a lógica de negócios, integração com banco de dados e APIs.Erick MirandaMaykon Júnio dos Santos Soares, Marllon Fausto
Analista de QAGarante a qualidade do produto, executando testes de funcionalidade, performance e usabilidade.Pedro Miguel MartinsErick Miranda
Analista de RequisitosDefine os requisitos funcionais e não funcionais do sistema e garante que eles sejam atendidos.Henrique MartinsPedro Miguel, Maykon Júnio dos Santos Soares, Marllon Fausto, Erick Miranda
+
+

Matriz de Comunicação

+ + + + + + + + + + + + + + + + + + + + + + + + + +
FerramentaObjetivoFrequência
Microsoft TeamsReuniões semanais entre a equipe de desenvolvimento para planejamento, alinhamentos e feedbacks.Semanal
Google MeetReuniões entre a equipe de desenvolvimento e o cliente para relatar andamento, validar entregas e tirar dúvidas.Conforme necessário (reuniões com o cliente)
WhatsAppComunicação assíncrona entre equipe e cliente para sanar dúvidas ou realizar comunicações rápidas.Conforme necessário (interações informais)
+
+

Métodos e Frequência de Reuniões

+ + + + + + + + + + + + + + + +
ReuniãoObjetivoFrequência
Reunião de planejamento e revisão de IteraçãoPlanejamento e revisão do progresso das Iterações, alinhamento da equipe.Semanal
+
+

Frequência de Interações com o Cliente

+ + + + + + + + + + + + + + + + + + + + +
InteraçãoObjetivoFrequência
Revisões de IteraçãoCliente valida entregas e fornece feedback.A cada 2 semanas
Interações esporádicas via WhatsAppComunicação rápida para dúvidas ou ajustes imediatos.Conforme necessário
+
+

Planejamento das Fases e/ou Iterações do Projeto

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
IteraçãoFase RADProcesso de EngenhariaProduto (Entrega)Data InícioData FimDias
0Planejamento dos RequisitosDefinição do produto
Definição do Problema
Levantamento inicial e análise de requisitos
Documento de visão inicial do produto22/10/202404/11/202414
1Planejamento dos RequisitosLevantamento inicial e análise de requisitosLevantamento de backlog incial05/11/202418/11/202414
2Planejamento dos RequisitosLevantamento inicial e análise de requisitos
Priorização incial de requisitos
Levantamento de backlog incial19/11/202402/12/202414
3Planejamento dos RequisitosRefinamento e priorização de backlog
Definição de DoR e DoD
Definição de critérios de aceitação
Backlog detalhado para MVP1 e MVP203/12/202416/12/202414
4User DesignPrototipação detalhada de [US01], [US04], [US05], [US08], [US06], [US13], [US02], [US07], [US16], [US17], [US18], [US19], [US20], [US24], [US09], [US10], [US11] e [US14]
Feedback de usuários
Ajustes com base no feedback
Protótipos para entregas parciais17/12/202430/12/202414
Pausa-Recesso de Fim de Ano-31/12/202407/01/20258
5Desenvolvimento e TestesDesenvolvimento iterativo e testes para [US01], [US04], [US05], [US08] e [US06]Entrega parcial 1 - MVP08/01/202521/01/202514
6Desenvolvimento e TestesDesenvolvimento iterativo e testes para [US13], [US02], [US07], [US16], [US17], [US18], [US19], [US20] e [US24]Entrega parcial 2 - MVP22/01/202504/02/202514
7Desenvolvimento e TestesDesenvolvimento iterativo e testes para [US09], [US10], [US11] e [US14]Entrega parcial 3 - MVP05/02/202518/02/202514
+ + + + + + + + + + + + + + +
+
+ + + + + +
+ + + +
+ + + +
+
+
+
+ +
+ + + + + + + + + + + + + + + + + + \ No newline at end of file