diff --git a/adminapi/schema/lg/persons_fr.json b/adminapi/schema/lg/persons_fr.json deleted file mode 100644 index 51913c1..0000000 --- a/adminapi/schema/lg/persons_fr.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "title": "Une Personne au niveau d'une tribut avec des informations personnelle", - "description": "Un alias peut se stoquer comme un objet Person avec des informations supplémentaire permettant de qualifier son profil", - "properties": { - "alias": { "title": "Une identité numérique d'apxtrib" }, - "dt_create": { "title": "Date de creation de cette personne" }, - "dt_update": { "title": "Date de derniére mise à jour" }, - "dt_lastlogin": { "title": "Date de derniere authentification" }, - "dt_close": { "title": "Date de fermeture de compte" }, - "recoveryauth": { - "title": "Information pour recuperer ses codes d'accès", - "properties": { - "email": { "title": "email de recuperation" }, - "alias": { - "title": "Alias qui doit exister comme une Person dans une tribu" - }, - "privatekey": { "title": "Private key link to alias" }, - "passphrase": { "title": "Passphrase to uncipher privatekey" } - } - }, - "biography": { "title": "Description courte" }, - "imgavatar": { "title": "Url de l'image utilisée comme avatar" }, - "accessrights": { "title": "Droits d'accès" } - } -} diff --git a/adminapi/schema/pagans.json b/adminapi/schema/pagans.json index 6424d3f..3fdf20c 100644 --- a/adminapi/schema/pagans.json +++ b/adminapi/schema/pagans.json @@ -15,7 +15,7 @@ "title": "Alias", "description": "text to remember easily a public key", "type": "string", - "minLength": 4, + "minLength": 3, "pattern": "^[a-z0-9]*$" }, "dt_delete": { @@ -34,8 +34,8 @@ "apxid": "alias", "apxuniquekey": ["publickey"], "apxidx": [ - { "name": "lst_alias", "keyval": "alias" }, - { "name": "alias", "keyval": "alias" } + { "name": "lst_alias", "type":"array", "keyval": "alias" }, + { "name": "alias", "type":"view", "keyval": "alias","objkey":[],"filter":"" } ], "apxaccessrights": { "owner": { "R": [], "D": [] }, diff --git a/adminapi/schema/persons.json b/adminapi/schema/persons.json deleted file mode 100755 index d3d2067..0000000 --- a/adminapi/schema/persons.json +++ /dev/null @@ -1,194 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "/schema/person", - "title": "Person minimum definition to link a person to a pagan identity", - "description": "A person is a human with a apxtrib identity (alias = Public Private Key) that accept to be part of a tribe (a person is store inside a tribe). Information stored for a person are only visible from the town's Mayor and the tribe's Druid. You need at least trust the druid that trust the mayor (for sensitive data Mayor and Druid can be the same apx Identity.) Only a pagan that have the privateKey can read cipher data. The purpose of this schema is to link a person to a tribe and manage basic activities, profil for specific purpose will be a tribe object that can be add additionalProperties of this is set at true.", - "type": "object", - "properties": { - "alias": { - "title": "alias", - "description": "A unique string identifying a unique public key", - "type": "string", - "minLength": 5, - "pattern": "^[a-z0-9]*$" - }, - "owner": { - "title": "Owner of this person", - "description": "For accessright purpose this is always equal as alias", - "type": "string", - "format": "Alias" - }, - "dt_create": { - "type": "string", - "format": "date-time", - "default": "dayjs.now()" - }, - "dt_update": { - "type": "string", - "format": "date-time" - }, - "dt_lastlogin": { - "title": "Last time login", - "description": "Last time this person authentify as alias access to this tribe", - "type": "string", - "format": "date-time" - }, - "dt_delete": { - "title": "Date of leaving tribe", - "description": "Date from when this alias is ban of tribe by druid or want to leave. A pocess of data cleaning has to be run depending of Tribe's rules.", - "type": "string", - "format": "date" - }, - "will": { - "title": "Will script after leaving tribe", - "description": "This will script will be apply on your data 30 days after your delete", - "type": "string", - "format": "js" - }, - "recoveryauth": { - "title": "Store numeric identity to recover it by email", - "description": "This object store numeric identity alias with an email mainly used at Person level to recover by email a private and passphrase key associate to alias", - "type": "object", - "properties": { - "email": { - "type": "string", - "format": "email" - }, - "privatekey": { - "type": "string", - "format": "pgpprivatekey" - }, - "publickey": { - "type": "string", - "format": "pgppublickey" - }, - "passphrase": { - "type": "string" - } - } - }, - "firstname": { - "title": "A firstname", - "description": "This will be use to present yourself", - "type": "string" - }, - "lastname": { - "title": "A lastname", - "description": "This will be use to present yourself", - "type": "string" - }, - "dt_birth": { - "title": "Your birthdate", - "description": "Date of birth you want to communicate", - "type": "string", - "format": "date" - }, - "pronom": { - "title": "Your pronom", - "description": "The way you want people communicate with you", - "type": "string", - "enum": ["0", "1", "2"] - }, - "emailcom": { - "title": "email use to communicate with you", - "description": "email used by tribe to communicate with you, depending of your profil you can also define other mail to interact with other person", - "type": "string", - "format": "email" - }, - "hobbies": { - "title": "My hobbies", - "type": "array", - "comment": "from a tree word combinaison /lg/hobbies_xx.json" - }, - "biography": { - "title": "Your bio or few words to define yourself", - "description": "Use this to share your values, this will be public to all of tribe's members and link to your person", - "type": "string", - "pattern": "^.{O,150}$" - }, - "mbti": { - "type": "object" - }, - "imgavatar": { - "title": "A picture of your person or personnality", - "description": "This picture will be public to all tribe's member", - "type": "url" - }, - "profils": { - "title": "Array of profil", - "description": "List of profil to get accessright on object", - "type": "array" - } - }, - "required": ["alias", "profilaccess"], - "additionalProperties": true, - "apxid": "alias", - "apxuniquekey": ["alias"], - "apxidx": [ - { - "name": "lst_alias", - "keyval": "alias" - }, - { - "name": "alias", - "keyval": "alias" - }, - { - "name": "profils_alias", - "keyval": "profils", - "objkey": "alias" - }, - { - "name": "emailcom_alias", - "keyval": "emailcom", - "objkey": "alias" - }, - { - "name": "hobbies_alias", - "keyval": "hobbies", - "objkey": "alias" - } - ], - "apxaccessrights": { - "owner": { - "D": [], - "R": [ - "alias", - "dt_create", - "dt_update", - "last_login", - "firstname", - "lastname", - "dt_birth", - "pronom", - "emailcom", - "hobies", - "biography", - "imgavatar", - "profilaccess" - ], - "U": [ - "firstname", - "lastname", - "dt_birth", - "pronom", - "emailcom", - "hobies", - "biography", - "imgavatar", - "profilaccess" - ] - }, - "pagan": { - "C": [] - }, - "mayor": { - "D": [], - "R": ["alias"] - }, - "druid": { - "D": [], - "R": ["alias"] - } - } -} diff --git a/adminapi/template/createidentity_fr.js b/adminapi/template/createidentity_fr.js new file mode 100644 index 0000000..b29fd42 --- /dev/null +++ b/adminapi/template/createidentity_fr.js @@ -0,0 +1,100 @@ +// See https://nodemailer.com/message/ for available fields to add +// email template to get key registration +const tplemail={}; +tplemail.sender = "smatchtit" +tplemail.replyTo="{{{name}}}<{{{email}}}>" +tplemail.inreplyTo="" +tplemail.references="" +//tplemail.from = "noreply@smatchit.io" get by default in configtrib.emailcontact or server ;emailcontact +tplemail.to="<{{emailcontact}}>" +tplemail.subject="Vos clés d'identification pour {{alias}}" +tplemail.cc="" +tplemail.bcc="" +tplemail.attachments=[] +/*example + attachments: [ + { + filename: "{{data}}.txt", + pathfile: "{{data}}", + contenttype: "text/plain", + minepart: "mixed", + }, + { + filename: "my-image.jpg", + content: "blabla content", + contenttype: "image/jpeg", + minepart: "alternative", + }, + ], + if content and filepath is present filepath content replace content + */ +tplemail.html=` + + + + + + + + + + + + + +
+

+ smatchit +

+
+
+

Votre identité numérique: {{alias}}

+

Vous avez souhaité recevoir vos clés d'identification via {{tribe}}. Une identité numerique est composée de 2 fichiers texte appelés clé privée et clé public.

+

+ Son usage est simple mais souvent méconnu, avec une fonction mathematique, la clé privée permet de signer un message. Avec une autre fonction, on vérifie que la signature est bien issue de la cle public sans avoir besoin de disposer de la clé privée. +

+

Les applications de {{tribe}} fonctionnent toutes de cette façon et permettent non seulement de vous identifier mais aussi de chiffrer vos données lisible uniquement grâce à votre clé privée. Pour simplifier l'usage de ces clés nous associons un alias à votre clé public.

+ {{#avecpassphrase}} +

+ Pour plus de securité, on peut vous demander une passphrase qui dans votre cas est :{{passphrase}} +

+ {{/avecpassphrase}} +

Gardez précieusement ces clés et ne communiquez jamais votre clé privée. Uniquement votre alias (et eventuellement votre clé public).

+ +
+ + + + +
+

+ smatchit +

+
+ + + + +
+

+ Nos conditions d'utilisation et politique de protection des données CGU +

+
+ + +` +tplemail.text=` +Vos clés d'authentifications: +alias: {{alias}} +passphrase: {{passphrase}} +publickey: copier coller entre les 2 lignes ------- +--------------------- +{{publickey}} +--------------------- +privatekye: copier coller entre les 2 lignes ------- +--------------------- +{{privatekey}} +--------------------- +` +module.exports=tplemail; \ No newline at end of file diff --git a/adminapi/www/adminapx/conf/nginxmodelwebsite.conf.mustache b/adminapi/www/adminapx/conf/nginxmodelwebsite.conf.mustache index b5d217e..0481808 100755 --- a/adminapi/www/adminapx/conf/nginxmodelwebsite.conf.mustache +++ b/adminapi/www/adminapx/conf/nginxmodelwebsite.conf.mustache @@ -30,6 +30,16 @@ location ~* /nationchains/schema/ { rewrite /nationchains/schema/(.*$) /$1 break; root {{{dirapi}}}/adminapi/schema/; } +location ~* /{{tribeId}}/schema/{ + rewrite /{{tribeId}}/schema/(.*$) /$1 break; + root {{dirtown}}/tribes/{{tribeId}}/schema/; +} + +location ~* /{{tribeId}}/models/{ + rewrite /{{tribeId}}/models/(.*$) /$1 break; + root {{dirtown}}/tribes/{{tribeId}}/api/models/lg/; +} + # /plugins/pluginame/components/xxx?plugin=pluginname&pluginkey=key # acess if exist pluginkey location /plugins/ { diff --git a/adminapi/www/cdn/apidoc/assets/main.bundle.js b/adminapi/www/cdn/apidoc/assets/main.bundle.js index ab349e4..090f726 100644 --- a/adminapi/www/cdn/apidoc/assets/main.bundle.js +++ b/adminapi/www/cdn/apidoc/assets/main.bundle.js @@ -1,8 +1,8 @@ -(()=>{var Ja={8325:(w,E,o)=>{const d=Symbol("SemVer ANY");class r{static get ANY(){return d}constructor(v,h){if(h=n(h),v instanceof r){if(v.loose===!!h.loose)return v;v=v.value}s("comparator",v,h),this.options=h,this.loose=!!h.loose,this.parse(v),this.semver===d?this.value="":this.value=this.operator+this.semver.version,s("comp",this)}parse(v){const h=this.options.loose?u[c.COMPARATORLOOSE]:u[c.COMPARATOR],p=v.match(h);if(!p)throw new TypeError(`Invalid comparator: ${v}`);this.operator=p[1]!==void 0?p[1]:"",this.operator==="="&&(this.operator=""),p[2]?this.semver=new f(p[2],this.options.loose):this.semver=d}toString(){return this.value}test(v){if(s("Comparator.test",v,this.options.loose),this.semver===d||v===d)return!0;if(typeof v=="string")try{v=new f(v,this.options)}catch(h){return!1}return l(v,this.operator,this.semver,this.options)}intersects(v,h){if(!(v instanceof r))throw new TypeError("a Comparator is required");if((!h||typeof h!="object")&&(h={loose:!!h,includePrerelease:!1}),this.operator==="")return this.value===""?!0:new g(v.value,h).test(this.value);if(v.operator==="")return v.value===""?!0:new g(this.value,h).test(v.semver);const p=(this.operator===">="||this.operator===">")&&(v.operator===">="||v.operator===">"),A=(this.operator==="<="||this.operator==="<")&&(v.operator==="<="||v.operator==="<"),m=this.semver.version===v.semver.version,y=(this.operator===">="||this.operator==="<=")&&(v.operator===">="||v.operator==="<="),T=l(this.semver,"<",v.semver,h)&&(this.operator===">="||this.operator===">")&&(v.operator==="<="||v.operator==="<"),x=l(this.semver,">",v.semver,h)&&(this.operator==="<="||this.operator==="<")&&(v.operator===">="||v.operator===">");return p||A||m&&y||T||x}}w.exports=r;const n=o(349),{re:u,t:c}=o(3259),l=o(5609),s=o(4903),f=o(1630),g=o(1459)},1459:(w,E,o)=>{class d{constructor(H,W){if(W=u(W),H instanceof d)return H.loose===!!W.loose&&H.includePrerelease===!!W.includePrerelease?H:new d(H.raw,W);if(H instanceof c)return this.raw=H.value,this.set=[[H]],this.format(),this;if(this.options=W,this.loose=!!W.loose,this.includePrerelease=!!W.includePrerelease,this.raw=H,this.set=H.split("||").map(z=>this.parseRange(z.trim())).filter(z=>z.length),!this.set.length)throw new TypeError(`Invalid SemVer Range: ${H}`);if(this.set.length>1){const z=this.set[0];if(this.set=this.set.filter($=>!p($[0])),this.set.length===0)this.set=[z];else if(this.set.length>1){for(const $ of this.set)if($.length===1&&A($[0])){this.set=[$];break}}}this.format()}format(){return this.range=this.set.map(H=>H.join(" ").trim()).join("||").trim(),this.range}toString(){return this.range}parseRange(H){H=H.trim();const z=`parseRange:${Object.keys(this.options).join(",")}:${H}`,$=n.get(z);if($)return $;const V=this.options.loose,Y=V?f[g.HYPHENRANGELOOSE]:f[g.HYPHENRANGE];H=H.replace(Y,L(this.options.includePrerelease)),l("hyphen replace",H),H=H.replace(f[g.COMPARATORTRIM],i),l("comparator trim",H),H=H.replace(f[g.TILDETRIM],v),H=H.replace(f[g.CARETTRIM],h),H=H.split(/\s+/).join(" ");let nt=H.split(" ").map(dt=>y(dt,this.options)).join(" ").split(/\s+/).map(dt=>P(dt,this.options));V&&(nt=nt.filter(dt=>(l("loose invalid filter",dt,this.options),!!dt.match(f[g.COMPARATORLOOSE])))),l("range list",nt);const it=new Map,ut=nt.map(dt=>new c(dt,this.options));for(const dt of ut){if(p(dt))return[dt];it.set(dt.value,dt)}it.size>1&&it.has("")&&it.delete("");const et=[...it.values()];return n.set(z,et),et}intersects(H,W){if(!(H instanceof d))throw new TypeError("a Range is required");return this.set.some(z=>m(z,W)&&H.set.some($=>m($,W)&&z.every(V=>$.every(Y=>V.intersects(Y,W)))))}test(H){if(!H)return!1;if(typeof H=="string")try{H=new s(H,this.options)}catch(W){return!1}for(let W=0;WF.value==="<0.0.0-0",A=F=>F.value==="",m=(F,H)=>{let W=!0;const z=F.slice();let $=z.pop();for(;W&&z.length;)W=z.every(V=>$.intersects(V,H)),$=z.pop();return W},y=(F,H)=>(l("comp",F,H),F=D(F,H),l("caret",F),F=x(F,H),l("tildes",F),F=R(F,H),l("xrange",F),F=b(F,H),l("stars",F),F),T=F=>!F||F.toLowerCase()==="x"||F==="*",x=(F,H)=>F.trim().split(/\s+/).map(W=>C(W,H)).join(" "),C=(F,H)=>{const W=H.loose?f[g.TILDELOOSE]:f[g.TILDE];return F.replace(W,(z,$,V,Y,nt)=>{l("tilde",F,z,$,V,Y,nt);let it;return T($)?it="":T(V)?it=`>=${$}.0.0 <${+$+1}.0.0-0`:T(Y)?it=`>=${$}.${V}.0 <${$}.${+V+1}.0-0`:nt?(l("replaceTilde pr",nt),it=`>=${$}.${V}.${Y}-${nt} <${$}.${+V+1}.0-0`):it=`>=${$}.${V}.${Y} <${$}.${+V+1}.0-0`,l("tilde return",it),it})},D=(F,H)=>F.trim().split(/\s+/).map(W=>_(W,H)).join(" "),_=(F,H)=>{l("caret",F,H);const W=H.loose?f[g.CARETLOOSE]:f[g.CARET],z=H.includePrerelease?"-0":"";return F.replace(W,($,V,Y,nt,it)=>{l("caret",F,$,V,Y,nt,it);let ut;return T(V)?ut="":T(Y)?ut=`>=${V}.0.0${z} <${+V+1}.0.0-0`:T(nt)?V==="0"?ut=`>=${V}.${Y}.0${z} <${V}.${+Y+1}.0-0`:ut=`>=${V}.${Y}.0${z} <${+V+1}.0.0-0`:it?(l("replaceCaret pr",it),V==="0"?Y==="0"?ut=`>=${V}.${Y}.${nt}-${it} <${V}.${Y}.${+nt+1}-0`:ut=`>=${V}.${Y}.${nt}-${it} <${V}.${+Y+1}.0-0`:ut=`>=${V}.${Y}.${nt}-${it} <${+V+1}.0.0-0`):(l("no pr"),V==="0"?Y==="0"?ut=`>=${V}.${Y}.${nt}${z} <${V}.${Y}.${+nt+1}-0`:ut=`>=${V}.${Y}.${nt}${z} <${V}.${+Y+1}.0-0`:ut=`>=${V}.${Y}.${nt} <${+V+1}.0.0-0`),l("caret return",ut),ut})},R=(F,H)=>(l("replaceXRanges",F,H),F.split(/\s+/).map(W=>N(W,H)).join(" ")),N=(F,H)=>{F=F.trim();const W=H.loose?f[g.XRANGELOOSE]:f[g.XRANGE];return F.replace(W,(z,$,V,Y,nt,it)=>{l("xRange",F,z,$,V,Y,nt,it);const ut=T(V),et=ut||T(Y),dt=et||T(nt),yt=dt;return $==="="&&yt&&($=""),it=H.includePrerelease?"-0":"",ut?$===">"||$==="<"?z="<0.0.0-0":z="*":$&&yt?(et&&(Y=0),nt=0,$===">"?($=">=",et?(V=+V+1,Y=0,nt=0):(Y=+Y+1,nt=0)):$==="<="&&($="<",et?V=+V+1:Y=+Y+1),$==="<"&&(it="-0"),z=`${$+V}.${Y}.${nt}${it}`):et?z=`>=${V}.0.0${it} <${+V+1}.0.0-0`:dt&&(z=`>=${V}.${Y}.0${it} <${V}.${+Y+1}.0-0`),l("xRange return",z),z})},b=(F,H)=>(l("replaceStars",F,H),F.trim().replace(f[g.STAR],"")),P=(F,H)=>(l("replaceGTE0",F,H),F.trim().replace(f[H.includePrerelease?g.GTE0PRE:g.GTE0],"")),L=F=>(H,W,z,$,V,Y,nt,it,ut,et,dt,yt,Ot)=>(T(z)?W="":T($)?W=`>=${z}.0.0${F?"-0":""}`:T(V)?W=`>=${z}.${$}.0${F?"-0":""}`:Y?W=`>=${W}`:W=`>=${W}${F?"-0":""}`,T(ut)?it="":T(et)?it=`<${+ut+1}.0.0-0`:T(dt)?it=`<${ut}.${+et+1}.0-0`:yt?it=`<=${ut}.${et}.${dt}-${yt}`:F?it=`<${ut}.${et}.${+dt+1}-0`:it=`<=${it}`,`${W} ${it}`.trim()),k=(F,H,W)=>{for(let z=0;z0){const $=F[z].semver;if($.major===H.major&&$.minor===H.minor&&$.patch===H.patch)return!0}return!1}return!0}},1630:(w,E,o)=>{const d=o(4903),{MAX_LENGTH:r,MAX_SAFE_INTEGER:n}=o(3325),{re:u,t:c}=o(3259),l=o(349),{compareIdentifiers:s}=o(7342);class f{constructor(i,v){if(v=l(v),i instanceof f){if(i.loose===!!v.loose&&i.includePrerelease===!!v.includePrerelease)return i;i=i.version}else if(typeof i!="string")throw new TypeError(`Invalid Version: ${i}`);if(i.length>r)throw new TypeError(`version is longer than ${r} characters`);d("SemVer",i,v),this.options=v,this.loose=!!v.loose,this.includePrerelease=!!v.includePrerelease;const h=i.trim().match(v.loose?u[c.LOOSE]:u[c.FULL]);if(!h)throw new TypeError(`Invalid Version: ${i}`);if(this.raw=i,this.major=+h[1],this.minor=+h[2],this.patch=+h[3],this.major>n||this.major<0)throw new TypeError("Invalid major version");if(this.minor>n||this.minor<0)throw new TypeError("Invalid minor version");if(this.patch>n||this.patch<0)throw new TypeError("Invalid patch version");h[4]?this.prerelease=h[4].split(".").map(p=>{if(/^[0-9]+$/.test(p)){const A=+p;if(A>=0&&A=0;)typeof this.prerelease[h]=="number"&&(this.prerelease[h]++,h=-2);h===-1&&this.prerelease.push(0)}v&&(s(this.prerelease[0],v)===0?isNaN(this.prerelease[1])&&(this.prerelease=[v,0]):this.prerelease=[v,0]);break;default:throw new Error(`invalid increment argument: ${i}`)}return this.format(),this.raw=this.version,this}}w.exports=f},7200:(w,E,o)=>{const d=o(8216),r=(n,u)=>{const c=d(n.trim().replace(/^[=v]+/,""),u);return c?c.version:null};w.exports=r},5609:(w,E,o)=>{const d=o(4594),r=o(3228),n=o(145),u=o(9778),c=o(5429),l=o(7888),s=(f,g,i,v)=>{switch(g){case"===":return typeof f=="object"&&(f=f.version),typeof i=="object"&&(i=i.version),f===i;case"!==":return typeof f=="object"&&(f=f.version),typeof i=="object"&&(i=i.version),f!==i;case"":case"=":case"==":return d(f,i,v);case"!=":return r(f,i,v);case">":return n(f,i,v);case">=":return u(f,i,v);case"<":return c(f,i,v);case"<=":return l(f,i,v);default:throw new TypeError(`Invalid operator: ${g}`)}};w.exports=s},9485:(w,E,o)=>{const d=o(1630),r=o(8216),{re:n,t:u}=o(3259),c=(l,s)=>{if(l instanceof d)return l;if(typeof l=="number"&&(l=String(l)),typeof l!="string")return null;s=s||{};let f=null;if(!s.rtl)f=l.match(n[u.COERCE]);else{let g;for(;(g=n[u.COERCERTL].exec(l))&&(!f||f.index+f[0].length!==l.length);)(!f||g.index+g[0].length!==f.index+f[0].length)&&(f=g),n[u.COERCERTL].lastIndex=g.index+g[1].length+g[2].length;n[u.COERCERTL].lastIndex=-1}return f===null?null:r(`${f[2]}.${f[3]||"0"}.${f[4]||"0"}`,s)};w.exports=c},7548:(w,E,o)=>{const d=o(1630),r=(n,u,c)=>{const l=new d(n,c),s=new d(u,c);return l.compare(s)||l.compareBuild(s)};w.exports=r},7317:(w,E,o)=>{const d=o(9123),r=(n,u)=>d(n,u,!0);w.exports=r},9123:(w,E,o)=>{const d=o(1630),r=(n,u,c)=>new d(n,c).compare(new d(u,c));w.exports=r},3444:(w,E,o)=>{const d=o(8216),r=o(4594),n=(u,c)=>{if(r(u,c))return null;{const l=d(u),s=d(c),f=l.prerelease.length||s.prerelease.length,g=f?"pre":"",i=f?"prerelease":"";for(const v in l)if((v==="major"||v==="minor"||v==="patch")&&l[v]!==s[v])return g+v;return i}};w.exports=n},4594:(w,E,o)=>{const d=o(9123),r=(n,u,c)=>d(n,u,c)===0;w.exports=r},145:(w,E,o)=>{const d=o(9123),r=(n,u,c)=>d(n,u,c)>0;w.exports=r},9778:(w,E,o)=>{const d=o(9123),r=(n,u,c)=>d(n,u,c)>=0;w.exports=r},288:(w,E,o)=>{const d=o(1630),r=(n,u,c,l)=>{typeof c=="string"&&(l=c,c=void 0);try{return new d(n instanceof d?n.version:n,c).inc(u,l).version}catch(s){return null}};w.exports=r},5429:(w,E,o)=>{const d=o(9123),r=(n,u,c)=>d(n,u,c)<0;w.exports=r},7888:(w,E,o)=>{const d=o(9123),r=(n,u,c)=>d(n,u,c)<=0;w.exports=r},5254:(w,E,o)=>{const d=o(1630),r=(n,u)=>new d(n,u).major;w.exports=r},9887:(w,E,o)=>{const d=o(1630),r=(n,u)=>new d(n,u).minor;w.exports=r},3228:(w,E,o)=>{const d=o(9123),r=(n,u,c)=>d(n,u,c)!==0;w.exports=r},8216:(w,E,o)=>{const{MAX_LENGTH:d}=o(3325),{re:r,t:n}=o(3259),u=o(1630),c=o(349),l=(s,f)=>{if(f=c(f),s instanceof u)return s;if(typeof s!="string"||s.length>d||!(f.loose?r[n.LOOSE]:r[n.FULL]).test(s))return null;try{return new u(s,f)}catch(i){return null}};w.exports=l},8571:(w,E,o)=>{const d=o(1630),r=(n,u)=>new d(n,u).patch;w.exports=r},2115:(w,E,o)=>{const d=o(8216),r=(n,u)=>{const c=d(n,u);return c&&c.prerelease.length?c.prerelease:null};w.exports=r},6822:(w,E,o)=>{const d=o(9123),r=(n,u,c)=>d(u,n,c);w.exports=r},2490:(w,E,o)=>{const d=o(7548),r=(n,u)=>n.sort((c,l)=>d(l,c,u));w.exports=r},5374:(w,E,o)=>{const d=o(1459),r=(n,u,c)=>{try{u=new d(u,c)}catch(l){return!1}return u.test(n)};w.exports=r},6401:(w,E,o)=>{const d=o(7548),r=(n,u)=>n.sort((c,l)=>d(c,l,u));w.exports=r},5665:(w,E,o)=>{const d=o(8216),r=(n,u)=>{const c=d(n,u);return c?c.version:null};w.exports=r},7154:(w,E,o)=>{const d=o(3259),r=o(3325),n=o(1630),u=o(7342),c=o(8216),l=o(5665),s=o(7200),f=o(288),g=o(3444),i=o(5254),v=o(9887),h=o(8571),p=o(2115),A=o(9123),m=o(6822),y=o(7317),T=o(7548),x=o(6401),C=o(2490),D=o(145),_=o(5429),R=o(4594),N=o(3228),b=o(9778),P=o(7888),L=o(5609),k=o(9485),F=o(8325),H=o(1459),W=o(5374),z=o(6607),$=o(7530),V=o(7527),Y=o(1346),nt=o(3478),it=o(841),ut=o(8951),et=o(4666),dt=o(6024),yt=o(2277),Ot=o(8784);w.exports={parse:c,valid:l,clean:s,inc:f,diff:g,major:i,minor:v,patch:h,prerelease:p,compare:A,rcompare:m,compareLoose:y,compareBuild:T,sort:x,rsort:C,gt:D,lt:_,eq:R,neq:N,gte:b,lte:P,cmp:L,coerce:k,Comparator:F,Range:H,satisfies:W,toComparators:z,maxSatisfying:$,minSatisfying:V,minVersion:Y,validRange:nt,outside:it,gtr:ut,ltr:et,intersects:dt,simplifyRange:yt,subset:Ot,SemVer:n,re:d.re,src:d.src,tokens:d.t,SEMVER_SPEC_VERSION:r.SEMVER_SPEC_VERSION,compareIdentifiers:u.compareIdentifiers,rcompareIdentifiers:u.rcompareIdentifiers}},3325:w=>{const E="2.0.0",d=Number.MAX_SAFE_INTEGER||9007199254740991,r=16;w.exports={SEMVER_SPEC_VERSION:E,MAX_LENGTH:256,MAX_SAFE_INTEGER:d,MAX_SAFE_COMPONENT_LENGTH:r}},4903:w=>{const E=typeof process=="object"&&process.env&&process.env.NODE_DEBUG&&/\bsemver\b/i.test(process.env.NODE_DEBUG)?(...o)=>console.error("SEMVER",...o):()=>{};w.exports=E},7342:w=>{const E=/^[0-9]+$/,o=(r,n)=>{const u=E.test(r),c=E.test(n);return u&&c&&(r=+r,n=+n),r===n?0:u&&!c?-1:c&&!u?1:ro(n,r);w.exports={compareIdentifiers:o,rcompareIdentifiers:d}},349:w=>{const E=["includePrerelease","loose","rtl"],o=d=>d?typeof d!="object"?{loose:!0}:E.filter(r=>d[r]).reduce((r,n)=>(r[n]=!0,r),{}):{};w.exports=o},3259:(w,E,o)=>{const{MAX_SAFE_COMPONENT_LENGTH:d}=o(3325),r=o(4903);E=w.exports={};const n=E.re=[],u=E.src=[],c=E.t={};let l=0;const s=(f,g,i)=>{const v=l++;r(f,v,g),c[f]=v,u[v]=g,n[v]=new RegExp(g,i?"g":void 0)};s("NUMERICIDENTIFIER","0|[1-9]\\d*"),s("NUMERICIDENTIFIERLOOSE","[0-9]+"),s("NONNUMERICIDENTIFIER","\\d*[a-zA-Z-][a-zA-Z0-9-]*"),s("MAINVERSION",`(${u[c.NUMERICIDENTIFIER]})\\.(${u[c.NUMERICIDENTIFIER]})\\.(${u[c.NUMERICIDENTIFIER]})`),s("MAINVERSIONLOOSE",`(${u[c.NUMERICIDENTIFIERLOOSE]})\\.(${u[c.NUMERICIDENTIFIERLOOSE]})\\.(${u[c.NUMERICIDENTIFIERLOOSE]})`),s("PRERELEASEIDENTIFIER",`(?:${u[c.NUMERICIDENTIFIER]}|${u[c.NONNUMERICIDENTIFIER]})`),s("PRERELEASEIDENTIFIERLOOSE",`(?:${u[c.NUMERICIDENTIFIERLOOSE]}|${u[c.NONNUMERICIDENTIFIER]})`),s("PRERELEASE",`(?:-(${u[c.PRERELEASEIDENTIFIER]}(?:\\.${u[c.PRERELEASEIDENTIFIER]})*))`),s("PRERELEASELOOSE",`(?:-?(${u[c.PRERELEASEIDENTIFIERLOOSE]}(?:\\.${u[c.PRERELEASEIDENTIFIERLOOSE]})*))`),s("BUILDIDENTIFIER","[0-9A-Za-z-]+"),s("BUILD",`(?:\\+(${u[c.BUILDIDENTIFIER]}(?:\\.${u[c.BUILDIDENTIFIER]})*))`),s("FULLPLAIN",`v?${u[c.MAINVERSION]}${u[c.PRERELEASE]}?${u[c.BUILD]}?`),s("FULL",`^${u[c.FULLPLAIN]}$`),s("LOOSEPLAIN",`[v=\\s]*${u[c.MAINVERSIONLOOSE]}${u[c.PRERELEASELOOSE]}?${u[c.BUILD]}?`),s("LOOSE",`^${u[c.LOOSEPLAIN]}$`),s("GTLT","((?:<|>)?=?)"),s("XRANGEIDENTIFIERLOOSE",`${u[c.NUMERICIDENTIFIERLOOSE]}|x|X|\\*`),s("XRANGEIDENTIFIER",`${u[c.NUMERICIDENTIFIER]}|x|X|\\*`),s("XRANGEPLAIN",`[v=\\s]*(${u[c.XRANGEIDENTIFIER]})(?:\\.(${u[c.XRANGEIDENTIFIER]})(?:\\.(${u[c.XRANGEIDENTIFIER]})(?:${u[c.PRERELEASE]})?${u[c.BUILD]}?)?)?`),s("XRANGEPLAINLOOSE",`[v=\\s]*(${u[c.XRANGEIDENTIFIERLOOSE]})(?:\\.(${u[c.XRANGEIDENTIFIERLOOSE]})(?:\\.(${u[c.XRANGEIDENTIFIERLOOSE]})(?:${u[c.PRERELEASELOOSE]})?${u[c.BUILD]}?)?)?`),s("XRANGE",`^${u[c.GTLT]}\\s*${u[c.XRANGEPLAIN]}$`),s("XRANGELOOSE",`^${u[c.GTLT]}\\s*${u[c.XRANGEPLAINLOOSE]}$`),s("COERCE",`(^|[^\\d])(\\d{1,${d}})(?:\\.(\\d{1,${d}}))?(?:\\.(\\d{1,${d}}))?(?:$|[^\\d])`),s("COERCERTL",u[c.COERCE],!0),s("LONETILDE","(?:~>?)"),s("TILDETRIM",`(\\s*)${u[c.LONETILDE]}\\s+`,!0),E.tildeTrimReplace="$1~",s("TILDE",`^${u[c.LONETILDE]}${u[c.XRANGEPLAIN]}$`),s("TILDELOOSE",`^${u[c.LONETILDE]}${u[c.XRANGEPLAINLOOSE]}$`),s("LONECARET","(?:\\^)"),s("CARETTRIM",`(\\s*)${u[c.LONECARET]}\\s+`,!0),E.caretTrimReplace="$1^",s("CARET",`^${u[c.LONECARET]}${u[c.XRANGEPLAIN]}$`),s("CARETLOOSE",`^${u[c.LONECARET]}${u[c.XRANGEPLAINLOOSE]}$`),s("COMPARATORLOOSE",`^${u[c.GTLT]}\\s*(${u[c.LOOSEPLAIN]})$|^$`),s("COMPARATOR",`^${u[c.GTLT]}\\s*(${u[c.FULLPLAIN]})$|^$`),s("COMPARATORTRIM",`(\\s*)${u[c.GTLT]}\\s*(${u[c.LOOSEPLAIN]}|${u[c.XRANGEPLAIN]})`,!0),E.comparatorTrimReplace="$1$2$3",s("HYPHENRANGE",`^\\s*(${u[c.XRANGEPLAIN]})\\s+-\\s+(${u[c.XRANGEPLAIN]})\\s*$`),s("HYPHENRANGELOOSE",`^\\s*(${u[c.XRANGEPLAINLOOSE]})\\s+-\\s+(${u[c.XRANGEPLAINLOOSE]})\\s*$`),s("STAR","(<|>)?=?\\s*\\*"),s("GTE0","^\\s*>=\\s*0\\.0\\.0\\s*$"),s("GTE0PRE","^\\s*>=\\s*0\\.0\\.0-0\\s*$")},8951:(w,E,o)=>{const d=o(841),r=(n,u,c)=>d(n,u,">",c);w.exports=r},6024:(w,E,o)=>{const d=o(1459),r=(n,u,c)=>(n=new d(n,c),u=new d(u,c),n.intersects(u));w.exports=r},4666:(w,E,o)=>{const d=o(841),r=(n,u,c)=>d(n,u,"<",c);w.exports=r},7530:(w,E,o)=>{const d=o(1630),r=o(1459),n=(u,c,l)=>{let s=null,f=null,g=null;try{g=new r(c,l)}catch(i){return null}return u.forEach(i=>{g.test(i)&&(!s||f.compare(i)===-1)&&(s=i,f=new d(s,l))}),s};w.exports=n},7527:(w,E,o)=>{const d=o(1630),r=o(1459),n=(u,c,l)=>{let s=null,f=null,g=null;try{g=new r(c,l)}catch(i){return null}return u.forEach(i=>{g.test(i)&&(!s||f.compare(i)===1)&&(s=i,f=new d(s,l))}),s};w.exports=n},1346:(w,E,o)=>{const d=o(1630),r=o(1459),n=o(145),u=(c,l)=>{c=new r(c,l);let s=new d("0.0.0");if(c.test(s)||(s=new d("0.0.0-0"),c.test(s)))return s;s=null;for(let f=0;f{const h=new d(v.semver.version);switch(v.operator){case">":h.prerelease.length===0?h.patch++:h.prerelease.push(0),h.raw=h.format();case"":case">=":(!i||n(h,i))&&(i=h);break;case"<":case"<=":break;default:throw new Error(`Unexpected operation: ${v.operator}`)}}),i&&(!s||n(s,i))&&(s=i)}return s&&c.test(s)?s:null};w.exports=u},841:(w,E,o)=>{const d=o(1630),r=o(8325),{ANY:n}=r,u=o(1459),c=o(5374),l=o(145),s=o(5429),f=o(7888),g=o(9778),i=(v,h,p,A)=>{v=new d(v,A),h=new u(h,A);let m,y,T,x,C;switch(p){case">":m=l,y=f,T=s,x=">",C=">=";break;case"<":m=s,y=g,T=l,x="<",C="<=";break;default:throw new TypeError('Must provide a hilo val of "<" or ">"')}if(c(v,h,A))return!1;for(let D=0;D{b.semver===n&&(b=new r(">=0.0.0")),R=R||b,N=N||b,m(b.semver,R.semver,A)?R=b:T(b.semver,N.semver,A)&&(N=b)}),R.operator===x||R.operator===C||(!N.operator||N.operator===x)&&y(v,N.semver))return!1;if(N.operator===C&&T(v,N.semver))return!1}return!0};w.exports=i},2277:(w,E,o)=>{const d=o(5374),r=o(9123);w.exports=(n,u,c)=>{const l=[];let s=null,f=null;const g=n.sort((p,A)=>r(p,A,c));for(const p of g)d(p,u,c)?(f=p,s||(s=p)):(f&&l.push([s,f]),f=null,s=null);s&&l.push([s,null]);const i=[];for(const[p,A]of l)p===A?i.push(p):!A&&p===g[0]?i.push("*"):A?p===g[0]?i.push(`<=${A}`):i.push(`${p} - ${A}`):i.push(`>=${p}`);const v=i.join(" || "),h=typeof u.raw=="string"?u.raw:String(u);return v.length{const d=o(1459),r=o(8325),{ANY:n}=r,u=o(5374),c=o(9123),l=(i,v,h={})=>{if(i===v)return!0;i=new d(i,h),v=new d(v,h);let p=!1;t:for(const A of i.set){for(const m of v.set){const y=s(A,m,h);if(p=p||y!==null,y)continue t}if(p)return!1}return!0},s=(i,v,h)=>{if(i===v)return!0;if(i.length===1&&i[0].semver===n){if(v.length===1&&v[0].semver===n)return!0;h.includePrerelease?i=[new r(">=0.0.0-0")]:i=[new r(">=0.0.0")]}if(v.length===1&&v[0].semver===n){if(h.includePrerelease)return!0;v=[new r(">=0.0.0")]}const p=new Set;let A,m;for(const N of i)N.operator===">"||N.operator===">="?A=f(A,N,h):N.operator==="<"||N.operator==="<="?m=g(m,N,h):p.add(N.semver);if(p.size>1)return null;let y;if(A&&m){if(y=c(A.semver,m.semver,h),y>0)return null;if(y===0&&(A.operator!==">="||m.operator!=="<="))return null}for(const N of p){if(A&&!u(N,String(A),h)||m&&!u(N,String(m),h))return null;for(const b of v)if(!u(N,String(b),h))return!1;return!0}let T,x,C,D,_=m&&!h.includePrerelease&&m.semver.prerelease.length?m.semver:!1,R=A&&!h.includePrerelease&&A.semver.prerelease.length?A.semver:!1;_&&_.prerelease.length===1&&m.operator==="<"&&_.prerelease[0]===0&&(_=!1);for(const N of v){if(D=D||N.operator===">"||N.operator===">=",C=C||N.operator==="<"||N.operator==="<=",A){if(R&&N.semver.prerelease&&N.semver.prerelease.length&&N.semver.major===R.major&&N.semver.minor===R.minor&&N.semver.patch===R.patch&&(R=!1),N.operator===">"||N.operator===">="){if(T=f(A,N,h),T===N&&T!==A)return!1}else if(A.operator===">="&&!u(A.semver,String(N),h))return!1}if(m){if(_&&N.semver.prerelease&&N.semver.prerelease.length&&N.semver.major===_.major&&N.semver.minor===_.minor&&N.semver.patch===_.patch&&(_=!1),N.operator==="<"||N.operator==="<="){if(x=g(m,N,h),x===N&&x!==m)return!1}else if(m.operator==="<="&&!u(m.semver,String(N),h))return!1}if(!N.operator&&(m||A)&&y!==0)return!1}return!(A&&C&&!m&&y!==0||m&&D&&!A&&y!==0||R||_)},f=(i,v,h)=>{if(!i)return v;const p=c(i.semver,v.semver,h);return p>0?i:p<0||v.operator===">"&&i.operator===">="?v:i},g=(i,v,h)=>{if(!i)return v;const p=c(i.semver,v.semver,h);return p<0?i:p>0||v.operator==="<"&&i.operator==="<="?v:i};w.exports=l},6607:(w,E,o)=>{const d=o(1459),r=(n,u)=>new d(n,u).set.map(c=>c.map(l=>l.value).join(" ").trim().split(" "));w.exports=r},3478:(w,E,o)=>{const d=o(1459),r=(n,u)=>{try{return new d(n,u).range||"*"}catch(c){return null}};w.exports=r},9737:()=>{+function(w){"use strict";var E=".dropdown-backdrop",o='[data-toggle="dropdown"]',d=function(l){w(l).on("click.bs.dropdown",this.toggle)};d.VERSION="3.4.1";function r(l){var s=l.attr("data-target");s||(s=l.attr("href"),s=s&&/#[A-Za-z]/.test(s)&&s.replace(/.*(?=#[^\s]*$)/,""));var f=s!=="#"?w(document).find(s):null;return f&&f.length?f:l.parent()}function n(l){l&&l.which===3||(w(E).remove(),w(o).each(function(){var s=w(this),f=r(s),g={relatedTarget:this};f.hasClass("open")&&(l&&l.type=="click"&&/input|textarea/i.test(l.target.tagName)&&w.contains(f[0],l.target)||(f.trigger(l=w.Event("hide.bs.dropdown",g)),!l.isDefaultPrevented()&&(s.attr("aria-expanded","false"),f.removeClass("open").trigger(w.Event("hidden.bs.dropdown",g)))))}))}d.prototype.toggle=function(l){var s=w(this);if(!s.is(".disabled, :disabled")){var f=r(s),g=f.hasClass("open");if(n(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&w(document.createElement("div")).addClass("dropdown-backdrop").insertAfter(w(this)).on("click",n);var i={relatedTarget:this};if(f.trigger(l=w.Event("show.bs.dropdown",i)),l.isDefaultPrevented())return;s.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger(w.Event("shown.bs.dropdown",i))}return!1}},d.prototype.keydown=function(l){if(!(!/(38|40|27|32)/.test(l.which)||/input|textarea/i.test(l.target.tagName))){var s=w(this);if(l.preventDefault(),l.stopPropagation(),!s.is(".disabled, :disabled")){var f=r(s),g=f.hasClass("open");if(!g&&l.which!=27||g&&l.which==27)return l.which==27&&f.find(o).trigger("focus"),s.trigger("click");var i=" li:not(.disabled):visible a",v=f.find(".dropdown-menu"+i);if(v.length){var h=v.index(l.target);l.which==38&&h>0&&h--,l.which==40&&h{+function(w){"use strict";var E=function(r,n){this.init("popover",r,n)};if(!w.fn.tooltip)throw new Error("Popover requires tooltip.js");E.VERSION="3.4.1",E.DEFAULTS=w.extend({},w.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:''}),E.prototype=w.extend({},w.fn.tooltip.Constructor.prototype),E.prototype.constructor=E,E.prototype.getDefaults=function(){return E.DEFAULTS},E.prototype.setContent=function(){var r=this.tip(),n=this.getTitle(),u=this.getContent();if(this.options.html){var c=typeof u;this.options.sanitize&&(n=this.sanitizeHtml(n),c==="string"&&(u=this.sanitizeHtml(u))),r.find(".popover-title").html(n),r.find(".popover-content").children().detach().end()[c==="string"?"html":"append"](u)}else r.find(".popover-title").text(n),r.find(".popover-content").children().detach().end().text(u);r.removeClass("fade top bottom left right in"),r.find(".popover-title").html()||r.find(".popover-title").hide()},E.prototype.hasContent=function(){return this.getTitle()||this.getContent()},E.prototype.getContent=function(){var r=this.$element,n=this.options;return r.attr("data-content")||(typeof n.content=="function"?n.content.call(r[0]):n.content)},E.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};function o(r){return this.each(function(){var n=w(this),u=n.data("bs.popover"),c=typeof r=="object"&&r;!u&&/destroy|hide/.test(r)||(u||n.data("bs.popover",u=new E(this,c)),typeof r=="string"&&u[r]())})}var d=w.fn.popover;w.fn.popover=o,w.fn.popover.Constructor=E,w.fn.popover.noConflict=function(){return w.fn.popover=d,this}}(jQuery)},3497:()=>{+function(w){"use strict";function E(r,n){this.$body=w(document.body),this.$scrollElement=w(r).is(document.body)?w(window):w(r),this.options=w.extend({},E.DEFAULTS,n),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",w.proxy(this.process,this)),this.refresh(),this.process()}E.VERSION="3.4.1",E.DEFAULTS={offset:10},E.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},E.prototype.refresh=function(){var r=this,n="offset",u=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),w.isWindow(this.$scrollElement[0])||(n="position",u=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var c=w(this),l=c.data("target")||c.attr("href"),s=/^#./.test(l)&&w(l);return s&&s.length&&s.is(":visible")&&[[s[n]().top+u,l]]||null}).sort(function(c,l){return c[0]-l[0]}).each(function(){r.offsets.push(this[0]),r.targets.push(this[1])})},E.prototype.process=function(){var r=this.$scrollElement.scrollTop()+this.options.offset,n=this.getScrollHeight(),u=this.options.offset+n-this.$scrollElement.height(),c=this.offsets,l=this.targets,s=this.activeTarget,f;if(this.scrollHeight!=n&&this.refresh(),r>=u)return s!=(f=l[l.length-1])&&this.activate(f);if(s&&r=c[f]&&(c[f+1]===void 0||r{+function(w){"use strict";var E=function(n){this.element=w(n)};E.VERSION="3.4.1",E.TRANSITION_DURATION=150,E.prototype.show=function(){var n=this.element,u=n.closest("ul:not(.dropdown-menu)"),c=n.data("target");if(c||(c=n.attr("href"),c=c&&c.replace(/.*(?=#[^\s]*$)/,"")),!n.parent("li").hasClass("active")){var l=u.find(".active:last a"),s=w.Event("hide.bs.tab",{relatedTarget:n[0]}),f=w.Event("show.bs.tab",{relatedTarget:l[0]});if(l.trigger(s),n.trigger(f),!(f.isDefaultPrevented()||s.isDefaultPrevented())){var g=w(document).find(c);this.activate(n.closest("li"),u),this.activate(g,g.parent(),function(){l.trigger({type:"hidden.bs.tab",relatedTarget:n[0]}),n.trigger({type:"shown.bs.tab",relatedTarget:l[0]})})}}},E.prototype.activate=function(n,u,c){var l=u.find("> .active"),s=c&&w.support.transition&&(l.length&&l.hasClass("fade")||!!u.find("> .fade").length);function f(){l.removeClass("active").find("> .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),n.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),s?(n[0].offsetWidth,n.addClass("in")):n.removeClass("fade"),n.parent(".dropdown-menu").length&&n.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),c&&c()}l.length&&s?l.one("bsTransitionEnd",f).emulateTransitionEnd(E.TRANSITION_DURATION):f(),l.removeClass("in")};function o(n){return this.each(function(){var u=w(this),c=u.data("bs.tab");c||u.data("bs.tab",c=new E(this)),typeof n=="string"&&c[n]()})}var d=w.fn.tab;w.fn.tab=o,w.fn.tab.Constructor=E,w.fn.tab.noConflict=function(){return w.fn.tab=d,this};var r=function(n){n.preventDefault(),o.call(w(this),"show")};w(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',r).on("click.bs.tab.data-api",'[data-toggle="pill"]',r)}(jQuery)},6278:()=>{+function(w){"use strict";var E=["sanitize","whiteList","sanitizeFn"],o=["background","cite","href","itemtype","longdesc","poster","src","xlink:href"],d=/^aria-[\w-]*$/i,r={"*":["class","dir","id","lang","role",d],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},n=/^(?:(?:https?|mailto|ftp|tel|file):|[^&:/?#]*(?:[/?#]|$))/gi,u=/^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[a-z0-9+/]+=*$/i;function c(i,v){var h=i.nodeName.toLowerCase();if(w.inArray(h,v)!==-1)return w.inArray(h,o)!==-1?Boolean(i.nodeValue.match(n)||i.nodeValue.match(u)):!0;for(var p=w(v).filter(function(y,T){return T instanceof RegExp}),A=0,m=p.length;A
',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0},sanitize:!0,sanitizeFn:null,whiteList:r},s.prototype.init=function(i,v,h){if(this.enabled=!0,this.type=i,this.$element=w(v),this.options=this.getOptions(h),this.$viewport=this.options.viewport&&w(document).find(w.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var p=this.options.trigger.split(" "),A=p.length;A--;){var m=p[A];if(m=="click")this.$element.on("click."+this.type,this.options.selector,w.proxy(this.toggle,this));else if(m!="manual"){var y=m=="hover"?"mouseenter":"focusin",T=m=="hover"?"mouseleave":"focusout";this.$element.on(y+"."+this.type,this.options.selector,w.proxy(this.enter,this)),this.$element.on(T+"."+this.type,this.options.selector,w.proxy(this.leave,this))}}this.options.selector?this._options=w.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},s.prototype.getDefaults=function(){return s.DEFAULTS},s.prototype.getOptions=function(i){var v=this.$element.data();for(var h in v)v.hasOwnProperty(h)&&w.inArray(h,E)!==-1&&delete v[h];return i=w.extend({},this.getDefaults(),v,i),i.delay&&typeof i.delay=="number"&&(i.delay={show:i.delay,hide:i.delay}),i.sanitize&&(i.template=l(i.template,i.whiteList,i.sanitizeFn)),i},s.prototype.getDelegateOptions=function(){var i={},v=this.getDefaults();return this._options&&w.each(this._options,function(h,p){v[h]!=p&&(i[h]=p)}),i},s.prototype.enter=function(i){var v=i instanceof this.constructor?i:w(i.currentTarget).data("bs."+this.type);if(v||(v=new this.constructor(i.currentTarget,this.getDelegateOptions()),w(i.currentTarget).data("bs."+this.type,v)),i instanceof w.Event&&(v.inState[i.type=="focusin"?"focus":"hover"]=!0),v.tip().hasClass("in")||v.hoverState=="in"){v.hoverState="in";return}if(clearTimeout(v.timeout),v.hoverState="in",!v.options.delay||!v.options.delay.show)return v.show();v.timeout=setTimeout(function(){v.hoverState=="in"&&v.show()},v.options.delay.show)},s.prototype.isInStateTrue=function(){for(var i in this.inState)if(this.inState[i])return!0;return!1},s.prototype.leave=function(i){var v=i instanceof this.constructor?i:w(i.currentTarget).data("bs."+this.type);if(v||(v=new this.constructor(i.currentTarget,this.getDelegateOptions()),w(i.currentTarget).data("bs."+this.type,v)),i instanceof w.Event&&(v.inState[i.type=="focusout"?"focus":"hover"]=!1),!v.isInStateTrue()){if(clearTimeout(v.timeout),v.hoverState="out",!v.options.delay||!v.options.delay.hide)return v.hide();v.timeout=setTimeout(function(){v.hoverState=="out"&&v.hide()},v.options.delay.hide)}},s.prototype.show=function(){var i=w.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(i);var v=w.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(i.isDefaultPrevented()||!v)return;var h=this,p=this.tip(),A=this.getUID(this.type);this.setContent(),p.attr("id",A),this.$element.attr("aria-describedby",A),this.options.animation&&p.addClass("fade");var m=typeof this.options.placement=="function"?this.options.placement.call(this,p[0],this.$element[0]):this.options.placement,y=/\s?auto?\s?/i,T=y.test(m);T&&(m=m.replace(y,"")||"top"),p.detach().css({top:0,left:0,display:"block"}).addClass(m).data("bs."+this.type,this),this.options.container?p.appendTo(w(document).find(this.options.container)):p.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var x=this.getPosition(),C=p[0].offsetWidth,D=p[0].offsetHeight;if(T){var _=m,R=this.getPosition(this.$viewport);m=m=="bottom"&&x.bottom+D>R.bottom?"top":m=="top"&&x.top-DR.width?"left":m=="left"&&x.left-Cy.top+y.height&&(A.top=y.top+y.height-x)}else{var C=v.left-m,D=v.left+m+h;Cy.right&&(A.left=y.left+y.width-D)}return A},s.prototype.getTitle=function(){var i,v=this.$element,h=this.options;return i=v.attr("data-original-title")||(typeof h.title=="function"?h.title.call(v[0]):h.title),i},s.prototype.getUID=function(i){do i+=~~(Math.random()*1e6);while(document.getElementById(i));return i},s.prototype.tip=function(){if(!this.$tip&&(this.$tip=w(this.options.template),this.$tip.length!=1))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},s.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},s.prototype.enable=function(){this.enabled=!0},s.prototype.disable=function(){this.enabled=!1},s.prototype.toggleEnabled=function(){this.enabled=!this.enabled},s.prototype.toggle=function(i){var v=this;i&&(v=w(i.currentTarget).data("bs."+this.type),v||(v=new this.constructor(i.currentTarget,this.getDelegateOptions()),w(i.currentTarget).data("bs."+this.type,v))),i?(v.inState.click=!v.inState.click,v.isInStateTrue()?v.enter(v):v.leave(v)):v.tip().hasClass("in")?v.leave(v):v.enter(v)},s.prototype.destroy=function(){var i=this;clearTimeout(this.timeout),this.hide(function(){i.$element.off("."+i.type).removeData("bs."+i.type),i.$tip&&i.$tip.detach(),i.$tip=null,i.$arrow=null,i.$viewport=null,i.$element=null})},s.prototype.sanitizeHtml=function(i){return l(i,this.options.whiteList,this.options.sanitizeFn)};function f(i){return this.each(function(){var v=w(this),h=v.data("bs.tooltip"),p=typeof i=="object"&&i;!h&&/destroy|hide/.test(i)||(h||v.data("bs.tooltip",h=new s(this,p)),typeof i=="string"&&h[i]())})}var g=w.fn.tooltip;w.fn.tooltip=f,w.fn.tooltip.Constructor=s,w.fn.tooltip.noConflict=function(){return w.fn.tooltip=g,this}}(jQuery)},2027:w=>{var E=function(){this.Diff_Timeout=1,this.Diff_EditCost=4,this.Match_Threshold=.5,this.Match_Distance=1e3,this.Patch_DeleteThreshold=.5,this.Patch_Margin=4,this.Match_MaxBits=32},o=-1,d=1,r=0;E.Diff=function(n,u){return[n,u]},E.prototype.diff_main=function(n,u,c,l){typeof l=="undefined"&&(this.Diff_Timeout<=0?l=Number.MAX_VALUE:l=new Date().getTime()+this.Diff_Timeout*1e3);var s=l;if(n==null||u==null)throw new Error("Null input. (diff_main)");if(n==u)return n?[new E.Diff(r,n)]:[];typeof c=="undefined"&&(c=!0);var f=c,g=this.diff_commonPrefix(n,u),i=n.substring(0,g);n=n.substring(g),u=u.substring(g),g=this.diff_commonSuffix(n,u);var v=n.substring(n.length-g);n=n.substring(0,n.length-g),u=u.substring(0,u.length-g);var h=this.diff_compute_(n,u,f,s);return i&&h.unshift(new E.Diff(r,i)),v&&h.push(new E.Diff(r,v)),this.diff_cleanupMerge(h),h},E.prototype.diff_compute_=function(n,u,c,l){var s;if(!n)return[new E.Diff(d,u)];if(!u)return[new E.Diff(o,n)];var f=n.length>u.length?n:u,g=n.length>u.length?u:n,i=f.indexOf(g);if(i!=-1)return s=[new E.Diff(d,f.substring(0,i)),new E.Diff(r,g),new E.Diff(d,f.substring(i+g.length))],n.length>u.length&&(s[0][0]=s[2][0]=o),s;if(g.length==1)return[new E.Diff(o,n),new E.Diff(d,u)];var v=this.diff_halfMatch_(n,u);if(v){var h=v[0],p=v[1],A=v[2],m=v[3],y=v[4],T=this.diff_main(h,A,c,l),x=this.diff_main(p,m,c,l);return T.concat([new E.Diff(r,y)],x)}return c&&n.length>100&&u.length>100?this.diff_lineMode_(n,u,l):this.diff_bisect_(n,u,l)},E.prototype.diff_lineMode_=function(n,u,c){var l=this.diff_linesToChars_(n,u);n=l.chars1,u=l.chars2;var s=l.lineArray,f=this.diff_main(n,u,!1,c);this.diff_charsToLines_(f,s),this.diff_cleanupSemantic(f),f.push(new E.Diff(r,""));for(var g=0,i=0,v=0,h="",p="";g=1&&v>=1){f.splice(g-i-v,i+v),g=g-i-v;for(var A=this.diff_main(h,p,!1,c),m=A.length-1;m>=0;m--)f.splice(g,0,A[m]);g=g+A.length}v=0,i=0,h="",p="";break}g++}return f.pop(),f},E.prototype.diff_bisect_=function(n,u,c){for(var l=n.length,s=u.length,f=Math.ceil((l+s)/2),g=f,i=2*f,v=new Array(i),h=new Array(i),p=0;pc);D++){for(var _=-D+y;_<=D-T;_+=2){var R=g+_,N;_==-D||_!=D&&v[R-1]l)T+=2;else if(b>s)y+=2;else if(m){var P=g+A-_;if(P>=0&&P=L)return this.diff_bisectSplit_(n,u,N,b,c)}}}for(var k=-D+x;k<=D-C;k+=2){var P=g+k,L;k==-D||k!=D&&h[P-1]l)C+=2;else if(F>s)x+=2;else if(!m){var R=g+A-k;if(R>=0&&R=L)return this.diff_bisectSplit_(n,u,N,b,c)}}}}return[new E.Diff(o,n),new E.Diff(d,u)]},E.prototype.diff_bisectSplit_=function(n,u,c,l,s){var f=n.substring(0,c),g=u.substring(0,l),i=n.substring(c),v=u.substring(l),h=this.diff_main(f,g,!1,s),p=this.diff_main(i,v,!1,s);return h.concat(p)},E.prototype.diff_linesToChars_=function(n,u){var c=[],l={};c[0]="";function s(v){for(var h="",p=0,A=-1,m=c.length;Al?n=n.substring(c-l):cu.length?n:u,l=n.length>u.length?u:n;if(c.length<4||l.length*2=T.length?[N,b,P,L,R]:null}var g=f(c,l,Math.ceil(c.length/4)),i=f(c,l,Math.ceil(c.length/2)),v;if(!g&&!i)return null;i?g?v=g[4].length>i[4].length?g:i:v=i:v=g;var h,p,A,m;n.length>u.length?(h=v[0],p=v[1],A=v[2],m=v[3]):(A=v[0],m=v[1],h=v[2],p=v[3]);var y=v[4];return[h,p,A,m,y]},E.prototype.diff_cleanupSemantic=function(n){for(var u=!1,c=[],l=0,s=null,f=0,g=0,i=0,v=0,h=0;f0?c[l-1]:-1,g=0,i=0,v=0,h=0,s=null,u=!0)),f++;for(u&&this.diff_cleanupMerge(n),this.diff_cleanupSemanticLossless(n),f=1;f=y?(m>=p.length/2||m>=A.length/2)&&(n.splice(f,0,new E.Diff(r,A.substring(0,m))),n[f-1][1]=p.substring(0,p.length-m),n[f+1][1]=A.substring(m),f++):(y>=p.length/2||y>=A.length/2)&&(n.splice(f,0,new E.Diff(r,p.substring(0,y))),n[f-1][0]=d,n[f-1][1]=A.substring(0,A.length-y),n[f+1][0]=o,n[f+1][1]=p.substring(y),f++),f++}f++}},E.prototype.diff_cleanupSemanticLossless=function(n){function u(y,T){if(!y||!T)return 6;var x=y.charAt(y.length-1),C=T.charAt(0),D=x.match(E.nonAlphaNumericRegex_),_=C.match(E.nonAlphaNumericRegex_),R=D&&x.match(E.whitespaceRegex_),N=_&&C.match(E.whitespaceRegex_),b=R&&x.match(E.linebreakRegex_),P=N&&C.match(E.linebreakRegex_),L=b&&y.match(E.blanklineEndRegex_),k=P&&T.match(E.blanklineStartRegex_);return L||k?5:b||P?4:D&&!R&&N?3:R||N?2:D||_?1:0}for(var c=1;c=A&&(A=m,v=l,h=s,p=f)}n[c-1][1]!=v&&(v?n[c-1][1]=v:(n.splice(c-1,1),c--),n[c][1]=h,p?n[c+1][1]=p:(n.splice(c+1,1),c--))}c++}},E.nonAlphaNumericRegex_=/[^a-zA-Z0-9]/,E.whitespaceRegex_=/\s/,E.linebreakRegex_=/[\r\n]/,E.blanklineEndRegex_=/\n\r?\n$/,E.blanklineStartRegex_=/^\r?\n\r?\n/,E.prototype.diff_cleanupEfficiency=function(n){for(var u=!1,c=[],l=0,s=null,f=0,g=!1,i=!1,v=!1,h=!1;f0?c[l-1]:-1,v=h=!1),u=!0)),f++;u&&this.diff_cleanupMerge(n)},E.prototype.diff_cleanupMerge=function(n){n.push(new E.Diff(r,""));for(var u=0,c=0,l=0,s="",f="",g;u1?(c!==0&&l!==0&&(g=this.diff_commonPrefix(f,s),g!==0&&(u-c-l>0&&n[u-c-l-1][0]==r?n[u-c-l-1][1]+=f.substring(0,g):(n.splice(0,0,new E.Diff(r,f.substring(0,g))),u++),f=f.substring(g),s=s.substring(g)),g=this.diff_commonSuffix(f,s),g!==0&&(n[u][1]=f.substring(f.length-g)+n[u][1],f=f.substring(0,f.length-g),s=s.substring(0,s.length-g))),u-=c+l,n.splice(u,c+l),s.length&&(n.splice(u,0,new E.Diff(o,s)),u++),f.length&&(n.splice(u,0,new E.Diff(d,f)),u++),u++):u!==0&&n[u-1][0]==r?(n[u-1][1]+=n[u][1],n.splice(u,1)):u++,l=0,c=0,s="",f="";break}n[n.length-1][1]===""&&n.pop();var i=!1;for(u=1;uu));g++)s=c,f=l;return n.length!=g&&n[g][0]===o?f:f+(u-s)},E.prototype.diff_prettyHtml=function(n){for(var u=[],c=/&/g,l=//g,f=/\n/g,g=0;g");switch(i){case d:u[g]=''+h+"";break;case o:u[g]=''+h+"";break;case r:u[g]=""+h+"";break}}return u.join("")},E.prototype.diff_text1=function(n){for(var u=[],c=0;cthis.Match_MaxBits)throw new Error("Pattern too long for this browser.");var l=this.match_alphabet_(u),s=this;function f(N,b){var P=N/u.length,L=Math.abs(c-b);return s.Match_Distance?P+L/s.Match_Distance:L?1:P}var g=this.Match_Threshold,i=n.indexOf(u,c);i!=-1&&(g=Math.min(f(0,i),g),i=n.lastIndexOf(u,c+u.length),i!=-1&&(g=Math.min(f(0,i),g)));var v=1<=T;D--){var _=l[n.charAt(D-1)];if(y===0?C[D]=(C[D+1]<<1|1)&_:C[D]=(C[D+1]<<1|1)&_|((m[D+1]|m[D])<<1|1)|m[D+1],C[D]&v){var R=f(y,D-1);if(R<=g)if(g=R,i=D-1,i>c)T=Math.max(1,2*c-i);else break}}if(f(y+1,c)>g)break;m=C}return i},E.prototype.match_alphabet_=function(n){for(var u={},c=0;c2&&(this.diff_cleanupSemantic(s),this.diff_cleanupEfficiency(s));else if(n&&typeof n=="object"&&typeof u=="undefined"&&typeof c=="undefined")s=n,l=this.diff_text1(s);else if(typeof n=="string"&&u&&typeof u=="object"&&typeof c=="undefined")l=n,s=u;else if(typeof n=="string"&&typeof u=="string"&&c&&typeof c=="object")l=n,s=c;else throw new Error("Unknown call format to patch_make.");if(s.length===0)return[];for(var f=[],g=new E.patch_obj,i=0,v=0,h=0,p=l,A=l,m=0;m=2*this.Patch_Margin&&i&&(this.patch_addContext_(g,p),f.push(g),g=new E.patch_obj,i=0,p=A,v=h);break}y!==d&&(v+=T.length),y!==o&&(h+=T.length)}return i&&(this.patch_addContext_(g,p),f.push(g)),f},E.prototype.patch_deepCopy=function(n){for(var u=[],c=0;cthis.Match_MaxBits?(v=this.match_main(u,i.substring(0,this.Match_MaxBits),g),v!=-1&&(h=this.match_main(u,i.substring(i.length-this.Match_MaxBits),g+i.length-this.Match_MaxBits),(h==-1||v>=h)&&(v=-1))):v=this.match_main(u,i,g),v==-1)s[f]=!1,l-=n[f].length2-n[f].length1;else{s[f]=!0,l=v-g;var p;if(h==-1?p=u.substring(v,v+i.length):p=u.substring(v,h+this.Match_MaxBits),i==p)u=u.substring(0,v)+this.diff_text2(n[f].diffs)+u.substring(v+i.length);else{var A=this.diff_main(i,p,!1);if(i.length>this.Match_MaxBits&&this.diff_levenshtein(A)/i.length>this.Patch_DeleteThreshold)s[f]=!1;else{this.diff_cleanupSemanticLossless(A);for(var m=0,y,T=0;Tf[0][1].length){var g=u-f[0][1].length;f[0][1]=c.substring(f[0][1].length)+f[0][1],s.start1-=g,s.start2-=g,s.length1+=g,s.length2+=g}if(s=n[n.length-1],f=s.diffs,f.length==0||f[f.length-1][0]!=r)f.push(new E.Diff(r,c)),s.length1+=u,s.length2+=u;else if(u>f[f.length-1][1].length){var g=u-f[f.length-1][1].length;f[f.length-1][1]+=c.substring(0,g),s.length1+=g,s.length2+=g}return c},E.prototype.patch_splitMax=function(n){for(var u=this.Match_MaxBits,c=0;c2*u?(i.length1+=p.length,s+=p.length,v=!1,i.diffs.push(new E.Diff(h,p)),l.diffs.shift()):(p=p.substring(0,u-i.length1-this.Patch_Margin),i.length1+=p.length,s+=p.length,h===r?(i.length2+=p.length,f+=p.length):v=!1,i.diffs.push(new E.Diff(h,p)),p==l.diffs[0][1]?l.diffs.shift():l.diffs[0][1]=l.diffs[0][1].substring(p.length))}g=this.diff_text2(i.diffs),g=g.substring(g.length-this.Patch_Margin);var A=this.diff_text1(l.diffs).substring(0,this.Patch_Margin);A!==""&&(i.length1+=A.length,i.length2+=A.length,i.diffs.length!==0&&i.diffs[i.diffs.length-1][0]===r?i.diffs[i.diffs.length-1][1]+=A:i.diffs.push(new E.Diff(r,A))),v||n.splice(++c,0,i)}}},E.prototype.patch_toText=function(n){for(var u=[],c=0;c{var Za={8325:(b,v,s)=>{const d=Symbol("SemVer ANY");class r{static get ANY(){return d}constructor(m,c){if(c=n(c),m instanceof r){if(m.loose===!!c.loose)return m;m=m.value}o("comparator",m,c),this.options=c,this.loose=!!c.loose,this.parse(m),this.semver===d?this.value="":this.value=this.operator+this.semver.version,o("comp",this)}parse(m){const c=this.options.loose?u[p.COMPARATORLOOSE]:u[p.COMPARATOR],h=m.match(c);if(!h)throw new TypeError(`Invalid comparator: ${m}`);this.operator=h[1]!==void 0?h[1]:"",this.operator==="="&&(this.operator=""),h[2]?this.semver=new f(h[2],this.options.loose):this.semver=d}toString(){return this.value}test(m){if(o("Comparator.test",m,this.options.loose),this.semver===d||m===d)return!0;if(typeof m=="string")try{m=new f(m,this.options)}catch(c){return!1}return l(m,this.operator,this.semver,this.options)}intersects(m,c){if(!(m instanceof r))throw new TypeError("a Comparator is required");return this.operator===""?this.value===""?!0:new g(m.value,c).test(this.value):m.operator===""?m.value===""?!0:new g(this.value,c).test(m.semver):(c=n(c),c.includePrerelease&&(this.value==="<0.0.0-0"||m.value==="<0.0.0-0")||!c.includePrerelease&&(this.value.startsWith("<0.0.0")||m.value.startsWith("<0.0.0"))?!1:!!(this.operator.startsWith(">")&&m.operator.startsWith(">")||this.operator.startsWith("<")&&m.operator.startsWith("<")||this.semver.version===m.semver.version&&this.operator.includes("=")&&m.operator.includes("=")||l(this.semver,"<",m.semver,c)&&this.operator.startsWith(">")&&m.operator.startsWith("<")||l(this.semver,">",m.semver,c)&&this.operator.startsWith("<")&&m.operator.startsWith(">")))}}b.exports=r;const n=s(349),{re:u,t:p}=s(3259),l=s(5609),o=s(4903),f=s(1630),g=s(1459)},1459:(b,v,s)=>{class d{constructor(H,$){if($=u($),H instanceof d)return H.loose===!!$.loose&&H.includePrerelease===!!$.includePrerelease?H:new d(H.raw,$);if(H instanceof p)return this.raw=H.value,this.set=[[H]],this.format(),this;if(this.options=$,this.loose=!!$.loose,this.includePrerelease=!!$.includePrerelease,this.raw=H,this.set=H.split("||").map(Y=>this.parseRange(Y.trim())).filter(Y=>Y.length),!this.set.length)throw new TypeError(`Invalid SemVer Range: ${H}`);if(this.set.length>1){const Y=this.set[0];if(this.set=this.set.filter(K=>!E(K[0])),this.set.length===0)this.set=[Y];else if(this.set.length>1){for(const K of this.set)if(K.length===1&&x(K[0])){this.set=[K];break}}}this.format()}format(){return this.range=this.set.map(H=>H.join(" ").trim()).join("||").trim(),this.range}toString(){return this.range}parseRange(H){H=H.trim();const Y=((this.options.includePrerelease&&h)|(this.options.loose&&y))+":"+H,K=n.get(Y);if(K)return K;const Q=this.options.loose,ie=Q?f[g.HYPHENRANGELOOSE]:f[g.HYPHENRANGE];H=H.replace(ie,W(this.options.includePrerelease)),l("hyphen replace",H),H=H.replace(f[g.COMPARATORTRIM],i),l("comparator trim",H),H=H.replace(f[g.TILDETRIM],m),H=H.replace(f[g.CARETTRIM],c),H=H.split(/\s+/).join(" ");let fe=H.split(" ").map(Te=>A(Te,this.options)).join(" ").split(/\s+/).map(Te=>B(Te,this.options));Q&&(fe=fe.filter(Te=>(l("loose invalid filter",Te,this.options),!!Te.match(f[g.COMPARATORLOOSE])))),l("range list",fe);const J=new Map,Ee=fe.map(Te=>new p(Te,this.options));for(const Te of Ee){if(E(Te))return[Te];J.set(Te.value,Te)}J.size>1&&J.has("")&&J.delete("");const xe=[...J.values()];return n.set(Y,xe),xe}intersects(H,$){if(!(H instanceof d))throw new TypeError("a Range is required");return this.set.some(Y=>T(Y,$)&&H.set.some(K=>T(K,$)&&Y.every(Q=>K.every(ie=>Q.intersects(ie,$)))))}test(H){if(!H)return!1;if(typeof H=="string")try{H=new o(H,this.options)}catch($){return!1}for(let $=0;$F.value==="<0.0.0-0",x=F=>F.value==="",T=(F,H)=>{let $=!0;const Y=F.slice();let K=Y.pop();for(;$&&Y.length;)$=Y.every(Q=>K.intersects(Q,H)),K=Y.pop();return $},A=(F,H)=>(l("comp",F,H),F=O(F,H),l("caret",F),F=D(F,H),l("tildes",F),F=R(F,H),l("xrange",F),F=N(F,H),l("stars",F),F),w=F=>!F||F.toLowerCase()==="x"||F==="*",D=(F,H)=>F.trim().split(/\s+/).map($=>C($,H)).join(" "),C=(F,H)=>{const $=H.loose?f[g.TILDELOOSE]:f[g.TILDE];return F.replace($,(Y,K,Q,ie,fe)=>{l("tilde",F,Y,K,Q,ie,fe);let J;return w(K)?J="":w(Q)?J=`>=${K}.0.0 <${+K+1}.0.0-0`:w(ie)?J=`>=${K}.${Q}.0 <${K}.${+Q+1}.0-0`:fe?(l("replaceTilde pr",fe),J=`>=${K}.${Q}.${ie}-${fe} <${K}.${+Q+1}.0-0`):J=`>=${K}.${Q}.${ie} <${K}.${+Q+1}.0-0`,l("tilde return",J),J})},O=(F,H)=>F.trim().split(/\s+/).map($=>I($,H)).join(" "),I=(F,H)=>{l("caret",F,H);const $=H.loose?f[g.CARETLOOSE]:f[g.CARET],Y=H.includePrerelease?"-0":"";return F.replace($,(K,Q,ie,fe,J)=>{l("caret",F,K,Q,ie,fe,J);let Ee;return w(Q)?Ee="":w(ie)?Ee=`>=${Q}.0.0${Y} <${+Q+1}.0.0-0`:w(fe)?Q==="0"?Ee=`>=${Q}.${ie}.0${Y} <${Q}.${+ie+1}.0-0`:Ee=`>=${Q}.${ie}.0${Y} <${+Q+1}.0.0-0`:J?(l("replaceCaret pr",J),Q==="0"?ie==="0"?Ee=`>=${Q}.${ie}.${fe}-${J} <${Q}.${ie}.${+fe+1}-0`:Ee=`>=${Q}.${ie}.${fe}-${J} <${Q}.${+ie+1}.0-0`:Ee=`>=${Q}.${ie}.${fe}-${J} <${+Q+1}.0.0-0`):(l("no pr"),Q==="0"?ie==="0"?Ee=`>=${Q}.${ie}.${fe}${Y} <${Q}.${ie}.${+fe+1}-0`:Ee=`>=${Q}.${ie}.${fe}${Y} <${Q}.${+ie+1}.0-0`:Ee=`>=${Q}.${ie}.${fe} <${+Q+1}.0.0-0`),l("caret return",Ee),Ee})},R=(F,H)=>(l("replaceXRanges",F,H),F.split(/\s+/).map($=>_($,H)).join(" ")),_=(F,H)=>{F=F.trim();const $=H.loose?f[g.XRANGELOOSE]:f[g.XRANGE];return F.replace($,(Y,K,Q,ie,fe,J)=>{l("xRange",F,Y,K,Q,ie,fe,J);const Ee=w(Q),xe=Ee||w(ie),Te=xe||w(fe),qe=Te;return K==="="&&qe&&(K=""),J=H.includePrerelease?"-0":"",Ee?K===">"||K==="<"?Y="<0.0.0-0":Y="*":K&&qe?(xe&&(ie=0),fe=0,K===">"?(K=">=",xe?(Q=+Q+1,ie=0,fe=0):(ie=+ie+1,fe=0)):K==="<="&&(K="<",xe?Q=+Q+1:ie=+ie+1),K==="<"&&(J="-0"),Y=`${K+Q}.${ie}.${fe}${J}`):xe?Y=`>=${Q}.0.0${J} <${+Q+1}.0.0-0`:Te&&(Y=`>=${Q}.${ie}.0${J} <${Q}.${+ie+1}.0-0`),l("xRange return",Y),Y})},N=(F,H)=>(l("replaceStars",F,H),F.trim().replace(f[g.STAR],"")),B=(F,H)=>(l("replaceGTE0",F,H),F.trim().replace(f[H.includePrerelease?g.GTE0PRE:g.GTE0],"")),W=F=>(H,$,Y,K,Q,ie,fe,J,Ee,xe,Te,qe,dt)=>(w(Y)?$="":w(K)?$=`>=${Y}.0.0${F?"-0":""}`:w(Q)?$=`>=${Y}.${K}.0${F?"-0":""}`:ie?$=`>=${$}`:$=`>=${$}${F?"-0":""}`,w(Ee)?J="":w(xe)?J=`<${+Ee+1}.0.0-0`:w(Te)?J=`<${Ee}.${+xe+1}.0-0`:qe?J=`<=${Ee}.${xe}.${Te}-${qe}`:F?J=`<${Ee}.${xe}.${+Te+1}-0`:J=`<=${J}`,`${$} ${J}`.trim()),z=(F,H,$)=>{for(let Y=0;Y0){const K=F[Y].semver;if(K.major===H.major&&K.minor===H.minor&&K.patch===H.patch)return!0}return!1}return!0}},1630:(b,v,s)=>{const d=s(4903),{MAX_LENGTH:r,MAX_SAFE_INTEGER:n}=s(3325),{re:u,t:p}=s(3259),l=s(349),{compareIdentifiers:o}=s(7342);class f{constructor(i,m){if(m=l(m),i instanceof f){if(i.loose===!!m.loose&&i.includePrerelease===!!m.includePrerelease)return i;i=i.version}else if(typeof i!="string")throw new TypeError(`Invalid version. Must be a string. Got type "${typeof i}".`);if(i.length>r)throw new TypeError(`version is longer than ${r} characters`);d("SemVer",i,m),this.options=m,this.loose=!!m.loose,this.includePrerelease=!!m.includePrerelease;const c=i.trim().match(m.loose?u[p.LOOSE]:u[p.FULL]);if(!c)throw new TypeError(`Invalid Version: ${i}`);if(this.raw=i,this.major=+c[1],this.minor=+c[2],this.patch=+c[3],this.major>n||this.major<0)throw new TypeError("Invalid major version");if(this.minor>n||this.minor<0)throw new TypeError("Invalid minor version");if(this.patch>n||this.patch<0)throw new TypeError("Invalid patch version");c[4]?this.prerelease=c[4].split(".").map(h=>{if(/^[0-9]+$/.test(h)){const y=+h;if(y>=0&&y=0;)typeof this.prerelease[y]=="number"&&(this.prerelease[y]++,y=-2);if(y===-1){if(m===this.prerelease.join(".")&&c===!1)throw new Error("invalid increment argument: identifier already exists");this.prerelease.push(h)}}if(m){let y=[m,h];c===!1&&(y=[m]),o(this.prerelease[0],m)===0?isNaN(this.prerelease[1])&&(this.prerelease=y):this.prerelease=y}break}default:throw new Error(`invalid increment argument: ${i}`)}return this.format(),this.raw=this.version,this}}b.exports=f},7200:(b,v,s)=>{const d=s(8216),r=(n,u)=>{const p=d(n.trim().replace(/^[=v]+/,""),u);return p?p.version:null};b.exports=r},5609:(b,v,s)=>{const d=s(4594),r=s(3228),n=s(145),u=s(9778),p=s(5429),l=s(7888),o=(f,g,i,m)=>{switch(g){case"===":return typeof f=="object"&&(f=f.version),typeof i=="object"&&(i=i.version),f===i;case"!==":return typeof f=="object"&&(f=f.version),typeof i=="object"&&(i=i.version),f!==i;case"":case"=":case"==":return d(f,i,m);case"!=":return r(f,i,m);case">":return n(f,i,m);case">=":return u(f,i,m);case"<":return p(f,i,m);case"<=":return l(f,i,m);default:throw new TypeError(`Invalid operator: ${g}`)}};b.exports=o},9485:(b,v,s)=>{const d=s(1630),r=s(8216),{re:n,t:u}=s(3259),p=(l,o)=>{if(l instanceof d)return l;if(typeof l=="number"&&(l=String(l)),typeof l!="string")return null;o=o||{};let f=null;if(!o.rtl)f=l.match(n[u.COERCE]);else{let g;for(;(g=n[u.COERCERTL].exec(l))&&(!f||f.index+f[0].length!==l.length);)(!f||g.index+g[0].length!==f.index+f[0].length)&&(f=g),n[u.COERCERTL].lastIndex=g.index+g[1].length+g[2].length;n[u.COERCERTL].lastIndex=-1}return f===null?null:r(`${f[2]}.${f[3]||"0"}.${f[4]||"0"}`,o)};b.exports=p},7548:(b,v,s)=>{const d=s(1630),r=(n,u,p)=>{const l=new d(n,p),o=new d(u,p);return l.compare(o)||l.compareBuild(o)};b.exports=r},7317:(b,v,s)=>{const d=s(9123),r=(n,u)=>d(n,u,!0);b.exports=r},9123:(b,v,s)=>{const d=s(1630),r=(n,u,p)=>new d(n,p).compare(new d(u,p));b.exports=r},3444:(b,v,s)=>{const d=s(8216),r=(n,u)=>{const p=d(n,null,!0),l=d(u,null,!0),o=p.compare(l);if(o===0)return null;const f=o>0,g=f?p:l,i=f?l:p,m=!!g.prerelease.length,c=m?"pre":"";return p.major!==l.major?c+"major":p.minor!==l.minor?c+"minor":p.patch!==l.patch?c+"patch":m?"prerelease":i.patch?"patch":i.minor?"minor":"major"};b.exports=r},4594:(b,v,s)=>{const d=s(9123),r=(n,u,p)=>d(n,u,p)===0;b.exports=r},145:(b,v,s)=>{const d=s(9123),r=(n,u,p)=>d(n,u,p)>0;b.exports=r},9778:(b,v,s)=>{const d=s(9123),r=(n,u,p)=>d(n,u,p)>=0;b.exports=r},288:(b,v,s)=>{const d=s(1630),r=(n,u,p,l,o)=>{typeof p=="string"&&(o=l,l=p,p=void 0);try{return new d(n instanceof d?n.version:n,p).inc(u,l,o).version}catch(f){return null}};b.exports=r},5429:(b,v,s)=>{const d=s(9123),r=(n,u,p)=>d(n,u,p)<0;b.exports=r},7888:(b,v,s)=>{const d=s(9123),r=(n,u,p)=>d(n,u,p)<=0;b.exports=r},5254:(b,v,s)=>{const d=s(1630),r=(n,u)=>new d(n,u).major;b.exports=r},9887:(b,v,s)=>{const d=s(1630),r=(n,u)=>new d(n,u).minor;b.exports=r},3228:(b,v,s)=>{const d=s(9123),r=(n,u,p)=>d(n,u,p)!==0;b.exports=r},8216:(b,v,s)=>{const d=s(1630),r=(n,u,p=!1)=>{if(n instanceof d)return n;try{return new d(n,u)}catch(l){if(!p)return null;throw l}};b.exports=r},8571:(b,v,s)=>{const d=s(1630),r=(n,u)=>new d(n,u).patch;b.exports=r},2115:(b,v,s)=>{const d=s(8216),r=(n,u)=>{const p=d(n,u);return p&&p.prerelease.length?p.prerelease:null};b.exports=r},6822:(b,v,s)=>{const d=s(9123),r=(n,u,p)=>d(u,n,p);b.exports=r},2490:(b,v,s)=>{const d=s(7548),r=(n,u)=>n.sort((p,l)=>d(l,p,u));b.exports=r},5374:(b,v,s)=>{const d=s(1459),r=(n,u,p)=>{try{u=new d(u,p)}catch(l){return!1}return u.test(n)};b.exports=r},6401:(b,v,s)=>{const d=s(7548),r=(n,u)=>n.sort((p,l)=>d(p,l,u));b.exports=r},5665:(b,v,s)=>{const d=s(8216),r=(n,u)=>{const p=d(n,u);return p?p.version:null};b.exports=r},7154:(b,v,s)=>{const d=s(3259),r=s(3325),n=s(1630),u=s(7342),p=s(8216),l=s(5665),o=s(7200),f=s(288),g=s(3444),i=s(5254),m=s(9887),c=s(8571),h=s(2115),y=s(9123),E=s(6822),x=s(7317),T=s(7548),A=s(6401),w=s(2490),D=s(145),C=s(5429),O=s(4594),I=s(3228),R=s(9778),_=s(7888),N=s(5609),B=s(9485),W=s(8325),z=s(1459),F=s(5374),H=s(6607),$=s(7530),Y=s(7527),K=s(1346),Q=s(3478),ie=s(841),fe=s(8951),J=s(4666),Ee=s(6024),xe=s(2277),Te=s(8784);b.exports={parse:p,valid:l,clean:o,inc:f,diff:g,major:i,minor:m,patch:c,prerelease:h,compare:y,rcompare:E,compareLoose:x,compareBuild:T,sort:A,rsort:w,gt:D,lt:C,eq:O,neq:I,gte:R,lte:_,cmp:N,coerce:B,Comparator:W,Range:z,satisfies:F,toComparators:H,maxSatisfying:$,minSatisfying:Y,minVersion:K,validRange:Q,outside:ie,gtr:fe,ltr:J,intersects:Ee,simplifyRange:xe,subset:Te,SemVer:n,re:d.re,src:d.src,tokens:d.t,SEMVER_SPEC_VERSION:r.SEMVER_SPEC_VERSION,RELEASE_TYPES:r.RELEASE_TYPES,compareIdentifiers:u.compareIdentifiers,rcompareIdentifiers:u.rcompareIdentifiers}},3325:b=>{const v="2.0.0",d=Number.MAX_SAFE_INTEGER||9007199254740991,r=16,n=["major","premajor","minor","preminor","patch","prepatch","prerelease"];b.exports={MAX_LENGTH:256,MAX_SAFE_COMPONENT_LENGTH:r,MAX_SAFE_INTEGER:d,RELEASE_TYPES:n,SEMVER_SPEC_VERSION:v,FLAG_INCLUDE_PRERELEASE:1,FLAG_LOOSE:2}},4903:b=>{const v=typeof process=="object"&&process.env&&process.env.NODE_DEBUG&&/\bsemver\b/i.test(process.env.NODE_DEBUG)?(...s)=>console.error("SEMVER",...s):()=>{};b.exports=v},7342:b=>{const v=/^[0-9]+$/,s=(r,n)=>{const u=v.test(r),p=v.test(n);return u&&p&&(r=+r,n=+n),r===n?0:u&&!p?-1:p&&!u?1:rs(n,r);b.exports={compareIdentifiers:s,rcompareIdentifiers:d}},349:b=>{const v=Object.freeze({loose:!0}),s=Object.freeze({}),d=r=>r?typeof r!="object"?v:r:s;b.exports=d},3259:(b,v,s)=>{const{MAX_SAFE_COMPONENT_LENGTH:d}=s(3325),r=s(4903);v=b.exports={};const n=v.re=[],u=v.src=[],p=v.t={};let l=0;const o=(f,g,i)=>{const m=l++;r(f,m,g),p[f]=m,u[m]=g,n[m]=new RegExp(g,i?"g":void 0)};o("NUMERICIDENTIFIER","0|[1-9]\\d*"),o("NUMERICIDENTIFIERLOOSE","[0-9]+"),o("NONNUMERICIDENTIFIER","\\d*[a-zA-Z-][a-zA-Z0-9-]*"),o("MAINVERSION",`(${u[p.NUMERICIDENTIFIER]})\\.(${u[p.NUMERICIDENTIFIER]})\\.(${u[p.NUMERICIDENTIFIER]})`),o("MAINVERSIONLOOSE",`(${u[p.NUMERICIDENTIFIERLOOSE]})\\.(${u[p.NUMERICIDENTIFIERLOOSE]})\\.(${u[p.NUMERICIDENTIFIERLOOSE]})`),o("PRERELEASEIDENTIFIER",`(?:${u[p.NUMERICIDENTIFIER]}|${u[p.NONNUMERICIDENTIFIER]})`),o("PRERELEASEIDENTIFIERLOOSE",`(?:${u[p.NUMERICIDENTIFIERLOOSE]}|${u[p.NONNUMERICIDENTIFIER]})`),o("PRERELEASE",`(?:-(${u[p.PRERELEASEIDENTIFIER]}(?:\\.${u[p.PRERELEASEIDENTIFIER]})*))`),o("PRERELEASELOOSE",`(?:-?(${u[p.PRERELEASEIDENTIFIERLOOSE]}(?:\\.${u[p.PRERELEASEIDENTIFIERLOOSE]})*))`),o("BUILDIDENTIFIER","[0-9A-Za-z-]+"),o("BUILD",`(?:\\+(${u[p.BUILDIDENTIFIER]}(?:\\.${u[p.BUILDIDENTIFIER]})*))`),o("FULLPLAIN",`v?${u[p.MAINVERSION]}${u[p.PRERELEASE]}?${u[p.BUILD]}?`),o("FULL",`^${u[p.FULLPLAIN]}$`),o("LOOSEPLAIN",`[v=\\s]*${u[p.MAINVERSIONLOOSE]}${u[p.PRERELEASELOOSE]}?${u[p.BUILD]}?`),o("LOOSE",`^${u[p.LOOSEPLAIN]}$`),o("GTLT","((?:<|>)?=?)"),o("XRANGEIDENTIFIERLOOSE",`${u[p.NUMERICIDENTIFIERLOOSE]}|x|X|\\*`),o("XRANGEIDENTIFIER",`${u[p.NUMERICIDENTIFIER]}|x|X|\\*`),o("XRANGEPLAIN",`[v=\\s]*(${u[p.XRANGEIDENTIFIER]})(?:\\.(${u[p.XRANGEIDENTIFIER]})(?:\\.(${u[p.XRANGEIDENTIFIER]})(?:${u[p.PRERELEASE]})?${u[p.BUILD]}?)?)?`),o("XRANGEPLAINLOOSE",`[v=\\s]*(${u[p.XRANGEIDENTIFIERLOOSE]})(?:\\.(${u[p.XRANGEIDENTIFIERLOOSE]})(?:\\.(${u[p.XRANGEIDENTIFIERLOOSE]})(?:${u[p.PRERELEASELOOSE]})?${u[p.BUILD]}?)?)?`),o("XRANGE",`^${u[p.GTLT]}\\s*${u[p.XRANGEPLAIN]}$`),o("XRANGELOOSE",`^${u[p.GTLT]}\\s*${u[p.XRANGEPLAINLOOSE]}$`),o("COERCE",`(^|[^\\d])(\\d{1,${d}})(?:\\.(\\d{1,${d}}))?(?:\\.(\\d{1,${d}}))?(?:$|[^\\d])`),o("COERCERTL",u[p.COERCE],!0),o("LONETILDE","(?:~>?)"),o("TILDETRIM",`(\\s*)${u[p.LONETILDE]}\\s+`,!0),v.tildeTrimReplace="$1~",o("TILDE",`^${u[p.LONETILDE]}${u[p.XRANGEPLAIN]}$`),o("TILDELOOSE",`^${u[p.LONETILDE]}${u[p.XRANGEPLAINLOOSE]}$`),o("LONECARET","(?:\\^)"),o("CARETTRIM",`(\\s*)${u[p.LONECARET]}\\s+`,!0),v.caretTrimReplace="$1^",o("CARET",`^${u[p.LONECARET]}${u[p.XRANGEPLAIN]}$`),o("CARETLOOSE",`^${u[p.LONECARET]}${u[p.XRANGEPLAINLOOSE]}$`),o("COMPARATORLOOSE",`^${u[p.GTLT]}\\s*(${u[p.LOOSEPLAIN]})$|^$`),o("COMPARATOR",`^${u[p.GTLT]}\\s*(${u[p.FULLPLAIN]})$|^$`),o("COMPARATORTRIM",`(\\s*)${u[p.GTLT]}\\s*(${u[p.LOOSEPLAIN]}|${u[p.XRANGEPLAIN]})`,!0),v.comparatorTrimReplace="$1$2$3",o("HYPHENRANGE",`^\\s*(${u[p.XRANGEPLAIN]})\\s+-\\s+(${u[p.XRANGEPLAIN]})\\s*$`),o("HYPHENRANGELOOSE",`^\\s*(${u[p.XRANGEPLAINLOOSE]})\\s+-\\s+(${u[p.XRANGEPLAINLOOSE]})\\s*$`),o("STAR","(<|>)?=?\\s*\\*"),o("GTE0","^\\s*>=\\s*0\\.0\\.0\\s*$"),o("GTE0PRE","^\\s*>=\\s*0\\.0\\.0-0\\s*$")},8951:(b,v,s)=>{const d=s(841),r=(n,u,p)=>d(n,u,">",p);b.exports=r},6024:(b,v,s)=>{const d=s(1459),r=(n,u,p)=>(n=new d(n,p),u=new d(u,p),n.intersects(u,p));b.exports=r},4666:(b,v,s)=>{const d=s(841),r=(n,u,p)=>d(n,u,"<",p);b.exports=r},7530:(b,v,s)=>{const d=s(1630),r=s(1459),n=(u,p,l)=>{let o=null,f=null,g=null;try{g=new r(p,l)}catch(i){return null}return u.forEach(i=>{g.test(i)&&(!o||f.compare(i)===-1)&&(o=i,f=new d(o,l))}),o};b.exports=n},7527:(b,v,s)=>{const d=s(1630),r=s(1459),n=(u,p,l)=>{let o=null,f=null,g=null;try{g=new r(p,l)}catch(i){return null}return u.forEach(i=>{g.test(i)&&(!o||f.compare(i)===1)&&(o=i,f=new d(o,l))}),o};b.exports=n},1346:(b,v,s)=>{const d=s(1630),r=s(1459),n=s(145),u=(p,l)=>{p=new r(p,l);let o=new d("0.0.0");if(p.test(o)||(o=new d("0.0.0-0"),p.test(o)))return o;o=null;for(let f=0;f{const c=new d(m.semver.version);switch(m.operator){case">":c.prerelease.length===0?c.patch++:c.prerelease.push(0),c.raw=c.format();case"":case">=":(!i||n(c,i))&&(i=c);break;case"<":case"<=":break;default:throw new Error(`Unexpected operation: ${m.operator}`)}}),i&&(!o||n(o,i))&&(o=i)}return o&&p.test(o)?o:null};b.exports=u},841:(b,v,s)=>{const d=s(1630),r=s(8325),{ANY:n}=r,u=s(1459),p=s(5374),l=s(145),o=s(5429),f=s(7888),g=s(9778),i=(m,c,h,y)=>{m=new d(m,y),c=new u(c,y);let E,x,T,A,w;switch(h){case">":E=l,x=f,T=o,A=">",w=">=";break;case"<":E=o,x=g,T=l,A="<",w="<=";break;default:throw new TypeError('Must provide a hilo val of "<" or ">"')}if(p(m,c,y))return!1;for(let D=0;D{R.semver===n&&(R=new r(">=0.0.0")),O=O||R,I=I||R,E(R.semver,O.semver,y)?O=R:T(R.semver,I.semver,y)&&(I=R)}),O.operator===A||O.operator===w||(!I.operator||I.operator===A)&&x(m,I.semver))return!1;if(I.operator===w&&T(m,I.semver))return!1}return!0};b.exports=i},2277:(b,v,s)=>{const d=s(5374),r=s(9123);b.exports=(n,u,p)=>{const l=[];let o=null,f=null;const g=n.sort((h,y)=>r(h,y,p));for(const h of g)d(h,u,p)?(f=h,o||(o=h)):(f&&l.push([o,f]),f=null,o=null);o&&l.push([o,null]);const i=[];for(const[h,y]of l)h===y?i.push(h):!y&&h===g[0]?i.push("*"):y?h===g[0]?i.push(`<=${y}`):i.push(`${h} - ${y}`):i.push(`>=${h}`);const m=i.join(" || "),c=typeof u.raw=="string"?u.raw:String(u);return m.length{const d=s(1459),r=s(8325),{ANY:n}=r,u=s(5374),p=s(9123),l=(c,h,y={})=>{if(c===h)return!0;c=new d(c,y),h=new d(h,y);let E=!1;e:for(const x of c.set){for(const T of h.set){const A=g(x,T,y);if(E=E||A!==null,A)continue e}if(E)return!1}return!0},o=[new r(">=0.0.0-0")],f=[new r(">=0.0.0")],g=(c,h,y)=>{if(c===h)return!0;if(c.length===1&&c[0].semver===n){if(h.length===1&&h[0].semver===n)return!0;y.includePrerelease?c=o:c=f}if(h.length===1&&h[0].semver===n){if(y.includePrerelease)return!0;h=f}const E=new Set;let x,T;for(const _ of c)_.operator===">"||_.operator===">="?x=i(x,_,y):_.operator==="<"||_.operator==="<="?T=m(T,_,y):E.add(_.semver);if(E.size>1)return null;let A;if(x&&T){if(A=p(x.semver,T.semver,y),A>0)return null;if(A===0&&(x.operator!==">="||T.operator!=="<="))return null}for(const _ of E){if(x&&!u(_,String(x),y)||T&&!u(_,String(T),y))return null;for(const N of h)if(!u(_,String(N),y))return!1;return!0}let w,D,C,O,I=T&&!y.includePrerelease&&T.semver.prerelease.length?T.semver:!1,R=x&&!y.includePrerelease&&x.semver.prerelease.length?x.semver:!1;I&&I.prerelease.length===1&&T.operator==="<"&&I.prerelease[0]===0&&(I=!1);for(const _ of h){if(O=O||_.operator===">"||_.operator===">=",C=C||_.operator==="<"||_.operator==="<=",x){if(R&&_.semver.prerelease&&_.semver.prerelease.length&&_.semver.major===R.major&&_.semver.minor===R.minor&&_.semver.patch===R.patch&&(R=!1),_.operator===">"||_.operator===">="){if(w=i(x,_,y),w===_&&w!==x)return!1}else if(x.operator===">="&&!u(x.semver,String(_),y))return!1}if(T){if(I&&_.semver.prerelease&&_.semver.prerelease.length&&_.semver.major===I.major&&_.semver.minor===I.minor&&_.semver.patch===I.patch&&(I=!1),_.operator==="<"||_.operator==="<="){if(D=m(T,_,y),D===_&&D!==T)return!1}else if(T.operator==="<="&&!u(T.semver,String(_),y))return!1}if(!_.operator&&(T||x)&&A!==0)return!1}return!(x&&C&&!T&&A!==0||T&&O&&!x&&A!==0||R||I)},i=(c,h,y)=>{if(!c)return h;const E=p(c.semver,h.semver,y);return E>0?c:E<0||h.operator===">"&&c.operator===">="?h:c},m=(c,h,y)=>{if(!c)return h;const E=p(c.semver,h.semver,y);return E<0?c:E>0||h.operator==="<"&&c.operator==="<="?h:c};b.exports=l},6607:(b,v,s)=>{const d=s(1459),r=(n,u)=>new d(n,u).set.map(p=>p.map(l=>l.value).join(" ").trim().split(" "));b.exports=r},3478:(b,v,s)=>{const d=s(1459),r=(n,u)=>{try{return new d(n,u).range||"*"}catch(p){return null}};b.exports=r},9737:()=>{+function(b){"use strict";var v=".dropdown-backdrop",s='[data-toggle="dropdown"]',d=function(l){b(l).on("click.bs.dropdown",this.toggle)};d.VERSION="3.4.1";function r(l){var o=l.attr("data-target");o||(o=l.attr("href"),o=o&&/#[A-Za-z]/.test(o)&&o.replace(/.*(?=#[^\s]*$)/,""));var f=o!=="#"?b(document).find(o):null;return f&&f.length?f:l.parent()}function n(l){l&&l.which===3||(b(v).remove(),b(s).each(function(){var o=b(this),f=r(o),g={relatedTarget:this};f.hasClass("open")&&(l&&l.type=="click"&&/input|textarea/i.test(l.target.tagName)&&b.contains(f[0],l.target)||(f.trigger(l=b.Event("hide.bs.dropdown",g)),!l.isDefaultPrevented()&&(o.attr("aria-expanded","false"),f.removeClass("open").trigger(b.Event("hidden.bs.dropdown",g)))))}))}d.prototype.toggle=function(l){var o=b(this);if(!o.is(".disabled, :disabled")){var f=r(o),g=f.hasClass("open");if(n(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&b(document.createElement("div")).addClass("dropdown-backdrop").insertAfter(b(this)).on("click",n);var i={relatedTarget:this};if(f.trigger(l=b.Event("show.bs.dropdown",i)),l.isDefaultPrevented())return;o.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger(b.Event("shown.bs.dropdown",i))}return!1}},d.prototype.keydown=function(l){if(!(!/(38|40|27|32)/.test(l.which)||/input|textarea/i.test(l.target.tagName))){var o=b(this);if(l.preventDefault(),l.stopPropagation(),!o.is(".disabled, :disabled")){var f=r(o),g=f.hasClass("open");if(!g&&l.which!=27||g&&l.which==27)return l.which==27&&f.find(s).trigger("focus"),o.trigger("click");var i=" li:not(.disabled):visible a",m=f.find(".dropdown-menu"+i);if(m.length){var c=m.index(l.target);l.which==38&&c>0&&c--,l.which==40&&c{+function(b){"use strict";var v=function(r,n){this.init("popover",r,n)};if(!b.fn.tooltip)throw new Error("Popover requires tooltip.js");v.VERSION="3.4.1",v.DEFAULTS=b.extend({},b.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:''}),v.prototype=b.extend({},b.fn.tooltip.Constructor.prototype),v.prototype.constructor=v,v.prototype.getDefaults=function(){return v.DEFAULTS},v.prototype.setContent=function(){var r=this.tip(),n=this.getTitle(),u=this.getContent();if(this.options.html){var p=typeof u;this.options.sanitize&&(n=this.sanitizeHtml(n),p==="string"&&(u=this.sanitizeHtml(u))),r.find(".popover-title").html(n),r.find(".popover-content").children().detach().end()[p==="string"?"html":"append"](u)}else r.find(".popover-title").text(n),r.find(".popover-content").children().detach().end().text(u);r.removeClass("fade top bottom left right in"),r.find(".popover-title").html()||r.find(".popover-title").hide()},v.prototype.hasContent=function(){return this.getTitle()||this.getContent()},v.prototype.getContent=function(){var r=this.$element,n=this.options;return r.attr("data-content")||(typeof n.content=="function"?n.content.call(r[0]):n.content)},v.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};function s(r){return this.each(function(){var n=b(this),u=n.data("bs.popover"),p=typeof r=="object"&&r;!u&&/destroy|hide/.test(r)||(u||n.data("bs.popover",u=new v(this,p)),typeof r=="string"&&u[r]())})}var d=b.fn.popover;b.fn.popover=s,b.fn.popover.Constructor=v,b.fn.popover.noConflict=function(){return b.fn.popover=d,this}}(jQuery)},3497:()=>{+function(b){"use strict";function v(r,n){this.$body=b(document.body),this.$scrollElement=b(r).is(document.body)?b(window):b(r),this.options=b.extend({},v.DEFAULTS,n),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",b.proxy(this.process,this)),this.refresh(),this.process()}v.VERSION="3.4.1",v.DEFAULTS={offset:10},v.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},v.prototype.refresh=function(){var r=this,n="offset",u=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),b.isWindow(this.$scrollElement[0])||(n="position",u=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var p=b(this),l=p.data("target")||p.attr("href"),o=/^#./.test(l)&&b(l);return o&&o.length&&o.is(":visible")&&[[o[n]().top+u,l]]||null}).sort(function(p,l){return p[0]-l[0]}).each(function(){r.offsets.push(this[0]),r.targets.push(this[1])})},v.prototype.process=function(){var r=this.$scrollElement.scrollTop()+this.options.offset,n=this.getScrollHeight(),u=this.options.offset+n-this.$scrollElement.height(),p=this.offsets,l=this.targets,o=this.activeTarget,f;if(this.scrollHeight!=n&&this.refresh(),r>=u)return o!=(f=l[l.length-1])&&this.activate(f);if(o&&r=p[f]&&(p[f+1]===void 0||r{+function(b){"use strict";var v=function(n){this.element=b(n)};v.VERSION="3.4.1",v.TRANSITION_DURATION=150,v.prototype.show=function(){var n=this.element,u=n.closest("ul:not(.dropdown-menu)"),p=n.data("target");if(p||(p=n.attr("href"),p=p&&p.replace(/.*(?=#[^\s]*$)/,"")),!n.parent("li").hasClass("active")){var l=u.find(".active:last a"),o=b.Event("hide.bs.tab",{relatedTarget:n[0]}),f=b.Event("show.bs.tab",{relatedTarget:l[0]});if(l.trigger(o),n.trigger(f),!(f.isDefaultPrevented()||o.isDefaultPrevented())){var g=b(document).find(p);this.activate(n.closest("li"),u),this.activate(g,g.parent(),function(){l.trigger({type:"hidden.bs.tab",relatedTarget:n[0]}),n.trigger({type:"shown.bs.tab",relatedTarget:l[0]})})}}},v.prototype.activate=function(n,u,p){var l=u.find("> .active"),o=p&&b.support.transition&&(l.length&&l.hasClass("fade")||!!u.find("> .fade").length);function f(){l.removeClass("active").find("> .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),n.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),o?(n[0].offsetWidth,n.addClass("in")):n.removeClass("fade"),n.parent(".dropdown-menu").length&&n.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),p&&p()}l.length&&o?l.one("bsTransitionEnd",f).emulateTransitionEnd(v.TRANSITION_DURATION):f(),l.removeClass("in")};function s(n){return this.each(function(){var u=b(this),p=u.data("bs.tab");p||u.data("bs.tab",p=new v(this)),typeof n=="string"&&p[n]()})}var d=b.fn.tab;b.fn.tab=s,b.fn.tab.Constructor=v,b.fn.tab.noConflict=function(){return b.fn.tab=d,this};var r=function(n){n.preventDefault(),s.call(b(this),"show")};b(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',r).on("click.bs.tab.data-api",'[data-toggle="pill"]',r)}(jQuery)},6278:()=>{+function(b){"use strict";var v=["sanitize","whiteList","sanitizeFn"],s=["background","cite","href","itemtype","longdesc","poster","src","xlink:href"],d=/^aria-[\w-]*$/i,r={"*":["class","dir","id","lang","role",d],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},n=/^(?:(?:https?|mailto|ftp|tel|file):|[^&:/?#]*(?:[/?#]|$))/gi,u=/^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[a-z0-9+/]+=*$/i;function p(i,m){var c=i.nodeName.toLowerCase();if(b.inArray(c,m)!==-1)return b.inArray(c,s)!==-1?Boolean(i.nodeValue.match(n)||i.nodeValue.match(u)):!0;for(var h=b(m).filter(function(x,T){return T instanceof RegExp}),y=0,E=h.length;y
',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0},sanitize:!0,sanitizeFn:null,whiteList:r},o.prototype.init=function(i,m,c){if(this.enabled=!0,this.type=i,this.$element=b(m),this.options=this.getOptions(c),this.$viewport=this.options.viewport&&b(document).find(b.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var h=this.options.trigger.split(" "),y=h.length;y--;){var E=h[y];if(E=="click")this.$element.on("click."+this.type,this.options.selector,b.proxy(this.toggle,this));else if(E!="manual"){var x=E=="hover"?"mouseenter":"focusin",T=E=="hover"?"mouseleave":"focusout";this.$element.on(x+"."+this.type,this.options.selector,b.proxy(this.enter,this)),this.$element.on(T+"."+this.type,this.options.selector,b.proxy(this.leave,this))}}this.options.selector?this._options=b.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},o.prototype.getDefaults=function(){return o.DEFAULTS},o.prototype.getOptions=function(i){var m=this.$element.data();for(var c in m)m.hasOwnProperty(c)&&b.inArray(c,v)!==-1&&delete m[c];return i=b.extend({},this.getDefaults(),m,i),i.delay&&typeof i.delay=="number"&&(i.delay={show:i.delay,hide:i.delay}),i.sanitize&&(i.template=l(i.template,i.whiteList,i.sanitizeFn)),i},o.prototype.getDelegateOptions=function(){var i={},m=this.getDefaults();return this._options&&b.each(this._options,function(c,h){m[c]!=h&&(i[c]=h)}),i},o.prototype.enter=function(i){var m=i instanceof this.constructor?i:b(i.currentTarget).data("bs."+this.type);if(m||(m=new this.constructor(i.currentTarget,this.getDelegateOptions()),b(i.currentTarget).data("bs."+this.type,m)),i instanceof b.Event&&(m.inState[i.type=="focusin"?"focus":"hover"]=!0),m.tip().hasClass("in")||m.hoverState=="in"){m.hoverState="in";return}if(clearTimeout(m.timeout),m.hoverState="in",!m.options.delay||!m.options.delay.show)return m.show();m.timeout=setTimeout(function(){m.hoverState=="in"&&m.show()},m.options.delay.show)},o.prototype.isInStateTrue=function(){for(var i in this.inState)if(this.inState[i])return!0;return!1},o.prototype.leave=function(i){var m=i instanceof this.constructor?i:b(i.currentTarget).data("bs."+this.type);if(m||(m=new this.constructor(i.currentTarget,this.getDelegateOptions()),b(i.currentTarget).data("bs."+this.type,m)),i instanceof b.Event&&(m.inState[i.type=="focusout"?"focus":"hover"]=!1),!m.isInStateTrue()){if(clearTimeout(m.timeout),m.hoverState="out",!m.options.delay||!m.options.delay.hide)return m.hide();m.timeout=setTimeout(function(){m.hoverState=="out"&&m.hide()},m.options.delay.hide)}},o.prototype.show=function(){var i=b.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(i);var m=b.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(i.isDefaultPrevented()||!m)return;var c=this,h=this.tip(),y=this.getUID(this.type);this.setContent(),h.attr("id",y),this.$element.attr("aria-describedby",y),this.options.animation&&h.addClass("fade");var E=typeof this.options.placement=="function"?this.options.placement.call(this,h[0],this.$element[0]):this.options.placement,x=/\s?auto?\s?/i,T=x.test(E);T&&(E=E.replace(x,"")||"top"),h.detach().css({top:0,left:0,display:"block"}).addClass(E).data("bs."+this.type,this),this.options.container?h.appendTo(b(document).find(this.options.container)):h.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var A=this.getPosition(),w=h[0].offsetWidth,D=h[0].offsetHeight;if(T){var C=E,O=this.getPosition(this.$viewport);E=E=="bottom"&&A.bottom+D>O.bottom?"top":E=="top"&&A.top-DO.width?"left":E=="left"&&A.left-wx.top+x.height&&(y.top=x.top+x.height-A)}else{var w=m.left-E,D=m.left+E+c;wx.right&&(y.left=x.left+x.width-D)}return y},o.prototype.getTitle=function(){var i,m=this.$element,c=this.options;return i=m.attr("data-original-title")||(typeof c.title=="function"?c.title.call(m[0]):c.title),i},o.prototype.getUID=function(i){do i+=~~(Math.random()*1e6);while(document.getElementById(i));return i},o.prototype.tip=function(){if(!this.$tip&&(this.$tip=b(this.options.template),this.$tip.length!=1))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},o.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},o.prototype.enable=function(){this.enabled=!0},o.prototype.disable=function(){this.enabled=!1},o.prototype.toggleEnabled=function(){this.enabled=!this.enabled},o.prototype.toggle=function(i){var m=this;i&&(m=b(i.currentTarget).data("bs."+this.type),m||(m=new this.constructor(i.currentTarget,this.getDelegateOptions()),b(i.currentTarget).data("bs."+this.type,m))),i?(m.inState.click=!m.inState.click,m.isInStateTrue()?m.enter(m):m.leave(m)):m.tip().hasClass("in")?m.leave(m):m.enter(m)},o.prototype.destroy=function(){var i=this;clearTimeout(this.timeout),this.hide(function(){i.$element.off("."+i.type).removeData("bs."+i.type),i.$tip&&i.$tip.detach(),i.$tip=null,i.$arrow=null,i.$viewport=null,i.$element=null})},o.prototype.sanitizeHtml=function(i){return l(i,this.options.whiteList,this.options.sanitizeFn)};function f(i){return this.each(function(){var m=b(this),c=m.data("bs.tooltip"),h=typeof i=="object"&&i;!c&&/destroy|hide/.test(i)||(c||m.data("bs.tooltip",c=new o(this,h)),typeof i=="string"&&c[i]())})}var g=b.fn.tooltip;b.fn.tooltip=f,b.fn.tooltip.Constructor=o,b.fn.tooltip.noConflict=function(){return b.fn.tooltip=g,this}}(jQuery)},2027:b=>{var v=function(){this.Diff_Timeout=1,this.Diff_EditCost=4,this.Match_Threshold=.5,this.Match_Distance=1e3,this.Patch_DeleteThreshold=.5,this.Patch_Margin=4,this.Match_MaxBits=32},s=-1,d=1,r=0;v.Diff=function(n,u){return[n,u]},v.prototype.diff_main=function(n,u,p,l){typeof l=="undefined"&&(this.Diff_Timeout<=0?l=Number.MAX_VALUE:l=new Date().getTime()+this.Diff_Timeout*1e3);var o=l;if(n==null||u==null)throw new Error("Null input. (diff_main)");if(n==u)return n?[new v.Diff(r,n)]:[];typeof p=="undefined"&&(p=!0);var f=p,g=this.diff_commonPrefix(n,u),i=n.substring(0,g);n=n.substring(g),u=u.substring(g),g=this.diff_commonSuffix(n,u);var m=n.substring(n.length-g);n=n.substring(0,n.length-g),u=u.substring(0,u.length-g);var c=this.diff_compute_(n,u,f,o);return i&&c.unshift(new v.Diff(r,i)),m&&c.push(new v.Diff(r,m)),this.diff_cleanupMerge(c),c},v.prototype.diff_compute_=function(n,u,p,l){var o;if(!n)return[new v.Diff(d,u)];if(!u)return[new v.Diff(s,n)];var f=n.length>u.length?n:u,g=n.length>u.length?u:n,i=f.indexOf(g);if(i!=-1)return o=[new v.Diff(d,f.substring(0,i)),new v.Diff(r,g),new v.Diff(d,f.substring(i+g.length))],n.length>u.length&&(o[0][0]=o[2][0]=s),o;if(g.length==1)return[new v.Diff(s,n),new v.Diff(d,u)];var m=this.diff_halfMatch_(n,u);if(m){var c=m[0],h=m[1],y=m[2],E=m[3],x=m[4],T=this.diff_main(c,y,p,l),A=this.diff_main(h,E,p,l);return T.concat([new v.Diff(r,x)],A)}return p&&n.length>100&&u.length>100?this.diff_lineMode_(n,u,l):this.diff_bisect_(n,u,l)},v.prototype.diff_lineMode_=function(n,u,p){var l=this.diff_linesToChars_(n,u);n=l.chars1,u=l.chars2;var o=l.lineArray,f=this.diff_main(n,u,!1,p);this.diff_charsToLines_(f,o),this.diff_cleanupSemantic(f),f.push(new v.Diff(r,""));for(var g=0,i=0,m=0,c="",h="";g=1&&m>=1){f.splice(g-i-m,i+m),g=g-i-m;for(var y=this.diff_main(c,h,!1,p),E=y.length-1;E>=0;E--)f.splice(g,0,y[E]);g=g+y.length}m=0,i=0,c="",h="";break}g++}return f.pop(),f},v.prototype.diff_bisect_=function(n,u,p){for(var l=n.length,o=u.length,f=Math.ceil((l+o)/2),g=f,i=2*f,m=new Array(i),c=new Array(i),h=0;hp);D++){for(var C=-D+x;C<=D-T;C+=2){var O=g+C,I;C==-D||C!=D&&m[O-1]l)T+=2;else if(R>o)x+=2;else if(E){var _=g+y-C;if(_>=0&&_=N)return this.diff_bisectSplit_(n,u,I,R,p)}}}for(var B=-D+A;B<=D-w;B+=2){var _=g+B,N;B==-D||B!=D&&c[_-1]l)w+=2;else if(W>o)A+=2;else if(!E){var O=g+y-B;if(O>=0&&O=N)return this.diff_bisectSplit_(n,u,I,R,p)}}}}return[new v.Diff(s,n),new v.Diff(d,u)]},v.prototype.diff_bisectSplit_=function(n,u,p,l,o){var f=n.substring(0,p),g=u.substring(0,l),i=n.substring(p),m=u.substring(l),c=this.diff_main(f,g,!1,o),h=this.diff_main(i,m,!1,o);return c.concat(h)},v.prototype.diff_linesToChars_=function(n,u){var p=[],l={};p[0]="";function o(m){for(var c="",h=0,y=-1,E=p.length;yl?n=n.substring(p-l):pu.length?n:u,l=n.length>u.length?u:n;if(p.length<4||l.length*2=T.length?[I,R,_,N,O]:null}var g=f(p,l,Math.ceil(p.length/4)),i=f(p,l,Math.ceil(p.length/2)),m;if(!g&&!i)return null;i?g?m=g[4].length>i[4].length?g:i:m=i:m=g;var c,h,y,E;n.length>u.length?(c=m[0],h=m[1],y=m[2],E=m[3]):(y=m[0],E=m[1],c=m[2],h=m[3]);var x=m[4];return[c,h,y,E,x]},v.prototype.diff_cleanupSemantic=function(n){for(var u=!1,p=[],l=0,o=null,f=0,g=0,i=0,m=0,c=0;f0?p[l-1]:-1,g=0,i=0,m=0,c=0,o=null,u=!0)),f++;for(u&&this.diff_cleanupMerge(n),this.diff_cleanupSemanticLossless(n),f=1;f=x?(E>=h.length/2||E>=y.length/2)&&(n.splice(f,0,new v.Diff(r,y.substring(0,E))),n[f-1][1]=h.substring(0,h.length-E),n[f+1][1]=y.substring(E),f++):(x>=h.length/2||x>=y.length/2)&&(n.splice(f,0,new v.Diff(r,h.substring(0,x))),n[f-1][0]=d,n[f-1][1]=y.substring(0,y.length-x),n[f+1][0]=s,n[f+1][1]=h.substring(x),f++),f++}f++}},v.prototype.diff_cleanupSemanticLossless=function(n){function u(x,T){if(!x||!T)return 6;var A=x.charAt(x.length-1),w=T.charAt(0),D=A.match(v.nonAlphaNumericRegex_),C=w.match(v.nonAlphaNumericRegex_),O=D&&A.match(v.whitespaceRegex_),I=C&&w.match(v.whitespaceRegex_),R=O&&A.match(v.linebreakRegex_),_=I&&w.match(v.linebreakRegex_),N=R&&x.match(v.blanklineEndRegex_),B=_&&T.match(v.blanklineStartRegex_);return N||B?5:R||_?4:D&&!O&&I?3:O||I?2:D||C?1:0}for(var p=1;p=y&&(y=E,m=l,c=o,h=f)}n[p-1][1]!=m&&(m?n[p-1][1]=m:(n.splice(p-1,1),p--),n[p][1]=c,h?n[p+1][1]=h:(n.splice(p+1,1),p--))}p++}},v.nonAlphaNumericRegex_=/[^a-zA-Z0-9]/,v.whitespaceRegex_=/\s/,v.linebreakRegex_=/[\r\n]/,v.blanklineEndRegex_=/\n\r?\n$/,v.blanklineStartRegex_=/^\r?\n\r?\n/,v.prototype.diff_cleanupEfficiency=function(n){for(var u=!1,p=[],l=0,o=null,f=0,g=!1,i=!1,m=!1,c=!1;f0?p[l-1]:-1,m=c=!1),u=!0)),f++;u&&this.diff_cleanupMerge(n)},v.prototype.diff_cleanupMerge=function(n){n.push(new v.Diff(r,""));for(var u=0,p=0,l=0,o="",f="",g;u1?(p!==0&&l!==0&&(g=this.diff_commonPrefix(f,o),g!==0&&(u-p-l>0&&n[u-p-l-1][0]==r?n[u-p-l-1][1]+=f.substring(0,g):(n.splice(0,0,new v.Diff(r,f.substring(0,g))),u++),f=f.substring(g),o=o.substring(g)),g=this.diff_commonSuffix(f,o),g!==0&&(n[u][1]=f.substring(f.length-g)+n[u][1],f=f.substring(0,f.length-g),o=o.substring(0,o.length-g))),u-=p+l,n.splice(u,p+l),o.length&&(n.splice(u,0,new v.Diff(s,o)),u++),f.length&&(n.splice(u,0,new v.Diff(d,f)),u++),u++):u!==0&&n[u-1][0]==r?(n[u-1][1]+=n[u][1],n.splice(u,1)):u++,l=0,p=0,o="",f="";break}n[n.length-1][1]===""&&n.pop();var i=!1;for(u=1;uu));g++)o=p,f=l;return n.length!=g&&n[g][0]===s?f:f+(u-o)},v.prototype.diff_prettyHtml=function(n){for(var u=[],p=/&/g,l=//g,f=/\n/g,g=0;g");switch(i){case d:u[g]=''+c+"";break;case s:u[g]=''+c+"";break;case r:u[g]=""+c+"";break}}return u.join("")},v.prototype.diff_text1=function(n){for(var u=[],p=0;pthis.Match_MaxBits)throw new Error("Pattern too long for this browser.");var l=this.match_alphabet_(u),o=this;function f(I,R){var _=I/u.length,N=Math.abs(p-R);return o.Match_Distance?_+N/o.Match_Distance:N?1:_}var g=this.Match_Threshold,i=n.indexOf(u,p);i!=-1&&(g=Math.min(f(0,i),g),i=n.lastIndexOf(u,p+u.length),i!=-1&&(g=Math.min(f(0,i),g)));var m=1<=T;D--){var C=l[n.charAt(D-1)];if(x===0?w[D]=(w[D+1]<<1|1)&C:w[D]=(w[D+1]<<1|1)&C|((E[D+1]|E[D])<<1|1)|E[D+1],w[D]&m){var O=f(x,D-1);if(O<=g)if(g=O,i=D-1,i>p)T=Math.max(1,2*p-i);else break}}if(f(x+1,p)>g)break;E=w}return i},v.prototype.match_alphabet_=function(n){for(var u={},p=0;p2&&(this.diff_cleanupSemantic(o),this.diff_cleanupEfficiency(o));else if(n&&typeof n=="object"&&typeof u=="undefined"&&typeof p=="undefined")o=n,l=this.diff_text1(o);else if(typeof n=="string"&&u&&typeof u=="object"&&typeof p=="undefined")l=n,o=u;else if(typeof n=="string"&&typeof u=="string"&&p&&typeof p=="object")l=n,o=p;else throw new Error("Unknown call format to patch_make.");if(o.length===0)return[];for(var f=[],g=new v.patch_obj,i=0,m=0,c=0,h=l,y=l,E=0;E=2*this.Patch_Margin&&i&&(this.patch_addContext_(g,h),f.push(g),g=new v.patch_obj,i=0,h=y,m=c);break}x!==d&&(m+=T.length),x!==s&&(c+=T.length)}return i&&(this.patch_addContext_(g,h),f.push(g)),f},v.prototype.patch_deepCopy=function(n){for(var u=[],p=0;pthis.Match_MaxBits?(m=this.match_main(u,i.substring(0,this.Match_MaxBits),g),m!=-1&&(c=this.match_main(u,i.substring(i.length-this.Match_MaxBits),g+i.length-this.Match_MaxBits),(c==-1||m>=c)&&(m=-1))):m=this.match_main(u,i,g),m==-1)o[f]=!1,l-=n[f].length2-n[f].length1;else{o[f]=!0,l=m-g;var h;if(c==-1?h=u.substring(m,m+i.length):h=u.substring(m,c+this.Match_MaxBits),i==h)u=u.substring(0,m)+this.diff_text2(n[f].diffs)+u.substring(m+i.length);else{var y=this.diff_main(i,h,!1);if(i.length>this.Match_MaxBits&&this.diff_levenshtein(y)/i.length>this.Patch_DeleteThreshold)o[f]=!1;else{this.diff_cleanupSemanticLossless(y);for(var E=0,x,T=0;Tf[0][1].length){var g=u-f[0][1].length;f[0][1]=p.substring(f[0][1].length)+f[0][1],o.start1-=g,o.start2-=g,o.length1+=g,o.length2+=g}if(o=n[n.length-1],f=o.diffs,f.length==0||f[f.length-1][0]!=r)f.push(new v.Diff(r,p)),o.length1+=u,o.length2+=u;else if(u>f[f.length-1][1].length){var g=u-f[f.length-1][1].length;f[f.length-1][1]+=p.substring(0,g),o.length1+=g,o.length2+=g}return p},v.prototype.patch_splitMax=function(n){for(var u=this.Match_MaxBits,p=0;p2*u?(i.length1+=h.length,o+=h.length,m=!1,i.diffs.push(new v.Diff(c,h)),l.diffs.shift()):(h=h.substring(0,u-i.length1-this.Patch_Margin),i.length1+=h.length,o+=h.length,c===r?(i.length2+=h.length,f+=h.length):m=!1,i.diffs.push(new v.Diff(c,h)),h==l.diffs[0][1]?l.diffs.shift():l.diffs[0][1]=l.diffs[0][1].substring(h.length))}g=this.diff_text2(i.diffs),g=g.substring(g.length-this.Patch_Margin);var y=this.diff_text1(l.diffs).substring(0,this.Patch_Margin);y!==""&&(i.length1+=y.length,i.length2+=y.length,i.diffs.length!==0&&i.diffs[i.diffs.length-1][0]===r?i.diffs[i.diffs.length-1][1]+=y:i.diffs.push(new v.Diff(r,y))),m||n.splice(++p,0,i)}}},v.prototype.patch_toText=function(n){for(var u=[],p=0;p= 2.0.0-beta.1",7:">= 4.0.0 <4.3.0",8:">= 4.3.0"};o.REVISION_CHANGES=m;var y="[object Object]";r.prototype={constructor:r,logger:i.default,log:i.default.log,registerHelper:function(x,C){if(u.toString.call(x)===y){if(C)throw new l.default("Arg not supported with multiple helpers");u.extend(this.helpers,x)}else this.helpers[x]=C},unregisterHelper:function(x){delete this.helpers[x]},registerPartial:function(x,C){if(u.toString.call(x)===y)u.extend(this.partials,x);else{if(typeof C=="undefined")throw new l.default('Attempting to register a partial called "'+x+'" as undefined');this.partials[x]=C}},unregisterPartial:function(x){delete this.partials[x]},registerDecorator:function(x,C){if(u.toString.call(x)===y){if(C)throw new l.default("Arg not supported with multiple decorators");u.extend(this.decorators,x)}else this.decorators[x]=C},unregisterDecorator:function(x){delete this.decorators[x]},resetLoggedPropertyAccesses:function(){v.resetLoggedProperties()}};var T=i.default.log;o.log=T,o.createFrame=u.createFrame,o.logger=i.default},function(E,o){"use strict";function d(m){return g[m]}function r(m){for(var y=1;y":">",'"':""","'":"'","`":"`","=":"="},i=/[&<>"'`=]/g,v=/[&<>"'`=]/,h=Object.prototype.toString;o.toString=h;var p=function(m){return typeof m=="function"};p(/x/)&&(o.isFunction=p=function(m){return typeof m=="function"&&h.call(m)==="[object Function]"}),o.isFunction=p;var A=Array.isArray||function(m){return!(!m||typeof m!="object")&&h.call(m)==="[object Array]"};o.isArray=A},function(E,o,d){"use strict";function r(c,l){var s=l&&l.loc,f=void 0,g=void 0,i=void 0,v=void 0;s&&(f=s.start.line,g=s.end.line,i=s.start.column,v=s.end.column,c+=" - "+f+":"+i);for(var h=Error.prototype.constructor.call(this,c),p=0;p0?(c.ids&&(c.ids=[c.name]),n.helpers.each(u,c)):l(this);if(c.data&&c.ids){var f=r.createFrame(c.data);f.contextPath=r.appendContextPath(c.data.contextPath,c.name),c={data:f}}return s(u,c)})},E.exports=o.default},function(E,o,d){(function(r){"use strict";var n=d(13).default,u=d(1).default;o.__esModule=!0;var c=d(5),l=d(6),s=u(l);o.default=function(f){f.registerHelper("each",function(g,i){function v(R,N,b){y&&(y.key=R,y.index=N,y.first=N===0,y.last=!!b,T&&(y.contextPath=T+R)),m+=h(g[R],{data:y,blockParams:c.blockParams([g[R],R],[T+R,null])})}if(!i)throw new s.default("Must pass iterator to #each");var h=i.fn,p=i.inverse,A=0,m="",y=void 0,T=void 0;if(i.data&&i.ids&&(T=c.appendContextPath(i.data.contextPath,i.ids[0])+"."),c.isFunction(g)&&(g=g.call(this)),i.data&&(y=c.createFrame(i.data)),g&&typeof g=="object")if(c.isArray(g))for(var x=g.length;A=0?c:parseInt(u,10)}return u},log:function(u){if(u=n.lookupLevel(u),typeof console!="undefined"&&n.lookupLevel(n.level)<=u){var c=n.methodMap[u];console[c]||(c="log");for(var l=arguments.length,s=Array(l>1?l-1:0),f=1;f= 2.0.0-beta.1",7:">= 4.0.0 <4.3.0",8:">= 4.3.0"};s.REVISION_CHANGES=E;var x="[object Object]";r.prototype={constructor:r,logger:i.default,log:i.default.log,registerHelper:function(A,w){if(u.toString.call(A)===x){if(w)throw new l.default("Arg not supported with multiple helpers");u.extend(this.helpers,A)}else this.helpers[A]=w},unregisterHelper:function(A){delete this.helpers[A]},registerPartial:function(A,w){if(u.toString.call(A)===x)u.extend(this.partials,A);else{if(typeof w=="undefined")throw new l.default('Attempting to register a partial called "'+A+'" as undefined');this.partials[A]=w}},unregisterPartial:function(A){delete this.partials[A]},registerDecorator:function(A,w){if(u.toString.call(A)===x){if(w)throw new l.default("Arg not supported with multiple decorators");u.extend(this.decorators,A)}else this.decorators[A]=w},unregisterDecorator:function(A){delete this.decorators[A]},resetLoggedPropertyAccesses:function(){m.resetLoggedProperties()}};var T=i.default.log;s.log=T,s.createFrame=u.createFrame,s.logger=i.default},function(v,s){"use strict";function d(E){return g[E]}function r(E){for(var x=1;x":">",'"':""","'":"'","`":"`","=":"="},i=/[&<>"'`=]/g,m=/[&<>"'`=]/,c=Object.prototype.toString;s.toString=c;var h=function(E){return typeof E=="function"};h(/x/)&&(s.isFunction=h=function(E){return typeof E=="function"&&c.call(E)==="[object Function]"}),s.isFunction=h;var y=Array.isArray||function(E){return!(!E||typeof E!="object")&&c.call(E)==="[object Array]"};s.isArray=y},function(v,s,d){"use strict";function r(p,l){var o=l&&l.loc,f=void 0,g=void 0,i=void 0,m=void 0;o&&(f=o.start.line,g=o.end.line,i=o.start.column,m=o.end.column,p+=" - "+f+":"+i);for(var c=Error.prototype.constructor.call(this,p),h=0;h0?(p.ids&&(p.ids=[p.name]),n.helpers.each(u,p)):l(this);if(p.data&&p.ids){var f=r.createFrame(p.data);f.contextPath=r.appendContextPath(p.data.contextPath,p.name),p={data:f}}return o(u,p)})},v.exports=s.default},function(v,s,d){(function(r){"use strict";var n=d(13).default,u=d(1).default;s.__esModule=!0;var p=d(5),l=d(6),o=u(l);s.default=function(f){f.registerHelper("each",function(g,i){function m(O,I,R){x&&(x.key=O,x.index=I,x.first=I===0,x.last=!!R,T&&(x.contextPath=T+O)),E+=c(g[O],{data:x,blockParams:p.blockParams([g[O],O],[T+O,null])})}if(!i)throw new o.default("Must pass iterator to #each");var c=i.fn,h=i.inverse,y=0,E="",x=void 0,T=void 0;if(i.data&&i.ids&&(T=p.appendContextPath(i.data.contextPath,i.ids[0])+"."),p.isFunction(g)&&(g=g.call(this)),i.data&&(x=p.createFrame(i.data)),g&&typeof g=="object")if(p.isArray(g))for(var A=g.length;y=0?p:parseInt(u,10)}return u},log:function(u){if(u=n.lookupLevel(u),typeof console!="undefined"&&n.lookupLevel(n.level)<=u){var p=n.methodMap[u];console[p]||(p="log");for(var l=arguments.length,o=Array(l>1?l-1:0),f=1;f=D.LAST_COMPATIBLE_COMPILER_REVISION&&P<=D.COMPILER_REVISION)){if(P2&&L.push("'"+this.terminals_[N]+"'");F=this.lexer.showPosition?"Parse error on line "+(p+1)+`: +See https://handlebarsjs.com/api-reference/runtime-options.html#options-to-control-prototype-access for details`))}function l(){f(h).forEach(function(y){delete h[y]})}var o=d(34).default,f=d(13).default,g=d(3).default;s.__esModule=!0,s.createProtoAccessControl=r,s.resultIsAllowed=n,s.resetLoggedProperties=l;var i=d(36),m=d(32),c=g(m),h=o(null)},function(v,s,d){v.exports={default:d(35),__esModule:!0}},function(v,s,d){var r=d(9);v.exports=function(n,u){return r.create(n,u)}},function(v,s,d){"use strict";function r(){for(var p=arguments.length,l=Array(p),o=0;o=D.LAST_COMPATIBLE_COMPILER_REVISION&&_<=D.COMPILER_REVISION)){if(_2&&N.push("'"+this.terminals_[I]+"'");W=this.lexer.showPosition?"Parse error on line "+(h+1)+`: `+this.lexer.showPosition()+` -Expecting `+L.join(", ")+", got '"+(this.terminals_[x]||x)+"'":"Parse error on line "+(p+1)+": Unexpected "+(x==1?"end of input":"'"+(this.terminals_[x]||x)+"'"),this.parseError(F,{text:this.lexer.match,token:this.terminals_[x]||x,line:this.lexer.yylineno,loc:y,expected:L})}}if(_[0]instanceof Array&&_.length>1)throw new Error("Parse Error: multiple actions possible at state: "+D+", token: "+x);switch(_[0]){case 1:f.push(x),g.push(this.lexer.yytext),i.push(this.lexer.yylloc),f.push(_[1]),x=null,C?(x=C,C=null):(A=this.lexer.yyleng,h=this.lexer.yytext,p=this.lexer.yylineno,y=this.lexer.yylloc,m>0&&m--);break;case 2:if(b=this.productions_[_[1]][1],k.$=g[g.length-b],k._$={first_line:i[i.length-(b||1)].first_line,last_line:i[i.length-1].last_line,first_column:i[i.length-(b||1)].first_column,last_column:i[i.length-1].last_column},T&&(k._$.range=[i[i.length-(b||1)].range[0],i[i.length-1].range[1]]),R=this.performAction.call(k,h,A,p,this.yy,_[1],g,i),typeof R!="undefined")return R;b&&(f=f.slice(0,-1*b*2),g=g.slice(0,-1*b),i=i.slice(0,-1*b)),f.push(this.productions_[_[1]][0]),g.push(k.$),i.push(k._$),P=v[f[f.length-2]][f[f.length-1]],f.push(P);break;case 3:return!0}}return!0}},u=function(){var c={EOF:1,parseError:function(l,s){if(!this.yy.parser)throw new Error(l);this.yy.parser.parseError(l,s)},setInput:function(l){return this._input=l,this._more=this._less=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var l=this._input[0];this.yytext+=l,this.yyleng++,this.offset++,this.match+=l,this.matched+=l;var s=l.match(/(?:\r\n?|\n).*/g);return s?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),l},unput:function(l){var s=l.length,f=l.split(/(?:\r\n?|\n)/g);this._input=l+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-s-1),this.offset-=s;var g=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),f.length-1&&(this.yylineno-=f.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:f?(f.length===g.length?this.yylloc.first_column:0)+g[g.length-f.length].length-f[0].length:this.yylloc.first_column-s},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-s]),this},more:function(){return this._more=!0,this},less:function(l){this.unput(this.match.slice(l))},pastInput:function(){var l=this.matched.substr(0,this.matched.length-this.match.length);return(l.length>20?"...":"")+l.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var l=this.match;return l.length<20&&(l+=this._input.substr(0,20-l.length)),(l.substr(0,20)+(l.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var l=this.pastInput(),s=new Array(l.length+1).join("-");return l+this.upcomingInput()+` -`+s+"^"},next:function(){if(this.done)return this.EOF;this._input||(this.done=!0);var l,s,f,g,i;this._more||(this.yytext="",this.match="");for(var v=this._currentRules(),h=0;hs[0].length)||(s=f,g=h,this.options.flex));h++);return s?(i=s[0].match(/(?:\r\n?|\n).*/g),i&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+s[0].length},this.yytext+=s[0],this.match+=s[0],this.matches=s,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._input=this._input.slice(s[0].length),this.matched+=s[0],l=this.performAction.call(this,this.yy,this,v[g],this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),l||void 0):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text. -`+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var l=this.next();return typeof l!="undefined"?l:this.lex()},begin:function(l){this.conditionStack.push(l)},popState:function(){return this.conditionStack.pop()},_currentRules:function(){return this.conditions[this.conditionStack[this.conditionStack.length-1]].rules},topState:function(){return this.conditionStack[this.conditionStack.length-2]},pushState:function(l){this.begin(l)}};return c.options={},c.performAction=function(l,s,f,g){function i(v,h){return s.yytext=s.yytext.substring(v,s.yyleng-h+v)}switch(f){case 0:if(s.yytext.slice(-2)==="\\\\"?(i(0,1),this.begin("mu")):s.yytext.slice(-1)==="\\"?(i(0,1),this.begin("emu")):this.begin("mu"),s.yytext)return 15;break;case 1:return 15;case 2:return this.popState(),15;case 3:return this.begin("raw"),15;case 4:return this.popState(),this.conditionStack[this.conditionStack.length-1]==="raw"?15:(i(5,9),"END_RAW_BLOCK");case 5:return 15;case 6:return this.popState(),14;case 7:return 65;case 8:return 68;case 9:return 19;case 10:return this.popState(),this.begin("raw"),23;case 11:return 55;case 12:return 60;case 13:return 29;case 14:return 47;case 15:return this.popState(),44;case 16:return this.popState(),44;case 17:return 34;case 18:return 39;case 19:return 51;case 20:return 48;case 21:this.unput(s.yytext),this.popState(),this.begin("com");break;case 22:return this.popState(),14;case 23:return 48;case 24:return 73;case 25:return 72;case 26:return 72;case 27:return 87;case 28:break;case 29:return this.popState(),54;case 30:return this.popState(),33;case 31:return s.yytext=i(1,2).replace(/\\"/g,'"'),80;case 32:return s.yytext=i(1,2).replace(/\\'/g,"'"),80;case 33:return 85;case 34:return 82;case 35:return 82;case 36:return 83;case 37:return 84;case 38:return 81;case 39:return 75;case 40:return 77;case 41:return 72;case 42:return s.yytext=s.yytext.replace(/\\([\\\]])/g,"$1"),72;case 43:return"INVALID";case 44:return 5}},c.rules=[/^(?:[^\x00]*?(?=(\{\{)))/,/^(?:[^\x00]+)/,/^(?:[^\x00]{2,}?(?=(\{\{|\\\{\{|\\\\\{\{|$)))/,/^(?:\{\{\{\{(?=[^\/]))/,/^(?:\{\{\{\{\/[^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=[=}\s\/.])\}\}\}\})/,/^(?:[^\x00]+?(?=(\{\{\{\{)))/,/^(?:[\s\S]*?--(~)?\}\})/,/^(?:\()/,/^(?:\))/,/^(?:\{\{\{\{)/,/^(?:\}\}\}\})/,/^(?:\{\{(~)?>)/,/^(?:\{\{(~)?#>)/,/^(?:\{\{(~)?#\*?)/,/^(?:\{\{(~)?\/)/,/^(?:\{\{(~)?\^\s*(~)?\}\})/,/^(?:\{\{(~)?\s*else\s*(~)?\}\})/,/^(?:\{\{(~)?\^)/,/^(?:\{\{(~)?\s*else\b)/,/^(?:\{\{(~)?\{)/,/^(?:\{\{(~)?&)/,/^(?:\{\{(~)?!--)/,/^(?:\{\{(~)?![\s\S]*?\}\})/,/^(?:\{\{(~)?\*?)/,/^(?:=)/,/^(?:\.\.)/,/^(?:\.(?=([=~}\s\/.)|])))/,/^(?:[\/.])/,/^(?:\s+)/,/^(?:\}(~)?\}\})/,/^(?:(~)?\}\})/,/^(?:"(\\["]|[^"])*")/,/^(?:'(\\[']|[^'])*')/,/^(?:@)/,/^(?:true(?=([~}\s)])))/,/^(?:false(?=([~}\s)])))/,/^(?:undefined(?=([~}\s)])))/,/^(?:null(?=([~}\s)])))/,/^(?:-?[0-9]+(?:\.[0-9]+)?(?=([~}\s)])))/,/^(?:as\s+\|)/,/^(?:\|)/,/^(?:([^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=([=~}\s\/.)|]))))/,/^(?:\[(\\\]|[^\]])*\])/,/^(?:.)/,/^(?:$)/],c.conditions={mu:{rules:[7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44],inclusive:!1},emu:{rules:[2],inclusive:!1},com:{rules:[6],inclusive:!1},raw:{rules:[3,4,5],inclusive:!1},INITIAL:{rules:[0,1,44],inclusive:!0}},c}();return n.lexer=u,r.prototype=n,n.Parser=r,new r}();o.default=d,E.exports=o.default},function(E,o,d){"use strict";function r(){var i=arguments.length<=0||arguments[0]===void 0?{}:arguments[0];this.options=i}function n(i,v,h){v===void 0&&(v=i.length);var p=i[v-1],A=i[v-2];return p?p.type==="ContentStatement"?(A||!h?/\r?\n\s*?$/:/(^|\r?\n)\s*?$/).test(p.original):void 0:h}function u(i,v,h){v===void 0&&(v=-1);var p=i[v+1],A=i[v+2];return p?p.type==="ContentStatement"?(A||!h?/^\s*?\r?\n/:/^\s*?(\r?\n|$)/).test(p.original):void 0:h}function c(i,v,h){var p=i[v==null?0:v+1];if(p&&p.type==="ContentStatement"&&(h||!p.rightStripped)){var A=p.value;p.value=p.value.replace(h?/^\s+/:/^[ \t]*\r?\n?/,""),p.rightStripped=p.value!==A}}function l(i,v,h){var p=i[v==null?i.length-1:v-1];if(p&&p.type==="ContentStatement"&&(h||!p.leftStripped)){var A=p.value;return p.value=p.value.replace(h?/\s+$/:/[ \t]+$/,""),p.leftStripped=p.value!==A,p.leftStripped}}var s=d(1).default;o.__esModule=!0;var f=d(49),g=s(f);r.prototype=new g.default,r.prototype.Program=function(i){var v=!this.options.ignoreStandalone,h=!this.isRootSeen;this.isRootSeen=!0;for(var p=i.body,A=0,m=p.length;A0)throw new m.default("Invalid path: "+C,{loc:x});b===".."&&_++}}return{type:"PathExpression",data:y,depth:_,parts:D,original:C,loc:x}}function f(y,T,x,C,D,_){var R=C.charAt(3)||C.charAt(2),N=R!=="{"&&R!=="&",b=/\*/.test(C);return{type:b?"Decorator":"MustacheStatement",path:y,params:T,hash:x,escaped:N,strip:D,loc:this.locInfo(_)}}function g(y,T,x,C){r(y,x),C=this.locInfo(C);var D={type:"Program",body:T,strip:{},loc:C};return{type:"BlockStatement",path:y.path,params:y.params,hash:y.hash,program:D,openStrip:{},inverseStrip:{},closeStrip:{},loc:C}}function i(y,T,x,C,D,_){C&&C.path&&r(y,C);var R=/\*/.test(y.open);T.blockParams=y.blockParams;var N=void 0,b=void 0;if(x){if(R)throw new m.default("Unexpected inverse block on decorator",x);x.chain&&(x.program.body[0].closeStrip=C.strip),b=x.strip,N=x.program}return D&&(D=N,N=T,T=D),{type:R?"DecoratorBlock":"BlockStatement",path:y.path,params:y.params,hash:y.hash,program:T,inverse:N,openStrip:y.strip,inverseStrip:b,closeStrip:C&&C.strip,loc:this.locInfo(_)}}function v(y,T){if(!T&&y.length){var x=y[0].loc,C=y[y.length-1].loc;x&&C&&(T={source:x.source,start:{line:x.start.line,column:x.start.column},end:{line:C.end.line,column:C.end.column}})}return{type:"Program",body:y,strip:{},loc:T}}function h(y,T,x,C){return r(y,x),{type:"PartialBlockStatement",name:y.path,params:y.params,hash:y.hash,program:T,openStrip:y.strip,closeStrip:x&&x.strip,loc:this.locInfo(C)}}var p=d(1).default;o.__esModule=!0,o.SourceLocation=n,o.id=u,o.stripFlags=c,o.stripComment=l,o.preparePath=s,o.prepareMustache=f,o.prepareRawBlock=g,o.prepareBlock=i,o.prepareProgram=v,o.preparePartialBlock=h;var A=d(6),m=p(A)},function(E,o,d){"use strict";function r(){}function n(m,y,T){if(m==null||typeof m!="string"&&m.type!=="Program")throw new i.default("You must pass a string or Handlebars AST to Handlebars.precompile. You passed "+m);y=y||{},"data"in y||(y.data=!0),y.compat&&(y.useDepths=!0);var x=T.parse(m,y),C=new T.Compiler().compile(x,y);return new T.JavaScriptCompiler().compile(C,y)}function u(m,y,T){function x(){var _=T.parse(m,y),R=new T.Compiler().compile(_,y),N=new T.JavaScriptCompiler().compile(R,y,void 0,!0);return T.template(N)}function C(_,R){return D||(D=x()),D.call(this,_,R)}if(y===void 0&&(y={}),m==null||typeof m!="string"&&m.type!=="Program")throw new i.default("You must pass a string or Handlebars AST to Handlebars.compile. You passed "+m);y=v.extend({},y),"data"in y||(y.data=!0),y.compat&&(y.useDepths=!0);var D=void 0;return C._setup=function(_){return D||(D=x()),D._setup(_)},C._child=function(_,R,N,b){return D||(D=x()),D._child(_,R,N,b)},C}function c(m,y){if(m===y)return!0;if(v.isArray(m)&&v.isArray(y)&&m.length===y.length){for(var T=0;T1)throw new i.default("Unsupported number of partial arguments: "+T.length,m);T.length||(this.options.explicitPartialContext?this.opcode("pushLiteral","undefined"):T.push({type:"PathExpression",parts:[],depth:0}));var x=m.name.original,C=m.name.type==="SubExpression";C&&this.accept(m.name),this.setupFullMustacheParams(m,y,void 0,!0);var D=m.indent||"";this.options.preventIndent&&D&&(this.opcode("appendContent",D),D=""),this.opcode("invokePartial",C,x,D),this.opcode("append")},PartialBlockStatement:function(m){this.PartialStatement(m)},MustacheStatement:function(m){this.SubExpression(m),m.escaped&&!this.options.noEscape?this.opcode("appendEscaped"):this.opcode("append")},Decorator:function(m){this.DecoratorBlock(m)},ContentStatement:function(m){m.value&&this.opcode("appendContent",m.value)},CommentStatement:function(){},SubExpression:function(m){l(m);var y=this.classifySexpr(m);y==="simple"?this.simpleSexpr(m):y==="helper"?this.helperSexpr(m):this.ambiguousSexpr(m)},ambiguousSexpr:function(m,y,T){var x=m.path,C=x.parts[0],D=y!=null||T!=null;this.opcode("getContext",x.depth),this.opcode("pushProgram",y),this.opcode("pushProgram",T),x.strict=!0,this.accept(x),this.opcode("invokeAmbiguous",C,D)},simpleSexpr:function(m){var y=m.path;y.strict=!0,this.accept(y),this.opcode("resolvePossibleLambda")},helperSexpr:function(m,y,T){var x=this.setupFullMustacheParams(m,y,T),C=m.path,D=C.parts[0];if(this.options.knownHelpers[D])this.opcode("invokeKnownHelper",x.length,D);else{if(this.options.knownHelpersOnly)throw new i.default("You specified knownHelpersOnly, but used the unknown helper "+D,m);C.strict=!0,C.falsy=!0,this.accept(C),this.opcode("invokeHelper",x.length,C.original,p.default.helpers.simpleId(C))}},PathExpression:function(m){this.addDepth(m.depth),this.opcode("getContext",m.depth);var y=m.parts[0],T=p.default.helpers.scopedId(m),x=!m.depth&&!T&&this.blockParamIndex(y);x?this.opcode("lookupBlockParam",x,m.parts):y?m.data?(this.options.data=!0,this.opcode("lookupData",m.depth,m.parts,m.strict)):this.opcode("lookupOnContext",m.parts,m.falsy,m.strict,T):this.opcode("pushContext")},StringLiteral:function(m){this.opcode("pushString",m.value)},NumberLiteral:function(m){this.opcode("pushLiteral",m.value)},BooleanLiteral:function(m){this.opcode("pushLiteral",m.value)},UndefinedLiteral:function(){this.opcode("pushLiteral","undefined")},NullLiteral:function(){this.opcode("pushLiteral","null")},Hash:function(m){var y=m.pairs,T=0,x=y.length;for(this.opcode("pushHash");T=0)return[y,C]}}}},function(E,o,d){"use strict";function r(p){this.value=p}function n(){}function u(p,A,m,y){var T=A.popStack(),x=0,C=m.length;for(p&&C--;x1)throw new Error("Parse Error: multiple actions possible at state: "+D+", token: "+A);switch(C[0]){case 1:f.push(A),g.push(this.lexer.yytext),i.push(this.lexer.yylloc),f.push(C[1]),A=null,w?(A=w,w=null):(y=this.lexer.yyleng,c=this.lexer.yytext,h=this.lexer.yylineno,x=this.lexer.yylloc,E>0&&E--);break;case 2:if(R=this.productions_[C[1]][1],B.$=g[g.length-R],B._$={first_line:i[i.length-(R||1)].first_line,last_line:i[i.length-1].last_line,first_column:i[i.length-(R||1)].first_column,last_column:i[i.length-1].last_column},T&&(B._$.range=[i[i.length-(R||1)].range[0],i[i.length-1].range[1]]),O=this.performAction.call(B,c,y,h,this.yy,C[1],g,i),typeof O!="undefined")return O;R&&(f=f.slice(0,-1*R*2),g=g.slice(0,-1*R),i=i.slice(0,-1*R)),f.push(this.productions_[C[1]][0]),g.push(B.$),i.push(B._$),_=m[f[f.length-2]][f[f.length-1]],f.push(_);break;case 3:return!0}}return!0}},u=function(){var p={EOF:1,parseError:function(l,o){if(!this.yy.parser)throw new Error(l);this.yy.parser.parseError(l,o)},setInput:function(l){return this._input=l,this._more=this._less=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var l=this._input[0];this.yytext+=l,this.yyleng++,this.offset++,this.match+=l,this.matched+=l;var o=l.match(/(?:\r\n?|\n).*/g);return o?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),l},unput:function(l){var o=l.length,f=l.split(/(?:\r\n?|\n)/g);this._input=l+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-o-1),this.offset-=o;var g=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),f.length-1&&(this.yylineno-=f.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:f?(f.length===g.length?this.yylloc.first_column:0)+g[g.length-f.length].length-f[0].length:this.yylloc.first_column-o},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-o]),this},more:function(){return this._more=!0,this},less:function(l){this.unput(this.match.slice(l))},pastInput:function(){var l=this.matched.substr(0,this.matched.length-this.match.length);return(l.length>20?"...":"")+l.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var l=this.match;return l.length<20&&(l+=this._input.substr(0,20-l.length)),(l.substr(0,20)+(l.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var l=this.pastInput(),o=new Array(l.length+1).join("-");return l+this.upcomingInput()+` +`+o+"^"},next:function(){if(this.done)return this.EOF;this._input||(this.done=!0);var l,o,f,g,i;this._more||(this.yytext="",this.match="");for(var m=this._currentRules(),c=0;co[0].length)||(o=f,g=c,this.options.flex));c++);return o?(i=o[0].match(/(?:\r\n?|\n).*/g),i&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+o[0].length},this.yytext+=o[0],this.match+=o[0],this.matches=o,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._input=this._input.slice(o[0].length),this.matched+=o[0],l=this.performAction.call(this,this.yy,this,m[g],this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),l||void 0):this._input===""?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+`. Unrecognized text. +`+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var l=this.next();return typeof l!="undefined"?l:this.lex()},begin:function(l){this.conditionStack.push(l)},popState:function(){return this.conditionStack.pop()},_currentRules:function(){return this.conditions[this.conditionStack[this.conditionStack.length-1]].rules},topState:function(){return this.conditionStack[this.conditionStack.length-2]},pushState:function(l){this.begin(l)}};return p.options={},p.performAction=function(l,o,f,g){function i(m,c){return o.yytext=o.yytext.substring(m,o.yyleng-c+m)}switch(f){case 0:if(o.yytext.slice(-2)==="\\\\"?(i(0,1),this.begin("mu")):o.yytext.slice(-1)==="\\"?(i(0,1),this.begin("emu")):this.begin("mu"),o.yytext)return 15;break;case 1:return 15;case 2:return this.popState(),15;case 3:return this.begin("raw"),15;case 4:return this.popState(),this.conditionStack[this.conditionStack.length-1]==="raw"?15:(i(5,9),"END_RAW_BLOCK");case 5:return 15;case 6:return this.popState(),14;case 7:return 65;case 8:return 68;case 9:return 19;case 10:return this.popState(),this.begin("raw"),23;case 11:return 55;case 12:return 60;case 13:return 29;case 14:return 47;case 15:return this.popState(),44;case 16:return this.popState(),44;case 17:return 34;case 18:return 39;case 19:return 51;case 20:return 48;case 21:this.unput(o.yytext),this.popState(),this.begin("com");break;case 22:return this.popState(),14;case 23:return 48;case 24:return 73;case 25:return 72;case 26:return 72;case 27:return 87;case 28:break;case 29:return this.popState(),54;case 30:return this.popState(),33;case 31:return o.yytext=i(1,2).replace(/\\"/g,'"'),80;case 32:return o.yytext=i(1,2).replace(/\\'/g,"'"),80;case 33:return 85;case 34:return 82;case 35:return 82;case 36:return 83;case 37:return 84;case 38:return 81;case 39:return 75;case 40:return 77;case 41:return 72;case 42:return o.yytext=o.yytext.replace(/\\([\\\]])/g,"$1"),72;case 43:return"INVALID";case 44:return 5}},p.rules=[/^(?:[^\x00]*?(?=(\{\{)))/,/^(?:[^\x00]+)/,/^(?:[^\x00]{2,}?(?=(\{\{|\\\{\{|\\\\\{\{|$)))/,/^(?:\{\{\{\{(?=[^\/]))/,/^(?:\{\{\{\{\/[^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=[=}\s\/.])\}\}\}\})/,/^(?:[^\x00]+?(?=(\{\{\{\{)))/,/^(?:[\s\S]*?--(~)?\}\})/,/^(?:\()/,/^(?:\))/,/^(?:\{\{\{\{)/,/^(?:\}\}\}\})/,/^(?:\{\{(~)?>)/,/^(?:\{\{(~)?#>)/,/^(?:\{\{(~)?#\*?)/,/^(?:\{\{(~)?\/)/,/^(?:\{\{(~)?\^\s*(~)?\}\})/,/^(?:\{\{(~)?\s*else\s*(~)?\}\})/,/^(?:\{\{(~)?\^)/,/^(?:\{\{(~)?\s*else\b)/,/^(?:\{\{(~)?\{)/,/^(?:\{\{(~)?&)/,/^(?:\{\{(~)?!--)/,/^(?:\{\{(~)?![\s\S]*?\}\})/,/^(?:\{\{(~)?\*?)/,/^(?:=)/,/^(?:\.\.)/,/^(?:\.(?=([=~}\s\/.)|])))/,/^(?:[\/.])/,/^(?:\s+)/,/^(?:\}(~)?\}\})/,/^(?:(~)?\}\})/,/^(?:"(\\["]|[^"])*")/,/^(?:'(\\[']|[^'])*')/,/^(?:@)/,/^(?:true(?=([~}\s)])))/,/^(?:false(?=([~}\s)])))/,/^(?:undefined(?=([~}\s)])))/,/^(?:null(?=([~}\s)])))/,/^(?:-?[0-9]+(?:\.[0-9]+)?(?=([~}\s)])))/,/^(?:as\s+\|)/,/^(?:\|)/,/^(?:([^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=([=~}\s\/.)|]))))/,/^(?:\[(\\\]|[^\]])*\])/,/^(?:.)/,/^(?:$)/],p.conditions={mu:{rules:[7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44],inclusive:!1},emu:{rules:[2],inclusive:!1},com:{rules:[6],inclusive:!1},raw:{rules:[3,4,5],inclusive:!1},INITIAL:{rules:[0,1,44],inclusive:!0}},p}();return n.lexer=u,r.prototype=n,n.Parser=r,new r}();s.default=d,v.exports=s.default},function(v,s,d){"use strict";function r(){var i=arguments.length<=0||arguments[0]===void 0?{}:arguments[0];this.options=i}function n(i,m,c){m===void 0&&(m=i.length);var h=i[m-1],y=i[m-2];return h?h.type==="ContentStatement"?(y||!c?/\r?\n\s*?$/:/(^|\r?\n)\s*?$/).test(h.original):void 0:c}function u(i,m,c){m===void 0&&(m=-1);var h=i[m+1],y=i[m+2];return h?h.type==="ContentStatement"?(y||!c?/^\s*?\r?\n/:/^\s*?(\r?\n|$)/).test(h.original):void 0:c}function p(i,m,c){var h=i[m==null?0:m+1];if(h&&h.type==="ContentStatement"&&(c||!h.rightStripped)){var y=h.value;h.value=h.value.replace(c?/^\s+/:/^[ \t]*\r?\n?/,""),h.rightStripped=h.value!==y}}function l(i,m,c){var h=i[m==null?i.length-1:m-1];if(h&&h.type==="ContentStatement"&&(c||!h.leftStripped)){var y=h.value;return h.value=h.value.replace(c?/\s+$/:/[ \t]+$/,""),h.leftStripped=h.value!==y,h.leftStripped}}var o=d(1).default;s.__esModule=!0;var f=d(49),g=o(f);r.prototype=new g.default,r.prototype.Program=function(i){var m=!this.options.ignoreStandalone,c=!this.isRootSeen;this.isRootSeen=!0;for(var h=i.body,y=0,E=h.length;y0)throw new E.default("Invalid path: "+w,{loc:A});R===".."&&C++}}return{type:"PathExpression",data:x,depth:C,parts:D,original:w,loc:A}}function f(x,T,A,w,D,C){var O=w.charAt(3)||w.charAt(2),I=O!=="{"&&O!=="&",R=/\*/.test(w);return{type:R?"Decorator":"MustacheStatement",path:x,params:T,hash:A,escaped:I,strip:D,loc:this.locInfo(C)}}function g(x,T,A,w){r(x,A),w=this.locInfo(w);var D={type:"Program",body:T,strip:{},loc:w};return{type:"BlockStatement",path:x.path,params:x.params,hash:x.hash,program:D,openStrip:{},inverseStrip:{},closeStrip:{},loc:w}}function i(x,T,A,w,D,C){w&&w.path&&r(x,w);var O=/\*/.test(x.open);T.blockParams=x.blockParams;var I=void 0,R=void 0;if(A){if(O)throw new E.default("Unexpected inverse block on decorator",A);A.chain&&(A.program.body[0].closeStrip=w.strip),R=A.strip,I=A.program}return D&&(D=I,I=T,T=D),{type:O?"DecoratorBlock":"BlockStatement",path:x.path,params:x.params,hash:x.hash,program:T,inverse:I,openStrip:x.strip,inverseStrip:R,closeStrip:w&&w.strip,loc:this.locInfo(C)}}function m(x,T){if(!T&&x.length){var A=x[0].loc,w=x[x.length-1].loc;A&&w&&(T={source:A.source,start:{line:A.start.line,column:A.start.column},end:{line:w.end.line,column:w.end.column}})}return{type:"Program",body:x,strip:{},loc:T}}function c(x,T,A,w){return r(x,A),{type:"PartialBlockStatement",name:x.path,params:x.params,hash:x.hash,program:T,openStrip:x.strip,closeStrip:A&&A.strip,loc:this.locInfo(w)}}var h=d(1).default;s.__esModule=!0,s.SourceLocation=n,s.id=u,s.stripFlags=p,s.stripComment=l,s.preparePath=o,s.prepareMustache=f,s.prepareRawBlock=g,s.prepareBlock=i,s.prepareProgram=m,s.preparePartialBlock=c;var y=d(6),E=h(y)},function(v,s,d){"use strict";function r(){}function n(E,x,T){if(E==null||typeof E!="string"&&E.type!=="Program")throw new i.default("You must pass a string or Handlebars AST to Handlebars.precompile. You passed "+E);x=x||{},"data"in x||(x.data=!0),x.compat&&(x.useDepths=!0);var A=T.parse(E,x),w=new T.Compiler().compile(A,x);return new T.JavaScriptCompiler().compile(w,x)}function u(E,x,T){function A(){var C=T.parse(E,x),O=new T.Compiler().compile(C,x),I=new T.JavaScriptCompiler().compile(O,x,void 0,!0);return T.template(I)}function w(C,O){return D||(D=A()),D.call(this,C,O)}if(x===void 0&&(x={}),E==null||typeof E!="string"&&E.type!=="Program")throw new i.default("You must pass a string or Handlebars AST to Handlebars.compile. You passed "+E);x=m.extend({},x),"data"in x||(x.data=!0),x.compat&&(x.useDepths=!0);var D=void 0;return w._setup=function(C){return D||(D=A()),D._setup(C)},w._child=function(C,O,I,R){return D||(D=A()),D._child(C,O,I,R)},w}function p(E,x){if(E===x)return!0;if(m.isArray(E)&&m.isArray(x)&&E.length===x.length){for(var T=0;T1)throw new i.default("Unsupported number of partial arguments: "+T.length,E);T.length||(this.options.explicitPartialContext?this.opcode("pushLiteral","undefined"):T.push({type:"PathExpression",parts:[],depth:0}));var A=E.name.original,w=E.name.type==="SubExpression";w&&this.accept(E.name),this.setupFullMustacheParams(E,x,void 0,!0);var D=E.indent||"";this.options.preventIndent&&D&&(this.opcode("appendContent",D),D=""),this.opcode("invokePartial",w,A,D),this.opcode("append")},PartialBlockStatement:function(E){this.PartialStatement(E)},MustacheStatement:function(E){this.SubExpression(E),E.escaped&&!this.options.noEscape?this.opcode("appendEscaped"):this.opcode("append")},Decorator:function(E){this.DecoratorBlock(E)},ContentStatement:function(E){E.value&&this.opcode("appendContent",E.value)},CommentStatement:function(){},SubExpression:function(E){l(E);var x=this.classifySexpr(E);x==="simple"?this.simpleSexpr(E):x==="helper"?this.helperSexpr(E):this.ambiguousSexpr(E)},ambiguousSexpr:function(E,x,T){var A=E.path,w=A.parts[0],D=x!=null||T!=null;this.opcode("getContext",A.depth),this.opcode("pushProgram",x),this.opcode("pushProgram",T),A.strict=!0,this.accept(A),this.opcode("invokeAmbiguous",w,D)},simpleSexpr:function(E){var x=E.path;x.strict=!0,this.accept(x),this.opcode("resolvePossibleLambda")},helperSexpr:function(E,x,T){var A=this.setupFullMustacheParams(E,x,T),w=E.path,D=w.parts[0];if(this.options.knownHelpers[D])this.opcode("invokeKnownHelper",A.length,D);else{if(this.options.knownHelpersOnly)throw new i.default("You specified knownHelpersOnly, but used the unknown helper "+D,E);w.strict=!0,w.falsy=!0,this.accept(w),this.opcode("invokeHelper",A.length,w.original,h.default.helpers.simpleId(w))}},PathExpression:function(E){this.addDepth(E.depth),this.opcode("getContext",E.depth);var x=E.parts[0],T=h.default.helpers.scopedId(E),A=!E.depth&&!T&&this.blockParamIndex(x);A?this.opcode("lookupBlockParam",A,E.parts):x?E.data?(this.options.data=!0,this.opcode("lookupData",E.depth,E.parts,E.strict)):this.opcode("lookupOnContext",E.parts,E.falsy,E.strict,T):this.opcode("pushContext")},StringLiteral:function(E){this.opcode("pushString",E.value)},NumberLiteral:function(E){this.opcode("pushLiteral",E.value)},BooleanLiteral:function(E){this.opcode("pushLiteral",E.value)},UndefinedLiteral:function(){this.opcode("pushLiteral","undefined")},NullLiteral:function(){this.opcode("pushLiteral","null")},Hash:function(E){var x=E.pairs,T=0,A=x.length;for(this.opcode("pushHash");T=0)return[x,w]}}}},function(v,s,d){"use strict";function r(h){this.value=h}function n(){}function u(h,y,E,x){var T=y.popStack(),A=0,w=E.length;for(h&&w--;A0&&(m+=", "+y.join(", "));var T=0;c(this.aliases).forEach(function(D){var _=A.aliases[D];_.children&&_.referenceCount>1&&(m+=", alias"+ ++T+"="+D,_.children[0]="alias"+T)}),this.lookupPropertyFunctionIsUsed&&(m+=", "+this.lookupPropertyFunctionVarDeclaration());var x=["container","depth0","helpers","partials","data"];(this.useBlockParams||this.useDepths)&&x.push("blockParams"),this.useDepths&&x.push("depths");var C=this.mergeSource(m);return p?(x.push(C),Function.apply(this,x)):this.source.wrap(["function(",x.join(","),`) { - `,C,"}"])},mergeSource:function(p){var A=this.environment.isSimple,m=!this.forceBuffer,y=void 0,T=void 0,x=void 0,C=void 0;return this.source.each(function(D){D.appendToBuffer?(x?D.prepend(" + "):x=D,C=D):(x&&(T?x.prepend("buffer += "):y=!0,C.add(";"),x=C=void 0),T=!0,A||(m=!1))}),m?x?(x.prepend("return "),C.add(";")):T||this.source.push('return "";'):(p+=", buffer = "+(y?"":this.initializeBuffer()),x?(x.prepend("return buffer + "),C.add(";")):this.source.push("return buffer;")),p&&this.source.prepend("var "+p.substring(2)+(y?"":`; +`),this.decorators=this.decorators.merge()));var O=this.createFunctionContext(x);if(this.isChild)return O;var I={compiler:this.compilerInfo(),main:O};this.decorators&&(I.main_d=this.decorators,I.useDecorators=!0);var R=this.context,_=R.programs,N=R.decorators;for(D=0,C=_.length;D0&&(E+=", "+x.join(", "));var T=0;p(this.aliases).forEach(function(D){var C=y.aliases[D];C.children&&C.referenceCount>1&&(E+=", alias"+ ++T+"="+D,C.children[0]="alias"+T)}),this.lookupPropertyFunctionIsUsed&&(E+=", "+this.lookupPropertyFunctionVarDeclaration());var A=["container","depth0","helpers","partials","data"];(this.useBlockParams||this.useDepths)&&A.push("blockParams"),this.useDepths&&A.push("depths");var w=this.mergeSource(E);return h?(A.push(w),Function.apply(this,A)):this.source.wrap(["function(",A.join(","),`) { + `,w,"}"])},mergeSource:function(h){var y=this.environment.isSimple,E=!this.forceBuffer,x=void 0,T=void 0,A=void 0,w=void 0;return this.source.each(function(D){D.appendToBuffer?(A?D.prepend(" + "):A=D,w=D):(A&&(T?A.prepend("buffer += "):x=!0,w.add(";"),A=w=void 0),T=!0,y||(E=!1))}),E?A?(A.prepend("return "),w.add(";")):T||this.source.push('return "";'):(h+=", buffer = "+(x?"":this.initializeBuffer()),A?(A.prepend("return buffer + "),w.add(";")):this.source.push("return buffer;")),h&&this.source.prepend("var "+h.substring(2)+(x?"":`; `)),this.source.merge()},lookupPropertyFunctionVarDeclaration:function(){return` lookupProperty = container.lookupProperty || function(parent, propertyName) { if (Object.prototype.hasOwnProperty.call(parent, propertyName)) { @@ -47,52 +47,378 @@ Expecting `+L.join(", ")+", got '"+(this.terminals_[x]||x)+"'":"Parse error on l } return undefined } - `.trim()},blockValue:function(p){var A=this.aliasable("container.hooks.blockHelperMissing"),m=[this.contextName(0)];this.setupHelperArgs(p,0,m);var y=this.popStack();m.splice(1,0,y),this.push(this.source.functionCall(A,"call",m))},ambiguousBlockValue:function(){var p=this.aliasable("container.hooks.blockHelperMissing"),A=[this.contextName(0)];this.setupHelperArgs("",0,A,!0),this.flushInline();var m=this.topStack();A.splice(1,0,m),this.pushSource(["if (!",this.lastHelper,") { ",m," = ",this.source.functionCall(p,"call",A),"}"])},appendContent:function(p){this.pendingContent?p=this.pendingContent+p:this.pendingLocation=this.source.currentLocation,this.pendingContent=p},append:function(){if(this.isInline())this.replaceStack(function(A){return[" != null ? ",A,' : ""']}),this.pushSource(this.appendToBuffer(this.popStack()));else{var p=this.popStack();this.pushSource(["if (",p," != null) { ",this.appendToBuffer(p,void 0,!0)," }"]),this.environment.isSimple&&this.pushSource(["else { ",this.appendToBuffer("''",void 0,!0)," }"])}},appendEscaped:function(){this.pushSource(this.appendToBuffer([this.aliasable("container.escapeExpression"),"(",this.popStack(),")"]))},getContext:function(p){this.lastContext=p},pushContext:function(){this.pushStackLiteral(this.contextName(this.lastContext))},lookupOnContext:function(p,A,m,y){var T=0;y||!this.options.compat||this.lastContext?this.pushContext():this.push(this.depthedLookup(p[T++])),this.resolvePath("context",p,T,A,m)},lookupBlockParam:function(p,A){this.useBlockParams=!0,this.push(["blockParams[",p[0],"][",p[1],"]"]),this.resolvePath("context",A,1)},lookupData:function(p,A,m){p?this.pushStackLiteral("container.data(data, "+p+")"):this.pushStackLiteral("data"),this.resolvePath("data",A,0,!0,m)},resolvePath:function(p,A,m,y,T){var x=this;if(this.options.strict||this.options.assumeObjects)return void this.push(u(this.options.strict&&T,this,A,p));for(var C=A.length;mthis.stackVars.length&&this.stackVars.push("stack"+this.stackSlot),this.topStackName()},topStackName:function(){return"stack"+this.stackSlot},flushInline:function(){var p=this.inlineStack;this.inlineStack=[];for(var A=0,m=p.length;A{var d;/*! -* Sizzle CSS Selector Engine v2.3.10 -* https://sizzlejs.com/ -* -* Copyright JS Foundation and other contributors -* Released under the MIT license -* https://js.foundation/ -* -* Date: 2023-02-14 -*/(function(r){var n,u,c,l,s,f,g,i,v,h,p,A,m,y,T,x,C,D,_,R="sizzle"+1*new Date,N=r.document,b=0,P=0,L=Gt(),k=Gt(),F=Gt(),H=Gt(),W=function(M,G){return M===G&&(p=!0),0},z={}.hasOwnProperty,$=[],V=$.pop,Y=$.push,nt=$.push,it=$.slice,ut=function(M,G){for(var J=0,Z=M.length;J+~]|"+dt+")"+dt+"*"),Rt=new RegExp(dt+"|>"),Se=new RegExp(ie),kt=new RegExp("^"+yt+"$"),Ut={ID:new RegExp("^#("+yt+")"),CLASS:new RegExp("^\\.("+yt+")"),TAG:new RegExp("^("+yt+"|[*])"),ATTR:new RegExp("^"+Ot),PSEUDO:new RegExp("^"+ie),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+dt+"*(even|odd|(([+-]|)(\\d*)n|)"+dt+"*(?:([+-]|)"+dt+"*(\\d+)|))"+dt+"*\\)|)","i"),bool:new RegExp("^(?:"+et+")$","i"),needsContext:new RegExp("^"+dt+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+dt+"*((?:-\\d)?\\d*)"+dt+"*\\)|)(?=[^-]|$)","i")},We=/HTML$/i,Ft=/^(?:input|select|textarea|button)$/i,lt=/^h\d$/i,Ct=/^[^{]+\{\s*\[native \w/,It=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,st=/[+~]/,mt=new RegExp("\\\\[\\da-fA-F]{1,6}"+dt+"?|\\\\([^\\r\\n\\f])","g"),vt=function(M,G){var J="0x"+M.slice(1)-65536;return G||(J<0?String.fromCharCode(J+65536):String.fromCharCode(J>>10|55296,J&1023|56320))},St=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,Jt=function(M,G){return G?M==="\0"?"\uFFFD":M.slice(0,-1)+"\\"+M.charCodeAt(M.length-1).toString(16)+" ":"\\"+M},Xt=function(){A()},jt=me(function(M){return M.disabled===!0&&M.nodeName.toLowerCase()==="fieldset"},{dir:"parentNode",next:"legend"});try{nt.apply($=it.call(N.childNodes),N.childNodes),$[N.childNodes.length].nodeType}catch(M){nt={apply:$.length?function(G,J){Y.apply(G,it.call(J))}:function(G,J){for(var Z=G.length,U=0;G[Z++]=J[U++];);G.length=Z-1}}}function Dt(M,G,J,Z){var U,q,tt,at,ht,gt,xt,Tt=G&&G.ownerDocument,Lt=G?G.nodeType:9;if(J=J||[],typeof M!="string"||!M||Lt!==1&&Lt!==9&&Lt!==11)return J;if(!Z&&(A(G),G=G||m,T)){if(Lt!==11&&(ht=It.exec(M)))if(U=ht[1]){if(Lt===9)if(tt=G.getElementById(U)){if(tt.id===U)return J.push(tt),J}else return J;else if(Tt&&(tt=Tt.getElementById(U))&&_(G,tt)&&tt.id===U)return J.push(tt),J}else{if(ht[2])return nt.apply(J,G.getElementsByTagName(M)),J;if((U=ht[3])&&u.getElementsByClassName&&G.getElementsByClassName)return nt.apply(J,G.getElementsByClassName(U)),J}if(u.qsa&&!H[M+" "]&&(!x||!x.test(M))&&(Lt!==1||G.nodeName.toLowerCase()!=="object")){if(xt=M,Tt=G,Lt===1&&(Rt.test(M)||_e.test(M))){for(Tt=st.test(M)&&dn(G.parentNode)||G,(Tt!==G||!u.scope)&&((at=G.getAttribute("id"))?at=at.replace(St,Jt):G.setAttribute("id",at=R)),gt=f(M),q=gt.length;q--;)gt[q]=(at?"#"+at:":scope")+" "+gn(gt[q]);xt=gt.join(",")}try{return nt.apply(J,Tt.querySelectorAll(xt)),J}catch(Yt){H(M,!0)}finally{at===R&&G.removeAttribute("id")}}}return i(M.replace(he,"$1"),G,J,Z)}function Gt(){var M=[];function G(J,Z){return M.push(J+" ")>c.cacheLength&&delete G[M.shift()],G[J+" "]=Z}return G}function Qt(M){return M[R]=!0,M}function qt(M){var G=m.createElement("fieldset");try{return!!M(G)}catch(J){return!1}finally{G.parentNode&&G.parentNode.removeChild(G),G=null}}function He(M,G){for(var J=M.split("|"),Z=J.length;Z--;)c.attrHandle[J[Z]]=G}function Oe(M,G){var J=G&&M,Z=J&&M.nodeType===1&&G.nodeType===1&&M.sourceIndex-G.sourceIndex;if(Z)return Z;if(J){for(;J=J.nextSibling;)if(J===G)return-1}return M?1:-1}function Ce(M){return function(G){var J=G.nodeName.toLowerCase();return J==="input"&&G.type===M}}function Tn(M){return function(G){var J=G.nodeName.toLowerCase();return(J==="input"||J==="button")&&G.type===M}}function sn(M){return function(G){return"form"in G?G.parentNode&&G.disabled===!1?"label"in G?"label"in G.parentNode?G.parentNode.disabled===M:G.disabled===M:G.isDisabled===M||G.isDisabled!==!M&&jt(G)===M:G.disabled===M:"label"in G?G.disabled===M:!1}}function Ue(M){return Qt(function(G){return G=+G,Qt(function(J,Z){for(var U,q=M([],J.length,G),tt=q.length;tt--;)J[U=q[tt]]&&(J[U]=!(Z[U]=J[U]))})})}function dn(M){return M&&typeof M.getElementsByTagName!="undefined"&&M}u=Dt.support={},s=Dt.isXML=function(M){var G=M&&M.namespaceURI,J=M&&(M.ownerDocument||M).documentElement;return!We.test(G||J&&J.nodeName||"HTML")},A=Dt.setDocument=function(M){var G,J,Z=M?M.ownerDocument||M:N;return Z==m||Z.nodeType!==9||!Z.documentElement||(m=Z,y=m.documentElement,T=!s(m),N!=m&&(J=m.defaultView)&&J.top!==J&&(J.addEventListener?J.addEventListener("unload",Xt,!1):J.attachEvent&&J.attachEvent("onunload",Xt)),u.scope=qt(function(U){return y.appendChild(U).appendChild(m.createElement("div")),typeof U.querySelectorAll!="undefined"&&!U.querySelectorAll(":scope fieldset div").length}),u.cssHas=qt(function(){try{return m.querySelector(":has(*,:jqfake)"),!1}catch(U){return!0}}),u.attributes=qt(function(U){return U.className="i",!U.getAttribute("className")}),u.getElementsByTagName=qt(function(U){return U.appendChild(m.createComment("")),!U.getElementsByTagName("*").length}),u.getElementsByClassName=Ct.test(m.getElementsByClassName),u.getById=qt(function(U){return y.appendChild(U).id=R,!m.getElementsByName||!m.getElementsByName(R).length}),u.getById?(c.filter.ID=function(U){var q=U.replace(mt,vt);return function(tt){return tt.getAttribute("id")===q}},c.find.ID=function(U,q){if(typeof q.getElementById!="undefined"&&T){var tt=q.getElementById(U);return tt?[tt]:[]}}):(c.filter.ID=function(U){var q=U.replace(mt,vt);return function(tt){var at=typeof tt.getAttributeNode!="undefined"&&tt.getAttributeNode("id");return at&&at.value===q}},c.find.ID=function(U,q){if(typeof q.getElementById!="undefined"&&T){var tt,at,ht,gt=q.getElementById(U);if(gt){if(tt=gt.getAttributeNode("id"),tt&&tt.value===U)return[gt];for(ht=q.getElementsByName(U),at=0;gt=ht[at++];)if(tt=gt.getAttributeNode("id"),tt&&tt.value===U)return[gt]}return[]}}),c.find.TAG=u.getElementsByTagName?function(U,q){if(typeof q.getElementsByTagName!="undefined")return q.getElementsByTagName(U);if(u.qsa)return q.querySelectorAll(U)}:function(U,q){var tt,at=[],ht=0,gt=q.getElementsByTagName(U);if(U==="*"){for(;tt=gt[ht++];)tt.nodeType===1&&at.push(tt);return at}return gt},c.find.CLASS=u.getElementsByClassName&&function(U,q){if(typeof q.getElementsByClassName!="undefined"&&T)return q.getElementsByClassName(U)},C=[],x=[],(u.qsa=Ct.test(m.querySelectorAll))&&(qt(function(U){var q;y.appendChild(U).innerHTML="",U.querySelectorAll("[msallowcapture^='']").length&&x.push("[*^$]="+dt+`*(?:''|"")`),U.querySelectorAll("[selected]").length||x.push("\\["+dt+"*(?:value|"+et+")"),U.querySelectorAll("[id~="+R+"-]").length||x.push("~="),q=m.createElement("input"),q.setAttribute("name",""),U.appendChild(q),U.querySelectorAll("[name='']").length||x.push("\\["+dt+"*name"+dt+"*="+dt+`*(?:''|"")`),U.querySelectorAll(":checked").length||x.push(":checked"),U.querySelectorAll("a#"+R+"+*").length||x.push(".#.+[+~]"),U.querySelectorAll("\\\f"),x.push("[\\r\\n\\f]")}),qt(function(U){U.innerHTML="";var q=m.createElement("input");q.setAttribute("type","hidden"),U.appendChild(q).setAttribute("name","D"),U.querySelectorAll("[name=d]").length&&x.push("name"+dt+"*[*^$|!~]?="),U.querySelectorAll(":enabled").length!==2&&x.push(":enabled",":disabled"),y.appendChild(U).disabled=!0,U.querySelectorAll(":disabled").length!==2&&x.push(":enabled",":disabled"),U.querySelectorAll("*,:x"),x.push(",.*:")})),(u.matchesSelector=Ct.test(D=y.matches||y.webkitMatchesSelector||y.mozMatchesSelector||y.oMatchesSelector||y.msMatchesSelector))&&qt(function(U){u.disconnectedMatch=D.call(U,"*"),D.call(U,"[s!='']:x"),C.push("!=",ie)}),u.cssHas||x.push(":has"),x=x.length&&new RegExp(x.join("|")),C=C.length&&new RegExp(C.join("|")),G=Ct.test(y.compareDocumentPosition),_=G||Ct.test(y.contains)?function(U,q){var tt=U.nodeType===9&&U.documentElement||U,at=q&&q.parentNode;return U===at||!!(at&&at.nodeType===1&&(tt.contains?tt.contains(at):U.compareDocumentPosition&&U.compareDocumentPosition(at)&16))}:function(U,q){if(q){for(;q=q.parentNode;)if(q===U)return!0}return!1},W=G?function(U,q){if(U===q)return p=!0,0;var tt=!U.compareDocumentPosition-!q.compareDocumentPosition;return tt||(tt=(U.ownerDocument||U)==(q.ownerDocument||q)?U.compareDocumentPosition(q):1,tt&1||!u.sortDetached&&q.compareDocumentPosition(U)===tt?U==m||U.ownerDocument==N&&_(N,U)?-1:q==m||q.ownerDocument==N&&_(N,q)?1:h?ut(h,U)-ut(h,q):0:tt&4?-1:1)}:function(U,q){if(U===q)return p=!0,0;var tt,at=0,ht=U.parentNode,gt=q.parentNode,xt=[U],Tt=[q];if(!ht||!gt)return U==m?-1:q==m?1:ht?-1:gt?1:h?ut(h,U)-ut(h,q):0;if(ht===gt)return Oe(U,q);for(tt=U;tt=tt.parentNode;)xt.unshift(tt);for(tt=q;tt=tt.parentNode;)Tt.unshift(tt);for(;xt[at]===Tt[at];)at++;return at?Oe(xt[at],Tt[at]):xt[at]==N?-1:Tt[at]==N?1:0}),m},Dt.matches=function(M,G){return Dt(M,null,null,G)},Dt.matchesSelector=function(M,G){if(A(M),u.matchesSelector&&T&&!H[G+" "]&&(!C||!C.test(G))&&(!x||!x.test(G)))try{var J=D.call(M,G);if(J||u.disconnectedMatch||M.document&&M.document.nodeType!==11)return J}catch(Z){H(G,!0)}return Dt(G,m,null,[M]).length>0},Dt.contains=function(M,G){return(M.ownerDocument||M)!=m&&A(M),_(M,G)},Dt.attr=function(M,G){(M.ownerDocument||M)!=m&&A(M);var J=c.attrHandle[G.toLowerCase()],Z=J&&z.call(c.attrHandle,G.toLowerCase())?J(M,G,!T):void 0;return Z!==void 0?Z:u.attributes||!T?M.getAttribute(G):(Z=M.getAttributeNode(G))&&Z.specified?Z.value:null},Dt.escape=function(M){return(M+"").replace(St,Jt)},Dt.error=function(M){throw new Error("Syntax error, unrecognized expression: "+M)},Dt.uniqueSort=function(M){var G,J=[],Z=0,U=0;if(p=!u.detectDuplicates,h=!u.sortStable&&M.slice(0),M.sort(W),p){for(;G=M[U++];)G===M[U]&&(Z=J.push(U));for(;Z--;)M.splice(J[Z],1)}return h=null,M},l=Dt.getText=function(M){var G,J="",Z=0,U=M.nodeType;if(U){if(U===1||U===9||U===11){if(typeof M.textContent=="string")return M.textContent;for(M=M.firstChild;M;M=M.nextSibling)J+=l(M)}else if(U===3||U===4)return M.nodeValue}else for(;G=M[Z++];)J+=l(G);return J},c=Dt.selectors={cacheLength:50,createPseudo:Qt,match:Ut,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(M){return M[1]=M[1].replace(mt,vt),M[3]=(M[3]||M[4]||M[5]||"").replace(mt,vt),M[2]==="~="&&(M[3]=" "+M[3]+" "),M.slice(0,4)},CHILD:function(M){return M[1]=M[1].toLowerCase(),M[1].slice(0,3)==="nth"?(M[3]||Dt.error(M[0]),M[4]=+(M[4]?M[5]+(M[6]||1):2*(M[3]==="even"||M[3]==="odd")),M[5]=+(M[7]+M[8]||M[3]==="odd")):M[3]&&Dt.error(M[0]),M},PSEUDO:function(M){var G,J=!M[6]&&M[2];return Ut.CHILD.test(M[0])?null:(M[3]?M[2]=M[4]||M[5]||"":J&&Se.test(J)&&(G=f(J,!0))&&(G=J.indexOf(")",J.length-G)-J.length)&&(M[0]=M[0].slice(0,G),M[2]=J.slice(0,G)),M.slice(0,3))}},filter:{TAG:function(M){var G=M.replace(mt,vt).toLowerCase();return M==="*"?function(){return!0}:function(J){return J.nodeName&&J.nodeName.toLowerCase()===G}},CLASS:function(M){var G=L[M+" "];return G||(G=new RegExp("(^|"+dt+")"+M+"("+dt+"|$)"))&&L(M,function(J){return G.test(typeof J.className=="string"&&J.className||typeof J.getAttribute!="undefined"&&J.getAttribute("class")||"")})},ATTR:function(M,G,J){return function(Z){var U=Dt.attr(Z,M);return U==null?G==="!=":G?(U+="",G==="="?U===J:G==="!="?U!==J:G==="^="?J&&U.indexOf(J)===0:G==="*="?J&&U.indexOf(J)>-1:G==="$="?J&&U.slice(-J.length)===J:G==="~="?(" "+U.replace(ge," ")+" ").indexOf(J)>-1:G==="|="?U===J||U.slice(0,J.length+1)===J+"-":!1):!0}},CHILD:function(M,G,J,Z,U){var q=M.slice(0,3)!=="nth",tt=M.slice(-4)!=="last",at=G==="of-type";return Z===1&&U===0?function(ht){return!!ht.parentNode}:function(ht,gt,xt){var Tt,Lt,Yt,Et,Mt,Ee,Re=q!==tt?"nextSibling":"previousSibling",se=ht.parentNode,Ze=at&&ht.nodeName.toLowerCase(),kn=!xt&&!at,xe=!1;if(se){if(q){for(;Re;){for(Et=ht;Et=Et[Re];)if(at?Et.nodeName.toLowerCase()===Ze:Et.nodeType===1)return!1;Ee=Re=M==="only"&&!Ee&&"nextSibling"}return!0}if(Ee=[tt?se.firstChild:se.lastChild],tt&&kn){for(Et=se,Yt=Et[R]||(Et[R]={}),Lt=Yt[Et.uniqueID]||(Yt[Et.uniqueID]={}),Tt=Lt[M]||[],Mt=Tt[0]===b&&Tt[1],xe=Mt&&Tt[2],Et=Mt&&se.childNodes[Mt];Et=++Mt&&Et&&Et[Re]||(xe=Mt=0)||Ee.pop();)if(Et.nodeType===1&&++xe&&Et===ht){Lt[M]=[b,Mt,xe];break}}else if(kn&&(Et=ht,Yt=Et[R]||(Et[R]={}),Lt=Yt[Et.uniqueID]||(Yt[Et.uniqueID]={}),Tt=Lt[M]||[],Mt=Tt[0]===b&&Tt[1],xe=Mt),xe===!1)for(;(Et=++Mt&&Et&&Et[Re]||(xe=Mt=0)||Ee.pop())&&!((at?Et.nodeName.toLowerCase()===Ze:Et.nodeType===1)&&++xe&&(kn&&(Yt=Et[R]||(Et[R]={}),Lt=Yt[Et.uniqueID]||(Yt[Et.uniqueID]={}),Lt[M]=[b,xe]),Et===ht)););return xe-=U,xe===Z||xe%Z===0&&xe/Z>=0}}},PSEUDO:function(M,G){var J,Z=c.pseudos[M]||c.setFilters[M.toLowerCase()]||Dt.error("unsupported pseudo: "+M);return Z[R]?Z(G):Z.length>1?(J=[M,M,"",G],c.setFilters.hasOwnProperty(M.toLowerCase())?Qt(function(U,q){for(var tt,at=Z(U,G),ht=at.length;ht--;)tt=ut(U,at[ht]),U[tt]=!(q[tt]=at[ht])}):function(U){return Z(U,0,J)}):Z}},pseudos:{not:Qt(function(M){var G=[],J=[],Z=g(M.replace(he,"$1"));return Z[R]?Qt(function(U,q,tt,at){for(var ht,gt=Z(U,null,at,[]),xt=U.length;xt--;)(ht=gt[xt])&&(U[xt]=!(q[xt]=ht))}):function(U,q,tt){return G[0]=U,Z(G,null,tt,J),G[0]=null,!J.pop()}}),has:Qt(function(M){return function(G){return Dt(M,G).length>0}}),contains:Qt(function(M){return M=M.replace(mt,vt),function(G){return(G.textContent||l(G)).indexOf(M)>-1}}),lang:Qt(function(M){return kt.test(M||"")||Dt.error("unsupported lang: "+M),M=M.replace(mt,vt).toLowerCase(),function(G){var J;do if(J=T?G.lang:G.getAttribute("xml:lang")||G.getAttribute("lang"))return J=J.toLowerCase(),J===M||J.indexOf(M+"-")===0;while((G=G.parentNode)&&G.nodeType===1);return!1}}),target:function(M){var G=r.location&&r.location.hash;return G&&G.slice(1)===M.id},root:function(M){return M===y},focus:function(M){return M===m.activeElement&&(!m.hasFocus||m.hasFocus())&&!!(M.type||M.href||~M.tabIndex)},enabled:sn(!1),disabled:sn(!0),checked:function(M){var G=M.nodeName.toLowerCase();return G==="input"&&!!M.checked||G==="option"&&!!M.selected},selected:function(M){return M.parentNode&&M.parentNode.selectedIndex,M.selected===!0},empty:function(M){for(M=M.firstChild;M;M=M.nextSibling)if(M.nodeType<6)return!1;return!0},parent:function(M){return!c.pseudos.empty(M)},header:function(M){return lt.test(M.nodeName)},input:function(M){return Ft.test(M.nodeName)},button:function(M){var G=M.nodeName.toLowerCase();return G==="input"&&M.type==="button"||G==="button"},text:function(M){var G;return M.nodeName.toLowerCase()==="input"&&M.type==="text"&&((G=M.getAttribute("type"))==null||G.toLowerCase()==="text")},first:Ue(function(){return[0]}),last:Ue(function(M,G){return[G-1]}),eq:Ue(function(M,G,J){return[J<0?J+G:J]}),even:Ue(function(M,G){for(var J=0;JG?G:J;--Z>=0;)M.push(Z);return M}),gt:Ue(function(M,G,J){for(var Z=J<0?J+G:J;++Z1?function(G,J,Z){for(var U=M.length;U--;)if(!M[U](G,J,Z))return!1;return!0}:M[0]}function Bn(M,G,J){for(var Z=0,U=G.length;Z-1&&(tt[xt]=!(at[xt]=Lt))}}else se=fn(se===at?se.splice(Mt,se.length):se),U?U(null,at,se,gt):nt.apply(at,se)})}function Cn(M){for(var G,J,Z,U=M.length,q=c.relative[M[0].type],tt=q||c.relative[" "],at=q?1:0,ht=me(function(Tt){return Tt===G},tt,!0),gt=me(function(Tt){return ut(G,Tt)>-1},tt,!0),xt=[function(Tt,Lt,Yt){var Et=!q&&(Yt||Lt!==v)||((G=Lt).nodeType?ht(Tt,Lt,Yt):gt(Tt,Lt,Yt));return G=null,Et}];at1&&_n(xt),at>1&&gn(M.slice(0,at-1).concat({value:M[at-2].type===" "?"*":""})).replace(he,"$1"),J,at0,Z=M.length>0,U=function(q,tt,at,ht,gt){var xt,Tt,Lt,Yt=0,Et="0",Mt=q&&[],Ee=[],Re=v,se=q||Z&&c.find.TAG("*",gt),Ze=b+=Re==null?1:Math.random()||.1,kn=se.length;for(gt&&(v=tt==m||tt||gt);Et!==kn&&(xt=se[Et])!=null;Et++){if(Z&&xt){for(Tt=0,!tt&&xt.ownerDocument!=m&&(A(xt),at=!T);Lt=M[Tt++];)if(Lt(xt,tt||m,at)){ht.push(xt);break}gt&&(b=Ze)}J&&((xt=!Lt&&xt)&&Yt--,q&&Mt.push(xt))}if(Yt+=Et,J&&Et!==Yt){for(Tt=0;Lt=G[Tt++];)Lt(Mt,Ee,tt,at);if(q){if(Yt>0)for(;Et--;)Mt[Et]||Ee[Et]||(Ee[Et]=V.call(ht));Ee=fn(Ee)}nt.apply(ht,Ee),gt&&!q&&Ee.length>0&&Yt+G.length>1&&Dt.uniqueSort(ht)}return gt&&(b=Ze,v=Re),Mt};return J?Qt(U):U}g=Dt.compile=function(M,G){var J,Z=[],U=[],q=F[M+" "];if(!q){for(G||(G=f(M)),J=G.length;J--;)q=Cn(G[J]),q[R]?Z.push(q):U.push(q);q=F(M,ur(U,Z)),q.selector=M}return q},i=Dt.select=function(M,G,J,Z){var U,q,tt,at,ht,gt=typeof M=="function"&&M,xt=!Z&&f(M=gt.selector||M);if(J=J||[],xt.length===1){if(q=xt[0]=xt[0].slice(0),q.length>2&&(tt=q[0]).type==="ID"&&G.nodeType===9&&T&&c.relative[q[1].type]){if(G=(c.find.ID(tt.matches[0].replace(mt,vt),G)||[])[0],G)gt&&(G=G.parentNode);else return J;M=M.slice(q.shift().value.length)}for(U=Ut.needsContext.test(M)?0:q.length;U--&&(tt=q[U],!c.relative[at=tt.type]);)if((ht=c.find[at])&&(Z=ht(tt.matches[0].replace(mt,vt),st.test(q[0].type)&&dn(G.parentNode)||G))){if(q.splice(U,1),M=Z.length&&gn(q),!M)return nt.apply(J,Z),J;break}}return(gt||g(M,xt))(Z,G,!T,J,!G||st.test(M)&&dn(G.parentNode)||G),J},u.sortStable=R.split("").sort(W).join("")===R,u.detectDuplicates=!!p,A(),u.sortDetached=qt(function(M){return M.compareDocumentPosition(m.createElement("fieldset"))&1}),qt(function(M){return M.innerHTML="",M.firstChild.getAttribute("href")==="#"})||He("type|href|height|width",function(M,G,J){if(!J)return M.getAttribute(G,G.toLowerCase()==="type"?1:2)}),(!u.attributes||!qt(function(M){return M.innerHTML="",M.firstChild.setAttribute("value",""),M.firstChild.getAttribute("value")===""}))&&He("value",function(M,G,J){if(!J&&M.nodeName.toLowerCase()==="input")return M.defaultValue}),qt(function(M){return M.getAttribute("disabled")==null})||He(et,function(M,G,J){var Z;if(!J)return M[G]===!0?G.toLowerCase():(Z=M.getAttributeNode(G))&&Z.specified?Z.value:null});var Xn=r.Sizzle;Dt.noConflict=function(){return r.Sizzle===Dt&&(r.Sizzle=Xn),Dt},d=function(){return Dt}.call(E,o,E,w),d!==void 0&&(w.exports=d)})(window)},7178:(w,E,o)=>{var d,r;d=[o(8934),o(7792),o(2134),o(8663),o(454),o(6981),o(7661),o(8048),o(461),o(1045),o(6525),o(5385)],r=function(n,u,c,l,s,f,g){"use strict";var i=/%20/g,v=/#.*$/,h=/([?&])_=[^&]*/,p=/^(.*?):[ \t]*([^\r\n]*)$/mg,A=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,m=/^(?:GET|HEAD)$/,y=/^\/\//,T={},x={},C="*/".concat("*"),D=u.createElement("a");D.href=s.href;function _(L){return function(k,F){typeof k!="string"&&(F=k,k="*");var H,W=0,z=k.toLowerCase().match(l)||[];if(c(F))for(;H=z[W++];)H[0]==="+"?(H=H.slice(1)||"*",(L[H]=L[H]||[]).unshift(F)):(L[H]=L[H]||[]).push(F)}}function R(L,k,F,H){var W={},z=L===x;function $(V){var Y;return W[V]=!0,n.each(L[V]||[],function(nt,it){var ut=it(k,F,H);if(typeof ut=="string"&&!z&&!W[ut])return k.dataTypes.unshift(ut),$(ut),!1;if(z)return!(Y=ut)}),Y}return $(k.dataTypes[0])||!W["*"]&&$("*")}function N(L,k){var F,H,W=n.ajaxSettings.flatOptions||{};for(F in k)k[F]!==void 0&&((W[F]?L:H||(H={}))[F]=k[F]);return H&&n.extend(!0,L,H),L}function b(L,k,F){for(var H,W,z,$,V=L.contents,Y=L.dataTypes;Y[0]==="*";)Y.shift(),H===void 0&&(H=L.mimeType||k.getResponseHeader("Content-Type"));if(H){for(W in V)if(V[W]&&V[W].test(H)){Y.unshift(W);break}}if(Y[0]in F)z=Y[0];else{for(W in F){if(!Y[0]||L.converters[W+" "+Y[0]]){z=W;break}$||($=W)}z=z||$}if(z)return z!==Y[0]&&Y.unshift(z),F[z]}function P(L,k,F,H){var W,z,$,V,Y,nt={},it=L.dataTypes.slice();if(it[1])for($ in L.converters)nt[$.toLowerCase()]=L.converters[$];for(z=it.shift();z;)if(L.responseFields[z]&&(F[L.responseFields[z]]=k),!Y&&H&&L.dataFilter&&(k=L.dataFilter(k,L.dataType)),Y=z,z=it.shift(),z){if(z==="*")z=Y;else if(Y!=="*"&&Y!==z){if($=nt[Y+" "+z]||nt["* "+z],!$){for(W in nt)if(V=W.split(" "),V[1]===z&&($=nt[Y+" "+V[0]]||nt["* "+V[0]],$)){$===!0?$=nt[W]:nt[W]!==!0&&(z=V[0],it.unshift(V[1]));break}}if($!==!0)if($&&L.throws)k=$(k);else try{k=$(k)}catch(ut){return{state:"parsererror",error:$?ut:"No conversion from "+Y+" to "+z}}}}return{state:"success",data:k}}return n.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:s.href,type:"GET",isLocal:A.test(s.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":C,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":n.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(L,k){return k?N(N(L,n.ajaxSettings),k):N(n.ajaxSettings,L)},ajaxPrefilter:_(T),ajaxTransport:_(x),ajax:function(L,k){typeof L=="object"&&(k=L,L=void 0),k=k||{};var F,H,W,z,$,V,Y,nt,it,ut,et=n.ajaxSetup({},k),dt=et.context||et,yt=et.context&&(dt.nodeType||dt.jquery)?n(dt):n.event,Ot=n.Deferred(),ie=n.Callbacks("once memory"),ge=et.statusCode||{},he={},ve={},_e="canceled",Rt={readyState:0,getResponseHeader:function(kt){var Ut;if(Y){if(!z)for(z={};Ut=p.exec(W);)z[Ut[1].toLowerCase()+" "]=(z[Ut[1].toLowerCase()+" "]||[]).concat(Ut[2]);Ut=z[kt.toLowerCase()+" "]}return Ut==null?null:Ut.join(", ")},getAllResponseHeaders:function(){return Y?W:null},setRequestHeader:function(kt,Ut){return Y==null&&(kt=ve[kt.toLowerCase()]=ve[kt.toLowerCase()]||kt,he[kt]=Ut),this},overrideMimeType:function(kt){return Y==null&&(et.mimeType=kt),this},statusCode:function(kt){var Ut;if(kt)if(Y)Rt.always(kt[Rt.status]);else for(Ut in kt)ge[Ut]=[ge[Ut],kt[Ut]];return this},abort:function(kt){var Ut=kt||_e;return F&&F.abort(Ut),Se(0,Ut),this}};if(Ot.promise(Rt),et.url=((L||et.url||s.href)+"").replace(y,s.protocol+"//"),et.type=k.method||k.type||et.method||et.type,et.dataTypes=(et.dataType||"*").toLowerCase().match(l)||[""],et.crossDomain==null){V=u.createElement("a");try{V.href=et.url,V.href=V.href,et.crossDomain=D.protocol+"//"+D.host!=V.protocol+"//"+V.host}catch(kt){et.crossDomain=!0}}if(et.data&&et.processData&&typeof et.data!="string"&&(et.data=n.param(et.data,et.traditional)),R(T,et,k,Rt),Y)return Rt;nt=n.event&&et.global,nt&&n.active++===0&&n.event.trigger("ajaxStart"),et.type=et.type.toUpperCase(),et.hasContent=!m.test(et.type),H=et.url.replace(v,""),et.hasContent?et.data&&et.processData&&(et.contentType||"").indexOf("application/x-www-form-urlencoded")===0&&(et.data=et.data.replace(i,"+")):(ut=et.url.slice(H.length),et.data&&(et.processData||typeof et.data=="string")&&(H+=(g.test(H)?"&":"?")+et.data,delete et.data),et.cache===!1&&(H=H.replace(h,"$1"),ut=(g.test(H)?"&":"?")+"_="+f.guid+++ut),et.url=H+ut),et.ifModified&&(n.lastModified[H]&&Rt.setRequestHeader("If-Modified-Since",n.lastModified[H]),n.etag[H]&&Rt.setRequestHeader("If-None-Match",n.etag[H])),(et.data&&et.hasContent&&et.contentType!==!1||k.contentType)&&Rt.setRequestHeader("Content-Type",et.contentType),Rt.setRequestHeader("Accept",et.dataTypes[0]&&et.accepts[et.dataTypes[0]]?et.accepts[et.dataTypes[0]]+(et.dataTypes[0]!=="*"?", "+C+"; q=0.01":""):et.accepts["*"]);for(it in et.headers)Rt.setRequestHeader(it,et.headers[it]);if(et.beforeSend&&(et.beforeSend.call(dt,Rt,et)===!1||Y))return Rt.abort();if(_e="abort",ie.add(et.complete),Rt.done(et.success),Rt.fail(et.error),F=R(x,et,k,Rt),!F)Se(-1,"No Transport");else{if(Rt.readyState=1,nt&&yt.trigger("ajaxSend",[Rt,et]),Y)return Rt;et.async&&et.timeout>0&&($=window.setTimeout(function(){Rt.abort("timeout")},et.timeout));try{Y=!1,F.send(he,Se)}catch(kt){if(Y)throw kt;Se(-1,kt)}}function Se(kt,Ut,We,Ft){var lt,Ct,It,st,mt,vt=Ut;Y||(Y=!0,$&&window.clearTimeout($),F=void 0,W=Ft||"",Rt.readyState=kt>0?4:0,lt=kt>=200&&kt<300||kt===304,We&&(st=b(et,Rt,We)),!lt&&n.inArray("script",et.dataTypes)>-1&&n.inArray("json",et.dataTypes)<0&&(et.converters["text script"]=function(){}),st=P(et,st,Rt,lt),lt?(et.ifModified&&(mt=Rt.getResponseHeader("Last-Modified"),mt&&(n.lastModified[H]=mt),mt=Rt.getResponseHeader("etag"),mt&&(n.etag[H]=mt)),kt===204||et.type==="HEAD"?vt="nocontent":kt===304?vt="notmodified":(vt=st.state,Ct=st.data,It=st.error,lt=!It)):(It=vt,(kt||!vt)&&(vt="error",kt<0&&(kt=0))),Rt.status=kt,Rt.statusText=(Ut||vt)+"",lt?Ot.resolveWith(dt,[Ct,vt,Rt]):Ot.rejectWith(dt,[Rt,vt,It]),Rt.statusCode(ge),ge=void 0,nt&&yt.trigger(lt?"ajaxSuccess":"ajaxError",[Rt,et,lt?Ct:It]),ie.fireWith(dt,[Rt,vt]),nt&&(yt.trigger("ajaxComplete",[Rt,et]),--n.active||n.event.trigger("ajaxStop")))}return Rt},getJSON:function(L,k,F){return n.get(L,k,F,"json")},getScript:function(L,k){return n.get(L,void 0,k,"script")}}),n.each(["get","post"],function(L,k){n[k]=function(F,H,W,z){return c(H)&&(z=z||W,W=H,H=void 0),n.ajax(n.extend({url:F,type:k,dataType:z,data:H,success:W},n.isPlainObject(F)&&F))}}),n.ajaxPrefilter(function(L){var k;for(k in L.headers)k.toLowerCase()==="content-type"&&(L.contentType=L.headers[k]||"")}),n}.apply(E,d),r!==void 0&&(w.exports=r)},7533:(w,E,o)=>{var d,r;d=[o(8934),o(2134),o(6981),o(7661),o(7178)],r=function(n,u,c,l){"use strict";var s=[],f=/(=)\?(?=&|$)|\?\?/;n.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var g=s.pop()||n.expando+"_"+c.guid++;return this[g]=!0,g}}),n.ajaxPrefilter("json jsonp",function(g,i,v){var h,p,A,m=g.jsonp!==!1&&(f.test(g.url)?"url":typeof g.data=="string"&&(g.contentType||"").indexOf("application/x-www-form-urlencoded")===0&&f.test(g.data)&&"data");if(m||g.dataTypes[0]==="jsonp")return h=g.jsonpCallback=u(g.jsonpCallback)?g.jsonpCallback():g.jsonpCallback,m?g[m]=g[m].replace(f,"$1"+h):g.jsonp!==!1&&(g.url+=(l.test(g.url)?"&":"?")+g.jsonp+"="+h),g.converters["script json"]=function(){return A||n.error(h+" was not called"),A[0]},g.dataTypes[0]="json",p=window[h],window[h]=function(){A=arguments},v.always(function(){p===void 0?n(window).removeProp(h):window[h]=p,g[h]&&(g.jsonpCallback=i.jsonpCallback,s.push(h)),A&&u(p)&&p(A[0]),A=p=void 0}),"script"})}.apply(E,d),r!==void 0&&(w.exports=r)},4581:(w,E,o)=>{var d,r;d=[o(8934),o(4552),o(2134),o(2889),o(7178),o(8482),o(2632),o(655)],r=function(n,u,c){"use strict";n.fn.load=function(l,s,f){var g,i,v,h=this,p=l.indexOf(" ");return p>-1&&(g=u(l.slice(p)),l=l.slice(0,p)),c(s)?(f=s,s=void 0):s&&typeof s=="object"&&(i="POST"),h.length>0&&n.ajax({url:l,type:i||"GET",dataType:"html",data:s}).done(function(A){v=arguments,h.html(g?n("
").append(n.parseHTML(A)).find(g):A)}).always(f&&function(A,m){h.each(function(){f.apply(this,v||[A.responseText,m,A])})}),this}}.apply(E,d),r!==void 0&&(w.exports=r)},5488:(w,E,o)=>{var d,r;d=[o(8934),o(7792),o(7178)],r=function(n,u){"use strict";n.ajaxPrefilter(function(c){c.crossDomain&&(c.contents.script=!1)}),n.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(c){return n.globalEval(c),c}}}),n.ajaxPrefilter("script",function(c){c.cache===void 0&&(c.cache=!1),c.crossDomain&&(c.type="GET")}),n.ajaxTransport("script",function(c){if(c.crossDomain||c.scriptAttrs){var l,s;return{send:function(f,g){l=n(" + diff --git a/api/middlewares/checkHeaders.js b/api/middlewares/checkHeaders.js index 822b7e7..fb03c8a 100755 --- a/api/middlewares/checkHeaders.js +++ b/api/middlewares/checkHeaders.js @@ -1,47 +1,51 @@ const conf = require(`${process.env.dirtown}/conf.json`); /** - * @api{get}/CheckHeaders + * @api {get} http://header/CheckHeaders - CheckHeaders * @apiGroup Middlewares * @apiName CheckHeaders - * @apiDescription a list of header is mandatory to access apxtrib see tribes/townconf.json.exposedHeaders + * @apiDescription a list of headers are mandatory to access apxtrib see in your space town /conf.json.exposedHeaders * - * @apiHeader {string} xalias anonymous or unique alias - * @apiHeader {string} xapp name of the webapp store in tribe/tribeid/www/xapp + * @apiHeader {string} xalias 'anonymous' or unique alias + * @apiHeader {string} xapp name of the webapp store in tribe/tribeid/www/{xapp} * @apiHeader {string} xlang the 2 letter request langage (if does not exist then return en = english). - * @apiHeader {string} xtribe unique tribe name ere xapp exist + * @apiHeader {string} xtribe unique tribe name where xapp exist * @apiHeader {string} xdays a timestamp 0 or generate during the authentifyme process * @apiHeader {string} xhash anonymous or signature of message: xalias_xdays created by alias private key during authentifyme process * @apiHeader {array[]} xprofils list of string profil apply into xtribe for xapp - * @apiHeader {string} xuuid a unique number c reated the fisrt time a domain is visited + * @apiHeader {string} xuuid a unique number uuid.v4 created the fisrt time a domain is visited on a device * @apiHeader {integer} xtrkversion a version number link to tracking system * - * @apiError missingexposedHeaders it miss an exposedHeaders - * @apiErrorExample {json} Error-Response: - * HTTP/1/1 400 Not Found - * { - * status:400, - * ref:"middlewares" - * msg:"missingheaders", - * data: ["headermissing1"] - * } - *@apiErrorExample {json} Error-Response: - * HTTP/1/1 404 Not Found - * { - * status:404, - * ref:"middlewares" - * msg:"tribeiddoesnotexist", - * data: {xalias} - * } - * @apiHeaderExample {json} Header-Exemple: - * { - * xtribe:"apache", - * xalias:"toto", - * xhash:"", - * xdays:"123" - * xlang:"en", - * xapp:"popular" - * } - */ + * @apiHeaderExample {json} Header-Example: + * { + * Cache-Control: "no-cache", + * Expires: 0, Pragma:"no-cache", + * xalias:"jojo", + * xapp:"presentation", + * xdays:1700733068298 + * xhash:"LS0tLS1CRUdJTiBQR1AgU0lHTkVEIE1FU1NBR0UtLS0tLQpIYXNoOiBTSEE1MTIKCmpvam9fMTcwMDczMzA2ODI5OAotLS0tLUJFR0lOIFBHUCBTSUdOQVRVUkUtLS0tLQoKd25VRUFSWUtBQ2NGZ21WZklJd0prTmFVQ0daRHVUYnBGaUVFTjZlc1ZMSWdURmtPRGFVaDFwUUlaa081Ck51a0FBR09MQVA5OS96c21YeEd0b0VuYnpnekppZDJMcDA3YlBNZ1gwNUdhOUFVWjlCQm91Z0VBOVlYVworYjZIM2JHWHVhbEVOc3BrdUk1alNlTFNUWGNkSStjTExTZk5OQTg9Cj1uVjhNCi0tLS0tRU5EIFBHUCBTSUdOQVRVUkUtLS0tLQo=", + * xlang:"fr", + * xprofils:["anonymous", "pagans"], + * xtribe:"smatchit", + * xtrkversion:1, + * xuuid:"ea1cf73f-27f5-4c69-ab53-197a0feab9b2" + * } + * @apiErrorExample {json} Error-Response: + * HTTP/1/1 400 Not Found + * { + * status:400, + * ref:"middlewares", + * msg:"missingheaders", + * data:["headermissing1"] + * } + * @apiErrorExample {json} Error-Response: + * HTTP/1/1 404 Not Found + * { + * status:404, + * ref:"middlewares" + * msg:"tribeiddoesnotexist", + * data: {xalias} + * } + */ const checkHeaders = (req, res, next) => { req.session = {}; const header = {}; @@ -66,6 +70,7 @@ const checkHeaders = (req, res, next) => { if (missingheader != "") { // bad request return res.status(400).json({ + status:400, ref: "middlewares", msg: "missingheader", data: missingheader, @@ -80,6 +85,7 @@ const checkHeaders = (req, res, next) => { ) ) { return res.status(404).json({ + status:404, ref: "middlewares", msg: "tribeiddoesnotexist", data: { xtribe: header.xtribe }, diff --git a/api/middlewares/header.md b/api/middlewares/header.md index be5c59a..21fde47 100644 --- a/api/middlewares/header.md +++ b/api/middlewares/header.md @@ -14,13 +14,9 @@ Objects manage in apXtrib: pagans, notifications, nations, towns, tribes, wwws  All others objects are manage in town/tribe  -persons is the only exception, schema is manage in apXtrib but data are store in a tribe. - -apxtrib conf is set in a conf.json at the same folder level: - ```plaintext /apxtrib/ # core process -/townName_nationName/conf.json # town settings +/townName_nationName/conf.json # town settings contain all glabl parameter ``` url: **/api/routeName** For core api apXtrib in /apxtrib : @@ -29,7 +25,7 @@ url: **/api/routeName** For core api apXtrib in /apxtrib : /apxtrib/api/middlewares/ /apxtrib/api/routes/ /apxtrib/api/models/ -/apxtrib/api/models/lg/ language customisation for api response +/apxtrib/api/models/lg/ lauage accessible by https://wall-ants.ndda.fr/nationchains/models/Checkjson_fr.json /apxtrib/api/models/unitest/ ``` @@ -38,13 +34,11 @@ url: **/api/smatchit/routeName** for tribe smatchit example api in /town\_nation ```plaintext /town_nation/tribes/smatchit/api/routes/ /town_nation/tribes/smatchit/api/models/ -/town_nation/tribes/smatchit/api/models/lg/ language customization +/town_nation/tribes/smatchit/api/models/lg/ language customization accessible https://smatchit.io/smatchit/models/model_lg.json ``` **static files** are served by nginx, each tribe nginx conf are store and can be customize in /town\_nation/www/nginx\_xtribe\_xapp.conf -object www/websitename are serve with nginx not express. - ## Object management (Odmdb) An object has a name and is defined by a schema that contain properties key. @@ -52,6 +46,8 @@ An object has a name and is defined by a schema that contain properties key. A propertie has a name and a list of caracteristics (type, pattern,format,...) that have to be validate to be accepted. All properties respect the rules [https://json-schema.org/draft/2020-12/schema,](https://json-schema.org/draft/2020-12/schema,) some extra"format" can be add to mutualise recurrent regex pattern +To access a schema [https://wall-ants.ndda.fr/nationchains/schema/nations.json](https://wall-ants.ndda.fr/nationchains/schema/nations.json) and language specifique [https//:wall-ants.ndda.fr/nationchains/schema/lg/nations\_fr.json](https//:wall-ants.ndda.fr/nationchains/schema/lg/nations_fr.json) + A checkjson.js is available to manage all specific format [https://wall-ants.ndda.fr/Checkjson.js](https://wall-ants.ndda.fr/Checkjson.js) see **Odmdb - schema Checkjson** **Additional properties that not exist in 2020-12/schema :** @@ -75,26 +71,7 @@ Items of an object are store in files into :   ## api pre-request -**Valid header** - -A ‘private’ request to pass must contain exposeHeaders from town conf.json - -api.exposedHeaders :\["xdays", "xhash", "xalias", "xlang", "xtribe", "xapp", "xuuid" \] - -By default for anonymous user: - -```plaintext -{"headers":{ - "xtrkversion":1, - "xtribe":"tribeid ex: smatchit", - "xapp":"websitename ex:presentation", - "xlang":"fr", - "xalias":"anonymous", - "xhash":"anonymous", - "xdays":0 - } -} -``` +**Valid header see Middlewares** App use openpgp.js lib to sign xdays\_xalias with a privatekey and store it in xhash. @@ -102,22 +79,31 @@ App use openpgp.js lib to sign xdays\_xalias with a privatekey and store it in x See Pagans models that contain authentification process -**api Return can be direct json in case of get without authenntification or an object data** +**api Return in 3 data structure:** -{status, ref,msg,data}: +A - data file from a classical get  [https://wall-ants.ndda.fr/Checkjson.js](https://smatchit.io/Checkjson.js) + +B -  a json single answer {status, ref,msg,data}: * status: http code return * ref: model/route name reference where message come from * msg: a message template key store into models/lg/name\_lg.json (where lg is 2 letters language) * data: an object data use to render the value of the message key. +C - a json multi answer {status,multimsg:\[{ref,msg,data}\]} + +         Each {ref,msg,data\] work the same way than B + +To show feedback context message in a language lg => get /nationchains/models/{{ref}}\_{{lg}}.json +This contain a json {msg:"mustache template string to render with data"}   + ## Accessrights: -An alias is just an identity, to access a tribe a person must exist with alias into /town/tribes/tribename/persons/itm/alias.json +An alias is just an identity, to access a tribe, a person must exist with an authenticated alias into /town/tribes/tribename/persons/itm/alias.json -A person has a property profils with a list of profilename, common profiles are : pagan (an identity)  / person (an identity with access right in a tribe) / druid (the administrator of a tribe) / major (administrator of a town/server) +A person has a property profils with a list of profilename, common profiles are : anonymous (no identity) / pagan (an identity)  / person (an identity with access right into a tribe) / druid (the administrator of a tribe) / major (administrator of a town/server) -Into a tribe you can have many other profil with specifics accessright on tribe's object. +Each object has an apxaccessrights that is a list of profil and CRUD access per object key . ## Add tribe's api: diff --git a/api/middlewares/isAuthenticated.js b/api/middlewares/isAuthenticated.js index 3ab1129..019d580 100755 --- a/api/middlewares/isAuthenticated.js +++ b/api/middlewares/isAuthenticated.js @@ -6,52 +6,28 @@ const glob = require("glob"); const openpgp = require("openpgp"); /** - * @api{get}/istauthenticated + * @api {get} http://header/istauthenticated - isAuthenticated * @apiGroup Middlewares - * @apiName isAUthenticated - * @apiDescription Check that exist in town/tmp/tokens/xalias_xdays_xhash.substr(20,200) if not, check the xhash signature with message xalias_xdays come from public key belonging to xalias. If check pass then store a xhash into /tmp/tokens. - * A process run each day to clean up all xhas tmp/tokens oldest than 24 hours. - * If authentify it returns header with xprofils store into a person objject -xtribes/person/alias - * - * @apiHeader {string} xalias anonymous or unique alias - * @apiHeader {string} xapp name of the webapp store in tribe/tribeid/www/xapp - * @apiHeader {string} xlang the 2 letter request langage (if does not exist then return en = english). - * @apiHeader {string} xtribe unique tribe name ere xapp exist - * @apiHeader {string} xdays a timestamp 0 or generate during the authentifyme process - * @apiHeader {string} xhash anonymous or signature of message: xalias_xdays created by alias private key during authentifyme process - * @apiHeader {array[]} xprofils list of string profil apply into xtribe for xapp - * @apiHeader {string} xuuid a unique number c reated the fisrt time a domain is visited - * @apiHeader {integer} xtrkversion a version number link to tracking system - * - * @apiErrorExample {json} Error-Response: - * HTTP/1/1 400 Not Found - * { - * status:400, - * ref:"middlewares" - * msg:"missingheaders", - * data: ["headermissing1"] - * } - *@apiErrorExample {json} Error-Response: - * HTTP/1/1 404 Not Found - * { - * status:404, - * ref:"middlewares" - * msg:"tribeiddoesnotexist", - * data: {xalias} - * } - * - * @apiHeaderExample {json} Header-Exemple: - * { - * xtribe:"apache", - * xalias:"toto", - * xhash:"", - * xdays:"123" - * xlang:"en", - * xapp:"popular" - * } + * @apiName isAuthenticated + * @apiDescription - valid if exist xalias_xdays_xhash.substr(20,200) in town/tmp/tokens/ + * - if not, + * - valid if xhash signature sign xalias_xdays with alias's publickey. + * - if not valid => not allowed + * - If valid => + * - store a xalias_xdays_xhash.substr (20,200) into /tmp/tokens with xprofils array from person. + * - update header.xprofils from this token + * + * apXtrib profils are anonymous, pagans, mayor (on a node server), druid (on a tribe like smatchit). + * + * pagan identity is independant of domain (tribe), by default profils are :['anonymous','pagans']. if this alias exist in a tribe domain as a person then his profils come from /tribes/{tribeId}/objects/person/itm/{alias}.json profils:['anonymous','pagans','person','seeker'] any profils allowed to act on tribe objects. + * + * Each profil have CRUD accessright on object managed in schema in apxaccessrights:{owner,profil:{"C":[],"R":[properties],"U":[properties],"D":[]}}, see Odmdb for details. + * + * A process run once each day to clean up all xhash tmp/tokens oldest than 24 hours. + * **/ const isAuthenticated = async (req, res, next) => { - const withlog = true; + const withlog = false; const currentday = dayjs().date(); fs.ensureDirSync(`${process.env.dirtown}/tmp/tokens`); let menagedone = fs.existsSync( @@ -197,8 +173,7 @@ const isAuthenticated = async (req, res, next) => { return res.status(resnotauth.status).send(resnotauth); } // authenticated then get person profils (person = pagan for a xtrib) - req.session.header.xprofils.push("pagans"); - const person = `${process.env.dirtown}/tribes/${req.session.header.xtribe}/persons/itm/${req.session.header.xalias}.json`; + const person = `${process.env.dirtown}/tribes/${req.session.header.xtribe}/objects/persons/itm/${req.session.header.xalias}.json`; if (withlog) { console.log("Profils tribe/app management"); console.log("person", person); @@ -206,7 +181,11 @@ const isAuthenticated = async (req, res, next) => { if (fs.existsSync(person)) { const infoperson = fs.readJSONSync(person); console.log(infoperson); - infoperson.profils.forEach((p) => req.session.header.xprofils.push(p)); + infoperson.profils.forEach((p) => { + if (!req.session.header.xprofils.includes(p)) req.session.header.xprofils.push(p); + }) + }else{ + if (!req.session.header.xprofils.includes('pagans')) req.session.header.xprofils.push("pagans"); } fs.outputJSONSync(tmpfs, req.session.header.xprofils); } else { diff --git a/api/models/Checkjson.js b/api/models/Checkjson.js index 6f10522..2cc2dc3 100755 --- a/api/models/Checkjson.js +++ b/api/models/Checkjson.js @@ -12,6 +12,7 @@ Checkjson.schema.properties = {}; Checkjson.schema.properties.type = {}; Checkjson.schema.properties.type.string = (str) => typeof str === "string"; Checkjson.schema.properties.type.array = (val) => Array.isArray(val); +Checkjson.schema.properties.type.object = (val) => typeof val === 'object' && val !== null && !Array.isArray(val); Checkjson.schema.properties.type.number = (n) => typeof n === "number"; Checkjson.schema.properties.type.boolean = (n) => typeof n === "boolean"; Checkjson.schema.properties.type.integer = (n) => @@ -130,18 +131,25 @@ Checkjson.schema.validation = (schema) => { } if ( properties[p].type && - typeof properties[p].type === "object" && - Array.isArray(properties[p].type) - ) { - properties[p].type.forEach((tp) => { - if (!Checkjson.schema.properties.type[tp]) + typeof properties[p].type === "object"){ + if (properties[p]['$ref']){ + //This is manage by Odmdb.schema to load recursively complex schema multimsg.push({ ref: "Checkjson", - msg: "schemaerrtypedoesnotexist", - data: { propertie: p, type: properties[p].type }, - }); - }); - } + msg: "externalrefnotload", + data: { propertie: p, ref: properties[p]["$ref"]}, + }); + } + //case type=="object" with properties + if (properties[p].properties){ + const checksub = Checkjson.schema.validation(properties[p]) + if (checksub.status!=200){ + multimsg = multimsg.concat(checksub.multimsg) + } + } + // if not $ref or no properties then any object is accepted + } + if ( properties[p].format && !Checkjson.schema.properties.format[properties[p].format] @@ -189,40 +197,38 @@ Checkjson.schema.data = (schema, data, withschemacheck) => { console.log('---------') console.log(data) */ - if (withschemacheck) { - const validschema = Checkjson.schema.validation(schema); - if (validschema.status != 200) return validschema; - } - const multimsg = []; - const res = { - status: 200, - data: { itm: data }, - }; - if (schema.properties) { - const properties = schema.properties; + const propertiescheck=(properties,subdata)=>{ + // properties ={prop1:{type,format},prop2:{type:object,...}} + // subdata={prop1,prop2} + // Return [] => no error, else 1 item per error {msg,ref:checkjson,data} + let multimsg=[] Object.keys(properties).forEach((p) => { //type is mandatory in a propertie - if (data[p]) { + if (subdata[p]) { + if (properties[p].properties){ + //means it is a subobject + multimsg=multimsg.concat(propertiescheck(properties[p].properties,subdata[p])) + } + //type can be a list of string; number, array, boolean, object, null const typlist = properties[p].type && typeof properties[p].type === "string" ? [properties[p].type] : properties[p].type; let valid = false; typlist.forEach((typ) => { - // at least one test have to be ok - if (Checkjson.schema.properties.type[typ](data[p])) valid = true; + // at least one test have to be valid + if (Checkjson.schema.properties.type[typ](subdata[p])) valid = true; }); if (!valid) multimsg.push({ ref: "Checkjson", msg: "dataerrpropertie", - data: { key: p, value: data[p] }, + data: { key: p, value: subdata[p] }, }); - if ( properties[p].minLength && !Checkjson.schema.properties.minLength( - data[p], + subdata[p], properties[p].minLength ) ) { @@ -231,7 +237,7 @@ Checkjson.schema.data = (schema, data, withschemacheck) => { msg: "dataerrpropertie", data: { key: p, - value: data[p], + value: subdata[p], minLength: properties[p].minLength, }, }); @@ -239,7 +245,7 @@ Checkjson.schema.data = (schema, data, withschemacheck) => { if ( properties[p].maxLength && !Checkjson.schema.properties.maxLength( - data[p], + subdata[p], properties[p].maxLength ) ) { @@ -248,7 +254,7 @@ Checkjson.schema.data = (schema, data, withschemacheck) => { msg: "dataerrpropertie", data: { key: p, - value: data[p], + value: subdata[p], maxLength: properties[p].maxLength, }, }); @@ -256,7 +262,7 @@ Checkjson.schema.data = (schema, data, withschemacheck) => { if ( properties[p].multipleOf && !Checkjson.schema.properties.multipleOf( - data[p], + subdata[p], properties[p].multipleOf ) ) { @@ -265,7 +271,7 @@ Checkjson.schema.data = (schema, data, withschemacheck) => { msg: "dataerrpropertie", data: { key: p, - value: data[p], + value: subdata[p], multipleOf: properties[p].multipleOf, }, }); @@ -279,7 +285,7 @@ Checkjson.schema.data = (schema, data, withschemacheck) => { // test range if ( !Checkjson.schema.properties.range( - data[p], + subdata[p], properties[p].minimum, properties[p].exclusiveMinimum, properties[p].maximum, @@ -291,7 +297,7 @@ Checkjson.schema.data = (schema, data, withschemacheck) => { msg: "dataerrpropertie", data: { key: p, - value: data[p], + value: subdata[p], minimum: properties[p].minimum, maximum: properties[p].maximum, exclusiveMinimum: properties[p].exclusiveMinimum, @@ -302,12 +308,12 @@ Checkjson.schema.data = (schema, data, withschemacheck) => { } if ( properties[p].enum && - !Checkjson.schema.properties.enum(data[p], properties[p].enum) + !Checkjson.schema.properties.enum(subdata[p], properties[p].enum) ) { multimsg.push({ ref: "Checkjson", msg: "dataerrpropertie", - data: { key: p, value: data[p], enumlst: properties[p].enum }, + data: { key: p, value: subdata[p], enumlst: properties[p].enum }, }); } if (properties[p].format) { @@ -316,12 +322,12 @@ Checkjson.schema.data = (schema, data, withschemacheck) => { } if ( properties[p].pattern && - !Checkjson.schema.properties.pattern(data[p], properties[p].pattern) + !Checkjson.schema.properties.pattern(subdata[p], properties[p].pattern) ) { multimsg.push({ ref: "Checkjson", msg: "dataerrpropertie", - data: { key: p, value: data[p], pattern: properties[p].pattern }, + data: { key: p, value: subdata[p], pattern: properties[p].pattern }, }); } } else if (schema.required && schema.required.includes(p)) { @@ -332,18 +338,27 @@ Checkjson.schema.data = (schema, data, withschemacheck) => { }); } }); - } //end properties - if (schema.apxid) { - res.data.apxid = data[schema.apxid]; + return multimsg + };//end propertiescheck() + + if (withschemacheck) { + const validschema = Checkjson.schema.validation(schema); + if (validschema.status != 200) return validschema; } - if (multimsg.length > 0) { + let multi=propertiescheck(schema.properties,data) + const res = {}; + + if (multi.length > 0) { res.status = 417; - res.multimsg = multimsg; + res.multimsg = multi; } else { res.status = 200; res.ref = "Checkjson"; res.msg = "validcheck"; } + if (schema.apxid) { + res.data={apxid : data[schema.apxid],itm:data}; + } return res; }; if (typeof module !== "undefined") module.exports = Checkjson; diff --git a/api/models/Nations.js b/api/models/Nations.js index f268446..da7141a 100755 --- a/api/models/Nations.js +++ b/api/models/Nations.js @@ -113,6 +113,7 @@ Nations.updateobjectsfromfreshesttown = (dnstownlist, objectidx) => { }); } } + return {status:200,ref:"Nations",msg:"updated",data:{}}; }; Nations.synchronizeold = () => { /* diff --git a/api/models/Notifications.js b/api/models/Notifications.js index 695fe2a..d353221 100644 --- a/api/models/Notifications.js +++ b/api/models/Notifications.js @@ -11,29 +11,38 @@ const conf = require(`${process.env.dirtown}/conf.json`); * volatile notification message from tribe activities to Pagans / person () * */ - const Notifications = {}; +Notifications.get = (alias, tribeId) => { + const notiffile = `${conf.dirtown}/tribes/${req.params.tribeId}/notifications/${req.params.alias}.json`; + const msg = fs.existsSync(notiffile) ? fs.readJSONSync(notiffile) : {}; + return { + status: 200, + ref: "Notification", + msg: "Messagelist", + data: { notif: [{ tribeId, msg }] }, + }; +}; Notifications.sendsms = async (data, tribeId) => { -/** - * Never use need wallet in mailjet to test - * To set up with mailjet see https://dev.mailjet.com/sms/guides/send-sms-api/#authentication - * - * @param {string} data.To a phone number with international +3360101010101 - * @param {string} data.Text text to send - * - * a conf.sms with {url:"smsurl", Token:"", From:""} - * - * - */ + /** + * Never use need wallet in mailjet to test + * To set up with mailjet see https://dev.mailjet.com/sms/guides/send-sms-api/#authentication + * + * @param {string} data.To a phone number with international +3360101010101 + * @param {string} data.Text text to send + * + * a conf.sms with {url:"smsurl", Token:"", From:""} + * + * + */ if (!conf.sms) { return { status: 412, ref: "Notifications", msg: "missingconf", - tribe: tribeId, + data: { tribe: tribeId }, }; } let missingk = [][("To", "Text")].forEach((k) => { @@ -46,10 +55,10 @@ Notifications.sendsms = async (data, tribeId) => { status: 428, ref: "Notifications", msg: "missingdata", - missingk: missingk, + data: { missingk: missingk }, }; } - let confsms= conf.sms; + let confsms = conf.sms; if ( fs.existsSync( `${process.env.dirtown}/tribes/itm/${req.session.header.xtribe}.json` @@ -60,19 +69,28 @@ Notifications.sendsms = async (data, tribeId) => { ); if (conftrib.sms) confsms = conftrib.sms; } - data.From=confsms.From - const sendsms= await axios.post(confsms.url, - { + data.From = confsms.From; + const sendsms = await axios.post(confsms.url, { headers: { Authorization: `Bearer ${confsms.MJ_TOKEN}`, "Content-Type": "application/json", }, body: JSON.stringify(data), }); - if (sendsms.status==200){ - return {status:200,ref:"Notifications",msg:"successfullsentsms"}; - }else{ - return {status:sendsms.status, ref:"Notifications",msg:"errsendsms",err:sendsms.data} + if (sendsms.status == 200) { + return { + status: 200, + ref: "Notifications", + msg: "successfullsentsms", + data: {}, + }; + } else { + return { + status: sendsms.status, + ref: "Notifications", + msg: "errsendsms", + data: { err: sendsms.data }, + }; } /* si tout se passe bien: @@ -100,36 +118,39 @@ Notifications.sendsms = async (data, tribeId) => { Notifications.sendmail = async (data, tribe) => { /** - * @param {string} data.From an email authorized by smtp used priority from header xtribe - * @param {string} data.To list of email separate by , + * @param {string} [data.from] an email authorized by smtp used priority from header xtribe + * @param {string} data.to list of email separate by , * @param {string} data.subject * @param {string} data.html * @param {string} data.text - * @param {string} data.Cc list of email in copy - * @param {string} data.Bcc list of email in hidden copy - * @param {string} data.filelist an array of object {filename:"",pathfile:"",filetype:""} pathfile to attach as file name of type:filetype "filename" to this email + * @param {string} [data.Cc] list of email in copy + * @param {string} [data.Bcc] list of email in hidden copy + * @param {string} [data.filelist} an array of object {filename:"",pathfile:"",filetype:""} pathfile to attach as file name of type:filetype "filename" to this email * example of filetype : "text/plain", "text/csv", image/gif", "application/json", "application/zip" * * @example data - * {"From":"wall-ants.ndda.fr", - * "To":"wall-ants.ndda.fr", + * {"to":"wall-ants.ndda.fr", * "subject":"Test", * "html":"

test welcome

", * "text":"test welcome", * "attachments":[{filename:"text.txt",pathfile:"/media/phil/textA.txt","contenttype":"text/plain"}] * } - * @return {object} { status: 200, ref:"pagans",msg:"aliasexist",data: { alias, publicKey } } + * @return {object} + * { status: 200, ref:"pagans",msg:"aliasexist",data: { alias, publicKey } } * * */ - if (!conf.smtp) { + if (!conf.smtp || !conf.emailcontact) { return { status: 412, ref: "Notifications", msg: "missingconf", - tribe: tribeId, + data: { tribe: tribe }, }; } + if (!data.from) { + data.from = conf.emailcontact; + } let missingk = []; ["from", "to", "subject", "html", "text"].forEach((k) => { if (!data[k]) { @@ -138,35 +159,59 @@ Notifications.sendmail = async (data, tribe) => { }); if (missingk.lenght > 0) { return { - status: 428, + status: 428, ref: "Notifications", msg: "missingdata", - missingk: missingk, + data: { missingk: missingk }, }; } - const conftribfile=`${process.env.dirtown}/tribes/itm/${tribe}.json`; - const confsmtp =(fs.existsSync(conftribfile))? fs.readJSONSync(conftribfile).smtp : conf.smtp; - + let confsmtp = conf.smtp; + const conftribfile = `${process.env.dirtown}/tribes/itm/${tribe}.json`; + if (fs.existsSync(conftribfile)) { + const conftrib = fs.readJSONSync(conftribfile); + confsmtp = conftrib.smtp; + data.from = conftrib.emailcontact; + } + //const client = smtp.connect(confsmtp); const transporter = await nodemailer.createTransport(confsmtp); //@todo add attachments management - let missingfile=[] - if (missingfile.lenght > 0) + if (data.filelist) { + let missingfile = []; + data.filelist.forEach((fo) => { + if (fs.existsSync(fo.pathfile)){ + + }else{ missingfile.push(fo.pathfile);} + }); + if (missingfile.lenght > 0) + return { + status: 428, + ref: "Notifications", + msg: "missingfile", + data: { missingfile: missingfile }, + }; + } + console.log("data:", data); + const res = await transporter.sendMail(data); + if ( + res.accepted && + data.to.split(",").reduce((acc, m) => acc && res.accepted.includes(m), true) + ) { + data.accepted = res.accepted; + data.rejected = res.rejected; return { - status: 428, + status: 200, ref: "Notifications", - msg: "missingfile", - missingfile: missingfile, + msg: "successfullsentemail", + data, }; - try { - // Send the email - //const res = await client.sendMail(data) - const res = await transporter.sendMail(data) - //console.log('res envoie',res) - return { status: 200, ref: "Notifications", msg: "successfullsent", data }; - } catch (err) { - //console.log('err envoie',err) - return { status: 502, ref: "Notifications", msg: "errsendmail", err: err }; + } else if (res.accepted && res.rejected) { + data.accepted = res.accepted; + data.rejected = res.rejected; + return { status: 410, ref: "Notifications", msg: "errsendmail", data }; + } else { + data.errmailer = res.err; + return { status: 417, ref: "Notifications", msg: "errsendmail", data }; } }; diff --git a/api/models/Odmdb.js b/api/models/Odmdb.js index 47426da..24e5d7d 100644 --- a/api/models/Odmdb.js +++ b/api/models/Odmdb.js @@ -5,6 +5,7 @@ const dayjs = require("dayjs"); const axios = require("axios"); const conf = require(`${process.env.dirtown}/conf.json`); const Checkjson = require(`./Checkjson.js`); +const { promiseHooks } = require("v8"); /** * This manage Objects for indexing, searching, checking and act to CRUD @@ -153,72 +154,100 @@ Odmdb.updateObject = (objectPathname, meta) => {}; * @return {status:200,data:{conf:"schemaconf",schema:"schemacontent"} } */ Odmdb.Schema = (objectPathname, validschema) => { + const getpath = (schemaPath) => { + if (schemaPath.slice(-5) != ".json") schemaPath += ".json"; + if (schemaPath.substring(0, 4) == "http") { + // lance requete http pour recuperer le schema avec un await axios + } else { + if (schemaPath.substring(0, 9) == "adminapi/") { + schemaPath = `${conf.dirapi}/${schemaPath}`; + } else { + schemaPath = `${conf.dirtown}/tribes/${schemaPath}`; + } + if (!fs.existsSync(schemaPath)) { + return {}; + } else { + return fs.readJsonSync(schemaPath); + } + } + }; const confschema = fs.readJsonSync(`${objectPathname}/conf.json`); - let schemaPath = confschema.schema; const res = { status: 200, ref: "Odmdb", msg: "getschema", data: { conf: confschema }, }; - if (schemaPath.slice(-5) != ".json") schemaPath += ".json"; - if (schemaPath.substring(0, 4) == "http") { - // lance requete http pour recuperer le schema avec un await axios - } else { - if (schemaPath.substring(0, 9) == "adminapi/") { - schemaPath = `${conf.dirapi}/${schemaPath}`; - } else { - schemaPath = `${conf.dirtown}/tribes/${schemaPath}`; - } - if (!fs.existsSync(schemaPath)) { - return { - status: 404, - ref: "Odmdb", - msg: "schemanotfound", - data: { schemaPath, schema: {} }, - }; - } - res.data.schema = fs.readJsonSync(schemaPath); - if (!res.data.schema.apxid) { - return { - status: 406, - ref: "Odmdb", - msg: "missingprimarykey", - data: {}, - }; - } - if (res.data.schema.apxidx) { - //add apxidx to apxuniquekey in case not - if (!res.data.schema.apxuniquekey.includes(res.data.schema.apxid)) { - res.data.schema.apxuniquekey.push(res.data.schema.apxid); + res.data.schema = getpath(confschema.schema); + + if (Object.keys(res.data.schema).length == 0) { + return { + status: 404, + ref: "Odmdb", + msg: "schemanotfound", + data: { schemaPath, schema: {} }, + }; + } + + //looking for type:object with $ref to load and replace by ref content (ref must be adminapi/ or tribeid/) + //@todo only 1 level $ref if multi level need to rewrite with recursive call + Object.keys(res.data.schema.properties).forEach((p) => { + if ( + res.data.schema.properties[p].type == "object" && + res.data.schema.properties[p]["$ref"] + ) { + const subschema = getpath(res.data.schema.properties[p]["$ref"]); + if (Object.keys(res.data.schema).length == 0) { + res.status = 404; + res.msg = "missingref"; + res.data.missingref = res.data.schema.properties[p]["$ref"]; + return res; + } else { + subschema.description += ` from external schema: ${res.data.schema.properties[p]["$ref"]}`; + res.data.schema.properties[p] = subschema; } - res.data.schema.apxidx.forEach((idx) => { - if ( - idx.objkey && - !res.data.schema.apxuniquekey.includes(idx.keyval) && - !idx.objkey.includes(res.data.schema.apxid) - ) { - return { - status: 406, - ref: "Odmdb", - msg: "unconsistencyapxidx", - data: { - name: idx.name, - keyval: idx.keyval, - objkey: idx.objkey, - apxid: res.data.schema.apxid, - }, - }; - } - }); } - if (validschema || 1 == 1) { - // return {status:200, ref, msg} or {status!:200,multimsg:[{ref,msg;data}]} - const check = Checkjson.schema.validation(res.data.schema); - if (check.status != 200) { - res.multimsg = check.multimsg; - res.status = check.status; + }); + + if (!res.data.schema.apxid) { + return { + status: 406, + ref: "Odmdb", + msg: "missingprimarykey", + data: {}, + }; + } + if (res.data.schema.apxidx) { + //add apxidx to apxuniquekey in case not + if (!res.data.schema.apxuniquekey.includes(res.data.schema.apxid)) { + res.data.schema.apxuniquekey.push(res.data.schema.apxid); + } + res.data.schema.apxidx.forEach((idx) => { + if ( + idx.objkey && + !res.data.schema.apxuniquekey.includes(idx.keyval) && + !idx.objkey.includes(res.data.schema.apxid) + ) { + return { + status: 406, + ref: "Odmdb", + msg: "unconsistencyapxidx", + data: { + name: idx.name, + keyval: idx.keyval, + objkey: idx.objkey, + apxid: res.data.schema.apxid, + }, + }; } + }); + } + if (validschema || 1 == 1) { + // return {status:200, ref, msg} or {status!:200,multimsg:[{ref,msg;data}]} + const check = Checkjson.schema.validation(res.data.schema); + if (check.status != 200) { + res.multimsg = check.multimsg; + res.status = check.status; } } return res; @@ -243,6 +272,32 @@ Odmdb.search = (objectPath, objectName, search) => { if (schema.status != 200) return schema; }; +Odmdb.r =(objectPathname, apxid, role)=>{ + const itmf=`${objectPathname}/itm/${apxid}.json` + if (!fs.existsSync(itmf)){ + return {status:404,ref: "Odmdb",msg: "persondoesnotexist",data: {person:apxid}} + } + const getschema = Odmdb.Schema(objectPathname, true); + if (getschema.status != 200) return getschema; + const itm=fs.readJsonSync(itmf); + if (itm.owner && itm.owner == role.xalias) { + role.xprofils.push("owner"); + } + const accessright = Odmdb.accessright( + getschema.data.schema.apxaccessrights, + role + ); + if (!accessright.R) { + return {status:403, ref:"Odmdb",msg:"forbidden",data: {person:apxid}} + } + const data={} + accessright.R.forEach(p=>{ + data[p]=itm[p] + }) + return {status:200, ref:"Odmdb",msg:"found",data} +} + + /** * To get an array of item (itm) per primarykey with a list of field * Object are store in objectPath/objectName/conf.json contain @@ -252,8 +307,12 @@ Odmdb.search = (objectPath, objectName, search) => { * @role {xalias,xprofiles} allow to get accessright come from header * @propertiesfilter (optionnal) key to return for each object (if undefined then return all) * @Return {status:200; data:{uuid:{data filter by @propertiesfilter},uuid:"notfound"}} - */ -Odmdb.reads = (objectPathname, apxidlist, role, propertiesfilter) => { + +ASUP doit être gerer au niveau des view des index + + +*/ +Odmdb.ASUPreads = (objectPathname, apxidlist, role, propertiesfilter) => { const res = { status: 200, data: {} }; const getschema = Odmdb.Schema(objectPathname, true); if (getschema.status != 200) return getschema; @@ -313,6 +372,8 @@ Odmdb.reads = (objectPathname, apxidlist, role, propertiesfilter) => { * example: {"C":[],"R":[properties list],"U":[properties ist],"D":[]} */ Odmdb.accessright = (apxaccessrights, role) => { + //console.log("apxaccessrights",apxaccessrights) + //console.log("role",role) const accessright = {}; role.xprofils.forEach((p) => { if (apxaccessrights[p]) { @@ -324,6 +385,7 @@ Odmdb.accessright = (apxaccessrights, role) => { ...new Set([...accessright[act], ...apxaccessrights[p][act]]), ]; } + //console.log(act,accessright[act]) }); } }); @@ -340,7 +402,7 @@ Odmdb.accessright = (apxaccessrights, role) => { * */ -Odmdb.cud = (objectPathname, crud, itm, role) => { +Odmdb.cud = (objectPathname, crud, itm, role,runindex=true) => { const getschema = Odmdb.Schema(objectPathname, true); if (getschema.status != 200) return getschema; @@ -352,14 +414,19 @@ Odmdb.cud = (objectPathname, crud, itm, role) => { data: { missingkey: getschema.data.schema.apxid }, }; } - const pathindex=`${objectPathname}/idx/lst_${getschema.data.schema.apxid}.json`; - if (!fs.existsSync(pathindex)){ - fs.outputJSONSync(pathindex,[]) + fs.ensureDirSync(`${objectPathname}/itm/`) + fs.ensureDirSync(`${objectPathname}/idx/`) + const existid=fs.existsSync(`${objectPathname}/itm/${itm[getschema.data.schema.apxid]}.json`); + + /*const pathindex = `${objectPathname}/idx/lst_${getschema.data.schema.apxid}.json`; + if (!fs.existsSync(pathindex)) { + fs.outputJSONSync(pathindex, []); fs.ensureDirSync(`${objectPathname}/itm/`); } const existid = fs .readJSONSync(pathindex) .includes(itm[getschema.data.schema.apxid]); + */ if (existid && crud == "C") { return { status: 406, @@ -391,9 +458,11 @@ Odmdb.cud = (objectPathname, crud, itm, role) => { : {}; if (existid && itmold.owner && itmold.owner == role.xalias) { role.xprofils.push("owner"); - } else { + } + if (!existid && crud=="C" && !itm.owner) { // set owner cause this is a Create itm.owner = role.xalias; + role.xprofils.push("owner"); } //get accessright {C:[],R:[],U:[],D:[]} if exist means authorize, if array contain properties (for R and U) right is only allowed on properties const accessright = Odmdb.accessright( @@ -415,7 +484,7 @@ Odmdb.cud = (objectPathname, crud, itm, role) => { } //delete or save if (crud == "D") { - itmold["dt_delete"] = dayjs(); + itmold["dt_delete"] = dayjs().toISOString(); fs.outputJSONSync( `${objectPathname}/delitm/${itmold[getschema.data.schema.apxid]}.json`, itmold @@ -431,9 +500,9 @@ Odmdb.cud = (objectPathname, crud, itm, role) => { accessright.U.forEach((p) => { itmtostore[p] = itm[p]; }); - itmtostore.dt_update = dayjs(); + itmtostore.dt_update = dayjs().toISOString(); } - if (crud == "C") itmtostore.dt_create = dayjs(); + if (crud == "C") itmtostore.dt_create = dayjs().toISOString(); // check consistency of datatostore const chkdata = Checkjson.schema.data( getschema.data.schema, @@ -443,31 +512,109 @@ Odmdb.cud = (objectPathname, crud, itm, role) => { if (chkdata.status != 200) return chkdata; if (!getschema.data.schema.apxuniquekey) getschema.data.schema.apxuniquekey = []; - + console.log(`${objectPathname}/itm/${chkdata.data.apxid}.json`); + console.log(chkdata.data.itm); fs.outputJSONSync( `${objectPathname}/itm/${chkdata.data.apxid}.json`, chkdata.data.itm ); } - console.log("getschema", getschema); - //update idx - Odmdb.idxfromitm( - objectPathname, - crud, - itm, - itmold, - [], - getschema.data.schema - ); - getschema.data.conf.lastupdatedata = dayjs(); + //console.log("getschema", getschema); + //rebuild index if requested + console.log("runidx",runindex) + console.log(objectPathname) + if (runindex) Odmdb.runidx(objectPathname,getschema.data.schema); + getschema.data.conf.lastupdatedata = dayjs().toISOString(); fs.outputJSONSync(`${objectPathname}/conf.json`, getschema.data.conf); return { status: 200, ref: "Odmdb", msg: "cudsuccessfull", - data: { itm: chkdata.data.itm }, + data: {}, }; }; +/** + * apxidx:[list of index file + * { name: string, // filename in /idx/name.json + * type: array (list of unique value found in keyval), example: [val1, val2, val3,....] eventualy filter + * view (only unique key and object with objkey eventually filter by filter ) example: {idalias:{itm}} + * distribution (=> {val of keyval:[apxid itm value]} with ) + * keyval:string, // a propertie of type string or array + * objkeys:[] and array of properties if empty [] means all properties, if 1 element => an array of this properties + * filter : an eval function base on itm data (itm.key) that return true (return data item) or false (ignore item) + * + */ +Odmdb.runidx = (objectPathname, schema) => { + console.log(`idx for ${objectPathname}`); + if (!schema || !schema.apxid) { + const getschema = Odmdb.Schema(objectPathname, true); + if (getschema.status != 200) return getschema; + schema = getschema.data.schema; + } + const ventil = {}; + schema.apxidx.forEach((id) => { + ventil[id.name] = id; + ventil[id.name].isunique = schema.apxuniquekey.includes(id.keyval); + ventil[id.name].nbobjkey = id.objkey ? id.objkey.length : 0; + ventil[id.name].keyvaltype = schema.properties[id.keyval].type; + ventil[id.name].filter = id.filter ? id.filter.replace(/;/g, "") : ""; // check integrity of string + ventil[id.name].data = ventil[id.name].type == "array" ? [] : {}; + }); + glob.sync(`${objectPathname}/itm/*.json`).forEach((i) => { + const itm = fs.readJSONSync(i); + Object.keys(ventil).forEach((n) => { + let keep = true; + if (ventil[n].filter != "") { + try { + keep = eval(ventil[n].filter); + } catch (err) { + keep = false; + } + } + if (keep && ventil[n].type == "array" && itm[ventil[n].keyval]) { + if (ventil[n].keyvaltype == "array") { + itm[ventil[n].keyval].forEach((v) => { + if (!ventil[n].data.includes(v)) ventil[n].data.push(v); + }); + } else { + if (!ventil[n].data.includes(itm[ventil[n].keyval])) + ventil[n].data.push(itm[ventil[n].keyval]); + } + } + if ( + keep && + ventil[n].type == "view" && + ventil[n].isunique && + itm[ventil[n].keyval] + ) { + if (ventil[n].nbobjkey == 0) + ventil[n].data[itm[ventil[n].keyval]] = itm; + if (ventil[n].nbobjkey == 1) + ventil[n].data[itm[ventil[n].keyval]] = itm[ventil[n].objkey[0]]; + if (ventil[n].nbobjkey > 1) { + const objdata={} + Object.keys(itm).forEach(k=>{ + if (ventil[n].objkey.includes(k)) objdata[k]=itm[k]; + }) + ventil[n].data[itm[ventil[n].keyval]]=objdata + } + } + if (keep && ventil[n].type == "distribution" && itm[ventil[n].keyval] ) { + const listval = (ventil[n].keyvaltype=="string")? [itm[ventil[n].keyval]] : itm[ventil[n].keyval]; + // itm[ventil[n].keyval] is an array + listval.forEach(val=>{ + if (!ventil[n].data[val]) ventil[n].data[val] = []; + ventil[n].data[val].push(itm[schema.apxid]) + }); + } + }); + }); + Object.keys(ventil).forEach((n)=>{ + //console.log(`${objectPathname}/idx/${ventil[n].name}.json`) + fs.outputJSON(`${objectPathname}/idx/${ventil[n].name}.json`,ventil[n].data); + }) +}; + /** * create/update idx from itm(s) * @@ -490,7 +637,7 @@ Odmdb.cud = (objectPathname, crud, itm, role) => { * Odmdb.idxfromitm('.../tribes/ndda/pagans',"I",{},{},[{ name:"publickey_alias",keyval:"publickey",objkey:["alias"]}], {pagans schema}) * */ -Odmdb.idxfromitm = (objectPathname, crud, itm, itmold, idxs = [], schema) => { +Odmdb.ASUPidxfromitm = (objectPathname, crud, itm, itmold, idxs = [], schema) => { console.log(`idxfromitem for ${objectPathname} action:${crud}`); if (!schema || !schema.apxid) { const getschema = Odmdb.Schema(objectPathname, true); @@ -601,8 +748,8 @@ Odmdb.idxfromitm = (objectPathname, crud, itm, itmold, idxs = [], schema) => { if (crud != "I") { //update lastupdatedata to inform something change const confschema = fs.readJSONSync(`${objectPathname}/conf.json`); - confschema.lastupdatedata = dayjs(); - fs.outputJSONSync(`${objectPathname}/conf.json`, getschema.data.conf); + confschema.lastupdatedata = dayjs().toISOString(); + fs.outputJSONSync(`${objectPathname}/conf.json`, confschema); } return { status: 200, ref: "Odmdb", msg: "successreindex", data: {} }; }; @@ -652,7 +799,7 @@ Odmdb.updatefromidxall = (objectname, idxname, data, lastupdate) => { //check if it miss id in fresher update means conf.lastupdate will be now to indicate Object.keys(localidx).forEach((id) => { if (!data[id]) { - conflastupdate = dayjs(); + conflastupdate = dayjs().toISOString(); } }); // update the object files diff --git a/api/models/Pagans.js b/api/models/Pagans.js index 98df469..6687424 100644 --- a/api/models/Pagans.js +++ b/api/models/Pagans.js @@ -3,13 +3,11 @@ const path = require("path"); const dayjs = require("dayjs"); const fs = require("fs-extra"); const axios = require("axios"); +const Mustache = require('mustache'); const openpgp = require("openpgp"); const Notifications = require("../models/Notifications.js"); const Odmdb = require("../models/Odmdb.js"); -/*if (fs.existsSync("../../nationchains/tribes/conf.json")) { - conf = require("../../nationchains/tribes/conf.json"); -}*/ const conf = require(`${process.env.dirtown}/conf.json`); /** @@ -37,6 +35,7 @@ Pagans.logout = (alias, tribe, xdays, xhash) => { //max filename in ext4: 255 characters tmpfs += `_${xhash.substring(150, 150 + tmpfs.length - 249)}.json`; fs.remove(tmpfs); + console.log('logout token',tmpfs) return { status: 200, ref: "Pagans", msg: "logout" }; }; @@ -47,7 +46,7 @@ Pagans.logout = (alias, tribe, xdays, xhash) => { * **/ Pagans.getalias = (alias) => { - //bypass Odmdb cause all is public + //bypass Odmdb cause all is public save ressources if (fs.existsSync(`${conf.dirapi}/nationchains/pagans/itm/${alias}.json`)) { return { status: 200, @@ -67,106 +66,7 @@ Pagans.getalias = (alias) => { } }; -/** - * @param {string} alias that exist - * @param {string} tribeId that exist with a person alias - * @return {object} { status: 200, ref:"pagans",msg:"personexist",data: { person } } - * { status: 404, ref:"pagans",msg:"persondoesnotexist",data: { person } } - * - **/ -Pagans.getperson = (tribeid, alias, role) => { - const objlst = Odmdb.reads( - `${conf.dirtown}/tribes/${tribeid}/persons`, - [alias], - role - ); - if (objlst.data[alias] == "notfound") { - return { - status: 404, - ref: "Pagans", - msg: "persondoesnotexist", - data: { alias, tribeid }, - }; - } else { - return { - status: 200, - ref: "Pagans", - msg: "personexist", - data: objlst.data[alias], - }; - } -}; -Pagans.create = (objpagan, role) => { - /** - * @param {object} objpagan {alias,publickey} a unique alias/publickey that identify an identity - * @param {array} role {xalias,xprofils} requester and list of profil - * @return {object} { status: 200, data: { alias, publicKey } } - * xhash was checked by isauthenticated - * @todo use Odmdb to add a pagan - */ - return Odmdb.cud(`${conf.dirapi}/nationchains/pagans`, "C", objpagan, role); - /* - let apxpagans = {}; - if (fs.existsSync(`${conf.dirapi}/nationchains/pagans/idx/alias_all.json`)) { - apxpagans = fs.readJsonSync( - `${conf.dirapi}/nationchains/pagans/idx/alias_all.json` - ); - } - if (apxpagans[objpagan.alias]) { - return { status: 409, ref: "Pagans", msg: "aliasexist", data: { alias } }; - } - apxpagans[objpagan.alias] = { alias, publicKey }; - fs.outputJsonSync( - `${conf.dirapi}/nationchains/pagans/idx/alias_all.json`, - apxpagans - ); - fs.outputJsonSync(`${conf.dirapi}/nationchains/pagans/itm/${alias}.json`, { - alias, - publicKey, - }); - return { - status: 200, - ref: "Pagans", - msg: "identitycreate", - data: { alias, publicKey }, - }; - */ -}; - -/** - * @Param {string} alias pagan unique id - * @Param {string} tribeid tribe id in this town - * @Param {object} persondata that respect /nationchains/schema/person.json + nationchains/tribe/tribeid/schema/personextented.json - * @return create or update a person /tribe/tribeid/person/alias.json - * todo later use Odmdb ans schema person to manage this - */ -Pagans.personupdate = (tribeid, alias, personupdate, role) => { - const personinit = { - alias: alias, - dt_create: dayjs(), - profils: ["person"], - }; - const personfile = `${process.env.dirtown}/tribes/${tribeid}/person/itm/${alias}.json`; - const persondata = fs.existsSync(personfile) - ? fs.readJSONSync(personfile) - : personinit; - persondata.dt_update = dayjs(); - - Object.keys(personupdate).forEach((d) => { - persondata[d] = personupdate[d]; - }); - //const checkjson= Checkjson.schema.data = (fs.readJsonSync(`${conf.dirapi}/nationchains/schema/person.json`, person, false) - // if checkjson.status==200 create /update with odmdb to update index data - // see odmdb that did all and return standard message - fs.outputJSONSync(personfile, persondata, { space: 2 }); - return { - status: 200, - ref: "Pagans", - msg: "successfullupdate", - data: { alias: alias, tribeid: tribeid }, - }; -}; /** * Send email with alias's keys to email or person alias person.recovery.email * @@ -183,38 +83,38 @@ Pagans.personupdate = (tribeid, alias, personupdate, role) => { Pagans.sendmailkey = ( alias, privatekey, - tribeid, + tribe, passphrase, publickey, - email + email, + lg ) => { - const person = { alias, privatekey, tribeid }; + const person = { alias, privatekey, tribe }; console.log( alias, "-", - privatekey, + privatekey.substring(0,10), "-", - tribeid, + tribe, "-", passphrase, "-", - publickey, + publickey.substring(0,10), "-", email ); - if (!publickey || !email || !passphrase || !privatekey) { - const personfile = `${process.env.dirtown}/tribes/${tribeid}/person/itm/${alias}.json`; - const persondata = fs.existsSync(personfile) - ? fs.readJsonSync(personfile) - : {}; - if (persondata.length == 0) { + + if (!publickey || !email || !privatekey) { + const personfile = `${process.env.dirtown}/tribes/${tribe}/objects/persons/itm/${alias}.json`; + if (!fs.existsSync(personfile)) { return { status: 404, ref: "Pagans", msg: "persondoesnotexist", - data: { alias, tribeid }, + data: { alias, tribe }, }; } + const persondata= fs.readJsonSync(personfile); person.email = persondata.recoveryauth.email; person.publickey = persondata.recoveryauth.publickey; person.privatekey = persondata.recoveryauth.privatekey; @@ -224,48 +124,30 @@ Pagans.sendmailkey = ( person.passphrase = passphrase; person.publickey = publickey; } + person.avecpassphrase=(person.passphrase!="") console.log("person:", person); + const tplemail = require(`${conf.dirapi}/adminapi/template/createidentity_${lg}.js`) - //feedback.withemail = true; - //feedback.email = email; - //feedback.privatekey = privatekey; - //feedback.passphrase = passphrase; - const mailidentity = { - subjecttpl: "Information pour l'alias: {{alias}}", - htmltpl: - "

Votre identité {{alias}} via {{tribeid}}

Passphrase:

{{{passphrase}}

Cle public:

{{{publickey}}

Cle privée

{{{privatekey}}

", - texttpl: - "Votre identité {{alias}}\nPassphrase:\n{{{passphrase}}\nCle public:\n{{{publickey}}\nCle privée\n{{{privatekey}}", - filelist: [], - }; - + person.message const maildata = { - To: person.email, - subject: Mustache.render(mailidentity.subject, person), - htmlpart: Mustache.render(mailidentity.htmltpl, person), - textpart: Mustache.render(mailidentity.texttpl, person), - filelist: [], + to: person.email, + subject: Mustache.render(tplemail.subject, person), + html: Mustache.render(tplemail.html, person), + text: Mustache.render(tplemail.text, person), + attachments: [ + { + filename:`${person.alias}_publickey.txt`, + content: person.publickey, + contentType:"text/plain" + }, + { + filename:`${person.alias}_privatekey.txt`, + content: person.privatekey, + contentType:"text/plain" + } + ] }; - fs.outputFileSync( - `${conf.dirtown}/tmp/${person.alias}_privatekey.txt`, - person.privatekey, - "utf8" - ); - maildata.filelist.push({ - filename: "${person.alias}_privatekey.txt", - pathfile: `${conf.dirtown}/tmp/${person.alias}_privatekey.txt`, - }); - fs.outputFileSync( - `${conf.dirtown}/tmp/${person.alias}_publickey.txt`, - person.publickey, - "utf8" - ); - maildata.filelist.push({ - filename: "${person.alias}_publickey.txt", - pathfile: `${conf.dirtown}/tmp/${person.alias}_publickey.txt`, - }); - //fs.readJSONSync('${conf.dirapi}/api/') - return Notifications.sendmail(maildata, tribeid); + return Notifications.sendmail(maildata, tribe); }; Pagans.authenticatedetachedSignature = async ( @@ -306,15 +188,6 @@ Pagans.authenticatedetachedSignature = async ( } }; -/** - * todo recuperer tous les tokens et les distribuer à la town - * @param {string} alias - */ -Pagans.deletealias = (alias) => { - // check if alias is used in the blockchain - // if not then delete itm pagan alias => this means that alias is now available for someone else -}; -Pagans.deleteperson = (alias, tribeId) => {}; Pagans.keyrecovery = (tribeid, email) => { glob .GlobSync(`${conf.dirtown}/tribes/${tribeId}/Person/*.json`) diff --git a/api/models/lg/Checkjson_fr.json b/api/models/lg/Checkjson_fr.json index b55d69f..a76cb1c 100644 --- a/api/models/lg/Checkjson_fr.json +++ b/api/models/lg/Checkjson_fr.json @@ -2,5 +2,6 @@ "validcheck":"Your data are valid", "typedoesnnotexistinschema":"This type in your propertie is not manage by Checkjson.js", "dataerrpropertie":"Check your data that not fit your schema rules propertie", - "dataerrpropertiesrequired":"This propertie is required and not present in your data" + "dataerrpropertiesrequired":"This propertie is required and not present in your data", + "externalrefnotload":"You have in your schema a relative sub schema, you have to load it before" } \ No newline at end of file diff --git a/api/models/lg/Odmdb_fr.json b/api/models/lg/Odmdb_fr.json index cafa6b5..4754193 100644 --- a/api/models/lg/Odmdb_fr.json +++ b/api/models/lg/Odmdb_fr.json @@ -1,14 +1,19 @@ { "alreadyexist": "Un object {{objectname}} avec la clé {{key}} existe déjà avec {{val}}", - "doesnotexist": "L'object {{objectname}} avec la clé {{key}} ,'existe pas avec {{val}}", + "doesnotexist": "L'object {{objectname}} n'existe pas avec {{key}}:{{val}}", "getschema": "Schema {{{conf.name}}}", "schemanotfound": "Schema introuvable dans {{{schemaPath}}}", "pathnamedoesnotexist": "Le repertoire n'existe pas {{{indexpath}}}", "objectfiledoesnotexist": "Le fichier n'existe pas {{{objectpath}}}", "cudsuccessfull": "Mise à jour effectuée avec succés", + "successfulcreatewithoutemail":"Créer sans envoi d'email", + "successfulcreatewitemail":"Créer vous allez recevoir un email", "missingprimarykey": "Il manque une clé primaire apxid pour stocker et identifier les objects", "unconsistencyapxidx": "L'index {{name}} doit contenir en objkey au moins {{apxid}} car keyval n'est pas unique", "profilnotallow": "Vous n'avez pas le profil de {{profils}}, cette action n'est pas authorisée", "successreindex": "Objet reindexé à partir des items, vos index sont à jour", - "indexexist":"L'indexe existe" + "indexexist":"L'indexe existe", + "typenotavailable":"Le type: {{type}} pour la propertie : {{propertie}} de l'object :{{objectPathname}} n'est pas pris en compte pour l'indexation", + "objectslist":"Liste des objects d'apxtrib et de {{tribe}}", + "errordelete":"Desolé impossible de supprimer ce compte" } diff --git a/api/models/lg/Pagans_fr.json b/api/models/lg/Pagans_fr.json index 8f9c1bf..1c365cd 100644 --- a/api/models/lg/Pagans_fr.json +++ b/api/models/lg/Pagans_fr.json @@ -1,13 +1,12 @@ { - "aliasexist": "Cet alias {{data.alias}} existe", - "emailerr": "Verifier votre email", + "aliasexist": "Cet alias {{alias}} existe", + "emailerr": "Verifier votre email {{email}}", "aliasorprivkeytooshort": "Vérifiez votre alias et votre clé privée", - "aliasdoesnotexist": "Cet alias {{data.alias}} n'existe pas", - "personexist": "Cette personne {{data.alias}} existe pour {{data.tribeid}}", - "persondoesnotexist": "Cette personne {{data.alias}} n'existe pas pour {{data.tribeid}}", - "successfullcreate": "La création de cette identité {{data.alias}} a été un succès. {{#data.withemail}} Un email a été envoyé à {{data.email}}, si vous ne le recevez pas, veuillez télécharger vos clés avant de quitter cette page.{{/data.withemail}}", - "successfulcreatewithoutemail": "La creation de data.alias}} a été un succès. Aucun email ,'a été envoyé, verifier bien que vos clés sont bien sauvegardé de votre coté", - "successfulluppdate": "Votre alias en tant que Personne est maintenant mis à jour dans {{data.tribeid}}", + "aliasdoesnotexist": "Cet alias {{alias}} n'existe pas", + "personexist": "Cette personne {{alias}} existe pour {{tribeid}}", + "persondoesnotexist": "Cette personne {{alias}} n'existe pas pour {{tribeid}}", + "successfulcreate":"Votre identité {{alias}} a été créee à partir de vos clés.{{#emailsent}} Un email a été envoyé à {{email}}, si vous ne le recevez pas, veuillez télécharger vos clés avant de quitter cette page.{{/emailsent}} {{#emailerror}}Un problème lors de l'envoi sur {{email}} s'est produit. Veuillez télécharger vos clés avant de quitter cette page.{{/emailerror}}
{{#createperson}}Félicitation Votre compte est ouvert chez {{tribe}}. {{/createperson}} {{#errorperson}}Attention votre identité n'a pas été associée à {{tribe}}. Vous pourrez rejoindre {{tribe}} dans l'écran suivant. {{/errorperson}}", + "successfulluppdate": "Votre alias en tant que Personne est maintenant mis à jour dans {{tribeid}}", "errcreate": "Desolé, un probléme inconnu empeche la creation", "logout": "Votre token a été supprimé du server" } diff --git a/api/routes/nations.js b/api/routes/nations.js index 9b65fba..144a737 100755 --- a/api/routes/nations.js +++ b/api/routes/nations.js @@ -1,4 +1,5 @@ const express = require( 'express' ); +const fs=require('fs-extra'); const conf = require(`${process.env.dirtown}/conf.json`); // Classes @@ -9,32 +10,26 @@ const isAuthenticated = require( '../middlewares/isAuthenticated' ); const router = express.Router(); /* -Manage the social world - -@Todo - -Manage a new nation +Manage nation A major create a nation with at least a town => nation:{name, towns:[]} contracts/nationname.js + contracts/townsname.js Manage a new towns in a nation => update nation:[nationname:towns:[]} contracts/townname.js - - - - - - - */ -router.post( '/push', checkHeaders, ( req, res ) => { - // Get information from other apxtrib instance in req.body - // check req.body.hashnext => means this is a candidate to validate next block - // - // return it's own information back with the last call to Nationchains.synchronize() - res.send( { status: 200, payload: { moreinfo: fs.readFileSync( `${conf.tribes}/${conf.mayorId}/nationchains/nodes/${conf.rootURL}`, 'utf-8' ) } } ) + + +/** + * @api {put} /nations/viewtown/:town - nationlist from a town major + * @apigroup Nation + * @apiName nationlist + * @apiDescription get list of nation from a town to help this instance to update network topology + * @apiParam {string} town fromwhich the data come from + * @apiSuccess {object} refreshnetworktopoly + * * HTTP/1.1 200 OK + * {status:200,ref:"Nations",msg:"updated",data:{}}; + * + */ +router.put( '/', checkHeaders, isAuthenticated, ( req, res ) => { + const uptown = Nations.updatetown() + res.status(uptown.status).send(uptown) } ) -router.get('/synchro',checkHeaders, isAuthenticated,(req,res)=>{ - // run a sync from a list of electedtown to update nationchains folder - console.log('TODO') -}) - module.exports = router; diff --git a/api/routes/notifications.js b/api/routes/notifications.js index 3747a3f..3fcc786 100644 --- a/api/routes/notifications.js +++ b/api/routes/notifications.js @@ -1,9 +1,6 @@ const express = require("express"); -const fs = require("fs-extra"); -const path = require("path"); - // Classes -const Pagans = require("../models/Notifications.js"); +const Notifications = require("../models/Notifications.js"); // Middlewares const checkHeaders = require("../middlewares/checkHeaders"); @@ -12,48 +9,22 @@ const isAuthenticated = require("../middlewares/isAuthenticated"); const router = express.Router(); /** - * Get form data and send notification to user by email, sms, alert - * @api{post}/messageanonymous - * @apiName Notification - * @apiDescription Send information as anonymous to tribe's druid - * @apiGroup apxtrib + * @api {get} /notifications/:alias/:tribeId + * @apiName notiflist + * @apiDescription Get list of notifications for an alias and a tribe + * @apiGroup Notification * - * @apiUse apxHeader - * @apiParam {string} objectname Mandatory - * @apiParam {String} indexname Mandatory if in conf.nationObjects then file is into nationchains/ else in /nationchains/tribes/xtribe/objectname/idx/indexname indexname contains the ObjectName .*_ (before the first _) - * - * - * @apiError {json} objectNotfound the file does not exist - * @apiErrorExample {json} - * HTTP/1.1 404 Not Found - {"status":404,"ref":"Odmdb","msg":"pathnamedoesnotexist","data":{indexpath}} - * - * @apiSuccess {object} indexfile content + * @apiParam {string} alias + * @apiParam {string} tribeId + * @apiSuccess {object} notif content * @apiSuccessExample {json} Success-Response: * HTTP/1.1 200 OK - * {"status":200, "ref":"Odmdb", "msg":"indexexist", "data":{indexname,content:{index file}} + * {status:200,ref:"Notification",msg:"Messagelist",data:{notif:[{tribeId,msg:{from(email or uuid or alias):[{dt,msg}]}}]} * - * **/ -router.get("/alias/:alias", (req, res) => { - const getalias = Pagans.getalias(req.params.alias); +router.get("/:alias/:tribeId", (req, res) => { + const getnot = Notification.get(req.params.alias,req.params.tribeId); res.status(getalias.status).send(getalias); }); -/** - * Remove serveur token - * @api {get} /pagans/logout - * @apiName Remove token - * @apiGroup Pagans - * - */ -router.get("/logout", checkHeaders, isAuthenticated, (req, res) => { - console.log(req.session.header); - const logout = Pagans.logout( - req.session.header.xalias, - req.session.header.xtribe, - req.session.header.xdays, - req.session.header.xhash - ); - res.status(logout.status).json(logout); -}); + module.exports=router; \ No newline at end of file diff --git a/api/routes/odmdb.js b/api/routes/odmdb.js index 3ba1459..1714733 100644 --- a/api/routes/odmdb.js +++ b/api/routes/odmdb.js @@ -9,13 +9,52 @@ const checkHeaders = require("../middlewares/checkHeaders"); const isAuthenticated = require("../middlewares/isAuthenticated"); const router = express.Router(); - /** - * @api{get}/odmdb/idx/:objectname/:indexname - index Get + * @api {get} /odmdb/objects - objects Get + * @apiGroup Odmdb + * @apiName getIndex + * @apiDescription Get objects available for header.xtribe + * + * @apiSuccess {object} contain data.indexname + * @apiSuccessExample {json} Success-Response: + * HTTP/1.1 200 OK + * {"status":200, "ref":"Odmdb", "msg":"objectslist", "data":{indexname,content:{index file}} + * + * + */ +router.get("/objects", checkHeaders, isAuthenticated, (req, res) => { + const data = { + tribe: req.session.headers.xtribe, + apx: { conf: {}, objectnames: [] }, + tribe: { conf: {}, objectnames: [] }, + }; + glob.sync(`${conf.dirapi}/adminapi/schema/*.json`).forEach((f) => { + const objectname = path.basename(f, ".json"); + if (objectname == "conf") { + data.apx.conf = fs.readJSONSync(f); + } else { + data.apx.objectnames.push(objectnames); + } + }); + glob + .sync(`${conf.dirtown}/tribes/${req.session.headers.xtribe}/schema/*.json`) + .forEach((f) => { + const objectname = path.basename(f, ".json"); + if (objectname == "conf") { + data.apx.conf = fs.readJSONSync(f); + } else { + data.apx.objectnames.push(objectnames); + } + }); + res.status(200).json({ status: 200, ref: "Odmdb", msg: "objectslist", data }); +}); +/** + * @api {get} /odmdb/idx/:tribe/:objectname/:indexname - index Get * @apiGroup Odmdb * @apiName getIndex * @apiDescription Get index file for an object * + * @apiParam {string} tribe if common adminapi or tribename * @apiParam {string} objectname If in conf.nationObjects then object is into nationchains/ else in tribes/xtribe/objectname/idx/indexname indexname * @apiParam {String} indexname name of index file in /idx/indexnamme.json * @@ -32,39 +71,37 @@ const router = express.Router(); * * */ - router.get( - "/idx/:objectname/:indexname", - checkHeaders, - isAuthenticated, - (req, res) => { - console.log("passe"); - // indexname = objectname_key_value.json - let objectLocation = "../../nationchains/"; - if (!conf.api.nationObjects.includes(req.params.objectname)) { - objectLocation += `tribes/${req.session.headers.xtribe}/`; - // check if accessright - } - const indexpath = `${objectLocation}/${req.params.objectname}/idx/${req.params.indexname}`; - if (fs.existsSync(indexpath)) { - res - .status(200) - .json({ - ref: "Odmdb", - msg: "indexexist", - data: { - indexname: req.params.indexname, - content: fs.readJsonSync(indexpath), - }, - }); - } else { - res.status(404).json({ - ref: "Odmdb", - msg: "pathnamedoesnotexist", - data: { indexpath }, - }); - } +router.get( + "/idx/:tribe/:objectname/:indexname", + checkHeaders, + isAuthenticated, + (req, res) => { + console.log("passe"); + // indexname = objectname_key_value.json + let objectLocation = "../../nationchains/"; + if (!conf.api.nationObjects.includes(req.params.objectname)) { + objectLocation += `tribes/${req.session.headers.xtribe}/`; + // check if accessright } - ); + const indexpath = `${objectLocation}/${req.params.objectname}/idx/${req.params.indexname}`; + if (fs.existsSync(indexpath)) { + res.status(200).json({ + ref: "Odmdb", + msg: "indexexist", + data: { + indexname: req.params.indexname, + content: fs.readJsonSync(indexpath), + }, + }); + } else { + res.status(404).json({ + ref: "Odmdb", + msg: "pathnamedoesnotexist", + data: { indexpath }, + }); + } + } +); /** * @api {get} /odmdb/rebuildidx/:objectname - index refresh all @@ -75,7 +112,7 @@ const router = express.Router(); * @apiParam {string} objectname Mandatory * * @apiSuccess {object} indexfile content - * @apiSuccessExample {json} Success-Response: + * @apiSuccessExample {json} successreindex * HTTP/1.1 200 OK * {"status":200, "ref":"Odmdb", "msg":"successreindex", "data":{"indexlist":[]}} * @@ -85,58 +122,56 @@ const router = express.Router(); {"status":404,"ref":"Odmdb","msg":"see nationchains/model/lg/Odmdb_xx.json","data":"object to render with msg"} * */ - router.get( - "/rebuildidx/:objectname", - checkHeaders, - isAuthenticated, - (req, res) => { - console.log("reindex"); - // check validity and accessright - const objectPathname = conf.api.nationObjects.includes( - req.params.objectname - ) - ? `${conf.dirapi}/nationchains/${req.params.objectname}` - : `${conf.dirtown}/tribes/${req.session.header.xtribe}/${req.params.objectname}`; - //console.log(objectPathname); - if (!fs.existsSync(objectPathname)) { - res.status(404).json({ - status: 404, - ref: "Odmdb", - msg: "pathnamedoesnotexist", - data: { indexpath: objectPathname }, - }); - return false; - } - if ( - conf.api.nationObjects.includes(req.params.objectname) && - !req.session.header.xprofils.includes("mayor") - ) { - res.status(403).json({ - status: 403, - ref: "Odmdb", - msg: "profilnotallow", - data: { profils: "mayor" }, - }); - return false; - } - if ( - !conf.api.nationObjects.includes(req.params.objectname) && - !req.session.header.xprofils.includes("druid") - ) { - res.status(403).json({ - status: 403, - ref: "Odmdb", - msg: "profilnotallow", - data: { profils: "druid" }, - }); - return false; - } - const reindex = Odmdb.idxfromitm(objectPathname, "I", {}, {}, [], {}); - res.status(reindex.status).json(reindex); +router.get( + "/rebuildidx/:objectname", + checkHeaders, + isAuthenticated, + (req, res) => { + console.log("reindex"); + // check validity and accessright + const objectPathname = conf.api.nationObjects.includes( + req.params.objectname + ) + ? `${conf.dirapi}/nationchains/${req.params.objectname}` + : `${conf.dirtown}/tribes/${req.session.header.xtribe}/${req.params.objectname}`; + //console.log(objectPathname); + if (!fs.existsSync(objectPathname)) { + res.status(404).json({ + status: 404, + ref: "Odmdb", + msg: "pathnamedoesnotexist", + data: { indexpath: objectPathname }, + }); + return false; } - ); - - + if ( + conf.api.nationObjects.includes(req.params.objectname) && + !req.session.header.xprofils.includes("mayor") + ) { + res.status(403).json({ + status: 403, + ref: "Odmdb", + msg: "profilnotallow", + data: { profils: "mayor" }, + }); + return false; + } + if ( + !conf.api.nationObjects.includes(req.params.objectname) && + !req.session.header.xprofils.includes("druid") + ) { + res.status(403).json({ + status: 403, + ref: "Odmdb", + msg: "profilnotallow", + data: { profils: "druid" }, + }); + return false; + } + const reindex = Odmdb.idxfromitm(objectPathname, "I", {}, {}, [], {}); + res.status(reindex.status).json(reindex); + } +); /** * @api {post} /odmdb/itm/:objectname - item Create @@ -144,22 +179,22 @@ const router = express.Router(); * @apiName postItm * @apiPermission none * @apiDescription Add an new item (data) into a collection of objectname items. Before Check data integrity with the relevant schema. - * Then create a new primarykey. For multilanguage return see nationchains/model/lg/Odmdb_xx.json. - * + * Then create a new primarykey. For multilanguage return see nationchains/model/lg/Odmdb_xx.json. + * * @apiParam {string} objectname Place where to create new item, schema and version are available in /objectname/conf.json - * + * * @apiBody {Object} data must pass Checkjson.js with schema - * + * * @apiSuccess {json} data idxprimary Value of idxprimary into objectname collection * @apiSuccessExample {json} Success-Response: * HTTP/1.1 200 OK * {"status":200, "ref":"Odmdb", "msg":"cudsuccessfull", "data":{"itm":{}}} - * + * * @apiError {json} schemanotfound The objectname schema is not found * @apiError {json} pathnamedoesnotexist The objectname does not exist for the tribe * @apiError {json} missingprimarykey Body data must have primarykey to be created - * @apiError {json} unconsistencyapxidx some Body data get unique key that already exist - * @apiError {json} checkjsonfalse The body data are not consistent with the schema + * @apiError {json} unconsistencyapxidx some Body data get unique key that already exist + * @apiError {json} checkjsonfalse The body data are not consistent with the schema * @apiErrorExample {json} * HTTP/1.1 404 Not Found * {"status":404,"ref":"Odmdb","msg":"see nationchains/model/lg/Odmdb_xx.json","data":"object to render with msg"} @@ -168,7 +203,7 @@ const router = express.Router(); router.post("/itm/:objectname", checkHeaders, isAuthenticated, (req, res) => { // Create an item of an object with no specificities // if specificities then create a route / model that import odmdb - res.json({}) + res.json({}); }); router.get( "/searchitems/:objectname/:question", @@ -246,14 +281,14 @@ router.get( } ); /** - * @api {get} https://wall-ants.ndda.fr/Checkjson.js - schema check data lib + * @api {get} https://wall-ants.ndda.fr/Checkjson.js - schema Checkjson.js * @apiGroup Odmdb * @apiName checkjsonjs * @apiDescription Public js lib to import in a browser by :
* `````` * to import in a node.js:
* ```const Checkjson = require(`Checkjson.js`);``` - * + * * with functions:
* Checkjson.schema.validation(schema) that return
* - {status:200, ref:"Checkjson", msg:"validcheck"} => all rules are correct
@@ -262,14 +297,12 @@ router.get( * Checkjson.schema.data(schema{json},data{json},withschemacheck{boolean}) that return
* - {status:200, ref:"Checkjson", msg:"validcheck"} => all data keys respect schema rules
* - {status:417, multimsg:[{ref:"Checkjson",msg:"errorkey",data:{}}]}
- * + * * To identify issues, get the language errorkey list with a get - * https://wall-ants.ndda.fr/nationchains/models/Checkjson_lg.json - * + * https://wall-ants.ndda.fr/nationchains/models/Checkjson_lg.json + * */ - - /** * @api {get} https://wall-ants.ndda.fr/nationchains/schema/:objectname - schema Get public * @apiGroup Odmdb @@ -331,43 +364,170 @@ router.get( **/ /** - * @api {get} /odmdb/schema/:objectname - schema Get private + * @api {get} https://tribedns/:tribe/schema/:objectname.json - schema Get from tribe * @apiGroup Odmdb * @apiName getPrivateSchema - * @apiDescription Get a private (profil must have accessright R on object) to a Schema model + * @apiDescription Get a tribe schema or schema/lg/:objectname_xx.json this is served by nginx not express. tribedns is the domain name (ex:smatchit.io) * - * @apiParam {String} objectname Mandatory + * @apiParam {string} tribe where schema is stored ex;smatchit + * @apiParam {String} objectname the json file name ex persons.json or for language /lg/persons_fr.json * - * @apiError {object} ref objectmodel to get in the right language + * @apiError {object} ref objectname note found * @apiErrorExample {json} Error-response: * HTTP/1.1 404 Not Found - * {"status":404,"ref":"Odmdb","msg":"schemanotfound","data":{"fullpath"}} - * - * @apiSuccess {object} data contains schema requested - * @apiSuccessExample {json} Success-Response: + * ... + * @apiSuccess {json} data contains schema requested + * @apiSuccessExample {json} Success-Response for : https://smatchit.io/smatchit/schema/persons.json * HTTP/1.1 200 Success-response: - * {"status":200,"data":{schema}} - */ -router.get("schema/:objectname", checkHeaders, isAuthenticated, (req, res) => { - const fullpath = path.resolve( - `${__dirname}/tribes/${req.session.header.xworkon}/schema/${req.params.pathobjectname}.json` - ); - if (fs.existsSync(fullpath)) { - res.status(200).json({ data: fs.readJsonSync(fullpath) }); - } else { - res - .status(404) - .json({ status:404, msg: "schemanotfound", ref: "odmdb", data: { fullpath } }); + * {{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "/smatchit/schema/sirets", + "title": "Siret is a legal french company", + "description": "A recruiter can active a jobad if a maxnumber is not reach for this siret. Maxnumber is set depending of an offer or can be set manualy", + "type": "object", + "properties": { + "siret": { + "title": "siret", + "description": "A unique string identifying a company ", + "type": "string", + "minLength": 14, + "pattern": "^[0-9]*$" + }, + "owner": { + "title": "Owner of this siret", + "description": "For accessright purpose this is set by the alias that pay the first time a subscription", + "type": "string" + }, + "dt_create": { + "type": "string", + "format": "date-time", + "default": "dayjs.now()" + }, + "dt_update": { + "type": "string", + "format": "date-time" + }, + "subscription": { + "title": "Offer subscribe", + "type": "array", + "items": { + "type": "object", + "properties": { + "offer": { "type": "string", "enum": ["A", "B", "C", "FREE"] }, + "dt_payment": { "type": "string", "format": "date-time" } + } + } + }, + "emailbilling":{ + "type":"string", + "format":"email" + }, + "namebilling":{ + "type":"string" + }, + "maxactivejobad": { + "title": "Number of active jobad at the same time", + "description": "Alloaw by subscription payment for a date inside the last dt_payment and offer", + "type": "integer" + }, + "activejobad": { + "title": "Current number of active jobadd", + "type": "integer" + }, + "frenchlocation": { + "title": "Location", + "description": "use franch gov refential to locaize", + "$ref": "nationchains/schema/frenchlocation" + }, + "denomination": { + "title": "Company name", + "type": "string" + } + }, + "required": ["siret"], + "additionalProperties": true, + "apxid": "siret", + "apxuniquekey": ["siret"], + "apxidx": [ + { + "name": "lst_siret", + "keyval": "siret" + } + ], + "apxaccessrights": { + "owner": { + "D": [], + "R": [ + "siret", + "dt_create", + "dt_update", + "subscription", + "maxactivejobadd", + "activejobadd", + "frenchlocation", + "demomination" + ], + "U": ["frenchlocation", "demomination"] + }, + "druid": { + "C": [], + "D": [], + "R": [ + "siret", + "dt_create", + "dt_update", + "subscription", + "maxactivejobadd", + "activejobadd", + "frenchlocation", + "demomination" + ], + "U": [ + "subscription", + "maxactivejobadd", + "activejobadd", + "frenchlocation", + "demomination" + ] + }, + "pagans": { "C": [] }, + "adminrecruiter": { + "C": [], + "R": [ + "siret", + "dt_create", + "dt_update", + "subscription", + "maxactivejobadd", + "activejobadd", + "frenchlocation", + "demomination" + ], + "U": ["frenchlocation", "demomination"] + }, + "recruiter": { + "R": [ + "siret", + "dt_create", + "dt_update", + "subscription", + "maxactivejobadd", + "activejobadd", + "frenchlocation", + "demomination" + ] + } } -}); +}} + */ /** - * @api {put} /odmdb/schema/:objectname - schema Put + * @api {put} https://wall-ants.ndda.fr/odmdb/schema/:tribe/:objectname - schema Put * @apiGroup Odmdb * @apiName putSchema * @apiDescription Replace a schema by another one need druid profil for a tribe * - * @apiParam {String} objectname Mandatory + * @apiParam {String} objectname * * @apiBody {string} schemapath where to store schema .../schema * @apiBody {string} objectpath where to store object ...objectname/idx/conf.json @@ -386,23 +546,27 @@ router.get("schema/:objectname", checkHeaders, isAuthenticated, (req, res) => { * * */ -router.put("schema/:objectname", checkHeaders, isAuthenticated, (req, res) => { - const fullpath = path.resolve( - `${__dirname}/tribes/${req.session.header.xworkon}/schema/${req.params.pathobjectname}.json` - ); - const set = Odmdb.setObject( - path.resolve(`${__dirname}/tribes/${req.session.header.xworkon}`) - ); +router.put( + "schema/:tribe/:objectname", + checkHeaders, + isAuthenticated, + (req, res) => { + const fullpath = path.resolve( + `${__dirname}/tribes/${req.session.header.xworkon}/schema/${req.params.pathobjectname}.json` + ); + const set = Odmdb.setObject( + path.resolve(`${__dirname}/tribes/${req.session.header.xworkon}`) + ); - if (fs.existsSync(fullpath)) { - res.status(200).json({ data: fs.readJsonSync(fullpath) }); - } else { - res - .status(404) - .json({ msg: "schemanotfound", ref: "odmdb", data: { fullpath } }); + if (fs.existsSync(fullpath)) { + res.status(200).json({ data: fs.readJsonSync(fullpath) }); + } else { + res + .status(404) + .json({ msg: "schemanotfound", ref: "odmdb", data: { fullpath } }); + } } -}); - +); /** * @api {get} https://wall-ants.ndda.fr/nationchains/models/:modelname_lg.json - translation notif Get public diff --git a/api/routes/pagans.js b/api/routes/pagans.js index 3241416..1679eda 100755 --- a/api/routes/pagans.js +++ b/api/routes/pagans.js @@ -1,14 +1,15 @@ const express = require("express"); const fs = require("fs-extra"); const path = require("path"); - // Classes const Pagans = require("../models/Pagans.js"); - +const Odmdb = require("../models/Odmdb.js"); // Middlewares const checkHeaders = require("../middlewares/checkHeaders"); const isAuthenticated = require("../middlewares/isAuthenticated"); +const conf = require(`${process.env.dirtown}/conf.json`); + const router = express.Router(); /** * /api/models/Pagans.js @@ -44,8 +45,8 @@ router.get("/alias/:alias", (req, res) => { * @api {get} /pagans/logout - pagan Logout * @apiName Removetoken * @apiGroup Pagans - * @apiDescription Remove token - * + * @apiDescription Remove token + * * @apiSuccess {object} indexfile content * @apiSuccessExample {json} Success-Response: * HTTP/1.1 200 OK @@ -101,6 +102,12 @@ router.get("/isauth", checkHeaders, isAuthenticated, (req, res) => { * - xhash is well signed from private key linked to the publickey of alias * - check that alias does not already exist (if yes then verifiedsigne would be false) * Need to wait next block chain to be sure that alias is register in the blokchain + * @apiBody {string} alias available (that does not already exist check get /api/alias/:alias that must return 404). + * @apiBody {string} publickey + * @apiBody {string} [email] if specified then an email is sent to it with public and privatekey + * @apiBody {string} [privatekey] + * @apiBody {string} [passphrase] if not specidied => passphrase="" + * @apiBody {string} [trustedtribe] the tribename if not specified then the process will only create a pagan identity, else an item person is create for trustedtribe (that must exist with profil 'person'). To create a person with an existing pagan identity use put /api/person/:alias after authenticated you (headers). In case a person is created then we use all valid other apiBody respecting rules https://smatchit.io/api/odmdb/schema/persons.json * * @apiError {json} objectNotfound the file does not exist * @apiErrorExample {json} @@ -113,42 +120,64 @@ router.get("/isauth", checkHeaders, isAuthenticated, (req, res) => { * {"status":200, "ref":"Odmdb", "msg":"indexexist", "data":{indexname,content:{index file}} * */ -router.post("/", checkHeaders, isAuthenticated, (req, res) => { - //console.log("pass ici", req.body); - const objpagan = { alias: req.body.alias, publickey: req.body.publickey }; - const newpagan = Pagans.create(objpagan, { +router.post("/", checkHeaders, isAuthenticated, async (req, res) => { + console.log("pass ici", req.body); + const role = { xalias: req.session.header.xalias, xprofils: req.session.header.xprofils, - }); + }; + const emailregex = + /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; + if (!(req.body.trustedtribe && req.body.email && emailregex.test(req.body.email) )) { + res.status(400).json({status:400,ref:"Pagans",msg:"emailerr", data:{email:req.body.email}}) + return + } + const objpagan = { alias: req.body.alias, publickey: req.body.publickey }; + const newpagan = Odmdb.cud(`${conf.dirapi}/nationchains/pagans`, "C", objpagan, role); + const createprocess={status:200, ref:"Pagans", msg:"successfulcreate",data:{alias:req.body.alias}}; if (newpagan.status == 200) { if (req.body.email) { - const emailsent = Pagans.sendmailkey( + const emailsent = await Pagans.sendmailkey( req.body.alias, req.body.privatekey, req.session.header.xtribe, req.body.passphrase, req.body.publickey, - req.body.email + req.body.email, + req.session.header.xlang ); + createprocess.data.emailsent = (emailsent.status == 200); + createprocess.data.email=req.body.email + createprocess.data.tribe=req.session.header.xtribe; + if (emailsent.status!=200) { + console.log("err emailsent: ",emailsent) + createprocess.data.emailerror = emailsent.data.err; + } } if (req.body.trustedtribe) { - const personup = Pagans.personupdate( - req.body.alias, - req.body.trustedtribe, - { - recoveryauth: { - email: req.body.email, - privatekey: req.body.privatekey, - publickey: req.body.publickey, - passphrase: req.body.passphrase, - }, - } - ); - if (personup.status !== 200) - console.log("Warning no recovery registration", personup); - } - if (emailsent && emailsent.status != 200) { - newpagan.msg = "successfulcreatewithoutemail"; + const persondata = { + alias: req.body.alias, + owner: req.body.alias, + profils: ["pagans", "persons"], + recoveryauth: { + email: req.body.email, + privatekey: req.body.privatekey, + publickey: req.body.publickey, + passphrase: req.body.passphrase, + }, + }; + const personup = Odmdb.cud(`${conf.dirtown}/tribes/${req.body.trustedtribe}/objects/persons`, "C", persondata, {xprofils:["pagan"],xalias:req.body.alias}); + console.log('personup',personup) + if (personup.status==200){ + createprocess.data.createperson=true; + }else{ + createprocess.data.createperson=false; + createprocess.data.errorperson=true; + createprocess.data.errpersonup=personup.data; + console.log("Warning pagan created but person not created and no recovery registration", personup); + } + res.status(createprocess.status).json(createprocess); + }else{ res.status(newpagan.status).json(newpagan); } } else { @@ -161,31 +190,45 @@ router.post("/", checkHeaders, isAuthenticated, (req, res) => { * @apiName deletepagan * @apiGroup Pagans * @apiDescription - * Delete an alias and his publickey + * Delete an alias and his publickey, this mean that publickey disapear as well as alias. All tribe will be inform and will delete person of this alias if they have. This alias will be availlable after 1 year. * */ router.delete("/alias/:alias", checkHeaders, isAuthenticated, (req, res) => { console.log(`DELETE pagans nationchains/pagans/${req.params.alias}.json`); const result = Pagans.deletealias(req.params.id, req.session.header); - res.status(result.status).send(result.data); + res.status(result.status).send(result); }); +/** + * @api {delete} /pagans/person/:alias - person Delete + * @apiName deleteperson + * @apiGroup Pagans + * @apiDescription + * Unsubscribe a person to a tribe => remove a person item and all data link to this alias + * */ router.delete("/person/:alias", checkHeaders, isAuthenticated, (req, res) => { - console.log(`DELETE pagans nationchains/pagans/${req.params.alias}.json`); - const result = Pagans.deleteperson(req.params.id, req.session.header); - res.status(result.status).send(result.data); + const personpath=`${conf.dirtown}/tribes/${req.session.header.xtribe}/objects/persons`; + const role = { + xalias: req.session.header.xalias, + xprofils: req.session.header.xprofils, + }; + req.session.header.role + const delperson = Odmdb.cud(personpath,"D",{alias:req.params.alias},role,true); + console.log(`DELETE person ${personpath}/${req.params.alias}.json `); + console.log(delperson) + res.status(delperson.status).json(delperson); }); /** - * @api {get} /pagans/person:alias - person Get + * @api {get} /pagans/person/:alias - person Get * @apiName getpersondata - * @apiDescription Get person information from his alias for a xtribe (data and profils per apps) + * @apiDescription Get person information from his alias for a xtribe (data and profils per apps) * @apiGroup Pagans * * @apiParam {string} alias - * + * * @apiSuccess (200) personExist * @apiSuccessExample {json} * {status:200, ref:"pagans",msg:"personexist",data: { person } } - * + * * @apiError (404) Notfound * @apiErrorExample {json} * {status: 404, ref:"pagans",msg:"persondoesnotexist",data: { person } } @@ -195,57 +238,32 @@ router.delete("/person/:alias", checkHeaders, isAuthenticated, (req, res) => { * else need accessright to on person set at R * */ router.get("/person/:alias", checkHeaders, isAuthenticated, (req, res) => { - const getperson = Pagans.getperson( - req.session.header.xtribe, - req.params.alias, - { xprofils: req.session.header.xprofils, xalias: req.session.header.xalias } - ); + const getperson=Odmdb.r( `${conf.dirtown}/tribes/${req.session.header.xtribe}/objects/persons`,req.params.alias,{ xprofils: req.session.header.xprofils, xalias: req.session.header.xalias }) res.status(getperson.status).send(getperson); }); -/** - * @api {post} /pagans/person - person Post - * @apiName addperson - * @apiGroup Pagans - * @apiDescription - * add a person = alias + tribe with specific accessright and specific schema link to tribe - * - * - * - * @todo add tribe/schema/person.json - */ -router.post("/person", checkHeaders, isAuthenticated, (req, res) => { - //console.log(req.body); - const persoad = Pagans.personcreate( - req.session.header.xtribe, - req.body.alias, - req.body, - { xprofils: req.session.header.xprofils, xalias: req.session.header.xalias } - ); - res.status(persoad.status).json(persoad); -}); - /** * @api {put} /pagans/person - person Put * @apiName updateperson * @apiGroup Pagans - * @apiDescription - * update a person = alias + tribe with specific accessright and specific schema link to tribe - -* @todo add tribe/schema/person.json + * @apiDescription add or update a person = alias in a tribe. alias authenticated must have a profil with accessright into schema person. + * @apiHeader {string} xalias + * @apiParam {object} in line with schema in https://smatchit.io/api/odmdb/schema/persons + * */ router.put("/person", checkHeaders, isAuthenticated, (req, res) => { //console.log(req.body); - const persoup = Pagans.personupdate( - req.session.header.xtribe, - req.body.alias, - req.body, - { xprofils: req.session.header.xprofils, xalias: req.session.header.xalias } - ); - res.status(persoup.status).json(persoup); + const pathobj=`${conf.dirtown}/tribes/${req.session.header.xtribe}/objects/persons`; + const action = (fs.existsSync(`${pathobj}/itm/${req.body.alias}.json`))? "U":"C"; + //set req.body to be in line with schema + if (!req.body.profils){ + req.body.profils=["anonymous","pagans","persons"] + } + const personup = Odmdb.cud(pathobj, action, req.body, {xprofils:req.session.header.xprofils, xalias:req.session.header.xalias}); + console.log('personup',personup) + res.status(personup.status).json(personup); }); - /** * @api {get} /pagans/keyrecovery/tribe/email - recovery key by email * @apiName recoveryKey diff --git a/api/routes/towns.js b/api/routes/towns.js index fa30875..88e6201 100755 --- a/api/routes/towns.js +++ b/api/routes/towns.js @@ -8,161 +8,25 @@ const Notifications = require("../models/Notifications.js"); const checkHeaders = require("../middlewares/checkHeaders"); const isAuthenticated = require("../middlewares/isAuthenticated"); const router = express.Router(); -/* -*/ -router.get("/changeowner/:alias",checkHeaders, isAuthenticated, (req, res) => { - /** - * @api {get} /towns/ownershipr/:alias - * @apiName Change owner of a town mayorId - * @apiGroup Pagans +/** + * @api {get} /towns/ownershipr/:alias - town owner change + * @apiName changeowner + * @apiGroup Towns + * @apiDescription Change owner (major role) of a town (server) after a first install or just to resale it. Only the current major can run this. * @param {string} alias an alias that will become owner of a town - * @apiSuccess (200) {object} {ref:"towns",msg:"ownerchangesuccess",data: { alias } } - * @apiError (404) {object} {ref:"towns",msg:"aliasnotallow",data: { alias} } + * @apiSuccess (object) ownerchangesuccess + * @apiSuccessExample {json} + * HTTP/1.1 200 OK + * {status:200, ref:"towns",msg:"ownerchangesuccess",data: { alias } } + * @apiError {object} aliasnotallow + * @apiErrorExample {json} + * HTTP/1.1 403 Forbidden + * {status:403,ref:"towns",msg:"aliasnotallow",data: { alias} } * **/ +router.get("/changeowner/:alias",checkHeaders, isAuthenticated, (req, res) => { res.send(Towns.changeowner(req.params.alias, req.session.header.xalias)); }); -//======================================================================================= -router.get("/person/:alias", checkHeaders, isAuthenticated, (req, res) => { - /** - * @api {get} /pagans/person:alias - * @apiName Is register check xalias and xhash - * @apiGroup Pagans - * @apiUse apxHeader - * @param {string} alias that exist - * @param {string} tribeId that exist with a person alias - * @apiSuccess (200) {ref:"pagans",msg:"personexist",data: { person } } - * @apiError (404) {ref:"pagans",msg:"persondoesnotexist",data: { person } } - * - * @todo check accessright for req.session.header.xalias to see if jhe can get person data - * if req.param.alias == req.session.header.xalias => Owner - * else need accessright to on person set at R - * */ - res.send(Pagans.getperson(req.params.alias, req.session.header.xtribe)); -}); - -router.get("/isauth", checkHeaders, isAuthenticated, (req, res) => { - /** - * @api {get} /pagans/isauth - * @apiName Is register check xalias and xhash - * @apiGroup Pagans - * @apiUse apxHeader - * - * @apiError (400) {object} status missingheaders / xalias does not exist / signaturefailled - * @apiError (401) {object} alias anonymous (not authenticated) - * @apiError (404) {string} tribe does not exist - * - * @apiSuccess (200) {object} data contains indexfile requested - * - */ - res.send({ - status: 200, - ref: "headers", - msg: "authenticated", - data: { - xalias: req.session.header.xalias, - }, - }); -}); -router.post("/", checkHeaders, isAuthenticated, (req, res) => { - /** - * @api {post} /pagans - * @apiName Is register check xalias and xhash - * @apiGroup Pagans - * @apiUse apxHeader - * - * Create a pagan account from alias, publickey, if trusted recovery => - * Create a person in xtribe/person/xalias.json with profil.auth={email,privatekey, passphrase} - * Middleware isAuthenticated check that: - * - xhash is well signed from private key linked to the publickey of alias - * - check that alias does not already exist (if yes then verifiedsigne would be false) - * Need to wait next block chain to be sure that alias is register in the blokchain - */ - console.log("pass ici", req.body); - const feedback = { alias: req.body.alias, publickey: req.body.publickey }; - const newpagan = Pagans.create(req.body.alias, req.body.publickey); - if (newpagan.status == 200) { - if (req.body.email) { - feedback.withemail = true; - feedback.email = req.body.email; - feedback.privatekey = req.body.privatekey; - feedback.passphrase = req.body.passphrase; - Notifications.send({ - type: "email", - from: "", - dest: [req.body.email], - tpl: "registeremail", - tribe: req.session.header.xtribe, - data: feedback, - }); - } - if (req.body.trustedtribe) { - if (req.app.locals.tribeids.includes(req.body.trustedtribe)) { - delete feedback.withemail; - const persondata = { recovery: feedback }; - res.send( - Pagans.personupdate(req.body.alias, req.body.trustedtribe, persondata) - ); - } else { - res.send({ - status: 404, - ref: "Pagans", - msg: "tribedoesnotexist", - data: { tribe: req.body.trustedtribe }, - }); - } - } else { - newpagan.data = feedback; - res.send(newpagan); - } - } else { - //error to create pagan - res.send(newpagan); - } -}); -router.put("/person", checkHeaders, isAuthenticated, (req, res) => { - /** - * @api {put} /pagans/person - * @apiName Is register check xalias and xhash - * @apiGroup Pagans - * @apiUse apxHeader - * - * add/update a person = alias + tribe with specific accessright and specific schema link to tribe - * @todo add tribe/schema/person.json - */ - console.log(req.body); - res.send( - Pagans.personupdate(req.body.alias, req.session.header.xtribe, req.body) - ); -}); -router.delete("/:alias", checkHeaders, isAuthenticated, (req, res) => { - /** - * @api {delete} /pagans/:alias - * @apiName Is register check xalias and xhash - * @apiGroup Pagans - * @apiUse apxHeader - * */ - console.log(`DELETE pagans nationchains/pagans/${req.params.alias}.json`); - const result = Pagans.delete(req.params.id, req.session.header); - res.status(result.status).send(result.data); -}); -router.get("/keyrecovery/:tribeid/:email", checkHeaders, (req, res) => { - /** - * @api {get} /pagans/keyrecovery/tribe/email - * @apiName apxtrib - * @apiGroup Pagans - * - * - * - * @apiError (400) {object} status missingheaders / xalias does not exist / signaturefailled - * @apiError (401) {object} alias anonymous (not authenticated) - * @apiError (404) {string} tribe does not exist - * - * @apiSuccess (200) {object} data contains indexfile requested - * - */ - res.send(Pagans.keyrecovery(req.params.tribeId, req.params.email)); -}); module.exports = router; diff --git a/api/routes/tribes.js b/api/routes/tribes.js index ffd9952..2050776 100755 --- a/api/routes/tribes.js +++ b/api/routes/tribes.js @@ -1,6 +1,7 @@ const express = require( 'express' ); const fs = require( 'fs-extra' ); const path = require( 'path' ); +const glob = require('glob'); const conf = require(`${process.env.dirtown}/conf.json`); // Classes @@ -10,25 +11,24 @@ const checkHeaders = require( '../middlewares/checkHeaders' ); const isAuthenticated = require( '../middlewares/isAuthenticated' ); const router = express.Router(); - +/** +* @api {get} /tribes/www/:tribeId - tribe list +* @apiName getlisttrib +* @apiDescription Get list of www object (space web) +* @apiGroup Tribes +* +* @apiParam {String} tribeId it identify an existing tribe* +* @apiSuccess (object) listwww contains folder name in www for tribeId +* @apiSuccessExample {json} listwww +* HTTP/1.1 200 OK +* {status:200,ref:"Tribes",msg:"listwww",data:{listwww}} +*/ router.get('www', checkHeaders,isAuthenticated,(req,res)=>{ - /** - * @api {get} /tribes/www/:tribeId - * @apiName Get list of www object (space web) - * @apiGroup Tribes - * - * @apiUse apxHeader - * - * @apiParam {String} tribeId Mandatory it identify an existing tribe - * @apiParam {String} Check if Person has access as Read to object www - * @apiError (404) {string} status the file does not exist - * @apiError (404) {string} ref objectmodel to get in the right language - * @apiError (404) {string} msg key to get template from objectmodel - * @apiError (404) {object} data use to render lg/objectmodel_lg.json - * - * @apiSuccess (200) {object} data contains indexfile requested - */ - res.status(200).json({data:{}}) + let listwww=[] + glob.sync(`${conf.dirtown}/tribes/${req.params.tribeId}/www/*`).forEach(d=>{ + listwww.push(d.split("/").pop()) + }) + res.status(200).json({status:200,ref:"Tribes",msg:"listwww",data:{listwww}}) }) //router.post('www/') to create a webspace diff --git a/api/routes/wwws.js b/api/routes/wwws.js index 9472438..8e304e4 100644 --- a/api/routes/wwws.js +++ b/api/routes/wwws.js @@ -8,39 +8,12 @@ const checkHeaders = require("../middlewares/checkHeaders"); const isAuthenticated = require("../middlewares/isAuthenticated"); const router = express.Router(); - -/** - * To manage an nginx conf - * - */ - -router.get("/tribes/:tribeId", checkHeaders, isAuthenticated, (req, res) => { - /** - * @api {get} /www/tribes/:tribeId - * @apiName Get list of application Name - * @apiGroup Www - * - * @apiUse apxHeader - * - * @apiParam {String} tribeId Mandatory that have to exist in current town and - * - * @apiError (404) {string} status the folder does not exist - * @apiError (404) {string} ref objectmodel to get in the right language - * @apiError (404) {string} msg key to get template from objectmodel - * @apiError (404) {object} data use to www's model: 'Www' } );render lg/objectmodel_lg.json - * - * @apiSuccess (200) {object} data contains liste of www conf of a tribe - * - */ - +// GET api/wwws/conf/:tribeId/:website +// if profils accessright return the nginx conf in ${conf.dirtown}/tribes/${req.param.tribeId}/www/nginx_${req.params.tribeId}_${req.params.website}.conf +router.get("/conf/:tribeId/:website", checkHeaders, isAuthenticated, (req, res) => { res.send(Www.configlist(req.params.tribeId)); }); -router.post("/:webappname", checkHeaders, isAuthenticated, (req, res) => { - /** - * Create a space web /tribes/www/webappname - * - * - * */ +router.post("/conf/:tribeId/:website", checkHeaders, isAuthenticated, (req, res) => { res.send(Wwws.create(req.params.tribeId)); }); module.exports = router; diff --git a/api/test/notifications.js b/api/test/notifications.js deleted file mode 100644 index 29f7dd2..0000000 --- a/api/test/notifications.js +++ /dev/null @@ -1,58 +0,0 @@ -const express = require("express"); -const fs = require("fs-extra"); -const path = require("path"); - -// Classes -const Pagans = require("../models/Notifications.js"); - -// Middlewares -const checkHeaders = require("../middlewares/checkHeaders"); -const isAuthenticated = require("../middlewares/isAuthenticated"); - -const router = express.Router(); - -/** - * Get form data and send notification to user by email, sms, alert - * @api{post}/messageanonymous - * @apiName Notification - * @apiDescription Send information as anonymous to tribe's druid - * @apiGroup apxtrib - * - * @apiUse apxHeader - * @apiParam {string} objectname Mandatory - * @apiParam {String} indexname Mandatory if in conf.nationObjects then file is into nationchains/ else in /nationchains/tribes/xtribe/objectname/idx/indexname indexname contains the ObjectName .*_ (before the first _) - * - * - * @apiError {json} objectNotfound the file does not exist - * @apiErrorExample {json} - * HTTP/1.1 404 Not Found - {"status":404,"ref":"Odmdb","msg":"pathnamedoesnotexist","data":{indexpath}} - * - * @apiSuccess {object} indexfile content - * @apiSuccessExample {json} Success-Response: - * HTTP/1.1 200 OK - * {"status":200, "ref":"Odmdb", "msg":"indexexist", "data":{indexname,content:{index file}} - * - * - **/ -router.get("/alias/:alias", (req, res) => { - const getalias = Pagans.getalias(req.params.alias); - res.status(getalias.status).send(getalias); -}); -/** - * Remove serveur token - * @api {get} /pagans/logout - * @apiName Remove token - * @apiGroup Pagans - * - */ -router.get("/logout", checkHeaders, isAuthenticated, (req, res) => { - console.log(req.session.header); - const logout = Pagans.logout( - req.session.header.xalias, - req.session.header.xtribe, - req.session.header.xdays, - req.session.header.xhash - ); - res.status(logout.status).json(logout); -}); \ No newline at end of file diff --git a/api/test/odmdb.js b/api/test/odmdb.js deleted file mode 100644 index f3eab70..0000000 --- a/api/test/odmdb.js +++ /dev/null @@ -1,437 +0,0 @@ -const express = require("express"); -const glob = require("glob"); -const fs = require("fs-extra"); -const path = require("path"); -const conf = require(`${process.env.dirtown}/conf.json`); -const Odmdb = require("../models/Odmdb.js"); -// Middlewares -const checkHeaders = require("../middlewares/checkHeaders"); -const isAuthenticated = require("../middlewares/isAuthenticated"); -const router = express.Router(); - - -/** - * @api{get}/odmdb/idx/:objectname/:indexname - index Get - * @apiGroup Odmdb - * @apiName getIndex - * @apiDescription Get index file for an object - * - * @apiParam {string} objectname If in conf.nationObjects then object is into nationchains/ else in tribes/xtribe/objectname/idx/indexname indexname - * @apiParam {String} indexname name of index file in /idx/indexnamme.json - * - * - * @apiError {json} objectNotfound the file does not exist - * @apiErrorExample {json} - * HTTP/1.1 404 Not Found - {"status":404,"ref":"Odmdb","msg":"pathnamedoesnotexist","data":{indexpath}} - * - * @apiSuccess {object} indexfile content - * @apiSuccessExample {json} Success-Response: - * HTTP/1.1 200 OK - * {"status":200, "ref":"Odmdb", "msg":"indexexist", "data":{indexname,content:{index file}} - * - * - */ - router.get( - "/idx/:objectname/:indexname", - checkHeaders, - isAuthenticated, - (req, res) => { - console.log("passe"); - // indexname = objectname_key_value.json - let objectLocation = "../../nationchains/"; - if (!conf.api.nationObjects.includes(req.params.objectname)) { - objectLocation += `tribes/${req.session.headers.xtribe}/`; - // check if accessright - } - const indexpath = `${objectLocation}/${req.params.objectname}/idx/${req.params.indexname}`; - if (fs.existsSync(indexpath)) { - res - .status(200) - .json({ - ref: "Odmdb", - msg: "indexexist", - data: { - indexname: req.params.indexname, - content: fs.readJsonSync(indexpath), - }, - }); - } else { - res.status(404).json({ - ref: "Odmdb", - msg: "pathnamedoesnotexist", - data: { indexpath }, - }); - } - } - ); - -/** - * @api {get} /odmdb/rebuildidx/:objectname - index refresh all - * @apiGroup Odmdb - * @apiName refreshAllIndex - * @apiDescription Rebuild all index for an object, this can be usefull in case crash or any data conflict. - * - * @apiParam {string} objectname Mandatory - * - * @apiSuccess {object} indexfile content - * @apiSuccessExample {json} Success-Response: - * HTTP/1.1 200 OK - * {"status":200, "ref":"Odmdb", "msg":"successreindex", "data":{"indexlist":[]}} - * - * @apiError {json} objectNotfound the file does not exist - * @apiErrorExample {json} - * HTTP/1.1 404 Not Found - {"status":404,"ref":"Odmdb","msg":"see nationchains/model/lg/Odmdb_xx.json","data":"object to render with msg"} - * - */ - router.get( - "/rebuildidx/:objectname", - checkHeaders, - isAuthenticated, - (req, res) => { - console.log("reindex"); - // check validity and accessright - const objectPathname = conf.api.nationObjects.includes( - req.params.objectname - ) - ? `${conf.dirapi}/nationchains/${req.params.objectname}` - : `${conf.dirtown}/tribes/${req.session.header.xtribe}/${req.params.objectname}`; - //console.log(objectPathname); - if (!fs.existsSync(objectPathname)) { - res.status(404).json({ - status: 404, - ref: "Odmdb", - msg: "pathnamedoesnotexist", - data: { indexpath: objectPathname }, - }); - return false; - } - if ( - conf.api.nationObjects.includes(req.params.objectname) && - !req.session.header.xprofils.includes("mayor") - ) { - res.status(403).json({ - status: 403, - ref: "Odmdb", - msg: "profilnotallow", - data: { profils: "mayor" }, - }); - return false; - } - if ( - !conf.api.nationObjects.includes(req.params.objectname) && - !req.session.header.xprofils.includes("druid") - ) { - res.status(403).json({ - status: 403, - ref: "Odmdb", - msg: "profilnotallow", - data: { profils: "druid" }, - }); - return false; - } - const reindex = Odmdb.idxfromitm(objectPathname, "I", {}, {}, [], {}); - res.status(reindex.status).json(reindex); - } - ); - - - -/** - * @api {post} /odmdb/itm/:objectname - item Create - * @apiGroup Odmdb - * @apiName postItm - * @apiPermission none - * @apiDescription Add an new item (data) into a collection of objectname items. Before Check data integrity with the relevant schema. - * Then create a new primarykey. For multilanguage return see nationchains/model/lg/Odmdb_xx.json. - * - * @apiParam {string} objectname Place where to create new item, schema and version are available in /objectname/conf.json - * - * @apiBody {Object} data must pass Checkjson.js with schema - * - * @apiSuccess {json} data idxprimary Value of idxprimary into objectname collection - * @apiSuccessExample {json} Success-Response: - * HTTP/1.1 200 OK - * {"status":200, "ref":"Odmdb", "msg":"cudsuccessfull", "data":{"itm":{}}} - * - * @apiError {json} schemanotfound The objectname schema is not found - * @apiError {json} pathnamedoesnotexist The objectname does not exist for the tribe - * @apiError {json} missingprimarykey Body data must have primarykey to be created - * @apiError {json} unconsistencyapxidx some Body data get unique key that already exist - * @apiError {json} checkjsonfalse The body data are not consistent with the schema - * @apiErrorExample {json} - * HTTP/1.1 404 Not Found - * {"status":404,"ref":"Odmdb","msg":"see nationchains/model/lg/Odmdb_xx.json","data":"object to render with msg"} - * - */ -router.post("/itm/:objectname", checkHeaders, isAuthenticated, (req, res) => { - // Create an item of an object with no specificities - // if specificities then create a route / model that import odmdb -}); -router.get( - "/searchitems/:objectname/:question", - checkHeaders, - isAuthenticated, - (req, res) => { - /** - * - * - */ - console.log( - "route referentials get all language" + - req.params.objectname + - "-" + - req.params.question - ); - const getref = Referentials.getref( - true, - req.params.source, - req.params.idref, - req.session.header.xworkon, - req.session.header.xlang - ); - // Return any status the data if any erreur return empty object - res.jsonp(getref.payload.data); - } -); - -/** - * @api {get} /odmdb/itm/:objectname/:primaryindex - item Get - * @apiGroup Odmdb - * @apiName getItemFromId - * @apiDescription Get itm for a primaryid of an object - * - * @apiParam {String} objectname name Mandatory if in conf.nationObjects then file is into nationchains/ else in /nationchains/tribes/xtribe/objectname - * @apiParam {String} primaryindex the unique id where item is store - * - * @apiError {json} objectNotfound the file item does not exist - * @apiErrorExample {json} - * HTTP/1.1 404 Not Found - * {"status":404,"ref":"Odmdb","msg":"doesnotexist","data":{"objectname":"objectname","key":"apxid","val":"primaryindex"}} - * - * @apiSuccess {object} indexfile content - * @apiSuccessExample {json} Success-Response: - * HTTP/1.1 200 OK - * {"status":200, "ref":"Odmdb", "msg":"indexexist", "data":{"indexname","content":{itm file}} - * - * - */ -// indexname = objectname_key_value.json -router.get( - "/itm/:objectname/:primaryindex", - checkHeaders, - - isAuthenticated, - (req, res) => { - const objectName = req.params.objectname; - const objectId = req.params.primaryindex; - let objectLocation = "../../nationchains/"; - if (!conf.api.nationObjects.includes(objectName)) { - objectLocation += `tribes/${req.session.headers.xtribe}/${objectName}`; - // check if accessright on object on item - // in case not res.status(403) - } - const objectpath = `${objectLocation}/${objectName}/itm/${objectId}`; - - if (fs.existsSync(objectpath)) { - res.status(200).json({ data: fs.readJsonSync(objectpath) }); - } else { - res.status(404).json({ - ref: "Odmdb", - msg: "objectfiledoesnotexist", - data: { objectpath }, - }); - } - } -); -/** - * @api {get} https://wall-ants.ndda.fr/Checkjson.js - schema check data lib - * @apiGroup Odmdb - * @apiName checkjsonjs - * @apiDescription Public js lib to import in a browser by :
- * `````` - * to import in a node.js:
- * ```const Checkjson = require(`Checkjson.js`);``` - * - * with functions:
- * Checkjson.schema.validation(schema) that return
- * - {status:200, ref:"Checkjson", msg:"validcheck"} => all rules are correct
- * - {status:406, multimsg:[{ref:"Checkjson",msg:"errorkey",data:{}}]}
- * - * Checkjson.schema.data(schema{json},data{json},withschemacheck{boolean}) that return
- * - {status:200, ref:"Checkjson", msg:"validcheck"} => all data keys respect schema rules
- * - {status:417, multimsg:[{ref:"Checkjson",msg:"errorkey",data:{}}]}
- * - * To identify issues, get the language errorkey list with a get - * https://wall-ants.ndda.fr/nationchains/models/Checkjson_lg.json - * - */ - - - -/** - * @api {get} https://wall-ants.ndda.fr/nationchains/schema/:objectname - schema Get public - * @apiGroup Odmdb - * @apiName getPublicSchema - * @apiDescription Get a Schema model from public apxtrib (nations, pagans,persons,towns, tribes,wwws) - * @apiSuccess {json} contain json file - * @apiSuccessExample {json} Fichier direct - * HTTP/1.1 200 Success-response: - { - "$id": "https://smatchit.io/schema/pagan", - "$comment": "To create account bin apxtrib", - "title": "Pagans identity", - "description": "A numeric id in the nationchains world", - "type": "object", - "properties": { - "publickey": { - "title": "Alias's publickey", - "description": "Public key generate with openpgp.js", - "type": "string", - "format": "pgppublickey" - }, - "alias": { - "title": "Alias", - "description": "text to remember easily a public key", - "type": "string", - "minLength": 4, - "pattern": "^[a-z0-9]*$" - }, - "dt_delete": { - "title": "Date of death", - "description": "Date of alias delete request, your will will be apply", - "type": "string", - "format": "date-time" - }, - "will": { - "title": "Will script after death", - "description": "This will script will be apply on your data 30 days after your death", - "type": "string" - } - }, - "required": ["publickey", "alias"], - "apxid": "alias", - "apxuniquekey": ["publickey"], - "apxidx": [ - { "name": "lst_alias", "keyval": "alias" }, - { "name": "alias", "keyval": "alias" } - ], - "apxaccessrights": { - "owner": { "R": [], "D": [] }, - "anonymous": { "C": [], "R": ["alias"] }, - "pagan": { "R": ["alias", "publickey"] } - } -} - - * @apiError {json} contain json file - * @apiErrorExample {string} nginx html not found message - * HTTP/1.1 404 Not Found - * ... -**/ - -/** - * @api {get} /odmdb/schema/:objectname - schema Get private - * @apiGroup Odmdb - * @apiName getPrivateSchema - * @apiDescription Get a private (profil must have accessright R on object) to a Schema model - * - * @apiParam {String} objectname Mandatory - * - * @apiError {object} ref objectmodel to get in the right language - * @apiErrorExample {json} Error-response: - * HTTP/1.1 404 Not Found - * {"status":404,"ref":"Odmdb","msg":"schemanotfound","data":{"fullpath"}} - * - * @apiSuccess {object} data contains schema requested - * @apiSuccessExample {json} Success-Response: - * HTTP/1.1 200 Success-response: - * {"status":200,"data":{schema}} - */ -router.get("schema/:objectname", checkHeaders, isAuthenticated, (req, res) => { - const fullpath = path.resolve( - `${__dirname}/tribes/${req.session.header.xworkon}/schema/${req.params.pathobjectname}.json` - ); - if (fs.existsSync(fullpath)) { - res.status(200).json({ data: fs.readJsonSync(fullpath) }); - } else { - res - .status(404) - .json({ status:404, msg: "schemanotfound", ref: "odmdb", data: { fullpath } }); - } -}); - -/** - * @api {put} /odmdb/schema/:objectname - schema Put - * @apiGroup Odmdb - * @apiName putSchema - * @apiDescription Replace a schema by another one need druid profil for a tribe - * - * @apiParam {String} objectname Mandatory - * - * @apiBody {string} schemapath where to store schema .../schema - * @apiBody {string} objectpath where to store object ...objectname/idx/conf.json - * @apiBody {json} schema content - * @apiBody {json} schemalang content in lg - * @apiBody {string} lang define which schemalg is (2 letters) - * - * @apiError {object} ref objectmodel to get in the right language - * @apiErrorExample {json} Error-response: - * HTTP/1.1 404 Not Found - * {"status":404,"ref":"Odmdb","msg":"schemanotfound","data":{"fullpath"}} - * - * @apiSuccess {object} data contains schema requested - * HTTP/1.1 200 Success-response: - * {"status":200,"data":{schema}} - * - * - */ -router.put("schema/:objectname", checkHeaders, isAuthenticated, (req, res) => { - const fullpath = path.resolve( - `${__dirname}/tribes/${req.session.header.xworkon}/schema/${req.params.pathobjectname}.json` - ); - const set = Odmdb.setObject( - path.resolve(`${__dirname}/tribes/${req.session.header.xworkon}`) - ); - - if (fs.existsSync(fullpath)) { - res.status(200).json({ data: fs.readJsonSync(fullpath) }); - } else { - res - .status(404) - .json({ msg: "schemanotfound", ref: "odmdb", data: { fullpath } }); - } -}); - - -/** - * @api {get} https://wall-ants.ndda.fr/nationchains/models/:modelname_lg.json - translation notif Get public - * @apiGroup Odmdb - * @apiName getPublicModelmessagekey - * @apiDescription Get a public json object for the ref: modelname in language lg, to get a template description with key msg - * @apiParam {string} modelname Mandatory - * @apiSuccess {json} contain json file - * @apiSuccessExample {json} Fichier direct - * HTTP/1.1 200 Success-response: - * { - "alreadyexist": "Un object {{objectname}} avec la clé {{key}} existe déjà avec {{val}}", - "doesnotexist": "L'object {{objectname}} avec la clé {{key}} ,'existe pas avec {{val}}", - "getschema": "Schema {{{conf.name}}}", - "schemanotfound": "Schema introuvable dans {{{schemaPath}}}", - "pathnamedoesnotexist": "Le repertoire n'existe pas {{{indexpath}}}", - "objectfiledoesnotexist": "Le fichier n'existe pas {{{objectpath}}}", - "cudsuccessfull": "Mise à jour effectuée avec succés", - "missingprimarykey": "Il manque une clé primaire apxid pour stocker et identifier les objects", - "unconsistencyapxidx": "L'index {{name}} doit contenir en objkey au moins {{apxid}} car keyval n'est pas unique", - "profilnotallow": "Vous n'avez pas le profil de {{profils}}, cette action n'est pas authorisée", - "successreindex": "Objet reindexé à partir des items, vos index sont à jour", - "indexexist":"L'indexe existe" -} - - * @apiError {json} contain json file - * @apiErrorExample {string} nginx html not found message - * HTTP/1.1 404 Not Found - * ... -**/ - -module.exports = router; diff --git a/api/test/pagans.js b/api/test/pagans.js deleted file mode 100755 index 3241416..0000000 --- a/api/test/pagans.js +++ /dev/null @@ -1,264 +0,0 @@ -const express = require("express"); -const fs = require("fs-extra"); -const path = require("path"); - -// Classes -const Pagans = require("../models/Pagans.js"); - -// Middlewares -const checkHeaders = require("../middlewares/checkHeaders"); -const isAuthenticated = require("../middlewares/isAuthenticated"); - -const router = express.Router(); -/** - * /api/models/Pagans.js - * - * Managed: - -/** - * Alias exist then return public key or not - * @api {get} /pagans/alias/:alias - alias Get - * @apiName isalias - * @apiGroup Pagans - * @apiDescription If alias exist return its publickey - * - * @param {string} alias - * - * @apiError {json} aliasdoesnotexist - * @apiErrorExample {json} - * HTTP/1.1 404 Not Found - {"status":404,"ref":"pagans","msg":"aliasdoesnotexist","data": { alias}} - * - * @apiSuccess {object} indexfile content - * @apiSuccessExample {json} Success-Response: - * HTTP/1.1 200 OK - * {"status":200, ref:"pagans","msg":"aliasexist","data": { alias, publicKey }} - * * - **/ -router.get("/alias/:alias", (req, res) => { - const getalias = Pagans.getalias(req.params.alias); - res.status(getalias.status).send(getalias); -}); -/** - * Remove serveur token - * @api {get} /pagans/logout - pagan Logout - * @apiName Removetoken - * @apiGroup Pagans - * @apiDescription Remove token - * - * @apiSuccess {object} indexfile content - * @apiSuccessExample {json} Success-Response: - * HTTP/1.1 200 OK - * {status: 200, ref: "Pagans", msg: "logout" - * - */ -router.get("/logout", checkHeaders, isAuthenticated, (req, res) => { - console.log(req.session.header); - const logout = Pagans.logout( - req.session.header.xalias, - req.session.header.xtribe, - req.session.header.xdays, - req.session.header.xhash - ); - res.status(logout.status).json(logout); -}); -/** - * @api {get} /pagans/isauth - pagan isAuthenticated? - * @apiName isAuth - * @apiGroup Pagans - * @apiDescription Check if pagan's token is still valid - * - * @apiError (400) missingheaders - * @apiError (400) xaliasdoesnotexist - * @apiError (400) signaturefailled - * @apiError (401) aliasanonymous - * @apiError (404) tribedoesnotexist - * - * @apiSuccess (200) valid - * {object} data contains indexfile requested - * - */ -router.get("/isauth", checkHeaders, isAuthenticated, (req, res) => { - res.status(200).send({ - status: 200, - ref: "headers", - msg: "authenticated", - data: { - xalias: req.session.header.xalias, - xprofils: req.session.header.xprofils, - }, - }); -}); - -/** - * @api {post} /pagans - pagan Post - * @apiName addpagan - * @apiGroup Pagans - * @apiDescription - * Create a pagan account from alias, publickey, if trusted recovery => - * Create a person in xtribe/person/xalias.json with profil.auth={email,privatekey, passphrase} - * Middleware isAuthenticated check that: - * - xhash is well signed from private key linked to the publickey of alias - * - check that alias does not already exist (if yes then verifiedsigne would be false) - * Need to wait next block chain to be sure that alias is register in the blokchain - * - * @apiError {json} objectNotfound the file does not exist - * @apiErrorExample {json} - * HTTP/1.1 404 Not Found - {"status":404,"ref":"Odmdb","msg":"pathnamedoesnotexist","data":{indexpath}} - * - * @apiSuccess {object} indexfile content - * @apiSuccessExample {json} Success-Response: - * HTTP/1.1 200 OK - * {"status":200, "ref":"Odmdb", "msg":"indexexist", "data":{indexname,content:{index file}} - * - */ -router.post("/", checkHeaders, isAuthenticated, (req, res) => { - //console.log("pass ici", req.body); - const objpagan = { alias: req.body.alias, publickey: req.body.publickey }; - const newpagan = Pagans.create(objpagan, { - xalias: req.session.header.xalias, - xprofils: req.session.header.xprofils, - }); - if (newpagan.status == 200) { - if (req.body.email) { - const emailsent = Pagans.sendmailkey( - req.body.alias, - req.body.privatekey, - req.session.header.xtribe, - req.body.passphrase, - req.body.publickey, - req.body.email - ); - } - if (req.body.trustedtribe) { - const personup = Pagans.personupdate( - req.body.alias, - req.body.trustedtribe, - { - recoveryauth: { - email: req.body.email, - privatekey: req.body.privatekey, - publickey: req.body.publickey, - passphrase: req.body.passphrase, - }, - } - ); - if (personup.status !== 200) - console.log("Warning no recovery registration", personup); - } - if (emailsent && emailsent.status != 200) { - newpagan.msg = "successfulcreatewithoutemail"; - res.status(newpagan.status).json(newpagan); - } - } else { - //error to create pagan certaily already exist - res.status(newpagan.status).json(newpagan); - } -}); -/** - * @api {delete} /pagans/alias/:alias - pagan Delete - * @apiName deletepagan - * @apiGroup Pagans - * @apiDescription - * Delete an alias and his publickey - * */ -router.delete("/alias/:alias", checkHeaders, isAuthenticated, (req, res) => { - console.log(`DELETE pagans nationchains/pagans/${req.params.alias}.json`); - const result = Pagans.deletealias(req.params.id, req.session.header); - res.status(result.status).send(result.data); -}); -router.delete("/person/:alias", checkHeaders, isAuthenticated, (req, res) => { - console.log(`DELETE pagans nationchains/pagans/${req.params.alias}.json`); - const result = Pagans.deleteperson(req.params.id, req.session.header); - res.status(result.status).send(result.data); -}); - -/** - * @api {get} /pagans/person:alias - person Get - * @apiName getpersondata - * @apiDescription Get person information from his alias for a xtribe (data and profils per apps) - * @apiGroup Pagans - * - * @apiParam {string} alias - * - * @apiSuccess (200) personExist - * @apiSuccessExample {json} - * {status:200, ref:"pagans",msg:"personexist",data: { person } } - * - * @apiError (404) Notfound - * @apiErrorExample {json} - * {status: 404, ref:"pagans",msg:"persondoesnotexist",data: { person } } - * - * @todo check accessright for req.session.header.xalias to see if jhe can get person data - * if req.param.alias == req.session.header.xalias => Owner - * else need accessright to on person set at R - * */ -router.get("/person/:alias", checkHeaders, isAuthenticated, (req, res) => { - const getperson = Pagans.getperson( - req.session.header.xtribe, - req.params.alias, - { xprofils: req.session.header.xprofils, xalias: req.session.header.xalias } - ); - res.status(getperson.status).send(getperson); -}); - -/** - * @api {post} /pagans/person - person Post - * @apiName addperson - * @apiGroup Pagans - * @apiDescription - * add a person = alias + tribe with specific accessright and specific schema link to tribe - * - * - * - * @todo add tribe/schema/person.json - */ -router.post("/person", checkHeaders, isAuthenticated, (req, res) => { - //console.log(req.body); - const persoad = Pagans.personcreate( - req.session.header.xtribe, - req.body.alias, - req.body, - { xprofils: req.session.header.xprofils, xalias: req.session.header.xalias } - ); - res.status(persoad.status).json(persoad); -}); - -/** - * @api {put} /pagans/person - person Put - * @apiName updateperson - * @apiGroup Pagans - * @apiDescription - * update a person = alias + tribe with specific accessright and specific schema link to tribe - -* @todo add tribe/schema/person.json - */ -router.put("/person", checkHeaders, isAuthenticated, (req, res) => { - //console.log(req.body); - const persoup = Pagans.personupdate( - req.session.header.xtribe, - req.body.alias, - req.body, - { xprofils: req.session.header.xprofils, xalias: req.session.header.xalias } - ); - res.status(persoup.status).json(persoup); -}); - - -/** - * @api {get} /pagans/keyrecovery/tribe/email - recovery key by email - * @apiName recoveryKey - * @apiGroup Pagans - * - * @apiError (400) {object} status missingheaders / xalias does not exist / signaturefailled - * @apiError (401) {object} alias anonymous (not authenticated) - * @apiError (404) {string} tribe does not exist - * - * @apiSuccess (200) {object} data contains indexfile requested - * - */ -router.get("/keyrecovery/:tribeid/:email", checkHeaders, (req, res) => { - res.send(Pagans.keyrecovery(req.params.tribeId, req.params.email)); -}); -module.exports = router; diff --git a/api/test/trackings.js b/api/test/trackings.js deleted file mode 100644 index 0f9c8cc..0000000 --- a/api/test/trackings.js +++ /dev/null @@ -1,82 +0,0 @@ -const express = require("express"); -const glob = require("glob"); -const fs = require("fs-extra"); -const path = require("path"); -const conf = require(`${process.env.dirtown}/conf.json`); -const Odmdb = require("../models/Odmdb.js"); -// Middlewares -const checkHeaders = require("../middlewares/checkHeaders"); -const isAuthenticated = require("../middlewares/isAuthenticated"); -const router = express.Router(); - - -/** - * @api {get} https://dns.xx/trk/pathtofile? - tracking system - * @apiGroup Trackings - * @apiName trackingsystem - * @apiDescription - * without header:
- * https://dns.xx/trk/pathtofile?alias=anonymous&uuid=1b506f71-1bff-416c-9057-cb8b86296f60&src=btnregister&version=1&lg=fr - * - * with header
- * https://dns.xx/trk/pathtofile?srckey=btnregister&version=1 - * - * where pathtofile is a ressource accessible from https://dns.xx/pathtofile -* html usage to track a loading page or email when a picture is load - * using apxwebapp in /src/ we got: - * < img src="static/img/photo.jpg" data-trksrckey="loadpage" data-version="1" > - * - * using html + apx.js (or at least with header {xalias,xuuid,xlang}) - * < img lazysrc="trk/static/img/photo.jpg data-trksrckey="loadpage" data-version="1" > - * - * in js action: - * - * - * - * - * - * - * #will hit an eventlistener
- * axios.get("https://dns.xx/trk/cdn/empty.json?alias=anonymous&uuid=1b506f71-1bff-416c-9057-cb8b86296f60&srckey=btnregister&version=1"); - * - * - * #or if no js available (example:email or pdf document)
- * < img src="https://dns.xx/trk/static/img/photo.jpg?alias=anonymous&uuid=1b506f71-1bff-416c-9057-cb8b86296f60&srckey=loadpage&version=1" - * - * - * - * - * will hit a tracker then redirect to url> * - * - * - * - * **if you use apx.js** : in html add in < button >, < img >, < a > tag data-trksrc="srckey" - * - * < img src="https://dns.xx/static/img/photo.jpg" data-trkversion="1" data-trksrckey="registerform"> - * < button data-trksrc="https://dns.xx/static/img/photo.jpg" data-trkversion="1" data-trksrckey="registerform"> - * - * - * Tracking log are store into tribe/logs/nginx/tribe_appname.trk.log - * Src have to be manage in tribe/api/models/lg/src_en.json - * {"srckey":{ - * "app":"presentation|app|apptest", - * "title":"", - * "description":"" - * } - * } - * - * - * @apiParam {String} alias=anonymous if authenticated we get from headers - * @apiParam {String} uuid a uuid v4 generate the first time a web page is open on a browser - * @apiParam {String} srckey source action that trig this get - * @apiParam {integer} version=1 can be an int, date or any version of the src - * @apiParam {integer} [tm] a timestamp of action when it is not immediate (for offline app) - * - */ - - - - -module.exports=router; \ No newline at end of file diff --git a/package.json b/package.json index 9e4d179..308639c 100755 --- a/package.json +++ b/package.json @@ -19,15 +19,15 @@ "logpm2": "pm2 logs apxtrib.js --lines 200", "dev": "node apxtrib.js", "unittest": "node unittest.js", - "apidoc": "apidoc -i api/middlewares api/test -o adminapi/www/apidoc", - "apidocsmatchit": "apidoc -i ../devfarm-ants/tribes/smatchit/api/routes -o adminapi/www/apidoc" + "apidoc": "apidoc -i api/middlewares api/routes -o adminapi/www/cdn/apidoc", + "apidocsmatchit": "apidoc -i ../devfarm-ants/tribes/smatchit/api/middlewares ../devfarm-ants/tribes/smatchit/api/routes -o ../devfarm-ants/tribes/smatchit/www/cdn/apidoc" }, "apidoc": { "name": "apXtrib", "version": "1.0.0", "title": "apiDoc for apXtrib", "description": "Core api documentation", - "url": "https://smatchit.io/api", + "url": "https://wall-ants.ndda.fr/api", "urlprod": "https://wall-ants.ndda.fr/apidoc/v1", "order": [ "Middlewares",