escobar 0.1.92__py3-none-any.whl → 0.1.94__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- escobar/_version.py +1 -1
- escobar/handlers.py +2 -2
- escobar/labextension/package.json +2 -2
- escobar/labextension/schemas/escobar/package.json.orig +1 -1
- escobar/labextension/static/{653.2348cd42bb15caeb6a4d.js → 653.09d06963cff377716db8.js} +1 -1
- escobar/labextension/static/{remoteEntry.4b2f86eacb2c83e28f43.js → remoteEntry.a77434f417b2a7097a56.js} +1 -1
- {escobar-0.1.92.data → escobar-0.1.94.data}/data/share/jupyter/labextensions/escobar/package.json +2 -2
- {escobar-0.1.92.data → escobar-0.1.94.data}/data/share/jupyter/labextensions/escobar/schemas/escobar/package.json.orig +1 -1
- escobar-0.1.92.data/data/share/jupyter/labextensions/escobar/static/653.2348cd42bb15caeb6a4d.js → escobar-0.1.94.data/data/share/jupyter/labextensions/escobar/static/653.09d06963cff377716db8.js +1 -1
- escobar-0.1.92.data/data/share/jupyter/labextensions/escobar/static/remoteEntry.4b2f86eacb2c83e28f43.js → escobar-0.1.94.data/data/share/jupyter/labextensions/escobar/static/remoteEntry.a77434f417b2a7097a56.js +1 -1
- escobar-0.1.94.dist-info/METADATA +200 -0
- {escobar-0.1.92.dist-info → escobar-0.1.94.dist-info}/RECORD +28 -28
- escobar-0.1.92.dist-info/METADATA +0 -56
- {escobar-0.1.92.data → escobar-0.1.94.data}/data/share/jupyter/labextensions/escobar/install.json +0 -0
- {escobar-0.1.92.data → escobar-0.1.94.data}/data/share/jupyter/labextensions/escobar/schemas/escobar/plugin.json +0 -0
- {escobar-0.1.92.data → escobar-0.1.94.data}/data/share/jupyter/labextensions/escobar/static/304.bf7e91be734e5b36cdc9.js +0 -0
- {escobar-0.1.92.data → escobar-0.1.94.data}/data/share/jupyter/labextensions/escobar/static/346.8a1e61ca6789b6fddfa7.js +0 -0
- {escobar-0.1.92.data → escobar-0.1.94.data}/data/share/jupyter/labextensions/escobar/static/379.40dd59dc19d4a6b42d25.js +0 -0
- {escobar-0.1.92.data → escobar-0.1.94.data}/data/share/jupyter/labextensions/escobar/static/57.17e53b4b9a954f39c4d8.js +0 -0
- {escobar-0.1.92.data → escobar-0.1.94.data}/data/share/jupyter/labextensions/escobar/static/648.a7d314faeacc762d891d.js +0 -0
- {escobar-0.1.92.data → escobar-0.1.94.data}/data/share/jupyter/labextensions/escobar/static/666.3bc65aac3a3be183ee19.js +0 -0
- {escobar-0.1.92.data → escobar-0.1.94.data}/data/share/jupyter/labextensions/escobar/static/874.c539726f31a1baa0267e.js +0 -0
- {escobar-0.1.92.data → escobar-0.1.94.data}/data/share/jupyter/labextensions/escobar/static/986.cbcf9d7c1cd8d06be435.js +0 -0
- {escobar-0.1.92.data → escobar-0.1.94.data}/data/share/jupyter/labextensions/escobar/static/oauth-callback.html +0 -0
- {escobar-0.1.92.data → escobar-0.1.94.data}/data/share/jupyter/labextensions/escobar/static/style.js +0 -0
- {escobar-0.1.92.data → escobar-0.1.94.data}/data/share/jupyter/labextensions/escobar/static/third-party-licenses.json +0 -0
- {escobar-0.1.92.dist-info → escobar-0.1.94.dist-info}/WHEEL +0 -0
- {escobar-0.1.92.dist-info → escobar-0.1.94.dist-info}/entry_points.txt +0 -0
- {escobar-0.1.92.dist-info → escobar-0.1.94.dist-info}/licenses/LICENSE +0 -0
@@ -1 +1 @@
|
|
1
|
-
var _JUPYTERLAB;(()=>{"use strict";var e,r,t,a,n,o,i,l,u,f,d,s,c,h,p,b,v,m,g,y,w,j,k,S,P,E={8056:(e,r,t)=>{var a={"./index":()=>Promise.all([t.e(666),t.e(923),t.e(653)]).then((()=>()=>t(4364))),"./extension":()=>Promise.all([t.e(666),t.e(923),t.e(653)]).then((()=>()=>t(4364))),"./style":()=>t.e(304).then((()=>()=>t(7923)))},n=(e,r)=>(t.R=r,r=t.o(a,e)?a[e]():Promise.resolve().then((()=>{throw new Error('Module "'+e+'" does not exist in container.')})),t.R=void 0,r),o=(e,r)=>{if(t.S){var a="default",n=t.S[a];if(n&&n!==e)throw new Error("Container initialization failed as it has already been initialized with a different share scope");return t.S[a]=e,t.I(a,r)}};t.d(r,{get:()=>n,init:()=>o})}},x={};function T(e){var r=x[e];if(void 0!==r)return r.exports;var t=x[e]={id:e,exports:{}};return E[e](t,t.exports,T),t.exports}T.m=E,T.c=x,T.n=e=>{var r=e&&e.__esModule?()=>e.default:()=>e;return T.d(r,{a:r}),r},T.d=(e,r)=>{for(var t in r)T.o(r,t)&&!T.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:r[t]})},T.f={},T.e=e=>Promise.all(Object.keys(T.f).reduce(((r,t)=>(T.f[t](e,r),r)),[])),T.u=e=>e+"."+{57:"17e53b4b9a954f39c4d8",304:"bf7e91be734e5b36cdc9",346:"8a1e61ca6789b6fddfa7",379:"40dd59dc19d4a6b42d25",648:"a7d314faeacc762d891d",653:"
|
1
|
+
var _JUPYTERLAB;(()=>{"use strict";var e,r,t,a,n,o,i,l,u,f,d,s,c,h,p,b,v,m,g,y,w,j,k,S,P,E={8056:(e,r,t)=>{var a={"./index":()=>Promise.all([t.e(666),t.e(923),t.e(653)]).then((()=>()=>t(4364))),"./extension":()=>Promise.all([t.e(666),t.e(923),t.e(653)]).then((()=>()=>t(4364))),"./style":()=>t.e(304).then((()=>()=>t(7923)))},n=(e,r)=>(t.R=r,r=t.o(a,e)?a[e]():Promise.resolve().then((()=>{throw new Error('Module "'+e+'" does not exist in container.')})),t.R=void 0,r),o=(e,r)=>{if(t.S){var a="default",n=t.S[a];if(n&&n!==e)throw new Error("Container initialization failed as it has already been initialized with a different share scope");return t.S[a]=e,t.I(a,r)}};t.d(r,{get:()=>n,init:()=>o})}},x={};function T(e){var r=x[e];if(void 0!==r)return r.exports;var t=x[e]={id:e,exports:{}};return E[e](t,t.exports,T),t.exports}T.m=E,T.c=x,T.n=e=>{var r=e&&e.__esModule?()=>e.default:()=>e;return T.d(r,{a:r}),r},T.d=(e,r)=>{for(var t in r)T.o(r,t)&&!T.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:r[t]})},T.f={},T.e=e=>Promise.all(Object.keys(T.f).reduce(((r,t)=>(T.f[t](e,r),r)),[])),T.u=e=>e+"."+{57:"17e53b4b9a954f39c4d8",304:"bf7e91be734e5b36cdc9",346:"8a1e61ca6789b6fddfa7",379:"40dd59dc19d4a6b42d25",648:"a7d314faeacc762d891d",653:"09d06963cff377716db8",666:"3bc65aac3a3be183ee19",874:"c539726f31a1baa0267e",986:"cbcf9d7c1cd8d06be435"}[e]+".js?v="+{57:"17e53b4b9a954f39c4d8",304:"bf7e91be734e5b36cdc9",346:"8a1e61ca6789b6fddfa7",379:"40dd59dc19d4a6b42d25",648:"a7d314faeacc762d891d",653:"09d06963cff377716db8",666:"3bc65aac3a3be183ee19",874:"c539726f31a1baa0267e",986:"cbcf9d7c1cd8d06be435"}[e],T.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),T.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),e={},r="escobar:",T.l=(t,a,n,o)=>{if(e[t])e[t].push(a);else{var i,l;if(void 0!==n)for(var u=document.getElementsByTagName("script"),f=0;f<u.length;f++){var d=u[f];if(d.getAttribute("src")==t||d.getAttribute("data-webpack")==r+n){i=d;break}}i||(l=!0,(i=document.createElement("script")).charset="utf-8",i.timeout=120,T.nc&&i.setAttribute("nonce",T.nc),i.setAttribute("data-webpack",r+n),i.src=t),e[t]=[a];var s=(r,a)=>{i.onerror=i.onload=null,clearTimeout(c);var n=e[t];if(delete e[t],i.parentNode&&i.parentNode.removeChild(i),n&&n.forEach((e=>e(a))),r)return r(a)},c=setTimeout(s.bind(null,void 0,{type:"timeout",target:i}),12e4);i.onerror=s.bind(null,i.onerror),i.onload=s.bind(null,i.onload),l&&document.head.appendChild(i)}},T.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},(()=>{T.S={};var e={},r={};T.I=(t,a)=>{a||(a=[]);var n=r[t];if(n||(n=r[t]={}),!(a.indexOf(n)>=0)){if(a.push(n),e[t])return e[t];T.o(T.S,t)||(T.S[t]={});var o=T.S[t],i="escobar",l=(e,r,t,a)=>{var n=o[e]=o[e]||{},l=n[r];(!l||!l.loaded&&(!a!=!l.eager?a:i>l.from))&&(n[r]={get:t,from:i,eager:!!a})},u=[];return"default"===t&&(l("@codemirror/merge","6.10.0",(()=>Promise.all([T.e(379),T.e(923)]).then((()=>()=>T(2379))))),l("escobar","0.1.94",(()=>Promise.all([T.e(666),T.e(923),T.e(653)]).then((()=>()=>T(4364))))),l("highlight.js","0",(()=>T.e(57).then((()=>()=>T(7057))))),l("katex","0.6.0",(()=>T.e(874).then((()=>()=>T(7874))))),l("markdown-it-highlightjs","4.2.0",(()=>T.e(648).then((()=>()=>T(9648))))),l("markdown-it-katex","2.0.3",(()=>T.e(986).then((()=>()=>T(7986))))),l("markdown-it","14.1.0",(()=>T.e(346).then((()=>()=>T(1346)))))),e[t]=u.length?Promise.all(u).then((()=>e[t]=1)):1}}})(),(()=>{var e;T.g.importScripts&&(e=T.g.location+"");var r=T.g.document;if(!e&&r&&(r.currentScript&&"SCRIPT"===r.currentScript.tagName.toUpperCase()&&(e=r.currentScript.src),!e)){var t=r.getElementsByTagName("script");if(t.length)for(var a=t.length-1;a>-1&&(!e||!/^http(s?):/.test(e));)e=t[a--].src}if(!e)throw new Error("Automatic publicPath is not supported in this browser");e=e.replace(/^blob:/,"").replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),T.p=e})(),t=e=>{var r=e=>e.split(".").map((e=>+e==e?+e:e)),t=/^([^-+]+)?(?:-([^+]+))?(?:\+(.+))?$/.exec(e),a=t[1]?r(t[1]):[];return t[2]&&(a.length++,a.push.apply(a,r(t[2]))),t[3]&&(a.push([]),a.push.apply(a,r(t[3]))),a},a=(e,r)=>{e=t(e),r=t(r);for(var a=0;;){if(a>=e.length)return a<r.length&&"u"!=(typeof r[a])[0];var n=e[a],o=(typeof n)[0];if(a>=r.length)return"u"==o;var i=r[a],l=(typeof i)[0];if(o!=l)return"o"==o&&"n"==l||"s"==l||"u"==o;if("o"!=o&&"u"!=o&&n!=i)return n<i;a++}},n=e=>{var r=e[0],t="";if(1===e.length)return"*";if(r+.5){t+=0==r?">=":-1==r?"<":1==r?"^":2==r?"~":r>0?"=":"!=";for(var a=1,o=1;o<e.length;o++)a--,t+="u"==(typeof(l=e[o]))[0]?"-":(a>0?".":"")+(a=2,l);return t}var i=[];for(o=1;o<e.length;o++){var l=e[o];i.push(0===l?"not("+u()+")":1===l?"("+u()+" || "+u()+")":2===l?i.pop()+" "+i.pop():n(l))}return u();function u(){return i.pop().replace(/^\((.+)\)$/,"$1")}},o=(e,r)=>{if(0 in e){r=t(r);var a=e[0],n=a<0;n&&(a=-a-1);for(var i=0,l=1,u=!0;;l++,i++){var f,d,s=l<e.length?(typeof e[l])[0]:"";if(i>=r.length||"o"==(d=(typeof(f=r[i]))[0]))return!u||("u"==s?l>a&&!n:""==s!=n);if("u"==d){if(!u||"u"!=s)return!1}else if(u)if(s==d)if(l<=a){if(f!=e[l])return!1}else{if(n?f>e[l]:f<e[l])return!1;f!=e[l]&&(u=!1)}else if("s"!=s&&"n"!=s){if(n||l<=a)return!1;u=!1,l--}else{if(l<=a||d<s!=n)return!1;u=!1}else"s"!=s&&"n"!=s&&(u=!1,l--)}}var c=[],h=c.pop.bind(c);for(i=1;i<e.length;i++){var p=e[i];c.push(1==p?h()|h():2==p?h()&h():p?o(p,r):!h())}return!!h()},i=(e,r)=>e&&T.o(e,r),l=e=>(e.loaded=1,e.get()),u=e=>Object.keys(e).reduce(((r,t)=>(e[t].eager&&(r[t]=e[t]),r)),{}),f=(e,r,t)=>{var n=t?u(e[r]):e[r];return(r=Object.keys(n).reduce(((e,r)=>!e||a(e,r)?r:e),0))&&n[r]},d=(e,r,t,n)=>{var i=n?u(e[r]):e[r];return(r=Object.keys(i).reduce(((e,r)=>!o(t,r)||e&&!a(e,r)?e:r),0))&&i[r]},s=(e,r,t)=>{var n=t?u(e[r]):e[r];return Object.keys(n).reduce(((e,r)=>!e||!n[e].loaded&&a(e,r)?r:e),0)},c=(e,r,t,a)=>"Unsatisfied version "+t+" from "+(t&&e[r][t].from)+" of shared singleton module "+r+" (required "+n(a)+")",h=(e,r,t,a,o)=>{var i=e[t];return"No satisfying version ("+n(a)+")"+(o?" for eager consumption":"")+" of shared module "+t+" found in shared scope "+r+".\nAvailable versions: "+Object.keys(i).map((e=>e+" from "+i[e].from)).join(", ")},p=e=>{throw new Error(e)},b=e=>{"undefined"!=typeof console&&console.warn&&console.warn(e)},m=(e,r,t)=>t?t():((e,r)=>p("Shared module "+r+" doesn't exist in shared scope "+e))(e,r),g=(v=e=>function(r,t,a,n,o){var i=T.I(r);return i&&i.then&&!a?i.then(e.bind(e,r,T.S[r],t,!1,n,o)):e(r,T.S[r],t,a,n,o)})(((e,r,t,a,n,o)=>{if(!i(r,t))return m(e,t,o);var u=d(r,t,n,a);return u?l(u):(b(h(r,e,t,n,a)),l(f(r,t,a)))})),y=v(((e,r,t,a,n,o)=>{if(!i(r,t))return m(e,t,o);var u=d(r,t,n,a);return u?l(u):o?o():void p(h(r,e,t,n,a))})),w=v(((e,r,t,a,n,u)=>{if(!i(r,t))return m(e,t,u);var f=s(r,t,a);return o(n,f)||b(c(r,t,f,n)),l(r[t][f])})),j={},k={195:()=>w("default","@codemirror/state",!1,[1,6,2,0]),1839:()=>w("default","@lezer/highlight",!1,[1,1,0,0]),2084:()=>w("default","@codemirror/language",!1,[1,6,0,0]),5024:()=>w("default","@codemirror/view",!1,[1,6,9,6]),1041:()=>w("default","@jupyterlab/debugger",!1,[1,4,4,2]),1731:()=>y("default","markdown-it-highlightjs",!1,[1,4,2,0],(()=>T.e(648).then((()=>()=>T(9648))))),2226:()=>w("default","@jupyterlab/mainmenu",!1,[1,4,4,2]),2235:()=>w("default","@jupyterlab/ui-components",!1,[1,4,4,2]),2653:()=>w("default","@jupyterlab/settingregistry",!1,[1,4,4,2]),3708:()=>w("default","@lezer/common",!1,[1,1,0,0]),4461:()=>w("default","@jupyterlab/fileeditor",!1,[1,4,4,2]),5256:()=>w("default","@lumino/widgets",!1,[1,2,3,1,,"alpha",0]),5263:()=>w("default","@jupyterlab/notebook",!1,[1,4,4,2]),5271:()=>y("default","highlight.js",!1,[1,11,11,1],(()=>T.e(57).then((()=>()=>T(7057))))),5551:()=>w("default","@jupyterlab/apputils",!1,[1,4,5,2]),5963:()=>y("default","@codemirror/merge",!1,[1,6,10,0],(()=>T.e(379).then((()=>()=>T(2379))))),6118:()=>w("default","@jupyterlab/application",!1,[1,4,4,2]),6954:()=>y("default","markdown-it-katex",!1,[1,2,0,3],(()=>T.e(986).then((()=>()=>T(7986))))),8178:()=>w("default","@jupyterlab/codemirror",!1,[1,4,4,2]),8914:()=>g("default","@jupyterlab/cells",!1,[1,4,4,2]),8968:()=>w("default","@jupyterlab/launcher",!1,[1,4,4,2]),9650:()=>y("default","markdown-it",!1,[1,14,1,0],(()=>T.e(346).then((()=>()=>T(1346))))),3285:()=>y("default","highlight.js",!1,[1,11,9,0],(()=>T.e(57).then((()=>()=>T(7057))))),8097:()=>y("default","katex",!1,[2,0,6,0],(()=>T.e(874).then((()=>()=>T(7874)))))},S={648:[3285],653:[1041,1731,2226,2235,2653,3708,4461,5256,5263,5271,5551,5963,6118,6954,8178,8914,8968,9650],923:[195,1839,2084,5024],986:[8097]},P={},T.f.consumes=(e,r)=>{T.o(S,e)&&S[e].forEach((e=>{if(T.o(j,e))return r.push(j[e]);if(!P[e]){var t=r=>{j[e]=0,T.m[e]=t=>{delete T.c[e],t.exports=r()}};P[e]=!0;var a=r=>{delete j[e],T.m[e]=t=>{throw delete T.c[e],r}};try{var n=k[e]();n.then?r.push(j[e]=n.then(t).catch(a)):t(n)}catch(e){a(e)}}}))},(()=>{var e={940:0};T.f.j=(r,t)=>{var a=T.o(e,r)?e[r]:void 0;if(0!==a)if(a)t.push(a[2]);else if(923!=r){var n=new Promise(((t,n)=>a=e[r]=[t,n]));t.push(a[2]=n);var o=T.p+T.u(r),i=new Error;T.l(o,(t=>{if(T.o(e,r)&&(0!==(a=e[r])&&(e[r]=void 0),a)){var n=t&&("load"===t.type?"missing":t.type),o=t&&t.target&&t.target.src;i.message="Loading chunk "+r+" failed.\n("+n+": "+o+")",i.name="ChunkLoadError",i.type=n,i.request=o,a[1](i)}}),"chunk-"+r,r)}else e[r]=0};var r=(r,t)=>{var a,n,[o,i,l]=t,u=0;if(o.some((r=>0!==e[r]))){for(a in i)T.o(i,a)&&(T.m[a]=i[a]);l&&l(T)}for(r&&r(t);u<o.length;u++)n=o[u],T.o(e,n)&&e[n]&&e[n][0](),e[n]=0},t=self.webpackChunkescobar=self.webpackChunkescobar||[];t.forEach(r.bind(null,0)),t.push=r.bind(null,t.push.bind(t))})(),T.nc=void 0;var O=T(8056);(_JUPYTERLAB=void 0===_JUPYTERLAB?{}:_JUPYTERLAB).escobar=O})();
|
@@ -0,0 +1,200 @@
|
|
1
|
+
Metadata-Version: 2.4
|
2
|
+
Name: escobar
|
3
|
+
Version: 0.1.94
|
4
|
+
Dynamic: Keywords
|
5
|
+
Summary: AI CHAT EXTENSION
|
6
|
+
Project-URL: Homepage, https://github.com/github_username/escobar
|
7
|
+
Project-URL: Bug Tracker, https://github.com/github_username/escobar/issues
|
8
|
+
Project-URL: Repository, https://github.com/github_username/escobar.git
|
9
|
+
Author-email: Escobar <me@test.com>
|
10
|
+
License: BSD 3-Clause License
|
11
|
+
|
12
|
+
Copyright (c) 2025, Escobar
|
13
|
+
All rights reserved.
|
14
|
+
|
15
|
+
Redistribution and use in source and binary forms, with or without
|
16
|
+
modification, are permitted provided that the following conditions are met:
|
17
|
+
|
18
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
19
|
+
list of conditions and the following disclaimer.
|
20
|
+
|
21
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
22
|
+
this list of conditions and the following disclaimer in the documentation
|
23
|
+
and/or other materials provided with the distribution.
|
24
|
+
|
25
|
+
3. Neither the name of the copyright holder nor the names of its
|
26
|
+
contributors may be used to endorse or promote products derived from
|
27
|
+
this software without specific prior written permission.
|
28
|
+
|
29
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
30
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
31
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
32
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
33
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
34
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
35
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
36
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
37
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
38
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
39
|
+
License-File: LICENSE
|
40
|
+
Classifier: Framework :: Jupyter
|
41
|
+
Classifier: Framework :: Jupyter :: JupyterLab
|
42
|
+
Classifier: Framework :: Jupyter :: JupyterLab :: 4
|
43
|
+
Classifier: Framework :: Jupyter :: JupyterLab :: Extensions
|
44
|
+
Classifier: Framework :: Jupyter :: JupyterLab :: Extensions :: Prebuilt
|
45
|
+
Classifier: License :: OSI Approved :: BSD License
|
46
|
+
Classifier: Programming Language :: Python
|
47
|
+
Classifier: Programming Language :: Python :: 3
|
48
|
+
Classifier: Programming Language :: Python :: 3.8
|
49
|
+
Classifier: Programming Language :: Python :: 3.9
|
50
|
+
Classifier: Programming Language :: Python :: 3.10
|
51
|
+
Classifier: Programming Language :: Python :: 3.11
|
52
|
+
Classifier: Programming Language :: Python :: 3.12
|
53
|
+
Requires-Python: >=3.8
|
54
|
+
Requires-Dist: aiohttp
|
55
|
+
Requires-Dist: jupyter-server>=2.0.0
|
56
|
+
Requires-Dist: websockets>=11.0
|
57
|
+
Description-Content-Type: text/markdown
|
58
|
+
|
59
|
+
# Escobar
|
60
|
+
|
61
|
+
Escobar was a bad guy.
|
62
|
+
|
63
|
+
AI Chat Extension for JupyterLab with comprehensive chat management and WebSocket proxy functionality. It is intended to talk to Bonnie server, located locally at `../bonnie` and on GitHub at https://github.com/voitta-ai/bonnie.
|
64
|
+
|
65
|
+
The request and response objects are defined in `src/types/protocol.ts`.
|
66
|
+
|
67
|
+
The corresponding objects for Bonnie are defined in `../bonnie/lib/protocol_messages.py` (relative to this project).
|
68
|
+
|
69
|
+
## Overall ecosystem
|
70
|
+
|
71
|
+
When running locally, for more ecosystem details see ../README.md. On GitHub see https://github.com/voitta-ai/voitta-ws/blob/master/README.md.
|
72
|
+
|
73
|
+
## Installation
|
74
|
+
|
75
|
+
For development installation:
|
76
|
+
|
77
|
+
```bash
|
78
|
+
jupyter labextension develop --overwrite . && pip uninstall escobar -y && pip install -e . && jupyter server extension enable escobar
|
79
|
+
```
|
80
|
+
|
81
|
+
## Features
|
82
|
+
|
83
|
+
**Configuration:**
|
84
|
+
|
85
|
+
Set the target WebSocket server in your `.env` file:
|
86
|
+
|
87
|
+
```
|
88
|
+
WEBSOCKET_PROXY_TARGET=ws://your-target-server/ws
|
89
|
+
```
|
90
|
+
|
91
|
+
**Usage:**
|
92
|
+
|
93
|
+
- Connect to: `ws://localhost:8888/ws` (your JupyterLab server)
|
94
|
+
- Traffic is automatically proxied to your configured target server
|
95
|
+
- Supports both `ws://` and `wss://` protocols
|
96
|
+
- Forwards authentication headers (Authorization, Cookie)
|
97
|
+
|
98
|
+
## Protocol and Message Exchange
|
99
|
+
|
100
|
+
Escobar communicates with the Bonnie backend server using a well-defined protocol based on JSON messages exchanged over WebSocket. The protocol message interfaces are defined in `src/types/protocol.ts` and correspond to Python classes in Bonnie's `lib/protocol_messages.py`.
|
101
|
+
|
102
|
+
### Message Structure
|
103
|
+
|
104
|
+
Each message is either a **request** or a **response**, identified by the `message_type` field. Messages include a unique `call_id` for correlating requests and responses. Requests include context identifiers such as `username` and `chatID` to maintain session state.
|
105
|
+
|
106
|
+
Key message classes include:
|
107
|
+
|
108
|
+
- `IListChatsRequest` / `IListChatsResponse`: List available chats for a user.
|
109
|
+
- `ILoadMessagesRequest` / `ILoadMessagesResponse`: Load messages from a chat.
|
110
|
+
- `ICreateNewChatRequest` / `ICreateNewChatResponse`: Create a new chat session.
|
111
|
+
- `IContinueRequest` / `IContinueResponse`: Continue an existing chat session.
|
112
|
+
- `IUserMessageRequest`: Send a user message to the backend.
|
113
|
+
- `IUserStopRequest`: Request to stop the current LLM generation.
|
114
|
+
- `ISaveSettingsRequest` / `ISaveSettingsResponse`: Save user settings.
|
115
|
+
- `IRetrieveSettingsRequest` / `IRetrieveSettingsResponse`: Retrieve user settings.
|
116
|
+
- `IStreamingResponse`: Streaming response for LLM content.
|
117
|
+
- `IToolCallRequest` / `IToolResponse`: Tool call requests and responses for backend tool integrations.
|
118
|
+
|
119
|
+
### Message Flow
|
120
|
+
|
121
|
+
The frontend sends requests to Bonnie, which processes them and sends back responses asynchronously. Streaming responses allow partial LLM outputs to be sent incrementally. Tool call messages enable the backend to request external tool executions.
|
122
|
+
|
123
|
+
There are two main chat session flows:
|
124
|
+
|
125
|
+
1. **Starting a New Chat:**
|
126
|
+
|
127
|
+
- The user sends an `ICreateNewChatRequest` to create a new chat session.
|
128
|
+
- Bonnie responds with `ICreateNewChatResponse` containing the new `chatID`.
|
129
|
+
- The frontend may optionally send an `IContinueRequest` to initialize or synchronize session state, but this is not strictly required immediately after creating a new chat.
|
130
|
+
|
131
|
+
2. **Continuing an Existing Chat:**
|
132
|
+
- The user selects an existing chat from the list.
|
133
|
+
- The frontend sends an `IContinueRequest` with the existing `chatID`.
|
134
|
+
- Bonnie responds with `IContinueResponse` to confirm session continuation.
|
135
|
+
- The frontend then sends `ILoadMessagesRequest` to load chat history.
|
136
|
+
- Bonnie responds with `ILoadMessagesResponse` containing past messages.
|
137
|
+
|
138
|
+
### Introspection and Voitta Router
|
139
|
+
|
140
|
+
Escobar integrates with the **Voitta Tool Router**, implemented in `src/voitta/voittaServer.ts`. The router manages the AI prompt and available tools, exposing an introspection interface.
|
141
|
+
|
142
|
+
- **Introspection**: The router provides a method `intraspect()` that returns the current prompt and tools in OpenAPI schema format. This allows clients to dynamically discover available tools and their interfaces.
|
143
|
+
- **Voitta Router**: Converts internal tool definitions into OpenAPI specifications compatible with FastAPI, enabling structured API interaction and dynamic tool invocation.
|
144
|
+
|
145
|
+
### Sequence Diagram
|
146
|
+
|
147
|
+
The following sequence diagram illustrates the message exchange between the JupyterLab extension (Escobar), the Voitta router, and the Bonnie backend server, including introspection and tool call flows, with clear separation of new chat creation and existing chat continuation flows.
|
148
|
+
|
149
|
+
```mermaid
|
150
|
+
sequenceDiagram
|
151
|
+
participant User as User (JupyterLab)
|
152
|
+
participant Escobar as Escobar Extension
|
153
|
+
participant Voitta as Voitta Tool Router
|
154
|
+
participant Bonnie as Bonnie Backend Server
|
155
|
+
|
156
|
+
%% Existing chat selection flow
|
157
|
+
User->>Escobar: IListChatsRequest (listChats)
|
158
|
+
Escobar->>Bonnie: IListChatsRequest (listChats)
|
159
|
+
Bonnie->>Escobar: IListChatsResponse (listChats)
|
160
|
+
Escobar->>User: IListChatsResponse (listChats)
|
161
|
+
|
162
|
+
User->>Escobar: IContinueRequest (continue) [select existing chat]
|
163
|
+
Escobar->>Bonnie: IContinueRequest (continue)
|
164
|
+
Bonnie->>Escobar: IContinueResponse (continue)
|
165
|
+
Escobar->>User: IContinueResponse (continue)
|
166
|
+
|
167
|
+
Escobar->>Bonnie: ILoadMessagesRequest (loadMessages)
|
168
|
+
Bonnie->>Escobar: ILoadMessagesResponse (loadMessages)
|
169
|
+
Escobar->>User: ILoadMessagesResponse (loadMessages)
|
170
|
+
|
171
|
+
%% New chat creation flow
|
172
|
+
User->>Escobar: ICreateNewChatRequest (createNewChat)
|
173
|
+
Escobar->>Bonnie: ICreateNewChatRequest (createNewChat)
|
174
|
+
Bonnie->>Escobar: ICreateNewChatResponse (createNewChat)
|
175
|
+
Escobar->>User: ICreateNewChatResponse (createNewChat)
|
176
|
+
|
177
|
+
%% Optional continue after new chat (not always required)
|
178
|
+
Escobar->>Bonnie: IContinueRequest (continue) [optional after new chat]
|
179
|
+
Bonnie->>Escobar: IContinueResponse (continue)
|
180
|
+
Escobar->>User: IContinueResponse (continue)
|
181
|
+
|
182
|
+
%% Sending user messages
|
183
|
+
User->>Escobar: IUserMessageRequest (userMessage)
|
184
|
+
Escobar->>Bonnie: IUserMessageRequest (userMessage)
|
185
|
+
Bonnie->>Voitta: Processes message, may invoke tools
|
186
|
+
Voitta->>Voitta: intraspect() returns prompt and tools (OpenAPI)
|
187
|
+
Bonnie->>Escobar: IStreamingResponse or IToolCallRequest
|
188
|
+
Escobar->>User: Displays response content
|
189
|
+
|
190
|
+
Bonnie->>Voitta: IToolCallRequest (tool_call)
|
191
|
+
Voitta->>Bonnie: IToolResponse (tool_response)
|
192
|
+
Bonnie->>Escobar: IToolResponse (tool_response)
|
193
|
+
Escobar->>User: Updates UI with tool results
|
194
|
+
```
|
195
|
+
|
196
|
+
### Note on `IContinueRequest` after new chat
|
197
|
+
|
198
|
+
The `IContinueRequest` sent after a new chat creation is optional and may be used to initialize or synchronize session state. It is not strictly required immediately after creating a new chat, but can help ensure the frontend and backend are fully synchronized before further interactions.
|
199
|
+
|
200
|
+
This diagram centralizes the protocol and introspection explanation for the entire system. Bonnie's README.md will reference this diagram for protocol details.
|
@@ -1,41 +1,41 @@
|
|
1
1
|
escobar/__init__.py,sha256=49-CR9xMGZLSPOsyU3gcG9qdJ1MbPLK45H0wk-tcjbk,2553
|
2
|
-
escobar/_version.py,sha256=
|
2
|
+
escobar/_version.py,sha256=AruO2u0KSxq4dId4YYaERsfmhi2hvtDPX3fYdo2JeYc,172
|
3
3
|
escobar/auth_handlers.py,sha256=AYxV1qJ-EOGRhVr1uReUX0BIglYJANOsKzD9sf0m7PM,3866
|
4
|
-
escobar/handlers.py,sha256=
|
5
|
-
escobar/labextension/package.json,sha256=
|
6
|
-
escobar/labextension/schemas/escobar/package.json.orig,sha256=
|
4
|
+
escobar/handlers.py,sha256=OgKsGuGlvT_cBtu9iz6GI-4cbLMbbBJBum4-k0Niyno,26429
|
5
|
+
escobar/labextension/package.json,sha256=1yIb72QBFNjjcRDG1RQ2LNJGyAVIqSkoujyH2ogqv6A,6329
|
6
|
+
escobar/labextension/schemas/escobar/package.json.orig,sha256=aywjmNdWUgFItjU9ZnY9CvfTYiCPvKzQHnRB8AN6YH0,6186
|
7
7
|
escobar/labextension/schemas/escobar/plugin.json,sha256=AZS7Oue7JILPdCSt5Mfn5Sogiz6g4bUBs7BrkRy6mQk,1332
|
8
8
|
escobar/labextension/static/304.bf7e91be734e5b36cdc9.js,sha256=v36RvnNOWzbNyYWP8rATHxwUO39PxnDdCcWC7BHaEGY,41440
|
9
9
|
escobar/labextension/static/346.8a1e61ca6789b6fddfa7.js,sha256=ih5hymeJtv3fp3MzETkV52Jwf7lPy4j8nyImSeaSlbE,126361
|
10
10
|
escobar/labextension/static/379.40dd59dc19d4a6b42d25.js,sha256=QN1Z3BnUprQtJa36fJk7Vupnt4ijtbA5DI_kyf01JPU,31700
|
11
11
|
escobar/labextension/static/57.17e53b4b9a954f39c4d8.js,sha256=F-U7S5qVTznE2Ku-ca2wq8p4w5EbN8wCqpWkZIIKwCs,958640
|
12
12
|
escobar/labextension/static/648.a7d314faeacc762d891d.js,sha256=p9MU-urMdi2JHU-HVyPZDNyz6bcuLccK27EGga_vUpc,3790
|
13
|
-
escobar/labextension/static/653.
|
13
|
+
escobar/labextension/static/653.09d06963cff377716db8.js,sha256=CdBpY8_zd3FtuL-IENyu-T_f2ao4trDSlbo5gLgZAnI,152410
|
14
14
|
escobar/labextension/static/666.3bc65aac3a3be183ee19.js,sha256=O8ZarDo74YPuGeyk30MLKCvS-7xpDDrxORYRON7mYhc,262639
|
15
15
|
escobar/labextension/static/874.c539726f31a1baa0267e.js,sha256=xTlybzGhuqAmfjXMO3AGfxjzz94dBXZ3C_ih4djSn-A,107988
|
16
16
|
escobar/labextension/static/986.cbcf9d7c1cd8d06be435.js,sha256=y8-dfBzY0GvkNcQRx0NVz8fKIS4EDN0L2P6OPTa_oFo,1937
|
17
|
-
escobar/labextension/static/remoteEntry.
|
17
|
+
escobar/labextension/static/remoteEntry.a77434f417b2a7097a56.js,sha256=p3Q09Beypwl6VhFFcsZWAwMiZed_jCbsRQXovNdN7_s,9889
|
18
18
|
escobar/labextension/static/style.js,sha256=5zB0SWahcYtVtwQIHHWutwnJWoGiAlr7_rXNVVmOnAA,150
|
19
19
|
escobar/labextension/static/third-party-licenses.json,sha256=LhPj8JwPg5FGdt1ZGbbgwR346bUdzV5fXslJadpOsf8,38518
|
20
|
-
escobar-0.1.
|
21
|
-
escobar-0.1.
|
22
|
-
escobar-0.1.
|
23
|
-
escobar-0.1.
|
24
|
-
escobar-0.1.
|
25
|
-
escobar-0.1.
|
26
|
-
escobar-0.1.
|
27
|
-
escobar-0.1.
|
28
|
-
escobar-0.1.
|
29
|
-
escobar-0.1.
|
30
|
-
escobar-0.1.
|
31
|
-
escobar-0.1.
|
32
|
-
escobar-0.1.
|
33
|
-
escobar-0.1.
|
34
|
-
escobar-0.1.
|
35
|
-
escobar-0.1.
|
36
|
-
escobar-0.1.
|
37
|
-
escobar-0.1.
|
38
|
-
escobar-0.1.
|
39
|
-
escobar-0.1.
|
40
|
-
escobar-0.1.
|
41
|
-
escobar-0.1.
|
20
|
+
escobar-0.1.94.data/data/share/jupyter/labextensions/escobar/package.json,sha256=1yIb72QBFNjjcRDG1RQ2LNJGyAVIqSkoujyH2ogqv6A,6329
|
21
|
+
escobar-0.1.94.data/data/share/jupyter/labextensions/escobar/schemas/escobar/package.json.orig,sha256=aywjmNdWUgFItjU9ZnY9CvfTYiCPvKzQHnRB8AN6YH0,6186
|
22
|
+
escobar-0.1.94.data/data/share/jupyter/labextensions/escobar/schemas/escobar/plugin.json,sha256=AZS7Oue7JILPdCSt5Mfn5Sogiz6g4bUBs7BrkRy6mQk,1332
|
23
|
+
escobar-0.1.94.data/data/share/jupyter/labextensions/escobar/static/304.bf7e91be734e5b36cdc9.js,sha256=v36RvnNOWzbNyYWP8rATHxwUO39PxnDdCcWC7BHaEGY,41440
|
24
|
+
escobar-0.1.94.data/data/share/jupyter/labextensions/escobar/static/346.8a1e61ca6789b6fddfa7.js,sha256=ih5hymeJtv3fp3MzETkV52Jwf7lPy4j8nyImSeaSlbE,126361
|
25
|
+
escobar-0.1.94.data/data/share/jupyter/labextensions/escobar/static/379.40dd59dc19d4a6b42d25.js,sha256=QN1Z3BnUprQtJa36fJk7Vupnt4ijtbA5DI_kyf01JPU,31700
|
26
|
+
escobar-0.1.94.data/data/share/jupyter/labextensions/escobar/static/57.17e53b4b9a954f39c4d8.js,sha256=F-U7S5qVTznE2Ku-ca2wq8p4w5EbN8wCqpWkZIIKwCs,958640
|
27
|
+
escobar-0.1.94.data/data/share/jupyter/labextensions/escobar/static/648.a7d314faeacc762d891d.js,sha256=p9MU-urMdi2JHU-HVyPZDNyz6bcuLccK27EGga_vUpc,3790
|
28
|
+
escobar-0.1.94.data/data/share/jupyter/labextensions/escobar/static/653.09d06963cff377716db8.js,sha256=CdBpY8_zd3FtuL-IENyu-T_f2ao4trDSlbo5gLgZAnI,152410
|
29
|
+
escobar-0.1.94.data/data/share/jupyter/labextensions/escobar/static/666.3bc65aac3a3be183ee19.js,sha256=O8ZarDo74YPuGeyk30MLKCvS-7xpDDrxORYRON7mYhc,262639
|
30
|
+
escobar-0.1.94.data/data/share/jupyter/labextensions/escobar/static/874.c539726f31a1baa0267e.js,sha256=xTlybzGhuqAmfjXMO3AGfxjzz94dBXZ3C_ih4djSn-A,107988
|
31
|
+
escobar-0.1.94.data/data/share/jupyter/labextensions/escobar/static/986.cbcf9d7c1cd8d06be435.js,sha256=y8-dfBzY0GvkNcQRx0NVz8fKIS4EDN0L2P6OPTa_oFo,1937
|
32
|
+
escobar-0.1.94.data/data/share/jupyter/labextensions/escobar/static/remoteEntry.a77434f417b2a7097a56.js,sha256=p3Q09Beypwl6VhFFcsZWAwMiZed_jCbsRQXovNdN7_s,9889
|
33
|
+
escobar-0.1.94.data/data/share/jupyter/labextensions/escobar/static/style.js,sha256=5zB0SWahcYtVtwQIHHWutwnJWoGiAlr7_rXNVVmOnAA,150
|
34
|
+
escobar-0.1.94.data/data/share/jupyter/labextensions/escobar/static/third-party-licenses.json,sha256=LhPj8JwPg5FGdt1ZGbbgwR346bUdzV5fXslJadpOsf8,38518
|
35
|
+
escobar-0.1.94.data/data/share/jupyter/labextensions/escobar/install.json,sha256=PGNCDISpClogqe3RQpE0wvpKaZiDIh-LqwCxFpbQggY,175
|
36
|
+
escobar-0.1.94.data/data/share/jupyter/labextensions/escobar/static/oauth-callback.html,sha256=x4XBeQn6iVtgcsZzB1DCm61w4UYRYVXdkS6_nKQst34,4152
|
37
|
+
escobar-0.1.94.dist-info/METADATA,sha256=DCWNzaOamiyvWJLWEKoIZM2M9R4GqGerJ98C3v4ZOr4,9968
|
38
|
+
escobar-0.1.94.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
39
|
+
escobar-0.1.94.dist-info/entry_points.txt,sha256=X3dMLTQyNAzzDruDHTYkjThXl55cO3caop36DeLVaoM,143
|
40
|
+
escobar-0.1.94.dist-info/licenses/LICENSE,sha256=EI--pA6wgLNrsltKoAHAoJw-hAnqIVcfRMlDF43mqMA,1515
|
41
|
+
escobar-0.1.94.dist-info/RECORD,,
|
@@ -1,56 +0,0 @@
|
|
1
|
-
Metadata-Version: 2.4
|
2
|
-
Name: escobar
|
3
|
-
Version: 0.1.92
|
4
|
-
Dynamic: Keywords
|
5
|
-
Summary: AI CHAT EXTENSION
|
6
|
-
Project-URL: Homepage, https://github.com/github_username/escobar
|
7
|
-
Project-URL: Bug Tracker, https://github.com/github_username/escobar/issues
|
8
|
-
Project-URL: Repository, https://github.com/github_username/escobar.git
|
9
|
-
Author-email: Escobar <me@test.com>
|
10
|
-
License: BSD 3-Clause License
|
11
|
-
|
12
|
-
Copyright (c) 2025, Escobar
|
13
|
-
All rights reserved.
|
14
|
-
|
15
|
-
Redistribution and use in source and binary forms, with or without
|
16
|
-
modification, are permitted provided that the following conditions are met:
|
17
|
-
|
18
|
-
1. Redistributions of source code must retain the above copyright notice, this
|
19
|
-
list of conditions and the following disclaimer.
|
20
|
-
|
21
|
-
2. Redistributions in binary form must reproduce the above copyright notice,
|
22
|
-
this list of conditions and the following disclaimer in the documentation
|
23
|
-
and/or other materials provided with the distribution.
|
24
|
-
|
25
|
-
3. Neither the name of the copyright holder nor the names of its
|
26
|
-
contributors may be used to endorse or promote products derived from
|
27
|
-
this software without specific prior written permission.
|
28
|
-
|
29
|
-
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
30
|
-
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
31
|
-
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
32
|
-
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
33
|
-
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
34
|
-
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
35
|
-
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
36
|
-
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
37
|
-
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
38
|
-
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
39
|
-
License-File: LICENSE
|
40
|
-
Classifier: Framework :: Jupyter
|
41
|
-
Classifier: Framework :: Jupyter :: JupyterLab
|
42
|
-
Classifier: Framework :: Jupyter :: JupyterLab :: 4
|
43
|
-
Classifier: Framework :: Jupyter :: JupyterLab :: Extensions
|
44
|
-
Classifier: Framework :: Jupyter :: JupyterLab :: Extensions :: Prebuilt
|
45
|
-
Classifier: License :: OSI Approved :: BSD License
|
46
|
-
Classifier: Programming Language :: Python
|
47
|
-
Classifier: Programming Language :: Python :: 3
|
48
|
-
Classifier: Programming Language :: Python :: 3.8
|
49
|
-
Classifier: Programming Language :: Python :: 3.9
|
50
|
-
Classifier: Programming Language :: Python :: 3.10
|
51
|
-
Classifier: Programming Language :: Python :: 3.11
|
52
|
-
Classifier: Programming Language :: Python :: 3.12
|
53
|
-
Requires-Python: >=3.8
|
54
|
-
Requires-Dist: aiohttp
|
55
|
-
Requires-Dist: jupyter-server>=2.0.0
|
56
|
-
Requires-Dist: websockets>=11.0
|
{escobar-0.1.92.data → escobar-0.1.94.data}/data/share/jupyter/labextensions/escobar/install.json
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{escobar-0.1.92.data → escobar-0.1.94.data}/data/share/jupyter/labextensions/escobar/static/style.js
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|