Разработано веб-приложение
This commit is contained in:
		
							
								
								
									
										1
									
								
								app/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								app/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | |||||||
|  | from .main import app | ||||||
							
								
								
									
										31
									
								
								app/main.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								app/main.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,31 @@ | |||||||
|  | from fastapi import FastAPI | ||||||
|  | from fastapi.responses import HTMLResponse | ||||||
|  | from jinja2 import Environment, FileSystemLoader | ||||||
|  |  | ||||||
|  |  | ||||||
|  | app = FastAPI( | ||||||
|  |     openapi_url=None, | ||||||
|  |     docs_url=None, | ||||||
|  |     redoc_url=None, | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | env = Environment( | ||||||
|  |     loader=FileSystemLoader( | ||||||
|  |         searchpath='./templates', | ||||||
|  |     ), | ||||||
|  |     enable_async=True, | ||||||
|  | ) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @app.get('/') | ||||||
|  | async def function(): | ||||||
|  |     template = env.get_template('main.jinja2') | ||||||
|  |     return HTMLResponse( | ||||||
|  |         content=await template.render_async( | ||||||
|  |             title='Калькулятор рисков', | ||||||
|  |             description='Матрица n×m: игры с природой. Матрица 2×2: аналитический и графический методы.', | ||||||
|  |             keywords='калькулятор,теория рисков,теория игр,матрица,игры с природой,критерии,аналитический метод,графический метод', | ||||||
|  |             robots='all', | ||||||
|  |         ), | ||||||
|  |         status_code=200, | ||||||
|  |     ) | ||||||
							
								
								
									
										5
									
								
								main.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								main.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | |||||||
|  | from app import app | ||||||
|  |  | ||||||
|  |  | ||||||
|  | if __name__ == '__main__': | ||||||
|  |     app.run() | ||||||
							
								
								
									
										27
									
								
								nginx/main.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								nginx/main.conf
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,27 @@ | |||||||
|  | server { | ||||||
|  |     listen                  212.109.196.217:443 ssl; | ||||||
|  |     listen                  [2a01:230:4:700::6969]:443 ssl; | ||||||
|  |  | ||||||
|  |     server_name             risk-calc.csasq.ru; | ||||||
|  |     server_tokens           off; | ||||||
|  |  | ||||||
|  |     ssl_certificate         /etc/letsencrypt/live/csasq.ru/fullchain.pem; | ||||||
|  |     ssl_certificate_key     /etc/letsencrypt/live/csasq.ru/privkey.pem; | ||||||
|  |  | ||||||
|  |     keepalive_timeout       5; | ||||||
|  |  | ||||||
|  |     location / { | ||||||
|  |         include                 /opt/risk-calc.csasq.ru/nginx/secure-headers.conf; | ||||||
|  |         include                 ./conf.d/http-proxy.conf; | ||||||
|  |  | ||||||
|  |         proxy_pass              http://risk-calc.csasq.ru; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     location /static/ { | ||||||
|  |         include                 /opt/risk-calc.csasq.ru/nginx/secure-headers.conf; | ||||||
|  |         include                 ./conf.d/gzip.conf; | ||||||
|  |  | ||||||
|  |         root                    /opt/risk-calc.csasq.ru; | ||||||
|  |         expires                 1d; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										6
									
								
								nginx/secure-headers.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								nginx/secure-headers.conf
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,6 @@ | |||||||
|  | add_header	Content-Security-Policy "default-src 'self'; style-src 'self' 'unsafe-inline'"; | ||||||
|  | add_header	X-Frame-Options "DENY"; | ||||||
|  | add_header	X-Content-Type-Options "nosniff"; | ||||||
|  | add_header	Strict-Transport-Security "max-age=31536000; includeSubDomains"; | ||||||
|  | add_header	Referrer-Policy "origin"; | ||||||
|  | add_header	X-XSS-Protection "1; mode=block; report=mailto:security@csasq.ru"; | ||||||
							
								
								
									
										4
									
								
								requirements.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								requirements.txt
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,4 @@ | |||||||
|  | fastapi | ||||||
|  | gunicorn | ||||||
|  | jinja2 | ||||||
|  | uvicorn | ||||||
							
								
								
									
										
											BIN
										
									
								
								static/fonts/cyrillic-ext.woff2
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								static/fonts/cyrillic-ext.woff2
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								static/fonts/cyrillic.woff2
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								static/fonts/cyrillic.woff2
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								static/fonts/latin-ext.woff2
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								static/fonts/latin-ext.woff2
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								static/fonts/latin.woff2
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								static/fonts/latin.woff2
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								static/fonts/vietnamese.woff2
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								static/fonts/vietnamese.woff2
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										4
									
								
								static/icons/risk-calc.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								static/icons/risk-calc.svg
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,4 @@ | |||||||
|  | <svg id="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18"> | ||||||
|  |     <rect x="1" y="1" width="16" height="16" fill="#FFF" /> | ||||||
|  |     <path d="m16,0H2C.9,0,0,.9,0,2v14c0,1.1.9,2,2,2h14c1.1,0,2-.9,2-2V2c0-1.1-.9-2-2-2m-6,4.1l1.1-1.1,1.4,1.4,1.4-1.4,1.1,1.1-1.4,1.4,1.4,1.4-1.1,1.1-1.4-1.4-1.4,1.4-1.1-1.1,1.4-1.4-1.4-1.4m-6.8.6h5v1.5H3.2v-1.5m5.3,8.3h-2v2h-1.5v-2h-2v-1.5h2v-2h1.5v2h2v1.5m6.5,1.2h-5v-1.5h5v1.5m0-2.4h-5v-1.5h5v1.5Z" fill="#3574f0" /> | ||||||
|  | </svg> | ||||||
| After Width: | Height: | Size: 458 B | 
							
								
								
									
										4
									
								
								static/scripts/main.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								static/scripts/main.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,4 @@ | |||||||
|  | document.addEventListener('DOMContentLoaded', () => { | ||||||
|  |     window.application = new Application(); | ||||||
|  |     application.open(Application.DEFAULT_FRAGMENT); | ||||||
|  | }); | ||||||
							
								
								
									
										1174
									
								
								static/scripts/vendor.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1174
									
								
								static/scripts/vendor.js
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										306
									
								
								static/styles/main.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										306
									
								
								static/styles/main.css
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,306 @@ | |||||||
|  | @font-face { | ||||||
|  |     font-family: 'Exo 2'; | ||||||
|  |     font-style: normal; | ||||||
|  |     font-weight: 100 900; | ||||||
|  |     src: url('/static/fonts/cyrillic-ext.woff2') format('woff2'); | ||||||
|  |     unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @font-face { | ||||||
|  |     font-family: 'Exo 2'; | ||||||
|  |     font-style: normal; | ||||||
|  |     font-weight: 100 900; | ||||||
|  |     src: url('/static/fonts/cyrillic.woff2') format('woff2'); | ||||||
|  |     unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @font-face { | ||||||
|  |     font-family: 'Exo 2'; | ||||||
|  |     font-style: normal; | ||||||
|  |     font-weight: 100 900; | ||||||
|  |     src: url('/static/fonts/vietnamese.woff2') format('woff2'); | ||||||
|  |     unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @font-face { | ||||||
|  |     font-family: 'Exo 2'; | ||||||
|  |     font-style: normal; | ||||||
|  |     font-weight: 100 900; | ||||||
|  |     src: url('/static/fonts/latin-ext.woff2') format('woff2'); | ||||||
|  |     unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @font-face { | ||||||
|  |     font-family: 'Exo 2'; | ||||||
|  |     font-style: normal; | ||||||
|  |     font-weight: 100 900; | ||||||
|  |     src: url('/static/fonts/latin.woff2') format('woff2'); | ||||||
|  |     unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | :root { | ||||||
|  |     --color-1: #2E436E; | ||||||
|  |     --color-2: #1E1F22; | ||||||
|  |     --color-3: #2B2D30; | ||||||
|  |     --color-4: #43454A; | ||||||
|  |     --color-5: #575757; | ||||||
|  |     --color-6: #CED0D6; | ||||||
|  |     --color-7: #569ACC; | ||||||
|  |     --color-8: #3574F0; | ||||||
|  |     --color-9: #528D58; | ||||||
|  |     --color-10: #C94F4F; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | html, | ||||||
|  | input, | ||||||
|  | button, | ||||||
|  | textarea, | ||||||
|  | select { | ||||||
|  |     font-family: 'Exo 2', sans-serif; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | html, | ||||||
|  | body { | ||||||
|  |     height: 100%; | ||||||
|  |     color: var(--color-6); | ||||||
|  |     background-color: var(--color-2); | ||||||
|  |     color-scheme: dark light; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | body { | ||||||
|  |     display: flex; | ||||||
|  |     flex-direction: column; | ||||||
|  |     margin: 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | input[type="text"], | ||||||
|  | input[type="number"] { | ||||||
|  |     color: var(--color-6); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | a { | ||||||
|  |     color: var(--color-7); | ||||||
|  |     text-decoration: none; | ||||||
|  |     outline: none; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | a:hover, | ||||||
|  | a:focus { | ||||||
|  |     text-decoration: underline; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .hidden { | ||||||
|  |     display: none; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #top-bar { | ||||||
|  |     display: flex; | ||||||
|  |     justify-content: space-between; | ||||||
|  |     align-items: center; | ||||||
|  |     padding: .25rem .5rem; | ||||||
|  |     background-color: var(--color-3); | ||||||
|  |     border-bottom: solid 2px var(--color-2); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #logo { | ||||||
|  |     display: flex; | ||||||
|  |     align-items: center; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #icon { | ||||||
|  |     width: 1.5rem; | ||||||
|  |     height: 1.5rem; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #title { | ||||||
|  |     margin-left: .5rem; | ||||||
|  |     font-size: 1.2rem; | ||||||
|  |     font-weight: bold; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #actions { | ||||||
|  |     display: flex; | ||||||
|  |     align-items: center; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #actions button { | ||||||
|  |     display: flex; | ||||||
|  |     justify-content: center; | ||||||
|  |     align-items: center; | ||||||
|  |     padding: .4rem .6rem; | ||||||
|  |     color: var(--color-6); | ||||||
|  |     background: none; | ||||||
|  |     border: none; | ||||||
|  |     border-radius: .25rem; | ||||||
|  |     outline: none; | ||||||
|  |     font-size: 1rem; | ||||||
|  |     cursor: pointer; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #actions button:hover, | ||||||
|  | #actions button:focus { | ||||||
|  |     background: var(--color-4); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #actions .icon { | ||||||
|  |     width: 1.2rem; | ||||||
|  |     height: 1.2rem; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #content { | ||||||
|  |     position: sticky; | ||||||
|  |     display: flex; | ||||||
|  |     height: 100%; | ||||||
|  |     overflow-y: auto; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #menu { | ||||||
|  |     display: flex; | ||||||
|  |     flex-direction: column; | ||||||
|  |     justify-content: stretch; | ||||||
|  |     max-width: 16rem; | ||||||
|  |     background-color: var(--color-3); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #menu .header { | ||||||
|  |     padding: .75rem; | ||||||
|  |     font-weight: bold; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #menu .item { | ||||||
|  |     display: flex; | ||||||
|  |     align-items: stretch; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #menu input[type="button"] { | ||||||
|  |     padding: .5rem .75rem; | ||||||
|  |     width: 100%; | ||||||
|  |     color: var(--color-6); | ||||||
|  |     background: none; | ||||||
|  |     border: none; | ||||||
|  |     outline: none; | ||||||
|  |     white-space: pre-wrap; | ||||||
|  |     text-align: start; | ||||||
|  |     cursor: pointer; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #menu input[type="button"]:hover, | ||||||
|  | #menu input[type="button"]:focus { | ||||||
|  |     color: white; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #menu input[type="button"].active { | ||||||
|  |     color: white; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #menu .marker { | ||||||
|  |     width: 3px; | ||||||
|  |     background: none; | ||||||
|  |     border-radius: 3px; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #menu input[type="button"].active + .marker { | ||||||
|  |     background: var(--color-8); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #main { | ||||||
|  |     position: sticky; | ||||||
|  |     display: flex; | ||||||
|  |     width: 100%; | ||||||
|  |     overflow: auto; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #input { | ||||||
|  |     flex: 1 1 auto; | ||||||
|  |     padding: .75rem; | ||||||
|  |     min-width: 24rem; | ||||||
|  |     overflow: auto; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #input [data-fragment]:not(.active), | ||||||
|  | #output [data-fragment]:not(.active) { | ||||||
|  |     display: none; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #main input { | ||||||
|  |     width: 10rem; | ||||||
|  |     background: none; | ||||||
|  |     border: none; | ||||||
|  |     outline: solid 1px var(--color-5); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #main input:focus { | ||||||
|  |     outline: solid 2px var(--color-8); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #main input[type="button"] { | ||||||
|  |     padding: .25rem 1.5rem; | ||||||
|  |     width: 100%; | ||||||
|  |     color: white; | ||||||
|  |     border-radius: .25rem; | ||||||
|  |     outline: none; | ||||||
|  |     cursor: pointer; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #main input[type="button"].primary { | ||||||
|  |     padding: .25rem 1.5rem; | ||||||
|  |     background: var(--color-8); | ||||||
|  |     border: solid 1px var(--color-2); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #main input[type="button"].secondary { | ||||||
|  |     padding: .25rem 1.5rem; | ||||||
|  |     background: none; | ||||||
|  |     border: solid 1px var(--color-4); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #main input[type="button"]:focus { | ||||||
|  |     outline: solid 2px var(--color-8); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #output { | ||||||
|  |     flex: 1 1 auto; | ||||||
|  |     padding: .75rem; | ||||||
|  |     border-left: solid 1px var(--color-3); | ||||||
|  |     overflow: auto; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #bottom-bar { | ||||||
|  |     display: flex; | ||||||
|  |     justify-content: end; | ||||||
|  |     align-items: center; | ||||||
|  |     padding: .5rem; | ||||||
|  |     background-color: var(--color-3); | ||||||
|  |     border-top: solid .15rem var(--color-2); | ||||||
|  |     font-size: .8rem; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | table.properties th { | ||||||
|  |     font-weight: normal; | ||||||
|  |     text-align: start; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | table.properties th[colspan="2"] { | ||||||
|  |     padding: 1rem 0 .5rem 0; | ||||||
|  |     font-weight: bold; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | table.properties td:nth-child(2) { | ||||||
|  |     padding-left: 1rem; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | table.properties td[colspan="2"] { | ||||||
|  |     padding: .5rem 0 .5rem 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | table.properties td[colspan="2"] > div { | ||||||
|  |     display: flex; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | table.properties td[colspan="2"] > div > :not(:first-child) { | ||||||
|  |     margin-left: .5rem; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | table.matrix input { | ||||||
|  |     width: 3rem !important; | ||||||
|  | } | ||||||
							
								
								
									
										364
									
								
								templates/main.jinja2
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										364
									
								
								templates/main.jinja2
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,364 @@ | |||||||
|  | <!DOCTYPE html> | ||||||
|  | <html lang="ru"> | ||||||
|  |     <head> | ||||||
|  |         <meta charset="UTF-8" /> | ||||||
|  |         <meta name="application-name" content="Калькулятор рисков" /> | ||||||
|  |         <meta name="author" content="Иваницкий Глеб Олегович" /> | ||||||
|  |         <meta name="description" content="{{ description }}" /> | ||||||
|  |         <meta name="keywords" content="{{ keywords }}" /> | ||||||
|  |         <meta name="robots" content="{{ robots }}" /> | ||||||
|  |         <title>{{ title }}</title> | ||||||
|  |         <link rel="icon" href="/static/icons/risk-calc.svg" type="image/svg+xml" /> | ||||||
|  |         <link rel="stylesheet" href="/static/styles/main.css" /> | ||||||
|  |         <script src="/static/scripts/vendor.js"></script> | ||||||
|  |         <script src="/static/scripts/main.js"></script> | ||||||
|  |     </head> | ||||||
|  |     <body> | ||||||
|  |         <aside id="top-bar"> | ||||||
|  |             <div id="logo"> | ||||||
|  |                 <svg id="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18"> | ||||||
|  |                     <rect x="1" y="1" width="16" height="16" fill="#FFF"></rect> | ||||||
|  |                     <path d="m16,0H2C.9,0,0,.9,0,2v14c0,1.1.9,2,2,2h14c1.1,0,2-.9,2-2V2c0-1.1-.9-2-2-2m-6,4.1l1.1-1.1,1.4,1.4,1.4-1.4,1.1,1.1-1.4,1.4,1.4,1.4-1.1,1.1-1.4-1.4-1.4,1.4-1.1-1.1,1.4-1.4-1.4-1.4m-6.8.6h5v1.5H3.2v-1.5m5.3,8.3h-2v2h-1.5v-2h-2v-1.5h2v-2h1.5v2h2v1.5m6.5,1.2h-5v-1.5h5v1.5m0-2.4h-5v-1.5h5v1.5Z" fill="#3574f0"></path> | ||||||
|  |                 </svg> | ||||||
|  |                 <span id="title">Калькулятор рисков</span> | ||||||
|  |             </div> | ||||||
|  |             <div id="actions"> | ||||||
|  |                 <button id="solve"> | ||||||
|  |                     <svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"> | ||||||
|  |                         <path d="M73 39c-14.8-9.1-33.4-9.4-48.5-.9S0 62.6 0 80V432c0 17.4 9.4 33.4 24.5 41.9s33.7 8.1 48.5-.9L361 297c14.3-8.7 23-24.2 23-41s-8.7-32.2-23-41L73 39z" fill="var(--color-9)"></path> | ||||||
|  |                     </svg> | ||||||
|  |                     <span style="padding-left: .5rem; padding-right: .1rem;">Решить</span> | ||||||
|  |                 </button> | ||||||
|  |             </div> | ||||||
|  |         </aside> | ||||||
|  |         <div id="content"> | ||||||
|  |             <aside id="menu"> | ||||||
|  |                 <span class="header">Меню</span> | ||||||
|  |                 <div class="item"> | ||||||
|  |                     <input data-fragment="1" type="button" value="Матрица n×m. Игры с природой" /> | ||||||
|  |                     <div class="marker"></div> | ||||||
|  |                 </div> | ||||||
|  |                 <div class="item"> | ||||||
|  |                     <input data-fragment="2" type="button" value="Матрица 2×2. Графоаналитический метод" /> | ||||||
|  |                     <div class="marker"></div> | ||||||
|  |                 </div> | ||||||
|  |             </aside> | ||||||
|  |             <main id="main"> | ||||||
|  |                 <section id="input"> | ||||||
|  |                     <div data-fragment="1"> | ||||||
|  |                         <table id="fragment-1-matrix" class="matrix"></table> | ||||||
|  |                         <table class="properties"> | ||||||
|  |                             <tr> | ||||||
|  |                                 <th colspan="2">Размер матрицы</th> | ||||||
|  |                             </tr> | ||||||
|  |                             <tr> | ||||||
|  |                                 <th> | ||||||
|  |                                     <label for="fragment-1-width">Ширина:</label> | ||||||
|  |                                 </th> | ||||||
|  |                                 <td> | ||||||
|  |                                     <input id="fragment-1-width" type="number" min="2" value="2" /> | ||||||
|  |                                 </td> | ||||||
|  |                             </tr> | ||||||
|  |                             <tr> | ||||||
|  |                                 <th> | ||||||
|  |                                     <label for="fragment-1-height">Высота:</label> | ||||||
|  |                                 </th> | ||||||
|  |                                 <td> | ||||||
|  |                                     <input id="fragment-1-height" type="number" min="2" value="2" /> | ||||||
|  |                                 </td> | ||||||
|  |                             </tr> | ||||||
|  |                             <tr> | ||||||
|  |                                 <td colspan="2"> | ||||||
|  |                                     <input id="fragment-1-generate-matrix" class="primary" type="button" value="Применить" /> | ||||||
|  |                                 </td> | ||||||
|  |                             </tr> | ||||||
|  |                             <tr> | ||||||
|  |                                 <th colspan="2">Заполнить случайными значениями</th> | ||||||
|  |                             </tr> | ||||||
|  |                             <tr> | ||||||
|  |                                 <th> | ||||||
|  |                                     <label for="fragment-1-min-random-value">Минимальное:</label> | ||||||
|  |                                 </th> | ||||||
|  |                                 <td> | ||||||
|  |                                     <input id="fragment-1-min-random-value" type="number" value="0" /> | ||||||
|  |                                 </td> | ||||||
|  |                             </tr> | ||||||
|  |                             <tr> | ||||||
|  |                                 <th> | ||||||
|  |                                     <label for="fragment-1-max-random-value">Максимальное:</label> | ||||||
|  |                                 </th> | ||||||
|  |                                 <td> | ||||||
|  |                                     <input id="fragment-1-max-random-value" type="number" value="10" /> | ||||||
|  |                                 </td> | ||||||
|  |                             </tr> | ||||||
|  |                             <tr> | ||||||
|  |                                 <td colspan="2"> | ||||||
|  |                                     <div> | ||||||
|  |                                         <input id="fragment-1-fill-random-values" class="primary" type="button" value="Применить" /> | ||||||
|  |                                         <input id="fragment-1-clear-matrix" class="secondary" type="button" value="Очистить" /> | ||||||
|  |                                     </div> | ||||||
|  |                                 </td> | ||||||
|  |                             </tr> | ||||||
|  |                             <tr> | ||||||
|  |                                 <th colspan="2">Прочее</th> | ||||||
|  |                             </tr> | ||||||
|  |                             <tr> | ||||||
|  |                                 <th> | ||||||
|  |                                     <label for="fragment-1-optimism-criterion">Критерий оптимизма:</label> | ||||||
|  |                                 </th> | ||||||
|  |                                 <td> | ||||||
|  |                                     <input id="fragment-1-optimism-criterion" type="number" min="0" max="1" step=".1" value="0.5" /> | ||||||
|  |                                 </td> | ||||||
|  |                             </tr> | ||||||
|  |                             <tr> | ||||||
|  |                                 <th> | ||||||
|  |                                     <label for="fragment-1-fraction-digits">Точность округления:</label> | ||||||
|  |                                 </th> | ||||||
|  |                                 <td> | ||||||
|  |                                     <input id="fragment-1-fraction-digits" type="number" min="0" max="3" value="1" /> | ||||||
|  |                                 </td> | ||||||
|  |                             </tr> | ||||||
|  |                         </table> | ||||||
|  |                     </div> | ||||||
|  |                     <div data-fragment="2"> | ||||||
|  |                         <table id="fragment-2-matrix" class="matrix"></table> | ||||||
|  |                         <table class="properties"> | ||||||
|  |                             <tr> | ||||||
|  |                                 <th colspan="2">Заполнить случайными значениями</th> | ||||||
|  |                             </tr> | ||||||
|  |                             <tr> | ||||||
|  |                                 <th> | ||||||
|  |                                     <label for="fragment-2-min-random-value">Минимальное:</label> | ||||||
|  |                                 </th> | ||||||
|  |                                 <td> | ||||||
|  |                                     <input id="fragment-2-min-random-value" type="number" value="0" /> | ||||||
|  |                                 </td> | ||||||
|  |                             </tr> | ||||||
|  |                             <tr> | ||||||
|  |                                 <th> | ||||||
|  |                                     <label for="fragment-2-max-random-value">Максимальное:</label> | ||||||
|  |                                 </th> | ||||||
|  |                                 <td> | ||||||
|  |                                     <input id="fragment-2-max-random-value" type="number" value="10" /> | ||||||
|  |                                 </td> | ||||||
|  |                             </tr> | ||||||
|  |                             <tr> | ||||||
|  |                                 <td colspan="2"> | ||||||
|  |                                     <div> | ||||||
|  |                                         <input id="fragment-2-fill-random-values" class="primary" type="button" value="Применить" /> | ||||||
|  |                                         <input id="fragment-2-clear-matrix" class="secondary" type="button" value="Очистить" /> | ||||||
|  |                                     </div> | ||||||
|  |                                 </td> | ||||||
|  |                             </tr> | ||||||
|  |                             <tr> | ||||||
|  |                                 <th colspan="2">Прочее</th> | ||||||
|  |                             </tr> | ||||||
|  |                             <tr> | ||||||
|  |                                 <th> | ||||||
|  |                                     <label for="fragment-2-fraction-digits">Точность округления:</label> | ||||||
|  |                                 </th> | ||||||
|  |                                 <td> | ||||||
|  |                                     <input id="fragment-2-fraction-digits" type="number" min="0" max="3" value="2" /> | ||||||
|  |                                 </td> | ||||||
|  |                             </tr> | ||||||
|  |                             <tr> | ||||||
|  |                                 <th> | ||||||
|  |                                     <label for="fragment-2-graph-size">Размер графика:</label> | ||||||
|  |                                 </th> | ||||||
|  |                                 <td> | ||||||
|  |                                     <input id="fragment-2-graph-size" type="number" min="480" max="3840" value="720" /> | ||||||
|  |                                 </td> | ||||||
|  |                             </tr> | ||||||
|  |                         </table> | ||||||
|  |                     </div> | ||||||
|  |                 </section> | ||||||
|  |                 <section id="output"> | ||||||
|  |                     <div data-fragment="1"> | ||||||
|  |                         <table class="properties"> | ||||||
|  |                             <tr> | ||||||
|  |                                 <th colspan="2" style="padding-top: 0;">Седловая точка</th> | ||||||
|  |                             </tr> | ||||||
|  |                             <tr> | ||||||
|  |                                 <th> | ||||||
|  |                                     <label for="fragment-1-lowest-price">Нижняя цена игры:</label> | ||||||
|  |                                 </th> | ||||||
|  |                                 <td> | ||||||
|  |                                     <input id="fragment-1-lowest-price" type="text" data-value="" /> | ||||||
|  |                                 </td> | ||||||
|  |                             </tr> | ||||||
|  |                             <tr> | ||||||
|  |                                 <th> | ||||||
|  |                                     <label for="fragment-1-highest-price">Верхняя цена игры:</label> | ||||||
|  |                                 </th> | ||||||
|  |                                 <td> | ||||||
|  |                                     <input id="fragment-1-highest-price" type="text" data-value="" /> | ||||||
|  |                                 </td> | ||||||
|  |                             </tr> | ||||||
|  |                             <tr> | ||||||
|  |                                 <th> | ||||||
|  |                                     <label for="fragment-1-saddle-point">Седловая точка:</label> | ||||||
|  |                                 </th> | ||||||
|  |                                 <td> | ||||||
|  |                                     <input id="fragment-1-saddle-point" type="text" data-value="" /> | ||||||
|  |                                 </td> | ||||||
|  |                             </tr> | ||||||
|  |                             <tr> | ||||||
|  |                                 <th colspan="2">Критерии</th> | ||||||
|  |                             </tr> | ||||||
|  |                             <tr> | ||||||
|  |                                 <th> | ||||||
|  |                                     <label for="fragment-1-laplace-criterion">Критерий Лапласа:</label> | ||||||
|  |                                 </th> | ||||||
|  |                                 <td> | ||||||
|  |                                     <input id="fragment-1-laplace-criterion" type="text" data-value="" /> | ||||||
|  |                                 </td> | ||||||
|  |                             </tr> | ||||||
|  |                             <tr> | ||||||
|  |                                 <th> | ||||||
|  |                                     <label for="fragment-1-wald-criterion">Критерий Вальда:</label> | ||||||
|  |                                 </th> | ||||||
|  |                                 <td> | ||||||
|  |                                     <input id="fragment-1-wald-criterion" type="text" data-value="" /> | ||||||
|  |                                 </td> | ||||||
|  |                             </tr> | ||||||
|  |                             <tr> | ||||||
|  |                                 <th> | ||||||
|  |                                     <label for="fragment-1-max-of-max-criterion">Максимакс:</label> | ||||||
|  |                                 </th> | ||||||
|  |                                 <td> | ||||||
|  |                                     <input id="fragment-1-max-of-max-criterion" type="text" data-value="" /> | ||||||
|  |                                 </td> | ||||||
|  |                             </tr> | ||||||
|  |                             <tr> | ||||||
|  |                                 <th> | ||||||
|  |                                     <label for="fragment-1-min-of-min-criterion">Минимин:</label> | ||||||
|  |                                 </th> | ||||||
|  |                                 <td> | ||||||
|  |                                     <input id="fragment-1-min-of-min-criterion" type="text" data-value="" /> | ||||||
|  |                                 </td> | ||||||
|  |                             </tr> | ||||||
|  |                             <tr> | ||||||
|  |                                 <th> | ||||||
|  |                                     <label for="fragment-1-savage-criterion">Критерий Сэвиджа:</label> | ||||||
|  |                                 </th> | ||||||
|  |                                 <td> | ||||||
|  |                                     <input id="fragment-1-savage-criterion" type="text" data-value="" /> | ||||||
|  |                                 </td> | ||||||
|  |                             </tr> | ||||||
|  |                             <tr> | ||||||
|  |                                 <th> | ||||||
|  |                                     <label for="fragment-1-hurwitz-criterion">Критерий Гурвица:</label> | ||||||
|  |                                 </th> | ||||||
|  |                                 <td> | ||||||
|  |                                     <input id="fragment-1-hurwitz-criterion" type="text" data-value="" /> | ||||||
|  |                                 </td> | ||||||
|  |                             </tr> | ||||||
|  |                             <tr> | ||||||
|  |                                 <th colspan="2">Матрица сожалений</th> | ||||||
|  |                             </tr> | ||||||
|  |                         </table> | ||||||
|  |                         <table id="fragment-1-regret-matrix" class="matrix"></table> | ||||||
|  |                     </div> | ||||||
|  |                     <div data-fragment="2"> | ||||||
|  |                         <table class="properties"> | ||||||
|  |                             <tr> | ||||||
|  |                                 <th colspan="2" style="padding-top: 0;">Седловая точка</th> | ||||||
|  |                             </tr> | ||||||
|  |                             <tr> | ||||||
|  |                                 <th> | ||||||
|  |                                     <label for="fragment-2-lowest-price">Нижняя цена игры:</label> | ||||||
|  |                                 </th> | ||||||
|  |                                 <td> | ||||||
|  |                                     <input id="fragment-2-lowest-price" type="text" data-value="" /> | ||||||
|  |                                 </td> | ||||||
|  |                             </tr> | ||||||
|  |                             <tr> | ||||||
|  |                                 <th> | ||||||
|  |                                     <label for="fragment-2-highest-price">Верхняя цена игры:</label> | ||||||
|  |                                 </th> | ||||||
|  |                                 <td> | ||||||
|  |                                     <input id="fragment-2-highest-price" type="text" data-value="" /> | ||||||
|  |                                 </td> | ||||||
|  |                             </tr> | ||||||
|  |                             <tr> | ||||||
|  |                                 <th> | ||||||
|  |                                     <label for="fragment-2-saddle-point">Седловая точка:</label> | ||||||
|  |                                 </th> | ||||||
|  |                                 <td> | ||||||
|  |                                     <input id="fragment-2-saddle-point" type="text" data-value="" /> | ||||||
|  |                                 </td> | ||||||
|  |                             </tr> | ||||||
|  |                             <tr class="extra"> | ||||||
|  |                                 <th colspan="2">Вероятности стратегий и цена игры</th> | ||||||
|  |                             </tr> | ||||||
|  |                             <tr class="extra"> | ||||||
|  |                                 <th> | ||||||
|  |                                     <label for="fragment-2-p1">Стратегия A₁:</label> | ||||||
|  |                                 </th> | ||||||
|  |                                 <td> | ||||||
|  |                                     <input id="fragment-2-p1" type="text" data-value="" /> | ||||||
|  |                                 </td> | ||||||
|  |                             </tr> | ||||||
|  |                             <tr class="extra"> | ||||||
|  |                                 <th> | ||||||
|  |                                     <label for="fragment-2-p2">Стратегия A₂:</label> | ||||||
|  |                                 </th> | ||||||
|  |                                 <td> | ||||||
|  |                                     <input id="fragment-2-p2" type="text" data-value="" /> | ||||||
|  |                                 </td> | ||||||
|  |                             </tr> | ||||||
|  |                             <tr class="extra"> | ||||||
|  |                                 <th> | ||||||
|  |                                     <label for="fragment-2-q1">Стратегия B₁:</label> | ||||||
|  |                                 </th> | ||||||
|  |                                 <td> | ||||||
|  |                                     <input id="fragment-2-q1" type="text" data-value="" /> | ||||||
|  |                                 </td> | ||||||
|  |                             </tr> | ||||||
|  |                             <tr class="extra"> | ||||||
|  |                                 <th> | ||||||
|  |                                     <label for="fragment-2-q2">Стратегия B₂:</label> | ||||||
|  |                                 </th> | ||||||
|  |                                 <td> | ||||||
|  |                                     <input id="fragment-2-q2" type="text" data-value="" /> | ||||||
|  |                                 </td> | ||||||
|  |                             </tr> | ||||||
|  |                             <tr class="extra"> | ||||||
|  |                                 <th> | ||||||
|  |                                     <label for="fragment-2-v">Цена игры:</label> | ||||||
|  |                                 </th> | ||||||
|  |                                 <td> | ||||||
|  |                                     <input id="fragment-2-v" type="text" data-value="" /> | ||||||
|  |                                 </td> | ||||||
|  |                             </tr> | ||||||
|  |                         </table> | ||||||
|  |                         <table class="properties extra" style="margin-top: 1rem;"> | ||||||
|  |                             <tr> | ||||||
|  |                                 <th colspan="2" style="padding-top: 0;">График стратегий игрока A</th> | ||||||
|  |                             </tr> | ||||||
|  |                             <tr> | ||||||
|  |                                 <td> | ||||||
|  |                                     <canvas id="fragment-2-a-player-graph"></canvas> | ||||||
|  |                                 </td> | ||||||
|  |                             </tr> | ||||||
|  |                             <tr> | ||||||
|  |                                 <th colspan="2">График стратегий игрока B</th> | ||||||
|  |                             </tr> | ||||||
|  |                             <tr> | ||||||
|  |                                 <td> | ||||||
|  |                                     <canvas id="fragment-2-b-player-graph"></canvas> | ||||||
|  |                                 </td> | ||||||
|  |                             </tr> | ||||||
|  |                         </table> | ||||||
|  |                     </div> | ||||||
|  |                 </section> | ||||||
|  |             </main> | ||||||
|  |         </div> | ||||||
|  |         <aside id="bottom-bar"> | ||||||
|  |             <span>© Иваницкий Г. О., </span> | ||||||
|  |             <span id="copyright-years" data-from="2023">2023</span> | ||||||
|  |             <span>. </span> | ||||||
|  |             <a href="https://csasq.ru/about/contacts" target="_blank">Обратная связь</a> | ||||||
|  |         </aside> | ||||||
|  |     </body> | ||||||
|  | </html> | ||||||
		Reference in New Issue
	
	Block a user