├── .DS_Store ├── .gitattributes ├── CODE_OF_CONDUCT.md ├── LICENSE-Bootstrap ├── LICENSE.md ├── README.md ├── SECURITY.md ├── css ├── .DS_Store ├── bootstrap.min.css ├── bootstrap.min.css.map └── main.css ├── index.html ├── js ├── .DS_Store ├── bootstrap.min.js ├── bootstrap.min.js.map └── main.js └── screenshots ├── flsm.png ├── ip.png ├── netid.png └── vlsm.png /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vittorioPiotti/SubnettingSolver-Bootstrap/6b58d6b26c6106d1c70d4db079964d4022b51290/.DS_Store -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /LICENSE-Bootstrap: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2011-2024 The Bootstrap Authors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # GNU GENERAL PUBLIC LICENSE 2 | 3 | Version 3, 29 June 2007 4 | 5 | Copyright (C) 2024 SubnettingSolver author Vittorio Piotti 6 | 7 | 8 | Everyone is permitted to copy and distribute verbatim copies of this 9 | license document, but changing it is not allowed. 10 | 11 | ## Preamble 12 | 13 | The GNU General Public License is a free, copyleft license for 14 | software and other kinds of works. 15 | 16 | The licenses for most software and other practical works are designed 17 | to take away your freedom to share and change the works. By contrast, 18 | the GNU General Public License is intended to guarantee your freedom 19 | to share and change all versions of a program--to make sure it remains 20 | free software for all its users. We, the Free Software Foundation, use 21 | the GNU General Public License for most of our software; it applies 22 | also to any other work released this way by its authors. You can apply 23 | it to your programs, too. 24 | 25 | When we speak of free software, we are referring to freedom, not 26 | price. Our General Public Licenses are designed to make sure that you 27 | have the freedom to distribute copies of free software (and charge for 28 | them if you wish), that you receive source code or can get it if you 29 | want it, that you can change the software or use pieces of it in new 30 | free programs, and that you know you can do these things. 31 | 32 | To protect your rights, we need to prevent others from denying you 33 | these rights or asking you to surrender the rights. Therefore, you 34 | have certain responsibilities if you distribute copies of the 35 | software, or if you modify it: responsibilities to respect the freedom 36 | of others. 37 | 38 | For example, if you distribute copies of such a program, whether 39 | gratis or for a fee, you must pass on to the recipients the same 40 | freedoms that you received. You must make sure that they, too, receive 41 | or can get the source code. And you must show them these terms so they 42 | know their rights. 43 | 44 | Developers that use the GNU GPL protect your rights with two steps: 45 | (1) assert copyright on the software, and (2) offer you this License 46 | giving you legal permission to copy, distribute and/or modify it. 47 | 48 | For the developers' and authors' protection, the GPL clearly explains 49 | that there is no warranty for this free software. For both users' and 50 | authors' sake, the GPL requires that modified versions be marked as 51 | changed, so that their problems will not be attributed erroneously to 52 | authors of previous versions. 53 | 54 | Some devices are designed to deny users access to install or run 55 | modified versions of the software inside them, although the 56 | manufacturer can do so. This is fundamentally incompatible with the 57 | aim of protecting users' freedom to change the software. The 58 | systematic pattern of such abuse occurs in the area of products for 59 | individuals to use, which is precisely where it is most unacceptable. 60 | Therefore, we have designed this version of the GPL to prohibit the 61 | practice for those products. If such problems arise substantially in 62 | other domains, we stand ready to extend this provision to those 63 | domains in future versions of the GPL, as needed to protect the 64 | freedom of users. 65 | 66 | Finally, every program is threatened constantly by software patents. 67 | States should not allow patents to restrict development and use of 68 | software on general-purpose computers, but in those that do, we wish 69 | to avoid the special danger that patents applied to a free program 70 | could make it effectively proprietary. To prevent this, the GPL 71 | assures that patents cannot be used to render the program non-free. 72 | 73 | The precise terms and conditions for copying, distribution and 74 | modification follow. 75 | 76 | ## TERMS AND CONDITIONS 77 | 78 | ### 0. Definitions. 79 | 80 | "This License" refers to version 3 of the GNU General Public License. 81 | 82 | "Copyright" also means copyright-like laws that apply to other kinds 83 | of works, such as semiconductor masks. 84 | 85 | "The Program" refers to any copyrightable work licensed under this 86 | License. Each licensee is addressed as "you". "Licensees" and 87 | "recipients" may be individuals or organizations. 88 | 89 | To "modify" a work means to copy from or adapt all or part of the work 90 | in a fashion requiring copyright permission, other than the making of 91 | an exact copy. The resulting work is called a "modified version" of 92 | the earlier work or a work "based on" the earlier work. 93 | 94 | A "covered work" means either the unmodified Program or a work based 95 | on the Program. 96 | 97 | To "propagate" a work means to do anything with it that, without 98 | permission, would make you directly or secondarily liable for 99 | infringement under applicable copyright law, except executing it on a 100 | computer or modifying a private copy. Propagation includes copying, 101 | distribution (with or without modification), making available to the 102 | public, and in some countries other activities as well. 103 | 104 | To "convey" a work means any kind of propagation that enables other 105 | parties to make or receive copies. Mere interaction with a user 106 | through a computer network, with no transfer of a copy, is not 107 | conveying. 108 | 109 | An interactive user interface displays "Appropriate Legal Notices" to 110 | the extent that it includes a convenient and prominently visible 111 | feature that (1) displays an appropriate copyright notice, and (2) 112 | tells the user that there is no warranty for the work (except to the 113 | extent that warranties are provided), that licensees may convey the 114 | work under this License, and how to view a copy of this License. If 115 | the interface presents a list of user commands or options, such as a 116 | menu, a prominent item in the list meets this criterion. 117 | 118 | ### 1. Source Code. 119 | 120 | The "source code" for a work means the preferred form of the work for 121 | making modifications to it. "Object code" means any non-source form of 122 | a work. 123 | 124 | A "Standard Interface" means an interface that either is an official 125 | standard defined by a recognized standards body, or, in the case of 126 | interfaces specified for a particular programming language, one that 127 | is widely used among developers working in that language. 128 | 129 | The "System Libraries" of an executable work include anything, other 130 | than the work as a whole, that (a) is included in the normal form of 131 | packaging a Major Component, but which is not part of that Major 132 | Component, and (b) serves only to enable use of the work with that 133 | Major Component, or to implement a Standard Interface for which an 134 | implementation is available to the public in source code form. A 135 | "Major Component", in this context, means a major essential component 136 | (kernel, window system, and so on) of the specific operating system 137 | (if any) on which the executable work runs, or a compiler used to 138 | produce the work, or an object code interpreter used to run it. 139 | 140 | The "Corresponding Source" for a work in object code form means all 141 | the source code needed to generate, install, and (for an executable 142 | work) run the object code and to modify the work, including scripts to 143 | control those activities. However, it does not include the work's 144 | System Libraries, or general-purpose tools or generally available free 145 | programs which are used unmodified in performing those activities but 146 | which are not part of the work. For example, Corresponding Source 147 | includes interface definition files associated with source files for 148 | the work, and the source code for shared libraries and dynamically 149 | linked subprograms that the work is specifically designed to require, 150 | such as by intimate data communication or control flow between those 151 | subprograms and other parts of the work. 152 | 153 | The Corresponding Source need not include anything that users can 154 | regenerate automatically from other parts of the Corresponding Source. 155 | 156 | The Corresponding Source for a work in source code form is that same 157 | work. 158 | 159 | ### 2. Basic Permissions. 160 | 161 | All rights granted under this License are granted for the term of 162 | copyright on the Program, and are irrevocable provided the stated 163 | conditions are met. This License explicitly affirms your unlimited 164 | permission to run the unmodified Program. The output from running a 165 | covered work is covered by this License only if the output, given its 166 | content, constitutes a covered work. This License acknowledges your 167 | rights of fair use or other equivalent, as provided by copyright law. 168 | 169 | You may make, run and propagate covered works that you do not convey, 170 | without conditions so long as your license otherwise remains in force. 171 | You may convey covered works to others for the sole purpose of having 172 | them make modifications exclusively for you, or provide you with 173 | facilities for running those works, provided that you comply with the 174 | terms of this License in conveying all material for which you do not 175 | control copyright. Those thus making or running the covered works for 176 | you must do so exclusively on your behalf, under your direction and 177 | control, on terms that prohibit them from making any copies of your 178 | copyrighted material outside their relationship with you. 179 | 180 | Conveying under any other circumstances is permitted solely under the 181 | conditions stated below. Sublicensing is not allowed; section 10 makes 182 | it unnecessary. 183 | 184 | ### 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 185 | 186 | No covered work shall be deemed part of an effective technological 187 | measure under any applicable law fulfilling obligations under article 188 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 189 | similar laws prohibiting or restricting circumvention of such 190 | measures. 191 | 192 | When you convey a covered work, you waive any legal power to forbid 193 | circumvention of technological measures to the extent such 194 | circumvention is effected by exercising rights under this License with 195 | respect to the covered work, and you disclaim any intention to limit 196 | operation or modification of the work as a means of enforcing, against 197 | the work's users, your or third parties' legal rights to forbid 198 | circumvention of technological measures. 199 | 200 | ### 4. Conveying Verbatim Copies. 201 | 202 | You may convey verbatim copies of the Program's source code as you 203 | receive it, in any medium, provided that you conspicuously and 204 | appropriately publish on each copy an appropriate copyright notice; 205 | keep intact all notices stating that this License and any 206 | non-permissive terms added in accord with section 7 apply to the code; 207 | keep intact all notices of the absence of any warranty; and give all 208 | recipients a copy of this License along with the Program. 209 | 210 | You may charge any price or no price for each copy that you convey, 211 | and you may offer support or warranty protection for a fee. 212 | 213 | ### 5. Conveying Modified Source Versions. 214 | 215 | You may convey a work based on the Program, or the modifications to 216 | produce it from the Program, in the form of source code under the 217 | terms of section 4, provided that you also meet all of these 218 | conditions: 219 | 220 | - a) The work must carry prominent notices stating that you modified 221 | it, and giving a relevant date. 222 | - b) The work must carry prominent notices stating that it is 223 | released under this License and any conditions added under 224 | section 7. This requirement modifies the requirement in section 4 225 | to "keep intact all notices". 226 | - c) You must license the entire work, as a whole, under this 227 | License to anyone who comes into possession of a copy. This 228 | License will therefore apply, along with any applicable section 7 229 | additional terms, to the whole of the work, and all its parts, 230 | regardless of how they are packaged. This License gives no 231 | permission to license the work in any other way, but it does not 232 | invalidate such permission if you have separately received it. 233 | - d) If the work has interactive user interfaces, each must display 234 | Appropriate Legal Notices; however, if the Program has interactive 235 | interfaces that do not display Appropriate Legal Notices, your 236 | work need not make them do so. 237 | 238 | A compilation of a covered work with other separate and independent 239 | works, which are not by their nature extensions of the covered work, 240 | and which are not combined with it such as to form a larger program, 241 | in or on a volume of a storage or distribution medium, is called an 242 | "aggregate" if the compilation and its resulting copyright are not 243 | used to limit the access or legal rights of the compilation's users 244 | beyond what the individual works permit. Inclusion of a covered work 245 | in an aggregate does not cause this License to apply to the other 246 | parts of the aggregate. 247 | 248 | ### 6. Conveying Non-Source Forms. 249 | 250 | You may convey a covered work in object code form under the terms of 251 | sections 4 and 5, provided that you also convey the machine-readable 252 | Corresponding Source under the terms of this License, in one of these 253 | ways: 254 | 255 | - a) Convey the object code in, or embodied in, a physical product 256 | (including a physical distribution medium), accompanied by the 257 | Corresponding Source fixed on a durable physical medium 258 | customarily used for software interchange. 259 | - b) Convey the object code in, or embodied in, a physical product 260 | (including a physical distribution medium), accompanied by a 261 | written offer, valid for at least three years and valid for as 262 | long as you offer spare parts or customer support for that product 263 | model, to give anyone who possesses the object code either (1) a 264 | copy of the Corresponding Source for all the software in the 265 | product that is covered by this License, on a durable physical 266 | medium customarily used for software interchange, for a price no 267 | more than your reasonable cost of physically performing this 268 | conveying of source, or (2) access to copy the Corresponding 269 | Source from a network server at no charge. 270 | - c) Convey individual copies of the object code with a copy of the 271 | written offer to provide the Corresponding Source. This 272 | alternative is allowed only occasionally and noncommercially, and 273 | only if you received the object code with such an offer, in accord 274 | with subsection 6b. 275 | - d) Convey the object code by offering access from a designated 276 | place (gratis or for a charge), and offer equivalent access to the 277 | Corresponding Source in the same way through the same place at no 278 | further charge. You need not require recipients to copy the 279 | Corresponding Source along with the object code. If the place to 280 | copy the object code is a network server, the Corresponding Source 281 | may be on a different server (operated by you or a third party) 282 | that supports equivalent copying facilities, provided you maintain 283 | clear directions next to the object code saying where to find the 284 | Corresponding Source. Regardless of what server hosts the 285 | Corresponding Source, you remain obligated to ensure that it is 286 | available for as long as needed to satisfy these requirements. 287 | - e) Convey the object code using peer-to-peer transmission, 288 | provided you inform other peers where the object code and 289 | Corresponding Source of the work are being offered to the general 290 | public at no charge under subsection 6d. 291 | 292 | A separable portion of the object code, whose source code is excluded 293 | from the Corresponding Source as a System Library, need not be 294 | included in conveying the object code work. 295 | 296 | A "User Product" is either (1) a "consumer product", which means any 297 | tangible personal property which is normally used for personal, 298 | family, or household purposes, or (2) anything designed or sold for 299 | incorporation into a dwelling. In determining whether a product is a 300 | consumer product, doubtful cases shall be resolved in favor of 301 | coverage. For a particular product received by a particular user, 302 | "normally used" refers to a typical or common use of that class of 303 | product, regardless of the status of the particular user or of the way 304 | in which the particular user actually uses, or expects or is expected 305 | to use, the product. A product is a consumer product regardless of 306 | whether the product has substantial commercial, industrial or 307 | non-consumer uses, unless such uses represent the only significant 308 | mode of use of the product. 309 | 310 | "Installation Information" for a User Product means any methods, 311 | procedures, authorization keys, or other information required to 312 | install and execute modified versions of a covered work in that User 313 | Product from a modified version of its Corresponding Source. The 314 | information must suffice to ensure that the continued functioning of 315 | the modified object code is in no case prevented or interfered with 316 | solely because modification has been made. 317 | 318 | If you convey an object code work under this section in, or with, or 319 | specifically for use in, a User Product, and the conveying occurs as 320 | part of a transaction in which the right of possession and use of the 321 | User Product is transferred to the recipient in perpetuity or for a 322 | fixed term (regardless of how the transaction is characterized), the 323 | Corresponding Source conveyed under this section must be accompanied 324 | by the Installation Information. But this requirement does not apply 325 | if neither you nor any third party retains the ability to install 326 | modified object code on the User Product (for example, the work has 327 | been installed in ROM). 328 | 329 | The requirement to provide Installation Information does not include a 330 | requirement to continue to provide support service, warranty, or 331 | updates for a work that has been modified or installed by the 332 | recipient, or for the User Product in which it has been modified or 333 | installed. Access to a network may be denied when the modification 334 | itself materially and adversely affects the operation of the network 335 | or violates the rules and protocols for communication across the 336 | network. 337 | 338 | Corresponding Source conveyed, and Installation Information provided, 339 | in accord with this section must be in a format that is publicly 340 | documented (and with an implementation available to the public in 341 | source code form), and must require no special password or key for 342 | unpacking, reading or copying. 343 | 344 | ### 7. Additional Terms. 345 | 346 | "Additional permissions" are terms that supplement the terms of this 347 | License by making exceptions from one or more of its conditions. 348 | Additional permissions that are applicable to the entire Program shall 349 | be treated as though they were included in this License, to the extent 350 | that they are valid under applicable law. If additional permissions 351 | apply only to part of the Program, that part may be used separately 352 | under those permissions, but the entire Program remains governed by 353 | this License without regard to the additional permissions. 354 | 355 | When you convey a copy of a covered work, you may at your option 356 | remove any additional permissions from that copy, or from any part of 357 | it. (Additional permissions may be written to require their own 358 | removal in certain cases when you modify the work.) You may place 359 | additional permissions on material, added by you to a covered work, 360 | for which you have or can give appropriate copyright permission. 361 | 362 | Notwithstanding any other provision of this License, for material you 363 | add to a covered work, you may (if authorized by the copyright holders 364 | of that material) supplement the terms of this License with terms: 365 | 366 | - a) Disclaiming warranty or limiting liability differently from the 367 | terms of sections 15 and 16 of this License; or 368 | - b) Requiring preservation of specified reasonable legal notices or 369 | author attributions in that material or in the Appropriate Legal 370 | Notices displayed by works containing it; or 371 | - c) Prohibiting misrepresentation of the origin of that material, 372 | or requiring that modified versions of such material be marked in 373 | reasonable ways as different from the original version; or 374 | - d) Limiting the use for publicity purposes of names of licensors 375 | or authors of the material; or 376 | - e) Declining to grant rights under trademark law for use of some 377 | trade names, trademarks, or service marks; or 378 | - f) Requiring indemnification of licensors and authors of that 379 | material by anyone who conveys the material (or modified versions 380 | of it) with contractual assumptions of liability to the recipient, 381 | for any liability that these contractual assumptions directly 382 | impose on those licensors and authors. 383 | 384 | All other non-permissive additional terms are considered "further 385 | restrictions" within the meaning of section 10. If the Program as you 386 | received it, or any part of it, contains a notice stating that it is 387 | governed by this License along with a term that is a further 388 | restriction, you may remove that term. If a license document contains 389 | a further restriction but permits relicensing or conveying under this 390 | License, you may add to a covered work material governed by the terms 391 | of that license document, provided that the further restriction does 392 | not survive such relicensing or conveying. 393 | 394 | If you add terms to a covered work in accord with this section, you 395 | must place, in the relevant source files, a statement of the 396 | additional terms that apply to those files, or a notice indicating 397 | where to find the applicable terms. 398 | 399 | Additional terms, permissive or non-permissive, may be stated in the 400 | form of a separately written license, or stated as exceptions; the 401 | above requirements apply either way. 402 | 403 | ### 8. Termination. 404 | 405 | You may not propagate or modify a covered work except as expressly 406 | provided under this License. Any attempt otherwise to propagate or 407 | modify it is void, and will automatically terminate your rights under 408 | this License (including any patent licenses granted under the third 409 | paragraph of section 11). 410 | 411 | However, if you cease all violation of this License, then your license 412 | from a particular copyright holder is reinstated (a) provisionally, 413 | unless and until the copyright holder explicitly and finally 414 | terminates your license, and (b) permanently, if the copyright holder 415 | fails to notify you of the violation by some reasonable means prior to 416 | 60 days after the cessation. 417 | 418 | Moreover, your license from a particular copyright holder is 419 | reinstated permanently if the copyright holder notifies you of the 420 | violation by some reasonable means, this is the first time you have 421 | received notice of violation of this License (for any work) from that 422 | copyright holder, and you cure the violation prior to 30 days after 423 | your receipt of the notice. 424 | 425 | Termination of your rights under this section does not terminate the 426 | licenses of parties who have received copies or rights from you under 427 | this License. If your rights have been terminated and not permanently 428 | reinstated, you do not qualify to receive new licenses for the same 429 | material under section 10. 430 | 431 | ### 9. Acceptance Not Required for Having Copies. 432 | 433 | You are not required to accept this License in order to receive or run 434 | a copy of the Program. Ancillary propagation of a covered work 435 | occurring solely as a consequence of using peer-to-peer transmission 436 | to receive a copy likewise does not require acceptance. However, 437 | nothing other than this License grants you permission to propagate or 438 | modify any covered work. These actions infringe copyright if you do 439 | not accept this License. Therefore, by modifying or propagating a 440 | covered work, you indicate your acceptance of this License to do so. 441 | 442 | ### 10. Automatic Licensing of Downstream Recipients. 443 | 444 | Each time you convey a covered work, the recipient automatically 445 | receives a license from the original licensors, to run, modify and 446 | propagate that work, subject to this License. You are not responsible 447 | for enforcing compliance by third parties with this License. 448 | 449 | An "entity transaction" is a transaction transferring control of an 450 | organization, or substantially all assets of one, or subdividing an 451 | organization, or merging organizations. If propagation of a covered 452 | work results from an entity transaction, each party to that 453 | transaction who receives a copy of the work also receives whatever 454 | licenses to the work the party's predecessor in interest had or could 455 | give under the previous paragraph, plus a right to possession of the 456 | Corresponding Source of the work from the predecessor in interest, if 457 | the predecessor has it or can get it with reasonable efforts. 458 | 459 | You may not impose any further restrictions on the exercise of the 460 | rights granted or affirmed under this License. For example, you may 461 | not impose a license fee, royalty, or other charge for exercise of 462 | rights granted under this License, and you may not initiate litigation 463 | (including a cross-claim or counterclaim in a lawsuit) alleging that 464 | any patent claim is infringed by making, using, selling, offering for 465 | sale, or importing the Program or any portion of it. 466 | 467 | ### 11. Patents. 468 | 469 | A "contributor" is a copyright holder who authorizes use under this 470 | License of the Program or a work on which the Program is based. The 471 | work thus licensed is called the contributor's "contributor version". 472 | 473 | A contributor's "essential patent claims" are all patent claims owned 474 | or controlled by the contributor, whether already acquired or 475 | hereafter acquired, that would be infringed by some manner, permitted 476 | by this License, of making, using, or selling its contributor version, 477 | but do not include claims that would be infringed only as a 478 | consequence of further modification of the contributor version. For 479 | purposes of this definition, "control" includes the right to grant 480 | patent sublicenses in a manner consistent with the requirements of 481 | this License. 482 | 483 | Each contributor grants you a non-exclusive, worldwide, royalty-free 484 | patent license under the contributor's essential patent claims, to 485 | make, use, sell, offer for sale, import and otherwise run, modify and 486 | propagate the contents of its contributor version. 487 | 488 | In the following three paragraphs, a "patent license" is any express 489 | agreement or commitment, however denominated, not to enforce a patent 490 | (such as an express permission to practice a patent or covenant not to 491 | sue for patent infringement). To "grant" such a patent license to a 492 | party means to make such an agreement or commitment not to enforce a 493 | patent against the party. 494 | 495 | If you convey a covered work, knowingly relying on a patent license, 496 | and the Corresponding Source of the work is not available for anyone 497 | to copy, free of charge and under the terms of this License, through a 498 | publicly available network server or other readily accessible means, 499 | then you must either (1) cause the Corresponding Source to be so 500 | available, or (2) arrange to deprive yourself of the benefit of the 501 | patent license for this particular work, or (3) arrange, in a manner 502 | consistent with the requirements of this License, to extend the patent 503 | license to downstream recipients. "Knowingly relying" means you have 504 | actual knowledge that, but for the patent license, your conveying the 505 | covered work in a country, or your recipient's use of the covered work 506 | in a country, would infringe one or more identifiable patents in that 507 | country that you have reason to believe are valid. 508 | 509 | If, pursuant to or in connection with a single transaction or 510 | arrangement, you convey, or propagate by procuring conveyance of, a 511 | covered work, and grant a patent license to some of the parties 512 | receiving the covered work authorizing them to use, propagate, modify 513 | or convey a specific copy of the covered work, then the patent license 514 | you grant is automatically extended to all recipients of the covered 515 | work and works based on it. 516 | 517 | A patent license is "discriminatory" if it does not include within the 518 | scope of its coverage, prohibits the exercise of, or is conditioned on 519 | the non-exercise of one or more of the rights that are specifically 520 | granted under this License. You may not convey a covered work if you 521 | are a party to an arrangement with a third party that is in the 522 | business of distributing software, under which you make payment to the 523 | third party based on the extent of your activity of conveying the 524 | work, and under which the third party grants, to any of the parties 525 | who would receive the covered work from you, a discriminatory patent 526 | license (a) in connection with copies of the covered work conveyed by 527 | you (or copies made from those copies), or (b) primarily for and in 528 | connection with specific products or compilations that contain the 529 | covered work, unless you entered into that arrangement, or that patent 530 | license was granted, prior to 28 March 2007. 531 | 532 | Nothing in this License shall be construed as excluding or limiting 533 | any implied license or other defenses to infringement that may 534 | otherwise be available to you under applicable patent law. 535 | 536 | ### 12. No Surrender of Others' Freedom. 537 | 538 | If conditions are imposed on you (whether by court order, agreement or 539 | otherwise) that contradict the conditions of this License, they do not 540 | excuse you from the conditions of this License. If you cannot convey a 541 | covered work so as to satisfy simultaneously your obligations under 542 | this License and any other pertinent obligations, then as a 543 | consequence you may not convey it at all. For example, if you agree to 544 | terms that obligate you to collect a royalty for further conveying 545 | from those to whom you convey the Program, the only way you could 546 | satisfy both those terms and this License would be to refrain entirely 547 | from conveying the Program. 548 | 549 | ### 13. Use with the GNU Affero General Public License. 550 | 551 | Notwithstanding any other provision of this License, you have 552 | permission to link or combine any covered work with a work licensed 553 | under version 3 of the GNU Affero General Public License into a single 554 | combined work, and to convey the resulting work. The terms of this 555 | License will continue to apply to the part which is the covered work, 556 | but the special requirements of the GNU Affero General Public License, 557 | section 13, concerning interaction through a network will apply to the 558 | combination as such. 559 | 560 | ### 14. Revised Versions of this License. 561 | 562 | The Free Software Foundation may publish revised and/or new versions 563 | of the GNU General Public License from time to time. Such new versions 564 | will be similar in spirit to the present version, but may differ in 565 | detail to address new problems or concerns. 566 | 567 | Each version is given a distinguishing version number. If the Program 568 | specifies that a certain numbered version of the GNU General Public 569 | License "or any later version" applies to it, you have the option of 570 | following the terms and conditions either of that numbered version or 571 | of any later version published by the Free Software Foundation. If the 572 | Program does not specify a version number of the GNU General Public 573 | License, you may choose any version ever published by the Free 574 | Software Foundation. 575 | 576 | If the Program specifies that a proxy can decide which future versions 577 | of the GNU General Public License can be used, that proxy's public 578 | statement of acceptance of a version permanently authorizes you to 579 | choose that version for the Program. 580 | 581 | Later license versions may give you additional or different 582 | permissions. However, no additional obligations are imposed on any 583 | author or copyright holder as a result of your choosing to follow a 584 | later version. 585 | 586 | ### 15. Disclaimer of Warranty. 587 | 588 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 589 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 590 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT 591 | WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT 592 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 593 | A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND 594 | PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE 595 | DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR 596 | CORRECTION. 597 | 598 | ### 16. Limitation of Liability. 599 | 600 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 601 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR 602 | CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 603 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES 604 | ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT 605 | NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR 606 | LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM 607 | TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER 608 | PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 609 | 610 | ### 17. Interpretation of Sections 15 and 16. 611 | 612 | If the disclaimer of warranty and limitation of liability provided 613 | above cannot be given local legal effect according to their terms, 614 | reviewing courts shall apply local law that most closely approximates 615 | an absolute waiver of all civil liability in connection with the 616 | Program, unless a warranty or assumption of liability accompanies a 617 | copy of the Program in return for a fee. 618 | 619 | END OF TERMS AND CONDITIONS 620 | 621 | ## How to Apply These Terms to Your New Programs 622 | 623 | If you develop a new program, and you want it to be of the greatest 624 | possible use to the public, the best way to achieve this is to make it 625 | free software which everyone can redistribute and change under these 626 | terms. 627 | 628 | To do so, attach the following notices to the program. It is safest to 629 | attach them to the start of each source file to most effectively state 630 | the exclusion of warranty; and each file should have at least the 631 | "copyright" line and a pointer to where the full notice is found. 632 | 633 | 634 | Copyright (C) 635 | 636 | This program is free software: you can redistribute it and/or modify 637 | it under the terms of the GNU General Public License as published by 638 | the Free Software Foundation, either version 3 of the License, or 639 | (at your option) any later version. 640 | 641 | This program is distributed in the hope that it will be useful, 642 | but WITHOUT ANY WARRANTY; without even the implied warranty of 643 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 644 | GNU General Public License for more details. 645 | 646 | You should have received a copy of the GNU General Public License 647 | along with this program. If not, see . 648 | 649 | Also add information on how to contact you by electronic and paper 650 | mail. 651 | 652 | If the program does terminal interaction, make it output a short 653 | notice like this when it starts in an interactive mode: 654 | 655 | Copyright (C) 656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 657 | This is free software, and you are welcome to redistribute it 658 | under certain conditions; type `show c' for details. 659 | 660 | The hypothetical commands \`show w' and \`show c' should show the 661 | appropriate parts of the General Public License. Of course, your 662 | program's commands might be different; for a GUI interface, you would 663 | use an "about box". 664 | 665 | You should also get your employer (if you work as a programmer) or 666 | school, if any, to sign a "copyright disclaimer" for the program, if 667 | necessary. For more information on this, and how to apply and follow 668 | the GNU GPL, see . 669 | 670 | The GNU General Public License does not permit incorporating your 671 | program into proprietary programs. If your program is a subroutine 672 | library, you may consider it more useful to permit linking proprietary 673 | applications with the library. If this is what you want to do, use the 674 | GNU Lesser General Public License instead of this License. But first, 675 | please read . 676 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Subnetting Bootstrap 2 | 3 | Soluzione web per la risoluzione degli esercizi sulle reti. 4 | 5 | > [!NOTE] 6 | > Progetto scolastico 🎓 · Ⅳ 7 | 8 | 9 | 10 | > [!WARNING] 11 | > Correttezza VLSM non garantita 12 | 13 | --- 14 | 15 | ## Funzionalità 16 | 17 | - Identifica IP 18 | - Verifica Stessa Rete 19 | - Subnet a Maschera Fissa - FLSM 20 | - Subnet a Maschera Variabile - VLSM 21 | 22 | ## Ispirazione 23 | 24 | La grafica del sito web è stata ispirata e **sviluppata indipendentemente** riproponendo l'interfaccia utente offerta da [Scheduling Solver](https://process-scheduling-solver.boonsuen.com/) 25 | 26 | 27 | ## Preview 28 | 29 | Link al Sito [(link)](https://vittoriopiotti.altervista.org/Subnetting/index.html) 30 | 31 | 32 | --- 33 | 34 | 35 | 36 | 37 | ## Screenshots 38 | 39 | 40 | | | | 41 | |-|-| 42 | ||| 43 | 44 | ## Licenze 45 | 46 | 47 | ### SubnettingSolver 48 | 49 | **Copyright** 2024 Vittorio Piotti [(GitHub page)](https://github.com/vittorioPiotti) [(Personal page)](https://vittoriopiotti.altervista.org/) 50 | 51 | **Version** [v1.0.0](https://github.com/vittorioPiotti/SubnettingSolver-Bootstrap/releases/tag/v1.0.0) 52 | 53 | **License** [GPL-3.0](https://github.com/vittorioPiotti/SubnettingSolver-Bootstrap/blob/main/LICENSE.md) 54 | 55 | 56 | --- 57 | 58 | ### Bootstrap 59 | 60 | **Copyright** 2011-2018 The Bootstrap Authors 61 | 62 | **Version** [v5.2](https://github.com/twbs/bootstrap/releases/tag/v5.2.0) 63 | 64 | **License** [MIT](https://github.com/twbs/bootstrap/blob/main/LICENSE) 65 | 66 | 67 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /css/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vittorioPiotti/SubnettingSolver-Bootstrap/6b58d6b26c6106d1c70d4db079964d4022b51290/css/.DS_Store -------------------------------------------------------------------------------- /css/main.css: -------------------------------------------------------------------------------- 1 | /* 2 | Subnetting-Bootstrap v1.0.0 (https://github.com/vittorioPiotti/Subnetting-Bootstrap/releases/tag/1.0.0) 3 | Copyright 2024 Vittorio Piotti 4 | Licensed under GPL-3.0 (https://github.com/vittorioPiotti/Subnetting-Bootstrap/blob/main/LICENSE.md) 5 | */ 6 | 7 | 8 | 9 | #linkGitHub{ 10 | text-decoration: none; 11 | color: black; 12 | transition:0.5s; 13 | } 14 | 15 | #linkGitHub:hover { 16 | color: #008cff; 17 | transition:0.5s; 18 | } 19 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | 13 | 14 | 15 | 16 | Subnetting 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 |
37 |
38 |
39 |
40 |

