kandi background
Explore Kits

mina | Blazing fast application deployment tool | Continuous Deployment library

 by   mina-deploy Ruby Version: Current License: Non-SPDX

 by   mina-deploy Ruby Version: Current License: Non-SPDX

Download this library from

kandi X-RAY | mina Summary

mina is a Ruby library typically used in Devops, Continuous Deployment applications. mina has no bugs, it has no vulnerabilities and it has medium support. However mina has a Non-SPDX License. You can download it from GitHub, GitLab.
Blazing fast application deployment tool.
Support
Support
Quality
Quality
Security
Security
License
License
Reuse
Reuse

kandi-support Support

  • mina has a medium active ecosystem.
  • It has 4202 star(s) with 461 fork(s). There are 91 watchers for this library.
  • It had no major release in the last 12 months.
  • There are 25 open issues and 414 have been closed. On average issues are closed in 903 days. There are 2 open pull requests and 0 closed requests.
  • It has a neutral sentiment in the developer community.
  • The latest version of mina is current.
mina Support
Best in #Continuous Deployment
Average in #Continuous Deployment
mina Support
Best in #Continuous Deployment
Average in #Continuous Deployment

quality kandi Quality

  • mina has 0 bugs and 0 code smells.
mina Quality
Best in #Continuous Deployment
Average in #Continuous Deployment
mina Quality
Best in #Continuous Deployment
Average in #Continuous Deployment

securitySecurity

  • mina has no vulnerabilities reported, and its dependent libraries have no vulnerabilities reported.
  • mina code analysis shows 0 unresolved vulnerabilities.
  • There are 0 security hotspots that need review.
mina Security
Best in #Continuous Deployment
Average in #Continuous Deployment
mina Security
Best in #Continuous Deployment
Average in #Continuous Deployment

license License

  • mina has a Non-SPDX License.
  • Non-SPDX licenses can be open source with a non SPDX compliant license, or non open source licenses, and you need to review them closely before use.
mina License
Best in #Continuous Deployment
Average in #Continuous Deployment
mina License
Best in #Continuous Deployment
Average in #Continuous Deployment

buildReuse

  • mina releases are not available. You will need to build from source code and install.
  • It has 2352 lines of code, 77 functions and 58 files.
  • It has medium code complexity. Code complexity directly impacts maintainability of the code.
mina Reuse
Best in #Continuous Deployment
Average in #Continuous Deployment
mina Reuse
Best in #Continuous Deployment
Average in #Continuous Deployment
Top functions reviewed by kandi - BETA

