BG5 commited on
Commit
8201de9
·
1 Parent(s): 59b61a8

Upload 105 files

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .dockerignore +11 -0
  2. .github/workflows/docker-publish.yml +94 -0
  3. .github/workflows/python-publish.yml +36 -0
  4. .gitignore +135 -0
  5. Dockerfile +13 -0
  6. LICENSE +339 -0
  7. MANIFEST.in +5 -0
  8. bin/startup.sh +48 -0
  9. doc/HTTP-API.md +85 -0
  10. doc/images/s01.png +0 -0
  11. doc/images/s02.png +0 -0
  12. doc/images/s03.png +0 -0
  13. doc/images/s04.png +0 -0
  14. doc/images/s05.png +0 -0
  15. doc/images/s06.png +0 -0
  16. doc/images/s11.jpeg +0 -0
  17. doc/images/s12.jpeg +0 -0
  18. doc/images/t0.png +0 -0
  19. doc/images/t1.1.png +0 -0
  20. doc/images/t1.png +0 -0
  21. doc/images/t2.png +0 -0
  22. doc/images/t3.png +0 -0
  23. doc/images/t4.png +0 -0
  24. doc/images/t7.png +0 -0
  25. doc/wiki.md +204 -0
  26. doc/wiki_en.md +164 -0
  27. requirements.txt +13 -0
  28. requirements_api.txt +3 -0
  29. setup.py +76 -0
  30. src/pandora/__init__.py +3 -0
  31. src/pandora/__main__.py +6 -0
  32. src/pandora/bots/__init__.py +1 -0
  33. src/pandora/bots/legacy.py +495 -0
  34. src/pandora/bots/server.py +282 -0
  35. src/pandora/cloud_launcher.py +81 -0
  36. src/pandora/exts/__init__.py +1 -0
  37. src/pandora/exts/config.py +15 -0
  38. src/pandora/exts/hooks.py +39 -0
  39. src/pandora/exts/token.py +48 -0
  40. src/pandora/flask/static/_next/static/chunks/113-23682f80a24dd00d.js +0 -0
  41. src/pandora/flask/static/_next/static/chunks/14-0cb0d20affbd720d.js +1 -0
  42. src/pandora/flask/static/_next/static/chunks/174-bd28069f281ef76f.js +1 -0
  43. src/pandora/flask/static/_next/static/chunks/1f110208-44a6f43ddc5e9011.js +0 -0
  44. src/pandora/flask/static/_next/static/chunks/264-13e92c51b0315184.js +1 -0
  45. src/pandora/flask/static/_next/static/chunks/360-442b869f1ba4bb1b.js +9 -0
  46. src/pandora/flask/static/_next/static/chunks/424-d1d3bfe6a3ca6c4a.js +1 -0
  47. src/pandora/flask/static/_next/static/chunks/554.9b8bfd0762461d74.js +1 -0
  48. src/pandora/flask/static/_next/static/chunks/68a27ff6-1185184b61bc22d0.js +1 -0
  49. src/pandora/flask/static/_next/static/chunks/762-222df1028c0c1555.js +9 -0
  50. src/pandora/flask/static/_next/static/chunks/949.1a6eb804b5e91f61.js +1 -0