41 | Input 42 |

43 | 44 | 46 |
47 |
48 | 51 |
52 |
53 |
54 |
55 |
56 | 57 |
58 | 59 |

60 | Output 61 |

62 |
63 |
64 | 65 |
66 | 67 |
68 |

69 | Visualizza qui la soluzione dell'esercizio 70 |

71 |
72 |
73 |
74 |
75 |
76 | 84 |
85 |
86 | 87 | 88 | 89 | Subnetting Solver 90 |
91 |
92 |
93 | 112 | 113 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /js/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vittorioPiotti/SubnettingSolver-Bootstrap/6b58d6b26c6106d1c70d4db079964d4022b51290/js/.DS_Store -------------------------------------------------------------------------------- /js/bootstrap.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap v5.3.0-alpha3 (https://getbootstrap.com/) 3 | * Copyright 2011-2023 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 5 | */ 6 | !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e(require("@popperjs/core")):"function"==typeof define&&define.amd?define(["@popperjs/core"],e):(t="undefined"!=typeof globalThis?globalThis:t||self).bootstrap=e(t.Popper)}(this,(function(t){"use strict";function e(t){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(t)for(const s in t)if("default"!==s){const i=Object.getOwnPropertyDescriptor(t,s);Object.defineProperty(e,s,i.get?i:{enumerable:!0,get:()=>t[s]})}return e.default=t,Object.freeze(e)}const s=e(t),i=new Map,n={set(t,e,s){i.has(t)||i.set(t,new Map);const n=i.get(t);n.has(e)||0===n.size?n.set(e,s):console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(n.keys())[0]}.`)},get:(t,e)=>i.has(t)&&i.get(t).get(e)||null,remove(t,e){if(!i.has(t))return;const s=i.get(t);s.delete(e),0===s.size&&i.delete(t)}},o="transitionend",r=t=>(t&&window.CSS&&window.CSS.escape&&(t=t.replace(/#([^\s"#']+)/g,((t,e)=>`#${CSS.escape(e)}`))),t),a=t=>{t.dispatchEvent(new Event(o))},l=t=>!(!t||"object"!=typeof t)&&(void 0!==t.jquery&&(t=t[0]),void 0!==t.nodeType),c=t=>l(t)?t.jquery?t[0]:t:"string"==typeof t&&t.length>0?document.querySelector(r(t)):null,h=t=>{if(!l(t)||0===t.getClientRects().length)return!1;const e="visible"===getComputedStyle(t).getPropertyValue("visibility"),s=t.closest("details:not([open])");if(!s)return e;if(s!==t){const e=t.closest("summary");if(e&&e.parentNode!==s)return!1;if(null===e)return!1}return e},d=t=>!t||t.nodeType!==Node.ELEMENT_NODE||!!t.classList.contains("disabled")||(void 0!==t.disabled?t.disabled:t.hasAttribute("disabled")&&"false"!==t.getAttribute("disabled")),u=t=>{if(!document.documentElement.attachShadow)return null;if("function"==typeof t.getRootNode){const e=t.getRootNode();return e instanceof ShadowRoot?e:null}return t instanceof ShadowRoot?t:t.parentNode?u(t.parentNode):null},_=()=>{},g=t=>{t.offsetHeight},f=()=>window.jQuery&&!document.body.hasAttribute("data-bs-no-jquery")?window.jQuery:null,m=[],p=()=>"rtl"===document.documentElement.dir,b=t=>{var e;e=()=>{const e=f();if(e){const s=t.NAME,i=e.fn[s];e.fn[s]=t.jQueryInterface,e.fn[s].Constructor=t,e.fn[s].noConflict=()=>(e.fn[s]=i,t.jQueryInterface)}},"loading"===document.readyState?(m.length||document.addEventListener("DOMContentLoaded",(()=>{for(const t of m)t()})),m.push(e)):e()},v=(t,e=[],s=t)=>"function"==typeof t?t(...e):s,y=(t,e,s=!0)=>{if(!s)return void v(t);const i=(t=>{if(!t)return 0;let{transitionDuration:e,transitionDelay:s}=window.getComputedStyle(t);const i=Number.parseFloat(e),n=Number.parseFloat(s);return i||n?(e=e.split(",")[0],s=s.split(",")[0],1e3*(Number.parseFloat(e)+Number.parseFloat(s))):0})(e)+5;let n=!1;const r=({target:s})=>{s===e&&(n=!0,e.removeEventListener(o,r),v(t))};e.addEventListener(o,r),setTimeout((()=>{n||a(e)}),i)},w=(t,e,s,i)=>{const n=t.length;let o=t.indexOf(e);return-1===o?!s&&i?t[n-1]:t[0]:(o+=s?1:-1,i&&(o=(o+n)%n),t[Math.max(0,Math.min(o,n-1))])},A=/[^.]*(?=\..*)\.|.*/,E=/\..*/,C=/::\d+$/,T={};let k=1;const S={mouseenter:"mouseover",mouseleave:"mouseout"},L=new Set(["click","dblclick","mouseup","mousedown","contextmenu","mousewheel","DOMMouseScroll","mouseover","mouseout","mousemove","selectstart","selectend","keydown","keypress","keyup","orientationchange","touchstart","touchmove","touchend","touchcancel","pointerdown","pointermove","pointerup","pointerleave","pointercancel","gesturestart","gesturechange","gestureend","focus","blur","change","reset","select","submit","focusin","focusout","load","unload","beforeunload","resize","move","DOMContentLoaded","readystatechange","error","abort","scroll"]);function O(t,e){return e&&`${e}::${k++}`||t.uidEvent||k++}function I(t){const e=O(t);return t.uidEvent=e,T[e]=T[e]||{},T[e]}function D(t,e,s=null){return Object.values(t).find((t=>t.callable===e&&t.delegationSelector===s))}function N(t,e,s){const i="string"==typeof e,n=i?s:e||s;let o=j(t);return L.has(o)||(o=t),[i,n,o]}function P(t,e,s,i,n){if("string"!=typeof e||!t)return;let[o,r,a]=N(e,s,i);if(e in S){const t=t=>function(e){if(!e.relatedTarget||e.relatedTarget!==e.delegateTarget&&!e.delegateTarget.contains(e.relatedTarget))return t.call(this,e)};r=t(r)}const l=I(t),c=l[a]||(l[a]={}),h=D(c,r,o?s:null);if(h)return void(h.oneOff=h.oneOff&&n);const d=O(r,e.replace(A,"")),u=o?function(t,e,s){return function i(n){const o=t.querySelectorAll(e);for(let{target:r}=n;r&&r!==this;r=r.parentNode)for(const a of o)if(a===r)return $(n,{delegateTarget:r}),i.oneOff&&F.off(t,n.type,e,s),s.apply(r,[n])}}(t,s,r):function(t,e){return function s(i){return $(i,{delegateTarget:t}),s.oneOff&&F.off(t,i.type,e),e.apply(t,[i])}}(t,r);u.delegationSelector=o?s:null,u.callable=r,u.oneOff=n,u.uidEvent=d,c[d]=u,t.addEventListener(a,u,o)}function x(t,e,s,i,n){const o=D(e[s],i,n);o&&(t.removeEventListener(s,o,Boolean(n)),delete e[s][o.uidEvent])}function M(t,e,s,i){const n=e[s]||{};for(const[o,r]of Object.entries(n))o.includes(i)&&x(t,e,s,r.callable,r.delegationSelector)}function j(t){return t=t.replace(E,""),S[t]||t}const F={on(t,e,s,i){P(t,e,s,i,!1)},one(t,e,s,i){P(t,e,s,i,!0)},off(t,e,s,i){if("string"!=typeof e||!t)return;const[n,o,r]=N(e,s,i),a=r!==e,l=I(t),c=l[r]||{},h=e.startsWith(".");if(void 0===o){if(h)for(const s of Object.keys(l))M(t,l,s,e.slice(1));for(const[s,i]of Object.entries(c)){const n=s.replace(C,"");a&&!e.includes(n)||x(t,l,r,i.callable,i.delegationSelector)}}else{if(!Object.keys(c).length)return;x(t,l,r,o,n?s:null)}},trigger(t,e,s){if("string"!=typeof e||!t)return null;const i=f();let n=null,o=!0,r=!0,a=!1;e!==j(e)&&i&&(n=i.Event(e,s),i(t).trigger(n),o=!n.isPropagationStopped(),r=!n.isImmediatePropagationStopped(),a=n.isDefaultPrevented());const l=$(new Event(e,{bubbles:o,cancelable:!0}),s);return a&&l.preventDefault(),r&&t.dispatchEvent(l),l.defaultPrevented&&n&&n.preventDefault(),l}};function $(t,e={}){for(const[s,i]of Object.entries(e))try{t[s]=i}catch(e){Object.defineProperty(t,s,{configurable:!0,get:()=>i})}return t}function z(t){if("true"===t)return!0;if("false"===t)return!1;if(t===Number(t).toString())return Number(t);if(""===t||"null"===t)return null;if("string"!=typeof t)return t;try{return JSON.parse(decodeURIComponent(t))}catch(e){return t}}function H(t){return t.replace(/[A-Z]/g,(t=>`-${t.toLowerCase()}`))}const B={setDataAttribute(t,e,s){t.setAttribute(`data-bs-${H(e)}`,s)},removeDataAttribute(t,e){t.removeAttribute(`data-bs-${H(e)}`)},getDataAttributes(t){if(!t)return{};const e={},s=Object.keys(t.dataset).filter((t=>t.startsWith("bs")&&!t.startsWith("bsConfig")));for(const i of s){let s=i.replace(/^bs/,"");s=s.charAt(0).toLowerCase()+s.slice(1,s.length),e[s]=z(t.dataset[i])}return e},getDataAttribute:(t,e)=>z(t.getAttribute(`data-bs-${H(e)}`))};class q{static get Default(){return{}}static get DefaultType(){return{}}static get NAME(){throw new Error('You have to implement the static method "NAME", for each component!')}_getConfig(t){return t=this._mergeConfigObj(t),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}_configAfterMerge(t){return t}_mergeConfigObj(t,e){const s=l(e)?B.getDataAttribute(e,"config"):{};return{...this.constructor.Default,..."object"==typeof s?s:{},...l(e)?B.getDataAttributes(e):{},..."object"==typeof t?t:{}}}_typeCheckConfig(t,e=this.constructor.DefaultType){for(const[i,n]of Object.entries(e)){const e=t[i],o=l(e)?"element":null==(s=e)?`${s}`:Object.prototype.toString.call(s).match(/\s([a-z]+)/i)[1].toLowerCase();if(!new RegExp(n).test(o))throw new TypeError(`${this.constructor.NAME.toUpperCase()}: Option "${i}" provided type "${o}" but expected type "${n}".`)}var s}}class W extends q{constructor(t,e){super(),(t=c(t))&&(this._element=t,this._config=this._getConfig(e),n.set(this._element,this.constructor.DATA_KEY,this))}dispose(){n.remove(this._element,this.constructor.DATA_KEY),F.off(this._element,this.constructor.EVENT_KEY);for(const t of Object.getOwnPropertyNames(this))this[t]=null}_queueCallback(t,e,s=!0){y(t,e,s)}_getConfig(t){return t=this._mergeConfigObj(t,this._element),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}static getInstance(t){return n.get(c(t),this.DATA_KEY)}static getOrCreateInstance(t,e={}){return this.getInstance(t)||new this(t,"object"==typeof e?e:null)}static get VERSION(){return"5.3.0-alpha2"}static get DATA_KEY(){return`bs.${this.NAME}`}static get EVENT_KEY(){return`.${this.DATA_KEY}`}static eventName(t){return`${t}${this.EVENT_KEY}`}}const R=t=>{let e=t.getAttribute("data-bs-target");if(!e||"#"===e){let s=t.getAttribute("href");if(!s||!s.includes("#")&&!s.startsWith("."))return null;s.includes("#")&&!s.startsWith("#")&&(s=`#${s.split("#")[1]}`),e=s&&"#"!==s?s.trim():null}return r(e)},V={find:(t,e=document.documentElement)=>[].concat(...Element.prototype.querySelectorAll.call(e,t)),findOne:(t,e=document.documentElement)=>Element.prototype.querySelector.call(e,t),children:(t,e)=>[].concat(...t.children).filter((t=>t.matches(e))),parents(t,e){const s=[];let i=t.parentNode.closest(e);for(;i;)s.push(i),i=i.parentNode.closest(e);return s},prev(t,e){let s=t.previousElementSibling;for(;s;){if(s.matches(e))return[s];s=s.previousElementSibling}return[]},next(t,e){let s=t.nextElementSibling;for(;s;){if(s.matches(e))return[s];s=s.nextElementSibling}return[]},focusableChildren(t){const e=["a","button","input","textarea","select","details","[tabindex]",'[contenteditable="true"]'].map((t=>`${t}:not([tabindex^="-"])`)).join(",");return this.find(e,t).filter((t=>!d(t)&&h(t)))},getSelectorFromElement(t){const e=R(t);return e&&V.findOne(e)?e:null},getElementFromSelector(t){const e=R(t);return e?V.findOne(e):null},getMultipleElementsFromSelector(t){const e=R(t);return e?V.find(e):[]}},K=(t,e="hide")=>{const s=`click.dismiss${t.EVENT_KEY}`,i=t.NAME;F.on(document,s,`[data-bs-dismiss="${i}"]`,(function(s){if(["A","AREA"].includes(this.tagName)&&s.preventDefault(),d(this))return;const n=V.getElementFromSelector(this)||this.closest(`.${i}`);t.getOrCreateInstance(n)[e]()}))};class Q extends W{static get NAME(){return"alert"}close(){if(F.trigger(this._element,"close.bs.alert").defaultPrevented)return;this._element.classList.remove("show");const t=this._element.classList.contains("fade");this._queueCallback((()=>this._destroyElement()),this._element,t)}_destroyElement(){this._element.remove(),F.trigger(this._element,"closed.bs.alert"),this.dispose()}static jQueryInterface(t){return this.each((function(){const e=Q.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}K(Q,"close"),b(Q);const X='[data-bs-toggle="button"]';class Y extends W{static get NAME(){return"button"}toggle(){this._element.setAttribute("aria-pressed",this._element.classList.toggle("active"))}static jQueryInterface(t){return this.each((function(){const e=Y.getOrCreateInstance(this);"toggle"===t&&e[t]()}))}}F.on(document,"click.bs.button.data-api",X,(t=>{t.preventDefault();const e=t.target.closest(X);Y.getOrCreateInstance(e).toggle()})),b(Y);const U={endCallback:null,leftCallback:null,rightCallback:null},G={endCallback:"(function|null)",leftCallback:"(function|null)",rightCallback:"(function|null)"};class J extends q{constructor(t,e){super(),this._element=t,t&&J.isSupported()&&(this._config=this._getConfig(e),this._deltaX=0,this._supportPointerEvents=Boolean(window.PointerEvent),this._initEvents())}static get Default(){return U}static get DefaultType(){return G}static get NAME(){return"swipe"}dispose(){F.off(this._element,".bs.swipe")}_start(t){this._supportPointerEvents?this._eventIsPointerPenTouch(t)&&(this._deltaX=t.clientX):this._deltaX=t.touches[0].clientX}_end(t){this._eventIsPointerPenTouch(t)&&(this._deltaX=t.clientX-this._deltaX),this._handleSwipe(),v(this._config.endCallback)}_move(t){this._deltaX=t.touches&&t.touches.length>1?0:t.touches[0].clientX-this._deltaX}_handleSwipe(){const t=Math.abs(this._deltaX);if(t<=40)return;const e=t/this._deltaX;this._deltaX=0,e&&v(e>0?this._config.rightCallback:this._config.leftCallback)}_initEvents(){this._supportPointerEvents?(F.on(this._element,"pointerdown.bs.swipe",(t=>this._start(t))),F.on(this._element,"pointerup.bs.swipe",(t=>this._end(t))),this._element.classList.add("pointer-event")):(F.on(this._element,"touchstart.bs.swipe",(t=>this._start(t))),F.on(this._element,"touchmove.bs.swipe",(t=>this._move(t))),F.on(this._element,"touchend.bs.swipe",(t=>this._end(t))))}_eventIsPointerPenTouch(t){return this._supportPointerEvents&&("pen"===t.pointerType||"touch"===t.pointerType)}static isSupported(){return"ontouchstart"in document.documentElement||navigator.maxTouchPoints>0}}const Z="next",tt="prev",et="left",st="right",it="slid.bs.carousel",nt="carousel",ot="active",rt={ArrowLeft:st,ArrowRight:et},at={interval:5e3,keyboard:!0,pause:"hover",ride:!1,touch:!0,wrap:!0},lt={interval:"(number|boolean)",keyboard:"boolean",pause:"(string|boolean)",ride:"(boolean|string)",touch:"boolean",wrap:"boolean"};class ct extends W{constructor(t,e){super(t,e),this._interval=null,this._activeElement=null,this._isSliding=!1,this.touchTimeout=null,this._swipeHelper=null,this._indicatorsElement=V.findOne(".carousel-indicators",this._element),this._addEventListeners(),this._config.ride===nt&&this.cycle()}static get Default(){return at}static get DefaultType(){return lt}static get NAME(){return"carousel"}next(){this._slide(Z)}nextWhenVisible(){!document.hidden&&h(this._element)&&this.next()}prev(){this._slide(tt)}pause(){this._isSliding&&a(this._element),this._clearInterval()}cycle(){this._clearInterval(),this._updateInterval(),this._interval=setInterval((()=>this.nextWhenVisible()),this._config.interval)}_maybeEnableCycle(){this._config.ride&&(this._isSliding?F.one(this._element,it,(()=>this.cycle())):this.cycle())}to(t){const e=this._getItems();if(t>e.length-1||t<0)return;if(this._isSliding)return void F.one(this._element,it,(()=>this.to(t)));const s=this._getItemIndex(this._getActive());if(s===t)return;const i=t>s?Z:tt;this._slide(i,e[t])}dispose(){this._swipeHelper&&this._swipeHelper.dispose(),super.dispose()}_configAfterMerge(t){return t.defaultInterval=t.interval,t}_addEventListeners(){this._config.keyboard&&F.on(this._element,"keydown.bs.carousel",(t=>this._keydown(t))),"hover"===this._config.pause&&(F.on(this._element,"mouseenter.bs.carousel",(()=>this.pause())),F.on(this._element,"mouseleave.bs.carousel",(()=>this._maybeEnableCycle()))),this._config.touch&&J.isSupported()&&this._addTouchEventListeners()}_addTouchEventListeners(){for(const t of V.find(".carousel-item img",this._element))F.on(t,"dragstart.bs.carousel",(t=>t.preventDefault()));const t={leftCallback:()=>this._slide(this._directionToOrder(et)),rightCallback:()=>this._slide(this._directionToOrder(st)),endCallback:()=>{"hover"===this._config.pause&&(this.pause(),this.touchTimeout&&clearTimeout(this.touchTimeout),this.touchTimeout=setTimeout((()=>this._maybeEnableCycle()),500+this._config.interval))}};this._swipeHelper=new J(this._element,t)}_keydown(t){if(/input|textarea/i.test(t.target.tagName))return;const e=rt[t.key];e&&(t.preventDefault(),this._slide(this._directionToOrder(e)))}_getItemIndex(t){return this._getItems().indexOf(t)}_setActiveIndicatorElement(t){if(!this._indicatorsElement)return;const e=V.findOne(".active",this._indicatorsElement);e.classList.remove(ot),e.removeAttribute("aria-current");const s=V.findOne(`[data-bs-slide-to="${t}"]`,this._indicatorsElement);s&&(s.classList.add(ot),s.setAttribute("aria-current","true"))}_updateInterval(){const t=this._activeElement||this._getActive();if(!t)return;const e=Number.parseInt(t.getAttribute("data-bs-interval"),10);this._config.interval=e||this._config.defaultInterval}_slide(t,e=null){if(this._isSliding)return;const s=this._getActive(),i=t===Z,n=e||w(this._getItems(),s,i,this._config.wrap);if(n===s)return;const o=this._getItemIndex(n),r=e=>F.trigger(this._element,e,{relatedTarget:n,direction:this._orderToDirection(t),from:this._getItemIndex(s),to:o});if(r("slide.bs.carousel").defaultPrevented)return;if(!s||!n)return;const a=Boolean(this._interval);this.pause(),this._isSliding=!0,this._setActiveIndicatorElement(o),this._activeElement=n;const l=i?"carousel-item-start":"carousel-item-end",c=i?"carousel-item-next":"carousel-item-prev";n.classList.add(c),g(n),s.classList.add(l),n.classList.add(l),this._queueCallback((()=>{n.classList.remove(l,c),n.classList.add(ot),s.classList.remove(ot,c,l),this._isSliding=!1,r(it)}),s,this._isAnimated()),a&&this.cycle()}_isAnimated(){return this._element.classList.contains("slide")}_getActive(){return V.findOne(".active.carousel-item",this._element)}_getItems(){return V.find(".carousel-item",this._element)}_clearInterval(){this._interval&&(clearInterval(this._interval),this._interval=null)}_directionToOrder(t){return p()?t===et?tt:Z:t===et?Z:tt}_orderToDirection(t){return p()?t===tt?et:st:t===tt?st:et}static jQueryInterface(t){return this.each((function(){const e=ct.getOrCreateInstance(this,t);if("number"!=typeof t){if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}else e.to(t)}))}}F.on(document,"click.bs.carousel.data-api","[data-bs-slide], [data-bs-slide-to]",(function(t){const e=V.getElementFromSelector(this);if(!e||!e.classList.contains(nt))return;t.preventDefault();const s=ct.getOrCreateInstance(e),i=this.getAttribute("data-bs-slide-to");return i?(s.to(i),void s._maybeEnableCycle()):"next"===B.getDataAttribute(this,"slide")?(s.next(),void s._maybeEnableCycle()):(s.prev(),void s._maybeEnableCycle())})),F.on(window,"load.bs.carousel.data-api",(()=>{const t=V.find('[data-bs-ride="carousel"]');for(const e of t)ct.getOrCreateInstance(e)})),b(ct);const ht="show",dt="collapse",ut="collapsing",_t='[data-bs-toggle="collapse"]',gt={parent:null,toggle:!0},ft={parent:"(null|element)",toggle:"boolean"};class mt extends W{constructor(t,e){super(t,e),this._isTransitioning=!1,this._triggerArray=[];const s=V.find(_t);for(const t of s){const e=V.getSelectorFromElement(t),s=V.find(e).filter((t=>t===this._element));null!==e&&s.length&&this._triggerArray.push(t)}this._initializeChildren(),this._config.parent||this._addAriaAndCollapsedClass(this._triggerArray,this._isShown()),this._config.toggle&&this.toggle()}static get Default(){return gt}static get DefaultType(){return ft}static get NAME(){return"collapse"}toggle(){this._isShown()?this.hide():this.show()}show(){if(this._isTransitioning||this._isShown())return;let t=[];if(this._config.parent&&(t=this._getFirstLevelChildren(".collapse.show, .collapse.collapsing").filter((t=>t!==this._element)).map((t=>mt.getOrCreateInstance(t,{toggle:!1})))),t.length&&t[0]._isTransitioning)return;if(F.trigger(this._element,"show.bs.collapse").defaultPrevented)return;for(const e of t)e.hide();const e=this._getDimension();this._element.classList.remove(dt),this._element.classList.add(ut),this._element.style[e]=0,this._addAriaAndCollapsedClass(this._triggerArray,!0),this._isTransitioning=!0;const s=`scroll${e[0].toUpperCase()+e.slice(1)}`;this._queueCallback((()=>{this._isTransitioning=!1,this._element.classList.remove(ut),this._element.classList.add(dt,ht),this._element.style[e]="",F.trigger(this._element,"shown.bs.collapse")}),this._element,!0),this._element.style[e]=`${this._element[s]}px`}hide(){if(this._isTransitioning||!this._isShown())return;if(F.trigger(this._element,"hide.bs.collapse").defaultPrevented)return;const t=this._getDimension();this._element.style[t]=`${this._element.getBoundingClientRect()[t]}px`,g(this._element),this._element.classList.add(ut),this._element.classList.remove(dt,ht);for(const t of this._triggerArray){const e=V.getElementFromSelector(t);e&&!this._isShown(e)&&this._addAriaAndCollapsedClass([t],!1)}this._isTransitioning=!0,this._element.style[t]="",this._queueCallback((()=>{this._isTransitioning=!1,this._element.classList.remove(ut),this._element.classList.add(dt),F.trigger(this._element,"hidden.bs.collapse")}),this._element,!0)}_isShown(t=this._element){return t.classList.contains(ht)}_configAfterMerge(t){return t.toggle=Boolean(t.toggle),t.parent=c(t.parent),t}_getDimension(){return this._element.classList.contains("collapse-horizontal")?"width":"height"}_initializeChildren(){if(!this._config.parent)return;const t=this._getFirstLevelChildren(_t);for(const e of t){const t=V.getElementFromSelector(e);t&&this._addAriaAndCollapsedClass([e],this._isShown(t))}}_getFirstLevelChildren(t){const e=V.find(":scope .collapse .collapse",this._config.parent);return V.find(t,this._config.parent).filter((t=>!e.includes(t)))}_addAriaAndCollapsedClass(t,e){if(t.length)for(const s of t)s.classList.toggle("collapsed",!e),s.setAttribute("aria-expanded",e)}static jQueryInterface(t){const e={};return"string"==typeof t&&/show|hide/.test(t)&&(e.toggle=!1),this.each((function(){const s=mt.getOrCreateInstance(this,e);if("string"==typeof t){if(void 0===s[t])throw new TypeError(`No method named "${t}"`);s[t]()}}))}}F.on(document,"click.bs.collapse.data-api",_t,(function(t){("A"===t.target.tagName||t.delegateTarget&&"A"===t.delegateTarget.tagName)&&t.preventDefault();for(const t of V.getMultipleElementsFromSelector(this))mt.getOrCreateInstance(t,{toggle:!1}).toggle()})),b(mt);const pt="dropdown",bt="ArrowUp",vt="ArrowDown",yt="click.bs.dropdown.data-api",wt="keydown.bs.dropdown.data-api",At="show",Et='[data-bs-toggle="dropdown"]:not(.disabled):not(:disabled)',Ct=`${Et}.show`,Tt=".dropdown-menu",kt=p()?"top-end":"top-start",St=p()?"top-start":"top-end",Lt=p()?"bottom-end":"bottom-start",Ot=p()?"bottom-start":"bottom-end",It=p()?"left-start":"right-start",Dt=p()?"right-start":"left-start",Nt={autoClose:!0,boundary:"clippingParents",display:"dynamic",offset:[0,2],popperConfig:null,reference:"toggle"},Pt={autoClose:"(boolean|string)",boundary:"(string|element)",display:"string",offset:"(array|string|function)",popperConfig:"(null|object|function)",reference:"(string|element|object)"};class xt extends W{constructor(t,e){super(t,e),this._popper=null,this._parent=this._element.parentNode,this._menu=V.next(this._element,Tt)[0]||V.prev(this._element,Tt)[0]||V.findOne(Tt,this._parent),this._inNavbar=this._detectNavbar()}static get Default(){return Nt}static get DefaultType(){return Pt}static get NAME(){return pt}toggle(){return this._isShown()?this.hide():this.show()}show(){if(d(this._element)||this._isShown())return;const t={relatedTarget:this._element};if(!F.trigger(this._element,"show.bs.dropdown",t).defaultPrevented){if(this._createPopper(),"ontouchstart"in document.documentElement&&!this._parent.closest(".navbar-nav"))for(const t of[].concat(...document.body.children))F.on(t,"mouseover",_);this._element.focus(),this._element.setAttribute("aria-expanded",!0),this._menu.classList.add(At),this._element.classList.add(At),F.trigger(this._element,"shown.bs.dropdown",t)}}hide(){if(d(this._element)||!this._isShown())return;const t={relatedTarget:this._element};this._completeHide(t)}dispose(){this._popper&&this._popper.destroy(),super.dispose()}update(){this._inNavbar=this._detectNavbar(),this._popper&&this._popper.update()}_completeHide(t){if(!F.trigger(this._element,"hide.bs.dropdown",t).defaultPrevented){if("ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))F.off(t,"mouseover",_);this._popper&&this._popper.destroy(),this._menu.classList.remove(At),this._element.classList.remove(At),this._element.setAttribute("aria-expanded","false"),B.removeDataAttribute(this._menu,"popper"),F.trigger(this._element,"hidden.bs.dropdown",t)}}_getConfig(t){if("object"==typeof(t=super._getConfig(t)).reference&&!l(t.reference)&&"function"!=typeof t.reference.getBoundingClientRect)throw new TypeError(`${pt.toUpperCase()}: Option "reference" provided type "object" without a required "getBoundingClientRect" method.`);return t}_createPopper(){if(void 0===s)throw new TypeError("Bootstrap's dropdowns require Popper (https://popper.js.org)");let t=this._element;"parent"===this._config.reference?t=this._parent:l(this._config.reference)?t=c(this._config.reference):"object"==typeof this._config.reference&&(t=this._config.reference);const e=this._getPopperConfig();this._popper=s.createPopper(t,this._menu,e)}_isShown(){return this._menu.classList.contains(At)}_getPlacement(){const t=this._parent;if(t.classList.contains("dropend"))return It;if(t.classList.contains("dropstart"))return Dt;if(t.classList.contains("dropup-center"))return"top";if(t.classList.contains("dropdown-center"))return"bottom";const e="end"===getComputedStyle(this._menu).getPropertyValue("--bs-position").trim();return t.classList.contains("dropup")?e?St:kt:e?Ot:Lt}_detectNavbar(){return null!==this._element.closest(".navbar")}_getOffset(){const{offset:t}=this._config;return"string"==typeof t?t.split(",").map((t=>Number.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_getPopperConfig(){const t={placement:this._getPlacement(),modifiers:[{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"offset",options:{offset:this._getOffset()}}]};return(this._inNavbar||"static"===this._config.display)&&(B.setDataAttribute(this._menu,"popper","static"),t.modifiers=[{name:"applyStyles",enabled:!1}]),{...t,...v(this._config.popperConfig,[t])}}_selectMenuItem({key:t,target:e}){const s=V.find(".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)",this._menu).filter((t=>h(t)));s.length&&w(s,e,t===vt,!s.includes(e)).focus()}static jQueryInterface(t){return this.each((function(){const e=xt.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}static clearMenus(t){if(2===t.button||"keyup"===t.type&&"Tab"!==t.key)return;const e=V.find(Ct);for(const s of e){const e=xt.getInstance(s);if(!e||!1===e._config.autoClose)continue;const i=t.composedPath(),n=i.includes(e._menu);if(i.includes(e._element)||"inside"===e._config.autoClose&&!n||"outside"===e._config.autoClose&&n)continue;if(e._menu.contains(t.target)&&("keyup"===t.type&&"Tab"===t.key||/input|select|option|textarea|form/i.test(t.target.tagName)))continue;const o={relatedTarget:e._element};"click"===t.type&&(o.clickEvent=t),e._completeHide(o)}}static dataApiKeydownHandler(t){const e=/input|textarea/i.test(t.target.tagName),s="Escape"===t.key,i=[bt,vt].includes(t.key);if(!i&&!s)return;if(e&&!s)return;t.preventDefault();const n=this.matches(Et)?this:V.prev(this,Et)[0]||V.next(this,Et)[0]||V.findOne(Et,t.delegateTarget.parentNode),o=xt.getOrCreateInstance(n);if(i)return t.stopPropagation(),o.show(),void o._selectMenuItem(t);o._isShown()&&(t.stopPropagation(),o.hide(),n.focus())}}F.on(document,wt,Et,xt.dataApiKeydownHandler),F.on(document,wt,Tt,xt.dataApiKeydownHandler),F.on(document,yt,xt.clearMenus),F.on(document,"keyup.bs.dropdown.data-api",xt.clearMenus),F.on(document,yt,Et,(function(t){t.preventDefault(),xt.getOrCreateInstance(this).toggle()})),b(xt);const Mt="show",jt="mousedown.bs.backdrop",Ft={className:"modal-backdrop",clickCallback:null,isAnimated:!1,isVisible:!0,rootElement:"body"},$t={className:"string",clickCallback:"(function|null)",isAnimated:"boolean",isVisible:"boolean",rootElement:"(element|string)"};class zt extends q{constructor(t){super(),this._config=this._getConfig(t),this._isAppended=!1,this._element=null}static get Default(){return Ft}static get DefaultType(){return $t}static get NAME(){return"backdrop"}show(t){if(!this._config.isVisible)return void v(t);this._append();const e=this._getElement();this._config.isAnimated&&g(e),e.classList.add(Mt),this._emulateAnimation((()=>{v(t)}))}hide(t){this._config.isVisible?(this._getElement().classList.remove(Mt),this._emulateAnimation((()=>{this.dispose(),v(t)}))):v(t)}dispose(){this._isAppended&&(F.off(this._element,jt),this._element.remove(),this._isAppended=!1)}_getElement(){if(!this._element){const t=document.createElement("div");t.className=this._config.className,this._config.isAnimated&&t.classList.add("fade"),this._element=t}return this._element}_configAfterMerge(t){return t.rootElement=c(t.rootElement),t}_append(){if(this._isAppended)return;const t=this._getElement();this._config.rootElement.append(t),F.on(t,jt,(()=>{v(this._config.clickCallback)})),this._isAppended=!0}_emulateAnimation(t){y(t,this._getElement(),this._config.isAnimated)}}const Ht=".bs.focustrap",Bt="backward",qt={autofocus:!0,trapElement:null},Wt={autofocus:"boolean",trapElement:"element"};class Rt extends q{constructor(t){super(),this._config=this._getConfig(t),this._isActive=!1,this._lastTabNavDirection=null}static get Default(){return qt}static get DefaultType(){return Wt}static get NAME(){return"focustrap"}activate(){this._isActive||(this._config.autofocus&&this._config.trapElement.focus(),F.off(document,Ht),F.on(document,"focusin.bs.focustrap",(t=>this._handleFocusin(t))),F.on(document,"keydown.tab.bs.focustrap",(t=>this._handleKeydown(t))),this._isActive=!0)}deactivate(){this._isActive&&(this._isActive=!1,F.off(document,Ht))}_handleFocusin(t){const{trapElement:e}=this._config;if(t.target===document||t.target===e||e.contains(t.target))return;const s=V.focusableChildren(e);0===s.length?e.focus():this._lastTabNavDirection===Bt?s[s.length-1].focus():s[0].focus()}_handleKeydown(t){"Tab"===t.key&&(this._lastTabNavDirection=t.shiftKey?Bt:"forward")}}const Vt=".fixed-top, .fixed-bottom, .is-fixed, .sticky-top",Kt=".sticky-top",Qt="padding-right",Xt="margin-right";class Yt{constructor(){this._element=document.body}getWidth(){const t=document.documentElement.clientWidth;return Math.abs(window.innerWidth-t)}hide(){const t=this.getWidth();this._disableOverFlow(),this._setElementAttributes(this._element,Qt,(e=>e+t)),this._setElementAttributes(Vt,Qt,(e=>e+t)),this._setElementAttributes(Kt,Xt,(e=>e-t))}reset(){this._resetElementAttributes(this._element,"overflow"),this._resetElementAttributes(this._element,Qt),this._resetElementAttributes(Vt,Qt),this._resetElementAttributes(Kt,Xt)}isOverflowing(){return this.getWidth()>0}_disableOverFlow(){this._saveInitialAttribute(this._element,"overflow"),this._element.style.overflow="hidden"}_setElementAttributes(t,e,s){const i=this.getWidth();this._applyManipulationCallback(t,(t=>{if(t!==this._element&&window.innerWidth>t.clientWidth+i)return;this._saveInitialAttribute(t,e);const n=window.getComputedStyle(t).getPropertyValue(e);t.style.setProperty(e,`${s(Number.parseFloat(n))}px`)}))}_saveInitialAttribute(t,e){const s=t.style.getPropertyValue(e);s&&B.setDataAttribute(t,e,s)}_resetElementAttributes(t,e){this._applyManipulationCallback(t,(t=>{const s=B.getDataAttribute(t,e);null!==s?(B.removeDataAttribute(t,e),t.style.setProperty(e,s)):t.style.removeProperty(e)}))}_applyManipulationCallback(t,e){if(l(t))e(t);else for(const s of V.find(t,this._element))e(s)}}const Ut=".bs.modal",Gt="hidden.bs.modal",Jt="show.bs.modal",Zt="modal-open",te="show",ee="modal-static",se={backdrop:!0,focus:!0,keyboard:!0},ie={backdrop:"(boolean|string)",focus:"boolean",keyboard:"boolean"};class ne extends W{constructor(t,e){super(t,e),this._dialog=V.findOne(".modal-dialog",this._element),this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._isShown=!1,this._isTransitioning=!1,this._scrollBar=new Yt,this._addEventListeners()}static get Default(){return se}static get DefaultType(){return ie}static get NAME(){return"modal"}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||this._isTransitioning||F.trigger(this._element,Jt,{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._isTransitioning=!0,this._scrollBar.hide(),document.body.classList.add(Zt),this._adjustDialog(),this._backdrop.show((()=>this._showElement(t))))}hide(){this._isShown&&!this._isTransitioning&&(F.trigger(this._element,"hide.bs.modal").defaultPrevented||(this._isShown=!1,this._isTransitioning=!0,this._focustrap.deactivate(),this._element.classList.remove(te),this._queueCallback((()=>this._hideModal()),this._element,this._isAnimated())))}dispose(){F.off(window,Ut),F.off(this._dialog,Ut),this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}handleUpdate(){this._adjustDialog()}_initializeBackDrop(){return new zt({isVisible:Boolean(this._config.backdrop),isAnimated:this._isAnimated()})}_initializeFocusTrap(){return new Rt({trapElement:this._element})}_showElement(t){document.body.contains(this._element)||document.body.append(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.scrollTop=0;const e=V.findOne(".modal-body",this._dialog);e&&(e.scrollTop=0),g(this._element),this._element.classList.add(te),this._queueCallback((()=>{this._config.focus&&this._focustrap.activate(),this._isTransitioning=!1,F.trigger(this._element,"shown.bs.modal",{relatedTarget:t})}),this._dialog,this._isAnimated())}_addEventListeners(){F.on(this._element,"keydown.dismiss.bs.modal",(t=>{"Escape"===t.key&&(this._config.keyboard?this.hide():this._triggerBackdropTransition())})),F.on(window,"resize.bs.modal",(()=>{this._isShown&&!this._isTransitioning&&this._adjustDialog()})),F.on(this._element,"mousedown.dismiss.bs.modal",(t=>{F.one(this._element,"click.dismiss.bs.modal",(e=>{this._element===t.target&&this._element===e.target&&("static"!==this._config.backdrop?this._config.backdrop&&this.hide():this._triggerBackdropTransition())}))}))}_hideModal(){this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._isTransitioning=!1,this._backdrop.hide((()=>{document.body.classList.remove(Zt),this._resetAdjustments(),this._scrollBar.reset(),F.trigger(this._element,Gt)}))}_isAnimated(){return this._element.classList.contains("fade")}_triggerBackdropTransition(){if(F.trigger(this._element,"hidePrevented.bs.modal").defaultPrevented)return;const t=this._element.scrollHeight>document.documentElement.clientHeight,e=this._element.style.overflowY;"hidden"===e||this._element.classList.contains(ee)||(t||(this._element.style.overflowY="hidden"),this._element.classList.add(ee),this._queueCallback((()=>{this._element.classList.remove(ee),this._queueCallback((()=>{this._element.style.overflowY=e}),this._dialog)}),this._dialog),this._element.focus())}_adjustDialog(){const t=this._element.scrollHeight>document.documentElement.clientHeight,e=this._scrollBar.getWidth(),s=e>0;if(s&&!t){const t=p()?"paddingLeft":"paddingRight";this._element.style[t]=`${e}px`}if(!s&&t){const t=p()?"paddingRight":"paddingLeft";this._element.style[t]=`${e}px`}}_resetAdjustments(){this._element.style.paddingLeft="",this._element.style.paddingRight=""}static jQueryInterface(t,e){return this.each((function(){const s=ne.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===s[t])throw new TypeError(`No method named "${t}"`);s[t](e)}}))}}F.on(document,"click.bs.modal.data-api",'[data-bs-toggle="modal"]',(function(t){const e=V.getElementFromSelector(this);["A","AREA"].includes(this.tagName)&&t.preventDefault(),F.one(e,Jt,(t=>{t.defaultPrevented||F.one(e,Gt,(()=>{h(this)&&this.focus()}))}));const s=V.findOne(".modal.show");s&&ne.getInstance(s).hide(),ne.getOrCreateInstance(e).toggle(this)})),K(ne),b(ne);const oe="show",re="showing",ae="hiding",le=".offcanvas.show",ce="hidePrevented.bs.offcanvas",he="hidden.bs.offcanvas",de={backdrop:!0,keyboard:!0,scroll:!1},ue={backdrop:"(boolean|string)",keyboard:"boolean",scroll:"boolean"};class _e extends W{constructor(t,e){super(t,e),this._isShown=!1,this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._addEventListeners()}static get Default(){return de}static get DefaultType(){return ue}static get NAME(){return"offcanvas"}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||F.trigger(this._element,"show.bs.offcanvas",{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._backdrop.show(),this._config.scroll||(new Yt).hide(),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.classList.add(re),this._queueCallback((()=>{this._config.scroll&&!this._config.backdrop||this._focustrap.activate(),this._element.classList.add(oe),this._element.classList.remove(re),F.trigger(this._element,"shown.bs.offcanvas",{relatedTarget:t})}),this._element,!0))}hide(){this._isShown&&(F.trigger(this._element,"hide.bs.offcanvas").defaultPrevented||(this._focustrap.deactivate(),this._element.blur(),this._isShown=!1,this._element.classList.add(ae),this._backdrop.hide(),this._queueCallback((()=>{this._element.classList.remove(oe,ae),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._config.scroll||(new Yt).reset(),F.trigger(this._element,he)}),this._element,!0)))}dispose(){this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}_initializeBackDrop(){const t=Boolean(this._config.backdrop);return new zt({className:"offcanvas-backdrop",isVisible:t,isAnimated:!0,rootElement:this._element.parentNode,clickCallback:t?()=>{"static"!==this._config.backdrop?this.hide():F.trigger(this._element,ce)}:null})}_initializeFocusTrap(){return new Rt({trapElement:this._element})}_addEventListeners(){F.on(this._element,"keydown.dismiss.bs.offcanvas",(t=>{"Escape"===t.key&&(this._config.keyboard?this.hide():F.trigger(this._element,ce))}))}static jQueryInterface(t){return this.each((function(){const e=_e.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}F.on(document,"click.bs.offcanvas.data-api",'[data-bs-toggle="offcanvas"]',(function(t){const e=V.getElementFromSelector(this);if(["A","AREA"].includes(this.tagName)&&t.preventDefault(),d(this))return;F.one(e,he,(()=>{h(this)&&this.focus()}));const s=V.findOne(le);s&&s!==e&&_e.getInstance(s).hide(),_e.getOrCreateInstance(e).toggle(this)})),F.on(window,"load.bs.offcanvas.data-api",(()=>{for(const t of V.find(le))_e.getOrCreateInstance(t).show()})),F.on(window,"resize.bs.offcanvas",(()=>{for(const t of V.find("[aria-modal][class*=show][class*=offcanvas-]"))"fixed"!==getComputedStyle(t).position&&_e.getOrCreateInstance(t).hide()})),K(_e),b(_e);const ge=new Set(["background","cite","href","itemtype","longdesc","poster","src","xlink:href"]),fe=/^(?:(?:https?|mailto|ftp|tel|file|sms):|[^#&/:?]*(?:[#/?]|$))/i,me=/^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i,pe=(t,e)=>{const s=t.nodeName.toLowerCase();return e.includes(s)?!ge.has(s)||Boolean(fe.test(t.nodeValue)||me.test(t.nodeValue)):e.filter((t=>t instanceof RegExp)).some((t=>t.test(s)))},be={"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},ve={allowList:be,content:{},extraClass:"",html:!1,sanitize:!0,sanitizeFn:null,template:"
"},ye={allowList:"object",content:"object",extraClass:"(string|function)",html:"boolean",sanitize:"boolean",sanitizeFn:"(null|function)",template:"string"},we={entry:"(string|element|function|null)",selector:"(string|element)"};class Ae extends q{constructor(t){super(),this._config=this._getConfig(t)}static get Default(){return ve}static get DefaultType(){return ye}static get NAME(){return"TemplateFactory"}getContent(){return Object.values(this._config.content).map((t=>this._resolvePossibleFunction(t))).filter(Boolean)}hasContent(){return this.getContent().length>0}changeContent(t){return this._checkContent(t),this._config.content={...this._config.content,...t},this}toHtml(){const t=document.createElement("div");t.innerHTML=this._maybeSanitize(this._config.template);for(const[e,s]of Object.entries(this._config.content))this._setContent(t,s,e);const e=t.children[0],s=this._resolvePossibleFunction(this._config.extraClass);return s&&e.classList.add(...s.split(" ")),e}_typeCheckConfig(t){super._typeCheckConfig(t),this._checkContent(t.content)}_checkContent(t){for(const[e,s]of Object.entries(t))super._typeCheckConfig({selector:e,entry:s},we)}_setContent(t,e,s){const i=V.findOne(s,t);i&&((e=this._resolvePossibleFunction(e))?l(e)?this._putElementInTemplate(c(e),i):this._config.html?i.innerHTML=this._maybeSanitize(e):i.textContent=e:i.remove())}_maybeSanitize(t){return this._config.sanitize?function(t,e,s){if(!t.length)return t;if(s&&"function"==typeof s)return s(t);const i=(new window.DOMParser).parseFromString(t,"text/html"),n=[].concat(...i.body.querySelectorAll("*"));for(const t of n){const s=t.nodeName.toLowerCase();if(!Object.keys(e).includes(s)){t.remove();continue}const i=[].concat(...t.attributes),n=[].concat(e["*"]||[],e[s]||[]);for(const e of i)pe(e,n)||t.removeAttribute(e.nodeName)}return i.body.innerHTML}(t,this._config.allowList,this._config.sanitizeFn):t}_resolvePossibleFunction(t){return v(t,[this])}_putElementInTemplate(t,e){if(this._config.html)return e.innerHTML="",void e.append(t);e.textContent=t.textContent}}const Ee=new Set(["sanitize","allowList","sanitizeFn"]),Ce="fade",Te="show",ke=".modal",Se="hide.bs.modal",Le="hover",Oe="focus",Ie={AUTO:"auto",TOP:"top",RIGHT:p()?"left":"right",BOTTOM:"bottom",LEFT:p()?"right":"left"},De={allowList:be,animation:!0,boundary:"clippingParents",container:!1,customClass:"",delay:0,fallbackPlacements:["top","right","bottom","left"],html:!1,offset:[0,6],placement:"top",popperConfig:null,sanitize:!0,sanitizeFn:null,selector:!1,template:'',title:"",trigger:"hover focus"},Ne={allowList:"object",animation:"boolean",boundary:"(string|element)",container:"(string|element|boolean)",customClass:"(string|function)",delay:"(number|object)",fallbackPlacements:"array",html:"boolean",offset:"(array|string|function)",placement:"(string|function)",popperConfig:"(null|object|function)",sanitize:"boolean",sanitizeFn:"(null|function)",selector:"(string|boolean)",template:"string",title:"(string|element|function)",trigger:"string"};class Pe extends W{constructor(t,e){if(void 0===s)throw new TypeError("Bootstrap's tooltips require Popper (https://popper.js.org)");super(t,e),this._isEnabled=!0,this._timeout=0,this._isHovered=null,this._activeTrigger={},this._popper=null,this._templateFactory=null,this._newContent=null,this.tip=null,this._setListeners(),this._config.selector||this._fixTitle()}static get Default(){return De}static get DefaultType(){return Ne}static get NAME(){return"tooltip"}enable(){this._isEnabled=!0}disable(){this._isEnabled=!1}toggleEnabled(){this._isEnabled=!this._isEnabled}toggle(){this._isEnabled&&(this._activeTrigger.click=!this._activeTrigger.click,this._isShown()?this._leave():this._enter())}dispose(){clearTimeout(this._timeout),F.off(this._element.closest(ke),Se,this._hideModalHandler),this._element.getAttribute("data-bs-original-title")&&this._element.setAttribute("title",this._element.getAttribute("data-bs-original-title")),this._disposePopper(),super.dispose()}show(){if("none"===this._element.style.display)throw new Error("Please use show on visible elements");if(!this._isWithContent()||!this._isEnabled)return;const t=F.trigger(this._element,this.constructor.eventName("show")),e=(u(this._element)||this._element.ownerDocument.documentElement).contains(this._element);if(t.defaultPrevented||!e)return;this._disposePopper();const s=this._getTipElement();this._element.setAttribute("aria-describedby",s.getAttribute("id"));const{container:i}=this._config;if(this._element.ownerDocument.documentElement.contains(this.tip)||(i.append(s),F.trigger(this._element,this.constructor.eventName("inserted"))),this._popper=this._createPopper(s),s.classList.add(Te),"ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))F.on(t,"mouseover",_);this._queueCallback((()=>{F.trigger(this._element,this.constructor.eventName("shown")),!1===this._isHovered&&this._leave(),this._isHovered=!1}),this.tip,this._isAnimated())}hide(){if(this._isShown()&&!F.trigger(this._element,this.constructor.eventName("hide")).defaultPrevented){if(this._getTipElement().classList.remove(Te),"ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))F.off(t,"mouseover",_);this._activeTrigger.click=!1,this._activeTrigger.focus=!1,this._activeTrigger.hover=!1,this._isHovered=null,this._queueCallback((()=>{this._isWithActiveTrigger()||(this._isHovered||this._disposePopper(),this._element.removeAttribute("aria-describedby"),F.trigger(this._element,this.constructor.eventName("hidden")))}),this.tip,this._isAnimated())}}update(){this._popper&&this._popper.update()}_isWithContent(){return Boolean(this._getTitle())}_getTipElement(){return this.tip||(this.tip=this._createTipElement(this._newContent||this._getContentForTemplate())),this.tip}_createTipElement(t){const e=this._getTemplateFactory(t).toHtml();if(!e)return null;e.classList.remove(Ce,Te),e.classList.add(`bs-${this.constructor.NAME}-auto`);const s=(t=>{do{t+=Math.floor(1e6*Math.random())}while(document.getElementById(t));return t})(this.constructor.NAME).toString();return e.setAttribute("id",s),this._isAnimated()&&e.classList.add(Ce),e}setContent(t){this._newContent=t,this._isShown()&&(this._disposePopper(),this.show())}_getTemplateFactory(t){return this._templateFactory?this._templateFactory.changeContent(t):this._templateFactory=new Ae({...this._config,content:t,extraClass:this._resolvePossibleFunction(this._config.customClass)}),this._templateFactory}_getContentForTemplate(){return{".tooltip-inner":this._getTitle()}}_getTitle(){return this._resolvePossibleFunction(this._config.title)||this._element.getAttribute("data-bs-original-title")}_initializeOnDelegatedTarget(t){return this.constructor.getOrCreateInstance(t.delegateTarget,this._getDelegateConfig())}_isAnimated(){return this._config.animation||this.tip&&this.tip.classList.contains(Ce)}_isShown(){return this.tip&&this.tip.classList.contains(Te)}_createPopper(t){const e=v(this._config.placement,[this,t,this._element]),i=Ie[e.toUpperCase()];return s.createPopper(this._element,t,this._getPopperConfig(i))}_getOffset(){const{offset:t}=this._config;return"string"==typeof t?t.split(",").map((t=>Number.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_resolvePossibleFunction(t){return v(t,[this._element])}_getPopperConfig(t){const e={placement:t,modifiers:[{name:"flip",options:{fallbackPlacements:this._config.fallbackPlacements}},{name:"offset",options:{offset:this._getOffset()}},{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"arrow",options:{element:`.${this.constructor.NAME}-arrow`}},{name:"preSetPlacement",enabled:!0,phase:"beforeMain",fn:t=>{this._getTipElement().setAttribute("data-popper-placement",t.state.placement)}}]};return{...e,...v(this._config.popperConfig,[e])}}_setListeners(){const t=this._config.trigger.split(" ");for(const e of t)if("click"===e)F.on(this._element,this.constructor.eventName("click"),this._config.selector,(t=>{this._initializeOnDelegatedTarget(t).toggle()}));else if("manual"!==e){const t=e===Le?this.constructor.eventName("mouseenter"):this.constructor.eventName("focusin"),s=e===Le?this.constructor.eventName("mouseleave"):this.constructor.eventName("focusout");F.on(this._element,t,this._config.selector,(t=>{const e=this._initializeOnDelegatedTarget(t);e._activeTrigger["focusin"===t.type?Oe:Le]=!0,e._enter()})),F.on(this._element,s,this._config.selector,(t=>{const e=this._initializeOnDelegatedTarget(t);e._activeTrigger["focusout"===t.type?Oe:Le]=e._element.contains(t.relatedTarget),e._leave()}))}this._hideModalHandler=()=>{this._element&&this.hide()},F.on(this._element.closest(ke),Se,this._hideModalHandler)}_fixTitle(){const t=this._element.getAttribute("title");t&&(this._element.getAttribute("aria-label")||this._element.textContent.trim()||this._element.setAttribute("aria-label",t),this._element.setAttribute("data-bs-original-title",t),this._element.removeAttribute("title"))}_enter(){this._isShown()||this._isHovered?this._isHovered=!0:(this._isHovered=!0,this._setTimeout((()=>{this._isHovered&&this.show()}),this._config.delay.show))}_leave(){this._isWithActiveTrigger()||(this._isHovered=!1,this._setTimeout((()=>{this._isHovered||this.hide()}),this._config.delay.hide))}_setTimeout(t,e){clearTimeout(this._timeout),this._timeout=setTimeout(t,e)}_isWithActiveTrigger(){return Object.values(this._activeTrigger).includes(!0)}_getConfig(t){const e=B.getDataAttributes(this._element);for(const t of Object.keys(e))Ee.has(t)&&delete e[t];return t={...e,..."object"==typeof t&&t?t:{}},t=this._mergeConfigObj(t),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}_configAfterMerge(t){return t.container=!1===t.container?document.body:c(t.container),"number"==typeof t.delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),t}_getDelegateConfig(){const t={};for(const[e,s]of Object.entries(this._config))this.constructor.Default[e]!==s&&(t[e]=s);return t.selector=!1,t.trigger="manual",t}_disposePopper(){this._popper&&(this._popper.destroy(),this._popper=null),this.tip&&(this.tip.remove(),this.tip=null)}static jQueryInterface(t){return this.each((function(){const e=Pe.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}b(Pe);const xe={...Pe.Default,content:"",offset:[0,8],placement:"right",template:'',trigger:"click"},Me={...Pe.DefaultType,content:"(null|string|element|function)"};class je extends Pe{static get Default(){return xe}static get DefaultType(){return Me}static get NAME(){return"popover"}_isWithContent(){return this._getTitle()||this._getContent()}_getContentForTemplate(){return{".popover-header":this._getTitle(),".popover-body":this._getContent()}}_getContent(){return this._resolvePossibleFunction(this._config.content)}static jQueryInterface(t){return this.each((function(){const e=je.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}b(je);const Fe="click.bs.scrollspy",$e="active",ze="[href]",He={offset:null,rootMargin:"0px 0px -25%",smoothScroll:!1,target:null,threshold:[.1,.5,1]},Be={offset:"(number|null)",rootMargin:"string",smoothScroll:"boolean",target:"element",threshold:"array"};class qe extends W{constructor(t,e){super(t,e),this._targetLinks=new Map,this._observableSections=new Map,this._rootElement="visible"===getComputedStyle(this._element).overflowY?null:this._element,this._activeTarget=null,this._observer=null,this._previousScrollData={visibleEntryTop:0,parentScrollTop:0},this.refresh()}static get Default(){return He}static get DefaultType(){return Be}static get NAME(){return"scrollspy"}refresh(){this._initializeTargetsAndObservables(),this._maybeEnableSmoothScroll(),this._observer?this._observer.disconnect():this._observer=this._getNewObserver();for(const t of this._observableSections.values())this._observer.observe(t)}dispose(){this._observer.disconnect(),super.dispose()}_configAfterMerge(t){return t.target=c(t.target)||document.body,t.rootMargin=t.offset?`${t.offset}px 0px -30%`:t.rootMargin,"string"==typeof t.threshold&&(t.threshold=t.threshold.split(",").map((t=>Number.parseFloat(t)))),t}_maybeEnableSmoothScroll(){this._config.smoothScroll&&(F.off(this._config.target,Fe),F.on(this._config.target,Fe,ze,(t=>{const e=this._observableSections.get(t.target.hash);if(e){t.preventDefault();const s=this._rootElement||window,i=e.offsetTop-this._element.offsetTop;if(s.scrollTo)return void s.scrollTo({top:i,behavior:"smooth"});s.scrollTop=i}})))}_getNewObserver(){const t={root:this._rootElement,threshold:this._config.threshold,rootMargin:this._config.rootMargin};return new IntersectionObserver((t=>this._observerCallback(t)),t)}_observerCallback(t){const e=t=>this._targetLinks.get(`#${t.target.id}`),s=t=>{this._previousScrollData.visibleEntryTop=t.target.offsetTop,this._process(e(t))},i=(this._rootElement||document.documentElement).scrollTop,n=i>=this._previousScrollData.parentScrollTop;this._previousScrollData.parentScrollTop=i;for(const o of t){if(!o.isIntersecting){this._activeTarget=null,this._clearActiveClass(e(o));continue}const t=o.target.offsetTop>=this._previousScrollData.visibleEntryTop;if(n&&t){if(s(o),!i)return}else n||t||s(o)}}_initializeTargetsAndObservables(){this._targetLinks=new Map,this._observableSections=new Map;const t=V.find(ze,this._config.target);for(const e of t){if(!e.hash||d(e))continue;const t=V.findOne(e.hash,this._element);h(t)&&(this._targetLinks.set(e.hash,e),this._observableSections.set(e.hash,t))}}_process(t){this._activeTarget!==t&&(this._clearActiveClass(this._config.target),this._activeTarget=t,t.classList.add($e),this._activateParents(t),F.trigger(this._element,"activate.bs.scrollspy",{relatedTarget:t}))}_activateParents(t){if(t.classList.contains("dropdown-item"))V.findOne(".dropdown-toggle",t.closest(".dropdown")).classList.add($e);else for(const e of V.parents(t,".nav, .list-group"))for(const t of V.prev(e,".nav-link, .nav-item > .nav-link, .list-group-item"))t.classList.add($e)}_clearActiveClass(t){t.classList.remove($e);const e=V.find("[href].active",t);for(const t of e)t.classList.remove($e)}static jQueryInterface(t){return this.each((function(){const e=qe.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}))}}F.on(window,"load.bs.scrollspy.data-api",(()=>{for(const t of V.find('[data-bs-spy="scroll"]'))qe.getOrCreateInstance(t)})),b(qe);const We="ArrowLeft",Re="ArrowRight",Ve="ArrowUp",Ke="ArrowDown",Qe="active",Xe="fade",Ye="show",Ue='[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]',Ge=`.nav-link:not(.dropdown-toggle), .list-group-item:not(.dropdown-toggle), [role="tab"]:not(.dropdown-toggle), ${Ue}`;class Je extends W{constructor(t){super(t),this._parent=this._element.closest('.list-group, .nav, [role="tablist"]'),this._parent&&(this._setInitialAttributes(this._parent,this._getChildren()),F.on(this._element,"keydown.bs.tab",(t=>this._keydown(t))))}static get NAME(){return"tab"}show(){const t=this._element;if(this._elemIsActive(t))return;const e=this._getActiveElem(),s=e?F.trigger(e,"hide.bs.tab",{relatedTarget:t}):null;F.trigger(t,"show.bs.tab",{relatedTarget:e}).defaultPrevented||s&&s.defaultPrevented||(this._deactivate(e,t),this._activate(t,e))}_activate(t,e){t&&(t.classList.add(Qe),this._activate(V.getElementFromSelector(t)),this._queueCallback((()=>{"tab"===t.getAttribute("role")?(t.removeAttribute("tabindex"),t.setAttribute("aria-selected",!0),this._toggleDropDown(t,!0),F.trigger(t,"shown.bs.tab",{relatedTarget:e})):t.classList.add(Ye)}),t,t.classList.contains(Xe)))}_deactivate(t,e){t&&(t.classList.remove(Qe),t.blur(),this._deactivate(V.getElementFromSelector(t)),this._queueCallback((()=>{"tab"===t.getAttribute("role")?(t.setAttribute("aria-selected",!1),t.setAttribute("tabindex","-1"),this._toggleDropDown(t,!1),F.trigger(t,"hidden.bs.tab",{relatedTarget:e})):t.classList.remove(Ye)}),t,t.classList.contains(Xe)))}_keydown(t){if(![We,Re,Ve,Ke].includes(t.key))return;t.stopPropagation(),t.preventDefault();const e=[Re,Ke].includes(t.key),s=w(this._getChildren().filter((t=>!d(t))),t.target,e,!0);s&&(s.focus({preventScroll:!0}),Je.getOrCreateInstance(s).show())}_getChildren(){return V.find(Ge,this._parent)}_getActiveElem(){return this._getChildren().find((t=>this._elemIsActive(t)))||null}_setInitialAttributes(t,e){this._setAttributeIfNotExists(t,"role","tablist");for(const t of e)this._setInitialAttributesOnChild(t)}_setInitialAttributesOnChild(t){t=this._getInnerElement(t);const e=this._elemIsActive(t),s=this._getOuterElement(t);t.setAttribute("aria-selected",e),s!==t&&this._setAttributeIfNotExists(s,"role","presentation"),e||t.setAttribute("tabindex","-1"),this._setAttributeIfNotExists(t,"role","tab"),this._setInitialAttributesOnTargetPanel(t)}_setInitialAttributesOnTargetPanel(t){const e=V.getElementFromSelector(t);e&&(this._setAttributeIfNotExists(e,"role","tabpanel"),t.id&&this._setAttributeIfNotExists(e,"aria-labelledby",`${t.id}`))}_toggleDropDown(t,e){const s=this._getOuterElement(t);if(!s.classList.contains("dropdown"))return;const i=(t,i)=>{const n=V.findOne(t,s);n&&n.classList.toggle(i,e)};i(".dropdown-toggle",Qe),i(".dropdown-menu",Ye),s.setAttribute("aria-expanded",e)}_setAttributeIfNotExists(t,e,s){t.hasAttribute(e)||t.setAttribute(e,s)}_elemIsActive(t){return t.classList.contains(Qe)}_getInnerElement(t){return t.matches(Ge)?t:V.findOne(Ge,t)}_getOuterElement(t){return t.closest(".nav-item, .list-group-item")||t}static jQueryInterface(t){return this.each((function(){const e=Je.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}))}}F.on(document,"click.bs.tab",Ue,(function(t){["A","AREA"].includes(this.tagName)&&t.preventDefault(),d(this)||Je.getOrCreateInstance(this).show()})),F.on(window,"load.bs.tab",(()=>{for(const t of V.find('.active[data-bs-toggle="tab"], .active[data-bs-toggle="pill"], .active[data-bs-toggle="list"]'))Je.getOrCreateInstance(t)})),b(Je);const Ze="hide",ts="show",es="showing",ss={animation:"boolean",autohide:"boolean",delay:"number"},is={animation:!0,autohide:!0,delay:5e3};class ns extends W{constructor(t,e){super(t,e),this._timeout=null,this._hasMouseInteraction=!1,this._hasKeyboardInteraction=!1,this._setListeners()}static get Default(){return is}static get DefaultType(){return ss}static get NAME(){return"toast"}show(){F.trigger(this._element,"show.bs.toast").defaultPrevented||(this._clearTimeout(),this._config.animation&&this._element.classList.add("fade"),this._element.classList.remove(Ze),g(this._element),this._element.classList.add(ts,es),this._queueCallback((()=>{this._element.classList.remove(es),F.trigger(this._element,"shown.bs.toast"),this._maybeScheduleHide()}),this._element,this._config.animation))}hide(){this.isShown()&&(F.trigger(this._element,"hide.bs.toast").defaultPrevented||(this._element.classList.add(es),this._queueCallback((()=>{this._element.classList.add(Ze),this._element.classList.remove(es,ts),F.trigger(this._element,"hidden.bs.toast")}),this._element,this._config.animation)))}dispose(){this._clearTimeout(),this.isShown()&&this._element.classList.remove(ts),super.dispose()}isShown(){return this._element.classList.contains(ts)}_maybeScheduleHide(){this._config.autohide&&(this._hasMouseInteraction||this._hasKeyboardInteraction||(this._timeout=setTimeout((()=>{this.hide()}),this._config.delay)))}_onInteraction(t,e){switch(t.type){case"mouseover":case"mouseout":this._hasMouseInteraction=e;break;case"focusin":case"focusout":this._hasKeyboardInteraction=e}if(e)return void this._clearTimeout();const s=t.relatedTarget;this._element===s||this._element.contains(s)||this._maybeScheduleHide()}_setListeners(){F.on(this._element,"mouseover.bs.toast",(t=>this._onInteraction(t,!0))),F.on(this._element,"mouseout.bs.toast",(t=>this._onInteraction(t,!1))),F.on(this._element,"focusin.bs.toast",(t=>this._onInteraction(t,!0))),F.on(this._element,"focusout.bs.toast",(t=>this._onInteraction(t,!1)))}_clearTimeout(){clearTimeout(this._timeout),this._timeout=null}static jQueryInterface(t){return this.each((function(){const e=ns.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}return K(ns),b(ns),{Alert:Q,Button:Y,Carousel:ct,Collapse:mt,Dropdown:xt,Modal:ne,Offcanvas:_e,Popover:je,ScrollSpy:qe,Tab:Je,Toast:ns,Tooltip:Pe}})); 7 | //# sourceMappingURL=bootstrap.min.js.map -------------------------------------------------------------------------------- /js/main.js: -------------------------------------------------------------------------------- 1 | /* 2 | Subnetting-Bootstrap v1.0.0 (https://github.com/vittorioPiotti/Subnetting-Bootstrap/releases/tag/1.0.0) 3 | Copyright 2024 Vittorio Piotti 4 | Licensed under GPL-3.0 (https://github.com/vittorioPiotti/Subnetting-Bootstrap/blob/main/LICENSE.md) 5 | */ 6 | 7 | /* 8 | Bootstrap v4.0.0 (https://getbootstrap.com) 9 | Copyright 2011-2018 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) 10 | Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 11 | */ 12 | 13 | const modal = new bootstrap.Modal(document.getElementById("errore")); 14 | 15 | const RILEVA_IP = 0; 16 | const STESSA_RETE = 1; 17 | const FLSM = 2; 18 | const VLSM = 3; 19 | 20 | const IP = 0; 21 | const SM = 1; 22 | const GW = 2; 23 | const SH = 3; 24 | const EH = 4; 25 | const BR = 5; 26 | const ID = 6; 27 | 28 | class Address{ 29 | constructor(address) { 30 | this.addressIn = address; 31 | this.addressBin = new Array(); 32 | this.addressDec = new Array(); 33 | } 34 | checkAddress() { 35 | return (/^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\s){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/).test(this.addressIn); 36 | } 37 | setAddressBin(){ 38 | if(this.checkAddress() == true){ 39 | this.addressBin = this.addressIn.split(" ").map(ottetto => "00000000".slice(parseInt(ottetto).toString(2).length) + parseInt(ottetto).toString(2)); 40 | } 41 | } 42 | setAddressDec(){ 43 | if(this.checkAddress() == true)this.addressDec = this.addressIn.split(" ").map(Number); 44 | } 45 | getAddressBin(){ 46 | if(this.checkAddress() == true){ 47 | this.setAddressBin(); 48 | return this.addressBin; } 49 | } 50 | getAddressDec(){ 51 | if(this.checkAddress() == true){ 52 | this.setAddressDec(); 53 | return this.addressDec; 54 | } 55 | } 56 | getOttettoBin(i){ 57 | if(this.checkAddress() == true){ 58 | this.setAddressBin(); 59 | return this.addressBin[i]; 60 | } 61 | } 62 | getOttettoDec(i){ 63 | if(this.checkAddress() == true){ 64 | this.setAddressDec(); 65 | return this.addressDec[i]; 66 | } 67 | } 68 | setAddress(address){ 69 | this.addressIn = address; 70 | } 71 | 72 | getAddress(){ 73 | if(this.checkAddress() == true){ 74 | return this.addressIn; 75 | } 76 | } 77 | } 78 | class Ip extends Address{ 79 | constructor(ip){super(ip);} 80 | getTipo(){ 81 | if (parseInt(super.getOttettoDec(0)) == 10 //da 10.0.0.0 a 10.255.255.255 82 | || (parseInt(super.getOttettoDec(0)) == 172 && (parseInt(super.getOttettoDec(1)) >= 16 && parseInt(super.getOttettoDec(1)) <= 31))//da 172.16.0.0 a 172.31.255.255 83 | || (parseInt(super.getOttettoDec(0))) == 192 && parseInt(super.getOttettoDec(1)) == 168) return "privato";//tutti quelli dal primo ottetto pari a 192 o 168 84 | else return "pubblico"; 85 | 86 | } 87 | getClasse(){ 88 | if(super.checkAddress() == true){ 89 | const classi = ["A", "B", "C", "D", "E"]; 90 | //A: 1 - 127 = 128 indirizzi 91 | //B: 128 - 191 = 64 indirizzi 92 | //C: 192 - 223 = 32 indirizzi 93 | //D: 224 - 239 = 16 indirizzi 94 | //E: 240 - 255 = 16 indirizzi 95 | for(let i = 0; i < 4; i ++)if (super.getOttettoBin(0).charAt(i) == 0)return classi[i]; 96 | } 97 | } 98 | getBitClasse(){ 99 | //A: 8 bit 100 | //B: 16 bit 101 | //C: 24 bit 102 | 103 | if(super.checkAddress() == true)for(let i = 0; i < 3; i ++) if (super.getOttettoBin(0).charAt(i) == 0) return 8*(i+1); 104 | } 105 | } 106 | class Sm extends Address{ 107 | constructor(sm){super(sm);} 108 | checkSm(){ 109 | if (super.checkAddress() == false)return false; 110 | let k = -1 111 | if(this.getOttettoBin(0).charAt(0) == "0")return false 112 | for( let i = 0; i < 4; i++) 113 | for( let j = 0; j < 8; j++){ 114 | if(this.getOttettoBin(i).charAt(j) == "0" && k == -1)k = i; 115 | if(this.getOttettoBin(i).charAt(j) == "1" && k != -1)return false 116 | } 117 | return true; 118 | } 119 | } 120 | class SuperAddress extends Address{ 121 | constructor(ip,sm){ 122 | super(); 123 | this.ip = new Ip(ip); 124 | this.sm = new Sm(sm); 125 | } 126 | checkInput(){ 127 | if(this.ip.checkAddress() == true && this.sm.checkSm() == true)return true; 128 | else return false; 129 | } 130 | setAddress(address){ 131 | super.setAddress(address); 132 | } 133 | } 134 | class NetId extends SuperAddress{ 135 | constructor(ip,sm){ 136 | super(ip,sm); 137 | this.setAddress(); 138 | } 139 | setAddress(){ 140 | if(super.checkInput() == true){ 141 | let netId = ["","","",""]; 142 | for (let i = 0; i < 4; i++) for (let j = 0; j < 8; j++) netId[i] += (this.ip.getOttettoBin(i).charAt(j) & this.sm.getOttettoBin(i).charAt(j)); 143 | super.setAddress(netId.map(ottetto => parseInt(ottetto, 2)).join(" ")); 144 | } 145 | } 146 | } 147 | class IpSubnet extends Address{ 148 | constructor(ip,rete,maxReti){ 149 | super(); 150 | this.ip = new Ip(ip); 151 | this.rete = rete.toString(2); 152 | this.maxReti = maxReti; 153 | this.setAddress(); 154 | } 155 | setAddress(){ 156 | if(this.ip.checkAddress() == true){ 157 | let ipSubnet = "" 158 | ipSubnet = this.ip.getAddressBin().join("").substring(0, this.ip.getBitClasse()); 159 | ipSubnet += (this.rete .length < this.maxReti ? "0".repeat(this.maxReti - this.rete .length) + this.rete : this.rete ) + "0".repeat(32 - ipSubnet.length); 160 | super.setAddress(ipSubnet.replace(/(.{8})/g, "$1 ").trim().substring(0,35).split(" ").map(ottetto => parseInt(ottetto, 2)).join(" ")); 161 | } 162 | } 163 | } 164 | class SmSubnet extends Address{ 165 | constructor(bitSm){ 166 | super(); 167 | this.bitSm = bitSm; 168 | this.setAddress(); 169 | 170 | } 171 | setAddress(){ 172 | let sm = [0, 0, 0, 0]; 173 | let i = 0; 174 | while (this.bitSm > 0) { 175 | if (this.bitSm >= 8) { 176 | sm[i] = 255; 177 | this.bitSm -= 8; 178 | } else { 179 | sm[i] = (1 << this.bitSm) - 1 << (8 - this.bitSm); 180 | break; 181 | } 182 | i++; 183 | } 184 | super.setAddress(sm.join(" ")); 185 | } 186 | } 187 | class Broadcast extends SuperAddress{ 188 | constructor(ip,sm){ 189 | super(ip,sm); 190 | this.setAddress(); 191 | } 192 | setAddress(){ 193 | 194 | if(super.checkInput() == true){ 195 | let broadcast = ["","","",""]; 196 | for (let i = 0; i < 4; i++) { 197 | for (let j = 0; j < 8; j++) { 198 | if (this.sm.getOttettoBin(i).charAt(j) == 1) broadcast[i] += this.ip.getOttettoBin(i).charAt(j) 199 | else broadcast[i] += "1" 200 | } 201 | } 202 | for (let i = 0; i < 4; i++)while (broadcast[i].length < 8)broadcast[i] = "0" + broadcast[i] 203 | super.setAddress(broadcast.map(ottetto => parseInt(ottetto, 2)).join(" ")); 204 | } 205 | } 206 | } 207 | class Gateway extends SuperAddress{ 208 | constructor(ip,sm){ 209 | super(ip,sm); 210 | this.netId = new NetId(ip,sm) 211 | this.setAddress(); 212 | } 213 | setAddress(){ 214 | if(super.checkInput() == true){ 215 | let gateway = ["","","",""]; 216 | for (let i = 0; i < 4; i++)gateway[i] = this.netId.getOttettoBin(i); 217 | gateway[3] = gateway[3].substring(0, 7) + "1" 218 | super.setAddress(gateway.map(ottetto => parseInt(ottetto, 2)).join(" ")); 219 | } 220 | } 221 | } 222 | class StartHost extends SuperAddress{ 223 | constructor(ip,sm){ 224 | super(ip,sm); 225 | this.netId = new NetId(ip,sm) 226 | this.setAddress(); 227 | } 228 | setAddress(){ 229 | if(super.checkInput() == true){ 230 | let startHost = ["","","",""]; 231 | for (let i = 0; i < 4; i++)startHost[i] = this.netId.getOttettoBin(i); 232 | startHost[3] = startHost[3].substring(0, 6) + "10" 233 | super.setAddress(startHost.map(ottetto => parseInt(ottetto, 2)).join(" ")); 234 | } 235 | } 236 | } 237 | class EndHost extends SuperAddress{ 238 | constructor(ip,sm){ 239 | super(ip,sm); 240 | this.broadcast = new Broadcast(ip,sm) 241 | this.setAddress(); 242 | } 243 | setAddress(){ 244 | if(super.checkInput() == true){ 245 | let endHost = ["","","",""]; 246 | for (let i = 0; i < 4; i++)endHost[i] = this.broadcast.getOttettoBin(i); 247 | endHost[3] = endHost[3].substring(0, 7) + "0" 248 | super.setAddress(endHost.map(ottetto => parseInt(ottetto, 2)).join(" ")); 249 | } 250 | } 251 | } 252 | class StessaRete{ 253 | constructor(ip1,sm1,ip2,sm2){ 254 | this.netId = []; 255 | this.netId.push(new NetId(ip1,sm1)); 256 | this.netId.push(new NetId(ip2,sm2)); 257 | } 258 | 259 | checkInput(){ 260 | /* 261 | console.log(this.netId[0].sm.getAddressBin()) 262 | 263 | for(let i = 0; i < this.netId[0].sm.getAddressBin(); i ++){ 264 | this.netId[0].sm.getOttettoBin(i); 265 | if() 266 | } 267 | switch(this.netId[0].ip.getClasse()){ 268 | case 'A': 269 | break; 270 | case 'B': 271 | break; 272 | case 'C': 273 | break; 274 | default: 275 | return false; 276 | } 277 | */ 278 | if(this.netId[0].checkInput() == true && this.netId[1].checkInput() == true)return true; 279 | else return false; 280 | } 281 | 282 | getStessaRete(){ 283 | if(this.checkInput() == true){ 284 | if (this.netId[0].getAddress() == this.netId[1].getAddress() )return "stessa"; 285 | else return "diversa"; 286 | } 287 | } 288 | getAddress(i){ 289 | return this.netId[i].getAddress(); 290 | } 291 | 292 | 293 | } 294 | class MascheraFissa{ 295 | constructor(ip,numReti){ 296 | this.numReti = numReti; 297 | this.ip = new Ip(ip); 298 | this.reti = new Array(); 299 | } 300 | getMaxReti(){return Math.ceil(Math.log2(this.numReti));} 301 | getRetiPossibili(){ return Math.pow(2,this.getMaxReti()); } 302 | getRetiAvanzate(){return this.getRetiPossibili() - this.numReti;} 303 | checkSottoreti(){ 304 | //numero sottoreti - 3 (gateway,broadcast,netId) 305 | if(this.ip.checkAddress() == true){ 306 | const classi = ["A", "B", "C"]; 307 | if(this.numReti == 0)return false; 308 | for(let i = 0; i < 3; i++)if( this.ip.getClasse() == classi[i] && this.numReti >= Math.pow(2,24 - (8*i)) - 3)return false; 309 | return true; 310 | } 311 | } 312 | checkInput(){ 313 | if(this.ip.checkAddress() == true && this.checkSottoreti() == true)return true; 314 | else return false; 315 | } 316 | setSubnetting(){ 317 | if(this.checkInput() == true){ 318 | for(let i = 0; i < this.numReti; i ++){ 319 | this.reti[i] = new Array(); 320 | this.reti[i][IP] = new IpSubnet(this.ip.getAddress(),i,this.getMaxReti()); 321 | this.reti[i][SM] = new SmSubnet(this.ip.getBitClasse() + this.getMaxReti()); 322 | this.reti[i][ID] = new NetId(this.reti[i][IP].getAddress(),this.reti[i][SM].getAddress()); 323 | this.reti[i][GW] = new Gateway(this.reti[i][IP].getAddress(),this.reti[i][SM].getAddress()); 324 | this.reti[i][SH] = new StartHost(this.reti[i][IP].getAddress(),this.reti[i][SM].getAddress()); 325 | this.reti[i][EH] = new EndHost(this.reti[i][IP].getAddress(),this.reti[i][SM].getAddress()); 326 | this.reti[i][BR] = new Broadcast(this.reti[i][IP].getAddress(),this.reti[i][SM].getAddress()); 327 | } 328 | } 329 | } 330 | getAddress(i,tipo){ 331 | if(this.checkInput() == true){ 332 | return this.reti[i][tipo].getAddress(); 333 | } 334 | } 335 | } 336 | 337 | class MascheraVariabile{ 338 | getAddress(i,tipo){ 339 | 340 | return this.reti[i][tipo].getAddress(); 341 | 342 | } 343 | getBitSm(){ 344 | let sm = ""; 345 | switch(this.ip.getClasse()){ 346 | case "A": 347 | sm = 8 348 | break; 349 | case "B": 350 | sm = 16 351 | break; 352 | case "C": 353 | sm = 24 354 | break; 355 | } 356 | return sm; 357 | } 358 | getSm(){ 359 | let sm = ""; 360 | switch(this.ip.getClasse()){ 361 | case "A": 362 | sm = "255 0 0 0" 363 | break; 364 | case "B": 365 | sm = "255 255 0 0" 366 | break; 367 | case "C": 368 | sm = "255 255 255 0" 369 | break; 370 | } 371 | return sm; 372 | } 373 | initSm(){ 374 | let appSm = this.sm.getAddress().split(" "); 375 | for(let i = 0; i < appSm.length; i ++)appSm[i] = parseInt(appSm[i]).toString(2); 376 | 377 | 378 | 379 | } 380 | mascheraVariabile(){ 381 | for(let i = 0; i < this.numSubnet; i ++){ 382 | this.initIp(i); 383 | } 384 | } 385 | initIp(rete){ 386 | let appIp = this.ip.getAddress().split(" "); 387 | let app = "" 388 | for(let i = 0; i < appIp.length; i ++){ 389 | appIp[i] = parseInt(appIp[i]).toString(2); 390 | 391 | if(appIp[i].length < 8){ 392 | app = ""; 393 | for(let j = 0; j < 8 - appIp[i].length; j ++){ 394 | app += "0"; 395 | } 396 | appIp[i] = app + appIp[i]; 397 | } 398 | } 399 | 400 | 401 | let k = 0; 402 | app = 0; 403 | 404 | do{ 405 | app += this.maxHostSottorete[k]; 406 | k++; 407 | }while( k <= rete) 408 | app -= this.maxHostSottorete[rete]; 409 | 410 | console.log("APP = " + app); 411 | app = app.toString(2); 412 | console.log("APP = " + app); 413 | let c = 0; 414 | let i = this.bitSm / 8; 415 | 416 | while(c < app.length){ 417 | 418 | appIp[i] = app; 419 | if(appIp[i].length < 8){ 420 | app = ""; 421 | for(let j = 0; j < 8 - appIp[i].length; j ++){ 422 | app += "0"; 423 | } 424 | appIp[i] = app + appIp[i] ; 425 | } 426 | c += 8; 427 | 428 | } 429 | 430 | console.log("cazzo : " + appIp) 431 | let decimale = [] 432 | for (let i = 0; i < appIp.length; i++) { 433 | var binario = appIp[i]; 434 | var dec = parseInt(binario, 2); 435 | decimale.push(dec); 436 | } 437 | 438 | 439 | let appIpString = decimale.join(" "); 440 | console.log("cazzo : " + appIpString) 441 | this.reti[rete][IP] = new Ip(appIpString); 442 | 443 | 444 | 445 | let hostSubnetM = 32 - this.bitXhost[rete]; 446 | let appSm = this.generateSubnetMask(hostSubnetM) 447 | this.reti[rete][SM] = new Sm(appSm); 448 | this.reti[rete][ID] = new NetId(this.reti[rete][IP].getAddress(),this.reti[rete][SM].getAddress()); 449 | this.reti[rete][GW] = new Gateway(this.reti[rete][IP].getAddress(),this.reti[rete][SM].getAddress()); 450 | this.reti[rete][SH] = new StartHost(this.reti[rete][IP].getAddress(),this.reti[rete][SM].getAddress()); 451 | this.reti[rete][EH] = new EndHost(this.reti[rete][IP].getAddress(),this.reti[rete][SM].getAddress()); 452 | this.reti[rete][BR] = new Broadcast(this.reti[rete][IP].getAddress(),this.reti[rete][SM].getAddress()); 453 | 454 | 455 | 456 | 457 | } 458 | checkSottoreti(){ 459 | //numero sottoreti - 3 (gateway,broadcast,netId) 460 | if(this.ip.checkAddress() == true){ 461 | const classi = ["A", "B", "C"]; 462 | if(this.numSubnet == 0)return false; 463 | for(let i = 0; i < 3; i++)if( this.ip.getClasse() == classi[i] && this.numSubnet >= Math.pow(2,24 - (8*i)) - 3)return false; 464 | return true; 465 | } 466 | } 467 | checkHostSottoreti(){ 468 | 469 | for(let i = 0; i < this.hostXsubnet.length; i ++){ 470 | if (this.hostXsubnet[i] !== null) { 471 | if (Number.isInteger(parseInt(this.hostXsubnet[i]))) { 472 | if(parseInt(this.hostXsubnet[i]) >= Math.pow(2,parseInt(this.maxHostXsottorete)) - 3)return false; 473 | 474 | } else { 475 | return false; 476 | } 477 | } else { 478 | return false; 479 | } 480 | } 481 | return true; 482 | } 483 | checkInput(){ 484 | 485 | if(this.ip.checkAddress() == true && this.checkSottoreti() == true && this.checkHostSottoreti() == true)return true; 486 | else return false; 487 | } 488 | generateSubnetMask(bit) { 489 | let subnetMaskArray = []; 490 | 491 | let numBytes = Math.ceil(bit / 8); 492 | 493 | for (let i = 0; i < numBytes; i++) { 494 | if (bit >= 8) { 495 | subnetMaskArray.push(255); 496 | bit -= 8; 497 | } else { 498 | subnetMaskArray.push(256 - Math.pow(2, 8 - bit)); 499 | bit = 0; 500 | } 501 | } 502 | 503 | let subnetMaskString = subnetMaskArray.join(' '); 504 | 505 | return subnetMaskString; 506 | } 507 | 508 | 509 | 510 | getBitXhost(numHost) { 511 | let bit = 0; 512 | while (Math.pow(2, bit) - 2 < numHost) { 513 | bit++; 514 | } 515 | 516 | return bit; 517 | } 518 | constructor(ip,numSubnet,hostXsubnet){ 519 | 520 | this.ip = new Ip(ip); 521 | this.sm = new Sm(this.getSm()); 522 | this.bitSm = this.getBitSm(); 523 | this.reti = new Array(); 524 | this.numSubnet = numSubnet; 525 | this.hostXsubnet = hostXsubnet.sort(function(a, b) { 526 | return b - a; 527 | }); 528 | 529 | this.bitXhost = []; 530 | this.totBitSottoreti = 0; 531 | this.bitXsubnet = []; 532 | this.maxHostSottorete = []; 533 | 534 | for(let i = 0; i < this.hostXsubnet.length; i ++ ){ 535 | this.bitXhost[i] = this.getBitXhost(this.hostXsubnet[i]) 536 | this.totBitSottoreti += this.bitXhost[i]; 537 | this.bitXsubnet[i] = this.getBitSm() + this.bitXhost[i]; 538 | this.maxHostSottorete[i] = Math.pow(2, this.bitXhost[i]); 539 | } 540 | 541 | 542 | this.bitRete = 32 - this.totBitSottoreti ; 543 | this.numBitSubnet = parseInt(numSubnet - 1).toString(2).length; 544 | this.maxHostXsottorete = 32 - this.bitSm - this.numBitSubnet; 545 | console.log(this.maxHostXsottorete) 546 | this.maxSubnet = Math.pow(this.numSubnet, 2); 547 | let app = [] 548 | let appDecimale = []; 549 | for (let i = 0; i < app.length; i++) { 550 | let decimale = parseInt(app[i], 2).toString(10); 551 | appDecimale.push(decimale); 552 | } 553 | 554 | 555 | 556 | 557 | 558 | 559 | for(let i = 0; i < this.numSubnet; i ++)this.reti[i] = new Array(); 560 | 561 | 562 | 563 | 564 | } 565 | 566 | } 567 | 568 | 569 | 570 | class Esercizio{ 571 | constructor (nome,input,short){ 572 | this.nome = nome; 573 | this.input = input.split(";"); 574 | this.short = short; 575 | } 576 | getNome(){return this.nome;} 577 | getShort(){return this.short;} 578 | getInput(i){return this.input[i];} 579 | getNumeroInput(){return this.input.length;} 580 | } 581 | 582 | 583 | const esercizi = []; 584 | const select = document.getElementById("choice"); 585 | var selected = 0; 586 | 587 | 588 | esercizi.push(new Esercizio("Scopri tipo e classe di un IP","Indirizzo IP:","Analisi IP")); 589 | esercizi.push(new Esercizio("Scopri se stessa rete tra IP","Indirizzo IP.1:;Subnetmask SM.1:;Indirizzo IP.2:;Subnetmask SM.2:","Stessa rete")); 590 | esercizi.push(new Esercizio("Subnetting a maschera fissa","Indirizzo IP:;Numero sottoreti:","FLSM")); 591 | esercizi.push(new Esercizio("Subnetting a maschera variabile","Indirizzo IP:;Numero sottoreti:","VLSM")); 592 | 593 | function init(){ 594 | initChoice(); 595 | initInput(); 596 | } 597 | 598 | function initChoice(){ 599 | let choice = ""; 600 | let selected = "selected"; 601 | for(let i = 0; i < esercizi.length; i ++){ 602 | choice += ""; 603 | selected = " "; 604 | } 605 | document.getElementById("choice").innerHTML = choice; 606 | } 607 | 608 | function initInput(){ 609 | let input = ""; 610 | let placeholder = "255 255 255 255"; 611 | refresh(); 612 | for(let i = 0; i < esercizi[selected].getNumeroInput(); i ++){ 613 | input += "
"; 614 | input += ""; 615 | if(esercizi[selected].getInput(i) == "Numero sottoreti:")placeholder = "69"; 616 | input += ""; 617 | if(selected == VLSM && esercizi[selected].getInput(i) == "Numero sottoreti:")input += "
A campo riempito comparsa menu degli host per sottorete
"; 618 | input += "
"; 619 | } 620 | input += "
"; 621 | document.getElementById("input").innerHTML = input; 622 | if(selected == VLSM)initExtraInput(); 623 | } 624 | 625 | function initExtraInput(){ 626 | const inputElements = document.getElementsByClassName("form-control"); 627 | const lastInputElement = inputElements[1]; 628 | let input = 0; 629 | let displayOn = "d-block"; 630 | let displayOff = "d-none"; 631 | lastInputElement.addEventListener("input", function() { 632 | if (lastInputElement.value && check() == true) { 633 | input = ""; 634 | if(lastInputElement.value > 2){ 635 | input += "
"; 636 | input += "

scorrere

"; 637 | input += ""; 638 | input += ""; 639 | input += ""; 640 | input += "
"; 641 | } 642 | for(let i = 0; i < lastInputElement.value; i ++){ 643 | input += "
" 644 | input += ""; 645 | input += ""; 646 | input += "
"; 647 | } 648 | displayOn = "d-block"; 649 | displayOff = "d-none"; 650 | } 651 | else{ 652 | input = ""; 653 | displayOn = "d-none"; 654 | displayOff = "d-block"; 655 | } 656 | document.getElementById("extraInput").innerHTML = input; 657 | document.getElementById("extraInput").classList.add(displayOn); 658 | document.getElementById("sottoretiHelp").classList.add(displayOff); 659 | document.getElementById("sottoretiHelp").classList.remove(displayOn); 660 | document.getElementById("extraInput").classList.remove(displayOff); 661 | }); 662 | } 663 | function check(){ 664 | return true; 665 | } 666 | 667 | function refresh(){selected = select.options[select.selectedIndex].value;} 668 | 669 | 670 | function load(){ 671 | let input = document.getElementsByTagName("input"); 672 | let inputForm = document.getElementById("inputForm"); 673 | let outputForm = document.getElementById("outputForm"); 674 | let check = true; 675 | let output = ""; 676 | inputForm.className = "col-lg-5 col-12 mb-3"; 677 | outputForm.className = "col-lg-7 col-12 mb-3"; 678 | switch(parseInt(selected)){ 679 | case RILEVA_IP: 680 | let rilveIp = new Ip(input[0].value); 681 | check = rilveIp.checkAddress(); 682 | if(check == true){ 683 | output += "" 684 | output += "" 685 | output += "" 686 | output += "" 687 | output += "" 688 | output += "" 689 | output += "" 690 | output += "" 691 | output += "" 692 | output += "" 693 | output += "" 694 | output += "" 695 | output += "" 696 | output += "" 697 | output += "" 698 | output += "
IPClasseTipo
"+ rilveIp.getAddress() +"" + rilveIp.getClasse() +""+ rilveIp.getTipo()+"
" 699 | } 700 | break; 701 | case STESSA_RETE: 702 | let stessaRete = new StessaRete(input[0].value,input[1].value,input[2].value,input[3].value); 703 | check = stessaRete.checkInput(); 704 | if(check == true){ 705 | output = "
" 706 | output += "" 707 | output += "" 708 | output += "" 709 | output += "" 710 | output += "" 711 | output += "" 712 | output += "" 713 | output += "" 714 | output += "" 715 | output += "" 716 | output += "" 717 | output += "" 718 | output += "" 719 | output += "" 720 | output += "" 721 | output += "" 722 | output += "" 723 | output += "" 724 | output += "" 725 | output += "" 726 | output += "" 727 | output += "" 728 | output += "
IPSubnetmaskNet IdRete
"+ input[0].value +"" + input[1].value +""+ stessaRete.getAddress(0) +""+ stessaRete.getStessaRete()+"
"+ input[2].value +"" + input[3].value +""+ stessaRete.getAddress(1) +"
" 729 | output += "
" 730 | } 731 | break; 732 | case FLSM: 733 | 734 | let mascheraFissa = new MascheraFissa(input[0].value,input[1].value); 735 | check = mascheraFissa.checkInput(); 736 | if(check == true){ 737 | inputForm.className = " col-12 mb-3"; 738 | outputForm.className = "col-12 mb-3"; 739 | mascheraFissa.setSubnetting(); 740 | output = "
" 741 | output += "" 742 | output += "" 743 | output += "" 744 | output += "" 745 | output += "" 746 | output += "" 747 | output += "" 748 | output += "" 749 | output += "" 750 | output += "" 751 | output += "" 752 | output += "" 753 | output += "" 754 | output += "" 755 | for(let i= 0; i < input[1].value; i ++){ 756 | output += "" 757 | output += "" 758 | output += "" 759 | output += "" 760 | output += "" 761 | output += "" 762 | output += "" 763 | output += "" 764 | output += "" 765 | output += "" 766 | } 767 | 768 | output += "" 769 | output += "
#IPNet IdGatewayPrimo hostUltimo hostBroadcastSubnetmask
" + (i + 1)+"" + mascheraFissa.getAddress(i,IP)+"" + mascheraFissa.getAddress(i,ID)+"" + mascheraFissa.getAddress(i,GW)+"" + mascheraFissa.getAddress(i,SH)+"" + mascheraFissa.getAddress(i,EH)+"" + mascheraFissa.getAddress(i,BR)+"" + mascheraFissa.getAddress(i,SM)+"
" 770 | output += "
" 771 | } 772 | break; 773 | case VLSM: 774 | inputForm.className = " col-12 mb-3"; 775 | outputForm.className = "col-12 mb-3"; 776 | let ip = input[0].value; 777 | let numeroSottoreti = input[1].value; 778 | let hostXsottorete = []; 779 | for(let i = 0 ; i < numeroSottoreti; i ++){ 780 | hostXsottorete.push(input[i + 2].value) 781 | } 782 | let mascheraVariabile = new MascheraVariabile(ip,numeroSottoreti,hostXsottorete); 783 | check = mascheraVariabile.checkInput(); 784 | if(check == true){ 785 | mascheraVariabile.mascheraVariabile(); 786 | 787 | output = "
" 788 | output += "" 789 | output += "" 790 | output += "" 791 | output += "" 792 | output += "" 793 | output += "" 794 | output += "" 795 | output += "" 796 | output += "" 797 | output += "" 798 | output += "" 799 | output += "" 800 | output += "" 801 | output += "" 802 | for(let i= 0; i < input[1].value; i ++){ 803 | output += "" 804 | output += "" 805 | output += "" 806 | output += "" 807 | output += "" 808 | output += "" 809 | output += "" 810 | output += "" 811 | output += "" 812 | output += "" 813 | } 814 | 815 | output += "" 816 | output += "
#IPNet IdGatewayPrimo hostUltimo hostBroadcastSubnetmask
" + (i + 1)+"" + mascheraVariabile.getAddress(i,IP)+"" + mascheraVariabile.getAddress(i,ID)+"" + mascheraVariabile.getAddress(i,GW)+"" + mascheraVariabile.getAddress(i,SH)+"" + mascheraVariabile.getAddress(i,EH)+"" + mascheraVariabile.getAddress(i,BR)+"" + mascheraVariabile.getAddress(i,SM)+"
" 817 | output += "
" 818 | break; 819 | } 820 | 821 | } 822 | if(check == true){ 823 | document.getElementById("output").innerHTML = output; 824 | document.getElementById("select").innerHTML = "" + esercizi[parseInt(selected)].getShort()+"" 825 | 826 | } 827 | else modal.show(); 828 | 829 | } 830 | 831 | 832 | 833 | 834 | -------------------------------------------------------------------------------- /screenshots/flsm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vittorioPiotti/SubnettingSolver-Bootstrap/6b58d6b26c6106d1c70d4db079964d4022b51290/screenshots/flsm.png -------------------------------------------------------------------------------- /screenshots/ip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vittorioPiotti/SubnettingSolver-Bootstrap/6b58d6b26c6106d1c70d4db079964d4022b51290/screenshots/ip.png -------------------------------------------------------------------------------- /screenshots/netid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vittorioPiotti/SubnettingSolver-Bootstrap/6b58d6b26c6106d1c70d4db079964d4022b51290/screenshots/netid.png -------------------------------------------------------------------------------- /screenshots/vlsm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vittorioPiotti/SubnettingSolver-Bootstrap/6b58d6b26c6106d1c70d4db079964d4022b51290/screenshots/vlsm.png --------------------------------------------------------------------------------