kandi has reviewed mina and discovered the below as its top functions. This is intended to give you an instant insight into mina implemented functionality, and help decide if they suit your requirements.

  • Sort the minimum options for the current jar .
    • Initialize a new file .
      • Executes a command within the given path .
        • Adds a comment to the stack .
          • Install a script .
            • Raise an error if the given key is not set
              • Returns the top level tasks for the project level
                • Sets the current stage .
                  • Add a script to the output .
                    • Reserves a task .

                      Get all kandi verified functions for this library.

                      Get all kandi verified functions for this library.

                      mina Key Features

                      Blazing fast application deployment tool.

                      Excel: Min and max of text and blanks

                      copy iconCopydownload iconDownload
                      {=INDEX(A1:H1,MATCH(0,COUNTIF(A1:H1,">"&A1:H1&" "),0))}
                      
                      {=INDEX(A1:H1,MATCH(0,COUNTIF(A1:H1,">"&A1:H1&"*"),0))}
                      
                      {=INDEX(A1:H1,MATCH(0,COUNTIF(A1:H1,">"&A1:H1&" "),0))}
                      
                      {=INDEX(A1:H1,MATCH(0,COUNTIF(A1:H1,">"&A1:H1&"*"),0))}
                      

                      Apache Mina Integration With Aries blueprint have problem

                      copy iconCopydownload iconDownload
                      <bean id="filter" class="java.util.LinkedHashMap">
                          <argument>
                              <map>
                                  <entry key="codecFilter" value-ref="dfCodec"/>
                              </map>
                          </argument>
                      
                      </bean>
                      
                      <bean id="filters"
                            class="org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder">
                          <property name="filters" ref="filter"/>
                      </bean>
                      

                      XMPP wrong sender address (broadcast serverside)

                      copy iconCopydownload iconDownload
                      StanzaBuilder responseBuilder = StanzaBuilder.createDirectReply(stanza, true, "error");
                      
                      public static StanzaBuilder createDirectReply(XMPPCoreStanza original, boolean fromIsServerOnly, String type)
                      
                      if (fromIsServerOnly)
                         newFrom = new EntityImpl(null, newFrom.getDomain(), null);
                      stanzaBuilder.addAttribute("from", newFrom.getFullQualifiedName());
                      
                      StanzaBuilder responseBuilder = StanzaBuilder.createDirectReply(stanza, true, "error");
                      
                      public static StanzaBuilder createDirectReply(XMPPCoreStanza original, boolean fromIsServerOnly, String type)
                      
                      if (fromIsServerOnly)
                         newFrom = new EntityImpl(null, newFrom.getDomain(), null);
                      stanzaBuilder.addAttribute("from", newFrom.getFullQualifiedName());
                      
                      StanzaBuilder responseBuilder = StanzaBuilder.createDirectReply(stanza, true, "error");
                      
                      public static StanzaBuilder createDirectReply(XMPPCoreStanza original, boolean fromIsServerOnly, String type)
                      
                      if (fromIsServerOnly)
                         newFrom = new EntityImpl(null, newFrom.getDomain(), null);
                      stanzaBuilder.addAttribute("from", newFrom.getFullQualifiedName());
                      
                              // make sure that 'from' (if present) matches the bare authorized entity
                              // else respond with a stanza error 'unknown-sender'
                              // see rfc3920_draft-saintandre-rfc3920bis-04.txt#8.5.4
                              if (from != null && sessionContext.getInitiatingEntity() != null) {
                                  Entity fromBare = from.getBareJID();
                                  Entity initiatingEntity = sessionContext.getInitiatingEntity();
                                  if (!initiatingEntity.equals(fromBare)) {
                                      responseWriter.handleWrongFromJID(sessionContext, stanza);
                                      return;
                                  }
                              }
                      
                      private void sendAllSessions(final StringBuilder message, final Entity sender,
                              final ServerRuntimeContext serverContext, final EMailAddress recipientAddress) {
                          EntityImpl recipient = new EntityImpl(recipientAddress.getLocalName().getLocalName(),
                                  recipientAddress.getDomain().getDomainName(), null);
                          Stanza build = createStanza(message, sender, recipient);
                          for (SessionContext sessionContext : serverContext.getResourceRegistry().getSessions(recipient)) {
                              SessionState state = sessionContext.getState();
                              SessionStateHolder stateHolder = new SessionStateHolder();
                              stateHolder.setState(state);
                              Stanza stanza = new MessageStanza(build);
                              LOG.severe("Send xmpp stanza: " + stanza + " from " + stanza.getFrom());
                              sessionContext.setInitiatingEntity(sender); // THIS LINE IS ADDED
                              serverContext.getStanzaProcessor().processStanza(serverContext, sessionContext, stanza, stateHolder);
                          }
                      }
                      
                      <message type="headline" from="xxx" to="xxx" xml:lang="html">
                      <body>Test</body>
                      </message>
                      
                              // make sure that 'from' (if present) matches the bare authorized entity
                              // else respond with a stanza error 'unknown-sender'
                              // see rfc3920_draft-saintandre-rfc3920bis-04.txt#8.5.4
                              if (from != null && sessionContext.getInitiatingEntity() != null) {
                                  Entity fromBare = from.getBareJID();
                                  Entity initiatingEntity = sessionContext.getInitiatingEntity();
                                  if (!initiatingEntity.equals(fromBare)) {
                                      responseWriter.handleWrongFromJID(sessionContext, stanza);
                                      return;
                                  }
                              }
                      
                      private void sendAllSessions(final StringBuilder message, final Entity sender,
                              final ServerRuntimeContext serverContext, final EMailAddress recipientAddress) {
                          EntityImpl recipient = new EntityImpl(recipientAddress.getLocalName().getLocalName(),
                                  recipientAddress.getDomain().getDomainName(), null);
                          Stanza build = createStanza(message, sender, recipient);
                          for (SessionContext sessionContext : serverContext.getResourceRegistry().getSessions(recipient)) {
                              SessionState state = sessionContext.getState();
                              SessionStateHolder stateHolder = new SessionStateHolder();
                              stateHolder.setState(state);
                              Stanza stanza = new MessageStanza(build);
                              LOG.severe("Send xmpp stanza: " + stanza + " from " + stanza.getFrom());
                              sessionContext.setInitiatingEntity(sender); // THIS LINE IS ADDED
                              serverContext.getStanzaProcessor().processStanza(serverContext, sessionContext, stanza, stateHolder);
                          }
                      }
                      
                      <message type="headline" from="xxx" to="xxx" xml:lang="html">
                      <body>Test</body>
                      </message>
                      
                              // make sure that 'from' (if present) matches the bare authorized entity
                              // else respond with a stanza error 'unknown-sender'
                              // see rfc3920_draft-saintandre-rfc3920bis-04.txt#8.5.4
                              if (from != null && sessionContext.getInitiatingEntity() != null) {
                                  Entity fromBare = from.getBareJID();
                                  Entity initiatingEntity = sessionContext.getInitiatingEntity();
                                  if (!initiatingEntity.equals(fromBare)) {
                                      responseWriter.handleWrongFromJID(sessionContext, stanza);
                                      return;
                                  }
                              }
                      
                      private void sendAllSessions(final StringBuilder message, final Entity sender,
                              final ServerRuntimeContext serverContext, final EMailAddress recipientAddress) {
                          EntityImpl recipient = new EntityImpl(recipientAddress.getLocalName().getLocalName(),
                                  recipientAddress.getDomain().getDomainName(), null);
                          Stanza build = createStanza(message, sender, recipient);
                          for (SessionContext sessionContext : serverContext.getResourceRegistry().getSessions(recipient)) {
                              SessionState state = sessionContext.getState();
                              SessionStateHolder stateHolder = new SessionStateHolder();
                              stateHolder.setState(state);
                              Stanza stanza = new MessageStanza(build);
                              LOG.severe("Send xmpp stanza: " + stanza + " from " + stanza.getFrom());
                              sessionContext.setInitiatingEntity(sender); // THIS LINE IS ADDED
                              serverContext.getStanzaProcessor().processStanza(serverContext, sessionContext, stanza, stateHolder);
                          }
                      }
                      
                      <message type="headline" from="xxx" to="xxx" xml:lang="html">
                      <body>Test</body>
                      </message>
                      

                      React testing library not work with react router v6

                      copy iconCopydownload iconDownload
                      describe('testing Mine Page', () => {
                        test('check table components', () => {
                          render(
                            <MemoryRouter>
                              <MineTable />
                            </MemoryRouter>,
                          );
                          const pageTitle = screen.getByRole('heading', { name: /mina/i });
                          expect(pageTitle).toBeInTheDocument();
                        });
                      });
                      
                      const RouterWrapper = ({ children }) => (
                        <MemoryRouter>
                          {children}
                        </MemoryRouter>
                      );
                      
                      import { RouterWrapper } from '../path/to/RouterWrapper";
                      
                      describe('testing Mine Page', () => {
                        test('check table components', () => {
                          render(<MineTable />, { wrapper: RouterWrapper });
                          const pageTitle = screen.getByRole('heading', { name: /mina/i });
                          expect(pageTitle).toBeInTheDocument();
                        });
                      });
                      
                      describe('testing Mine Page', () => {
                        test('check table components', () => {
                          render(
                            <MemoryRouter>
                              <MineTable />
                            </MemoryRouter>,
                          );
                          const pageTitle = screen.getByRole('heading', { name: /mina/i });
                          expect(pageTitle).toBeInTheDocument();
                        });
                      });
                      
                      const RouterWrapper = ({ children }) => (
                        <MemoryRouter>
                          {children}
                        </MemoryRouter>
                      );
                      
                      import { RouterWrapper } from '../path/to/RouterWrapper";
                      
                      describe('testing Mine Page', () => {
                        test('check table components', () => {
                          render(<MineTable />, { wrapper: RouterWrapper });
                          const pageTitle = screen.getByRole('heading', { name: /mina/i });
                          expect(pageTitle).toBeInTheDocument();
                        });
                      });
                      
                      describe('testing Mine Page', () => {
                        test('check table components', () => {
                          render(
                            <MemoryRouter>
                              <MineTable />
                            </MemoryRouter>,
                          );
                          const pageTitle = screen.getByRole('heading', { name: /mina/i });
                          expect(pageTitle).toBeInTheDocument();
                        });
                      });
                      
                      const RouterWrapper = ({ children }) => (
                        <MemoryRouter>
                          {children}
                        </MemoryRouter>
                      );
                      
                      import { RouterWrapper } from '../path/to/RouterWrapper";
                      
                      describe('testing Mine Page', () => {
                        test('check table components', () => {
                          render(<MineTable />, { wrapper: RouterWrapper });
                          const pageTitle = screen.getByRole('heading', { name: /mina/i });
                          expect(pageTitle).toBeInTheDocument();
                        });
                      });
                      

                      filter out many rows where NaN another column in pandas

                      copy iconCopydownload iconDownload
                      df = df[df.groupby('person')['grade'].transform('count') > 0]
                      print(df)
                      
                      # Output
                        person  subject  grade
                      0  Cindy     Math   95.0
                      1  Cindy  English   88.0
                      2  Cindy  Science   93.0
                      3   Mina     Math   78.0
                      4   Mina  English   89.0
                      5   Mina  Science    NaN
                      
                      df1.groupby(['person'])['grade'].apply(lambda x: x.isnull().sum())<3
                      
                      import pandas as pd
                      import numpy as np
                      
                      df = pd.DataFrame({
                          "person":["Cindy","Cindy","Cindy","Mina","Mina","Mina","Brian","Brian","Brian"],
                          "subject":["Math","English","Science","Math","English","Scinece","Math","English","Science"],
                          "grade":[95,88,93,78,89, np.nan,np.nan,np.nan,np.nan ]
                      })
                      
                      sub =  df[(df["person"] == "Brian") & (df["grade"].isnull())]
                      df.drop(sub.index)
                      
                        person  subject  grade
                      0  Cindy     Math   95.0
                      1  Cindy  English   88.0
                      2  Cindy  Science   93.0
                      3   Mina     Math   78.0
                      4   Mina  English   89.0
                      5   Mina  Scinece    NaN
                      

                      How to perform a MIN value Grouped By Date Measure in PowerBI?

                      copy iconCopydownload iconDownload
                      MinPERCbyMonthYear :=
                      VAR MyTable =
                          SUMMARIZE ( Table1, Table1[MonthYear], "PERCbyMonthYear", [PERC] )
                      RETURN
                          MINX ( MyTable, [PERCbyMonthYear] )
                      

                      During the migration of a project using spring DM to Aries Blueprint, there is a problem that the bean property value cannot be properly converted

                      copy iconCopydownload iconDownload
                      <bean id="ioAcceptor" class="org.apache.mina.transport.socket.nio.NioSocketAcceptor">
                          <property name="defaultLocalAddress" value=":8000">
                            <bean class="java.net.InetSocketAddress">
                              <argument value="8000"/>
                            </bean>
                          <property name="handler" ref="minaHandler"/>
                          <property name="reuseAddress" value="true"/>
                          <property name="filterChainBuilder" ref="filters"/>
                      </bean>
                      

                      Im not being able to load preloader when i refresh the webpage

                      copy iconCopydownload iconDownload
                      <html>
                          <head>
                              <title>Expense Tracker</title>
                              
                          </head>
                          <body>
                          <iframe id="loader" src="loader.html" style="width:100%; height:100%; border:0px" ></iframe>
                      
                              <div id="mainContent" style="display:none"> Main Content goes here. </div>
                      
                              <script>
                                  setTimeout(function(){
                                     document.getElementById('loader').style.display='none';
                                 document.getElementById('mainContent').style.display='block';
                                  }, 3000);
                              </script>
                      </body>
                      
                      </html>

                      How to create a counter using recursion to get the total employees(direct or indirect) under a manager_id in javascript?

                      copy iconCopydownload iconDownload
                      const employees = [ 
                          [ 'Tom', 179, 180 ],
                          [ 'Liz', 150, 179 ],
                          [ 'Ricki', 120, 179 ],
                          [ 'Sona', 113, 150 ],
                          [ 'Preet', 558, 150 ],
                          [ 'Mina', 89, 558 ],
                          [ 'Yukti', 45, 120 ]
                      ];
                          
                      // Simulate what papa parse returns...
                      function parseCSV() {
                          return Promise.resolve(employees); 
                      }
                      
                      function displayRow(...row) {
                          console.log(...row.map(f => (f + '').padEnd(15)))
                      }
                      
                      async function testCounts() {
                          console.log('Direct and total counts for each worker:\n');
                      
                          let rows = await parseCSV();
                          displayRow('Name', 'Id', 'Direct', 'Total')
                          for(let [name, workerId, managerId] of rows) {
                              let directEmployees = CountDirectEmployees(workerId, rows);
                              let totalEmployees = CountEmployee(workerId, rows);
                              displayRow(name, workerId, directEmployees, totalEmployees)
                          }
                      }
                      
                      function getDirectEmployees(id, rows) {
                          return rows.filter(([name, workerId, managerId]) => managerId === id);
                      }
                      
                      function CountDirectEmployees(managerId, rows) {
                          return getDirectEmployees(managerId, rows).length;
                      }
                       
                      function CountEmployee(managerId, rows) {
                          // Count direct employees, then count employees of each of these
                          let directEmployees = getDirectEmployees(managerId, rows);
                          let count = directEmployees.length;
                          for(let [name, workerId] of directEmployees) {
                              count += CountEmployee(workerId, rows);
                          }
                          return count;
                      }
                       
                      testCounts()
                       
                      .as-console-wrapper { max-height: 100% !important; top: 0; }
                      const employees = [ 
                          [ 'Tom', 179, 180 ],
                          [ 'Liz', 150, 179 ],
                          [ 'Ricki', 120, 179 ],
                          [ 'Sona', 113, 150 ],
                          [ 'Preet', 558, 150 ],
                          [ 'Mina', 89, 558 ],
                          [ 'Yukti', 45, 120 ]
                      ];
                          
                      // Simulate what papa parse returns...
                      function parseCSV() {
                          return Promise.resolve(employees); 
                      }
                      
                      function displayRow(...row) {
                          console.log(...row.map(f => (f + '').padEnd(15)))
                      }
                      
                      async function testCounts() {
                          console.log('Direct and total counts for each worker:\n');
                      
                          let rows = await parseCSV();
                          displayRow('Name', 'Id', 'Direct', 'Total')
                          for(let [name, workerId, managerId] of rows) {
                              let directEmployees = CountDirectEmployees(workerId, rows);
                              let totalEmployees = CountEmployee(workerId, rows);
                              displayRow(name, workerId, directEmployees, totalEmployees)
                          }
                      }
                      
                      function getDirectEmployees(id, rows) {
                          return rows.filter(([name, workerId, managerId]) => managerId === id);
                      }
                      
                      function CountDirectEmployees(managerId, rows) {
                          return getDirectEmployees(managerId, rows).length;
                      }
                       
                      function CountEmployee(managerId, rows) {
                          // Count direct employees, then count employees of each of these
                          let directEmployees = getDirectEmployees(managerId, rows);
                          let count = directEmployees.length;
                          for(let [name, workerId] of directEmployees) {
                              count += CountEmployee(workerId, rows);
                          }
                          return count;
                      }
                       
                      testCounts()
                       
                      .as-console-wrapper { max-height: 100% !important; top: 0; }

                      Problem of connection apache directory studio

                      copy iconCopydownload iconDownload
                      -vm
                      E:\Repositories\Jdk11.0.12\bin\javaw.exe
                      

                      Community Discussions

                      Trending Discussions on mina
                      • Excel: Min and max of text and blanks
                      • Apache Mina Integration With Aries blueprint have problem
                      • XMPP wrong sender address (broadcast serverside)
                      • React testing library not work with react router v6
                      • filter out many rows where NaN another column in pandas
                      • Apache MINA sshd | When I added the dependency and import it in the class I get &quot;the type org.apache.sshd.client.SshClient is not accessible&quot; error
                      • How to perform a MIN value Grouped By Date Measure in PowerBI?
                      • During the migration of a project using spring DM to Aries Blueprint, there is a problem that the bean property value cannot be properly converted
                      • Can't run more than 2 paths with runpy
                      • Im not being able to load preloader when i refresh the webpage
                      Trending Discussions on mina

                      QUESTION

                      Excel: Min and max of text and blanks

                      Asked 2022-Mar-24 at 13:12

                      The Excel 2019 functions min(), max(), MinA(), and MaxA() don't work on non-numeric arguments. A StackOverflow answer gave a formula for performing the max and min operations on text values:

                      {=index(A2:A6, match(0, CountIf(A2:A6, ">" & A2:A6), 0))}
                      

                      for max, with min being the same with ">" changed to "<", and where {...} means an array formula entered with Ctrl-Shft-Enter.

                      This works well, but I've found a strange behavior in it. If the given range includes blank cells (i.e., empty, i.e., containing nothing) at the end of the range or inside the range, it works fine, but if it includes blanks at the beginning of the range, the formula returns 0:

                      Excel min max on text with blanks

                      To complicate matters further, if the blank cells are replaced with empty strings, ="", then the above behavior is the same, except that the one with the empty string at the beginning becomes empty instead of 0.

                      What is going on here? Why does this formula work with blanks or empty strings at the end or inside the range, but not at the beginning?

                      ANSWER

                      Answered 2022-Mar-24 at 13:12

                      This is a disadvantage of COUNTIF. While =A1>B1 will get FALSE and =B1>A1 will get TRUE because an empty cell is not greater than A but A is greater than empty, in COUNTIF blank ("") or empty will never be count. If you do =COUNTIF(A1:H1,">"&A1) you get 0. So nothing counts as to be greater than the empty cell A1.

                      This is because of the usage of text concatenation in COUNTIF. =COUNTIF(A1:H1,">"&A1) will become =COUNTIF(A1:H1,">") which counts how much values are greater than nothing. That counts 0.

                      In array context the COUNTIF(A1:H1,">"&A1:H1) gets {0,5,0,4,3,2,0,1} and so MATCH(0;{0,5,0,4,3,2,0,1},0) gets 1. Then INDEX(A1:H1,1) gets A1 which is empty. So the Formula shows 0 like =A1 also would do.

                      You would see this when using Evaluate Formula in Excel.

                      One could append a space behind the seach criteria in COUNTIF. So empty or blank would be handled like a space. And to each other cell value simply a space gets appended, what not should be problematic here.

                      {=INDEX(A1:H1,MATCH(0,COUNTIF(A1:H1,">"&A1:H1&" "),0))}
                      

                      should work.

                      Since COUNTIF is able using asterisk (*) used as the wildcard character to match any character, we also could append * instead of the space.

                      {=INDEX(A1:H1,MATCH(0,COUNTIF(A1:H1,">"&A1:H1&"*"),0))}
                      

                      Simply try what fits better.

                      Source https://stackoverflow.com/questions/71602089

                      Community Discussions, Code Snippets contain sources that include Stack Exchange Network

                      Vulnerabilities

                      No vulnerabilities reported

                      Install mina

                      You can download it from GitHub, GitLab.
                      On a UNIX-like operating system, using your system’s package manager is easiest. However, the packaged Ruby version may not be the newest one. There is also an installer for Windows. Managers help you to switch between multiple Ruby versions on your system. Installers can be used to install a specific or multiple Ruby versions. Please refer ruby-lang.org for more information.

                      Support

                      For any new features, suggestions and bugs create an issue on GitHub. If you have any questions check and ask questions on community page Stack Overflow .

                      DOWNLOAD this Library from

                      Find, review, and download reusable Libraries, Code Snippets, Cloud APIs from
                      over 430 million Knowledge Items
                      Find more libraries
                      Reuse Solution Kits and Libraries Curated by Popular Use Cases
                      Explore Kits

                      Save this library and start creating your kit

                      Explore Related Topics

                      Share this Page

                      share link
                      Reuse Pre-built Kits with mina
                      Consider Popular Continuous Deployment Libraries
                      Try Top Libraries by mina-deploy
                      Compare Continuous Deployment Libraries with Highest Support
                      Compare Continuous Deployment Libraries with Highest Quality
                      Compare Continuous Deployment Libraries with Highest Security
                      Compare Continuous Deployment Libraries with Permissive License
                      Compare Continuous Deployment Libraries with Highest Reuse
                      Find, review, and download reusable Libraries, Code Snippets, Cloud APIs from
                      over 430 million Knowledge Items
                      Find more libraries
                      Reuse Solution Kits and Libraries Curated by Popular Use Cases
                      Explore Kits

                      Save this library and start creating your kit

                      • © 2022 Open Weaver Inc.