.dockerignore ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .DS_Store
2
+
3
+ .git/
4
+ .idea/
5
+ .run/
6
+ .github/
7
+
8
+ venv/
9
+ build/
10
+ dist/
11
+ *.egg-info/
.github/workflows/docker-publish.yml ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Push Docker Image
2
+
3
+ on:
4
+ workflow_dispatch:
5
+
6
+ release:
7
+ types: [ published ]
8
+
9
+ permissions:
10
+ packages: write
11
+ contents: read
12
+
13
+ env:
14
+ IMAGE_NAME: pandora
15
+ PLATFORMS: linux/amd64,linux/arm64
16
+
17
+ jobs:
18
+ get-tags:
19
+ runs-on: ubuntu-latest
20
+ outputs:
21
+ image_version: ${{ steps.get_image_version.outputs.image_version }}
22
+ steps:
23
+ - uses: actions/checkout@v3
24
+
25
+ - name: Get Image Version
26
+ id: get_image_version
27
+ run: |
28
+ # Strip git ref prefix from version
29
+ IMAGE_VERSION=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,')
30
+
31
+ # Strip "v" prefix from tag name
32
+ [[ "${{ github.ref }}" == "refs/tags/"* ]] && IMAGE_VERSION=$(echo $IMAGE_VERSION | sed -e 's/^v//')
33
+
34
+ echo VERSION=$IMAGE_VERSION
35
+ echo "image_version=${IMAGE_VERSION}" >> $GITHUB_OUTPUT
36
+
37
+ push-ghcr:
38
+ needs: get-tags
39
+ runs-on: ubuntu-latest
40
+ env:
41
+ REGISTRY: ghcr.io
42
+
43
+ steps:
44
+ - uses: actions/checkout@v3
45
+
46
+ - name: Docker Setup QEMU
47
+ uses: docker/setup-qemu-action@v2
48
+
49
+ - name: Set up Docker BuildX
50
+ uses: docker/setup-buildx-action@v2
51
+
52
+ - name: Docker Login
53
+ uses: docker/login-action@v2
54
+ with:
55
+ registry: ${{ env.REGISTRY }}
56
+ username: ${{ github.repository_owner }}
57
+ password: ${{ secrets.GITHUB_TOKEN }}
58
+
59
+ - name: Build and Push
60
+ uses: docker/build-push-action@v4
61
+ with:
62
+ push: true
63
+ platforms: ${{ env.PLATFORMS }}
64
+ tags: |
65
+ ${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}:${{ needs.get-tags.outputs.image_version }}
66
+ ${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}:latest
67
+
68
+ push-docker-hub:
69
+ needs: get-tags
70
+ runs-on: ubuntu-latest
71
+
72
+ steps:
73
+ - uses: actions/checkout@v3
74
+
75
+ - name: Docker Setup QEMU
76
+ uses: docker/setup-qemu-action@v2
77
+
78
+ - name: Set up Docker BuildX
79
+ uses: docker/setup-buildx-action@v2
80
+
81
+ - name: Docker Login
82
+ uses: docker/login-action@v2
83
+ with:
84
+ username: ${{ secrets.DOCKERHUB_USERNAME }}
85
+ password: ${{ secrets.DOCKERHUB_TOKEN }}
86
+
87
+ - name: Build and Push
88
+ uses: docker/build-push-action@v4
89
+ with:
90
+ push: true
91
+ platforms: ${{ env.PLATFORMS }}
92
+ tags: |
93
+ ${{ secrets.DOCKERHUB_USERNAME }}/${{ env.IMAGE_NAME }}:${{ needs.get-tags.outputs.image_version }}
94
+ ${{ secrets.DOCKERHUB_USERNAME }}/${{ env.IMAGE_NAME }}:latest
.github/workflows/python-publish.yml ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Upload Python Package
2
+
3
+ on:
4
+ workflow_dispatch:
5
+
6
+ release:
7
+ types: [ published ]
8
+
9
+ permissions:
10
+ contents: read
11
+
12
+ jobs:
13
+ deploy:
14
+ runs-on: ubuntu-latest
15
+
16
+ steps:
17
+ - uses: actions/checkout@v3
18
+
19
+ - name: Set up Python
20
+ uses: actions/setup-python@v4
21
+ with:
22
+ python-version: 3.7
23
+
24
+ - name: Install dependencies
25
+ run: |
26
+ python -m pip install --upgrade pip
27
+ pip install build
28
+
29
+ - name: Build package
30
+ run: python -m build
31
+
32
+ - name: Publish package
33
+ uses: pypa/gh-action-pypi-publish@release/v1
34
+ with:
35
+ user: __token__
36
+ password: ${{ secrets.PYPI_API_TOKEN }}
.gitignore ADDED
@@ -0,0 +1,135 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ pip-wheel-metadata/
24
+ share/python-wheels/
25
+ *.egg-info/
26
+ .installed.cfg
27
+ *.egg
28
+ MANIFEST
29
+
30
+ # PyInstaller
31
+ #Usually these files are written by a python script from a template
32
+ #before PyInstaller builds the exe, so as to inject date/other infos into it.
33
+ *.manifest
34
+ *.spec
35
+
36
+ # Installer logs
37
+ pip-log.txt
38
+ pip-delete-this-directory.txt
39
+
40
+ # Unit test / coverage reports
41
+ htmlcov/
42
+ .tox/
43
+ .nox/
44
+ .coverage
45
+ .coverage.*
46
+ .cache
47
+ nosetests.xml
48
+ coverage.xml
49
+ *.cover
50
+ *.py,cover
51
+ .hypothesis/
52
+ .pytest_cache/
53
+
54
+ # Translations
55
+ *.mo
56
+ *.pot
57
+
58
+ # Django stuff:
59
+ *.log
60
+ local_settings.py
61
+ db.sqlite3
62
+ db.sqlite3-journal
63
+
64
+ # Flask stuff:
65
+ instance/
66
+ .webassets-cache
67
+
68
+ # Scrapy stuff:
69
+ .scrapy
70
+
71
+ # Sphinx documentation
72
+ docs/_build/
73
+
74
+ # PyBuilder
75
+ target/
76
+
77
+ # Jupyter Notebook
78
+ .ipynb_checkpoints
79
+
80
+ # IPython
81
+ profile_default/
82
+ ipython_config.py
83
+
84
+ # pyenv
85
+ .python-version
86
+
87
+ # pipenv
88
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
89
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
90
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
91
+ # install all needed dependencies.
92
+ # Pipfile.lock
93
+
94
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow
95
+ __pypackages__/
96
+
97
+ # Celery stuff
98
+ celerybeat-schedule
99
+ celerybeat.pid
100
+
101
+ # SageMath parsed files
102
+ *.sage.py
103
+
104
+ # Environments
105
+ .env
106
+ .venv
107
+ env/
108
+ venv/
109
+ ENV/
110
+ env.bak/
111
+ venv.bak/
112
+
113
+ # Spyder project settings
114
+ .spyderproject
115
+ .spyproject
116
+
117
+ # Rope project settings
118
+ .ropeproject
119
+
120
+ # mkdocs documentation
121
+ /site
122
+
123
+ # mypy
124
+ .mypy_cache/
125
+ .dmypy.json
126
+ dmypy.json
127
+
128
+ # Pyre type checker
129
+ .pyre/
130
+
131
+ # JetBrains IDEs configuration
132
+ .idea/
133
+
134
+ # macOS
135
+ .DS_Store
Dockerfile ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.9-slim@sha256:5f0192a4f58a6ce99f732fe05e3b3d00f12ae62e183886bca3ebe3d202686c7f
2
+
3
+ MAINTAINER "Neo Peng <pengzhile@gmail.com>"
4
+
5
+ VOLUME /data
6
+
7
+ WORKDIR /opt/app
8
+
9
+ ADD . .
10
+
11
+ RUN pip --no-cache-dir install --upgrade pip && pip --no-cache-dir install .[api,cloud]
12
+
13
+ ENTRYPOINT ["bin/startup.sh"]
LICENSE ADDED
@@ -0,0 +1,339 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ GNU GENERAL PUBLIC LICENSE
2
+ Version 2, June 1991
3
+
4
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
5
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6
+ Everyone is permitted to copy and distribute verbatim copies
7
+ of this license document, but changing it is not allowed.
8
+
9
+ Preamble
10
+
11
+ The licenses for most software are designed to take away your
12
+ freedom to share and change it. By contrast, the GNU General Public
13
+ License is intended to guarantee your freedom to share and change free
14
+ software--to make sure the software is free for all its users. This
15
+ General Public License applies to most of the Free Software
16
+ Foundation's software and to any other program whose authors commit to
17
+ using it. (Some other Free Software Foundation software is covered by
18
+ the GNU Lesser General Public License instead.) You can apply it to
19
+ your programs, too.
20
+
21
+ When we speak of free software, we are referring to freedom, not
22
+ price. Our General Public Licenses are designed to make sure that you
23
+ have the freedom to distribute copies of free software (and charge for
24
+ this service if you wish), that you receive source code or can get it
25
+ if you want it, that you can change the software or use pieces of it
26
+ in new free programs; and that you know you can do these things.
27
+
28
+ To protect your rights, we need to make restrictions that forbid
29
+ anyone to deny you these rights or to ask you to surrender the rights.
30
+ These restrictions translate to certain responsibilities for you if you
31
+ distribute copies of the software, or if you modify it.
32
+
33
+ For example, if you distribute copies of such a program, whether
34
+ gratis or for a fee, you must give the recipients all the rights that
35
+ you have. You must make sure that they, too, receive or can get the
36
+ source code. And you must show them these terms so they know their
37
+ rights.
38
+
39
+ We protect your rights with two steps: (1) copyright the software, and
40
+ (2) offer you this license which gives you legal permission to copy,
41
+ distribute and/or modify the software.
42
+
43
+ Also, for each author's protection and ours, we want to make certain
44
+ that everyone understands that there is no warranty for this free
45
+ software. If the software is modified by someone else and passed on, we
46
+ want its recipients to know that what they have is not the original, so
47
+ that any problems introduced by others will not reflect on the original
48
+ authors' reputations.
49
+
50
+ Finally, any free program is threatened constantly by software
51
+ patents. We wish to avoid the danger that redistributors of a free
52
+ program will individually obtain patent licenses, in effect making the
53
+ program proprietary. To prevent this, we have made it clear that any
54
+ patent must be licensed for everyone's free use or not licensed at all.
55
+
56
+ The precise terms and conditions for copying, distribution and
57
+ modification follow.
58
+
59
+ GNU GENERAL PUBLIC LICENSE
60
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61
+
62
+ 0. This License applies to any program or other work which contains
63
+ a notice placed by the copyright holder saying it may be distributed
64
+ under the terms of this General Public License. The "Program", below,
65
+ refers to any such program or work, and a "work based on the Program"
66
+ means either the Program or any derivative work under copyright law:
67
+ that is to say, a work containing the Program or a portion of it,
68
+ either verbatim or with modifications and/or translated into another
69
+ language. (Hereinafter, translation is included without limitation in
70
+ the term "modification".) Each licensee is addressed as "you".
71
+
72
+ Activities other than copying, distribution and modification are not
73
+ covered by this License; they are outside its scope. The act of
74
+ running the Program is not restricted, and the output from the Program
75
+ is covered only if its contents constitute a work based on the
76
+ Program (independent of having been made by running the Program).
77
+ Whether that is true depends on what the Program does.
78
+
79
+ 1. You may copy and distribute verbatim copies of the Program's
80
+ source code as you receive it, in any medium, provided that you
81
+ conspicuously and appropriately publish on each copy an appropriate
82
+ copyright notice and disclaimer of warranty; keep intact all the
83
+ notices that refer to this License and to the absence of any warranty;
84
+ and give any other recipients of the Program a copy of this License
85
+ along with the Program.
86
+
87
+ You may charge a fee for the physical act of transferring a copy, and
88
+ you may at your option offer warranty protection in exchange for a fee.
89
+
90
+ 2. You may modify your copy or copies of the Program or any portion
91
+ of it, thus forming a work based on the Program, and copy and
92
+ distribute such modifications or work under the terms of Section 1
93
+ above, provided that you also meet all of these conditions:
94
+
95
+ a) You must cause the modified files to carry prominent notices
96
+ stating that you changed the files and the date of any change.
97
+
98
+ b) You must cause any work that you distribute or publish, that in
99
+ whole or in part contains or is derived from the Program or any
100
+ part thereof, to be licensed as a whole at no charge to all third
101
+ parties under the terms of this License.
102
+
103
+ c) If the modified program normally reads commands interactively
104
+ when run, you must cause it, when started running for such
105
+ interactive use in the most ordinary way, to print or display an
106
+ announcement including an appropriate copyright notice and a
107
+ notice that there is no warranty (or else, saying that you provide
108
+ a warranty) and that users may redistribute the program under
109
+ these conditions, and telling the user how to view a copy of this
110
+ License. (Exception: if the Program itself is interactive but
111
+ does not normally print such an announcement, your work based on
112
+ the Program is not required to print an announcement.)
113
+
114
+ These requirements apply to the modified work as a whole. If
115
+ identifiable sections of that work are not derived from the Program,
116
+ and can be reasonably considered independent and separate works in
117
+ themselves, then this License, and its terms, do not apply to those
118
+ sections when you distribute them as separate works. But when you
119
+ distribute the same sections as part of a whole which is a work based
120
+ on the Program, the distribution of the whole must be on the terms of
121
+ this License, whose permissions for other licensees extend to the
122
+ entire whole, and thus to each and every part regardless of who wrote it.
123
+
124
+ Thus, it is not the intent of this section to claim rights or contest
125
+ your rights to work written entirely by you; rather, the intent is to
126
+ exercise the right to control the distribution of derivative or
127
+ collective works based on the Program.
128
+
129
+ In addition, mere aggregation of another work not based on the Program
130
+ with the Program (or with a work based on the Program) on a volume of
131
+ a storage or distribution medium does not bring the other work under
132
+ the scope of this License.
133
+
134
+ 3. You may copy and distribute the Program (or a work based on it,
135
+ under Section 2) in object code or executable form under the terms of
136
+ Sections 1 and 2 above provided that you also do one of the following:
137
+
138
+ a) Accompany it with the complete corresponding machine-readable
139
+ source code, which must be distributed under the terms of Sections
140
+ 1 and 2 above on a medium customarily used for software interchange; or,
141
+
142
+ b) Accompany it with a written offer, valid for at least three
143
+ years, to give any third party, for a charge no more than your
144
+ cost of physically performing source distribution, a complete
145
+ machine-readable copy of the corresponding source code, to be
146
+ distributed under the terms of Sections 1 and 2 above on a medium
147
+ customarily used for software interchange; or,
148
+
149
+ c) Accompany it with the information you received as to the offer
150
+ to distribute corresponding source code. (This alternative is
151
+ allowed only for noncommercial distribution and only if you
152
+ received the program in object code or executable form with such
153
+ an offer, in accord with Subsection b above.)
154
+
155
+ The source code for a work means the preferred form of the work for
156
+ making modifications to it. For an executable work, complete source
157
+ code means all the source code for all modules it contains, plus any
158
+ associated interface definition files, plus the scripts used to
159
+ control compilation and installation of the executable. However, as a
160
+ special exception, the source code distributed need not include
161
+ anything that is normally distributed (in either source or binary
162
+ form) with the major components (compiler, kernel, and so on) of the
163
+ operating system on which the executable runs, unless that component
164
+ itself accompanies the executable.
165
+
166
+ If distribution of executable or object code is made by offering
167
+ access to copy from a designated place, then offering equivalent
168
+ access to copy the source code from the same place counts as
169
+ distribution of the source code, even though third parties are not
170
+ compelled to copy the source along with the object code.
171
+
172
+ 4. You may not copy, modify, sublicense, or distribute the Program
173
+ except as expressly provided under this License. Any attempt
174
+ otherwise to copy, modify, sublicense or distribute the Program is
175
+ void, and will automatically terminate your rights under this License.
176
+ However, parties who have received copies, or rights, from you under
177
+ this License will not have their licenses terminated so long as such
178
+ parties remain in full compliance.
179
+
180
+ 5. You are not required to accept this License, since you have not
181
+ signed it. However, nothing else grants you permission to modify or
182
+ distribute the Program or its derivative works. These actions are
183
+ prohibited by law if you do not accept this License. Therefore, by
184
+ modifying or distributing the Program (or any work based on the
185
+ Program), you indicate your acceptance of this License to do so, and
186
+ all its terms and conditions for copying, distributing or modifying
187
+ the Program or works based on it.
188
+
189
+ 6. Each time you redistribute the Program (or any work based on the
190
+ Program), the recipient automatically receives a license from the
191
+ original licensor to copy, distribute or modify the Program subject to
192
+ these terms and conditions. You may not impose any further
193
+ restrictions on the recipients' exercise of the rights granted herein.
194
+ You are not responsible for enforcing compliance by third parties to
195
+ this License.
196
+
197
+ 7. If, as a consequence of a court judgment or allegation of patent
198
+ infringement or for any other reason (not limited to patent issues),
199
+ conditions are imposed on you (whether by court order, agreement or
200
+ otherwise) that contradict the conditions of this License, they do not
201
+ excuse you from the conditions of this License. If you cannot
202
+ distribute so as to satisfy simultaneously your obligations under this
203
+ License and any other pertinent obligations, then as a consequence you
204
+ may not distribute the Program at all. For example, if a patent
205
+ license would not permit royalty-free redistribution of the Program by
206
+ all those who receive copies directly or indirectly through you, then
207
+ the only way you could satisfy both it and this License would be to
208
+ refrain entirely from distribution of the Program.
209
+
210
+ If any portion of this section is held invalid or unenforceable under
211
+ any particular circumstance, the balance of the section is intended to
212
+ apply and the section as a whole is intended to apply in other
213
+ circumstances.
214
+
215
+ It is not the purpose of this section to induce you to infringe any
216
+ patents or other property right claims or to contest validity of any
217
+ such claims; this section has the sole purpose of protecting the
218
+ integrity of the free software distribution system, which is
219
+ implemented by public license practices. Many people have made
220
+ generous contributions to the wide range of software distributed
221
+ through that system in reliance on consistent application of that
222
+ system; it is up to the author/donor to decide if he or she is willing
223
+ to distribute software through any other system and a licensee cannot
224
+ impose that choice.
225
+
226
+ This section is intended to make thoroughly clear what is believed to
227
+ be a consequence of the rest of this License.
228
+
229
+ 8. If the distribution and/or use of the Program is restricted in
230
+ certain countries either by patents or by copyrighted interfaces, the
231
+ original copyright holder who places the Program under this License
232
+ may add an explicit geographical distribution limitation excluding
233
+ those countries, so that distribution is permitted only in or among
234
+ countries not thus excluded. In such case, this License incorporates
235
+ the limitation as if written in the body of this License.
236
+
237
+ 9. The Free Software Foundation may publish revised and/or new versions
238
+ of the General Public License from time to time. Such new versions will
239
+ be similar in spirit to the present version, but may differ in detail to
240
+ address new problems or concerns.
241
+
242
+ Each version is given a distinguishing version number. If the Program
243
+ specifies a version number of this License which applies to it and "any
244
+ later version", you have the option of following the terms and conditions
245
+ either of that version or of any later version published by the Free
246
+ Software Foundation. If the Program does not specify a version number of
247
+ this License, you may choose any version ever published by the Free Software
248
+ Foundation.
249
+
250
+ 10. If you wish to incorporate parts of the Program into other free
251
+ programs whose distribution conditions are different, write to the author
252
+ to ask for permission. For software which is copyrighted by the Free
253
+ Software Foundation, write to the Free Software Foundation; we sometimes
254
+ make exceptions for this. Our decision will be guided by the two goals
255
+ of preserving the free status of all derivatives of our free software and
256
+ of promoting the sharing and reuse of software generally.
257
+
258
+ NO WARRANTY
259
+
260
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261
+ FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
262
+ OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263
+ PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264
+ OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
266
+ TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
267
+ PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268
+ REPAIR OR CORRECTION.
269
+
270
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271
+ WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272
+ REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273
+ INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274
+ OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275
+ TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276
+ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277
+ PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278
+ POSSIBILITY OF SUCH DAMAGES.
279
+
280
+ END OF TERMS AND CONDITIONS
281
+
282
+ How to Apply These Terms to Your New Programs
283
+
284
+ If you develop a new program, and you want it to be of the greatest
285
+ possible use to the public, the best way to achieve this is to make it
286
+ free software which everyone can redistribute and change under these terms.
287
+
288
+ To do so, attach the following notices to the program. It is safest
289
+ to attach them to the start of each source file to most effectively
290
+ convey the exclusion of warranty; and each file should have at least
291
+ the "copyright" line and a pointer to where the full notice is found.
292
+
293
+ <one line to give the program's name and a brief idea of what it does.>
294
+ Copyright (C) <year> <name of author>
295
+
296
+ This program is free software; you can redistribute it and/or modify
297
+ it under the terms of the GNU General Public License as published by
298
+ the Free Software Foundation; either version 2 of the License, or
299
+ (at your option) any later version.
300
+
301
+ This program is distributed in the hope that it will be useful,
302
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
303
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
304
+ GNU General Public License for more details.
305
+
306
+ You should have received a copy of the GNU General Public License along
307
+ with this program; if not, write to the Free Software Foundation, Inc.,
308
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
309
+
310
+ Also add information on how to contact you by electronic and paper mail.
311
+
312
+ If the program is interactive, make it output a short notice like this
313
+ when it starts in an interactive mode:
314
+
315
+ Gnomovision version 69, Copyright (C) year name of author
316
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
317
+ This is free software, and you are welcome to redistribute it
318
+ under certain conditions; type `show c' for details.
319
+
320
+ The hypothetical commands `show w' and `show c' should show the appropriate
321
+ parts of the General Public License. Of course, the commands you use may
322
+ be called something other than `show w' and `show c'; they could even be
323
+ mouse-clicks or menu items--whatever suits your program.
324
+
325
+ You should also get your employer (if you work as a programmer) or your
326
+ school, if any, to sign a "copyright disclaimer" for the program, if
327
+ necessary. Here is a sample; alter the names:
328
+
329
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
330
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
331
+
332
+ <signature of Ty Coon>, 1 April 1989
333
+ Ty Coon, President of Vice
334
+
335
+ This General Public License does not permit incorporating your program into
336
+ proprietary programs. If your program is a subroutine library, you may
337
+ consider it more useful to permit linking proprietary applications with the
338
+ library. If this is what you want to do, use the GNU Lesser General
339
+ Public License instead of this License.
MANIFEST.in ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ include requirements.txt
2
+ include requirements_api.txt
3
+ include src/pandora/py.typed
4
+ recursive-include src/pandora/flask *
5
+ recursive-include src/pandora/migrations/scripts *
bin/startup.sh ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+
3
+ PANDORA_ARGS=""
4
+ PANDORA_COMMAND="pandora"
5
+ USER_CONFIG_DIR="/data"
6
+
7
+ if [ -n "${PANDORA_PROXY}" ]; then
8
+ PANDORA_ARGS="${PANDORA_ARGS} -p ${PANDORA_PROXY}"
9
+ fi
10
+
11
+ if [ -n "${PANDORA_ACCESS_TOKEN}" ]; then
12
+ mkdir -p "${USER_CONFIG_DIR}"
13
+
14
+ echo "${PANDORA_ACCESS_TOKEN}" >"${USER_CONFIG_DIR}/access_token.dat"
15
+ fi
16
+
17
+ if [ -n "${PANDORA_TOKENS_FILE}" ]; then
18
+ PANDORA_ARGS="${PANDORA_ARGS} --tokens_file ${PANDORA_TOKENS_FILE}"
19
+ fi
20
+
21
+ if [ -n "${PANDORA_SERVER}" ]; then
22
+ PANDORA_ARGS="${PANDORA_ARGS} -s ${PANDORA_SERVER}"
23
+ fi
24
+
25
+ if [ -n "${PANDORA_API}" ]; then
26
+ PANDORA_ARGS="${PANDORA_ARGS} -a"
27
+ fi
28
+
29
+ if [ -n "${PANDORA_LOGIN_LOCAL}" ]; then
30
+ PANDORA_ARGS="${PANDORA_ARGS} -l"
31
+ fi
32
+
33
+ if [ -n "${PANDORA_VERBOSE}" ]; then
34
+ PANDORA_ARGS="${PANDORA_ARGS} -v"
35
+ fi
36
+
37
+ if [ -n "${PANDORA_THREADS}" ]; then
38
+ PANDORA_ARGS="${PANDORA_ARGS} --threads ${PANDORA_THREADS}"
39
+ fi
40
+
41
+ if [ -n "${PANDORA_CLOUD}" ]; then
42
+ PANDORA_COMMAND="pandora-cloud"
43
+ fi
44
+
45
+ export USER_CONFIG_DIR
46
+
47
+ # shellcheck disable=SC2086
48
+ $(command -v ${PANDORA_COMMAND}) ${PANDORA_ARGS}
doc/HTTP-API.md ADDED
@@ -0,0 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Pandora HTTP API
2
+
3
+ ### 特殊说明:如果有多个`Access Token`,可以使用`X-Use-Token: token_name` 头指定使用哪个。
4
+
5
+ ### `/api/models`
6
+
7
+ * **HTTP方法:** `GET`
8
+ * **URL参数:** `无`
9
+ * **接口描述:** 列出账号可用的模型。
10
+
11
+ ### `/api/conversations`
12
+
13
+ * **HTTP方法:** `GET`
14
+ * **URL参数:**
15
+ * `offset` 数字类型,默认为:`1`。
16
+ * `limit` 数字类型,默认为:`20`。
17
+ * **接口描述:** 以分页方式列出会话列表。
18
+
19
+ ### `/api/conversations`
20
+
21
+ * **HTTP方法:** `DELETE`
22
+ * **URL参数:** `无`
23
+ * **接口描述:** 删除所有会话。
24
+
25
+ ### `/api/conversation/<conversation_id>`
26
+
27
+ * **HTTP方法:** `GET`
28
+ * **URL参数:** `无`
29
+ * **接口描述:** 通过会话ID获取指定会话详情。
30
+
31
+ ### `/api/conversation/<conversation_id>`
32
+
33
+ * **HTTP方法:** `DELETE`
34
+ * **URL参数:** `无`
35
+ * **接口描述:** 通过会话ID删除指定会话。
36
+
37
+ ### `/api/conversation/<conversation_id>`
38
+
39
+ * **HTTP方法:** `PATCH`
40
+ * **JSON字段:**
41
+ * `title` 新标题。
42
+ * **接口描述:** 通过会话ID设置指定的会话标题。
43
+
44
+ ### `/api/conversation/gen_title/<conversation_id>`
45
+
46
+ * **HTTP方法:** `POST`
47
+ * **JSON字段:**
48
+ * `model` 对话所使用的模型。
49
+ * `message_id` `ChatGPT`回复的那条消息的ID。
50
+ * **接口描述:** 自动生成指定新会话的标题,通常首次问答后调用。
51
+
52
+ ### `/api/conversation/talk`
53
+
54
+ * **HTTP方法:** `POST`
55
+ * **JSON字段:**
56
+ * `prompt` 提问的内容。
57
+ * `model` 对话使用的模型,通常整个会话中保持不变。
58
+ * `message_id` 消息ID,通常使用`str(uuid.uuid4())`来生成一个。
59
+ * `parent_message_id` 父消息ID,首次同样需要生成。之后获取上一条回复的消息ID即可。
60
+ * `conversation_id` 首次对话可不传。`ChatGPT`回复时可获取。
61
+ * `stream` 是否使用流的方式输出内容,默认为:`True`
62
+ * **接口描述:** 向`ChatGPT`提问,等待其回复。
63
+
64
+ ### `/api/conversation/regenerate`
65
+
66
+ * **HTTP方法:** `POST`
67
+ * **JSON字段:**
68
+ * `prompt` 提问的内容。
69
+ * `model` 对话使用的模型,通常整个会话中保持不变。
70
+ * `message_id` 上一条用户发送消息的ID。
71
+ * `parent_message_id` 上一条用户发送消息的父消息ID。
72
+ * `conversation_id` 会话ID,在这个接口不可不传。
73
+ * `stream` 是否使用流的方式输出内容,默认为:`True`
74
+ * **接口描述:** 让`ChatGPT`重新生成回复。
75
+
76
+ ### `/api/conversation/goon`
77
+
78
+ * **HTTP方法:** `POST`
79
+ * **JSON字段:**
80
+ * `model` 对话使用的模型,通常整个会话中保持不变。
81
+ * `parent_message_id` 父消息ID,上一次`ChatGPT`应答的消息ID。
82
+ * `conversation_id` 会话ID。
83
+ * `stream` 是否使用流的方式输出内容,默认为:`True`
84
+ * **接口描述:** 让`ChatGPT`讲之前的恢复继续下去。
85
+
doc/images/s01.png ADDED
doc/images/s02.png ADDED
doc/images/s03.png ADDED
doc/images/s04.png ADDED
doc/images/s05.png ADDED
doc/images/s06.png ADDED
doc/images/s11.jpeg ADDED
doc/images/s12.jpeg ADDED
doc/images/t0.png ADDED
doc/images/t1.1.png ADDED
doc/images/t1.png ADDED
doc/images/t2.png ADDED
doc/images/t3.png ADDED
doc/images/t4.png ADDED
doc/images/t7.png ADDED
doc/wiki.md ADDED
@@ -0,0 +1,204 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <br />
2
+
3
+ <p align="center">
4
+ <h3 align="center">潘多拉 Pandora</h3>
5
+ <p align="center">
6
+ 一个不只是命令行的 "ChatGPT"
7
+ <br />
8
+ <a href="https://github.com/pengzhile/pandora/blob/master/doc/wiki_en.md"><strong>Wiki in English »</strong></a>
9
+ <br />
10
+ <br />
11
+ <a href="https://chat.zhile.io">查看Demo</a>
12
+ ·
13
+ <a href="https://github.com/pengzhile/pandora/issues">报告Bug</a>
14
+ ·
15
+ <a href="https://github.com/pengzhile/pandora/issues">提出新特性</a>
16
+ </p>
17
+ </p>
18
+
19
+ ## 目录
20
+
21
+ - [如何运行](#如何运行)
22
+ - [程序参数](#程序参数)
23
+ - [Docker环境变量](#docker环境变量)
24
+ - [关于 Access Token](#关于-access-token)
25
+ - [HTTP服务文档](#http服务文档)
26
+ - [操作命令](#操作命令)
27
+ - [高阶设置](#高阶设置)
28
+ - [Cloud模式](#cloud模式)
29
+ - [使用Cloudflare Workers代理](#使用cloudflare-workers代理)
30
+
31
+ ## 如何运行
32
+
33
+ * Python版本目测起码要`3.7`
34
+
35
+ * pip安装运行
36
+
37
+ ```shell
38
+ pip install pandora-chatgpt
39
+ pandora
40
+ ```
41
+ * 如果你想支持`gpt-3.5-turbo`模式:
42
+
43
+ ```shell
44
+ pip install 'pandora-chatgpt[api]'
45
+ // 或者
46
+ pip install pandora-chatgpt[api]
47
+ pandora
48
+ ```
49
+ * 如果你想启用`cloud`模式:
50
+
51
+ ```shell
52
+ pip install 'pandora-chatgpt[cloud]'
53
+ // 或者
54
+ pip install pandora-chatgpt[cloud]
55
+ pandora-cloud
56
+ ```
57
+
58
+ * 编译运行
59
+
60
+ ```shell
61
+ pip install .
62
+ pandora
63
+ ```
64
+
65
+ * 如果你想支持`gpt-3.5-turbo`模式:
66
+
67
+ ```shell
68
+ pip install '.[api]'
69
+ // 或者
70
+ pip install .[api]
71
+ pandora
72
+ ```
73
+
74
+ * 如果你想启用`cloud`模式:
75
+
76
+ ```shell
77
+ pip install '.[cloud]'
78
+ // 或者
79
+ pip install .[cloud]
80
+ pandora-cloud
81
+ ```
82
+
83
+ * Docker Hub运行
84
+
85
+ ```shell
86
+ docker pull pengzhile/pandora
87
+ docker run -it --rm pengzhile/pandora
88
+ ```
89
+
90
+ * Docker编译运行
91
+
92
+ ```shell
93
+ docker build -t pandora .
94
+ docker run -it --rm pandora
95
+ ```
96
+
97
+ * Serverless部署见项目:[pandora-cloud-serverless](https://github.com/pengzhile/pandora-cloud-serverless)
98
+
99
+ * 输入用户名密码登录即可,登录密码理论上不显示出来,莫慌。
100
+ * 简单而粗暴,不失优雅。
101
+
102
+ ## 程序参数
103
+
104
+ * 可通过 `pandora --help` 查看。
105
+ * `-p` 或 `--proxy` 指定代理,格式:`protocol://user:pass@ip:port`。
106
+ * `-t` 或 `--token_file` 指定一个存放`Access Token`的文件,使用`Access Token`登录。
107
+ * `-s` 或 `--server` 以`http`服务方式启动,格式:`ip:port`。
108
+ * `-a` 或 `--api` 使用`gpt-3.5-turbo`API请求,**你可能需要向`OpenAI`支付费用**。
109
+ * `-l` 或 `--local` 使用本地环境登录,**你可能需要一个合适的代理IP以避免账号被风控!**
110
+ * `--tokens_file` 指定一个存放多`Access Token`的文件,内容为`{"key": "token"}`的形式。
111
+ * `--threads` 指定服务启动的线程数,默认为 `8`,Cloud模式为 `4`。
112
+ * `-v` 或 `--verbose` 显示调试信息,且出错时打印异常堆栈信息,供查错使用。
113
+
114
+ ## Docker环境变量
115
+
116
+ * `PANDORA_ACCESS_TOKEN` 指定`Access Token`字符串。
117
+ * `PANDORA_TOKENS_FILE` 指定一个存放多`Access Token`的文件路径。
118
+ * `PANDORA_PROXY` 指定代理,格式:`protocol://user:pass@ip:port`。
119
+ * `PANDORA_SERVER` 以`http`服务方式启动,格式:`ip:port`。
120
+ * `PANDORA_API` 使用`gpt-3.5-turbo`API请求,**你可能需要向`OpenAI`支付费用**。
121
+ * `PANDORA_LOGIN_LOCAL` 使用本地环境登录,**你可能需要一个合适的代理IP以避免账号被风控!**
122
+ * `PANDORA_VERBOSE` 显示调试信息,且出错时打印异常堆栈信息,供查错使用。
123
+ * `PANDORA_THREADS` 指定服务启动的线程数,默认为 `8`,Cloud模式为 `4`。
124
+ * 使用Docker方式,设置环境变量即可,无视上述`程序参数`。
125
+
126
+ ## 关于 Access Token
127
+
128
+ * 使用`Access Token`方式登录,可以无代理直连。
129
+ * [这个服务](https://ai-20230626.fakeopen.com/auth) 可以帮你安全有效拿到`Access Token`,无论是否第三方登录。
130
+ * 其中`accessToken`字段的那一长串内容即是`Access Token`。
131
+ * `Access Token`可以复制保存,其有效期目前为`14天`。
132
+ * 不要泄露你的`Access Token`,使用它可以操纵你的账号。
133
+
134
+ ## HTTP服务文档
135
+
136
+ * 如果你以`http`服务方式启动,现在你可以打开一个极简版的`ChatGPT`了。通过你指定的`http://ip:port`来访问。
137
+ * 通过`http://ip:port/?token=xxx`,传递一个Token的名字,可以切换到对应的`Access Token`。
138
+ * API文档见:[doc/HTTP-API.md](https://github.com/pengzhile/pandora/blob/master/doc/HTTP-API.md)
139
+
140
+ ## 操作命令
141
+
142
+ * 对话界面**连敲两次**`Enter`发送你的输入给`ChatGPT`。
143
+ * 对话界面使用`/?`可以打印支持的操作命令。
144
+ * `/title` 重新设置当前对话的标题。
145
+ * `/select` 回到选择会话界面。
146
+ * `/reload` 重新加载当前会话所有内容,`F5`你能懂吧。
147
+ * `/regen` 如果对`ChatGPT`当前回答不满意,可以让它重��回答。
148
+ * `/continue` 让`ChatGPT`继续输出回复的剩余部分。
149
+ * `/edit` 编辑你之前的一个提问。
150
+ * `/new` 直接开启一个新会话。
151
+ * `/del` 删除当前会话,回到会话选择界面。
152
+ * `/token` 打印当前的`Access Token`,也许你用得上,但不要泄露。
153
+ * `/copy` 复制`ChatGPT`上一次回复的内容到剪贴板。
154
+ * `/copy_code` 复制`ChatGPT`上一次回复的代码到剪贴板
155
+ * `/clear` 清屏,应该不用解释。
156
+ * `/version` 打印`Pandora`的版本信息。
157
+ * `/exit` 退出`潘多拉`。
158
+
159
+ ## 高阶设置
160
+
161
+ * 本部分内容不理解的朋友,**请勿擅动!**
162
+ * 环境变量 `OPENAI_API_PREFIX` 可以替换OpenAI Api的前缀`https://api.openai.com`。
163
+ * 环境变量 `CHATGPT_API_PREFIX` 可以替换ChatGPT Api的前缀`https://ai.fakeopen.com`。
164
+ * 如果你想持久存储`Docker`中`Pandora`产生的数据,你可以挂载宿主机目录至`/data`。
165
+ * 如果你在国内使用`pip`安装缓慢,可以考虑切换至腾讯的源:```pip config set global.index-url https://mirrors.cloud.tencent.com/pypi/simple```
166
+ * 镜像同步版本可能不及时,如果出现这种情况建议切换至官方源:```pip config set global.index-url https://pypi.org/simple```
167
+ * 默认使用`sqlite3`存储会话数据,如果你希望更换至`mysql`,可以这么做:
168
+ * 执行```pip install PyMySQL```安装驱动。
169
+ * 设置环境变量:`DATABASE_URI`为类似`mysql+pymysql://user:pass@localhost/dbname`的连接字符串。
170
+ * 环境变量指定`OPENAI_EMAIL`可以替代登录输入用户名,`OPENAI_PASSWORD`则可以替代输入密码, `OPENAI_MFA_CODE`则可以替代输入二次验证。
171
+ * 环境变量`API_SYSTEM_PROMPT`可以替换`api`模式下的系统`prompt`。
172
+
173
+ ## Cloud模式
174
+
175
+ * 搭建一个跟官方很像的`ChatGPT`服务,不能说很像,只能说一样。
176
+ * 该模式使用`pandora-cloud`启动,前提是你如前面所说安装好了。
177
+ * Docker环境变量:`PANDORA_CLOUD` 启动`cloud`模式。
178
+ * 该模式参数含义与普通模式相同,可`--help`查看。
179
+
180
+ ## 使用Cloudflare Workers代理
181
+
182
+ * 如果你感觉默认的`https://ai.fakeopen.com`在你那里可能被墙了,可以使用如下方法自行代理。
183
+ * 你需要一个`Cloudflare`账号,如果没有,可以[注册](https://dash.cloudflare.com/sign-up)一个。
184
+ * 登录后,点击`Workers`,然后点击`Create a Worker`,填入服务名称后点击`创建服务`。
185
+ * 点开你刚才创建的服务,点击`快速编辑`按钮,贴入下面的代码,然后点击`保存并部署`。
186
+
187
+ ```javascript
188
+ export default {
189
+ async fetch(request, env) {
190
+ const url = new URL(request.url);
191
+ url.host = 'ai.fakeopen.com';
192
+ return fetch(new Request(url, request))
193
+ }
194
+ }
195
+ ```
196
+
197
+ * 点击`触发器`选项卡,可以添加自定义访问域名。
198
+ * 参考`高阶设置`中的环境变量使用你的服务地址进行替换。
199
+
200
+ ## 日抛版代理地址
201
+
202
+ * 每日凌晨`1`点,将会同时生成一个当日子域名,如 `ai-20230625.fakeopen.com`。
203
+ * 子域名使用效果完全等同于 `ai.fakeopen.com`。至于作用,湖北的你肯定能懂。
204
+ * 可将环境变量替换成子域,如 `CHATGPT_API_PREFIX=https://ai-20230625.fakeopen.com`。
doc/wiki_en.md ADDED
@@ -0,0 +1,164 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <br />
2
+
3
+ <p align="center">
4
+ <h3 align="center">Pandora</h3>
5
+ <p align="center">
6
+ Pandora, talking with ChatGPT in command lines, and with more surprises.
7
+ <br />
8
+ <a href="https://github.com/pengzhile/pandora/blob/master/doc/wiki.md"><strong>Wiki in 中文 »</strong></a>
9
+ <br />
10
+ <br />
11
+ <a href="https://chat.zhile.io">Demo View</a>
12
+ ·
13
+ <a href="https://github.com/pengzhile/pandora/issues">Bug Report</a>
14
+ ·
15
+ <a href="https://github.com/pengzhile/pandora/issues">Feature Request</a>
16
+ </p>
17
+ </p>
18
+
19
+ ## Table of Contents
20
+
21
+ - [Make it run](#make-it-run)
22
+ - [Start parameters](#start-parameters)
23
+ - [Docker](#docker)
24
+ - [Access Token things](#access-token-things)
25
+ - [HTTP RESTful API](#http-restful-api)
26
+ - [Commands](#commands)
27
+ - [Cloud mode](#cloud-mode)
28
+
29
+ ## Make it run
30
+
31
+ * Python version no less than `3.7`
32
+
33
+ * install from `pip`
34
+
35
+ ```shell
36
+ pip install pandora-chatgpt
37
+ pandora
38
+ ```
39
+ * `gpt-3.5-turbo` mode:
40
+
41
+ ```shell
42
+ pip install 'pandora-chatgpt[api]'
43
+ // OR
44
+ pip install pandora-chatgpt[api]
45
+ pandora
46
+ ```
47
+ * `cloud` mode:
48
+
49
+ ```shell
50
+ pip install 'pandora-chatgpt[cloud]'
51
+ // OR
52
+ pip install pandora-chatgpt[cloud]
53
+ pandora-cloud
54
+ ```
55
+
56
+ * install from source
57
+
58
+ ```shell
59
+ pip install .
60
+ pandora
61
+ ```
62
+
63
+ * `gpt-3.5-turbo` mode:
64
+
65
+ ```shell
66
+ pip install '.[api]'
67
+ // OR
68
+ pip install .[api]
69
+ pandora
70
+ ```
71
+
72
+ * `cloud` mode:
73
+
74
+ ```shell
75
+ pip install '.[cloud]'
76
+ // OR
77
+ pip install .[cloud]
78
+ pandora-cloud
79
+ ```
80
+
81
+ * Docker Hub
82
+
83
+ ```shell
84
+ docker pull pengzhile/pandora
85
+ docker run -it --rm pengzhile/pandora
86
+ ```
87
+
88
+ * Docker build
89
+
90
+ ```shell
91
+ docker build -t pandora .
92
+ docker run -it --rm pandora
93
+ ```
94
+
95
+ * Serverless deploy:[pandora-cloud-serverless](https://github.com/pengzhile/pandora-cloud-serverless)
96
+
97
+ * login with your credentials
98
+
99
+ * stay simple, stay naive, stay elegant
100
+
101
+ ## Start parameters
102
+
103
+ * `pandora --help` for help text.
104
+ * `-p` or `--proxy` for setting the proxy. the value should be`protocol://user:pass@ip:port`.
105
+ * `-t` or `--token_file` for indicating the file that stores `Access Token`. You will login with access token if this option is in use.
106
+ * `-s` or `--server` starts the HTTP server, by which you could open a web page and interact with it in a fancy UI. the value should be`ip:port`.
107
+ * `-a` or `--api` use `gpt-3.5-turbo` API in backend. **NOTICE: you will be charged if this option is in use.**
108
+ * `-l` or `--local` login using the local environment. **You may need a suitable proxy IP to avoid account restrictions!**
109
+ * `--tokens_file` indicating a file storing multiple `Access Token`s. The file content should be like`{"key": "token"}`.
110
+ * `--threads` specify the number of server workers, default is `8`, and for cloud mode, it is `4`.
111
+ * `-v` or `--verbose` for verbose debugging messages.
112
+
113
+ ## Docker
114
+
115
+ These docker environment variables will override start parameters.
116
+
117
+ * `PANDORA_ACCESS_TOKEN` =`Access Token` string.
118
+ * `PANDORA_TOKENS_FILE` = the path of file which keeps `Access Token`s.
119
+ * `PANDORA_PROXY` =`protocol://user:pass@ip:port`.
120
+ * `PANDORA_SERVER` =`ip:port`.
121
+ * `PANDORA_API` for using `gpt-3.5-turbo` API. **NOTICE: you will be charged if this option is in use.**
122
+ * `PANDORA_LOGIN_LOCAL` login using the local environment. **You may need a suitable proxy IP to avoid account restrictions!**
123
+ * `PANDORA_VERBOSE` for verbose debugging messages.
124
+ * `PANDORA_THREADS` specify the number of server workers, default is `8`, and for cloud mode, it is `4`.
125
+
126
+ ## Access Token things
127
+
128
+ * no need for proxy if login with `Access Token`.
129
+ * you could obtain your access token safely with [this service](https://ai.fakeopen.com/auth).
130
+ * `Access Token` has a expiration time as `14 days`, you could save it and keep using within this period.
131
+ * leaking your `Access Token` will lead to loss of your account.
132
+
133
+ ## HTTP RESTFUL API
134
+
135
+ * if you start Pandora with `-s`/`--server`/`PANDORA_SERVER`, you could access a web UI with `http://ip:port`.
136
+ * you could switch access token by passing a different one with `http://ip:port/?token=xxx`.
137
+ * API documents: [doc/HTTP-API.md](https://github.com/pengzhile/pandora/blob/master/doc/HTTP-API.md)
138
+
139
+ ## Commands
140
+
141
+ * **double** `Enter` to send prompt to `ChatGPT`.
142
+ * `/?` for help text.
143
+ * `/title` for setting the title of current conversation.
144
+ * `/select` back to conversation choosing page.
145
+ * `/reload` for refreshing.
146
+ * `/regen` for regenerating answers if you are not satisfied with the last one.
147
+ * `/continue` make `ChatGPT` to append responses.
148
+ * `/edit` for editing your previous prompt.
149
+ * `/new` to start a new conversation.
150
+ * `/del` to delete current conversation and back to conversation choosing page.
151
+ * `/token` for printing current access token.
152
+ * `/copy` for copying the last response of `ChatGPT` to pasteboard.
153
+ * `/copy_code` for copying the code in the last response of `ChatGPT` to pasteboard.
154
+ * `/clear` for cleaning the screen.
155
+ * `/version` for printing the version of Pandora.
156
+ * `/exit` to exit Pandora.
157
+
158
+ ## Cloud mode
159
+
160
+ - setting up a service just like official `ChatGPT` website. it's so same as only jesus could tell it apart.
161
+
162
+ * you need to use `pandora-cloud` instead of `pandora` to start Pandora.
163
+ * enabling `PANDORA_CLOUD` if you are using Docker to start Pandora.
164
+ * Other parameters are same as these guys in normal mode.
requirements.txt ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ certifi
2
+ pyreadline3 ~= 3.4.0; platform_system == 'Windows'
3
+ httpx[socks]~=0.23.3
4
+ requests[socks]~=2.28.2
5
+ rich~=13.3.2
6
+ appdirs~=1.4.4
7
+ werkzeug~=2.2.3
8
+ flask[async]~=2.2.3
9
+ flask-cors~=3.0.10
10
+ waitress~=2.1.2
11
+ loguru~=0.6.0
12
+ pyjwt[crypto]~=2.6.0
13
+ pyperclip~=1.8.2
requirements_api.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ pandora-tiktoken~=0.3.1
2
+ sqlalchemy~=2.0.7
3
+ yoyo-migrations~=8.2.0
setup.py ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+
3
+ from setuptools import setup, find_packages
4
+
5
+ from src.pandora import __version__
6
+
7
+ with open('README.md', 'r', encoding='utf-8') as f:
8
+ long_description = f.read()
9
+
10
+ with open('requirements.txt', 'r', encoding='utf-8') as f:
11
+ requirements = f.read().split('\n')
12
+
13
+ with open('requirements_api.txt', 'r', encoding='utf-8') as f:
14
+ requirements_api = f.read().split('\n')
15
+
16
+ setup(
17
+ name='Pandora-ChatGPT',
18
+ version=__version__,
19
+ python_requires='>=3.7',
20
+ author='Neo Peng',
21
+ author_email='pengzhile@gmail.com',
22
+ keywords='OpenAI ChatGPT ChatGPT-Plus gpt-3.5-turbo gpt-3.5-turbo-0301',
23
+ description='A command-line interface to ChatGPT',
24
+ long_description=long_description,
25
+ long_description_content_type='text/markdown',
26
+ url='https://github.com/pengzhile/pandora',
27
+ packages=find_packages('src'),
28
+ package_dir={'pandora': 'src/pandora'},
29
+ include_package_data=True,
30
+ install_requires=requirements,
31
+ extras_require={
32
+ 'api': requirements_api,
33
+ 'cloud': ['pandora-cloud~=0.5.1'],
34
+ },
35
+ entry_points={
36
+ 'console_scripts': [
37
+ 'pandora = pandora.launcher:run',
38
+ 'pandora-cloud = pandora.cloud_launcher:run',
39
+ ]
40
+ },
41
+ project_urls={
42
+ 'Source': 'https://github.com/pengzhile/pandora',
43
+ 'Tracker': 'https://github.com/pengzhile/pandora/issues',
44
+ },
45
+ classifiers=[
46
+ 'Development Status :: 5 - Production/Stable',
47
+
48
+ 'Environment :: Console',
49
+ 'Environment :: Web Environment',
50
+
51
+ 'Framework :: Flask',
52
+
53
+ 'Intended Audience :: Developers',
54
+ 'Intended Audience :: End Users/Desktop',
55
+
56
+ 'License :: OSI Approved :: GNU General Public License v2 (GPLv2)',
57
+
58
+ 'Natural Language :: English',
59
+ 'Natural Language :: Chinese (Simplified)',
60
+
61
+ 'Operating System :: MacOS',
62
+ 'Operating System :: Microsoft :: Windows',
63
+ 'Operating System :: POSIX :: Linux',
64
+
65
+ 'Programming Language :: SQL',
66
+ 'Programming Language :: JavaScript',
67
+ 'Programming Language :: Python :: 3.7',
68
+ 'Programming Language :: Python :: 3.8',
69
+ 'Programming Language :: Python :: 3.9',
70
+ 'Programming Language :: Python :: 3.10',
71
+ 'Programming Language :: Python :: 3.11',
72
+
73
+ 'Topic :: Communications :: Chat',
74
+ 'Topic :: Internet :: WWW/HTTP',
75
+ ],
76
+ )
src/pandora/__init__.py ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+
3
+ __version__ = '1.3.0'
src/pandora/__main__.py ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+
3
+ from pandora import launcher
4
+
5
+ if __name__ == '__main__':
6
+ launcher.run()
src/pandora/bots/__init__.py ADDED
@@ -0,0 +1 @@
 
 
1
+ # -*- coding: utf-8 -*-
src/pandora/bots/legacy.py ADDED
@@ -0,0 +1,495 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+
3
+ import re
4
+ import uuid
5
+
6
+ import pyperclip
7
+ from rich.prompt import Prompt, Confirm
8
+
9
+ from .. import __version__
10
+ from ..openai.utils import Console
11
+
12
+
13
+ class ChatPrompt:
14
+ def __init__(self, prompt: str = None, parent_id=None, message_id=None):
15
+ self.prompt = prompt
16
+ self.parent_id = parent_id or self.gen_message_id()
17
+ self.message_id = message_id or self.gen_message_id()
18
+
19
+ @staticmethod
20
+ def gen_message_id():
21
+ return str(uuid.uuid4())
22
+
23
+
24
+ class State:
25
+ def __init__(self, title=None, conversation_id=None, model_slug=None, user_prompt=ChatPrompt(),
26
+ chatgpt_prompt=ChatPrompt()):
27
+ self.title = title
28
+ self.conversation_id = conversation_id
29
+ self.model_slug = model_slug
30
+ self.user_prompt = user_prompt
31
+ self.chatgpt_prompt = chatgpt_prompt
32
+ self.user_prompts = []
33
+ self.edit_index = None
34
+
35
+
36
+ class ChatBot:
37
+ def __init__(self, chatgpt):
38
+ self.chatgpt = chatgpt
39
+ self.token_key = None
40
+ self.state = None
41
+
42
+ def run(self):
43
+ self.token_key = self.__choice_token_key()
44
+
45
+ conversation_base = self.__choice_conversation()
46
+ if conversation_base:
47
+ self.__load_conversation(conversation_base['id'])
48
+ else:
49
+ self.__new_conversation()
50
+
51
+ self.__talk_loop()
52
+
53
+ def __talk_loop(self):
54
+ while True:
55
+ Console.info_b('You{}:'.format(' (edit)' if self.state and self.state.edit_index else ''))
56
+
57
+ prompt = self.__get_input()
58
+ if not prompt:
59
+ continue
60
+
61
+ if '/' == prompt[0]:
62
+ self.__process_command(prompt)
63
+ continue
64
+
65
+ self.__talk(prompt)
66
+
67
+ @staticmethod
68
+ def __get_input():
69
+ lines = []
70
+ while True:
71
+ line = input()
72
+
73
+ if not line:
74
+ break
75
+
76
+ if '/' == line[0]:
77
+ return line
78
+
79
+ lines.append(line)
80
+
81
+ return '\n'.join(lines)
82
+
83
+ def __process_command(self, command):
84
+ command = command.strip().lower()
85
+
86
+ if '/quit' == command or '/exit' == command or '/bye' == command:
87
+ raise KeyboardInterrupt
88
+ elif '/del' == command or '/delete' == command or '/remove' == command:
89
+ self.__del_conversation(self.state)
90
+ elif '/title' == command or '/set_title' == command or '/set-title' == command:
91
+ self.__set_conversation_title(self.state)
92
+ elif '/select' == command:
93
+ self.run()
94
+ elif '/refresh' == command or '/reload' == command:
95
+ self.__load_conversation(self.state.conversation_id)
96
+ elif '/new' == command:
97
+ self.__new_conversation()
98
+ self.__talk_loop()
99
+ elif '/regen' == command or '/regenerate' == command:
100
+ self.__regenerate_reply(self.state)
101
+ elif '/goon' == command or '/continue' == command:
102
+ self.__continue(self.state)
103
+ elif '/edit' == command or '/modify' == command:
104
+ self.__edit_choice()
105
+ elif '/token' == command:
106
+ self.__print_access_token()
107
+ elif '/cls' == command or '/clear' == command:
108
+ self.__clear_screen()
109
+ elif '/copy' == command or '/cp' == command:
110
+ self.__copy_text()
111
+ elif '/copy_code' == command or "/cp_code" == command:
112
+ self.__copy_code()
113
+ elif '/ver' == command or '/version' == command:
114
+ self.__print_version()
115
+ else:
116
+ self.__print_usage()
117
+
118
+ @staticmethod
119
+ def __print_usage():
120
+ Console.info_b('\n#### Command list:')
121
+ print('/?\t\tShow this help message.')
122
+ print('/title\t\tSet the current conversation\'s title.')
123
+ print('/select\t\tChoice a different conversation.')
124
+ print('/reload\t\tReload the current conversation.')
125
+ print('/regen\t\tRegenerate response.')
126
+ print('/continue\t\tContinue generating.')
127
+ print('/edit\t\tEdit one of your previous prompt.')
128
+ print('/new\t\tStart a new conversation.')
129
+ print('/del\t\tDelete the current conversation.')
130
+ print('/token\t\tPrint your access token.')
131
+ print('/copy\t\tCopy the last response to clipboard.')
132
+ print('/copy_code\t\tCopy code from last response.')
133
+ print('/clear\t\tClear your screen.')
134
+ print('/version\tPrint the version of Pandora.')
135
+ print('/exit\t\tExit Pandora.')
136
+ print()
137
+
138
+ def __edit_choice(self):
139
+ if not self.state.user_prompts:
140
+ return
141
+
142
+ choices = []
143
+ pattern = re.compile(r'\s+')
144
+ Console.info_b('Choice your prompt to edit:')
145
+ for idx, item in enumerate(self.state.user_prompts):
146
+ number = str(idx + 1)
147
+ choices.append(number)
148
+
149
+ preview_prompt = re.sub(pattern, ' ', item.prompt)
150
+ if len(preview_prompt) > 40:
151
+ preview_prompt = '{}...'.format(preview_prompt[0:40])
152
+
153
+ Console.info(' {}.\t{}'.format(number, preview_prompt))
154
+
155
+ choices.append('c')
156
+ Console.warn(' c.\t** Cancel')
157
+
158
+ default_choice = None if len(choices) > 2 else '1'
159
+ while True:
160
+ choice = Prompt.ask('Your choice', choices=choices, show_choices=False, default=default_choice)
161
+ if 'c' == choice:
162
+ return
163
+
164
+ self.state.edit_index = int(choice)
165
+ return
166
+
167
+ def __print_access_token(self):
168
+ Console.warn_b('\n#### Your access token (keep it private)')
169
+ Console.warn(self.chatgpt.get_access_token(token_key=self.token_key))
170
+ print()
171
+
172
+ def __clear_screen(self):
173
+ Console.clear()
174
+
175
+ if self.state:
176
+ self.__print_conversation_title(self.state.title)
177
+
178
+ @staticmethod
179
+ def __print_version():
180
+ Console.debug_bh('#### Version: {}'.format(__version__))
181
+ print()
182
+
183
+ def __new_conversation(self):
184
+ self.state = State(model_slug=self.__choice_model()['slug'])
185
+
186
+ self.state.title = 'New Chat'
187
+ self.__print_conversation_title(self.state.title)
188
+
189
+ @staticmethod
190
+ def __print_conversation_title(title: str):
191
+ Console.info_bh('==================== {} ===================='.format(title))
192
+ Console.debug_h('Double enter to send. Type /? for help.')
193
+
194
+ def __set_conversation_title(self, state: State):
195
+ if not state.conversation_id:
196
+ Console.error('#### Conversation has not been created.')
197
+ return
198
+
199
+ new_title = Prompt.ask('New title')
200
+ if len(new_title) > 64:
201
+ Console.error('#### Title too long.')
202
+ return
203
+
204
+ if self.chatgpt.set_conversation_title(state.conversation_id, new_title, token=self.token_key):
205
+ state.title = new_title
206
+ Console.debug('#### Set title success.')
207
+ else:
208
+ Console.error('#### Set title failed.')
209
+
210
+ def __clear_conversations(self):
211
+ if not Confirm.ask('Are you sure?', default=False):
212
+ return
213
+
214
+ if self.chatgpt.clear_conversations(token=self.token_key):
215
+ self.run()
216
+ else:
217
+ Console.error('#### Clear conversations failed.')
218
+
219
+ def __del_conversation(self, state: State):
220
+ if not state.conversation_id:
221
+ Console.error('#### Conversation has not been created.')
222
+ return
223
+
224
+ if not Confirm.ask('Are you sure?', default=False):
225
+ return
226
+
227
+ if self.chatgpt.del_conversation(state.conversation_id, token=self.token_key):
228
+ self.run()
229
+ else:
230
+ Console.error('#### Delete conversation failed.')
231
+
232
+ def __load_conversation(self, conversation_id):
233
+ if not conversation_id:
234
+ return
235
+
236
+ self.state = State(conversation_id=conversation_id)
237
+
238
+ nodes = []
239
+ result = self.chatgpt.get_conversation(conversation_id, token=self.token_key)
240
+ current_node_id = result['current_node']
241
+
242
+ while True:
243
+ node = result['mapping'][current_node_id]
244
+ if not node.get('parent'):
245
+ break
246
+
247
+ nodes.insert(0, node)
248
+ current_node_id = node['parent']
249
+
250
+ self.state.title = result['title']
251
+ self.__print_conversation_title(self.state.title)
252
+
253
+ merge = False
254
+ for node in nodes:
255
+ message = node['message']
256
+ if 'model_slug' in message['metadata']:
257
+ self.state.model_slug = message['metadata']['model_slug']
258
+
259
+ role = message['author']['role'] if 'author' in message else message['role']
260
+
261
+ if 'user' == role:
262
+ prompt = self.state.user_prompt
263
+ self.state.user_prompts.append(ChatPrompt(message['content']['parts'][0], parent_id=node['parent']))
264
+
265
+ Console.info_b('You:')
266
+ Console.info(message['content']['parts'][0])
267
+ elif 'assistant' == role:
268
+ prompt = self.state.chatgpt_prompt
269
+
270
+ if not merge:
271
+ Console.success_b('ChatGPT:')
272
+ Console.success(message['content']['parts'][0])
273
+
274
+ merge = 'end_turn' in message and message['end_turn'] is None
275
+ else:
276
+ continue
277
+
278
+ prompt.prompt = message['content']['parts'][0]
279
+ prompt.parent_id = node['parent']
280
+ prompt.message_id = node['id']
281
+
282
+ if not merge:
283
+ print()
284
+
285
+ def __talk(self, prompt):
286
+ Console.success_b('ChatGPT:')
287
+
288
+ first_prompt = not self.state.conversation_id
289
+
290
+ if self.state.edit_index:
291
+ idx = self.state.edit_index - 1
292
+ user_prompt = self.state.user_prompts[idx]
293
+ self.state.user_prompt = ChatPrompt(prompt, parent_id=user_prompt.parent_id)
294
+ self.state.user_prompts = self.state.user_prompts[0:idx]
295
+
296
+ self.state.edit_index = None
297
+ else:
298
+ self.state.user_prompt = ChatPrompt(prompt, parent_id=self.state.chatgpt_prompt.message_id)
299
+
300
+ status, _, generator = self.chatgpt.talk(prompt, self.state.model_slug, self.state.user_prompt.message_id,
301
+ self.state.user_prompt.parent_id, self.state.conversation_id,
302
+ token=self.token_key)
303
+ self.__print_reply(status, generator)
304
+
305
+ self.state.user_prompts.append(self.state.user_prompt)
306
+
307
+ if first_prompt:
308
+ new_title = self.chatgpt.gen_conversation_title(self.state.conversation_id, self.state.model_slug,
309
+ self.state.chatgpt_prompt.message_id, token=self.token_key)
310
+ self.state.title = new_title
311
+ Console.debug_bh('#### Title generated: ' + new_title)
312
+
313
+ def __regenerate_reply(self, state):
314
+ if not state.conversation_id:
315
+ Console.error('#### Conversation has not been created.')
316
+ return
317
+
318
+ status, _, generator = self.chatgpt.regenerate_reply(state.user_prompt.prompt, state.model_slug,
319
+ state.conversation_id, state.user_prompt.message_id,
320
+ state.user_prompt.parent_id, token=self.token_key)
321
+ print()
322
+ Console.success_b('ChatGPT:')
323
+ self.__print_reply(status, generator)
324
+
325
+ def __continue(self, state):
326
+ if not state.conversation_id:
327
+ Console.error('#### Conversation has not been created.')
328
+ return
329
+
330
+ status, _, generator = self.chatgpt.goon(state.model_slug, state.chatgpt_prompt.message_id,
331
+ state.conversation_id, token=self.token_key)
332
+ print()
333
+ Console.success_b('ChatGPT:')
334
+ self.__print_reply(status, generator)
335
+
336
+ def __print_reply(self, status, generator):
337
+ if 200 != status:
338
+ raise Exception(status, next(generator))
339
+
340
+ p = 0
341
+ for result in generator:
342
+ if result['error']:
343
+ raise Exception(result['error'])
344
+
345
+ if not result['message']:
346
+ raise Exception('miss message property.')
347
+
348
+ text = None
349
+ message = result['message']
350
+ if 'assistant' == message['author']['role']:
351
+ text = message['content']['parts'][0][p:]
352
+ p += len(text)
353
+
354
+ self.state.conversation_id = result['conversation_id']
355
+ self.state.chatgpt_prompt.prompt = message['content']['parts'][0]
356
+ self.state.chatgpt_prompt.parent_id = self.state.user_prompt.message_id
357
+ self.state.chatgpt_prompt.message_id = message['id']
358
+
359
+ if 'system' == message['author']['role']:
360
+ self.state.user_prompt.parent_id = message['id']
361
+
362
+ if text:
363
+ Console.success(text, end='')
364
+
365
+ print('\n')
366
+
367
+ def __choice_conversation(self, page=1, page_size=20):
368
+ conversations = self.chatgpt.list_conversations((page - 1) * page_size, page_size, token=self.token_key)
369
+ if not conversations['total']:
370
+ return None
371
+
372
+ choices = ['c', 'r', 'dd']
373
+ items = conversations['items']
374
+ first_page = 0 == conversations['offset']
375
+ last_page = (conversations['offset'] + conversations['limit']) >= conversations['total']
376
+
377
+ Console.info_b('Choice conversation (Page {}):'.format(page))
378
+ for idx, item in enumerate(items):
379
+ number = str(idx + 1)
380
+ choices.append(number)
381
+ choices.append('t' + number)
382
+ choices.append('d' + number)
383
+ Console.info(' {}.\t{}'.format(number, item['title'].replace('\n', ' ')))
384
+
385
+ if not last_page:
386
+ choices.append('n')
387
+ Console.warn(' n.\t>> Next page')
388
+
389
+ if not first_page:
390
+ choices.append('p')
391
+ Console.warn(' p.\t<< Previous page')
392
+
393
+ Console.warn(' t?.\tSet title for the conversation, eg: t1')
394
+ Console.warn(' d?.\tDelete the conversation, eg: d1')
395
+ Console.warn(' dd.\t!! Clear all conversations')
396
+ Console.warn(' r.\tRefresh conversation list')
397
+
398
+ if len(self.chatgpt.list_token_keys()) > 1:
399
+ choices.append('k')
400
+ Console.warn(' k.\tChoice access token')
401
+
402
+ Console.warn(' c.\t** Start new chat')
403
+
404
+ while True:
405
+ choice = Prompt.ask('Your choice', choices=choices, show_choices=False)
406
+ if 'c' == choice:
407
+ return None
408
+
409
+ if 'k' == choice:
410
+ self.run()
411
+ return
412
+
413
+ if 'r' == choice:
414
+ return self.__choice_conversation(page, page_size)
415
+
416
+ if 'n' == choice:
417
+ return self.__choice_conversation(page + 1, page_size)
418
+
419
+ if 'p' == choice:
420
+ return self.__choice_conversation(page - 1, page_size)
421
+
422
+ if 'dd' == choice:
423
+ self.__clear_conversations()
424
+ continue
425
+
426
+ if 't' == choice[0]:
427
+ self.__set_conversation_title(State(conversation_id=items[int(choice[1:]) - 1]['id']))
428
+ return self.__choice_conversation(page, page_size)
429
+
430
+ if 'd' == choice[0]:
431
+ self.__del_conversation(State(conversation_id=items[int(choice[1:]) - 1]['id']))
432
+ continue
433
+
434
+ return items[int(choice) - 1]
435
+
436
+ def __choice_token_key(self):
437
+ tokens = self.chatgpt.list_token_keys()
438
+
439
+ size = len(tokens)
440
+ if 1 == size:
441
+ return None
442
+
443
+ choices = ['r']
444
+ Console.info_b('Choice access token:')
445
+ for idx, item in enumerate(tokens):
446
+ number = str(idx + 1)
447
+ choices.append(number)
448
+ Console.info(' {}.\t{}'.format(number, item))
449
+
450
+ while True:
451
+ choice = Prompt.ask('Your choice', choices=choices, show_choices=False)
452
+
453
+ return tokens[int(choice) - 1]
454
+
455
+ def __choice_model(self):
456
+ models = self.chatgpt.list_models(token=self.token_key)
457
+
458
+ size = len(models)
459
+ if 1 == size:
460
+ return models[0]
461
+
462
+ choices = ['r']
463
+ Console.info_b('Choice model:')
464
+ for idx, item in enumerate(models):
465
+ number = str(idx + 1)
466
+ choices.append(number)
467
+ Console.info(' {}.\t{} - {} - {}'.format(number, item['title'], item['description'],
468
+ '|'.join(item['tags'])))
469
+
470
+ Console.warn(' r.\tRefresh model list')
471
+
472
+ while True:
473
+ choice = Prompt.ask('Your choice', choices=choices, show_choices=False)
474
+ if 'r' == choice:
475
+ return self.__choice_model()
476
+
477
+ return models[int(choice) - 1]
478
+
479
+ def __copy_text(self):
480
+ pyperclip.copy(self.state.chatgpt_prompt.prompt)
481
+ Console.info("已将上一次返回结果复制到剪切板。")
482
+ pass
483
+
484
+ def __copy_code(self):
485
+ text = self.state.chatgpt_prompt.prompt
486
+ pattern = re.compile(r'```.*\s([\s\S]*?)\s```')
487
+ result = re.findall(pattern, text)
488
+ if len(result) == 0:
489
+ Console.info("未找到代码。")
490
+ return
491
+ else:
492
+ code = '\n=======================================================\n'.join(result)
493
+ pyperclip.copy(code)
494
+ Console.info("已将上一次生成的代码复制到剪切板。")
495
+ pass
src/pandora/bots/server.py ADDED
@@ -0,0 +1,282 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+
3
+ import logging
4
+ from datetime import timedelta
5
+ from os.path import join, abspath, dirname
6
+
7
+ from flask import Flask, jsonify, make_response, request, Response, render_template
8
+ from flask_cors import CORS
9
+ from waitress import serve
10
+ from werkzeug.exceptions import default_exceptions
11
+ from werkzeug.middleware.proxy_fix import ProxyFix
12
+ from werkzeug.serving import WSGIRequestHandler
13
+
14
+ from .. import __version__
15
+ from ..exts.hooks import hook_logging
16
+ from ..openai.api import API
17
+
18
+
19
+ class ChatBot:
20
+ __default_ip = '127.0.0.1'
21
+ __default_port = 8008
22
+
23
+ def __init__(self, chatgpt, debug=False, sentry=False):
24
+ self.chatgpt = chatgpt
25
+ self.debug = debug
26
+ self.sentry = sentry
27
+ self.log_level = logging.DEBUG if debug else logging.WARN
28
+
29
+ hook_logging(level=self.log_level, format='[%(asctime)s] %(levelname)s in %(module)s: %(message)s')
30
+ self.logger = logging.getLogger('waitress')
31
+
32
+ def run(self, bind_str, threads=8):
33
+ host, port = self.__parse_bind(bind_str)
34
+
35
+ resource_path = abspath(join(dirname(__file__), '..', 'flask'))
36
+ app = Flask(__name__, static_url_path='',
37
+ static_folder=join(resource_path, 'static'),
38
+ template_folder=join(resource_path, 'templates'))
39
+ app.wsgi_app = ProxyFix(app.wsgi_app, x_port=1)
40
+ app.after_request(self.__after_request)
41
+
42
+ CORS(app, resources={r'/api/*': {'supports_credentials': True, 'expose_headers': [
43
+ 'Content-Type',
44
+ 'Authorization',
45
+ 'X-Requested-With',
46
+ 'Accept',
47
+ 'Origin',
48
+ 'Access-Control-Request-Method',
49
+ 'Access-Control-Request-Headers',
50
+ 'Content-Disposition',
51
+ ], 'max_age': 600}})
52
+
53
+ for ex in default_exceptions:
54
+ app.register_error_handler(ex, self.__handle_error)
55
+
56
+ app.route('/api/models')(self.list_models)
57
+ app.route('/api/conversations')(self.list_conversations)
58
+ app.route('/api/conversations', methods=['DELETE'])(self.clear_conversations)
59
+ app.route('/api/conversation/<conversation_id>')(self.get_conversation)
60
+ app.route('/api/conversation/<conversation_id>', methods=['DELETE'])(self.del_conversation)
61
+ app.route('/api/conversation/<conversation_id>', methods=['PATCH'])(self.set_conversation_title)
62
+ app.route('/api/conversation/gen_title/<conversation_id>', methods=['POST'])(self.gen_conversation_title)
63
+ app.route('/api/conversation/talk', methods=['POST'])(self.talk)
64
+ app.route('/api/conversation/regenerate', methods=['POST'])(self.regenerate)
65
+ app.route('/api/conversation/goon', methods=['POST'])(self.goon)
66
+
67
+ app.route('/api/auth/session')(self.session)
68
+ app.route('/api/accounts/check')(self.check)
69
+ app.route('/_next/data/olf4sv64FWIcQ_zCGl90t/chat.json')(self.chat_info)
70
+
71
+ app.route('/')(self.chat)
72
+ app.route('/chat')(self.chat)
73
+ app.route('/chat/<conversation_id>')(self.chat)
74
+
75
+ if not self.debug:
76
+ self.logger.warning('Serving on http://{}:{}'.format(host, port))
77
+
78
+ WSGIRequestHandler.protocol_version = 'HTTP/1.1'
79
+ serve(app, host=host, port=port, ident=None, threads=threads)
80
+
81
+ @staticmethod
82
+ def __after_request(resp):
83
+ resp.headers['X-Server'] = 'pandora/{}'.format(__version__)
84
+
85
+ return resp
86
+
87
+ def __parse_bind(self, bind_str):
88
+ sections = bind_str.split(':', 2)
89
+ if len(sections) < 2:
90
+ try:
91
+ port = int(sections[0])
92
+ return self.__default_ip, port
93
+ except ValueError:
94
+ return sections[0], self.__default_port
95
+
96
+ return sections[0], int(sections[1])
97
+
98
+ def __handle_error(self, e):
99
+ self.logger.error(e)
100
+
101
+ return make_response(jsonify({
102
+ 'code': e.code,
103
+ 'message': str(e.original_exception if self.debug and hasattr(e, 'original_exception') else e.name)
104
+ }), 500)
105
+
106
+ @staticmethod
107
+ def __set_cookie(resp, token_key, max_age):
108
+ resp.set_cookie('token-key', token_key, max_age=max_age, path='/', domain=None, httponly=True, samesite='Lax')
109
+
110
+ @staticmethod
111
+ def __get_token_key():
112
+ return request.headers.get('X-Use-Token', request.cookies.get('token-key'))
113
+
114
+ def chat(self, conversation_id=None):
115
+ query = {'chatId': [conversation_id]} if conversation_id else {}
116
+
117
+ token_key = request.args.get('token')
118
+ rendered = render_template('chat.html', pandora_base=request.url_root.strip('/'), query=query)
119
+ resp = make_response(rendered)
120
+
121
+ if token_key:
122
+ self.__set_cookie(resp, token_key, timedelta(days=30))
123
+
124
+ return resp
125
+
126
+ @staticmethod
127
+ def session():
128
+ ret = {
129
+ 'user': {
130
+ 'id': 'user-000000000000000000000000',
131
+ 'name': 'admin@openai.com',
132
+ 'email': 'admin@openai.com',
133
+ 'image': None,
134
+ 'picture': None,
135
+ 'groups': []
136
+ },
137
+ 'expires': '2089-08-08T23:59:59.999Z',
138
+ 'accessToken': 'secret',
139
+ }
140
+
141
+ return jsonify(ret)
142
+
143
+ @staticmethod
144
+ def chat_info():
145
+ ret = {
146
+ 'pageProps': {
147
+ 'user': {
148
+ 'id': 'user-000000000000000000000000',
149
+ 'name': 'admin@openai.com',
150
+ 'email': 'admin@openai.com',
151
+ 'image': None,
152
+ 'picture': None,
153
+ 'groups': []
154
+ },
155
+ 'serviceStatus': {},
156
+ 'userCountry': 'US',
157
+ 'geoOk': True,
158
+ 'serviceAnnouncement': {
159
+ 'paid': {},
160
+ 'public': {}
161
+ },
162
+ 'isUserInCanPayGroup': True
163
+ },
164
+ '__N_SSP': True
165
+ }
166
+
167
+ return jsonify(ret)
168
+
169
+ @staticmethod
170
+ def check():
171
+ ret = {
172
+ 'account_plan': {
173
+ 'is_paid_subscription_active': True,
174
+ 'subscription_plan': 'chatgptplusplan',
175
+ 'account_user_role': 'account-owner',
176
+ 'was_paid_customer': True,
177
+ 'has_customer_object': True,
178
+ 'subscription_expires_at_timestamp': 3774355199
179
+ },
180
+ 'user_country': 'US',
181
+ 'features': [
182
+ 'model_switcher',
183
+ 'dfw_message_feedback',
184
+ 'dfw_inline_message_regen_comparison',
185
+ 'model_preview',
186
+ 'system_message',
187
+ 'can_continue',
188
+ ],
189
+ }
190
+
191
+ return jsonify(ret)
192
+
193
+ def list_models(self):
194
+ return self.__proxy_result(self.chatgpt.list_models(True, self.__get_token_key()))
195
+
196
+ def list_conversations(self):
197
+ offset = request.args.get('offset', '0')
198
+ limit = request.args.get('limit', '20')
199
+
200
+ return self.__proxy_result(self.chatgpt.list_conversations(offset, limit, True, self.__get_token_key()))
201
+
202
+ def get_conversation(self, conversation_id):
203
+ return self.__proxy_result(self.chatgpt.get_conversation(conversation_id, True, self.__get_token_key()))
204
+
205
+ def del_conversation(self, conversation_id):
206
+ return self.__proxy_result(self.chatgpt.del_conversation(conversation_id, True, self.__get_token_key()))
207
+
208
+ def clear_conversations(self):
209
+ return self.__proxy_result(self.chatgpt.clear_conversations(True, self.__get_token_key()))
210
+
211
+ def set_conversation_title(self, conversation_id):
212
+ title = request.json['title']
213
+
214
+ return self.__proxy_result(
215
+ self.chatgpt.set_conversation_title(conversation_id, title, True, self.__get_token_key()))
216
+
217
+ def gen_conversation_title(self, conversation_id):
218
+ payload = request.json
219
+ model = payload['model']
220
+ message_id = payload['message_id']
221
+
222
+ return self.__proxy_result(
223
+ self.chatgpt.gen_conversation_title(conversation_id, model, message_id, True, self.__get_token_key()))
224
+
225
+ def talk(self):
226
+ payload = request.json
227
+ prompt = payload['prompt']
228
+ model = payload['model']
229
+ message_id = payload['message_id']
230
+ parent_message_id = payload['parent_message_id']
231
+ conversation_id = payload.get('conversation_id')
232
+ stream = payload.get('stream', True)
233
+
234
+ return self.__process_stream(
235
+ *self.chatgpt.talk(prompt, model, message_id, parent_message_id, conversation_id, stream,
236
+ self.__get_token_key()), stream)
237
+
238
+ def goon(self):
239
+ payload = request.json
240
+ model = payload['model']
241
+ parent_message_id = payload['parent_message_id']
242
+ conversation_id = payload.get('conversation_id')
243
+ stream = payload.get('stream', True)
244
+
245
+ return self.__process_stream(
246
+ *self.chatgpt.goon(model, parent_message_id, conversation_id, stream, self.__get_token_key()), stream)
247
+
248
+ def regenerate(self):
249
+ payload = request.json
250
+
251
+ conversation_id = payload.get('conversation_id')
252
+ if not conversation_id:
253
+ return self.talk()
254
+
255
+ prompt = payload['prompt']
256
+ model = payload['model']
257
+ message_id = payload['message_id']
258
+ parent_message_id = payload['parent_message_id']
259
+ stream = payload.get('stream', True)
260
+
261
+ return self.__process_stream(
262
+ *self.chatgpt.regenerate_reply(prompt, model, conversation_id, message_id, parent_message_id, stream,
263
+ self.__get_token_key()), stream)
264
+
265
+ @staticmethod
266
+ def __process_stream(status, headers, generator, stream):
267
+ if stream:
268
+ return Response(API.wrap_stream_out(generator, status), mimetype=headers['Content-Type'], status=status)
269
+
270
+ last_json = None
271
+ for json in generator:
272
+ last_json = json
273
+
274
+ return make_response(last_json, status)
275
+
276
+ @staticmethod
277
+ def __proxy_result(remote_resp):
278
+ resp = make_response(remote_resp.text)
279
+ resp.content_type = remote_resp.headers['Content-Type']
280
+ resp.status_code = remote_resp.status_code
281
+
282
+ return resp
src/pandora/cloud_launcher.py ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+
3
+ import argparse
4
+
5
+ from loguru import logger
6
+
7
+ from . import __version__
8
+ from .exts.hooks import hook_except_handle
9
+ from .openai.utils import Console
10
+
11
+ __show_verbose = False
12
+
13
+
14
+ def main():
15
+ global __show_verbose
16
+
17
+ Console.debug_b(
18
+ '''
19
+ Pandora-Cloud - A web interface to ChatGPT
20
+ Github: https://github.com/pengzhile/pandora
21
+ Version: {}, Mode: cloud, Engine: free
22
+ '''.format(__version__)
23
+ )
24
+
25
+ parser = argparse.ArgumentParser()
26
+ parser.add_argument(
27
+ '-p',
28
+ '--proxy',
29
+ help='Use a proxy. Format: protocol://user:pass@ip:port',
30
+ required=False,
31
+ type=str,
32
+ default=None,
33
+ )
34
+ parser.add_argument(
35
+ '-s',
36
+ '--server',
37
+ help='Specific server bind. Format: ip:port, default: 127.0.0.1:8018',
38
+ required=False,
39
+ type=str,
40
+ default='127.0.0.1:8018',
41
+ )
42
+ parser.add_argument(
43
+ '--threads',
44
+ help='Define the number of server workers, default: 4',
45
+ required=False,
46
+ type=int,
47
+ default=4,
48
+ )
49
+ parser.add_argument(
50
+ '-l',
51
+ '--local',
52
+ help='Login locally. Pay attention to the risk control of the login ip!',
53
+ action='store_true',
54
+ )
55
+ parser.add_argument(
56
+ '-v',
57
+ '--verbose',
58
+ help='Show exception traceback.',
59
+ action='store_true',
60
+ )
61
+ args, _ = parser.parse_known_args()
62
+ __show_verbose = args.verbose
63
+
64
+ try:
65
+ from pandora_cloud.server import ChatBot as CloudServer
66
+
67
+ return CloudServer(args.proxy, args.verbose, login_local=args.local).run(args.server, args.threads)
68
+ except (ImportError, ModuleNotFoundError):
69
+ Console.error_bh('### You need `pip install Pandora-ChatGPT[cloud]` to support cloud mode.')
70
+
71
+
72
+ def run():
73
+ hook_except_handle()
74
+
75
+ try:
76
+ main()
77
+ except Exception as e:
78
+ Console.error_bh('### Error occurred: ' + str(e))
79
+
80
+ if __show_verbose:
81
+ logger.exception('Exception occurred.')
src/pandora/exts/__init__.py ADDED
@@ -0,0 +1 @@
 
 
1
+ # -*- coding: utf-8 -*-
src/pandora/exts/config.py ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+
3
+ from datetime import datetime, timedelta
4
+ from os import getenv
5
+ from os.path import join
6
+
7
+ from appdirs import user_config_dir
8
+
9
+ USER_CONFIG_DIR = getenv('USER_CONFIG_DIR', user_config_dir('Pandora-ChatGPT'))
10
+ DATABASE_URI = getenv('DATABASE_URI',
11
+ 'sqlite:///{}?check_same_thread=False'.format(join(USER_CONFIG_DIR, 'pandora-chatgpt.db')))
12
+
13
+
14
+ def default_api_prefix():
15
+ return 'https://ai-{}.fakeopen.com'.format((datetime.now() - timedelta(days=1)).strftime('%Y%m%d'))
src/pandora/exts/hooks.py ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+
3
+ import logging
4
+ import sys
5
+
6
+ from loguru import logger
7
+
8
+
9
+ def __exception_handle(e_type, e_value, e_traceback):
10
+ if issubclass(e_type, KeyboardInterrupt):
11
+ print('\nBye...')
12
+ sys.exit(0)
13
+
14
+ sys.__excepthook__(e_type, e_value, e_traceback)
15
+
16
+
17
+ class __InterceptHandler(logging.Handler):
18
+ def emit(self, record):
19
+ try:
20
+ level = logger.level(record.levelname).name
21
+ except ValueError:
22
+ level = record.levelno
23
+
24
+ frame, depth = logging.currentframe(), 2
25
+ while frame.f_code.co_filename == logging.__file__:
26
+ frame = frame.f_back
27
+ depth += 1
28
+
29
+ logger.opt(depth=depth, exception=record.exc_info).log(
30
+ level, record.getMessage()
31
+ )
32
+
33
+
34
+ def hook_except_handle():
35
+ sys.excepthook = __exception_handle
36
+
37
+
38
+ def hook_logging(**kwargs):
39
+ logging.basicConfig(handlers=[__InterceptHandler()], **kwargs)
src/pandora/exts/token.py ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+
3
+ from jwt import decode
4
+
5
+ from ..openai.utils import Console
6
+
7
+ __public_key = b'-----BEGIN PUBLIC KEY-----\n' \
8
+ b'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA27rOErDOPvPc3mOADYtQ\n' \
9
+ b'BeenQm5NS5VHVaoO/Zmgsf1M0Wa/2WgLm9jX65Ru/K8Az2f4MOdpBxxLL686ZS+K\n' \
10
+ b'7eJC/oOnrxCRzFYBqQbYo+JMeqNkrCn34yed4XkX4ttoHi7MwCEpVfb05Qf/ZAmN\n' \
11
+ b'I1XjecFYTyZQFrd9LjkX6lr05zY6aM/+MCBNeBWp35pLLKhiq9AieB1wbDPcGnqx\n' \
12
+ b'lXuU/bLgIyqUltqLkr9JHsf/2T4VrXXNyNeQyBq5wjYlRkpBQDDDNOcdGpx1buRr\n' \
13
+ b'Z2hFyYuXDRrMcR6BQGC0ur9hI5obRYlchDFhlb0ElsJ2bshDDGRk5k3doHqbhj2I\n' \
14
+ b'gQIDAQAB\n' \
15
+ b'-----END PUBLIC KEY-----'
16
+
17
+
18
+ def check_access_token(access_token, api=False):
19
+ if access_token.startswith('fk-'):
20
+ return True
21
+
22
+ if api and (access_token.startswith('sk-') or access_token.startswith('pk-')):
23
+ return True
24
+
25
+ payload = (decode(access_token, key=__public_key, algorithms='RS256', audience=[
26
+ "https://api.openai.com/v1",
27
+ "https://openai.openai.auth0app.com/userinfo"
28
+ ], issuer='https://auth0.openai.com/'))
29
+
30
+ if 'scope' not in payload:
31
+ raise Exception('miss scope')
32
+
33
+ scope = payload['scope']
34
+ if 'model.read' not in scope or 'model.request' not in scope:
35
+ raise Exception('invalid scope')
36
+
37
+ if 'https://api.openai.com/auth' not in payload or 'https://api.openai.com/profile' not in payload:
38
+ raise Exception('belonging to an unregistered user.')
39
+
40
+ return payload
41
+
42
+
43
+ def check_access_token_out(access_token, api=False):
44
+ try:
45
+ return check_access_token(access_token, api)
46
+ except Exception as e:
47
+ Console.error('### Invalid access token: {}'.format(str(e)))
48
+ return False
src/pandora/flask/static/_next/static/chunks/113-23682f80a24dd00d.js ADDED
The diff for this file is too large to render. See raw diff
 
src/pandora/flask/static/_next/static/chunks/14-0cb0d20affbd720d.js ADDED
@@ -0,0 +1 @@
 
 
1
+ "use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[14],{77064:function(e,n,t){t.d(n,{$:function(){return m},u:function(){return p}});var r=t(31501),a=t(61079),s=t(14806),o=t(35250),i=t(19841),l=t(70079),u=t(65921),c=t(34303);function d(){var e=(0,s.Z)(['\nbefore:absolute before:w-2 before:h-2 before:visible before:content-[""] before:bg-gray-100 before:border-b before:border-r before:border-black/10\n',"\n","\n"]);return d=function(){return e},e}function f(){var e=(0,s.Z)(["absolute w-2 h-2 -z-10"]);return f=function(){return e},e}function p(e){var n=e.text,t=e.children;return(0,o.jsx)("div",{className:"tooltip-label flex items-center whitespace-pre-wrap py-1 px-2 text-center text-sm font-medium normal-case text-gray-700","data-content":n,children:t})}var m=function(e){var n=e.children,t=e.label,s=e.enterDelay,c=void 0===s?0:s,d=e.leaveDelay,f=void 0===d?50:d,p=e.placement,m=void 0===p?"bottom":p,v=e.offset,h=e.withArrow,x=e.interactive,g=void 0!==x&&x,y=e.wide,w=(0,l.useState)(!1),j=w[0],P=w[1],k=(0,l.useState)(null),Z=k[0],S=k[1],C=(0,l.useState)(null),N=C[0],_=C[1],A=(0,l.useState)(null),T=A[0],R=A[1],E=(0,u.D)(Z,N,{placement:m,modifiers:[{name:"offset",options:{offset:void 0===v?[0,14]:v}},{name:"arrow",options:{element:T}},]}),U=E.styles,F=E.attributes,M=E.forceUpdate,O=(0,l.useRef)(),L=(0,l.useRef)(),D=(0,l.useCallback)(function(){null==M||M(),L.current&&clearTimeout(L.current),O.current=setTimeout(function(){return P(!0)},c)},[c,M]),G=(0,l.useCallback)(function(){O.current&&clearTimeout(O.current),L.current=setTimeout(function(){return P(!1)},f)},[f]);return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)("span",{ref:S,onMouseEnter:D,onMouseLeave:G,children:n}),(0,o.jsxs)("div",(0,a.Z)((0,r.Z)({ref:_,style:U.popper},F.popper),{className:(0,i.Z)("relative z-10 m-0 rounded p-1 transition-opacity",j?"opacity-100":"pointer-events-none opacity-0",void 0!==y&&y?"max-w-sm":"max-w-xs","border border-black/10 bg-gray-100"),onMouseEnter:g?D:void 0,onMouseLeave:g?G:void 0,children:[t,(void 0===h||h)&&(0,o.jsx)(b,{ref:R,$placement:m})]}))]})},v=c.Z.div(d(),function(e){return"bottom"===e.$placement&&"-top-1 left-1/2 -translate-x-[50%] rotate-[225deg]"},function(e){return"top"===e.$placement&&"before:top-0 before:rotate-45"}),b=(0,c.Z)(v)(f())},86885:function(e,n,t){t.d(n,{Z:function(){return h}});var r=t(61706),a=t(45813),s=t(35250),o=t(61432),i=t(70079),l=t(1454),u=t(12762),c=t(98943),d=t(33264),f=t(66285),p=t(74516),m=t(35e3),v=t(69858),b=t(77507);function h(e){var n=e.isOpen,t=e.onClose,h=(0,i.useRef)(null),x=(0,f.hz)(),g=(0,u.WS)(),y=(0,i.useState)(!1),w=y[0],j=y[1],P=(0,o.useRouter)(),k=(0,i.useCallback)(function(){g(c.s6.closeAccountPaymentModal),t()},[t,g]),Z=(0,i.useCallback)((0,r.Z)(function(){var e;return(0,a.__generator)(this,function(n){switch(n.label){case 0:j(!0),g(c.s6.clickAccountPaymentCheckout),n.label=1;case 1:return n.trys.push([1,3,4,5]),[4,d.ZP.submitCheckoutForm()];case 2:return e=n.sent(),P.push(e.url),[3,5];case 3:return n.sent(),p.m.warning("The payments page encountered an error. Please try again. If the problem continues, please email support@openai.com.",{hasCloseButton:!0}),[3,5];case 4:return j(!1),[7];case 5:return[2]}})}),[P,g,j]),S=(0,i.useCallback)((0,r.Z)(function(){var e;return(0,a.__generator)(this,function(n){switch(n.label){case 0:j(!0),g(c.s6.clickAccountCustomerPortal),n.label=1;case 1:return n.trys.push([1,3,4,5]),[4,d.ZP.fetchCustomerPortalUrl()];case 2:return e=n.sent(),P.push(e.url),[3,5];case 3:return n.sent(),p.m.warning("The account management page encountered an error. Please try again. If the problem continues, please email support@openai.com.",{hasCloseButton:!0}),[3,5];case 4:return j(!1),[7];case 5:return[2]}})}),[P,g,j]),C=(0,f.mA)(function(e){var n;return null===(n=e.accountPlan)||void 0===n?void 0:n.hasCustomerObject}),N=x.has("disable_upgrade_ui");return(0,s.jsxs)(m.x,{isOpen:n,onClose:t,focusRef:h,children:[(0,s.jsxs)("div",{className:"flex w-full flex-row items-center justify-between border-b py-3 px-4 dark:border-gray-700",children:[(0,s.jsx)("span",{className:"text-base font-semibold sm:text-base",children:"Your Account"}),(0,s.jsx)("button",{className:"text-gray-700 opacity-50 transition hover:opacity-75 dark:text-white",onClick:k,children:(0,s.jsx)(l.q5L,{className:"h-6 w-6"})})]}),(0,s.jsxs)("div",{className:"grid sm:grid-cols-2",children:[(0,s.jsx)("div",{className:"relative order-2 col-span-1 border-t border-r-0 dark:border-gray-700 sm:order-1 sm:border-t-0 sm:border-r",children:(0,s.jsx)(v.Oi,{rowElements:[(0,s.jsx)(v.Cu,{text:"Free Plan"},"row-free-plan-name"),(0,s.jsx)(v.hi,{variant:"disabled",disabled:!0,text:b.S.free.callToAction.active},"row-free-plan-button"),(0,s.jsx)(v.G,{variant:"secondary",text:b.S.free.demandAccess},"row-free-plan-demand"),(0,s.jsx)(v.G,{variant:"secondary",text:b.S.free.responseSpeed},"row-free-plan-speed"),(0,s.jsx)(v.G,{className:"sm:pb-2",variant:"secondary",text:b.S.free.modelFeatures},"row-free-plan-updates"),]})}),(0,s.jsx)("div",{className:"relative order-1 col-span-1 sm:order-2",children:(0,s.jsx)(v.Oi,{rowElements:[(0,s.jsx)(v.Cu,{text:b.S.plus.name,children:(0,s.jsx)("span",{className:"font-semibold text-gray-500",children:b.S.plus.costInDollars})},"row-plus-plan-title"),(0,s.jsx)(v.hi,{variant:"primary",disabledText:N?"Due to high demand, we've temporarily paused upgrades.":"",disabled:w,isLoading:w,ref:h,onClick:Z,text:b.S.plus.callToAction.inactivePayment},"row-plus-plan-button"),(0,s.jsx)(v.G,{variant:"primary",text:b.S.plus.demandAccess},"row-plus-plan-demand"),(0,s.jsx)(v.G,{variant:"primary",text:b.S.plus.responseSpeed},"row-plus-plan-speed"),(0,s.jsx)(v.G,{className:"sm:pb-2",variant:"primary",text:b.S.plus.modelFeatures},"row-plus-plan-updates"),C&&(0,s.jsx)(v.nR,{className:"sm:pb-1",isLoading:w,text:b.S.manageSubscription.callToAction,onClick:S},"row-plus-plan-manage"),]})})]})]})}},35e3:function(e,n,t){t.d(n,{x:function(){return l}});var r=t(14806),a=t(35250),s=t(34303),o=t(73925);function i(){var e=(0,r.Z)(["flex grow items-center justify-center bg-white dark:bg-gray-900 rounded-md flex flex-col items-start overflow-hidden border shadow-md dark:border-gray-700"]);return i=function(){return e},e}var l=function(e){var n=e.children,t=e.isOpen,r=e.onClose,s=e.focusRef;return(0,a.jsx)(o.Z,{size:"fullscreen",isOpen:t,onModalClose:r,type:"success",title:"",className:"bg-transparent dark:bg-transparent",initialFocusRef:s,children:(0,a.jsx)("div",{className:"flex h-full flex-col items-center justify-start",children:(0,a.jsx)("div",{className:"relative",children:(0,a.jsx)(u,{children:n})})})})},u=s.Z.div(i())},69858:function(e,n,t){t.d(n,{Cu:function(){return b},G:function(){return g},Oi:function(){return v},hi:function(){return x},nR:function(){return y}});var r=t(14806),a=t(35250),s=t(19841),o=t(70079),i=t(1454),l=t(34303),u=t(39690),c=t(79876),d=t(77064);function f(){var e=(0,r.Z)(["p-4 flex flex-col gap-3 bg-white z-20 relative dark:bg-gray-900"]);return f=function(){return e},e}function p(){var e=(0,r.Z)(["gap-2 flex flex-row justify-start items-center text-sm"]);return p=function(){return e},e}function m(){var e=(0,r.Z)(["text-xl font-semibold justify-between items-center flex"]);return m=function(){return e},e}var v=function(e){var n=e.rowElements;return(0,a.jsx)(w,{children:n.map(function(e){return e})})},b=function(e){var n=e.className,t=e.text,r=e.children;return(0,a.jsxs)(P,{className:n,children:[(0,a.jsx)("span",{children:t}),r]})},h={"primary-disabled":"border-none bg-gray-200 py-3 font-semibold hover:bg-gray-200",primary:"border-none py-3 font-semibold",disabled:"dark:text-gray-white border-none bg-gray-300 py-3 font-semibold text-gray-800 hover:bg-gray-300 dark:bg-gray-500 dark:opacity-100"},x=(0,o.forwardRef)(function(e,n){var t=e.isLoading,r=void 0!==t&&t,o=e.disabled,l=e.onClick,f=e.variant,p=void 0===f?"primary":f,m=e.text,v=e.disabledText;return v?(0,a.jsx)("div",{className:"relative",children:(0,a.jsx)(d.$,{placement:"bottom",offset:[0,20],label:(0,a.jsx)(d.u,{children:v}),children:(0,a.jsxs)(u.z,{ref:n,as:"button",color:"disabled",className:(0,s.Z)("w-full",h[p]),children:[m,r&&(0,a.jsx)(c.ZP,{className:"animate-spin",icon:i.dAq})]})})}):(0,a.jsxs)(u.z,{disabled:void 0!==o&&o,onClick:l,openNewTab:!0,ref:n,as:"button",className:(0,s.Z)(h[p]),children:[(0,a.jsx)("span",{className:(0,s.Z)("inline-block",{"text-gray-700":"primary-disabled"===p,"text-white":"primary"===p}),children:m}),r&&(0,a.jsx)(c.ZP,{className:"animate-spin",icon:i.dAq})]})});x.displayName="PricingPlanButton";var g=function(e){var n=e.variant,t=void 0===n?"primary":n,r=e.className,o=e.text;return(0,a.jsxs)(j,{className:r,children:[(0,a.jsx)(c.ZP,{icon:i._rq,className:(0,s.Z)("h-5 w-5",{"text-green-700":"primary"==t,"text-gray-400":"secondary"==t})}),(0,a.jsx)("span",{children:o})]})},y=function(e){var n=e.className,t=e.text,r=e.isLoading,s=e.onClick;return(0,a.jsx)(j,{className:n,children:(0,a.jsxs)("button",{onClick:s,className:"flex flex-row items-center space-x-1 underline",children:[(0,a.jsx)("span",{children:t}),r&&(0,a.jsx)(c.ZP,{className:"animate-spin",icon:i.dAq})]})})},w=l.Z.div(f()),j=l.Z.div(p()),P=l.Z.div(m())},77507:function(e,n,t){t.d(n,{S:function(){return r}});var r={free:{name:"Free Plan",callToAction:{active:"Your Current Plan",inactive:"Your Current Plan"},costInDollars:"",demandAccess:"Available when demand is low",responseSpeed:"Standard response speed",modelFeatures:"Regular model updates"},plus:{name:"ChatGPT Plus",callToAction:{active:"Your current plan",inactive:"I'm Interested",inactivePayment:"Upgrade plan"},costInDollars:"USD $20/mo",demandAccess:"Available even when demand is high",responseSpeed:"Faster response speed",modelFeatures:"Priority access to new features"},manageSubscription:{callToAction:"Manage my subscription"}}},85087:function(e,n,t){t.d(n,{Z:function(){return u}});var r=t(87762),a=t(70079),s=t(82018),o=t(33264),i=t(66285),l=t(27252);function u(){var e=(0,s.kP)(),n=e.session,t=e.loading,u=(0,i.mA)(function(e){return e.hasBeenSet}),c=(0,l.g)(function(e){return e.updateFlagValue}),d=(0,r.a)(["account-status"],function(){return o.ZP.getAccountStatus(null==n?void 0:n.accessToken)},{enabled:!t&&Boolean(null==n?void 0:n.accessToken),onError:function(){console.error("Unable to load account")},onSuccess:function(e){var n;m(e),c("highlightPlusUpgrade",!(null===(n=e.account_plan)||void 0===n?void 0:n.is_paid_subscription_active))}}),f=d.data,p=d.isLoading,m=(0,i.mA)(function(e){return{accountPlan:e.accountPlan,updateAccountPlanWithResponse:e.updateAccountPlanWithResponse}}).updateAccountPlanWithResponse;return(0,a.useMemo)(function(){return{accountStatusResponse:f,isLoading:!u&&p}},[f,u,p])}},49690:function(e,n,t){t.d(n,{Z:function(){return c}});var r=t(27215),a=t(70079),s=t(12762),o=t(98943),i=t(82018),l=t(33264),u=t(66285);function c(e,n,t,c,d){var f=!(arguments.length>5)||void 0===arguments[5]||arguments[5],p=(0,u.mA)(function(e){return e.features}),m=(0,i.kP)().session,v=(0,s.WS)(t);(0,a.useEffect)(function(){f&&(p&&n.id&&s.ZP.setUser(n,p,c,d),v(o.s6.pageLoad))},[p,n.id,f]),(0,a.useEffect)(function(){if(null==m?void 0:m.accessToken)l.ZP.setAccessToken(m.accessToken);else if(m&&!(null==m?void 0:m.error)){var e;null===r.default||void 0===r.default||r.default.captureMessage("Missing access token for User: ".concat(null==m?void 0:null===(e=m.user)||void 0===e?void 0:e.id," (").concat(null==m?void 0:m.accessToken,")"))}(null==m?void 0:m.error)==="RefreshAccessTokenError"&&(null===r.default||void 0===r.default||r.default.captureException(m.error),window._oaiHandleSessionExpired("page load",m.error))},[m,n.id]),(0,a.useEffect)(function(){document.title=e},[e])}},66285:function(e,n,t){t.d(n,{hz:function(){return c},mA:function(){return l},nR:function(){return u}});var r=t(31501),a=t(61079),s=t(70079),o=t(59268),i={lastUpdated:Date.now(),hasBeenSet:!1},l=(0,o.ZP)()(function(e){return(0,a.Z)((0,r.Z)({},i),{updateAccountPlanWithResponse:function(n){var t,r,a,s,o;e({accountPlan:{hasPaidSubscription:(null==n?void 0:null===(t=n.account_plan)||void 0===t?void 0:t.is_paid_subscription_active)||!1,subscriptionPlan:(null==n?void 0:null===(r=n.account_plan)||void 0===r?void 0:r.subscription_plan)||"chatgptplusfreeplan",accountUserRole:(null==n?void 0:null===(a=n.account_plan)||void 0===a?void 0:a.account_user_role)||"account-owner",wasPaidCustomer:(null==n?void 0:null===(s=n.account_plan)||void 0===s?void 0:s.was_paid_customer)||!1,hasCustomerObject:(null==n?void 0:null===(o=n.account_plan)||void 0===o?void 0:o.has_customer_object)||!1},features:(null==n?void 0:n.features)||[],hasBeenSet:!0})}})}),u=function(){return l(function(e){var n;return null===(n=e.accountPlan)||void 0===n?void 0:n.hasPaidSubscription})},c=function(){var e=l(function(e){return e.features});return(0,s.useMemo)(function(){return new Set(e)},[e])}},27252:function(e,n,t){t.d(n,{g:function(){return l}});var r=t(33861),a=t(31501),s=t(61079),o=t(59268),i={flags:{isUserInCanPayGroup:!1,highlightPlusUpgrade:!1,failwhaleBypassEnabled:!1}},l=(0,o.ZP)()(function(e,n){return(0,s.Z)((0,a.Z)({},i),{updateFlagValue:function(t,o){var i=n().flags;e({flags:(0,s.Z)((0,a.Z)({},i),(0,r.Z)({},t,o))})}})})},82018:function(e,n,t){t.d(n,{kP:function(){return f},w7:function(){return u}});var r=t(61706),a=t(31501),s=t(45813),o=t(87762),i=t(44928),l=t(61432);function u(e){(0,i.signOut)((0,a.Z)({callbackUrl:window.location.origin+"/api/auth/logout"},e))}function c(){return d.apply(this,arguments)}function d(){return(d=(0,r.Z)(function(){var e,n;return(0,s.__generator)(this,function(e){switch(e.label){case 0:return[4,fetch("/api/auth/session")];case 1:return[4,e.sent().json()];case 2:if(Object.keys(n=e.sent()).length)return[2,n];return[2,null]}})})).apply(this,arguments)}function f(e){var n=e||{},t=n.required,r=n.redirectTo,a=n.queryConfig,s=(0,l.useRouter)(),i=(0,o.a)(["session"],c,{onSettled:function(e,n){(null==a?void 0:a.onSettled)&&(null==a||a.onSettled(e,n)),!e&&t&&s.push(r)}});return{session:(null==i?void 0:i.data)||null,loading:(null==i?void 0:i.status)==="loading"}}}}]);
src/pandora/flask/static/_next/static/chunks/174-bd28069f281ef76f.js ADDED
@@ -0,0 +1 @@
 
 
1
+ (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[174],{63561:function(e,t){"use strict";t.Z=function(e,t,i){return t in e?Object.defineProperty(e,t,{value:i,enumerable:!0,configurable:!0,writable:!0}):e[t]=i,e}},68561:function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=i(63561).Z,o=i(95781).Z,a=i(89478).Z;Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e){var t,i,l=e.src,c=e.sizes,h=e.unoptimized,p=void 0!==h&&h,w=e.priority,k=void 0!==w&&w,E=e.loading,I=e.lazyRoot,R=e.lazyBoundary,_=e.className,L=e.quality,q=e.width,C=e.height,O=e.style,N=e.objectFit,P=e.objectPosition,W=e.onLoadingComplete,B=e.placeholder,M=void 0===B?"empty":B,Z=e.blurDataURL,D=s(e,["src","sizes","unoptimized","priority","loading","lazyRoot","lazyBoundary","className","quality","width","height","style","objectFit","objectPosition","onLoadingComplete","placeholder","blurDataURL"]),U=d.useContext(m.ImageConfigContext),V=d.useMemo(function(){var e=y||U||f.imageConfigDefault,t=a(e.deviceSizes).concat(a(e.imageSizes)).sort(function(e,t){return e-t}),i=e.deviceSizes.sort(function(e,t){return e-t});return r({},e,{allSizes:t,deviceSizes:i})},[U]),F=c?"responsive":"intrinsic";"layout"in D&&(D.layout&&(F=D.layout),delete D.layout);var H=x;if("loader"in D){if(D.loader){var G=D.loader;H=function(e){e.config;var t=s(e,["config"]);return G(t)}}delete D.loader}var T="";if(function(e){var t;return"object"==typeof e&&(z(e)||void 0!==e.src)}(l)){var J=z(l)?l.default:l;if(!J.src)throw Error("An object should only be passed to the image component src parameter if it comes from a static image import. It must include src. Received ".concat(JSON.stringify(J)));if(Z=Z||J.blurDataURL,T=J.src,(!F||"fill"!==F)&&(C=C||J.height,q=q||J.width,!J.height||!J.width))throw Error("An object should only be passed to the image component src parameter if it comes from a static image import. It must include height and width. Received ".concat(JSON.stringify(J)))}l="string"==typeof l?l:T;var Q=!k&&("lazy"===E||void 0===E);(l.startsWith("data:")||l.startsWith("blob:"))&&(p=!0,Q=!1),b.has(l)&&(Q=!1),V.unoptimized&&(p=!0);var K=o(d.useState(!1),2),X=K[0],Y=K[1],$=o(g.useIntersection({rootRef:void 0===I?null:I,rootMargin:R||"200px",disabled:!Q}),3),ee=$[0],et=$[1],ei=$[2],en=!Q||et,eo={boxSizing:"border-box",display:"block",overflow:"hidden",width:"initial",height:"initial",background:"none",opacity:1,border:0,margin:0,padding:0},ea={boxSizing:"border-box",display:"block",width:"initial",height:"initial",background:"none",opacity:1,border:0,margin:0,padding:0},er=!1,el=A(q),ec=A(C),es=A(L),ed=Object.assign({},O,{position:"absolute",top:0,left:0,bottom:0,right:0,boxSizing:"border-box",padding:0,border:"none",margin:"auto",display:"block",width:0,height:0,minWidth:"100%",maxWidth:"100%",minHeight:"100%",maxHeight:"100%",objectFit:N,objectPosition:P}),eu="blur"!==M||X?{}:{backgroundSize:N||"cover",backgroundPosition:P||"0% 0%",filter:"blur(20px)",backgroundImage:'url("'.concat(Z,'")')};if("fill"===F)eo.display="block",eo.position="absolute",eo.top=0,eo.left=0,eo.bottom=0,eo.right=0;else if(void 0!==el&&void 0!==ec){var ef=ec/el,eg=isNaN(ef)?"100%":"".concat(100*ef,"%");"responsive"===F?(eo.display="block",eo.position="relative",er=!0,ea.paddingTop=eg):"intrinsic"===F?(eo.display="inline-block",eo.position="relative",eo.maxWidth="100%",er=!0,ea.maxWidth="100%",t="data:image/svg+xml,%3csvg%20xmlns=%27http://www.w3.org/2000/svg%27%20version=%271.1%27%20width=%27".concat(el,"%27%20height=%27").concat(ec,"%27/%3e")):"fixed"===F&&(eo.display="inline-block",eo.position="relative",eo.width=el,eo.height=ec)}var em={src:v,srcSet:void 0,sizes:void 0};en&&(em=S({config:V,src:l,unoptimized:p,layout:F,width:el,quality:es,sizes:c,loader:H}));var eh=l,ep="imagesizes";ep="imageSizes";var ey=(n(i={},"imageSrcSet",em.srcSet),n(i,ep,em.sizes),n(i,"crossOrigin",D.crossOrigin),i),eb=d.default.useLayoutEffect,ev=d.useRef(W),ew=d.useRef(l);d.useEffect(function(){ev.current=W},[W]),eb(function(){ew.current!==l&&(ei(),ew.current=l)},[ei,l]);var ez=r({isLazy:Q,imgAttributes:em,heightInt:ec,widthInt:el,qualityInt:es,layout:F,className:_,imgStyle:ed,blurStyle:eu,loading:E,config:V,unoptimized:p,placeholder:M,loader:H,srcString:eh,onLoadingCompleteRef:ev,setBlurComplete:Y,setIntersection:ee,isVisible:en,noscriptSizes:c},D);return d.default.createElement(d.default.Fragment,null,d.default.createElement("span",{style:eo},er?d.default.createElement("span",{style:ea},t?d.default.createElement("img",{style:{display:"block",maxWidth:"100%",width:"initial",height:"initial",background:"none",opacity:1,border:0,margin:0,padding:0},alt:"","aria-hidden":!0,src:t}):null):null,d.default.createElement(j,Object.assign({},ez))),k?d.default.createElement(u.default,null,d.default.createElement("link",Object.assign({key:"__nimg-"+em.src+em.srcSet+em.sizes,rel:"preload",as:"image",href:em.srcSet?void 0:em.src},ey))):null)};var r=i(17858).Z,l=i(16922).Z,c=i(86905).Z,s=i(31080).Z,d=c(i(70079)),u=l(i(76109)),f=i(60239),g=i(26790),m=i(94136);i(13279);var h=i(5189);function p(e){return"/"===e[0]?e.slice(1):e}var y={deviceSizes:[640,750,828,1080,1200,1920,2048,3840],imageSizes:[16,32,48,64,96,128,256,384],path:"/_next/image",loader:"default",dangerouslyAllowSVG:!1,unoptimized:!1},b=new Set,v="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7",w=new Map([["default",function(e){var t=e.config,i=e.src,n=e.width,o=e.quality;return i.endsWith(".svg")&&!t.dangerouslyAllowSVG?i:"".concat(h.normalizePathTrailingSlash(t.path),"?url=").concat(encodeURIComponent(i),"&w=").concat(n,"&q=").concat(o||75)}],["imgix",function(e){var t=e.config,i=e.src,n=e.width,o=e.quality,a=new URL("".concat(t.path).concat(p(i))),r=a.searchParams;return r.set("auto",r.getAll("auto").join(",")||"format"),r.set("fit",r.get("fit")||"max"),r.set("w",r.get("w")||n.toString()),o&&r.set("q",o.toString()),a.href}],["cloudinary",function(e){var t,i=e.config,n=e.src,o=e.width,a=["f_auto","c_limit","w_"+o,"q_"+(e.quality||"auto")].join(",")+"/";return"".concat(i.path).concat(a).concat(p(n))}],["akamai",function(e){var t=e.config,i=e.src,n=e.width;return"".concat(t.path).concat(p(i),"?imwidth=").concat(n)}],["custom",function(e){var t=e.src;throw Error('Image with src "'.concat(t,'" is missing "loader" prop.')+"\nRead more: https://nextjs.org/docs/messages/next-image-missing-loader")}],]);function z(e){return void 0!==e.default}function S(e){var t=e.config,i=e.src,n=e.unoptimized,o=e.layout,r=e.width,l=e.quality,c=e.sizes,s=e.loader;if(n)return{src:i,srcSet:void 0,sizes:void 0};var d=function(e,t,i,n){var o=e.deviceSizes,r=e.allSizes;if(n&&("fill"===i||"responsive"===i)){for(var l=/(^|\s)(1?\d?\d)vw/g,c=[];s=l.exec(n);s)c.push(parseInt(s[2]));if(c.length){var s,d,u=.01*(d=Math).min.apply(d,a(c));return{widths:r.filter(function(e){return e>=o[0]*u}),kind:"w"}}return{widths:r,kind:"w"}}return"number"!=typeof t||"fill"===i||"responsive"===i?{widths:o,kind:"w"}:{widths:a(new Set([t,2*t].map(function(e){return r.find(function(t){return t>=e})||r[r.length-1]}))),kind:"x"}}(t,r,o,c),u=d.widths,f=d.kind,g=u.length-1;return{sizes:c||"w"!==f?c:"100vw",srcSet:u.map(function(e,n){return"".concat(s({config:t,src:i,quality:l,width:e})," ").concat("w"===f?e:n+1).concat(f)}).join(", "),src:s({config:t,src:i,quality:l,width:u[g]})}}function A(e){return"number"==typeof e?e:"string"==typeof e?parseInt(e,10):void 0}function x(e){var t,i=(null==(t=e.config)?void 0:t.loader)||"default",n=w.get(i);if(n)return n(e);throw Error('Unknown "loader" found in "next.config.js". Expected: '.concat(f.VALID_LOADERS.join(", "),". Received: ").concat(i))}function k(e,t,i,n,o,a){e&&e.src!==v&&e["data-loaded-src"]!==t&&(e["data-loaded-src"]=t,("decode"in e?e.decode():Promise.resolve()).catch(function(){}).then(function(){if(e.parentNode&&(b.add(t),"blur"===n&&a(!0),null==o?void 0:o.current)){var i=e.naturalWidth,r=e.naturalHeight;o.current({naturalWidth:i,naturalHeight:r})}}))}var j=function(e){var t=e.imgAttributes,i=(e.heightInt,e.widthInt),n=e.qualityInt,o=e.layout,a=e.className,l=e.imgStyle,c=e.blurStyle,u=e.isLazy,f=e.placeholder,g=e.loading,m=e.srcString,h=e.config,p=e.unoptimized,y=e.loader,b=e.onLoadingCompleteRef,v=e.setBlurComplete,w=e.setIntersection,z=e.onLoad,A=e.onError,x=(e.isVisible,e.noscriptSizes),j=s(e,["imgAttributes","heightInt","widthInt","qualityInt","layout","className","imgStyle","blurStyle","isLazy","placeholder","loading","srcString","config","unoptimized","loader","onLoadingCompleteRef","setBlurComplete","setIntersection","onLoad","onError","isVisible","noscriptSizes"]);return g=u?"lazy":g,d.default.createElement(d.default.Fragment,null,d.default.createElement("img",Object.assign({},j,t,{decoding:"async","data-nimg":o,className:a,style:r({},l,c),ref:d.useCallback(function(e){w(e),(null==e?void 0:e.complete)&&k(e,m,o,f,b,v)},[w,m,o,f,b,v,]),onLoad:function(e){k(e.currentTarget,m,o,f,b,v),z&&z(e)},onError:function(e){"blur"===f&&v(!0),A&&A(e)}})),(u||"blur"===f)&&d.default.createElement("noscript",null,d.default.createElement("img",Object.assign({},j,S({config:h,src:m,unoptimized:p,layout:o,width:i,quality:n,sizes:x,loader:y}),{decoding:"async","data-nimg":o,style:l,className:a,loading:g}))))};("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},96424:function(e,t,i){e.exports=i(68561)}}]);
src/pandora/flask/static/_next/static/chunks/1f110208-44a6f43ddc5e9011.js ADDED
The diff for this file is too large to render. See raw diff
 
src/pandora/flask/static/_next/static/chunks/264-13e92c51b0315184.js ADDED
@@ -0,0 +1 @@
 
 
1
+ "use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[264],{34388:function(e,t,n){n.d(t,{T:function(){return o}});function o(e){return void 0!==e.userMessage}},33264:function(e,t,n){var o=n(61706),i=n(35025),a=n(9135),s=n(31501),r=n(61079),c=n(42928),h=n(45813),u=n(48879),d=n(44928);n(138);var p=n(34388),l=n(49674),f=window.__pandora_base+"/api",g=["cf-ipcountry"],m=function(){function e(){(0,i.Z)(this,e)}return e.setAccessToken=function(e){this.accessToken=e},e.getAuthHeader=function(e){var t=e||this.accessToken;if(!t)throw console.error("No access token when trying to use AuthHeader"),Error("No access token when trying to use AuthHeader");return{}},e.refreshApiKey=function(){var e=this;if(this.apiKeyRefreshing)return this.apiKeyRefreshing;var t=this;return this.apiKeyRefreshing=(0,o.Z)(function(){var e;return(0,h.__generator)(this,function(n){switch(n.label){case 0:return[4,(0,d.getSession)()];case 1:return(e=n.sent())&&t.setAccessToken(e.accessToken),[2];case 2:throw Error("Cannot refresh access token outside of browser");case 3:return[2]}})})(),setTimeout(function(){e.apiKeyRefreshing=null},6e4),this.apiKeyRefreshing},e.fetch=function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},i=this;return(0,o.Z)(function(){var o,a,c,u,d,p;return(0,h.__generator)(this,function(h){switch(h.label){case 0:return[4,fetch(e,o=(0,s.Z)({credentials:"include"},t))];case 1:if((a=h.sent()).status>=500)throw new l.kb;if(!(a.status>=400))return[3,12];h.label=2;case 2:return h.trys.push([2,4,,5]),[4,a.json()];case 3:return c=(null==(u=h.sent())?void 0:u.detail)||(null==u?void 0:u.error),[3,5];case 4:return d=h.sent(),console.error("Failed to parse error response",d),[3,5];case 5:if(console.error("API error",e,c),!((null==c?void 0:c.code)==="expired_session_key"||(null==c?void 0:c.code)==="token_expired"))return[3,11];h.label=6;case 6:if(h.trys.push([6,9,,10]),n.isRetry)return[3,8];return[4,i.refreshApiKey()];case 7:return h.sent(),[2,i.fetch(e,o,(0,r.Z)((0,s.Z)({},n),{isRetry:!0}))];case 8:return[3,10];case 9:return p=h.sent(),console.error("Failed to refresh expired access token: ".concat(p)),[3,10];case 10:console.error("Refresh access token failed when retrieving",e,c),window._oaiHandleSessionExpired("fetch",JSON.stringify(c)),h.label=11;case 11:if(null==c?void 0:c.type)throw new l.gK((null==c?void 0:c.message)||c,a.status,null==c?void 0:c.code,null==c?void 0:c.type);throw new l.kb;case 12:if(204===a.status)return[2,{}];return[2,a.json()]}})})()},e.getArtifacts=function(){return this.fetch("".concat(f,"/artifacts"),{method:"GET",headers:(0,s.Z)({"Content-Type":"application/json"},this.getAuthHeader())})},e.createArtifact=function(e){return this.fetch("".concat(f,"/artifacts"),{method:"POST",headers:(0,s.Z)({"Content-Type":"application/json"},this.getAuthHeader()),body:JSON.stringify({url:e,contents:"\n"})})},e.upload=function(e,t,n,o){var i=new FormData;return t&&i.append("conversation_id",t),i.append("model",n),i.append("parent_message_id",e),i.append("file",o),this.fetch("".concat(f,"/conversation/upload"),{method:"POST",headers:(0,s.Z)({},this.getAuthHeader()),body:i})},e.fetchFileForDownload=function(e,t){var n=new URLSearchParams({path:t});return fetch("".concat(f,"/conversation/").concat(e,"/download?").concat(n),{method:"GET",headers:(0,s.Z)({},this.getAuthHeader())})},e.checkFile=function(e,t){var n=new URLSearchParams({path:t});return this.fetch("".concat(f,"/conversation/").concat(e,"/check_file?").concat(n),{method:"GET",headers:(0,s.Z)({"Content-Type":"application/json"},this.getAuthHeader())})},e.sendDocument=function(){return this.fetch("".concat(f,"/private"),{method:"GET",headers:{"Content-Type":"application/json"}})},e.getRetrievalResults=function(e){return this.fetch("".concat(f,"/retrieval/public_data"),{method:"POST",headers:(0,s.Z)({"Content-Type":"application/json"},this.getAuthHeader()),body:JSON.stringify({query:e})})},e.getModels=function(e){return this.fetch("".concat(f,"/models"),{method:"GET",headers:(0,s.Z)({"Content-Type":"application/json"},this.getAuthHeader(e))})},e.getConversations=function(e,t,n){var o=new URLSearchParams({offset:e.toString(),limit:t.toString()});return this.fetch("".concat(f,"/conversations?").concat(o),{method:"GET",headers:(0,s.Z)({"Content-Type":"application/json"},this.getAuthHeader(n))})},e.getConversation=function(e,t){return this.fetch("".concat(f,"/conversation/").concat(e),{method:"GET",headers:(0,s.Z)({"Content-Type":"application/json"},this.getAuthHeader(t))})},e.generateTitle=function(e,t,n){return this.fetch("".concat(f,"/conversation/gen_title/").concat(e),{method:"POST",headers:(0,s.Z)({"Content-Type":"application/json"},this.getAuthHeader()),body:JSON.stringify({message_id:t,model:n})})},e.patchConversation=function(e,t){return this.fetch("".concat(f,"/conversation/").concat(e),{method:"PATCH",headers:(0,s.Z)({"Content-Type":"application/json"},this.getAuthHeader()),body:JSON.stringify(t)})},e.deleteConversation=function(e,t){return this.fetch("".concat(f,"/conversation/").concat(e),{method:"DELETE",headers:(0,s.Z)({"Content-Type":"application/json"},this.getAuthHeader()),body:JSON.stringify(t)})},e.deleteConversations=function(){return this.fetch("".concat(f,"/conversations"),{method:"DELETE",headers:(0,s.Z)({"Content-Type":"application/json"},this.getAuthHeader()),body:JSON.stringify({is_visible:!1})})},e.getLoginLink=function(e){return this.fetch("".concat(f,"/bypass/link"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({email:e})})},e.publicApiCompletionStream=function(e,t){var n=this;return(0,o.Z)(function(){var i,r,c,eps;return(0,h.__generator)(this,function(c){return eps={'variant':'regenerate','next':'talk','continue':'goon'},i=new AbortController,r={prompt:e.messages.length>0?e.messages[0]['content']['parts'][0]:'',message_id:e.messages.length>0?e.messages[0]['id']:'',conversation_id:e.threadId,parent_message_id:e.parentMessageId,model:e.model,plugin_ids:e.threadId?void 0:e.enabledPluginIds,timezone_offset_min:new Date().getTimezoneOffset()},(0,u.L)("".concat(window.__pandora_base+"/api","/conversation/",eps[e.completionType]),{method:"POST",credentials:"include",headers:(0,s.Z)({"Content-Type":"application/json"},n.getAuthHeader()),body:JSON.stringify(r),signal:i.signal,openWhenHidden:!0,onopen:function(e){return(0,o.Z)(function(){var t,n,o;return(0,h.__generator)(this,function(i){switch(i.label){case 0:if(t=e.headers.get("content-type")||"",e.ok&&t.includes("text/event-stream"))return[2];if(!t.includes("application/json"))return[3,2];return[4,e.json()];case 1:if(n=i.sent(),console.error(n),o=(null==n?void 0:n.error)||(null==n?void 0:n.detail)){if(e.status>=500)throw new l.kb((null==o?void 0:o.message)||o);throw((null==o?void 0:o.code)==="expired_session_key"||(null==o?void 0:o.code)==="invalid_api_key"||(null==o?void 0:o.code)==="token_expired")&&window._oaiHandleSessionExpired("stream",JSON.stringify(o)),new l.gK((null==o?void 0:o.message)||o,e.status,null==o?void 0:o.code,null==o?void 0:o.type,void 0,null==o?void 0:o.clears_in)}i.label=2;case 2:throw new l.kb}})})()},onmessage:function(e){if("[DONE]"===e.data)i.abort(),t({finish_reason:"stop"});else if("ping"===e.event);else try{var n=JSON.parse(e.data);if(n.error)throw new l.kb(n.error.message);t({message:n.message,threadId:n.conversation_id})}catch(o){if((0,p.T)(o))throw new l.kb(o.message)}},onerror:function(e){throw"Failed to fetch"===e.message&&(e=new l.kb("An error occurred. Either the engine you requested does not exist or there was another issue processing your request. If this issue persists please contact us through our help center at help.openai.com.")),t({err:e}),e}}).catch(function(e){(0,a.Z)(e,l.gK)||(0,a.Z)(e,l.kb)||console.error(e)}),[2,i]})})()},e.runModerationApi=function(e,t,n){return this.fetch("".concat("https://chat.openai.com/backend-api","/moderations"),{method:"POST",headers:(0,s.Z)({"Content-Type":"application/json"},this.getAuthHeader()),body:JSON.stringify({input:e,model:"text-moderation-playground",conversation_id:t,message_id:n})})},e.submitMessageFeedback=function(e){return this.fetch("".concat(f,"/conversation/message_feedback"),{method:"POST",headers:(0,s.Z)({"Content-Type":"application/json"},this.getAuthHeader()),body:JSON.stringify(e)})},e.submitMessageComparisonFeedback=function(e){return this.fetch("".concat(f,"/conversation/message_comparison_feedback"),{method:"POST",headers:(0,s.Z)({"Content-Type":"application/json"},this.getAuthHeader()),body:JSON.stringify(e)})},e.submitCheckoutForm=function(){return this.fetch("".concat(f,"/payments/checkout"),{method:"POST",headers:(0,s.Z)({"Content-Type":"application/json"},this.getAuthHeader())})},e.fetchCustomerPortalUrl=function(e){return this.fetch("".concat(f,"/payments/customer_portal"),{method:"GET",headers:(0,s.Z)({"Content-Type":"application/json"},this.getAuthHeader(e))})},e.getPlugins=function(e){var t=e.offset,n=e.limit,o=e.statuses,i=e.isInstalled,a=e.accessToken,r=[["offset",t.toString()],["limit",n.toString()],];if(o){var c=!0,h=!1,u=void 0;try{for(var d,p=o[Symbol.iterator]();!(c=(d=p.next()).done);c=!0){var l=d.value;r.push(["statuses",l])}}catch(g){h=!0,u=g}finally{try{c||null==p.return||p.return()}finally{if(h)throw u}}}i&&r.push(["is_installed","true"]);var m=new URLSearchParams(r);return this.fetch("".concat(f,"/aip/p?").concat(m),{method:"GET",headers:(0,s.Z)({"Content-Type":"application/json"},this.getAuthHeader(a))})},e.getPluginByDomain=function(e){var t=e.domain,n=e.accessToken,o=new URLSearchParams({offset:"0",limit:"1",domains:t});return this.fetch("".concat(f,"/aip/p?").concat(o),{method:"GET",headers:(0,s.Z)({"Content-Type":"application/json"},this.getAuthHeader(n))}).then(function(e){return 0===e.items.length?null:e.items[0]})},e.setLocalhostPlugin=function(e){var t=e.localhost,n=e.manifest,o=e.openapiSpec,i=e.accessToken;return this.fetch("".concat(f,"/aip/lhp"),{method:"POST",headers:(0,s.Z)({"Content-Type":"application/json"},this.getAuthHeader(i)),body:JSON.stringify({localhost:t,manifest:n,openapi_spec:o})})},e.scrapePluginManifest=function(e){var t=e.domain,n=e.manifestAccessToken,o=e.accessToken;return this.fetch("".concat(f,"/aip/p"),{method:"POST",headers:(0,s.Z)({"Content-Type":"application/json"},this.getAuthHeader(o)),body:JSON.stringify({domain:t,manifest_access_token:n})})},e.getPluginApi=function(e){var t=e.id,n=e.accessToken;return this.fetch("".concat(f,"/aip/p/").concat(t,"/api"),{method:"GET",headers:(0,s.Z)({"Content-Type":"application/json"},this.getAuthHeader(n))})},e.updatePluginUserSettings=function(e){var t=e.pluginId,n=e.isInstalled,o=e.accessToken;return this.fetch("".concat(f,"/aip/p/").concat(t,"/user-settings"),{method:"PATCH",headers:(0,s.Z)({"Content-Type":"application/json"},this.getAuthHeader(o)),body:JSON.stringify({is_installed:n})})},e.deletePlugin=function(e){var t=e.id,n=e.accessToken;return this.fetch("".concat(f,"/aip/p/").concat(t),{method:"DELETE",headers:(0,s.Z)({"Content-Type":"application/json"},this.getAuthHeader(n))})},e.setPluginUserHttpToken=function(e){var t=e.id,n=e.userAccessToken,o=e.accessToken;return this.fetch("".concat(f,"/aip/p/").concat(t,"/user-settings/http-auth"),{method:"POST",headers:(0,s.Z)({"Content-Type":"application/json"},this.getAuthHeader(o)),body:JSON.stringify({access_token:n})})},e.setPluginServiceHttpToken=function(e){var t=e.id,n=e.serviceAccessToken,o=e.accessToken;return this.fetch("".concat(f,"/aip/p/").concat(t,"/http-auth"),{method:"POST",headers:(0,s.Z)({"Content-Type":"application/json"},this.getAuthHeader(o)),body:JSON.stringify({access_token:n})})},e.setPluginOAuthClientCredentials=function(e){var t=e.id,n=e.clientId,o=e.clientSecret,i=e.accessToken;return this.fetch("".concat(f,"/aip/p/").concat(t,"/oauth"),{method:"POST",headers:(0,s.Z)({"Content-Type":"application/json"},this.getAuthHeader(i)),body:JSON.stringify({client_id:n,client_secret:o})})},e.getAccountStatus=function(e,t){var n=(0,s.Z)({"Content-Type":"application/json"},this.getAuthHeader(e));if(t){var o={},i=!0,a=!1,r=void 0;try{for(var h,u=Object.entries(t)[Symbol.iterator]();!(i=(h=u.next()).done);i=!0){var d=(0,c.Z)(h.value,2),p=d[0],l=d[1];g.includes(p.toLowerCase())&&(o[p]=l)}}catch(m){a=!0,r=m}finally{try{i||null==u.return||u.return()}finally{if(a)throw r}}n=(0,s.Z)({},o,n)}return this.fetch("/api/accounts/check",{method:"GET",headers:n})},e.pluginOauthCallback=function(e,t,n,o){var i=new URLSearchParams({code:t,redirect_uri:n});return this.fetch("".concat(f,"/aip/p/").concat(e,"/user-settings/oauth/callback?").concat(i),{method:"GET",headers:(0,s.Z)({"Content-Type":"application/json"},this.getAuthHeader(o))})},e.getPageMetadata=function(e){var t=e.url;return this.fetch("".concat(f,"/opengraph/tags?url=").concat(encodeURIComponent(t)),{method:"GET",headers:(0,s.Z)({"Content-Type":"application/json"},this.getAuthHeader())})},e.getModelMessageCap=function(){return this.fetch("https://chat.openai.com/public-api/conversation_limit",{method:"GET",headers:(0,s.Z)({"Content-Type":"application/json"},this.getAuthHeader())})},e}();m.auth0Client=null,t.ZP=m}}]);
src/pandora/flask/static/_next/static/chunks/360-442b869f1ba4bb1b.js ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[360],{27215:function(){},82330:function(e){var t="undefined"!=typeof Element,n="function"==typeof Map,r="function"==typeof Set,o="function"==typeof ArrayBuffer&&!!ArrayBuffer.isView;e.exports=function(e,i){try{return function e(i,a){if(i===a)return!0;if(i&&a&&"object"==typeof i&&"object"==typeof a){var s,f,u,c;if(i.constructor!==a.constructor)return!1;if(Array.isArray(i)){if((s=i.length)!=a.length)return!1;for(f=s;0!=f--;)if(!e(i[f],a[f]))return!1;return!0}if(n&&i instanceof Map&&a instanceof Map){if(i.size!==a.size)return!1;for(c=i.entries();!(f=c.next()).done;)if(!a.has(f.value[0]))return!1;for(c=i.entries();!(f=c.next()).done;)if(!e(f.value[1],a.get(f.value[0])))return!1;return!0}if(r&&i instanceof Set&&a instanceof Set){if(i.size!==a.size)return!1;for(c=i.entries();!(f=c.next()).done;)if(!a.has(f.value[0]))return!1;return!0}if(o&&ArrayBuffer.isView(i)&&ArrayBuffer.isView(a)){if((s=i.length)!=a.length)return!1;for(f=s;0!=f--;)if(i[f]!==a[f])return!1;return!0}if(i.constructor===RegExp)return i.source===a.source&&i.flags===a.flags;if(i.valueOf!==Object.prototype.valueOf)return i.valueOf()===a.valueOf();if(i.toString!==Object.prototype.toString)return i.toString()===a.toString();if((s=(u=Object.keys(i)).length)!==Object.keys(a).length)return!1;for(f=s;0!=f--;)if(!Object.prototype.hasOwnProperty.call(a,u[f]))return!1;if(t&&i instanceof Element)return!1;for(f=s;0!=f--;)if(("_owner"!==u[f]&&"__v"!==u[f]&&"__o"!==u[f]||!i.$$typeof)&&!e(i[u[f]],a[u[f]]))return!1;return!0}return i!=i&&a!=a}(e,i)}catch(a){if((a.message||"").match(/stack|recursion/i))return console.warn("react-fast-compare cannot handle circular refs"),!1;throw a}}},65921:function(e,t,n){"use strict";n.d(t,{D:function(){return eb}});var r=n(70079),o=n(99581);function i(e){if(null==e)return window;if("[object Window]"!==e.toString()){var t=e.ownerDocument;return t&&t.defaultView||window}return e}function a(e){var t=i(e).Element;return e instanceof t||e instanceof Element}function s(e){var t=i(e).HTMLElement;return e instanceof t||e instanceof HTMLElement}function f(e){if("undefined"==typeof ShadowRoot)return!1;var t=i(e).ShadowRoot;return e instanceof t||e instanceof ShadowRoot}var u=Math.max,c=Math.min,p=Math.round;function l(){var e=navigator.userAgentData;return null!=e&&e.brands?e.brands.map(function(e){return e.brand+"/"+e.version}).join(" "):navigator.userAgent}function d(){return!/^((?!chrome|android).)*safari/i.test(l())}function m(e,t,n){void 0===t&&(t=!1),void 0===n&&(n=!1);var r=e.getBoundingClientRect(),o=1,f=1;t&&s(e)&&(o=e.offsetWidth>0&&p(r.width)/e.offsetWidth||1,f=e.offsetHeight>0&&p(r.height)/e.offsetHeight||1);var u=(a(e)?i(e):window).visualViewport,c=!d()&&n,l=(r.left+(c&&u?u.offsetLeft:0))/o,m=(r.top+(c&&u?u.offsetTop:0))/f,h=r.width/o,v=r.height/f;return{width:h,height:v,top:m,right:l+h,bottom:m+v,left:l,x:l,y:m}}function h(e){var t,n=i(e);return{scrollLeft:n.pageXOffset,scrollTop:n.pageYOffset}}function v(e){return e?(e.nodeName||"").toLowerCase():null}function y(e){return((a(e)?e.ownerDocument:e.document)||window.document).documentElement}function g(e){return m(y(e)).left+h(e).scrollLeft}function b(e){return i(e).getComputedStyle(e)}function w(e){var t=b(e),n=t.overflow,r=t.overflowX,o=t.overflowY;return/auto|scroll|overlay|hidden/.test(n+o+r)}function x(e){var t=m(e),n=e.offsetWidth,r=e.offsetHeight;return 1>=Math.abs(t.width-n)&&(n=t.width),1>=Math.abs(t.height-r)&&(r=t.height),{x:e.offsetLeft,y:e.offsetTop,width:n,height:r}}function O(e){return"html"===v(e)?e:e.assignedSlot||e.parentNode||(f(e)?e.host:null)||y(e)}function j(e,t){void 0===t&&(t=[]);var n,r=function e(t){return["html","body","#document"].indexOf(v(t))>=0?t.ownerDocument.body:s(t)&&w(t)?t:e(O(t))}(e),o=r===(null==(n=e.ownerDocument)?void 0:n.body),a=i(r),f=o?[a].concat(a.visualViewport||[],w(r)?r:[]):r,u=t.concat(f);return o?u:u.concat(j(O(f)))}function E(e){return["table","td","th"].indexOf(v(e))>=0}function S(e){return s(e)&&"fixed"!==b(e).position?e.offsetParent:null}function D(e){for(var t=i(e),n=S(e);n&&E(n)&&"static"===b(n).position;)n=S(n);return n&&("html"===v(n)||"body"===v(n)&&"static"===b(n).position)?t:n||function(e){var t=/firefox/i.test(l());if(/Trident/i.test(l())&&s(e)&&"fixed"===b(e).position)return null;var n=O(e);for(f(n)&&(n=n.host);s(n)&&0>["html","body"].indexOf(v(n));){var r=b(n);if("none"!==r.transform||"none"!==r.perspective||"paint"===r.contain||-1!==["transform","perspective"].indexOf(r.willChange)||t&&"filter"===r.willChange||t&&r.filter&&"none"!==r.filter)return n;n=n.parentNode}return null}(e)||t}var A="bottom",k="right",M="left",P="auto",L=["top",A,k,M],B="start",W="viewport",R="popper",V=L.reduce(function(e,t){return e.concat([t+"-"+B,t+"-end"])},[]),H=[].concat(L,[P]).reduce(function(e,t){return e.concat([t,t+"-"+B,t+"-end"])},[]),T=["beforeRead","read","afterRead","beforeMain","main","afterMain","beforeWrite","write","afterWrite"],C={placement:"bottom",modifiers:[],strategy:"absolute"};function _(){for(var e=arguments.length,t=Array(e),n=0;n<e;n++)t[n]=arguments[n];return!t.some(function(e){return!(e&&"function"==typeof e.getBoundingClientRect)})}var q={passive:!0};function U(e){return e.split("-")[0]}function F(e){return e.split("-")[1]}function N(e){return["top","bottom"].indexOf(e)>=0?"x":"y"}function z(e){var t,n=e.reference,r=e.element,o=e.placement,i=o?U(o):null,a=o?F(o):null,s=n.x+n.width/2-r.width/2,f=n.y+n.height/2-r.height/2;switch(i){case"top":t={x:s,y:n.y-r.height};break;case A:t={x:s,y:n.y+n.height};break;case k:t={x:n.x+n.width,y:f};break;case M:t={x:n.x-r.width,y:f};break;default:t={x:n.x,y:n.y}}var u=i?N(i):null;if(null!=u){var c="y"===u?"height":"width";switch(a){case B:t[u]=t[u]-(n[c]/2-r[c]/2);break;case"end":t[u]=t[u]+(n[c]/2-r[c]/2)}}return t}var I={top:"auto",right:"auto",bottom:"auto",left:"auto"};function X(e){var t,n,r=e.popper,o=e.popperRect,a=e.placement,s=e.variation,f=e.offsets,u=e.position,c=e.gpuAcceleration,l=e.adaptive,d=e.roundOffsets,m=e.isFixed,h=f.x,v=void 0===h?0:h,g=f.y,w=void 0===g?0:g,x="function"==typeof d?d({x:v,y:w}):{x:v,y:w};v=x.x,w=x.y;var O=f.hasOwnProperty("x"),j=f.hasOwnProperty("y"),E=M,S="top",P=window;if(l){var L=D(r),B="clientHeight",W="clientWidth";L===i(r)&&(L=y(r),"static"!==b(L).position&&"absolute"===u&&(B="scrollHeight",W="scrollWidth")),("top"===a||(a===M||a===k)&&"end"===s)&&(S=A,w-=(m&&L===P&&P.visualViewport?P.visualViewport.height:L[B])-o.height,w*=c?1:-1),(a===M||("top"===a||a===A)&&"end"===s)&&(E=k,v-=(m&&L===P&&P.visualViewport?P.visualViewport.width:L[W])-o.width,v*=c?1:-1)}var R,V,H,T,C=Object.assign({position:u},l&&I),_=!0===d?(V=(R={x:v,y:w}).x,H=R.y,{x:p(V*(T=window.devicePixelRatio||1))/T||0,y:p(H*T)/T||0}):{x:v,y:w};return(v=_.x,w=_.y,c)?Object.assign({},C,((n={})[S]=j?"0":"",n[E]=O?"0":"",n.transform=1>=(P.devicePixelRatio||1)?"translate("+v+"px, "+w+"px)":"translate3d("+v+"px, "+w+"px, 0)",n)):Object.assign({},C,((t={})[S]=j?w+"px":"",t[E]=O?v+"px":"",t.transform="",t))}var Y={left:"right",right:"left",bottom:"top",top:"bottom"};function $(e){return e.replace(/left|right|bottom|top/g,function(e){return Y[e]})}var Z={start:"end",end:"start"};function G(e){return e.replace(/start|end/g,function(e){return Z[e]})}function J(e,t){var n=t.getRootNode&&t.getRootNode();if(e.contains(t))return!0;if(n&&f(n)){var r=t;do{if(r&&e.isSameNode(r))return!0;r=r.parentNode||r.host}while(r)}return!1}function K(e){return Object.assign({},e,{left:e.x,top:e.y,right:e.x+e.width,bottom:e.y+e.height})}function Q(e,t,n){var r,o,s,f,c,p,l,v,w,x,O,j;return t===W?K(function(e,t){var n=i(e),r=y(e),o=n.visualViewport,a=r.clientWidth,s=r.clientHeight,f=0,u=0;if(o){a=o.width,s=o.height;var c=d();(c||!c&&"fixed"===t)&&(f=o.offsetLeft,u=o.offsetTop)}return{width:a,height:s,x:f+g(e),y:u}}(e,n)):a(t)?((s=m(t,!1,"fixed"===n)).top=s.top+t.clientTop,s.left=s.left+t.clientLeft,s.bottom=s.top+t.clientHeight,s.right=s.left+t.clientWidth,s.width=t.clientWidth,s.height=t.clientHeight,s.x=s.left,s.y=s.top,s):K((f=y(e),p=y(f),l=h(f),v=null==(c=f.ownerDocument)?void 0:c.body,w=u(p.scrollWidth,p.clientWidth,v?v.scrollWidth:0,v?v.clientWidth:0),x=u(p.scrollHeight,p.clientHeight,v?v.scrollHeight:0,v?v.clientHeight:0),O=-l.scrollLeft+g(f),j=-l.scrollTop,"rtl"===b(v||p).direction&&(O+=u(p.clientWidth,v?v.clientWidth:0)-w),{width:w,height:x,x:O,y:j}))}function ee(){return{top:0,right:0,bottom:0,left:0}}function et(e){return Object.assign({},ee(),e)}function en(e,t){return t.reduce(function(t,n){return t[n]=e,t},{})}function er(e,t){void 0===t&&(t={});var n,r,o,i,f,p,l,d,h,g,w=t,x=w.placement,E=void 0===x?e.placement:x,S=w.strategy,M=void 0===S?e.strategy:S,P=w.boundary,B=w.rootBoundary,V=w.elementContext,H=void 0===V?R:V,T=w.altBoundary,C=w.padding,_=void 0===C?0:C,q=et("number"!=typeof _?_:en(_,L)),U=e.rects.popper,F=e.elements[void 0!==T&&T?H===R?"reference":R:H],N=(n=a(F)?F:F.contextElement||y(e.elements.popper),h=(d=[].concat("clippingParents"===(r=void 0===P?"clippingParents":P)?(p=j(O(n)),l=["absolute","fixed"].indexOf(b(n).position)>=0&&s(n)?D(n):n,a(l)?p.filter(function(e){return a(e)&&J(e,l)&&"body"!==v(e)}):[]):[].concat(r),[void 0===B?W:B]))[0],(g=d.reduce(function(e,t){var r=Q(n,t,M);return e.top=u(r.top,e.top),e.right=c(r.right,e.right),e.bottom=c(r.bottom,e.bottom),e.left=u(r.left,e.left),e},Q(n,h,M))).width=g.right-g.left,g.height=g.bottom-g.top,g.x=g.left,g.y=g.top,g),I=m(e.elements.reference),X=z({reference:I,element:U,strategy:"absolute",placement:E}),Y=K(Object.assign({},U,X)),$=H===R?Y:I,Z={top:N.top-$.top+q.top,bottom:$.bottom-N.bottom+q.bottom,left:N.left-$.left+q.left,right:$.right-N.right+q.right},G=e.modifiersData.offset;if(H===R&&G){var ee=G[E];Object.keys(Z).forEach(function(e){var t=[k,A].indexOf(e)>=0?1:-1,n=["top",A].indexOf(e)>=0?"y":"x";Z[e]+=ee[n]*t})}return Z}function eo(e,t,n){return u(e,c(t,n))}function ei(e,t,n){return void 0===n&&(n={x:0,y:0}),{top:e.top-t.height-n.y,right:e.right-t.width+n.x,bottom:e.bottom-t.height+n.y,left:e.left-t.width-n.x}}function ea(e){return["top",k,A,M].some(function(t){return e[t]>=0})}var es,ef,eu,ec,ep,el,ed=(es={defaultModifiers:[{name:"eventListeners",enabled:!0,phase:"write",fn:function(){},effect:function(e){var t=e.state,n=e.instance,r=e.options,o=r.scroll,a=void 0===o||o,s=r.resize,f=void 0===s||s,u=i(t.elements.popper),c=[].concat(t.scrollParents.reference,t.scrollParents.popper);return a&&c.forEach(function(e){e.addEventListener("scroll",n.update,q)}),f&&u.addEventListener("resize",n.update,q),function(){a&&c.forEach(function(e){e.removeEventListener("scroll",n.update,q)}),f&&u.removeEventListener("resize",n.update,q)}},data:{}},{name:"popperOffsets",enabled:!0,phase:"read",fn:function(e){var t=e.state,n=e.name;t.modifiersData[n]=z({reference:t.rects.reference,element:t.rects.popper,strategy:"absolute",placement:t.placement})},data:{}},{name:"computeStyles",enabled:!0,phase:"beforeWrite",fn:function(e){var t=e.state,n=e.options,r=n.gpuAcceleration,o=n.adaptive,i=n.roundOffsets,a=void 0===i||i,s={placement:U(t.placement),variation:F(t.placement),popper:t.elements.popper,popperRect:t.rects.popper,gpuAcceleration:void 0===r||r,isFixed:"fixed"===t.options.strategy};null!=t.modifiersData.popperOffsets&&(t.styles.popper=Object.assign({},t.styles.popper,X(Object.assign({},s,{offsets:t.modifiersData.popperOffsets,position:t.options.strategy,adaptive:void 0===o||o,roundOffsets:a})))),null!=t.modifiersData.arrow&&(t.styles.arrow=Object.assign({},t.styles.arrow,X(Object.assign({},s,{offsets:t.modifiersData.arrow,position:"absolute",adaptive:!1,roundOffsets:a})))),t.attributes.popper=Object.assign({},t.attributes.popper,{"data-popper-placement":t.placement})},data:{}},{name:"applyStyles",enabled:!0,phase:"write",fn:function(e){var t=e.state;Object.keys(t.elements).forEach(function(e){var n=t.styles[e]||{},r=t.attributes[e]||{},o=t.elements[e];s(o)&&v(o)&&(Object.assign(o.style,n),Object.keys(r).forEach(function(e){var t=r[e];!1===t?o.removeAttribute(e):o.setAttribute(e,!0===t?"":t)}))})},effect:function(e){var t=e.state,n={popper:{position:t.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};return Object.assign(t.elements.popper.style,n.popper),t.styles=n,t.elements.arrow&&Object.assign(t.elements.arrow.style,n.arrow),function(){Object.keys(t.elements).forEach(function(e){var r=t.elements[e],o=t.attributes[e]||{},i=Object.keys(t.styles.hasOwnProperty(e)?t.styles[e]:n[e]).reduce(function(e,t){return e[t]="",e},{});s(r)&&v(r)&&(Object.assign(r.style,i),Object.keys(o).forEach(function(e){r.removeAttribute(e)}))})}},requires:["computeStyles"]},{name:"offset",enabled:!0,phase:"main",requires:["popperOffsets"],fn:function(e){var t=e.state,n=e.options,r=e.name,o=n.offset,i=void 0===o?[0,0]:o,a=H.reduce(function(e,n){var r,o,a,s,f,u,c,p;return e[n]=(o=t.rects,f=[M,"top"].indexOf(s=U(n))>=0?-1:1,c=(u="function"==typeof i?i(Object.assign({},o,{placement:n})):i)[0],p=u[1],c=c||0,p=(p||0)*f,[M,k].indexOf(s)>=0?{x:p,y:c}:{x:c,y:p}),e},{}),s=a[t.placement],f=s.x,u=s.y;null!=t.modifiersData.popperOffsets&&(t.modifiersData.popperOffsets.x+=f,t.modifiersData.popperOffsets.y+=u),t.modifiersData[r]=a}},{name:"flip",enabled:!0,phase:"main",fn:function(e){var t=e.state,n=e.options,r=e.name;if(!t.modifiersData[r]._skip){for(var o=n.mainAxis,i=void 0===o||o,a=n.altAxis,s=void 0===a||a,f=n.fallbackPlacements,u=n.padding,c=n.boundary,p=n.rootBoundary,l=n.altBoundary,d=n.flipVariations,m=void 0===d||d,h=n.allowedAutoPlacements,v=t.options.placement,y=U(v),g=[v].concat(f||(y!==v&&m?function(e){if(U(e)===P)return[];var t=$(e);return[G(e),t,G(t)]}(v):[$(v)])).reduce(function(e,n){var r,o,i,a,s,f,l,d,v,y,g,b,w,x;return e.concat(U(n)===P?(o={placement:n,boundary:c,rootBoundary:p,padding:u,flipVariations:m,allowedAutoPlacements:h},a=(i=o).placement,s=i.boundary,f=i.rootBoundary,l=i.padding,d=i.flipVariations,y=void 0===(v=i.allowedAutoPlacements)?H:v,0===(w=(b=(g=F(a))?d?V:V.filter(function(e){return F(e)===g}):L).filter(function(e){return y.indexOf(e)>=0})).length&&(w=b),Object.keys(x=w.reduce(function(e,n){return e[n]=er(t,{placement:n,boundary:s,rootBoundary:f,padding:l})[U(n)],e},{})).sort(function(e,t){return x[e]-x[t]})):n)},[]),b=t.rects.reference,w=t.rects.popper,x=new Map,O=!0,j=g[0],E=0;E<g.length;E++){var S=g[E],D=U(S),W=F(S)===B,R=["top",A].indexOf(D)>=0,T=R?"width":"height",C=er(t,{placement:S,boundary:c,rootBoundary:p,altBoundary:l,padding:u}),_=R?W?k:M:W?A:"top";b[T]>w[T]&&(_=$(_));var q=$(_),N=[];if(i&&N.push(C[D]<=0),s&&N.push(C[_]<=0,C[q]<=0),N.every(function(e){return e})){j=S,O=!1;break}x.set(S,N)}if(O)for(var z=m?3:1,I=function(e){var t=g.find(function(t){var n=x.get(t);if(n)return n.slice(0,e).every(function(e){return e})});if(t)return j=t,"break"},X=z;X>0&&"break"!==I(X);X--);t.placement!==j&&(t.modifiersData[r]._skip=!0,t.placement=j,t.reset=!0)}},requiresIfExists:["offset"],data:{_skip:!1}},{name:"preventOverflow",enabled:!0,phase:"main",fn:function(e){var t,n=e.state,r=e.options,o=e.name,i=r.mainAxis,a=r.altAxis,s=r.boundary,f=r.rootBoundary,p=r.altBoundary,l=r.padding,d=r.tether,m=void 0===d||d,h=r.tetherOffset,v=void 0===h?0:h,y=er(n,{boundary:s,rootBoundary:f,padding:l,altBoundary:p}),g=U(n.placement),b=F(n.placement),w=!b,O=N(g),j="x"===O?"y":"x",E=n.modifiersData.popperOffsets,S=n.rects.reference,P=n.rects.popper,L="function"==typeof v?v(Object.assign({},n.rects,{placement:n.placement})):v,W="number"==typeof L?{mainAxis:L,altAxis:L}:Object.assign({mainAxis:0,altAxis:0},L),R=n.modifiersData.offset?n.modifiersData.offset[n.placement]:null,V={x:0,y:0};if(E){if(void 0===i||i){var H,T="y"===O?"top":M,C="y"===O?A:k,_="y"===O?"height":"width",q=E[O],z=q+y[T],I=q-y[C],X=m?-P[_]/2:0,Y=b===B?S[_]:P[_],$=b===B?-P[_]:-S[_],Z=n.elements.arrow,G=m&&Z?x(Z):{width:0,height:0},J=n.modifiersData["arrow#persistent"]?n.modifiersData["arrow#persistent"].padding:ee(),K=J[T],Q=J[C],et=eo(0,S[_],G[_]),en=w?S[_]/2-X-et-K-W.mainAxis:Y-et-K-W.mainAxis,ei=w?-S[_]/2+X+et+Q+W.mainAxis:$+et+Q+W.mainAxis,ea=n.elements.arrow&&D(n.elements.arrow),es=ea?"y"===O?ea.clientTop||0:ea.clientLeft||0:0,ef=null!=(H=null==R?void 0:R[O])?H:0,eu=eo(m?c(z,q+en-ef-es):z,q,m?u(I,q+ei-ef):I);E[O]=eu,V[O]=eu-q}if(void 0!==a&&a){var ec,ep,el,ed,em,eh=E[j],ev="y"===j?"height":"width",ey=eh+y["x"===O?"top":M],eg=eh-y["x"===O?A:k],eb=-1!==["top",M].indexOf(g),ew=null!=(ec=null==R?void 0:R[j])?ec:0,ex=eb?ey:eh-S[ev]-P[ev]-ew+W.altAxis,eO=eb?eh+S[ev]+P[ev]-ew-W.altAxis:eg,ej=m&&eb?(em=eo(ex,eh,eO))>eO?eO:em:eo(m?ex:ey,eh,m?eO:eg);E[j]=ej,V[j]=ej-eh}n.modifiersData[o]=V}},requiresIfExists:["offset"]},{name:"arrow",enabled:!0,phase:"main",fn:function(e){var t,n=e.state,r=e.name,o=e.options,i=n.elements.arrow,a=n.modifiersData.popperOffsets,s=U(n.placement),f=N(s),u=[M,k].indexOf(s)>=0?"height":"width";if(i&&a){var c,p,l=et("number"!=typeof(c="function"==typeof(c=o.padding)?c(Object.assign({},n.rects,{placement:n.placement})):c)?c:en(c,L)),d=x(i),m=n.rects.reference[u]+n.rects.reference[f]-a[f]-n.rects.popper[u],h=a[f]-n.rects.reference[f],v=D(i),y=v?"y"===f?v.clientHeight||0:v.clientWidth||0:0,g=l["y"===f?"top":M],b=y-d[u]-l["y"===f?A:k],w=y/2-d[u]/2+(m/2-h/2),O=eo(g,w,b);n.modifiersData[r]=((t={})[f]=O,t.centerOffset=O-w,t)}},effect:function(e){var t=e.state,n=e.options.element,r=void 0===n?"[data-popper-arrow]":n;if(null!=r&&("string"!=typeof r||(r=t.elements.popper.querySelector(r))))J(t.elements.popper,r)&&(t.elements.arrow=r)},requires:["popperOffsets"],requiresIfExists:["preventOverflow"]},{name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:function(e){var t=e.state,n=e.name,r=t.rects.reference,o=t.rects.popper,i=t.modifiersData.preventOverflow,a=er(t,{elementContext:"reference"}),s=er(t,{altBoundary:!0}),f=ei(a,r),u=ei(s,o,i),c=ea(f),p=ea(u);t.modifiersData[n]={referenceClippingOffsets:f,popperEscapeOffsets:u,isReferenceHidden:c,hasPopperEscaped:p},t.attributes.popper=Object.assign({},t.attributes.popper,{"data-popper-reference-hidden":c,"data-popper-escaped":p})}}]},ec=void 0===(eu=(ef=es).defaultModifiers)?[]:eu,el=void 0===(ep=ef.defaultOptions)?C:ep,function(e,t,n){void 0===n&&(n=el);var r,o,f={placement:"bottom",orderedModifiers:[],options:Object.assign({},C,el),modifiersData:{},elements:{reference:e,popper:t},attributes:{},styles:{}},u=[],c=!1,l={state:f,setOptions:function(n){var r,o,i,s,c,p,m,h,v="function"==typeof n?n(f.options):n;d(),f.options=Object.assign({},el,f.options,v),f.scrollParents={reference:a(e)?j(e):e.contextElement?j(e.contextElement):[],popper:j(t)};var y=(i=Object.keys(o=(r=[].concat(ec,f.options.modifiers)).reduce(function(e,t){var n=e[t.name];return e[t.name]=n?Object.assign({},n,t,{options:Object.assign({},n.options,t.options),data:Object.assign({},n.data,t.data)}):t,e},{})).map(function(e){return o[e]}),c=new Map,p=new Set,m=[],i.forEach(function(e){c.set(e.name,e)}),i.forEach(function(e){p.has(e.name)||function e(t){p.add(t.name),[].concat(t.requires||[],t.requiresIfExists||[]).forEach(function(t){if(!p.has(t)){var n=c.get(t);n&&e(n)}}),m.push(t)}(e)}),T.reduce(function(e,t){return e.concat(m.filter(function(e){return e.phase===t}))},[]));return f.orderedModifiers=y.filter(function(e){return e.enabled}),f.orderedModifiers.forEach(function(e){var t=e.name,n=e.options,r=e.effect;if("function"==typeof r){var o=r({state:f,name:t,instance:l,options:void 0===n?{}:n}),i=function(){};u.push(o||i)}}),l.update()},forceUpdate:function(){if(!c){var e,t,n,r,o,a,u,d,b,O,j,E,S,A=f.elements,k=A.reference,M=A.popper;if(_(k,M)){f.rects={reference:(e=k,t=D(M),n="fixed"===f.options.strategy,r=s(t),b=s(t)&&(u=p((a=(o=t).getBoundingClientRect()).width)/o.offsetWidth||1,d=p(a.height)/o.offsetHeight||1,1!==u||1!==d),O=y(t),j=m(e,b,n),E={scrollLeft:0,scrollTop:0},S={x:0,y:0},(r||!r&&!n)&&(("body"!==v(t)||w(O))&&(E=function(e){var t;return e!==i(e)&&s(e)?{scrollLeft:e.scrollLeft,scrollTop:e.scrollTop}:h(e)}(t)),s(t)?(S=m(t,!0),S.x+=t.clientLeft,S.y+=t.clientTop):O&&(S.x=g(O))),{x:j.left+E.scrollLeft-S.x,y:j.top+E.scrollTop-S.y,width:j.width,height:j.height}),popper:x(M)},f.reset=!1,f.placement=f.options.placement,f.orderedModifiers.forEach(function(e){return f.modifiersData[e.name]=Object.assign({},e.data)});for(var P=0;P<f.orderedModifiers.length;P++){if(!0===f.reset){f.reset=!1,P=-1;continue}var L=f.orderedModifiers[P],B=L.fn,W=L.options,R=void 0===W?{}:W,V=L.name;"function"==typeof B&&(f=B({state:f,options:R,name:V,instance:l})||f)}}}},update:function(){return o||(o=new Promise(function(e){Promise.resolve().then(function(){o=void 0,e(new Promise(function(e){l.forceUpdate(),e(f)}))})})),o},destroy:function(){d(),c=!0}};if(!_(e,t))return l;function d(){u.forEach(function(e){return e()}),u=[]}return l.setOptions(n).then(function(e){!c&&n.onFirstUpdate&&n.onFirstUpdate(e)}),l}),em=n(82330),eh=n.n(em),ev=function(e){return e.reduce(function(e,t){var n=t[0],r=t[1];return e[n]=r,e},{})},ey="undefined"!=typeof window&&window.document&&window.document.createElement?r.useLayoutEffect:r.useEffect,eg=[],eb=function(e,t,n){void 0===n&&(n={});var i=r.useRef(null),a={onFirstUpdate:n.onFirstUpdate,placement:n.placement||"bottom",strategy:n.strategy||"absolute",modifiers:n.modifiers||eg},s=r.useState({styles:{popper:{position:a.strategy,left:"0",top:"0"},arrow:{position:"absolute"}},attributes:{}}),f=s[0],u=s[1],c=r.useMemo(function(){return{name:"updateState",enabled:!0,phase:"write",fn:function(e){var t=e.state,n=Object.keys(t.elements);o.flushSync(function(){u({styles:ev(n.map(function(e){return[e,t.styles[e]||{}]})),attributes:ev(n.map(function(e){return[e,t.attributes[e]]}))})})},requires:["computeStyles"]}},[]),p=r.useMemo(function(){var e={onFirstUpdate:a.onFirstUpdate,placement:a.placement,strategy:a.strategy,modifiers:[].concat(a.modifiers,[c,{name:"applyStyles",enabled:!1}])};return eh()(i.current,e)?i.current||e:(i.current=e,e)},[a.onFirstUpdate,a.placement,a.strategy,a.modifiers,c]),l=r.useRef();return ey(function(){l.current&&l.current.setOptions(p)},[p]),ey(function(){if(null!=e&&null!=t){var r=(n.createPopper||ed)(e,t,p);return l.current=r,function(){r.destroy(),l.current=null}}},[e,t,n.createPopper]),{state:l.current?l.current.state:null,styles:f.styles,attributes:f.attributes,update:l.current?l.current.update:null,forceUpdate:l.current?l.current.forceUpdate:null}}},97838:function(e,t,n){"use strict";/**
2
+ * @license React
3
+ * use-sync-external-store-shim/with-selector.production.min.js
4
+ *
5
+ * Copyright (c) Facebook, Inc. and its affiliates.
6
+ *
7
+ * This source code is licensed under the MIT license found in the
8
+ * LICENSE file in the root directory of this source tree.
9
+ */ var r=n(70079),o=n(31178),i="function"==typeof Object.is?Object.is:function(e,t){return e===t&&(0!==e||1/e==1/t)||e!=e&&t!=t},a=o.useSyncExternalStore,s=r.useRef,f=r.useEffect,u=r.useMemo,c=r.useDebugValue;t.useSyncExternalStoreWithSelector=function(e,t,n,r,o){var p=s(null);if(null===p.current){var l={hasValue:!1,value:null};p.current=l}else l=p.current;var d=a(e,(p=u(function(){function e(e){if(!f){if(f=!0,a=e,e=r(e),void 0!==o&&l.hasValue){var t=l.value;if(o(t,e))return s=t}return s=e}if(t=s,i(a,e))return t;var n=r(e);return void 0!==o&&o(t,n)?t:(a=e,s=n)}var a,s,f=!1,u=void 0===n?null:n;return[function(){return e(t())},null===u?void 0:function(){return e(u())}]},[t,n,r,o]))[0],p[1]);return f(function(){l.hasValue=!0,l.value=d},[d]),c(d),d}},92280:function(e,t,n){"use strict";e.exports=n(97838)},59268:function(e,t,n){"use strict";n.d(t,{ZP:function(){return u}});let r=e=>{let t,n=new Set,r=(e,r)=>{let o="function"==typeof e?e(t):e;if(!Object.is(o,t)){let i=t;t=(null!=r?r:"object"!=typeof o)?o:Object.assign({},t,o),n.forEach(e=>e(t,i))}},o=()=>t,i=e=>(n.add(e),()=>n.delete(e)),a=()=>n.clear(),s={setState:r,getState:o,subscribe:i,destroy:a};return t=e(r,o,s),s},o=e=>e?r(e):r;var i=n(70079),a=n(92280);let{useSyncExternalStoreWithSelector:s}=a,f=e=>{let t="function"==typeof e?o(e):e,n=(e,n)=>(function(e,t=e.getState,n){let r=s(e.subscribe,e.getState,e.getServerState||e.getState,t,n);return(0,i.useDebugValue)(r),r})(t,e,n);return Object.assign(n,t),n},u=e=>e?f(e):f}}]);
src/pandora/flask/static/_next/static/chunks/424-d1d3bfe6a3ca6c4a.js ADDED
@@ -0,0 +1 @@
 
 
1
+ (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[424],{48879:function(t,e,r){"use strict";async function n(t,e){let r=t.getReader(),n;for(;!(n=await r.read()).done;)e(n.value)}function i(){return{data:"",event:"",id:"",retry:void 0}}r.d(e,{L:function(){return l}});var o=function(t,e){var r={};for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&0>e.indexOf(n)&&(r[n]=t[n]);if(null!=t&&"function"==typeof Object.getOwnPropertySymbols)for(var i=0,n=Object.getOwnPropertySymbols(t);i<n.length;i++)0>e.indexOf(n[i])&&Object.prototype.propertyIsEnumerable.call(t,n[i])&&(r[n[i]]=t[n[i]]);return r};let a="text/event-stream",s="last-event-id";function l(t,e){var{signal:r,headers:l,onopen:u,onmessage:f,onclose:g,onerror:d,openWhenHidden:p,fetch:h}=e,m=o(e,["signal","headers","onopen","onmessage","onclose","onerror","openWhenHidden","fetch"]);return new Promise((e,o)=>{let b=Object.assign({},l);b.accept||(b.accept=a);let v;function w(){v.abort(),document.hidden||I()}p||document.addEventListener("visibilitychange",w);let y=1e3,x=0;function k(){document.removeEventListener("visibilitychange",w),window.clearTimeout(x),v.abort()}null==r||r.addEventListener("abort",()=>{k(),e()});let A=null!=h?h:window.fetch,T=null!=u?u:c;async function I(){var r,a;v=new AbortController;try{let l=await A(t,Object.assign(Object.assign({},m),{headers:b,signal:v.signal}));await T(l);let c,u,p,h;await n(l.body,(a=function(t,e,r){let n=i(),o=new TextDecoder;return function(a,s){if(0===a.length)null==r||r(n),n=i();else if(s>0){let l=o.decode(a.subarray(0,s)),c=s+(32===a[s+1]?2:1),u=o.decode(a.subarray(c));switch(l){case"data":n.data=n.data?n.data+"\n"+u:u;break;case"event":n.event=u;break;case"id":t(n.id=u);break;case"retry":let f=parseInt(u,10);isNaN(f)||e(n.retry=f)}}}}(t=>{t?b[s]=t:delete b[s]},t=>{y=t},f),h=!1,function(t){void 0===c?(c=t,u=0,p=-1):c=function(t,e){let r=new Uint8Array(t.length+e.length);return r.set(t),r.set(e,t.length),r}(c,t);let e=c.length,r=0;for(;u<e;){h&&(10===c[u]&&(r=++u),h=!1);let n=-1;for(;u<e&&-1===n;++u)switch(c[u]){case 58:-1===p&&(p=u-r);break;case 13:h=!0;case 10:n=u}if(-1===n)break;a(c.subarray(r,n),p),r=u,p=-1}r===e?c=void 0:0!==r&&(c=c.subarray(r),u-=r)})),null==g||g(),k(),e()}catch(C){if(!v.signal.aborted)try{let w=null!==(r=null==d?void 0:d(C))&&void 0!==r?r:y;window.clearTimeout(x),x=window.setTimeout(I,w)}catch(S){k(),o(S)}}}I()})}function c(t){let e=t.headers.get("content-type");if(!(null==e?void 0:e.startsWith(a)))throw Error(`Expected content-type to be ${a}, Actual: ${e}`)}},25766:function(t,e,r){var n=r(53140),i=r(50694);function o(t){return null==t}function a(t){(t=function(t){var e={};for(var r in t)e[r]=t[r];return e}(t||{})).whiteList=t.whiteList||n.whiteList,t.onAttr=t.onAttr||n.onAttr,t.onIgnoreAttr=t.onIgnoreAttr||n.onIgnoreAttr,t.safeAttrValue=t.safeAttrValue||n.safeAttrValue,this.options=t}r(66380),a.prototype.process=function(t){if(!(t=(t=t||"").toString()))return"";var e=this.options,r=e.whiteList,n=e.onAttr,a=e.onIgnoreAttr,s=e.safeAttrValue;return i(t,function(t,e,i,l,c){var u=r[i],f=!1;if(!0===u?f=u:"function"==typeof u?f=u(l):u instanceof RegExp&&(f=u.test(l)),!0!==f&&(f=!1),l=s(i,l)){var g={position:e,sourcePosition:t,source:c,isWhite:f};if(f){var d=n(i,l,g);return o(d)?i+":"+l:d}var d=a(i,l,g);if(!o(d))return d}})},t.exports=a},53140:function(t,e){function r(){var t={};return t["align-content"]=!1,t["align-items"]=!1,t["align-self"]=!1,t["alignment-adjust"]=!1,t["alignment-baseline"]=!1,t.all=!1,t["anchor-point"]=!1,t.animation=!1,t["animation-delay"]=!1,t["animation-direction"]=!1,t["animation-duration"]=!1,t["animation-fill-mode"]=!1,t["animation-iteration-count"]=!1,t["animation-name"]=!1,t["animation-play-state"]=!1,t["animation-timing-function"]=!1,t.azimuth=!1,t["backface-visibility"]=!1,t.background=!0,t["background-attachment"]=!0,t["background-clip"]=!0,t["background-color"]=!0,t["background-image"]=!0,t["background-origin"]=!0,t["background-position"]=!0,t["background-repeat"]=!0,t["background-size"]=!0,t["baseline-shift"]=!1,t.binding=!1,t.bleed=!1,t["bookmark-label"]=!1,t["bookmark-level"]=!1,t["bookmark-state"]=!1,t.border=!0,t["border-bottom"]=!0,t["border-bottom-color"]=!0,t["border-bottom-left-radius"]=!0,t["border-bottom-right-radius"]=!0,t["border-bottom-style"]=!0,t["border-bottom-width"]=!0,t["border-collapse"]=!0,t["border-color"]=!0,t["border-image"]=!0,t["border-image-outset"]=!0,t["border-image-repeat"]=!0,t["border-image-slice"]=!0,t["border-image-source"]=!0,t["border-image-width"]=!0,t["border-left"]=!0,t["border-left-color"]=!0,t["border-left-style"]=!0,t["border-left-width"]=!0,t["border-radius"]=!0,t["border-right"]=!0,t["border-right-color"]=!0,t["border-right-style"]=!0,t["border-right-width"]=!0,t["border-spacing"]=!0,t["border-style"]=!0,t["border-top"]=!0,t["border-top-color"]=!0,t["border-top-left-radius"]=!0,t["border-top-right-radius"]=!0,t["border-top-style"]=!0,t["border-top-width"]=!0,t["border-width"]=!0,t.bottom=!1,t["box-decoration-break"]=!0,t["box-shadow"]=!0,t["box-sizing"]=!0,t["box-snap"]=!0,t["box-suppress"]=!0,t["break-after"]=!0,t["break-before"]=!0,t["break-inside"]=!0,t["caption-side"]=!1,t.chains=!1,t.clear=!0,t.clip=!1,t["clip-path"]=!1,t["clip-rule"]=!1,t.color=!0,t["color-interpolation-filters"]=!0,t["column-count"]=!1,t["column-fill"]=!1,t["column-gap"]=!1,t["column-rule"]=!1,t["column-rule-color"]=!1,t["column-rule-style"]=!1,t["column-rule-width"]=!1,t["column-span"]=!1,t["column-width"]=!1,t.columns=!1,t.contain=!1,t.content=!1,t["counter-increment"]=!1,t["counter-reset"]=!1,t["counter-set"]=!1,t.crop=!1,t.cue=!1,t["cue-after"]=!1,t["cue-before"]=!1,t.cursor=!1,t.direction=!1,t.display=!0,t["display-inside"]=!0,t["display-list"]=!0,t["display-outside"]=!0,t["dominant-baseline"]=!1,t.elevation=!1,t["empty-cells"]=!1,t.filter=!1,t.flex=!1,t["flex-basis"]=!1,t["flex-direction"]=!1,t["flex-flow"]=!1,t["flex-grow"]=!1,t["flex-shrink"]=!1,t["flex-wrap"]=!1,t.float=!1,t["float-offset"]=!1,t["flood-color"]=!1,t["flood-opacity"]=!1,t["flow-from"]=!1,t["flow-into"]=!1,t.font=!0,t["font-family"]=!0,t["font-feature-settings"]=!0,t["font-kerning"]=!0,t["font-language-override"]=!0,t["font-size"]=!0,t["font-size-adjust"]=!0,t["font-stretch"]=!0,t["font-style"]=!0,t["font-synthesis"]=!0,t["font-variant"]=!0,t["font-variant-alternates"]=!0,t["font-variant-caps"]=!0,t["font-variant-east-asian"]=!0,t["font-variant-ligatures"]=!0,t["font-variant-numeric"]=!0,t["font-variant-position"]=!0,t["font-weight"]=!0,t.grid=!1,t["grid-area"]=!1,t["grid-auto-columns"]=!1,t["grid-auto-flow"]=!1,t["grid-auto-rows"]=!1,t["grid-column"]=!1,t["grid-column-end"]=!1,t["grid-column-start"]=!1,t["grid-row"]=!1,t["grid-row-end"]=!1,t["grid-row-start"]=!1,t["grid-template"]=!1,t["grid-template-areas"]=!1,t["grid-template-columns"]=!1,t["grid-template-rows"]=!1,t["hanging-punctuation"]=!1,t.height=!0,t.hyphens=!1,t.icon=!1,t["image-orientation"]=!1,t["image-resolution"]=!1,t["ime-mode"]=!1,t["initial-letters"]=!1,t["inline-box-align"]=!1,t["justify-content"]=!1,t["justify-items"]=!1,t["justify-self"]=!1,t.left=!1,t["letter-spacing"]=!0,t["lighting-color"]=!0,t["line-box-contain"]=!1,t["line-break"]=!1,t["line-grid"]=!1,t["line-height"]=!1,t["line-snap"]=!1,t["line-stacking"]=!1,t["line-stacking-ruby"]=!1,t["line-stacking-shift"]=!1,t["line-stacking-strategy"]=!1,t["list-style"]=!0,t["list-style-image"]=!0,t["list-style-position"]=!0,t["list-style-type"]=!0,t.margin=!0,t["margin-bottom"]=!0,t["margin-left"]=!0,t["margin-right"]=!0,t["margin-top"]=!0,t["marker-offset"]=!1,t["marker-side"]=!1,t.marks=!1,t.mask=!1,t["mask-box"]=!1,t["mask-box-outset"]=!1,t["mask-box-repeat"]=!1,t["mask-box-slice"]=!1,t["mask-box-source"]=!1,t["mask-box-width"]=!1,t["mask-clip"]=!1,t["mask-image"]=!1,t["mask-origin"]=!1,t["mask-position"]=!1,t["mask-repeat"]=!1,t["mask-size"]=!1,t["mask-source-type"]=!1,t["mask-type"]=!1,t["max-height"]=!0,t["max-lines"]=!1,t["max-width"]=!0,t["min-height"]=!0,t["min-width"]=!0,t["move-to"]=!1,t["nav-down"]=!1,t["nav-index"]=!1,t["nav-left"]=!1,t["nav-right"]=!1,t["nav-up"]=!1,t["object-fit"]=!1,t["object-position"]=!1,t.opacity=!1,t.order=!1,t.orphans=!1,t.outline=!1,t["outline-color"]=!1,t["outline-offset"]=!1,t["outline-style"]=!1,t["outline-width"]=!1,t.overflow=!1,t["overflow-wrap"]=!1,t["overflow-x"]=!1,t["overflow-y"]=!1,t.padding=!0,t["padding-bottom"]=!0,t["padding-left"]=!0,t["padding-right"]=!0,t["padding-top"]=!0,t.page=!1,t["page-break-after"]=!1,t["page-break-before"]=!1,t["page-break-inside"]=!1,t["page-policy"]=!1,t.pause=!1,t["pause-after"]=!1,t["pause-before"]=!1,t.perspective=!1,t["perspective-origin"]=!1,t.pitch=!1,t["pitch-range"]=!1,t["play-during"]=!1,t.position=!1,t["presentation-level"]=!1,t.quotes=!1,t["region-fragment"]=!1,t.resize=!1,t.rest=!1,t["rest-after"]=!1,t["rest-before"]=!1,t.richness=!1,t.right=!1,t.rotation=!1,t["rotation-point"]=!1,t["ruby-align"]=!1,t["ruby-merge"]=!1,t["ruby-position"]=!1,t["shape-image-threshold"]=!1,t["shape-outside"]=!1,t["shape-margin"]=!1,t.size=!1,t.speak=!1,t["speak-as"]=!1,t["speak-header"]=!1,t["speak-numeral"]=!1,t["speak-punctuation"]=!1,t["speech-rate"]=!1,t.stress=!1,t["string-set"]=!1,t["tab-size"]=!1,t["table-layout"]=!1,t["text-align"]=!0,t["text-align-last"]=!0,t["text-combine-upright"]=!0,t["text-decoration"]=!0,t["text-decoration-color"]=!0,t["text-decoration-line"]=!0,t["text-decoration-skip"]=!0,t["text-decoration-style"]=!0,t["text-emphasis"]=!0,t["text-emphasis-color"]=!0,t["text-emphasis-position"]=!0,t["text-emphasis-style"]=!0,t["text-height"]=!0,t["text-indent"]=!0,t["text-justify"]=!0,t["text-orientation"]=!0,t["text-overflow"]=!0,t["text-shadow"]=!0,t["text-space-collapse"]=!0,t["text-transform"]=!0,t["text-underline-position"]=!0,t["text-wrap"]=!0,t.top=!1,t.transform=!1,t["transform-origin"]=!1,t["transform-style"]=!1,t.transition=!1,t["transition-delay"]=!1,t["transition-duration"]=!1,t["transition-property"]=!1,t["transition-timing-function"]=!1,t["unicode-bidi"]=!1,t["vertical-align"]=!1,t.visibility=!1,t["voice-balance"]=!1,t["voice-duration"]=!1,t["voice-family"]=!1,t["voice-pitch"]=!1,t["voice-range"]=!1,t["voice-rate"]=!1,t["voice-stress"]=!1,t["voice-volume"]=!1,t.volume=!1,t["white-space"]=!1,t.widows=!1,t.width=!0,t["will-change"]=!1,t["word-break"]=!0,t["word-spacing"]=!0,t["word-wrap"]=!0,t["wrap-flow"]=!1,t["wrap-through"]=!1,t["writing-mode"]=!1,t["z-index"]=!1,t}var n=/javascript\s*\:/img;e.whiteList=r(),e.getDefaultWhiteList=r,e.onAttr=function(t,e,r){},e.onIgnoreAttr=function(t,e,r){},e.safeAttrValue=function(t,e){return n.test(e)?"":e}},40101:function(t,e,r){var n=r(53140),i=r(25766);for(var o in(e=t.exports=function(t,e){return new i(e).process(t)}).FilterCSS=i,n)e[o]=n[o];"undefined"!=typeof window&&(window.filterCSS=t.exports)},50694:function(t,e,r){var n=r(66380);t.exports=function(t,e){";"!==(t=n.trimRight(t))[t.length-1]&&(t+=";");var r=t.length,i=!1,o=0,a=0,s="";function l(){if(!i){var r=n.trim(t.slice(o,a)),l=r.indexOf(":");if(-1!==l){var c=n.trim(r.slice(0,l)),u=n.trim(r.slice(l+1));if(c){var f=e(o,s.length,c,u,r);f&&(s+=f+"; ")}}}o=a+1}for(;a<r;a++){var c=t[a];if("/"===c&&"*"===t[a+1]){var u=t.indexOf("*/",a+2);if(-1===u)break;o=(a=u+1)+1,i=!1}else"("===c?i=!0:")"===c?i=!1:";"===c?i||l():"\n"===c&&l()}return n.trim(s)}},66380:function(t){t.exports={indexOf:function(t,e){var r,n;if(Array.prototype.indexOf)return t.indexOf(e);for(r=0,n=t.length;r<n;r++)if(t[r]===e)return r;return -1},forEach:function(t,e,r){var n,i;if(Array.prototype.forEach)return t.forEach(e,r);for(n=0,i=t.length;n<i;n++)e.call(r,t[n],n,t)},trim:function(t){return String.prototype.trim?t.trim():t.replace(/(^\s*)|(\s*$)/g,"")},trimRight:function(t){return String.prototype.trimRight?t.trimRight():t.replace(/(\s*$)/g,"")}}},56855:function(t,e,r){var n=r(40101).FilterCSS,i=r(40101).getDefaultWhiteList,o=r(12665);function a(){return{a:["target","href","title"],abbr:["title"],address:[],area:["shape","coords","href","alt"],article:[],aside:[],audio:["autoplay","controls","crossorigin","loop","muted","preload","src",],b:[],bdi:["dir"],bdo:["dir"],big:[],blockquote:["cite"],br:[],caption:[],center:[],cite:[],code:[],col:["align","valign","span","width"],colgroup:["align","valign","span","width"],dd:[],del:["datetime"],details:["open"],div:[],dl:[],dt:[],em:[],figcaption:[],figure:[],font:["color","size","face"],footer:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],header:[],hr:[],i:[],img:["src","alt","title","width","height"],ins:["datetime"],li:[],mark:[],nav:[],ol:[],p:[],pre:[],s:[],section:[],small:[],span:[],sub:[],summary:[],sup:[],strong:[],strike:[],table:["width","border","align","valign"],tbody:["align","valign"],td:["width","rowspan","colspan","align","valign"],tfoot:["align","valign"],th:["width","rowspan","colspan","align","valign"],thead:["align","valign"],tr:["rowspan","align","valign"],tt:[],u:[],ul:[],video:["autoplay","controls","crossorigin","loop","muted","playsinline","poster","preload","src","height","width",]}}var s=new n;function l(t){return t.replace(c,"&lt;").replace(u,"&gt;")}var c=/</g,u=/>/g,f=/"/g,g=/&quot;/g,d=/&#([a-zA-Z0-9]*);?/gim,p=/&colon;?/gim,h=/&newline;?/gim,m=/((j\s*a\s*v\s*a|v\s*b|l\s*i\s*v\s*e)\s*s\s*c\s*r\s*i\s*p\s*t\s*|m\s*o\s*c\s*h\s*a):/gi,b=/e\s*x\s*p\s*r\s*e\s*s\s*s\s*i\s*o\s*n\s*\(.*/gi,v=/u\s*r\s*l\s*\(.*/gi;function w(t){return t.replace(f,"&quot;")}function y(t){return t.replace(g,'"')}function x(t){return t.replace(d,function(t,e){return"x"===e[0]||"X"===e[0]?String.fromCharCode(parseInt(e.substr(1),16)):String.fromCharCode(parseInt(e,10))})}function k(t){return t.replace(p,":").replace(h," ")}function A(t){for(var e="",r=0,n=t.length;r<n;r++)e+=32>t.charCodeAt(r)?" ":t.charAt(r);return o.trim(e)}function T(t){return t=A(t=k(t=x(t=y(t))))}function I(t){return t=l(t=w(t))}function S(){return""}e.whiteList=a(),e.getDefaultWhiteList=a,e.onTag=function(t,e,r){},e.onIgnoreTag=function(t,e,r){},e.onTagAttr=function(t,e,r){},e.onIgnoreTagAttr=function(t,e,r){},e.safeAttrValue=function(t,e,r,n){if(r=T(r),"href"===e||"src"===e){if("#"===(r=o.trim(r)))return"#";if(!("http://"===r.substr(0,7)||"https://"===r.substr(0,8)||"mailto:"===r.substr(0,7)||"tel:"===r.substr(0,4)||"data:image/"===r.substr(0,11)||"ftp://"===r.substr(0,6)||"./"===r.substr(0,2)||"../"===r.substr(0,3)||"#"===r[0]||"/"===r[0]))return""}else if("background"===e){if(m.lastIndex=0,m.test(r))return""}else if("style"===e){if(b.lastIndex=0,b.test(r)||(v.lastIndex=0,v.test(r)&&(m.lastIndex=0,m.test(r))))return"";!1!==n&&(r=(n=n||s).process(r))}return r=I(r)},e.escapeHtml=l,e.escapeQuote=w,e.unescapeQuote=y,e.escapeHtmlEntities=x,e.escapeDangerHtml5Entities=k,e.clearNonPrintableCharacter=A,e.friendlyAttrValue=T,e.escapeAttrValue=I,e.onIgnoreTagStripAll=S,e.StripTagBody=function(t,e){"function"!=typeof e&&(e=function(){});var r=!Array.isArray(t),n=[],i=!1;return{onIgnoreTag:function(a,s,l){if(c=a,r?0:-1===o.indexOf(t,c))return e(a,s,l);if(!l.isClosing)return i||(i=l.position),"[removed]";var c,u="[/removed]",f=l.position+u.length;return n.push([!1!==i?i:l.position,f,]),i=!1,u},remove:function(t){var e="",r=0;return o.forEach(n,function(n){e+=t.slice(r,n[0]),r=n[1]}),e+=t.slice(r)}}},e.stripCommentTag=function(t){for(var e="",r=0;r<t.length;){var n=t.indexOf("<!--",r);if(-1===n){e+=t.slice(r);break}e+=t.slice(r,n);var i=t.indexOf("-->",n);if(-1===i)break;r=i+3}return e},e.stripBlankChar=function(t){var e=t.split("");return(e=e.filter(function(t){var e=t.charCodeAt(0);return 127!==e&&(!(e<=31)||10===e||13===e)})).join("")},e.cssFilter=s,e.getDefaultCSSWhiteList=i},138:function(t,e,r){var n=r(56855),i=r(43310),o=r(91611);function a(t,e){return new o(e).process(t)}(e=t.exports=a).filterXSS=a,e.FilterXSS=o,function(){for(var t in n)e[t]=n[t];for(var r in i)e[r]=i[r]}(),"undefined"!=typeof window&&(window.filterXSS=t.exports),"undefined"!=typeof self&&"undefined"!=typeof DedicatedWorkerGlobalScope&&self instanceof DedicatedWorkerGlobalScope&&(self.filterXSS=t.exports)},43310:function(t,e,r){var n=r(12665);function i(t){var e,r=n.spaceIndex(t);return e=-1===r?t.slice(1,-1):t.slice(1,r+1),"/"===(e=n.trim(e).toLowerCase()).slice(0,1)&&(e=e.slice(1)),"/"===e.slice(-1)&&(e=e.slice(0,-1)),e}function o(t){return"</"===t.slice(0,2)}var a=/[^a-zA-Z0-9\\_:.-]/gim;function s(t,e){for(;e<t.length;e++){var r=t[e];if(" "!==r){if("="===r)return e;return -1}}}function l(t,e){for(;e<t.length;e++){var r=t[e];if(" "!==r){if("'"===r||'"'===r)return e;return -1}}}function c(t,e){for(;e>0;e--){var r=t[e];if(" "!==r){if("="===r)return e;return -1}}}function u(t){var e;return'"'===t[0]&&'"'===t[t.length-1]||"'"===t[0]&&"'"===t[t.length-1]?t.substr(1,t.length-2):t}e.parseTag=function(t,e,r){"use strict";var n="",a=0,s=!1,l=!1,c=0,u=t.length,f="",g="";chariterator:for(c=0;c<u;c++){var d=t.charAt(c);if(!1===s){if("<"===d){s=c;continue}}else if(!1===l){if("<"===d){n+=r(t.slice(a,c)),s=c,a=c;continue}if(">"===d||c===u-1){n+=r(t.slice(a,s)),f=i(g=t.slice(s,c+1)),n+=e(s,n.length,f,g,o(g)),a=c+1,s=!1;continue}if('"'===d||"'"===d)for(var p=1,h=t.charAt(c-p);""===h.trim()||"="===h;){if("="===h){l=d;continue chariterator}h=t.charAt(c-++p)}}else if(d===l){l=!1;continue}}return a<u&&(n+=r(t.substr(a))),n},e.parseAttr=function(t,e){"use strict";var r=0,i=0,o=[],f=!1,g=t.length;function d(t,r){if(!((t=(t=n.trim(t)).replace(a,"").toLowerCase()).length<1)){var i=e(t,r||"");i&&o.push(i)}}for(var p=0;p<g;p++){var h,m,b=t.charAt(p);if(!1===f&&"="===b){f=t.slice(r,p),r=p+1,i='"'===t.charAt(r)||"'"===t.charAt(r)?r:l(t,p+1);continue}if(!1!==f&&p===i){if(-1===(m=t.indexOf(b,p+1)))break;d(f,n.trim(t.slice(i+1,m))),f=!1,r=(p=m)+1;continue}if(/\s|\n|\t/.test(b)){if(t=t.replace(/\s|\n|\t/g," "),!1===f){if(-1===(m=s(t,p))){d(n.trim(t.slice(r,p))),f=!1,r=p+1;continue}p=m-1;continue}if(-1!==(m=c(t,p-1)))continue;d(f,u(n.trim(t.slice(r,p)))),f=!1,r=p+1;continue}}return r<t.length&&(!1===f?d(t.slice(r)):d(f,u(n.trim(t.slice(r))))),n.trim(o.join(" "))}},12665:function(t){t.exports={indexOf:function(t,e){var r,n;if(Array.prototype.indexOf)return t.indexOf(e);for(r=0,n=t.length;r<n;r++)if(t[r]===e)return r;return -1},forEach:function(t,e,r){var n,i;if(Array.prototype.forEach)return t.forEach(e,r);for(n=0,i=t.length;n<i;n++)e.call(r,t[n],n,t)},trim:function(t){return String.prototype.trim?t.trim():t.replace(/(^\s*)|(\s*$)/g,"")},spaceIndex:function(t){var e=/\s|\n|\t/.exec(t);return e?e.index:-1}}},91611:function(t,e,r){var n=r(40101).FilterCSS,i=r(56855),o=r(43310),a=o.parseTag,s=o.parseAttr,l=r(12665);function c(t){return null==t}function u(t){(t=function(t){var e={};for(var r in t)e[r]=t[r];return e}(t||{})).stripIgnoreTag&&(t.onIgnoreTag&&console.error('Notes: cannot use these two options "stripIgnoreTag" and "onIgnoreTag" at the same time'),t.onIgnoreTag=i.onIgnoreTagStripAll),t.whiteList||t.allowList?t.whiteList=function(t){var e={};for(var r in t)Array.isArray(t[r])?e[r.toLowerCase()]=t[r].map(function(t){return t.toLowerCase()}):e[r.toLowerCase()]=t[r];return e}(t.whiteList||t.allowList):t.whiteList=i.whiteList,t.onTag=t.onTag||i.onTag,t.onTagAttr=t.onTagAttr||i.onTagAttr,t.onIgnoreTag=t.onIgnoreTag||i.onIgnoreTag,t.onIgnoreTagAttr=t.onIgnoreTagAttr||i.onIgnoreTagAttr,t.safeAttrValue=t.safeAttrValue||i.safeAttrValue,t.escapeHtml=t.escapeHtml||i.escapeHtml,this.options=t,!1===t.css?this.cssFilter=!1:(t.css=t.css||{},this.cssFilter=new n(t.css))}u.prototype.process=function(t){if(!(t=(t=t||"").toString()))return"";var e=this.options,r=e.whiteList,n=e.onTag,o=e.onIgnoreTag,u=e.onTagAttr,f=e.onIgnoreTagAttr,g=e.safeAttrValue,d=e.escapeHtml,p=this.cssFilter;e.stripBlankChar&&(t=i.stripBlankChar(t)),e.allowCommentTag||(t=i.stripCommentTag(t));var h=!1;e.stripIgnoreTagBody&&(o=(h=i.StripTagBody(e.stripIgnoreTagBody,o)).onIgnoreTag);var m=a(t,function(t,e,i,a,h){var m={sourcePosition:t,position:e,isClosing:h,isWhite:Object.prototype.hasOwnProperty.call(r,i)},b=n(i,a,m);if(!c(b))return b;if(m.isWhite){if(m.isClosing)return"</"+i+">";var v=function t(e){var r=l.spaceIndex(e);if(-1===r)return{html:"",closing:"/"===e[e.length-2]};var n="/"===(e=l.trim(e.slice(r+1,-1)))[e.length-1];return n&&(e=l.trim(e.slice(0,-1))),{html:e,closing:n}}(a),w=r[i],y=s(v.html,function(t,e){var r=-1!==l.indexOf(w,t),n=u(i,t,e,r);return c(n)?r?(e=g(i,t,e,p))?t+'="'+e+'"':t:(n=f(i,t,e,r),c(n))?void 0:n:n});return a="<"+i,y&&(a+=" "+y),v.closing&&(a+=" /"),a+=">"}return(b=o(i,a,m),c(b))?d(a):b},d);return h&&(m=h.remove(m)),m},t.exports=u}}]);
src/pandora/flask/static/_next/static/chunks/554.9b8bfd0762461d74.js ADDED
@@ -0,0 +1 @@
 
 
1
+ "use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[554],{76554:function(t,e,n){n.r(e),n.d(e,{getLocalhostPluginHttpApiCallData:function(){return l},makeLocalhostPluginHttpApiCall:function(){return c}});var r=n(61706),a=n(31501),o=n(45813),s=n(8844),i=n(68619);function l(t){var e,n=null===(e=t.metadata)||void 0===e?void 0:e.http_api_call_data;if(void 0!==n){if(t.author.role!==i.uU.Assistant){console.error("Refusing to make localhost plugin HTTP call from non-assistant message",t);return}if("object"!=typeof n||"string"!=typeof n.namespace||0===n.namespace.length||"string"!=typeof n.function_name||0===n.function_name.length||"string"!=typeof n.parent_message_id||0===n.parent_message_id.length||"string"!=typeof n.url||0===n.url.length||"string"!=typeof n.method||!["get","post","put","delete","patch"].includes(n.method)||!Array.isArray(n.qs_params)||n.qs_params.some(function(t){return!Array.isArray(t)||2!==t.length||"string"!=typeof t[0]||"string"!=typeof t[1]})||"object"!=typeof n.headers||Object.keys(n.headers).some(function(t){return"string"!=typeof t})||Object.values(n.headers).some(function(t){return"string"!=typeof t})||!(null===n.body||"object"==typeof n.body&&Object.keys(n.body).every(function(t){return"string"==typeof t}))||"string"!=typeof n.api_function_type||!["kwargs","chat"].includes(n.api_function_type)){console.error("Refusing to make localhost plugin HTTP call with invalid metadata",t);return}if(!/^https?:\/\/localhost:/.test(n.url)){console.error("Refusing to make localhost plugin HTTP call with non-localhost URL",t);return}return n}}function c(t){return u.apply(this,arguments)}function u(){return(u=(0,r.Z)(function(t){var e,n;return(0,o.__generator)(this,function(n){switch(n.label){case 0:return n.trys.push([0,2,,3]),[4,function(t){return p.apply(this,arguments)}(t)];case 1:return[2,n.sent()];case 2:return e=n.sent(),console.error("Error making localhost plugin HTTP call",e),[2,[{id:(0,s.Z)(),author:{role:i.uU.System},role:i.uU.Tool,content:{content_type:"text",parts:["Error making localhost plugin HTTP call: ".concat(e)]},metadata:{parent_message_id:t.parent_message_id,is_complete:!0}}]];case 3:return[2]}})})).apply(this,arguments)}function p(){return(p=(0,r.Z)(function(t){var e,n,r,l,c,u;function p(t){return Object.keys(t).map(function(t){return t.toLowerCase()})}return(0,o.__generator)(this,function(o){switch(o.label){case 0:var l,u;if(e={"content-type":"application/json"},u=(l=[p(t.headers),p(e)]).flat(),new Set(u).size!==u.length)throw Error("Refusing to make localhost plugin HTTP call with duplicate header keys");return n=t.url,t.qs_params.length>0&&(n=n+"?"+new URLSearchParams(t.qs_params)),r=void 0,null!==t.body&&(r=JSON.stringify(t.body)),[4,fetch(n,{method:t.method,headers:(0,a.Z)({},e,t.headers),body:r})];case 1:return[4,o.sent().text()];case 2:if(c=o.sent(),"chat"===t.api_function_type)return[2,[JSON.parse(c)]];if("kwargs"===t.api_function_type)return[2,[{id:(0,s.Z)(),author:{role:i.uU.Tool,name:"".concat(t.namespace,".").concat(t.function_name)},role:i.uU.Tool,content:{content_type:"text",parts:[c]},metadata:{parent_message_id:t.parent_message_id,is_complete:!0}}]];throw Error("Not implemented")}})})).apply(this,arguments)}}}]);
src/pandora/flask/static/_next/static/chunks/68a27ff6-1185184b61bc22d0.js ADDED
@@ -0,0 +1 @@
 
 
1
+ "use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[798],{13002:function(t,n,r){r.d(n,{oT$:function(){return o}});var e=r(50913);function o(t){return(0,e.w_)({tag:"svg",attr:{fill:"none",viewBox:"0 0 24 24",stroke:"currentColor"},child:[{tag:"path",attr:{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"2",d:"M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4"}}]})(t)}}}]);
src/pandora/flask/static/_next/static/chunks/762-222df1028c0c1555.js ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ "use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[762],{10538:function(t,e,r){/**
2
+ * @license React
3
+ * use-sync-external-store-shim.production.min.js
4
+ *
5
+ * Copyright (c) Facebook, Inc. and its affiliates.
6
+ *
7
+ * This source code is licensed under the MIT license found in the
8
+ * LICENSE file in the root directory of this source tree.
9
+ */ var s=r(70079),n="function"==typeof Object.is?Object.is:function(t,e){return t===e&&(0!==t||1/t==1/e)||t!=t&&e!=e},i=s.useState,u=s.useEffect,o=s.useLayoutEffect,c=s.useDebugValue;function l(t){var e=t.getSnapshot;t=t.value;try{var r=e();return!n(t,r)}catch(s){return!0}}function a(t,e){return e()}var h="undefined"==typeof window||void 0===window.document||void 0===window.document.createElement?a:function(t,e){var r=e(),s=i({inst:{value:r,getSnapshot:e}}),n=s[0].inst,a=s[1];return o(function(){n.value=r,n.getSnapshot=e,l(n)&&a({inst:n})},[t,r,e]),u(function(){return l(n)&&a({inst:n}),t(function(){l(n)&&a({inst:n})})},[t]),c(r),r};e.useSyncExternalStore=void 0!==s.useSyncExternalStore?s.useSyncExternalStore:h},31178:function(t,e,r){t.exports=r(10538)},89335:function(t,e,r){r.d(e,{z:function(){return c}});var s=r(49043),n=r(42422),i=r(31406),u=r(94521),o=r(99695);class c extends u.l{constructor(t,e){super(),this.client=t,this.options=e,this.trackedProps=new Set,this.selectError=null,this.bindMethods(),this.setOptions(e)}bindMethods(){this.remove=this.remove.bind(this),this.refetch=this.refetch.bind(this)}onSubscribe(){1===this.listeners.length&&(this.currentQuery.addObserver(this),l(this.currentQuery,this.options)&&this.executeFetch(),this.updateTimers())}onUnsubscribe(){this.listeners.length||this.destroy()}shouldFetchOnReconnect(){return a(this.currentQuery,this.options,this.options.refetchOnReconnect)}shouldFetchOnWindowFocus(){return a(this.currentQuery,this.options,this.options.refetchOnWindowFocus)}destroy(){this.listeners=[],this.clearStaleTimeout(),this.clearRefetchInterval(),this.currentQuery.removeObserver(this)}setOptions(t,e){let r=this.options,n=this.currentQuery;if(this.options=this.client.defaultQueryOptions(t),(0,s.VS)(r,this.options)||this.client.getQueryCache().notify({type:"observerOptionsUpdated",query:this.currentQuery,observer:this}),void 0!==this.options.enabled&&"boolean"!=typeof this.options.enabled)throw Error("Expected enabled to be a boolean");this.options.queryKey||(this.options.queryKey=r.queryKey),this.updateQuery();let i=this.hasListeners();i&&h(this.currentQuery,n,this.options,r)&&this.executeFetch(),this.updateResult(e),i&&(this.currentQuery!==n||this.options.enabled!==r.enabled||this.options.staleTime!==r.staleTime)&&this.updateStaleTimeout();let u=this.computeRefetchInterval();i&&(this.currentQuery!==n||this.options.enabled!==r.enabled||u!==this.currentRefetchInterval)&&this.updateRefetchInterval(u)}getOptimisticResult(t){let e=this.client.getQueryCache().build(this.client,t);return this.createResult(e,t)}getCurrentResult(){return this.currentResult}trackResult(t){let e={};return Object.keys(t).forEach(r=>{Object.defineProperty(e,r,{configurable:!1,enumerable:!0,get:()=>(this.trackedProps.add(r),t[r])})}),e}getCurrentQuery(){return this.currentQuery}remove(){this.client.getQueryCache().remove(this.currentQuery)}refetch({refetchPage:t,...e}={}){return this.fetch({...e,meta:{refetchPage:t}})}fetchOptimistic(t){let e=this.client.defaultQueryOptions(t),r=this.client.getQueryCache().build(this.client,e);return r.isFetchingOptimistic=!0,r.fetch().then(()=>this.createResult(r,e))}fetch(t){var e;return this.executeFetch({...t,cancelRefetch:null==(e=t.cancelRefetch)||e}).then(()=>(this.updateResult(),this.currentResult))}executeFetch(t){this.updateQuery();let e=this.currentQuery.fetch(this.options,t);return null!=t&&t.throwOnError||(e=e.catch(s.ZT)),e}updateStaleTimeout(){if(this.clearStaleTimeout(),s.sk||this.currentResult.isStale||!(0,s.PN)(this.options.staleTime))return;let t=(0,s.Kp)(this.currentResult.dataUpdatedAt,this.options.staleTime);this.staleTimeoutId=setTimeout(()=>{this.currentResult.isStale||this.updateResult()},t+1)}computeRefetchInterval(){var t;return"function"==typeof this.options.refetchInterval?this.options.refetchInterval(this.currentResult.data,this.currentQuery):null!=(t=this.options.refetchInterval)&&t}updateRefetchInterval(t){this.clearRefetchInterval(),this.currentRefetchInterval=t,!s.sk&&!1!==this.options.enabled&&(0,s.PN)(this.currentRefetchInterval)&&0!==this.currentRefetchInterval&&(this.refetchIntervalId=setInterval(()=>{(this.options.refetchIntervalInBackground||i.j.isFocused())&&this.executeFetch()},this.currentRefetchInterval))}updateTimers(){this.updateStaleTimeout(),this.updateRefetchInterval(this.computeRefetchInterval())}clearStaleTimeout(){this.staleTimeoutId&&(clearTimeout(this.staleTimeoutId),this.staleTimeoutId=void 0)}clearRefetchInterval(){this.refetchIntervalId&&(clearInterval(this.refetchIntervalId),this.refetchIntervalId=void 0)}createResult(t,e){let r=this.currentQuery,n=this.options,i=this.currentResult,u=this.currentResultState,c=this.currentResultOptions,a=t!==r,f=a?t.state:this.currentQueryInitialState,p=a?this.currentResult:this.previousQueryResult,{state:y}=t,{dataUpdatedAt:v,error:R,errorUpdatedAt:S,fetchStatus:b,status:m}=y,E=!1,Q=!1,g;if(e._optimisticResults){let I=this.hasListeners(),C=!I&&l(t,e),O=I&&h(t,r,e,n);(C||O)&&(b=(0,o.Kw)(t.options.networkMode)?"fetching":"paused",v||(m="loading")),"isRestoring"===e._optimisticResults&&(b="idle")}if(e.keepPreviousData&&!y.dataUpdatedAt&&null!=p&&p.isSuccess&&"error"!==m)g=p.data,v=p.dataUpdatedAt,m=p.status,E=!0;else if(e.select&&void 0!==y.data){if(i&&y.data===(null==u?void 0:u.data)&&e.select===this.selectFn)g=this.selectResult;else try{this.selectFn=e.select,g=e.select(y.data),g=(0,s.oE)(null==i?void 0:i.data,g,e),this.selectResult=g,this.selectError=null}catch(T){this.selectError=T}}else g=y.data;if(void 0!==e.placeholderData&&void 0===g&&"loading"===m){let w;if(null!=i&&i.isPlaceholderData&&e.placeholderData===(null==c?void 0:c.placeholderData))w=i.data;else if(w="function"==typeof e.placeholderData?e.placeholderData():e.placeholderData,e.select&&void 0!==w)try{w=e.select(w),this.selectError=null}catch(F){this.selectError=F}void 0!==w&&(m="success",g=(0,s.oE)(null==i?void 0:i.data,w,e),Q=!0)}this.selectError&&(R=this.selectError,g=this.selectResult,S=Date.now(),m="error");let U="fetching"===b,k="loading"===m,x="error"===m,P={status:m,fetchStatus:b,isLoading:k,isSuccess:"success"===m,isError:x,isInitialLoading:k&&U,data:g,dataUpdatedAt:v,error:R,errorUpdatedAt:S,failureCount:y.fetchFailureCount,failureReason:y.fetchFailureReason,errorUpdateCount:y.errorUpdateCount,isFetched:y.dataUpdateCount>0||y.errorUpdateCount>0,isFetchedAfterMount:y.dataUpdateCount>f.dataUpdateCount||y.errorUpdateCount>f.errorUpdateCount,isFetching:U,isRefetching:U&&!k,isLoadingError:x&&0===y.dataUpdatedAt,isPaused:"paused"===b,isPlaceholderData:Q,isPreviousData:E,isRefetchError:x&&0!==y.dataUpdatedAt,isStale:d(t,e),refetch:this.refetch,remove:this.remove};return P}updateResult(t){let e=this.currentResult,r=this.createResult(this.currentQuery,this.options);if(this.currentResultState=this.currentQuery.state,this.currentResultOptions=this.options,(0,s.VS)(r,e))return;this.currentResult=r;let n={cache:!0};(null==t?void 0:t.listeners)!==!1&&(()=>{if(!e)return!0;let{notifyOnChangeProps:t}=this.options;if("all"===t||!t&&!this.trackedProps.size)return!0;let r=new Set(null!=t?t:this.trackedProps);return this.options.useErrorBoundary&&r.add("error"),Object.keys(this.currentResult).some(t=>{let s=this.currentResult[t]!==e[t];return s&&r.has(t)})})()&&(n.listeners=!0),this.notify({...n,...t})}updateQuery(){let t=this.client.getQueryCache().build(this.client,this.options);if(t===this.currentQuery)return;let e=this.currentQuery;this.currentQuery=t,this.currentQueryInitialState=t.state,this.previousQueryResult=this.currentResult,this.hasListeners()&&(null==e||e.removeObserver(this),t.addObserver(this))}onQueryUpdate(t){let e={};"success"===t.type?e.onSuccess=!t.manual:"error"!==t.type||(0,o.DV)(t.error)||(e.onError=!0),this.updateResult(e),this.hasListeners()&&this.updateTimers()}notify(t){n.V.batch(()=>{var e,r,s,n,i,u,o,c;t.onSuccess?(null==(e=(r=this.options).onSuccess)||e.call(r,this.currentResult.data),null==(s=(n=this.options).onSettled)||s.call(n,this.currentResult.data,null)):t.onError&&(null==(i=(u=this.options).onError)||i.call(u,this.currentResult.error),null==(o=(c=this.options).onSettled)||o.call(c,void 0,this.currentResult.error)),t.listeners&&this.listeners.forEach(t=>{t(this.currentResult)}),t.cache&&this.client.getQueryCache().notify({query:this.currentQuery,type:"observerResultsUpdated"})})}}function l(t,e){var r,s;return!1!==e.enabled&&!t.state.dataUpdatedAt&&!("error"===t.state.status&&!1===e.retryOnMount)||t.state.dataUpdatedAt>0&&a(t,e,e.refetchOnMount)}function a(t,e,r){if(!1!==e.enabled){let s="function"==typeof r?r(t):r;return"always"===s||!1!==s&&d(t,e)}return!1}function h(t,e,r,s){return!1!==r.enabled&&(t!==e||!1===s.enabled)&&(!r.suspense||"error"!==t.state.status)&&d(t,r)}function d(t,e){return t.isStaleByTime(e.staleTime)}},404:function(t,e,r){r.d(e,{_:function(){return u}});var s=r(70079);let n,i=s.createContext((n=!1,{clearReset(){n=!1},reset(){n=!0},isReset:()=>n})),u=()=>s.useContext(i)},60112:function(t,e,r){r.d(e,{JN:function(){return u},KJ:function(){return o},pf:function(){return i}});var s=r(70079),n=r(83793);let i=(t,e)=>{(t.suspense||t.useErrorBoundary)&&!e.isReset()&&(t.retryOnMount=!1)},u=t=>{s.useEffect(()=>{t.clearReset()},[t])},o=({result:t,errorResetBoundary:e,useErrorBoundary:r,query:s})=>t.isError&&!e.isReset()&&!t.isFetching&&(0,n.L)(r,[t.error,s])},17866:function(t,e,r){r.d(e,{S:function(){return i}});var s=r(70079);let n=s.createContext(!1),i=()=>s.useContext(n);n.Provider},86857:function(t,e,r){r.d(e,{Fb:function(){return s},SB:function(){return i},Z$:function(){return n},j8:function(){return u}});let s=t=>{t.suspense&&"number"!=typeof t.staleTime&&(t.staleTime=1e3)},n=(t,e)=>t.isLoading&&t.isFetching&&!e,i=(t,e,r)=>(null==t?void 0:t.suspense)&&n(e,r),u=(t,e,r)=>e.fetchOptimistic(t).then(({data:e})=>{null==t.onSuccess||t.onSuccess(e),null==t.onSettled||t.onSettled(e,null)}).catch(e=>{r.clearReset(),null==t.onError||t.onError(e),null==t.onSettled||t.onSettled(void 0,e)})},52696:function(t,e,r){r.d(e,{r:function(){return h}});var s=r(70079),n=r(39858),i=r(42422),u=r(404),o=r(62906),c=r(17866),l=r(60112),a=r(86857);function h(t,e){let r=(0,o.NL)({context:t.context}),h=(0,c.S)(),d=(0,u._)(),f=r.defaultQueryOptions(t);f._optimisticResults=h?"isRestoring":"optimistic",f.onError&&(f.onError=i.V.batchCalls(f.onError)),f.onSuccess&&(f.onSuccess=i.V.batchCalls(f.onSuccess)),f.onSettled&&(f.onSettled=i.V.batchCalls(f.onSettled)),(0,a.Fb)(f),(0,l.pf)(f,d),(0,l.JN)(d);let[p]=s.useState(()=>new e(r,f)),y=p.getOptimisticResult(f);if((0,n.$)(s.useCallback(t=>h?()=>void 0:p.subscribe(i.V.batchCalls(t)),[p,h]),()=>p.getCurrentResult(),()=>p.getCurrentResult()),s.useEffect(()=>{p.setOptions(f,{listeners:!1})},[f,p]),(0,a.SB)(f,y,h))throw(0,a.j8)(f,p,d);if((0,l.KJ)({result:y,errorResetBoundary:d,useErrorBoundary:f.useErrorBoundary,query:p.getCurrentQuery()}))throw y.error;return f.notifyOnChangeProps?y:p.trackResult(y)}},87762:function(t,e,r){r.d(e,{a:function(){return u}});var s=r(49043),n=r(89335),i=r(52696);function u(t,e,r){let u=(0,s._v)(t,e,r);return(0,i.r)(u,n.z)}},39858:function(t,e,r){r.d(e,{$:function(){return n}});var s=r(31178);let n=s.useSyncExternalStore},83793:function(t,e,r){r.d(e,{L:function(){return s}});function s(t,e){return"function"==typeof t?t(...e):!!t}}}]);
src/pandora/flask/static/_next/static/chunks/949.1a6eb804b5e91f61.js ADDED
@@ -0,0 +1 @@
 
 
1
+ "use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[949],{93949:function(e,n,t){t.r(n),t.d(n,{SANDBOX_LINK_PREFIX:function(){return s},default:function(){return f},handleSandboxLinkClick:function(){return d}});var r=t(61706),a=t(45813),i=t(35250),c=t(70079),l=t(33264);function o(e){var n=e.accept,t=e.children,r=e.onFilePicked,a=(0,c.useRef)(null),l=(0,c.useCallback)(function(){var e;null===(e=a.current)||void 0===e||e.click()},[]),o=(0,c.useCallback)(function(e){var n,t=null===(n=e.target.files)||void 0===n?void 0:n[0];t&&(r(t),e.target.value="")},[r]);return(0,i.jsxs)(i.Fragment,{children:["function"==typeof t?t({onClick:l}):(0,i.jsx)("span",{role:"button",onClick:l,children:t}),(0,i.jsx)("input",{type:"file",accept:n,ref:a,className:"hidden",onChange:o})]})}var u=t(74516),s="sandbox:";function d(e,n,t){var i;return i=(0,r.Z)(function(r){var i,c,o,s,d,f,h,p,b,v;return(0,a.__generator)(this,function(a){switch(a.label){case 0:if(!(e.has("tools2")&&(null==n?void 0:null===(i=n.enabledTools)||void 0===i?void 0:i.includes("tools2"))))return[2];return c=r.substring(8),[4,l.ZP.checkFile(t.current,c)];case 1:if((o=a.sent()).exists)return[3,2];return u.m.warning("File does not exist: ".concat(c)),[3,6];case 2:if(!o.too_large)return[3,3];return s=(o.size/1024/1024).toFixed(0),d="100",u.m.warning("File is larger than download limit: ".concat(s," MB vs ").concat(d," MB")),[3,6];case 3:return[4,l.ZP.fetchFileForDownload(t.current,c)];case 4:return[4,a.sent().blob()];case 5:h=a.sent(),p=window.URL.createObjectURL(h),(b=document.createElement("a")).href=p,v=c.split("/").pop(),b.download=v,b.click(),a.label=6;case 6:return[2]}})}),function(e){return i.apply(this,arguments)}}function f(e){var n,t=e.onFileUpload,s=e.threadId,d=e.currentLeafId,f=e.modelBackend,h=e.disabled,p=e.children,b=(0,c.useState)(!1),v=b[0],k=b[1],g=(0,c.useCallback)((n=(0,r.Z)(function(e){var n,r,i;return(0,a.__generator)(this,function(a){switch(a.label){case 0:k(!0),a.label=1;case 1:if(a.trys.push([1,,3,4]),e.size>104857600)return n=(e.size/1024/1024).toFixed(0),r="100",u.m.warning("File is larger than upload limit: ".concat(n," MB vs ").concat(r," MB"),{hasCloseButton:!0,duration:15}),[2];return[4,l.ZP.upload(d,s,f,e)];case 2:return t(a.sent()),[3,4];case 3:return k(!1),[7];case 4:return[2]}})}),function(e){return n.apply(this,arguments)}),[t,s,d,f]);return h||v?p(v):(0,i.jsx)(o,{onFilePicked:g,children:p(v)})}}}]);