diff --git a/.github/workflows/ci-build.yaml b/.github/workflows/ci-build.yaml index 7ee907da..b71f4035 100644 --- a/.github/workflows/ci-build.yaml +++ b/.github/workflows/ci-build.yaml @@ -1,39 +1,53 @@ -name: CI build +name: CI build on: - # push: - # branches: - # - master pull_request: branches: - master + workflow_dispatch: + jobs: - checklinks: + build: name: Linux runs-on: ubuntu-latest - strategy: - fail-fast: false + env: + # Control the use of htmlproofer. Set to '1' to enable htmlproofer. + USE_HTMLPROOFER: '0' steps: - - uses: actions/checkout@v2 - - name: Ruby - uses: actions/setup-ruby@v1 + # Clone the repository and checkout into the relevant branch + - uses: actions/checkout@v3.5.0 + + # Install Ruby + - name: Install Ruby + uses: ruby/setup-ruby@v1 with: - ruby-version: 2.6.x - - name: Setup Rubygems, Bundler, jekyll - run: | + ruby-version: 2.7.3 # Check https://pages.github.com/versions/ for the current Ruby version used by gh pages. + + # Install dependencies required to run jekyll build + - name: Install gh-pages rubygem via bundler + run: | + # Update gem and bundler gem update --system --no-document gem update bundler --no-document - gem install jekyll bundler + # Set the bundle directory bundle config set path vendor/bundle + # Install Gemfile contents via bundler bundle install + + # Build the website via jekyll - name: Build jekyll website with drafts run: bundle exec jekyll build --drafts - # - name: Check for broken links - # run: | - # bundle exec htmlproofer --disable-external --allow-hash-href --internal-domains=rse.shef.ac.uk,rse.sheffield.ac.uk --log-level :debug ./_site &> links.log - # continue-on-error: true - # - name: Archive log links - # uses: actions/upload-artifact@v1 - # with: - # name: links-check.log - # path: links.log + # Check for broken links if enabled + - name: Check for broken links + if: ${{ env.USE_HTMLPROOFER == '1' }} + run: | + bundle exec htmlproofer --disable-external --allow-hash-href --internal-domains=rse.shef.ac.uk,rse.sheffield.ac.uk --log-level :debug ./_site &> links.log + continue-on-error: true + + # Store the list of potentially broken links + - name: Archive log links + if: ${{ env.USE_HTMLPROOFER == '1' }} + uses: actions/upload-artifact@v1 + with: + name: links-check.log + path: links.log diff --git a/.github/workflows/pa11y.yaml b/.github/workflows/pa11y.yaml new file mode 100644 index 00000000..6d1025d3 --- /dev/null +++ b/.github/workflows/pa11y.yaml @@ -0,0 +1,43 @@ +name: pa11y tests + +on: + pull_request: + branches: + - master + workflow_dispatch: + +jobs: + build: + name: Building site and running pa11y-ci tests + runs-on: ubuntu-latest + + steps: + # Clone the repository and checkout into the relevant branch + - uses: actions/checkout@v3.5.0 + + # Install Ruby + - name: Install Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: 2.7.3 # Check https://pages.github.com/versions/ for the current Ruby version used by gh pages. + + # Install dependencies required to run jekyll build + - name: Install gh-pages rubygem via bundler + run: | + # Update gem and bundler + gem update --system --no-document + gem update bundler --no-document + # Set the bundle directory + bundle config set path vendor/bundle + # Install Gemfile contents via bundler + bundle install + + # Install pa11y requirements + - name: Install pa11y-ci + run: npm install -g pa11y-ci + + # Check site accesibility + - name: Serve site and test with pa11y + run: | + bundle exec jekyll serve --detach + pa11y-ci http://localhost:4000/ diff --git a/.gitignore b/.gitignore index a9bc0c37..4d5698a1 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,9 @@ vendor/ # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 +# jetbrains +.idea/ + # User-specific stuff .idea/**/workspace.xml .idea/**/tasks.xml @@ -84,4 +87,8 @@ fabric.properties RSE-Sheffield.github.io.Rproj .Rhistory +# vscode +.vscode/ +# Emacs +*~ \ No newline at end of file diff --git a/.idea/deployment.xml b/.idea/deployment.xml deleted file mode 100644 index 7448bdef..00000000 --- a/.idea/deployment.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml deleted file mode 100644 index 15a15b21..00000000 --- a/.idea/encodings.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml deleted file mode 100644 index 03d9549e..00000000 --- a/.idea/inspectionProfiles/Project_Default.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index 28a804d8..00000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index d905bbe9..00000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/rsesite.iml b/.idea/rsesite.iml deleted file mode 100644 index 24643cc3..00000000 --- a/.idea/rsesite.iml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 94a25f7f..00000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/Gemfile b/Gemfile index c544be35..d51c8548 100644 --- a/Gemfile +++ b/Gemfile @@ -21,6 +21,7 @@ gem "github-pages", group: :jekyll_plugins # If you have any plugins, put them here! group :jekyll_plugins do gem "jekyll-feed", "~> 0.6" + gem "jekyll-paginate" end # Windows does not include zoneinfo files, so bundle the tzinfo-data gem @@ -31,3 +32,8 @@ gem "html-proofer" # For redirects gem "jekyll-redirect-from" + +# Emojis https://github.com/jekyll/jemoji +gem "jemoji" + +gem "webrick", "~> 1.7" diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 00000000..55468794 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,171 @@ +# Creative Commons Attribution-ShareAlike 4.0 International + +Creative Commons Corporation (“Creative Commons”) is not a law firm and does not provide legal services or legal advice. Distribution of Creative Commons public licenses does not create a lawyer-client or other relationship. Creative Commons makes its licenses and related information available on an “as-is” basis. Creative Commons gives no warranties regarding its licenses, any material licensed under their terms and conditions, or any related information. Creative Commons disclaims all liability for damages resulting from their use to the fullest extent possible. + +### Using Creative Commons Public Licenses + +Creative Commons public licenses provide a standard set of terms and conditions that creators and other rights holders may use to share original works of authorship and other material subject to copyright and certain other rights specified in the public license below. The following considerations are for informational purposes only, are not exhaustive, and do not form part of our licenses. + +* __Considerations for licensors:__ Our public licenses are intended for use by those authorized to give the public permission to use material in ways otherwise restricted by copyright and certain other rights. Our licenses are irrevocable. Licensors should read and understand the terms and conditions of the license they choose before applying it. Licensors should also secure all rights necessary before applying our licenses so that the public can reuse the material as expected. Licensors should clearly mark any material not subject to the license. This includes other CC-licensed material, or material used under an exception or limitation to copyright. [More considerations for licensors](http://wiki.creativecommons.org/Considerations_for_licensors_and_licensees#Considerations_for_licensors). + +* __Considerations for the public:__ By using one of our public licenses, a licensor grants the public permission to use the licensed material under specified terms and conditions. If the licensor’s permission is not necessary for any reason–for example, because of any applicable exception or limitation to copyright–then that use is not regulated by the license. Our licenses grant only permissions under copyright and certain other rights that a licensor has authority to grant. Use of the licensed material may still be restricted for other reasons, including because others have copyright or other rights in the material. A licensor may make special requests, such as asking that all changes be marked or described. Although not required by our licenses, you are encouraged to respect those requests where reasonable. [More considerations for the public](http://wiki.creativecommons.org/Considerations_for_licensors_and_licensees#Considerations_for_licensees). + +## Creative Commons Attribution-ShareAlike 4.0 International Public License + +By exercising the Licensed Rights (defined below), You accept and agree to be bound by the terms and conditions of this Creative Commons Attribution-ShareAlike 4.0 International Public License ("Public License"). To the extent this Public License may be interpreted as a contract, You are granted the Licensed Rights in consideration of Your acceptance of these terms and conditions, and the Licensor grants You such rights in consideration of benefits the Licensor receives from making the Licensed Material available under these terms and conditions. + +### Section 1 – Definitions. + +a. __Adapted Material__ means material subject to Copyright and Similar Rights that is derived from or based upon the Licensed Material and in which the Licensed Material is translated, altered, arranged, transformed, or otherwise modified in a manner requiring permission under the Copyright and Similar Rights held by the Licensor. For purposes of this Public License, where the Licensed Material is a musical work, performance, or sound recording, Adapted Material is always produced where the Licensed Material is synched in timed relation with a moving image. + +b. __Adapter's License__ means the license You apply to Your Copyright and Similar Rights in Your contributions to Adapted Material in accordance with the terms and conditions of this Public License. + +c. __BY-SA Compatible License__ means a license listed at [creativecommons.org/compatiblelicenses](http://creativecommons.org/compatiblelicenses), approved by Creative Commons as essentially the equivalent of this Public License. + +d. __Copyright and Similar Rights__ means copyright and/or similar rights closely related to copyright including, without limitation, performance, broadcast, sound recording, and Sui Generis Database Rights, without regard to how the rights are labeled or categorized. For purposes of this Public License, the rights specified in Section 2(b)(1)-(2) are not Copyright and Similar Rights. + +e. __Effective Technological Measures__ means those measures that, in the absence of proper authority, may not be circumvented under laws fulfilling obligations under Article 11 of the WIPO Copyright Treaty adopted on December 20, 1996, and/or similar international agreements. + +f. __Exceptions and Limitations__ means fair use, fair dealing, and/or any other exception or limitation to Copyright and Similar Rights that applies to Your use of the Licensed Material. + +g. __License Elements__ means the license attributes listed in the name of a Creative Commons Public License. The License Elements of this Public License are Attribution and ShareAlike. + +h. __Licensed Material__ means the artistic or literary work, database, or other material to which the Licensor applied this Public License. + +i. __Licensed Rights__ means the rights granted to You subject to the terms and conditions of this Public License, which are limited to all Copyright and Similar Rights that apply to Your use of the Licensed Material and that the Licensor has authority to license. + +j. __Licensor__ means the individual(s) or entity(ies) granting rights under this Public License. + +k. __Share__ means to provide material to the public by any means or process that requires permission under the Licensed Rights, such as reproduction, public display, public performance, distribution, dissemination, communication, or importation, and to make material available to the public including in ways that members of the public may access the material from a place and at a time individually chosen by them. + +l. __Sui Generis Database Rights__ means rights other than copyright resulting from Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, as amended and/or succeeded, as well as other essentially equivalent rights anywhere in the world. + +m. __You__ means the individual or entity exercising the Licensed Rights under this Public License. __Your__ has a corresponding meaning. + +### Section 2 – Scope. + +a. ___License grant.___ + + 1. Subject to the terms and conditions of this Public License, the Licensor hereby grants You a worldwide, royalty-free, non-sublicensable, non-exclusive, irrevocable license to exercise the Licensed Rights in the Licensed Material to: + + A. reproduce and Share the Licensed Material, in whole or in part; and + + B. produce, reproduce, and Share Adapted Material. + + 2. __Exceptions and Limitations.__ For the avoidance of doubt, where Exceptions and Limitations apply to Your use, this Public License does not apply, and You do not need to comply with its terms and conditions. + + 3. __Term.__ The term of this Public License is specified in Section 6(a). + + 4. __Media and formats; technical modifications allowed.__ The Licensor authorizes You to exercise the Licensed Rights in all media and formats whether now known or hereafter created, and to make technical modifications necessary to do so. The Licensor waives and/or agrees not to assert any right or authority to forbid You from making technical modifications necessary to exercise the Licensed Rights, including technical modifications necessary to circumvent Effective Technological Measures. For purposes of this Public License, simply making modifications authorized by this Section 2(a)(4) never produces Adapted Material. + + 5. __Downstream recipients.__ + + A. __Offer from the Licensor – Licensed Material.__ Every recipient of the Licensed Material automatically receives an offer from the Licensor to exercise the Licensed Rights under the terms and conditions of this Public License. + + B. __Additional offer from the Licensor – Adapted Material.__ Every recipient of Adapted Material from You automatically receives an offer from the Licensor to exercise the Licensed Rights in the Adapted Material under the conditions of the Adapter’s License You apply. + + C. __No downstream restrictions.__ You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, the Licensed Material if doing so restricts exercise of the Licensed Rights by any recipient of the Licensed Material. + + 6. __No endorsement.__ Nothing in this Public License constitutes or may be construed as permission to assert or imply that You are, or that Your use of the Licensed Material is, connected with, or sponsored, endorsed, or granted official status by, the Licensor or others designated to receive attribution as provided in Section 3(a)(1)(A)(i). + +b. ___Other rights.___ + + 1. Moral rights, such as the right of integrity, are not licensed under this Public License, nor are publicity, privacy, and/or other similar personality rights; however, to the extent possible, the Licensor waives and/or agrees not to assert any such rights held by the Licensor to the limited extent necessary to allow You to exercise the Licensed Rights, but not otherwise. + + 2. Patent and trademark rights are not licensed under this Public License. + + 3. To the extent possible, the Licensor waives any right to collect royalties from You for the exercise of the Licensed Rights, whether directly or through a collecting society under any voluntary or waivable statutory or compulsory licensing scheme. In all other cases the Licensor expressly reserves any right to collect such royalties. + +### Section 3 – License Conditions. + +Your exercise of the Licensed Rights is expressly made subject to the following conditions. + +a. ___Attribution.___ + + 1. If You Share the Licensed Material (including in modified form), You must: + + A. retain the following if it is supplied by the Licensor with the Licensed Material: + + i. identification of the creator(s) of the Licensed Material and any others designated to receive attribution, in any reasonable manner requested by the Licensor (including by pseudonym if designated); + + ii. a copyright notice; + + iii. a notice that refers to this Public License; + + iv. a notice that refers to the disclaimer of warranties; + + v. a URI or hyperlink to the Licensed Material to the extent reasonably practicable; + + B. indicate if You modified the Licensed Material and retain an indication of any previous modifications; and + + C. indicate the Licensed Material is licensed under this Public License, and include the text of, or the URI or hyperlink to, this Public License. + + 2. You may satisfy the conditions in Section 3(a)(1) in any reasonable manner based on the medium, means, and context in which You Share the Licensed Material. For example, it may be reasonable to satisfy the conditions by providing a URI or hyperlink to a resource that includes the required information. + + 3. If requested by the Licensor, You must remove any of the information required by Section 3(a)(1)(A) to the extent reasonably practicable. + +b. ___ShareAlike.___ + +In addition to the conditions in Section 3(a), if You Share Adapted Material You produce, the following conditions also apply. + +1. The Adapter’s License You apply must be a Creative Commons license with the same License Elements, this version or later, or a BY-SA Compatible License. + +2. You must include the text of, or the URI or hyperlink to, the Adapter's License You apply. You may satisfy this condition in any reasonable manner based on the medium, means, and context in which You Share Adapted Material. + +3. You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, Adapted Material that restrict exercise of the rights granted under the Adapter's License You apply. + +### Section 4 – Sui Generis Database Rights. + +Where the Licensed Rights include Sui Generis Database Rights that apply to Your use of the Licensed Material: + +a. for the avoidance of doubt, Section 2(a)(1) grants You the right to extract, reuse, reproduce, and Share all or a substantial portion of the contents of the database; + +b. if You include all or a substantial portion of the database contents in a database in which You have Sui Generis Database Rights, then the database in which You have Sui Generis Database Rights (but not its individual contents) is Adapted Material, including for purposes of Section 3(b); and + +c. You must comply with the conditions in Section 3(a) if You Share all or a substantial portion of the contents of the database. + +For the avoidance of doubt, this Section 4 supplements and does not replace Your obligations under this Public License where the Licensed Rights include other Copyright and Similar Rights. + +### Section 5 – Disclaimer of Warranties and Limitation of Liability. + +a. __Unless otherwise separately undertaken by the Licensor, to the extent possible, the Licensor offers the Licensed Material as-is and as-available, and makes no representations or warranties of any kind concerning the Licensed Material, whether express, implied, statutory, or other. This includes, without limitation, warranties of title, merchantability, fitness for a particular purpose, non-infringement, absence of latent or other defects, accuracy, or the presence or absence of errors, whether or not known or discoverable. Where disclaimers of warranties are not allowed in full or in part, this disclaimer may not apply to You.__ + +b. __To the extent possible, in no event will the Licensor be liable to You on any legal theory (including, without limitation, negligence) or otherwise for any direct, special, indirect, incidental, consequential, punitive, exemplary, or other losses, costs, expenses, or damages arising out of this Public License or use of the Licensed Material, even if the Licensor has been advised of the possibility of such losses, costs, expenses, or damages. Where a limitation of liability is not allowed in full or in part, this limitation may not apply to You.__ + +c. The disclaimer of warranties and limitation of liability provided above shall be interpreted in a manner that, to the extent possible, most closely approximates an absolute disclaimer and waiver of all liability. + +### Section 6 – Term and Termination. + +a. This Public License applies for the term of the Copyright and Similar Rights licensed here. However, if You fail to comply with this Public License, then Your rights under this Public License terminate automatically. + +b. Where Your right to use the Licensed Material has terminated under Section 6(a), it reinstates: + + 1. automatically as of the date the violation is cured, provided it is cured within 30 days of Your discovery of the violation; or + + 2. upon express reinstatement by the Licensor. + + For the avoidance of doubt, this Section 6(b) does not affect any right the Licensor may have to seek remedies for Your violations of this Public License. + +c. For the avoidance of doubt, the Licensor may also offer the Licensed Material under separate terms or conditions or stop distributing the Licensed Material at any time; however, doing so will not terminate this Public License. + +d. Sections 1, 5, 6, 7, and 8 survive termination of this Public License. + +### Section 7 – Other Terms and Conditions. + +a. The Licensor shall not be bound by any additional or different terms or conditions communicated by You unless expressly agreed. + +b. Any arrangements, understandings, or agreements regarding the Licensed Material not stated herein are separate from and independent of the terms and conditions of this Public License. + +### Section 8 – Interpretation. + +a. For the avoidance of doubt, this Public License does not, and shall not be interpreted to, reduce, limit, restrict, or impose conditions on any use of the Licensed Material that could lawfully be made without permission under this Public License. + +b. To the extent possible, if any provision of this Public License is deemed unenforceable, it shall be automatically reformed to the minimum extent necessary to make it enforceable. If the provision cannot be reformed, it shall be severed from this Public License without affecting the enforceability of the remaining terms and conditions. + +c. No term or condition of this Public License will be waived and no failure to comply consented to unless expressly agreed to by the Licensor. + +d. Nothing in this Public License constitutes or may be interpreted as a limitation upon, or waiver of, any privileges and immunities that apply to the Licensor or You, including from the legal processes of any jurisdiction or authority. + +> Creative Commons is not a party to its public licenses. Notwithstanding, Creative Commons may elect to apply one of its public licenses to material it publishes and in those instances will be considered the “Licensor.” The text of the Creative Commons public licenses is dedicated to the public domain under the [CC0 Public Domain Dedication](https://creativecommons.org/publicdomain/zero/1.0/legalcode). Except for the limited purpose of indicating that material is shared under a Creative Commons public license or as otherwise permitted by the Creative Commons policies published at [creativecommons.org/policies](http://creativecommons.org/policies), Creative Commons does not authorize the use of the trademark “Creative Commons” or any other trademark or logo of Creative Commons without its prior written consent including, without limitation, in connection with any unauthorized modifications to any of its public licenses or any other arrangements, understandings, or agreements concerning use of licensed material. For the avoidance of doubt, this paragraph does not form part of the public licenses. +> +> Creative Commons may be contacted at creativecommons.org. diff --git a/README.md b/README.md index 8f33cea5..e231781e 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,21 @@ This repository contains the source for the RSE-Sheffield website, built with [J The website is hosted on GitHub Pages and can be found at [https://rse.shef.ac.uk](https://rse.shef.ac.uk). +All content (excluding logos or where explicitly stated) licensed under the + +CC BY-SA 4.0 + +license. + ## Development ### Install Dependencies @@ -11,14 +26,19 @@ The website is hosted on GitHub Pages and can be found at [https://rse.shef.ac.u 1. Install Ruby * On Windows, this installer can be used [https://rubyinstaller.org/](https://rubyinstaller.org/) * On Linux, follow the instructions according to your distribution e.g. for Debian/Ubuntu: + ```sh sudo apt install ruby-full ``` + 2. Install `bundler` (via a terminal): + ```sh - gem install bundler jekyll + gem install bundler ``` + 3. Install other dependencies: + ```sh cd path/to/clone/of/this/repo bundle config set path vendor/bundle @@ -60,19 +80,17 @@ bundle exec jekyll build Generated HTML files can be found in `_site`. - - ## Writing Content Content can be written in Markdown, reStructuredText or as HTML. -### Assets: Images, PDFs etc. +### Assets: Images, PDFs etc Resources such as images should be stored in the `assets` directory. E.g. `assets/images/image.png`. This can then be included in your markdown file via: -``` +```markdown ![description of image](/assets/images/image.png){: .img-fluid} ``` @@ -83,11 +101,12 @@ This applies the `img-fluid` css class to the generate `` element, to make PDFs or other very large binary files should be stored in an alternate repository, to avoid polluting the main website source with very large files. ##### Seminar-slides + For seminar content, use the [RSE-Sheffield/seminar-slides](https://github.com/RSE-Sheffield/seminar-slides) repository. Detailed instructions are provided in the README.md for how to add files, and how to link to them. ##### Others -Other files could be stored in an appropriate directory within `assets`, or alternatively another repository could be set up similar to [RSE-Sheffield/seminar-slides](https://github.com/RSE-Sheffield/seminar-slides). +Other files could be stored in an appropriate directory within `assets`, or alternatively another repository could be set up similar to [RSE-Sheffield/seminar-slides](https://github.com/RSE-Sheffield/seminar-slides). ### Linking to Local Content @@ -95,16 +114,53 @@ Ideally link to other pages using either Jekyll's Liquid variables, relative or e.g. `[Target]({{site.url}}/target/page/)`, `[Target](target/page/)` or `[Target](/target/page/)` - Avoid absolute links such as `https://rse.shef.ac.uk/target/page/` which prevent local testing. - - ### Pages The general website pages are stored in `pages/`, as Markdown or HTML files. -See the [Jekyll Docs /pages/](for https://jekyllrb.com/docs/pages/) for more information. +See the [Jekyll Docs /pages/](https://jekyllrb.com/docs/pages/) for more information. + +### Staff Pages + +Staff pages contain biographies of current and alumni (previous) members of the team. There are a few key fields that +require careful attention to when adding a new member or updating details of those who have left the team. + +The header of each Markdown file is written in [yaml](https://yaml.org) with intuitive and self-explanatory fields +names. + + +#### New Members + +When adding a new member a new Markdown file should be created under +`RSE-Sheffield.github.io/_people/-.md` with the following example YAML header. + +```yaml +--- +alumnum: false +level: 2 +published: true + +othernames: +surname: +role: +--- +``` + +Most fields required for the header are self-explanatory. One key field is that of `level` which should be completed +according to the level of appointment as detailed in the table below. + +| Level | Description | +|:-----:|:----------------------------------| +| 0 | Head of Department | +| 1 | Senior Research Software Engineer | +| 2 | Research Software Engineer | +| 3 | Junior Research Software Engineer | + +Details of alumni of the RSE team are kept and this is defined by the `alumnum` field. Whilst a member of the team this +should be `false` and their profile will be listed under _Contact > RSE TEAM_, but after having left the team it should +be `true` which means their details will be listed under _Contact > Alumni_. ### Blog Posts @@ -112,24 +168,27 @@ Blog posts are located in the `_posts` directory. The filename **MUST** be prepended with a date (ISO 8601) e.g. `2018-01-01-foo-bar.md`. -Each blog post has a YAML *FrontMatter*, which **must** contain a `slug` (unique), `title`, `author`, and `date`. +Each blog post has a YAML *FrontMatter*, which **must** contain a `slug` (unique), `title`, `author`, `date` and `excerpt_separator`. Optional fields can also be included, such as `layout`, `category` (or `categories`), `tags` etc. -`image` is an optional field and will override the default image (RSE logo) for social cards. +`image` is an optional field and will override the default image (RSE logo) for social cards. The YAML header should look something like: -``` +```yaml --- slug: foo-bar title: foo-bar author: Baz date: 2018-01-01 00:00:00 +excerpt_separator: category: tags: social_image: /assets/images/logo/rse-logoonly-stroke.png --- ``` +The `excerpt_separator` defines a token, which when placed in the blog post causes the remainder of the post to be omitted from blog post previews shown around the website (e.g. [here](https://rse.shef.ac.uk/blog/). It is recommended that blog posts account for the excerpt by having the first paragraph/s act as an introduction to the blog post's content. If `excerpt_separator` is not included in the front-matter, the first line-break will be treated as the end of the excerpt, the suggested seperator `` is a html comment so will not be visible within blog posts. + **Warning: GitHub will refuse to serve Jekyll sites that include funny characters (e.g. `&` or `@` in the `title:` YAML field unless the entire title is enclosed in double-quotes**, even though the Jekyll site will build locally without warnings. **Warning: Social Card images [cannot be SVGs](https://developer.twitter.com/en/docs/twitter-for-websites/cards/overview/summary-card-with-large-image)**. @@ -143,7 +202,6 @@ Events have a YAML FrontMatter, which **must** include `category`, `date`, `from The `category` variable classifies the type of event. The list of existing categories can be found at `_data/event-categories.yml`. - Different categories of event may expect or make use of additional variables, such as `speaker`, `institute` and `title` for the `seminar` category. See other examples of the same category for further details. The following are some of the **FrontMatter** variables which can be set: @@ -172,7 +230,7 @@ Categories should have an associated `image` representation and a `text` value f i.e. -``` +```yaml seminar: image: "/assets/images/icons/icons8-training-50.png" text: "Seminar" @@ -186,13 +244,14 @@ To create a new page which lists all events of a given category: 1. Create a new page, i.e. `pages/newcategory.md` 2. Include the `event_list.html` template with the key from your new category: - ``` + + ```liquid {% include events_list.html category="newcategory" %} ``` ### Adding/editing info re RSE team projects -Each project listed in [`_data/projects.csv`](_data/projects.csv) should have a description in a markdown file in the [`_project_descriptions/`](_project_descriptions/) folder. The markdown file nust be named identically to the text in the key column of `projects.csv`. +Each project listed in [`_data/projects.csv`](_data/projects.csv) should have a description in a markdown file in the [`_project_descriptions/`](_project_descriptions/) folder. The markdown file must be named identically to the text in the key column of `projects.csv`. The following project data (and metadata) are to be populated in `projects.csv`: @@ -212,7 +271,7 @@ The following project data (and metadata) are to be populated in `projects.csv`: Project descriptions are to be written in markdown with a header containing the project key: -``` +```yaml --- key: --- @@ -220,10 +279,10 @@ key: The text should address the following: -- A general description of the project, its aims and objectives, link to project website (if available). -- What does / did the RSE collaboration add to the project? -- Current and planned project outputs linked to RSE contribution (e.g. GitHub link, papers, talks). -- Project impact beyond software (societal benefits, policy change, improved media output, financial / business, public engagement, health benefits). +* A general description of the project, its aims and objectives, link to project website (if available). +* What does / did the RSE collaboration add to the project? +* Current and planned project outputs linked to RSE contribution (e.g. GitHub link, papers, talks). +* Project impact beyond software (societal benefits, policy change, improved media output, financial / business, public engagement, health benefits). ## Layout and Style @@ -234,13 +293,11 @@ Layouts (or pages) may reference *includes* which are re-usable sections of mark Style should primarily be controlled through CSS, both through the site theme and any custom CSS rules. Custom CSS should be specified in `assets/css/custom.css` - ### Table Formatting Markdown tables generated by jekyll are not well-themed by the website theme / bootstrap by default, as classes need adding to the table to improve the formatting. This can be achieved in jekyll using a Kramdown feature as follows: - -``` +```markdown | Example | Table | A | |---------|-------|---| | 1 | 2 | 3 | diff --git a/_config.yml b/_config.yml index c0477bd0..249a8a6a 100644 --- a/_config.yml +++ b/_config.yml @@ -51,14 +51,15 @@ plugins: - jekyll-feed - jekyll-seo-tag - jekyll-redirect-from + - jekyll-paginate + - jemoji exclude: - Gemfile - Gemfile.lock - vendor strict_front_matter: true defaults: - - - scope: + - scope: path: "pages" values: layout: "page" @@ -82,3 +83,7 @@ defaults: type: "newsletters" values: layout: "newsletter" + +# Configure Blog +paginate: 10 +paginate_path: /blog/page:num/ diff --git a/_data/event-categories.yml b/_data/event-categories.yml index 0d3afc7a..973bdd18 100644 --- a/_data/event-categories.yml +++ b/_data/event-categories.yml @@ -4,6 +4,9 @@ seminar: dltraining: image: "/assets/images/icons/icons8-connect-50.png" text: "Workshop" +gitzerohero: + image: "/assets/images/icons/icons8-schedule-50.png" + text: "Workshop" candc: image: "/assets/images/icons/icons8-cafe-50.png" text: "Coffee
& Cake" diff --git a/_data/navigation.yml b/_data/navigation.yml index 23c26f44..68896989 100644 --- a/_data/navigation.yml +++ b/_data/navigation.yml @@ -1,29 +1,41 @@ -- title: RSE Service +- title: Collaborate subitems: - - title: RSE Service Overview - url: /service/ - - title: Service Model Provision - url: /service/provision/ - - title: What we do - url: /service/activities + - title: Why work with us? + url: /collaboration/ + - title: How to work with us + url: /collaboration/provision/ + - title: Collaboration Guide + url: /collaboration/guide/ + - title: What We Do + url: /collaboration/activities + - title: Costing RSE time + url: /collaboration/costing + - title: Tier 2 Open Call + url: /collaboration/tier2 - title: Projects - url: /service/projects + url: /collaboration/projects - title: Testimonials - url: /service/testimonials -- title: "Support & Training" + url: /collaboration/testimonials +- title: "Training" subitems: - - title: Overview + - title: Training Courses url: /training/ - title: Researcher Programming Resources url: /training/programming + - title: Researcher Artificial Intelligence and Machine Learning Resources + url: /training/deeplearning - title: Code Clinic url: /support/code-clinic - - title: Deep Learning - url: /training/deeplearning -- title: RSE Community + - title: "COM4521/COM6521: Parallel Computing with GPUs" + url: /training/com4521 +- title: Our Community subitems: - title: Overview url: /community + - title: Code of Conduct + url: /community/code_of_conduct + - title: Slack + url: /community/slack - title: Lunch Bytes talks url: /community/lunch-bytes - title: Seminar Series diff --git a/_data/projects.csv b/_data/projects.csv index 65d30db9..dfb0d104 100644 --- a/_data/projects.csv +++ b/_data/projects.csv @@ -1,40 +1,41 @@ -id,key,title,long_title,tech_methods,rses,start,end,department,level,show -1,,Neurodegenerative Dementia,Neurodegenerative Dementia,,Daniele Tartarini,01/03/2020,28/02/2023,Computer Science,2,0 -2,,EMODnet,EMODnet,,Anna Krystalli,01/01/2020,18/04/2023,Animal and Plant Science,2,1 -4,citcom,CITCoM,Casual Inference for Testing of Computational Models,"Python, Docker, HPC, machine learning",Robert Turner,01/01/2021,01/07/2024,Computer Science,1,1 -6,,Strituvad,Strituvad,,"Peter Heywood, David Wilby",16/04/2018,01/11/2021,Mathematics and Statistics,2,1 -7,bbsrc_chaste,BBSRC: Cell Modelling,BBSRC: Cell Modelling,"C++, cell, simulation, Docker, Python, HPC",Twin Karmakharm,01/10/2018,30/09/2021,Mathematics and Statistics,2,1 -8,,CompBioMed2,CompBioMed2,,Daniele Tartarini,01/10/2019,30/09/2023,INSIGNEO,2,1 -9,primage,Primage,Primage,"C++, CUDA, Python, HPC, FLAME GPU, ABM, simulation",Robert Chisholm,01/01/2019,31/12/2022,INSIGNEO,1,1 -10,,Google DNI Journalist,Google DNI Journalist,,"David Jones, Twin Karmakharm",01/01/2019,01/01/2020,Computer Science,2,1 -11,,ELG,ELG,,David Jones,07/01/2019,01/01/2020,Computer Science,2,1 -12,brc,BRC,NIHR Sheffield Biomedical Research Centre,"databases, Ansible, training, MATLAB, R, REDCap, XNAT, servers","Anna Krystalli, Will Furnass, Robert Turner",01/05/2018,31/03/2022,INSIGNEO,1,1 -13,,E2EEHM Vibration Analytics,E2EEHM Vibration Analytics,,David Jones,01/11/2019,31/03/2020,Automatic Control and Systems Engineering,2,1 -16,,Insigneo TO 2019,Insigneo TO 2019,,Daniele Tartarini,01/08/2019,01/08/2021,INSIGNEO,2,0 -17,,ACCE DTP,ACCE DTP,,Anna Krystalli,01/01/2020,30/04/2020,University of York,2,1 -19,,Reprohacks,Reprohacks,,Anna Krystalli,01/01/2020,31/03/2020,N8 ,2,1 -21,,RateSetter+,RateSetter+,,John Charlton,18/11/2019,17/03/2021,Mechanical Engineering,2,1 -22,pykale,Prognostic: Cardiac MRI with ML,pykale (Multimodal/transfer learning on graphs/images/videos),"Python, version control, static analysis, GitHub, testing, machine learning","David Jones, Robert Turner, Will Furnass",01/10/2020,30/09/2021,Computer Science,1,1 -24,polar,Polar Portal,Polar Portal: Sea ice edge detection,"Python, Docker, MATLAB",Robert Turner,01/11/2019,01/02/2020,Geography,1,1 -25,,A Network For Lemons,A Network For Lemons,,Anna Krystalli,09/09/2019,08/09/2020,Management School,2,1 -27,comsciimpact,IMPACT Acceleration,IMPACT Acceleration,,David Wilby,01/08/2019,31/07/2021,Computer Science,1,1 -28,itshpc,IT Services HPC Support 2019-2021,IT Services HPC Support 2019-2021,"HPC, Slurm, Puppet, Nagios, collectd, Grafana, InfluxDB, SGE, Grid Engine, Singularity",Will Furnass,01/08/2019,01/08/2021,IT Services,1,1 -30,,Accelerate,Accelerate,,"Peter Heywood, Mozhgan Kabiri Chimeh, Matt Leach",01/03/2016,01/10/2021,Computer Science,2,1 -31,com4521,Teaching Support for GPU Module,Teaching Support for GPU Module,"teaching, C, OpenMP, CUDA, HPC","Paul Richmond, Mozhgan Kabiri Chimeh, Robert Chisholm, John Charlton, Peter Heywood",01/09/2015,,Computer Science,1,1 -32,,SoBigData++,SoBigData++,,"David Jones, Twin Karmakharm",01/01/2020,01/01/2022,Computer Science,2,1 -33,,RISIS II (includes WeVerfiy and some ELG),RISIS II (includes WeVerfiy and some ELG),,"Twin Karmakharm, David Wilby",01/01/2020,30/06/2021,Computer Science,2,1 -34,gpy,Learning to move as a human,Multiple output Gaussian processes for GPy,"Python, Gaussian processes, documentation, testing, continuous integration, MATLAB",Robert Turner,01/10/2019,01/01/2021,Computer Science,1,1 -40,jade2,JADE II Support,JADE II Support,"deep learning, HPC, teaching, user support","Anna Krystalli, Twin Karmakharm",01/02/2020,01/08/2021,IT Services,2,1 -45,basisflow,BasisFlow,BasisFlow,,Twin Karmakharm,01/01/2021,31/12/2023,Chemistry,2,1 -53,ramp,RAMP SCRC Covid Support,RAMP SCRC Covid Support,"Python, agile, testing, continuous integration, documentation",Robert Turner,01/05/2020,01/08/2020,Computer Science,2,1 -55,,IFPRI,IFPRI,,David Wilby,01/07/2020,01/08/2020,Computer Science,2,1 -56,,Opening Up Minds,Opening Up Minds,,Anna Krystalli,18/01/2021,18/06/2021,Psychology,2,1 -57,,Flood Modelling Festival of the Mind,Flood Modelling Festival of the Mind,,"Matt Leach, Paul Richmond",01/07/2020,01/09/2020,Civil Engineering,2,1 -58,ratesetter,RateSetter / Merseyrail,RateSetter / Merseyrail,"C++, FLAME GPU, ABM",Twin Karmakharm,18/11/2019,01/12/2020,Mechanical Engineering,2,1 -64,scrc-pipeline,SCRC Follow on,Covid epidemiology data pipeline,"Python, agile, testing, continuous integration, documentation",Robert Turner,01/01/2021,01/01/2022,External,1,1 -65,,Hole in the Road,Hole in the Road,,Matt Leach,24/09/2020,13/10/2020,Computer Science,2,1 -71,,JBC: Data and Data Science,JBC: Data and Data Science,,"David Jones, David Wilby",01/01/2021,01/07/2021,Department of Health and Social Care,2,1 -75,airqo,AirQo: Air Quality (Google),AirQo: Kampala Air Quality,"Python, Scrum, testing, machine learning, Gaussian processes, containers, cloud, continuous integration",Robert Turner,01/03/2021,01/05/2021,Computer Science,1,1 -78,,Rail Transport,Rail Transport,,"John Charlton, Peter Heywood",29/01/2021,28/11/2021,Mechanical Engineering,2,1 -79,rumour_veracity, Rumour Veracity, Rumour Veracity,"NLP, deep learning, social media, Python, Javascript, Django, Vue.js, full stack","Twin Karmakharm, David Wilby",01/01/2019,30/06/2021,Computer Science,2,1 -,firstdraftcoviddash,FirstDraft × GATE COVID Dashboard,FirstDraft × GATE COVID Data Deficits Dashboard,"Python, Django, Vue.js, Javascript, web apps, elasticsearch, PostgreSQL, databases","David Wilby, Twin Karmakharm",01/06/2020,31/07/2020,Computer Science,1,1 +id,key,title,long_title,tech_methods,rses,start,end,department,level,show +1,,Neurodegenerative Dementia,Neurodegenerative Dementia,,Daniele Tartarini,01/03/2020,28/02/2023,Computer Science,2,0 +2,,EMODnet,EMODnet,,Anna Krystalli,01/01/2020,18/04/2023,Animal and Plant Science,2,1 +4,citcom,CITCoM,Casual Inference for Testing of Computational Models,"Python, Docker, HPC, machine learning",Robert Turner,01/01/2021,01/07/2024,Computer Science,1,1 +5,flamegpu2,FLAME GPU 2,FLAME GPU 2,"FLAME GPU, CUDA, C++, Python, ABM, simulation, HPC","Paul Richmond, Mozhgan Kabiri Chimeh, Peter Heywood, Robert Chisholm, Matt Leach",23/11/2016,,,1,1 +6,,Strituvad,Strituvad,,"Peter Heywood, David Wilby",16/04/2018,01/11/2021,Mathematics and Statistics,2,1 +7,bbsrc_chaste,BBSRC: Cell Modelling,BBSRC: Cell Modelling,"C++, cell, simulation, Docker, Python, HPC",Twin Karmakharm,01/10/2018,30/09/2021,Mathematics and Statistics,2,1 +8,,CompBioMed2,CompBioMed2,,Daniele Tartarini,01/10/2019,30/09/2023,INSIGNEO,2,1 +9,primage,Primage,Primage,"C++, CUDA, Python, HPC, FLAME GPU, ABM, simulation",Robert Chisholm,01/01/2019,31/12/2022,INSIGNEO,1,1 +10,,Google DNI Journalist,Google DNI Journalist,,"David Jones, Twin Karmakharm",01/01/2019,01/01/2020,Computer Science,2,1 +11,,ELG,ELG,,David Jones,07/01/2019,01/01/2020,Computer Science,2,1 +12,brc,BRC,NIHR Sheffield Biomedical Research Centre,"databases, Ansible, training, MATLAB, R, REDCap, XNAT, servers","Anna Krystalli, Will Furnass, Robert Turner",01/05/2018,31/03/2022,INSIGNEO,1,1 +13,,E2EEHM Vibration Analytics,E2EEHM Vibration Analytics,,David Jones,01/11/2019,31/03/2020,Automatic Control and Systems Engineering,2,1 +16,,Insigneo TO 2019,Insigneo TO 2019,,Daniele Tartarini,01/08/2019,01/08/2021,INSIGNEO,2,0 +17,,ACCE DTP,ACCE DTP,,Anna Krystalli,01/01/2020,30/04/2020,University of York,2,1 +19,,Reprohacks,Reprohacks,,Anna Krystalli,01/01/2020,31/03/2020,N8 ,2,1 +21,,RateSetter+,RateSetter+,,John Charlton,18/11/2019,17/03/2021,Mechanical Engineering,2,1 +22,pykale,Prognostic: Cardiac MRI with ML,pykale (Multimodal/transfer learning on graphs/images/videos),"Python, version control, static analysis, GitHub, testing, machine learning","David Jones, Robert Turner, Will Furnass",01/10/2020,30/09/2021,Computer Science,1,1 +24,polar,Polar Portal,Polar Portal: Sea ice edge detection,"Python, Docker, MATLAB",Robert Turner,01/11/2019,01/02/2020,Geography,1,1 +25,,A Network For Lemons,A Network For Lemons,,Anna Krystalli,09/09/2019,08/09/2020,Management School,2,1 +27,comsciimpact,IMPACT Acceleration,IMPACT Acceleration,machine learning,David Wilby,01/08/2019,31/07/2021,Computer Science,1,1 +28,itshpc,IT Services HPC Support 2019-2021,IT Services HPC Support 2019-2021,"HPC, Slurm, Puppet, Nagios, collectd, Grafana, InfluxDB, SGE, Grid Engine, Singularity",Will Furnass,01/08/2019,01/08/2021,IT Services,1,1 +30,,Accelerate,Accelerate,,"Peter Heywood, Mozhgan Kabiri Chimeh, Matt Leach",01/03/2016,01/10/2021,Computer Science,2,1 +31,com4521,Teaching Support for GPU Module,Teaching Support for GPU Module,"teaching, C, OpenMP, CUDA, HPC","Paul Richmond, Mozhgan Kabiri Chimeh, Robert Chisholm, John Charlton, Peter Heywood",01/09/2015,,Computer Science,1,1 +32,,SoBigData++,SoBigData++,,"David Jones, Twin Karmakharm",01/01/2020,01/01/2022,Computer Science,2,1 +33,,RISIS II (includes WeVerfiy and some ELG),RISIS II (includes WeVerfiy and some ELG),,"Twin Karmakharm, David Wilby",01/01/2020,30/06/2021,Computer Science,2,1 +34,gpy,Learning to move as a human,Multiple output Gaussian processes for GPy,"Python, Gaussian processes, documentation, testing, continuous integration, MATLAB, machine learning",Robert Turner,01/10/2019,01/01/2021,Computer Science,1,1 +40,jade2,JADE II Support,JADE II Support,"deep learning, HPC, teaching, user support, machine learning","Anna Krystalli, Twin Karmakharm",01/02/2020,01/08/2021,IT Services,2,1 +45,basisflow,BasisFlow,BasisFlow,,Twin Karmakharm,01/01/2021,31/12/2023,Chemistry,2,1 +53,ramp,RAMP SCRC Covid Support,RAMP SCRC Covid Support,"Python, agile, testing, continuous integration, documentation",Robert Turner,01/05/2020,01/08/2020,Computer Science,2,1 +55,,IFPRI,IFPRI,,David Wilby,01/07/2020,01/08/2020,Computer Science,2,1 +56,,Opening Up Minds,Opening Up Minds,,Anna Krystalli,18/01/2021,18/06/2021,Psychology,2,1 +57,floodfotm,Flood Modelling Festival of the Mind,Flood Modelling Festival of the Mind,"GPU, unreal engine, FLAME GPU","Matt Leach, Paul Richmond",01/07/2020,01/09/2020,Civil Engineering,2,1 +58,ratesetter,RateSetter / Merseyrail,RateSetter / Merseyrail,"C++, FLAME GPU, ABM",Twin Karmakharm,18/11/2019,01/12/2020,Mechanical Engineering,2,1 +64,scrc-pipeline,SCRC Follow on,Covid epidemiology data pipeline,"Python, agile, testing, continuous integration, documentation",Robert Turner,01/01/2021,01/01/2022,External,1,1 +65,holeintheroad,Hole in the Road,Hole in the Road,"VR, Unity",Matt Leach,24/09/2020,13/10/2020,Computer Science,1,1 +71,,JBC: Data and Data Science,JBC: Data and Data Science,,"David Jones, David Wilby",01/01/2021,01/07/2021,Department of Health and Social Care,2,1 +75,airqo,AirQo: Air Quality (Google),AirQo: Kampala Air Quality,"Python, Scrum, testing, machine learning, Gaussian processes, containers, cloud, continuous integration",Robert Turner,01/03/2021,01/09/2021,Computer Science,1,1 +78,,Rail Transport,Rail Transport,,"John Charlton, Peter Heywood",29/01/2021,28/11/2021,Mechanical Engineering,2,1 +79,rumour_veracity, Rumour Veracity, Rumour Veracity,"NLP, deep learning, social media, Python, Javascript, Django, Vue.js, full stack, machine learning","Twin Karmakharm, David Wilby",01/01/2019,30/06/2021,Computer Science,2,1 +,firstdraftcoviddash,FirstDraft × GATE COVID Dashboard,FirstDraft × GATE COVID Data Deficits Dashboard,"Python, Django, Vue.js, Javascript, web apps, elasticsearch, PostgreSQL, databases","David Wilby, Twin Karmakharm",01/06/2020,31/07/2020,Computer Science,1,1 diff --git a/_events/event-2021-06-16-RIT-image.md b/_events/event-2021-06-16-RIT-image.md new file mode 100644 index 00000000..0c89c29f --- /dev/null +++ b/_events/event-2021-06-16-RIT-image.md @@ -0,0 +1,14 @@ +--- +title: Image processing techniques and technology +tags: +permalink: /training/workshop/2021-06-16-RIT-image +date: 2021-06-16 +from: "09:30" +to: "12:15" +location: "Online" +institute: "Research IT" +--- + +The theme is image processing with a focus on research experiences in processing digital images. As well as presenting an overview of the research topic, presentations will consider different aspects of image processing. For example image generation, image comparison, image transformations, extracting data from images, image classification or image segmentation. + +See the [eventbrite page](https://www.eventbrite.co.uk/e/research-it-forum-tickets-154417568103) for more details and registration. diff --git a/_events/event-2021-11-17-library-opensource.md b/_events/event-2021-11-17-library-opensource.md new file mode 100644 index 00000000..c6173f31 --- /dev/null +++ b/_events/event-2021-11-17-library-opensource.md @@ -0,0 +1,16 @@ +--- +title: Open Research Conversation - Open Source Licensing +tags: +permalink: /training/workshop/2021-11-17-library-opensource +date: 2021-11-17 +from: "12:00" +to: "13:00" +location: "Online" +institute: "Scholarly Communications Team (Library)" +--- + +Sharing software is a key part of open research, but the licensing issues presented by open source are different to those for other outputs. + +This event will include talks by Tom Stafford, Psychology and University Research Practice Lead, and Bob Turner, Research Software Engineer. + +[Sign up here with Eventbrite](https://www.eventbrite.co.uk/e/open-research-conversation-open-source-licensing-tickets-178653927707) \ No newline at end of file diff --git a/_events/event-2021-11-18-ReproHack-hub-launch.md b/_events/event-2021-11-18-ReproHack-hub-launch.md new file mode 100644 index 00000000..3551006a --- /dev/null +++ b/_events/event-2021-11-18-ReproHack-hub-launch.md @@ -0,0 +1,35 @@ +--- +title: ReproHack Hub Launch +tags: +permalink: /training/workshop/2021-11-18-ReproHack-hub-launch +date: 2021-11-18 +from: "10:00" +to: "17:00" +location: "Online" +institute: "ReproHack Core Team - N8 CIR - Sheffield RSE" +--- + +#### **For all those interested in reproducibility and code review!** + +The ReproHack core team, in collaboration with the [N8 Centre of Excellence in Computationally Intensive Research](https://n8cir.org.uk/) and Sheffield Research Software Engineering are thrilled to invite you to celebrate with us on November 18th 2021 the launch of our ReproHack Hub! + +#### [reprohack.org/](https://reprohack.org/) + +Reprohacks are one day hackathons providing a sandbox environment for practicing reproducible research. Authors submit papers with associated code and data for review. During events, participants attempt to reproduce submitted papers of their choice and feed back their experiences to authors by completing a review form. We spend time sharing and learning from the experiences of participants in the group and informal peer-to-peer training sessions often emerge! e.g. we’ve had impromptu Docker (container) school, live demos of publishing code to Zenodo and mentored contributions to open source projects. + +There will also be two short talks: +- Dr. [Esther Plomp](https://www.tudelft.nl/en/library/research-data-management/r/support/data-stewardship/contact/esther-plomp), TU Delft, will introduce the [Turing Way community](https://the-turing-way.netlify.app/welcome), a great resource to continue learning on these topics. +- Prof. [Stephen Eglen](https://sje30.github.io/), Cambridge University will introduce the [CodeCheck](https://codecheck.org.uk/) project, an initiative working towards integrating reproducibility checks into the scholarly communication process. + +So if you would like friendly review on the reproducibility of the code and data associated with a paper, submit it to our ReproHack Hub [paper list](https://reprohack.org/paper/). + +If you want to get practical experience in reproducibility by working with other people’s materials, [join us on the day](https://www.reprohack.org/event/11/). + +We hope to see you there! + + + diff --git a/_events/event-2022-10-25-code_cafe.md b/_events/event-2022-10-25-code_cafe.md new file mode 100644 index 00000000..21a77252 --- /dev/null +++ b/_events/event-2022-10-25-code_cafe.md @@ -0,0 +1,16 @@ +--- +title: Code Café +tags: +date: 2022-10-25 +from: "14:00" +to: "15:00" +location: "University of Sheffield Student Union View Café / Room 1" +--- + +I've set this up as a bit of an experiment. I've booked a very small room (6 people) adjacent to the View Café in the student union. The idea is that anyone can come and chat about research code and related things. I wanted a space that was "neutral" i.e. not in a specific department or professional services building. But I also wanted people to be able to identify others to chat to - hence the little room. Hopefully this is a scalable way of doing things and if it works, we can do more. + +Drinks and snacks can be bought from View Café. + +All University of Sheffield people involved with research welcome. + +
Coffee and laptop
diff --git a/_events/gpucourse-2022-02-07.md b/_events/gpucourse-2022-02-07.md new file mode 100644 index 00000000..a5b682e4 --- /dev/null +++ b/_events/gpucourse-2022-02-07.md @@ -0,0 +1,31 @@ +--- +title: "Parallel Computing with GPUs" +category: training +tags: parallel, cuda, GPUs, OpenMP +permalink: /training/workshop/2022-02-07-gpu-course +date: 2022-02-07 +from: "Spring Semester Week 1" +to: "Week 12" +location: "In Person" +speaker: "Paul Richmond" +--- + +## 12 Week Parallel Computing with GPUs course + +Starting this term (Feb) is a 12 week course on "Parallel Computing with GPUs". The course has been designed as an undergraduate 4th year (and MSc) module for Computer Science but is available to staff and PhD Students (as part of the DDP program) and regularly has staff and PhD student enrolment. + +The first 3 weeks are focused on teaching C and OpenMP followed by GPU programming with CUDA C. Lectures are provided as pre-recorded mini lectures and there are 2 hours of scheduled support per week to undertake practical lab classes. Assessment is not required for DDP or staff participants. You can attend all or just parts of the course. + +If you are interested in enrolling as staff or a PhD student then please express you interest on the following google form: [bit.ly/GPU2022](bit.ly/GPU2022) + +If you are interested in joining after the start of week one then please contact [Paul Richmond](https://paulrichmond.shef.ac.uk/) directly. + +**Prerequisite skills:** Some programming experience. + +**Learning Objectives** +* Compare and contrast parallel computing architectures +* Implement programs for GPUs and multicore architectures +* Apply benchmarking and profiling to GPU programs to understand performance +* Identify and address limiting factors and apply optimisation to improve code performance + +This course will be run in person but recordings of lectures will be availble for self paced learning. diff --git a/_events/lunchbytes-2021-04-01.md b/_events/lunchbytes-2021-04-01.md index e56c8829..1d3e2fcb 100644 --- a/_events/lunchbytes-2021-04-01.md +++ b/_events/lunchbytes-2021-04-01.md @@ -20,7 +20,7 @@ This session will take place on [Google Meet](https://meet.google.com/sqk-bdmi-t We also have a [Google Jam Board](https://jamboard.google.com/d/1Z6kZfJIabiWX31KgtEl6yoCo1Tlb4cRXgxUuFyqozEM/edit?usp=sharing) where you can note down any questions or comments before or during the event. -The slides for each talk will be made available after the event. +- [Video of the event](https://digitalmedia.sheffield.ac.uk/media/Lunch%20bytes%205%20Making%20GPU%20Programming%20More%20Portable/1_lldycy2n) ## Talk 1: PyFR: Facilitating Heterogeneous GPU Computing from a Homogeneous Codebase diff --git a/_events/lunchbytes-2021-05-12.md b/_events/lunchbytes-2021-05-12.md index 71c3bd12..4a71497f 100644 --- a/_events/lunchbytes-2021-05-12.md +++ b/_events/lunchbytes-2021-05-12.md @@ -5,13 +5,28 @@ published: True from: "12:00" to: "13:00" location: "Google Meet" -speaker: "TBD" +speaker: "Dr Anna Krystalli" institute: -title: "Lunch bytes: Good practise in R" +title: "Lunch bytes: Putting the R into Reproducible Research" image: redirect_from: - /events/LunchBytes-2021-05-12.html slides_url: --- -Short talks on how to achieve better practise in `R`. More information coming soon! +R and its ecosystem of packages offers a wide variety of statistical and graphical techniques and is increasing in popularity as the tool of choice for data analysis in academia. +In addition to its powerful analytical features, the R ecosystem provides a large number of tools and conventions to help support more open, robust and reproducible research. This includes tools for managing research projects, building robust analysis workflows, documenting data and code, testing code and disseminating and sharing analyses. +In this talk we’ll take a whistle-stop tour of the breadth of available tools, demonstrating the ways R and the Rstudio integrated development environment can be used to underpin more open reproducible research and facilitate best practice + +This talk will be approximately 45 minutes, leaving 15 minutes for questions/discussion. + +This session will take place on [Google Meet](https://meet.google.com/dft-xnvj-fmn) and participants can join 15 minutes before the start of the session. +- [Video of the event](https://digitalmedia.sheffield.ac.uk/media/Lunch+bytes+6A+Putting+the+R+into+Reproducible+Research/1_kwofatj6) +- [Slides of the event](http://bit.ly/r-in-repro-research-dc-srse) + + +We also have a [Google Jam Board](https://jamboard.google.com/d/1WLdKli_Lpm96tCTYHt63jLUf_xbTlubbpobphPR44Hk/edit?usp=sharing) where you can note down any questions or comments before or during the event. + +### Speaker Bio + +Anna is a Research Software Engineer (RSE) at the University of Sheffield with a background in Marine Macroecology and research software development in R. She is part of a team of RSEs working to help researchers build more robust analysis pipelines and software, promote best practice in research programming and digital resource management and facilitate the shift to more open, transparent and collaborative research culture. She is also an editor for rOpenSci, a 2019 Software Sustainability Institute Fellow and a member of the ReproHack core team. Overall, her passion lies in helping researchers and the research community as a whole make better use of the real workhorses of research, code and data, and in spreading the word about the joys of R. diff --git a/_events/lunchbytes-2021-06-09.md b/_events/lunchbytes-2021-06-09.md new file mode 100644 index 00000000..e8d77dba --- /dev/null +++ b/_events/lunchbytes-2021-06-09.md @@ -0,0 +1,26 @@ +--- +category: lunchbytes +date: 2021-06-09 +published: True +from: "12:00" +to: "13:00" +location: "Google Meet" +speaker: "Anna Krystalli, Farah Shahi, Nyashadzaishe Mafirakureva, Richard Simmonds" +institute: +title: "Lunch bytes: Clinical Research Software" +image: +redirect_from: + - /events/LunchBytes-2021-06-09.html +slides_url: +--- + + + +Short talks on how University of Sheffield researchers and RSEs, and collaborators worldwide, are using [REDCap](https://www.project-redcap.org/) and other platforms to handle clinical research data. The clinical research we will focus on here relates gathering data on people (e.g. evaluating interventions) rather than more fundamental laboratory research. + +- [**REDCap features, setup and maintenance**](https://docs.google.com/presentation/d/e/2PACX-1vSAWAtWiWC-qeGkK_YPNd7IdG7IbP0wWm_chAm-9th9CeNUfatcachw0U_vRl4CSSgMQRWgc1fESM_R/pub?start=true&loop=true&delayms=3000&slide=id.p) Anna Krystalli +- [**Transcriptomic Responses for the Identification of Pathogens**](https://drive.google.com/file/d/1EKjA4k_gs4cPsG5RFqx7gO1fNckSlxbk/view?usp=sharing) Farah Shahi +- **Using REDCap to capture the economic impact on households of seeking care for children sick with, or exposed to, tuberculosis in three sub-Saharan African countries** Nyasha Mafirakureva +- [**Using REDCap alongside an existing Electronic Data Capture (EDC) system: Fitting in with existing processes and comparing functionality between systems**](https://docs.google.com/presentation/d/1xWrkiYlv9AHTxwk0k-M9RJmDSFqW-sc6/view?usp=sharing) Richard Simmonds + +We also have a [Google Jam Board](https://jamboard.google.com/d/11UY6-HkAjMzG9RbxH8aE-7hjl4dD4mnFMW1XMxoQS94) where you can note down any questions or comments before or during the event. diff --git a/_events/lunchbytes-2021-07-05.md b/_events/lunchbytes-2021-07-05.md new file mode 100644 index 00000000..6fbc0186 --- /dev/null +++ b/_events/lunchbytes-2021-07-05.md @@ -0,0 +1,34 @@ +--- +category: lunchbytes +date: 2021-07-05 +published: True +from: "12:00" +to: "13:00" +location: "Google Meet" +speaker: "Andrei Paleyes" +institute: +title: "Lunch bytes: Challenges in Deploying Machine Learning, or What is rarely talked about at ML conferences." +image: +redirect_from: + - /events/LunchBytes-2021-07-05.html +slides_url: +--- + + + +### Abstract +In addition to being a thriving academic discipline, machine learning is increasingly adopted as a solution to real world business problems. But underneath this seeming success lies a chasm of failures. In fact, according to recent surveys among industry practitioners, the majority of ML projects still fail. It turns out that deployment workflow of ML is far from trivial, and adds a pile of its own challenges on top of those that already exist in software development practice. In this talk we will follow the steps of the ML deployment process, talk about issues people face at each step, and touch upon possible solutions. + +The talk is based on this [paper](https://arxiv.org/abs/2011.09926), reading it before the talk isn't required. + +This talk will be approximately 45 minutes, leaving 15 minutes for questions/discussion. + +This session will take place on [Google Meet](https://meet.google.com/kxv-nvyh-cbt) and participants can join 15 minutes before the start of the session. +- [Video of the event](https://digitalmedia.sheffield.ac.uk/media/Lunch+bytes+8A+Challenges+in+Deploying+Machine+Learning/1_1q0mq7do) + + + +We also have a [Google Jam Board](https://jamboard.google.com/d/1pSGFJSjkKZd1jejTQrFP2Tro5Bllioto2Z68NjjOXbM/edit?usp=sharing) where you can note down any questions or comments before or during the event. + +### Speaker Bio +Andrei is a PhD student in the [ML@CL](https://mlatcl.github.io/jekyll/update/2020/02/03/machine-learning-at-the-computer-lab.html) group led by [Prof. Neil Lawrence](https://inverseprobability.com/). He is interested in machine learning deployment and how it can be improved with better software systems. Before starting his PhD journey Andrei was developing software for a decade, working on everything from web applications to data center infrastructure to ML applications. diff --git a/_events/lunchbytes-2021-09-15.md b/_events/lunchbytes-2021-09-15.md new file mode 100644 index 00000000..f3db198e --- /dev/null +++ b/_events/lunchbytes-2021-09-15.md @@ -0,0 +1,32 @@ +--- +category: lunchbytes +date: 2021-09-15 +published: True +from: "12:00" +to: "13:00" +location: "Zoom" +speaker: "Matt Williams (Bristol), Simon Li (Dundee), James Graham (Southampton/SSI)" +institute: +title: "LunchBytes × SeptembRSE Special: Python Virtual Environment Showdown" +image: +slides_url: +--- + +To coincide with this year's online RSE conference, [SeptembRSE](https://septembrse.society-rse.org/registration/), LunchBytes will be "colocating" on Zoom as part of the conference programme. All are welcome whether or not you're attending the conference, or at The University of Sheffield, so tell your friends! + +This month's topic will be a showdown between some of the different options for managing virtual environments when working with Python. Will `Conda` come out on top? Or will the favourite be `venv` or `Poetry`? + +Python is one of the most popular languages for research computing and virtual environments are a valuable method for managing dependencies within a project and ensuring a reproducible environment. There are lots of options around for virtual environment management in Python, in this special LunchBytes we'll be exploring the pros and cons of some of them with help from members of the research software engineering community. + +## Speakers +[Introductory and closing slides](/lunchbytes_sep_2021) +* Matt Williams (Bristol) - `venv` - [slides](https://drive.google.com/file/d/1EmF3_GSOlM7J9mzPyoylN6_-Mr2qiIv_/view?usp=sharing) +* Simon Li (Dundee) - `conda` - [slides](https://www.manicstreetpreacher.co.uk/septembrse-2021-python-conda/) +* James Graham (Southampton/SSI) - `poetry` (see [video](https://youtu.be/POI3Fn157pY?t=1189) for live demo) + +## Video + + +## Joining instructions +Please sign up for the event ahead of time at [this link](https://www.eventbrite.co.uk/e/lunchbytes-septembrse-special-python-virtual-environment-showdown-tickets-170150369335) +The zoom link will be shared shortly before the event begins. \ No newline at end of file diff --git a/_events/lunchbytes-2021-10-13.md b/_events/lunchbytes-2021-10-13.md new file mode 100644 index 00000000..c5b3b5e7 --- /dev/null +++ b/_events/lunchbytes-2021-10-13.md @@ -0,0 +1,55 @@ +--- +category: lunchbytes +date: 2021-10-13 +published: True +from: "12:00" +to: "13:00" +location: "Google Meet" +speaker: "Gemma Ives (host, University of Sheffield), Mike Croucher (Mathworks), Tim Rogers (University of Sheffield), Fred Sonnenwald (University of Sheffield)" +institute: +title: "LunchBytes: Better MATLAB, Better Research" +image: +redirect_from: + - /events/LunchBytes-2021-10-13.html +slides_url: +--- + + + +Short talks on how University of Sheffield researchers are using Matlab features old and new, straightforward and complex. A chance to get perspectives from researchers and from MathWorks, and to discuss Matlab in the research software ecosystem. + +This session will take place on [Google Meet](https://meet.google.com/jde-tgwa-hru) and participants can join 15 minutes before the start of the session. [Add to your calendar.](https://calendar.google.com/event?action=TEMPLATE&tmeid=NTUwZDlwdDlubTc1bGg1OG1oYzRrOXJ1b3Ugci5kLnR1cm5lckBzaGVmZmllbGQuYWMudWs&tmsrc=r.d.turner%40sheffield.ac.uk) + +We also have a [Google Jam Board](https://jamboard.google.com/d/1O9NVU0p3zU9yStNghyPlT7prWxa0A_mPMCSHJYVFj6U) where you can note down any questions or comments before or during the event. + +--- + +**What's neat about using the MATLAB IDE for research (and teaching)** + +*Fred Sonnenwald* + +MATLAB tightly integrates its command window, editor, debugger, profiler, and live scripts into an Integrated Development Environment (IDE) in a way uncommon for interpreted languages. This short talk will go over these features and provide some examples of how I've used them to aid in research (and teaching). + +[Slides](/assets/slides/2121-10-13_LB_MATLAB/LunchBytes 13 October 2021 Fred Sonnenwald v1.1.pptx) + +--- + +**MATLAB Live Editor Tasks: The art of programming without programming** + +*Mike Croucher* + +Some researchers prefer to analyse their data using easy to use Graphical User Interfaces while others insist that coding is the only way to ensure reproducible, reusable and correct computational research. + +Why choose when you can have both with MATLAB Live Editor tasks? + +[Slides and code](/assets/slides/2121-10-13_LB_MATLAB/Sheffield_Lunch_Croucher.zip) + +--- + +**Writing Object Oriented MATLAB For Parallel Compute: Challenges and Successes** + +*Tim Rogers* + +For a large number of algorithms the computation can be broken down into independent blocks which have a self-contained set of attributes and methods, for example, it may be necessary to run multiple instances of an algorithm with different parameters. To improve modularity, reusability and reproducibility it can be beneficial to define an 'object' which packages these blocks. Formally, this is called an OOP approach to writing code (although the brief definition here is not complete). Despite being a popular approach in other languages, most notably Python, it is not widely employed within MATLAB where more commonly a functional programming model is used. This talk will show an example of one algorithm where an OOP model greatly improves the readability and useability of the code base by defining objects which can be used as building blocks of more complicated algorithms. The task of system identification using an Iterated Batch Importance Sampling algorithm will be used as a demonstration. A particular focus of the talk will be on how MATLAB objects can be written such that they are amenable for use within parallel compute structures provided by MATLAB, such as 'parfor' loops, for which there are some specific challenges. + +[Slides](/assets/slides/2121-10-13_LB_MATLAB/lunchbytes_parallel_classes_TR.pdf) diff --git a/_events/lunchbytes-2022-02-17.md b/_events/lunchbytes-2022-02-17.md new file mode 100644 index 00000000..16015e4b --- /dev/null +++ b/_events/lunchbytes-2022-02-17.md @@ -0,0 +1,47 @@ +--- +category: lunchbytes +date: 2022-02-17 +published: True +from: "12:00" +to: "13:00" +location: "Google Meet" +speaker: "Twin Karmakharm (University of Sheffield), Peter Heywood (University of Sheffield)" +institute: +title: "LunchBytes: High Performance Computing (HPC) at Sheffield and Beyond" +image: +slides_url: +--- + +If you find yourself running simulations that take days, struggling to fit datasets in your computer's memory, training deep +learning models or wish you had more computational resource for doing research, HPC might be the solution! + +A High Performance Computing (HPC) Cluster is a network of computers with a lot of CPUs, RAM and hard disk space. At +Sheffield, we offer access to many HPC systems locally and externally which are free at point of use to all researchers +and academics. + +This session will take place on [Google Meet](https://meet.google.com/uzu-jfvm-fqv) and participants can join 15 minutes before the start of the session. + +We also have a [Google Jam Board](https://jamboard.google.com/d/1DYU0QM5RdJF5c-jtsRqwKQM8cAMgiUVvt_4_d9_aBNw/edit?usp=sharing) where you can note down any questions or comments before or during the event. + +#### HPC at Sheffield and Beyond: Overview + +Speaker: *Twin Karmakharm* + +This talk gives an overview of what a HPC is, what it's used for, why you'd want to use it and the systems available to +Sheffield researchers and academics. + +[Slides](https://rse.shef.ac.uk/uos-hpc-resources-presentation) + +#### HPC Beyond Sheffield: JADE and Bede + +Speaker: *Peter Heywood* + +Alongside the local HPC facilities at The University of Sheffield, researchers can also access regional Tier-2 HPC facilities in the UK. +This talk will describe the Tier-2 HPC systems available to TUoS researchers, why using Tier-2 HPC can be beneficial and how these systems can be accessed and used. +There will be a focus on the JADE and Bede GPU-based Tier 2 systems which TUoS is affiliated with. + +[Slides](https://rse.shef.ac.uk/hpc-beyond-sheffield-jade-and-bede-presentation) + +#### Video + +
\ No newline at end of file diff --git a/_events/lunchbytes-2022-03-17.md b/_events/lunchbytes-2022-03-17.md new file mode 100644 index 00000000..55a9c84e --- /dev/null +++ b/_events/lunchbytes-2022-03-17.md @@ -0,0 +1,37 @@ +--- +category: lunchbytes +date: 2022-03-17 +published: True +from: "12:00" +to: "13:00" +location: "Google Meet" +speaker: "Christos Anastopoulos (University of Sheffield), Mark C Hodgkinson (University of Sheffield)" +institute: +title: "Software engineering in High Energy / Particle Physics" +image: +slides_url: +--- + +This session will take place on [Google Meet](https://meet.google.com/unb-cjmh-sus) and participants can join 15 minutes before the start of the session. + +We also have a [Google Jam Board](https://jamboard.google.com/d/1KTbvVzwqINY-qMfNAmiUUs8QTPSJogdatDO3MEB-djU) where you can note down any questions or comments before or during the event. + +## Migrating 4 million lines of C++ code to multi threading + +**Christos Anastopoulos** + +The Atlas collaboration had to migrate its production software to run in a multi threaded environment. This necessitated a significant refactoring of the relevant code base. This effort would be practically impossible without employing gitlab, code review , unit test, integration tests inside the git pipeline, and regular larger scale tests continuously stressing the code base. The talk will attempt to describe how these are used inside the ATLAS collaboration and how they helped to achieve migrating to code base to successfully run in MT. + +[Slides](/assets/slides/2022-03-17-lb-hep/ATLAS_4M_MT.pdf) + +## A new era of computing at the Large Hadron Collider + +**Mark C Hodgkinson** + +The Large Hadron Collider will enter a new era of "high luminosity" in the late 2020's which will entail higher data rates, as well as more complex data to analyse. New software solutions may be required beyond the current CPU based multi-threading paradigm in use in LHC experiments. I will discuss current efforts to study alternate approaches such as offloading code to GPU and machine learning based data analysis, which may bring the required resource and physics performance improvements. I also also briefly discuss software training programs in usage in the particle physics community. These are important to provide skills to new people for existing work (c++, python etc) and new approaches in the future (GPU etc). + +[Slides](/assets/slides/2022-03-17-lb-hep/LunchBytes_mhodgkin_2022.pdf) + +## Video + + diff --git a/_events/lunchbytes-2022-05-19.md b/_events/lunchbytes-2022-05-19.md new file mode 100644 index 00000000..c6bfaaec --- /dev/null +++ b/_events/lunchbytes-2022-05-19.md @@ -0,0 +1,43 @@ +--- +category: lunchbytes +date: 2022-05-19 +published: True +from: "12:00" +to: "13:00" +location: "Google Meet" +speaker: "RSE Community" +institute: +title: "LunchBytes: Handy tools for git(s) - live demo round table" +image: +slides_url: +--- + + +In this edition of LunchBytes, we'll be getting together to show off our favourite tools that help with using _git_ and _GitHub_ + +Think: command line tools, IDE plugins, GitHub/Lab features etc. + + +![](https://assets.website-files.com/6167686a04de0ebe0681d0c4/620193f40010d74e1b1aabfc_gitsave-300x2101.png) + + +# Speakers + +Host slides: [here](/lunchbytes-may-2022/) + +* Will Furnass - [bash git prompt](https://github.com/magicmonty/bash-git-prompt) +* Neil Shephard - [Magit!](https://magit.vc/) +* David Wilby - [GitHub Command Line Tool](https://github.com/cli/cli) +* David Wilby (again) - [GitHub Suggestions](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/reviewing-changes-in-pull-requests/incorporating-feedback-in-your-pull-request) +* David Wilby (*again*) - [GitKraken Client](https://www.gitkraken.com/) +* Bob Turner - [VS Code](https://code.visualstudio.com/docs/editor/versioncontrol) +* Joe Heffer - [PyCharm](https://www.jetbrains.com/help/pycharm/using-git-integration.html) +* Mark Dunning - [RStudio](https://www.rstudio.com/) + +# Video Recording + +
+ +# Blog post +We've also put together a blog post containing the tools described. [Find it here!](/blog/2022-08-18-git-tools) + diff --git a/_events/lunchbytes-2022-07-21.md b/_events/lunchbytes-2022-07-21.md new file mode 100644 index 00000000..992021db --- /dev/null +++ b/_events/lunchbytes-2022-07-21.md @@ -0,0 +1,59 @@ +--- +category: lunchbytes +date: 2022-07-21 +published: True +from: "13:30" +to: "14:30" +location: "Google Meet" +speaker: "Will Furnass, Magda Dabrowska, Ian Sudbery, Joe Heffer" +institute: +title: "LunchBytes: Workflow Managers" +image: +slides_url: +--- + +Scientific workflows (for example in bioinformatics) often require several different scripts or pieces of software to be run and their outputs fed into each other. Ideally, we'd like to be able to understand the provenance of the output, without having to re-run the entire workflow every time a minor change is made to code or data. This is often difficult to achieve with bash or Python scripts (for example), but workflow managers can help. + +In this session we will learn more about the problems of controlling workflows / pipelines using scripts, and about what workflow managers are, and how they can help. + +### Video + + + +### The trouble with scripts (Will Furnass) + +Scripts let us chain together several bits of software, often taking the output of one and feeding it into another and/or running the same software repeatedly with different inputs. This is often far better than entering commands into a prompt and then having to remember those commands and their sequence when doing the same job again. + +However, glueing together the parts of a multi-step or multi-input workflow using scripts can be difficult: it's all too easy to create scripts that aren't portable between machines/systems, are brittle/unreliable, are difficult to read and test and aren't modular or reusable. + +For which cases are scripts a good way of running a workflow and for which might they be problematic? + +[Slides for "The trouble with scripts (Will Furnass)"](/assets/slides/2022-07-21-workflow-lb/LunchBytes%202022-07-21_%20the%20trouble%20with%20scripts_%20motivation%20for%20.pdf) + +### Nextflow (Magda Dabrowska) + +[Nextflow](https://www.nextflow.io/) is a relatively new workflow manager which allows for writing scalable computational pipelines. It is based on Java and written in written in '[Groovy](https://groovy-lang.org/)' (a programming language which compiles to Java byte code), however it provides a multitude of tools and template scripts to allow for a quick and easy access to typical workflows, without the need to learn its programming language. Major advantages of Nextflow are: + +- Support for execution on multiple platforms without the need to tailor your script. +- High portability with the support for executors used within the UoS HPC systems: SGE and SLURM. +- Easy project reproducibility with the support for containers such as Docker, Conda and Singularity. +- Effortless parallelism implicitly defined by workflow inputs and outputs. +- Ability to resume the execution from the last successful checkpoint. + +[Slides for Nextflow (Magda Dabrowska)](/assets/slides/2022-07-21-workflow-lb/Nextflow.pptx) + +### Ruffus (Ian Sudbery) + +[Ruffus](http://www.ruffus.org.uk/) is one of the oldest of the modern style workflow management systems. Ruffus pipelines consist of a series of python functions that are linked together using a python feature known as decorators. Ruffus is a lighter weight alternative to systems such as Nextflow, while still offering the ability to create rich dependency graphs of tasks and orchestrate their submission to an HPC. It embodies the philosophy that for users to choose to use a reproducible pipeline in the real world, when under pressure, using a pipeline must be as easy, or easier, than the manual alternative. In my talk I will demonstrate the creation of a pipeline for a bioinformatics task consisting of multiple non-trival steps within 15 minutes. + +### Common Workflow Language (Joe Heffer) + +[Common Workflow Language](https://www.commonwl.org/) (CWL) is an open standard for describing how to run command line tools and connect them to create workflows. + +The CWL standard is not specific to any language or technology, so enables interoperability between the many different workflow languages, enabling researchers to share workflows. It's more abstract than any particular language implementation, aiming to support a super-set of the features of other languages. CWL allows portability across these systems because the logical/computational parts of a workflow are decoupled from the code that runs them. + +[Slides for Common Workflow Language (Joe Heffer)](/assets/slides/2022-07-21-workflow-lb/Workflow%20managers%20for%20research%20IT.pdf) + +### Questions (Jamboard) + +We have a [Google Jam Board](https://jamboard.google.com/d/1c0DdvFEHmAVD7c5LYPLqWa5X9Q6kYecnic6eyqIW8V4) where questions were fielded. diff --git a/_events/lunchbytes-2022-10-20.md b/_events/lunchbytes-2022-10-20.md new file mode 100644 index 00000000..4eb4033e --- /dev/null +++ b/_events/lunchbytes-2022-10-20.md @@ -0,0 +1,33 @@ +--- +category: lunchbytes +date: 2022-10-20 +published: True +from: "12:30" +to: "13:30" +location: "Google Meet" +speaker: "Dr Ilse Daly" +institute: +title: "LunchBytes: From Eyes to Apps" +image: +slides_url: +--- + +### Abstract + +Our speaker this month was Dr Ilse Daly who told us about her journey from vision scientist to start-up founder at her company Blackdog Biomechanics. + + + +*I've had a varied academic career, going from a Physics undergraduate to an Ecology of Vision PhD where I specialised in tracking and understanding the weird and wonderful eyes of the mantis shrimp. Mantis shrimp have 12 distinct colour receptors (we have 3), can see 2 types of polarized light (we see none) and can move their eyes independently in three rotational planes. Building a bespoke mantis shrimp eye tracker was an *"interesting"* task, which put me on the path to becoming a software developer. However, there's a pretty big gulf between being a true software developer and someone who just writes MATLAB code to track shrimp eyes!* + +*As my academic career went on, I realised two things 1) academia wasn't really for me and 2) the computer vision techniques I'd been learning could be used for a lot of useful stuff. So I started tinkering on the side - in the evenings and at weekends and I eventually fell into app development, which in turn led to me to starting my own business; BLACKDOG biomechanics.* + +*Sounds easy right: have an idea, write the app, sell the app... Turns out that's not entirely how it works, as I'll show in this talk.* + +![](https://upload.wikimedia.org/wikipedia/commons/thumb/1/1e/Odontodactylus_scyllarus_R%C3%A9union.jpg/640px-Odontodactylus_scyllarus_R%C3%A9union.jpg) + +Image: Cédric Péneau via [Wikimedia](https://commons.wikimedia.org/wiki/File:Odontodactylus_scyllarus_R%C3%A9union.jpg) + +
\ No newline at end of file diff --git a/_events/lunchbytes-2022-11-24.md b/_events/lunchbytes-2022-11-24.md new file mode 100644 index 00000000..e3d87570 --- /dev/null +++ b/_events/lunchbytes-2022-11-24.md @@ -0,0 +1,42 @@ +--- +category: lunchbytes +date: 2022-11-24 +published: True +from: "12:00" +to: "13:00" +location: "Google Meet" +speaker: "Emma Norling, Shangshang Gu, Ashley Cadby, Norbert Gyenge, Bob Turner" +institute: +title: "LunchBytes Panel: Teaching Code" +image: +slides_url: +--- + +As code and software become an ever bigger part of research (its likely that [around 1/3 of researchers write code](https://rse.shef.ac.uk/sssurvey/)), coding and other digital skills become ever more important to researchers. + + + +In this online panel discussion, we will explore this with a few questions like these: + +- How do you teach code e.g. lectures, live-coding, lab classes? What works well for you? +- Is there a difference between "teaching" and "training" in this context? +- When is the best time in a career to start learning to code? +- I'm a new (student / researcher / lecturer / professor). How do I start learning to code? +- Is writing code an essential skill for quantitative researchers? What are the implications for teaching / training? +- What tips do you have to help others teach better? +- Can the way we train people to code help make software engineering more inclusive and diverse? + +There may also be time for some audience questions. + +The panel includes [Emma Norling](https://www.sheffield.ac.uk/dcs/people/academic/emma-norling) (Director of Learning and Teaching in the Department of Computer Science at the University of Sheffield), [Shangshang Gu](https://www.linkedin.com/in/%E5%B0%9A%E5%B0%9A-%E9%A1%BE-89935b129) (School of Health and Related Research, University of Sheffield), [Ashley Cadby](https://www.sheffield.ac.uk/physics/people/academic/ashley-cadby) who plays a key role in teaching code in the Department of Physics and Astronomy at the University of Sheffield and [Norbert Gyenge](https://www.linkedin.com/in/norbert-g-gyenge-7ba718201) (IT Services) with expertise in shorter courses. + +### Joining Instructions +Join on Google meet at: + +By joining with a University of Sheffield google account you will be admitted automatically. + +External attendees are welcome but please read our [Code of Conduct](/community/code_of_conduct) and contact the organiser first at [r.d.turner@sheffield.ac.uk](mailto:r.d.turner@sheffield.ac.uk). + +### Questions + +We'll use sli.do for questions, link will be circulated during the event. diff --git a/_events/seminar-2021-12-02.md b/_events/seminar-2021-12-02.md new file mode 100644 index 00000000..a269e7f7 --- /dev/null +++ b/_events/seminar-2021-12-02.md @@ -0,0 +1,21 @@ +--- +category: seminar +date: 2021-12-02 +published: True + +from: "14:00" +to: "15:00" +location: "Online" +speaker: "Jens Krinke" +institute: "University College London" +title: "Toxic Code on Stack Overflow" + +image: +slides_url: +--- + +**This event is being run by the Testing Research Group** + +Software developers use Stack Overflow to interact and exchange code snippets and research uses Stack Overflow to harvest code snippets for use with recommendation systems. However, code on Stack Overflow may have quality issues, such as security or license problems. In this talk I will present our work on how users of Stack Overflow perceive such issues, how we studied the problem of outdated code and potential license violations, and how code is non-compliant with coding style. The prevalence of such toxic code may affect mining or machine learning tasks using Stack Overflow as a code base. + +Google meet link: \ No newline at end of file diff --git a/_events/seminar-2021-12-15.md b/_events/seminar-2021-12-15.md new file mode 100644 index 00000000..ecc6f480 --- /dev/null +++ b/_events/seminar-2021-12-15.md @@ -0,0 +1,25 @@ +--- +category: seminar +date: 2021-12-15 +published: True + +from: "9:30" +to: "11:30" +location: "Online" +speaker: "Various" +institute: "Research IT" +title: "Research-IT Forum: Analysing Human Language: Mining Textual Data and Natural Language Processing" + +image: +slides_url: +--- + +**This event is being run by Research IT** + +The Research-IT forum is a regular event providing updates on developments relating to research computing covering research software, computational science, data science, qualitative and quantitative analysis and the management of research outputs. It is a forum where researchers can showcase their work in an environment conducive to creative discussion. + +This event will explore data mining and natural language processing at the University. Our six speakers, from various departments, will present their specific research and the topics range from analysing social media speech to corpus analysis. + +To register, please go to: + +For more information about the event, please visit: \ No newline at end of file diff --git a/_events/talk-2021-05-21-sheffield-digital-fest.md b/_events/talk-2021-05-21-sheffield-digital-fest.md new file mode 100644 index 00000000..d03cf181 --- /dev/null +++ b/_events/talk-2021-05-21-sheffield-digital-fest.md @@ -0,0 +1,35 @@ +--- +category: seminar +date: 2021-05-21 +published: true +from: "12:30" +to: "13:50" +location: "Online" +speaker: "Will Furnass, Joe Heffer, Gemma Ives" +slides_url: +title: "The software and people behind academic research" +--- + +This event was part of the [Sheffield Digital festival](https://sheffielddigitalfestival.com/). + +The use of data and computational analysis in research is increasing and it is critical in getting new insights. But how does the code that drives this research get written? What is different about writing software in a research environment? What are the challenges around data management and infrastructure? And how can visualisation technologies make the outputs of research of greater value and interest to other researchers and the public? + +[Recording of the talks](https://digitalmedia.sheffield.ac.uk/media/The+software+and+people+behind+academic+research/1_t8io4ez6) + +#### Will Furnass, Research Software Engineer: Turning ideas into code + +Much of modern research is facilitated by code that researchers have had a hand in writing. In this first talk we explore the processes through which research ideas are encapsulated as software, which often involves interactive data exploration, then how this software evolves (or not) over time. We also discuss the computational demands of research and common technologies, before concluding with a look at challenges relating to the development of coding skills in academia, the drive for reproducible research, and how funding and incentives shape the research software lifecycle. + +[Slides](https://docs.google.com/presentation/d/1Wemj0VxZlYn6rraUR7xaa0M8gMqZOzSpxC_xXw4DIyU/) + +#### Joe Heffer, Research Data Engineer: Supporting Coronavirus Genomics + +We provided software engineering expertise for researchers from The University of Sheffield who are participating in the COVID-19 Genomics UK (COG-UK) Consortium which provides large-scale, rapid genomic sequencing to guide the public health response to the pandemic. + +[Slides](https://docs.google.com/presentation/d/1u420fMDQBC7rh4mmJUzD07eFqucHZSUrqDE0Lqzfc7k/) + +#### Gemma Ives, Research Data Scientist: Communicating Research Through Visualisation + +More and more often researchers are openly sharing their research data and their findings, encouraging engagement and scrutiny from politicians and the public. This final talk will discuss how and why data visualisation is becoming an essential skill in academic research. + +[Slides](https://docs.google.com/presentation/d/1Zo-qSLD4pf762aV1KeRnllVPp2glvSufQu_h9hiCzM8) diff --git a/_events/talk-2022-04-28-rses-info-new-people.md b/_events/talk-2022-04-28-rses-info-new-people.md new file mode 100644 index 00000000..fafd4712 --- /dev/null +++ b/_events/talk-2022-04-28-rses-info-new-people.md @@ -0,0 +1,31 @@ +--- +category: talk +date: 2022-04-28 +published: true +from: "14:30" +to: "15:00" +location: "Online" +speaker: "Bob Turner, RSE Team" +institute: "University of Sheffield" +title: "Introduction to the Research Software Engineering Team" +--- + +Google meet link: . + +This session, *aimed at people newly joining the University of Sheffield as academics*, will introduce the RSE Team. We will cover: + +* Why there is an RSE Team at the University of Sheffield: + * External drivers including UKRI focus on open and reproducible research, and high profile research software failures. + * Improving RSE careers. + * Facilitating access by research projects to software engineering skills. + * Our sustainable funding model. +* What the RSE Team does: + * Implementing good practice (e.g. testing, version control, documentation). + * Software development in Python, R, Matlab, C, etc. + * Improving software performance. + * Packaging and managing dependencies. +* How to access free at point of use help via [Code Clinics](https://goo.gl/forms/5MVy0jM6xQhWlpmn1). +* How to engage with the RSE Community. +* How to collaborate with the RSE Team on funded projects (e.g. by adding a percentage of an RSE to as grant application). + +![People collaborating around laptop](/assets/images/collab-laptop.webp) diff --git a/_events/workshop-2021-07-12-n8cir-training-hpc-genomics.md b/_events/workshop-2021-07-12-n8cir-training-hpc-genomics.md new file mode 100644 index 00000000..9fac0f01 --- /dev/null +++ b/_events/workshop-2021-07-12-n8cir-training-hpc-genomics.md @@ -0,0 +1,58 @@ +--- +title: "High Performance Computing for Healthcare (day 1)" +category: training +tags: HPC, genomics, shell +permalink: /training/workshop/2021-07-12-n8cir-training-hpc-genomics +date: 2021-07-12 +from: "09:00" +to: "17:00" +location: "Online" +speaker: "Will Furnass, Mark Dunning" +--- + +This workshop is being +funded by the [N8 Centre for Computationally-Intensive Research (N8 CIR)](https://n8cir.org.uk/events/hpc-healthcare/), +is being organised by the N8 CIR and TUOS and +is being delivered by TUOS' RSE team and TUOS' Bioinformatics Core. + +#### Dates + +This workshop takes place over two days, 12 July and 14 July. Please only register if you will be able to attend both sessions if your application is successful. + +#### Overview +High Performance Computing (HPC) is an increasingly important tool utilised by researchers, helping to overcome the limitations processing parallelism and memory found in even the most powerful desktop systems. With more computing power available researchers can perform more and bigger experiments leading to improved accuracy and better research outcomes. A further benefit is that HPC systems require researchers to define their workflow as jobs, which aids reproducibility. + +However, making use of an HPC system, whether on-premise or in the cloud, isn’t as simple as just logging on and firing up the software. HPC users must be able to log in to remote computers using the bash shell, upload data and install software before they can begin to conduct experiments. Even the code may need to be adapted to run in parallel and maximise the benefits of HPC platforms. + +For these reasons, many researchers shy away from adding HPC to their research toolkit. + +This two-day workshop is intended to remove some of the mystery from HPC systems, making it easier for researchers to access them and accelerate their research. The material in this course will be healthcare-related using an omics data analysis. Participants will be given a set of sequencing reads from a next-generation sequencing experiment and perform the steps involved in identifying DNA mutations. + +Although the example dataset used will be Genomics, many of the tools and techniques will be applicable to other healthcare use-cases. + +#### Learning Outcomes + - Improved familiarity with the bash shell + - Install local software needed to access HPC (e.g. mobaxterm) + - Transfer files to and from HPC + - Submit, manage and evaluate the resource utilisation of HPC batch jobs + - Be aware of the importance of parallelisation + - Ability to run “embarrassingly parallel” Bioinformatics pipelines (e.g. quality control and alignment of a set of individuals profiled using next generation sequencing data) + +#### Prerequisites + - Previous experience with the bash shell would be useful but the workshop does include an introduction to using the shell on HPC systems. + - Some familiarity with biological concepts, including the structure of DNA, nucleotide abbreviations, and the concept of genomic variation within a population. + +#### Registration +As part of the application process, you will be asked to provide a brief explanation of how attending this workshop will benefit your research. You may find it useful to write this piece before attempting to register for the event. + +After the application deadline has passed, submissions will be considered, and successful applicants will be offered a place by e-mail. This process will help to ensure that each of the N8 universities are represented at, and benefit from the course. + +This event is only open to those working or studying at one of the N8 Research Partnership universities. Please register using your academic (.ac.uk) e-mail address to help verify your eligibility. + + + +The registration deadline is 5th July. diff --git a/_events/workshop-2021-07-14-n8cir-training-hpc-genomics.md b/_events/workshop-2021-07-14-n8cir-training-hpc-genomics.md new file mode 100644 index 00000000..dc2c44ea --- /dev/null +++ b/_events/workshop-2021-07-14-n8cir-training-hpc-genomics.md @@ -0,0 +1,58 @@ +--- +title: "High Performance Computing for Healthcare (day 2)" +category: training +tags: HPC, genomics, shell +permalink: /training/workshop/2021-07-14-n8cir-training-hpc-genomics +date: 2021-07-14 +from: "09:00" +to: "17:00" +location: "Online" +speaker: "Will Furnass, Mark Dunning" +--- + +This workshop is being +funded by the [N8 Centre for Computationally-Intensive Research (N8 CIR)](https://n8cir.org.uk/events/hpc-healthcare/), +is being organised by the N8 CIR and TUOS and +is being delivered by TUOS' RSE team and TUOS' Bioinformatics Core. + +#### Dates + +This workshop takes place over two days, 12 July and 14 July. Please only register if you will be able to attend both sessions if your application is successful. + +#### Overview +High Performance Computing (HPC) is an increasingly important tool utilised by researchers, helping to overcome the limitations processing parallelism and memory found in even the most powerful desktop systems. With more computing power available researchers can perform more and bigger experiments leading to improved accuracy and better research outcomes. A further benefit is that HPC systems require researchers to define their workflow as jobs, which aids reproducibility. + +However, making use of an HPC system, whether on-premise or in the cloud, isn’t as simple as just logging on and firing up the software. HPC users must be able to log in to remote computers using the bash shell, upload data and install software before they can begin to conduct experiments. Even the code may need to be adapted to run in parallel and maximise the benefits of HPC platforms. + +For these reasons, many researchers shy away from adding HPC to their research toolkit. + +This two-day workshop is intended to remove some of the mystery from HPC systems, making it easier for researchers to access them and accelerate their research. The material in this course will be healthcare-related using an omics data analysis. Participants will be given a set of sequencing reads from a next-generation sequencing experiment and perform the steps involved in identifying DNA mutations. + +Although the example dataset used will be Genomics, many of the tools and techniques will be applicable to other healthcare use-cases. + +#### Learning Outcomes + - Improved familiarity with the bash shell + - Install local software needed to access HPC (e.g. mobaxterm) + - Transfer files to and from HPC + - Submit, manage and evaluate the resource utilisation of HPC batch jobs + - Be aware of the importance of parallelisation + - Ability to run “embarrassingly parallel” Bioinformatics pipelines (e.g. quality control and alignment of a set of individuals profiled using next generation sequencing data) + +#### Prerequisites + - Previous experience with the bash shell would be useful but the workshop does include an introduction to using the shell on HPC systems. + - Some familiarity with biological concepts, including the structure of DNA, nucleotide abbreviations, and the concept of genomic variation within a population. + +#### Registration +As part of the application process, you will be asked to provide a brief explanation of how attending this workshop will benefit your research. You may find it useful to write this piece before attempting to register for the event. + +After the application deadline has passed, submissions will be considered, and successful applicants will be offered a place by e-mail. This process will help to ensure that each of the N8 universities are represented at, and benefit from the course. + +This event is only open to those working or studying at one of the N8 Research Partnership universities. Please register using your academic (.ac.uk) e-mail address to help verify your eligibility. + + + +The registration deadline is 5th July. diff --git a/_events/workshop-2021-09-13-gp-summer-school.md b/_events/workshop-2021-09-13-gp-summer-school.md new file mode 100644 index 00000000..1c70a485 --- /dev/null +++ b/_events/workshop-2021-09-13-gp-summer-school.md @@ -0,0 +1,17 @@ +--- +title: "Gaussian Process Summer School 2021" +category: +tags: Gaussian Processes, Machine Learning +date: 2021-09-13 +end-date: 2021-09-16 +location: "Online" +speaker: "Various" +--- + +The Gaussian Process Summer Schools are a series of schools and workshops aimed at researchers who want to understand and use Gaussian process models, both in theory and practice. They are organised by the [Sheffield Machine Learning Group](https://www.sheffield.ac.uk/dcs/research/groups/machine-learning) and others. + +**The Gaussian Process Summer School will be a virtual event from Monday September, 13 2021 to Thursday September, 16 2021.** + +For the event, we will use Zoom. If you have already registered, we will contact you close to the beginning of the School with instructions about how to connect. The School will include round table sessions with the speakers where participants can interact with them. + +**[More details and registration here](http://gpss.cc/gpss21/)** diff --git a/_events/workshop-2021-10-01-git-zero-hero.md b/_events/workshop-2021-10-01-git-zero-hero.md new file mode 100644 index 00000000..a2ae6d93 --- /dev/null +++ b/_events/workshop-2021-10-01-git-zero-hero.md @@ -0,0 +1,34 @@ +--- +title: "git & GitHub through GitKraken - from Zero to Hero!" +category: training +tags: collaboration, git, github, gitkraken +permalink: /training/workshop/2021-10-01-git-zero-hero +date: 2021-10-01 +from: "10:00" +to: "16:30" +location: "Online" +speaker: "Anna Krystalli, David Wilby, RSE Team" +--- + +## How can we effectively work together on the same code? + +**This is an introductory course, teaching the git and GitHub skills required to manage research code over it's development lifecycle. These skills are essential for collaborative research teams.** + +*This event is for University of Sheffield researchers and research students only. Please register with an **@shef.ac.uk** or **@sheffield.ac.uk** email address to ensure your ticket request is accepted.* + +**Prerequisite skills:** Some programming experience. + +**Learning Objectives** +* Version controlling your own project through Git & GitHub. +* Basic collaboration through forks on GitHub. +* Advanced team collaboration through branches on GitHub. +* Using the GitKraken GUI for a smooth version control experience. + +We plan to run this course online, but will investigate the possibly of hybrid delivery. + +More details and registration via [eventbrite](https://www.eventbrite.co.uk/e/git-github-through-gitkraken-from-zero-to-hero-tickets-163513044919). + +**Course material:** https://srse-git-github-zero2hero.netlify.app/ + +
Together, We Create

Photo by Jeremy Bishop on Unsplash

+ diff --git a/_events/workshop-2021-10-07-good-soft.md b/_events/workshop-2021-10-07-good-soft.md new file mode 100644 index 00000000..525dc679 --- /dev/null +++ b/_events/workshop-2021-10-07-good-soft.md @@ -0,0 +1,36 @@ +--- +title: "Write better research software (in Python)" +category: training +tags: documentation, testing, licensing +permalink: /training/workshop/2021-10-07-good-soft +date: 2021-10-07 +from: "12:30" +to: "16:30" +location: "Online" +speaker: "David Wilby, Bob Turner, RSE Team" +--- + +## How can we write better research software? + +**If you want the software you make for research to produce trustworthy results and to be reusable by others on different computers, this course will help.** + +*This event is for University of Sheffield researchers and research students only. Please register with an **@shef.ac.uk** or **@sheffield.ac.uk** email address to ensure your ticket request is accepted.* + +**Prerequisite skills:** Some python programming experience. + +**Learning Objectives** + +* Add documentation directly into python code using "docstrings" +* How and when to make your code open source +* Write tests (using `pytest`) so you can update your code with confidence + +This is a pilot course and as such we may encounter problems that we wouldn't normally expect. We will use feedback from this event to improve the course in future! Learning objectives are subject to change. + +We plan to run this course online, but will investigate the possibly of hybrid delivery. + +More details and registration via [eventbrite](https://www.eventbrite.co.uk/e/write-better-research-software-in-python-tickets-163827758235). + +**Course material:** + +
Together, We Create

Museums Victoria on Unsplash

+ diff --git a/_events/workshop-2021-12-09-git-zero-hero.md b/_events/workshop-2021-12-09-git-zero-hero.md new file mode 100644 index 00000000..9a3bc9f2 --- /dev/null +++ b/_events/workshop-2021-12-09-git-zero-hero.md @@ -0,0 +1,46 @@ +--- +title: "git & GitHub through GitKraken - from Zero to Hero!" +category: gitzerohero +tags: collaboration, git, github, gitkraken +permalink: /training/workshop/2021-12-09-git-zero-hero +date: 2021-12-09 +from: "10:00" +to: "16:30" +location: "Online" +speaker: "RSE Team" +--- + +## How can we effectively work together on the same code? + +**This is an introductory course, teaching the git and GitHub skills required to manage research code over it's development lifecycle. These skills are essential for collaborative research teams.** + +*This event is for University of Sheffield researchers and research students only. Please register with an **@shef.ac.uk** or **@sheffield.ac.uk** email address to ensure your ticket request is accepted.* + +**Prerequisite skills:** Some programming experience. + +**Learning Objectives** +* Version controlling your own project through Git & GitHub. +* Basic collaboration through forks on GitHub. +* Advanced team collaboration through branches on GitHub. +* Using the GitKraken GUI for a smooth version control experience. + +This course will be run online. + +
+ +We are delighted to be able to make free at point of use training available to the research community, to enable better software and more open, reproducible research. However, **free at point of use training is not free**. The cost of a course can easily run to thousands of pounds, if preparation costs are taken into account. + +**If you sign up for a course, please make sure you either attend or cancel your booking.** Bookings can usually be cancelled using [eventbrite.com](https://www.eventbrite.com) or, failing that, by emailing [rse@sheffield.ac.uk](mailto:rse@sheffield.ac.uk). + +Running courses that are not fully attended wastes our funding (which is provided by taxpayers, charities and students, amongst others) and reduces our collective capacity to improve research outputs and researcher experiences. + +Persistent failure to attend booked courses might result in you being excluded from future training opportunities. + +
+ +More details and registration via [eventbrite](https://www.eventbrite.co.uk/e/git-github-through-gitkraken-from-zero-to-hero-tickets-194428941197). + +**Course material:** + +
Together, We Create

Photo by Jeremy Bishop on Unsplash

+ diff --git a/_events/workshop-2022-01-20-git-zero-hero.md b/_events/workshop-2022-01-20-git-zero-hero.md new file mode 100644 index 00000000..e4229d43 --- /dev/null +++ b/_events/workshop-2022-01-20-git-zero-hero.md @@ -0,0 +1,46 @@ +--- +title: "git & GitHub through GitKraken - from Zero to Hero!" +category: gitzerohero +tags: collaboration, git, github, gitkraken +permalink: /training/workshop/2022-01-20-git-zero-hero +date: 2022-01-20 +from: "10:00" +to: "16:30" +location: "Online" +speaker: "RSE Team" +--- + +## How can we effectively work together on the same code? + +**This is an introductory course, teaching the git and GitHub skills required to manage research code over it's development lifecycle. These skills are essential for collaborative research teams.** + +*This event is for University of Sheffield researchers and research students only. Please register with an **@shef.ac.uk** or **@sheffield.ac.uk** email address to ensure your ticket request is accepted.* + +**Prerequisite skills:** Some programming experience. + +**Learning Objectives** +* Version controlling your own project through Git & GitHub. +* Basic collaboration through forks on GitHub. +* Advanced team collaboration through branches on GitHub. +* Using the GitKraken GUI for a smooth version control experience. + +This course will be run online. + +
+ +We are delighted to be able to make free at point of use training available to the research community, to enable better software and more open, reproducible research. However, **free at point of use training is not free**. The cost of a course can easily run to thousands of pounds, if preparation costs are taken into account. + +**If you sign up for a course, please make sure you either attend or cancel your booking.** Bookings can usually be cancelled using [eventbrite.com](https://www.eventbrite.com) or, failing that, by emailing [rse@sheffield.ac.uk](mailto:rse@sheffield.ac.uk). + +Running courses that are not fully attended wastes our funding (which is provided by taxpayers, charities and students, amongst others) and reduces our collective capacity to improve research outputs and researcher experiences. + +Persistent failure to attend booked courses might result in you being excluded from future training opportunities. + +
+ +More details and registration via [eventbrite](https://www.eventbrite.co.uk/e/git-github-through-gitkraken-from-zero-to-hero-tickets-211065621957). + +**Course material:** + +
Together, We Create

Photo by Jeremy Bishop on Unsplash

+ diff --git a/_events/workshop-2022-02-01-git-zero-hero.md b/_events/workshop-2022-02-01-git-zero-hero.md new file mode 100644 index 00000000..df1033c7 --- /dev/null +++ b/_events/workshop-2022-02-01-git-zero-hero.md @@ -0,0 +1,45 @@ +--- +title: "git & GitHub through GitKraken - from Zero to Hero!" +category: gitzerohero +tags: collaboration, git, github, gitkraken +permalink: /training/workshop/2022-02-01-git-zero-hero +date: 2022-02-01 +from: "10:00" +to: "16:30" +location: "Online" +speaker: "RSE Team" +--- + +## How can we effectively work together on the same code? + +**This is an introductory course, teaching the git and GitHub skills required to manage research code over it's development lifecycle. These skills are essential for collaborative research teams.** + +*This event is for University of Sheffield researchers and research students only. Please register with an **@shef.ac.uk** or **@sheffield.ac.uk** email address to ensure your ticket request is accepted.* + +**Prerequisite skills:** Some programming experience. + +**Learning Objectives** +* Version controlling your own project through Git & GitHub. +* Basic collaboration through forks on GitHub. +* Advanced team collaboration through branches on GitHub. +* Using the GitKraken GUI for a smooth version control experience. + +This course will be run online. + +
+ +We are delighted to be able to make free at point of use training available to the research community, to enable better software and more open, reproducible research. However, **free at point of use training is not free**. The cost of a course can easily run to thousands of pounds, if preparation costs are taken into account. + +**If you sign up for a course, please make sure you either attend or cancel your booking.** Bookings can usually be cancelled using [eventbrite.com](https://www.eventbrite.com) or, failing that, by emailing [rse@sheffield.ac.uk](mailto:rse@sheffield.ac.uk). + +Running courses that are not fully attended wastes our funding (which is provided by taxpayers, charities and students, amongst others) and reduces our collective capacity to improve research outputs and researcher experiences. + +Persistent failure to attend booked courses might result in you being excluded from future training opportunities. + +
+ +More details and registration via [eventbrite](https://www.eventbrite.co.uk/e/git-github-through-gitkraken-from-zero-to-hero-tickets-194495038897). + +**Course material:** + +
Together, We Create

Photo by Jeremy Bishop on Unsplash

diff --git a/_events/workshop-2022-03-10-git-zero-hero.md b/_events/workshop-2022-03-10-git-zero-hero.md new file mode 100644 index 00000000..0fcef50c --- /dev/null +++ b/_events/workshop-2022-03-10-git-zero-hero.md @@ -0,0 +1,46 @@ +--- +title: "git & GitHub through GitKraken - from Zero to Hero!" +category: gitzerohero +tags: collaboration, git, github, gitkraken +permalink: /training/workshop/2022-03-10-git-zero-hero +date: 2022-03-10 +from: "10:00" +to: "16:30" +location: "Online" +speaker: "RSE Team" +--- + +## How can we effectively work together on the same code? + +**This is an introductory course, teaching the git and GitHub skills required to manage research code over it's development lifecycle. These skills are essential for collaborative research teams.** + +*This event is for University of Sheffield researchers and research students only. Please register with an **@shef.ac.uk** or **@sheffield.ac.uk** email address to ensure your ticket request is accepted.* + +**Prerequisite skills:** Some programming experience. + +**Learning Objectives** +* Version controlling your own project through Git & GitHub. +* Basic collaboration through forks on GitHub. +* Advanced team collaboration through branches on GitHub. +* Using the GitKraken GUI for a smooth version control experience. + +This course will be run online. + +
+ +We are delighted to be able to make free at point of use training available to the research community, to enable better software and more open, reproducible research. However, **free at point of use training is not free**. The cost of a course can easily run to thousands of pounds, if preparation costs are taken into account. + +**If you sign up for a course, please make sure you either attend or cancel your booking.** Bookings can usually be cancelled using [eventbrite.com](https://www.eventbrite.com) or, failing that, by emailing [rse@sheffield.ac.uk](mailto:rse@sheffield.ac.uk). + +Running courses that are not fully attended wastes our funding (which is provided by taxpayers, charities and students, amongst others) and reduces our collective capacity to improve research outputs and researcher experiences. + +Persistent failure to attend booked courses might result in you being excluded from future training opportunities. + +
+ +More details and registration via [eventbrite](https://www.eventbrite.co.uk/e/git-github-through-gitkraken-from-zero-to-hero-tickets-211067186637). + +**Course material:** + +
Together, We Create

Photo by Jeremy Bishop on Unsplash

+ diff --git a/_events/workshop-2022-04-05-git-zero-hero.md b/_events/workshop-2022-04-05-git-zero-hero.md new file mode 100644 index 00000000..26330d37 --- /dev/null +++ b/_events/workshop-2022-04-05-git-zero-hero.md @@ -0,0 +1,47 @@ +--- +title: "git & GitHub through GitKraken - from Zero to Hero!" +category: gitzerohero +tags: collaboration, git, github, gitkraken +permalink: /training/workshop/2022-04-05-git-zero-hero +date: 2022-04-12 +from: "10:00" +to: "16:30" +location: "Online" +speaker: "RSE Team" +--- + +** Please note that this workshop was originally scheduled for 5th April 2022 and has been rescheduled to 12th April** + +## How can we effectively work together on the same code? + +**This is an introductory course, teaching the git and GitHub skills required to manage research code over it's development lifecycle. These skills are essential for collaborative research teams.** + +*This event is for University of Sheffield researchers and research students only. Please register with an **@shef.ac.uk** or **@sheffield.ac.uk** email address to ensure your ticket request is accepted.* + +**Prerequisite skills:** Some programming experience. + +**Learning Objectives** +* Version controlling your own project through Git & GitHub. +* Basic collaboration through forks on GitHub. +* Advanced team collaboration through branches on GitHub. +* Using the GitKraken GUI for a smooth version control experience. + +This course will be run online. + +
+ +We are delighted to be able to make free at point of use training available to the research community, to enable better software and more open, reproducible research. However, **free at point of use training is not free**. The cost of a course can easily run to thousands of pounds, if preparation costs are taken into account. + +**If you sign up for a course, please make sure you either attend or cancel your booking.** Bookings can usually be cancelled using [eventbrite.com](https://www.eventbrite.com) or, failing that, by emailing [rse@sheffield.ac.uk](mailto:rse@sheffield.ac.uk). + +Running courses that are not fully attended wastes our funding (which is provided by taxpayers, charities and students, amongst others) and reduces our collective capacity to improve research outputs and researcher experiences. + +Persistent failure to attend booked courses might result in you being excluded from future training opportunities. + +
+ +More details and registration via [eventbrite](https://www.eventbrite.co.uk/e/git-github-through-gitkraken-from-zero-to-hero-tickets-194495580517). + +**Course material:** + +
Together, We Create

Photo by Jeremy Bishop on Unsplash

diff --git a/_events/workshop-2022-04-06-deep-learning-with-tensorflow-in-python.md b/_events/workshop-2022-04-06-deep-learning-with-tensorflow-in-python.md new file mode 100644 index 00000000..82955fbf --- /dev/null +++ b/_events/workshop-2022-04-06-deep-learning-with-tensorflow-in-python.md @@ -0,0 +1,48 @@ +--- +title: "Deep Learning with Tensorflow in Python" +category: dltraining +tags: deep-learning, python +permalink: /training/workshop/2022-04-06-deep-learning-with-tensorflow-in-python +date: 2022-04-06 +from: "09:00" +to: "17:00" +location: "Online" +speaker: "Twin Karmakharm, Fariba Yousefi" +--- + +#### Course Description + +Recent advances in deep neural networks coupled with an increasing amount and complexity of scientific data collected in a wide array of domains provide many [exciting opportunities for deep learning applications in scientific settings](https://arxiv.org/abs/2003.11755). Furthermore, libraries such as Google’s Tensorflow python library have made building deep learning models more accessible through common tools, freely available to researchers. + +In this course, we’ll introduce some basic neural network and deep learning theory and give participants practical experience in some popular deep learning models and techniques. + +**Content includes:** + +- Introduction to Regression and Classification using neural networks +- Image classification with Convolutional neural networks +- Speeding up the training process of your own models using existing neural network + +#### Course Delivery + +The course will be delivered online through blackboard collaborate. There will be a significant practical element to the course and we will be working online in [Google Colab](https://colab.research.google.com/) notebooks. + +#### Course Requirements + +Familiarity with python programming basics. + +#### Please cancel if you cannot attend + +We are delighted to be able to make free at point of use training available to the research community, to enable better software and more open, reproducible research. However, free at point of use training is not free. The cost of a course can easily run to thousands of pounds, if preparation costs are taken into account. + +If you sign up for a course, please make sure you either attend or cancel your booking. Bookings can usually be cancelled using eventbrite.com or, failing that, by emailing rse@sheffield.ac.uk. + +Running courses that are not fully attended wastes our funding (which is provided by taxpayers, charities and students, amongst others) and reduces our collective capacity to improve research outputs and researcher experiences. + +Persistent failure to attend booked courses might result in you being excluded from future training opportunities. + + + diff --git a/_events/workshop-2022-05-10-git-zero-hero.md b/_events/workshop-2022-05-10-git-zero-hero.md new file mode 100644 index 00000000..a535a3ea --- /dev/null +++ b/_events/workshop-2022-05-10-git-zero-hero.md @@ -0,0 +1,45 @@ +--- +title: "git & GitHub through GitKraken - from Zero to Hero!" +category: gitzerohero +tags: collaboration, git, github, gitkraken +permalink: /training/workshop/2022-05-10-git-zero-hero +date: 2022-05-10 +from: "09:30" +to: "16:30" +location: "Online" +speaker: "RSE Team" +--- + +## How can we effectively work together on the same code? + +**This is an introductory course, teaching the git and GitHub skills required to manage research code over it's development lifecycle. These skills are essential for collaborative research teams.** + +*This event is for University of Sheffield researchers and research students only. Please register with an **@shef.ac.uk** or **@sheffield.ac.uk** email address to ensure your ticket request is accepted.* + +**Prerequisite skills:** Some programming experience. + +**Learning Objectives** +* Version controlling your own project through Git & GitHub. +* Basic collaboration through forks on GitHub. +* Advanced team collaboration through branches on GitHub. +* Using the GitKraken GUI for a smooth version control experience. + +This course will be run online. + +
+ +We are delighted to be able to make free at point of use training available to the research community, to enable better software and more open, reproducible research. However, **free at point of use training is not free**. The cost of a course can easily run to thousands of pounds, if preparation costs are taken into account. + +**If you sign up for a course, please make sure you either attend or cancel your booking.** Bookings can usually be cancelled using [eventbrite.com](https://www.eventbrite.com) or, failing that, by emailing [rse@sheffield.ac.uk](mailto:rse@sheffield.ac.uk). + +Running courses that are not fully attended wastes our funding (which is provided by taxpayers, charities and students, amongst others) and reduces our collective capacity to improve research outputs and researcher experiences. + +Persistent failure to attend booked courses might result in you being excluded from future training opportunities. + +
+ +More details and registration via [eventbrite](https://www.eventbrite.co.uk/e/git-github-through-gitkraken-from-zero-to-hero-registration-305676375267). + +**Course material:** + +
Together, We Create

Photo by Jeremy Bishop on Unsplash

diff --git a/_events/workshop-2022-06-06-git-zero-hero.md b/_events/workshop-2022-06-06-git-zero-hero.md new file mode 100644 index 00000000..0bfbad1d --- /dev/null +++ b/_events/workshop-2022-06-06-git-zero-hero.md @@ -0,0 +1,48 @@ +--- +title: "git & GitHub through GitKraken - from Zero to Hero!" +category: gitzerohero +tags: collaboration, git, github, gitkraken +permalink: /training/workshop/2022-06-06-git-zero-hero +date: 2022-06-06 +end-date: 2022-06-07 +from: "12:30" +to: "16:30" +location: "Online" +speaker: "RSE Team" +--- + +## How can we effectively work together on the same code? + +**This is an introductory course, teaching the git and GitHub skills required to manage research code over it's development lifecycle. These skills are essential for collaborative research teams.** + +*This event is for University of Sheffield researchers and research students only. Please register with an **@shef.ac.uk** or **@sheffield.ac.uk** email address to ensure your ticket request is accepted.* + +**Prerequisite skills:** Some programming experience. + +**Learning Objectives** +* Version controlling your own project through Git & GitHub. +* Basic collaboration through forks on GitHub. +* Advanced team collaboration through branches on GitHub. +* Using the GitKraken GUI for a smooth version control experience. + +This course will be run online. + +
+ +We are delighted to be able to make free at point of use training available to the research community, to enable better software and more open, reproducible research. However, **free at point of use training is not free**. The cost of a course can easily run to thousands of pounds, if preparation costs are taken into account. + +**If you sign up for a course, please make sure you either attend or cancel your booking.** Bookings can usually be cancelled using [eventbrite.com](https://www.eventbrite.com) or, failing that, by emailing [rse@sheffield.ac.uk](mailto:rse@sheffield.ac.uk). + +Running courses that are not fully attended wastes our funding (which is provided by taxpayers, charities and students, amongst others) and reduces our collective capacity to improve research outputs and researcher experiences. + +Persistent failure to attend booked courses might result in you being excluded from future training opportunities. + +
+ +More details and registration via [eventbrite](https://www.eventbrite.co.uk/e/git-github-through-gitkraken-from-zero-to-hero-registration-305736765897). + +**Please note:** This workshop will run over 2 half days from 12:30-16:30 on Monday 6th and Tuesday 7th June 2022. + +**Course material:** + +
Together, We Create

Photo by Jeremy Bishop on Unsplash

diff --git a/_events/workshop-2022-06-08-deep-learning-with-tensorflow-in-python.md b/_events/workshop-2022-06-08-deep-learning-with-tensorflow-in-python.md new file mode 100644 index 00000000..5b17afee --- /dev/null +++ b/_events/workshop-2022-06-08-deep-learning-with-tensorflow-in-python.md @@ -0,0 +1,48 @@ +--- +title: "Introduction to Deep Learning with Tensorflow in Python" +category: dltraining +tags: deep-learning, python +permalink: /training/workshop/2022-06-08-deep-learning-with-tensorflow-in-python +date: 2022-06-08 +from: "09:00" +to: "17:00" +location: "Online" +speaker: "Twin Karmakharm, Fariba Yousefi" +--- + +#### Course Description + +Recent advances in deep neural networks coupled with an increasing amount and complexity of scientific data collected in a wide array of domains provide many [exciting opportunities for deep learning applications in scientific settings](https://arxiv.org/abs/2003.11755). Furthermore, libraries such as Google’s Tensorflow python library have made building deep learning models more accessible through common tools, freely available to researchers. + +In this course, we’ll introduce some basic neural network and deep learning theory and give participants practical experience in some popular deep learning models and techniques. + +**Content includes:** + +- Introduction to Regression and Classification using neural networks +- Image classification with Convolutional neural networks +- Speeding up the training process of your own models using existing neural network + +#### Course Delivery + +The course will be delivered online through blackboard collaborate. There will be a significant practical element to the course and we will be working online in [Google Colab](https://colab.research.google.com/) notebooks. + +#### Course Requirements + +Familiarity with python programming basics. + +#### Please cancel if you cannot attend + +We are delighted to be able to make free at point of use training available to the research community, to enable better software and more open, reproducible research. However, free at point of use training is not free. The cost of a course can easily run to thousands of pounds, if preparation costs are taken into account. + +If you sign up for a course, please make sure you either attend or cancel your booking. Bookings can usually be cancelled using eventbrite.com or, failing that, by emailing rse@sheffield.ac.uk. + +Running courses that are not fully attended wastes our funding (which is provided by taxpayers, charities and students, amongst others) and reduces our collective capacity to improve research outputs and researcher experiences. + +Persistent failure to attend booked courses might result in you being excluded from future training opportunities. + + + diff --git a/_events/workshop-2022-07-26-git-zero-hero.md b/_events/workshop-2022-07-26-git-zero-hero.md new file mode 100644 index 00000000..091cbd2b --- /dev/null +++ b/_events/workshop-2022-07-26-git-zero-hero.md @@ -0,0 +1,45 @@ +--- +title: "git & GitHub through GitKraken - from Zero to Hero!" +category: gitzerohero +tags: collaboration, git, github, gitkraken +permalink: /training/workshop/2022-07-26-git-zero-hero +date: 2022-07-26 +from: "09:30" +to: "16:30" +location: "Online" +speaker: "RSE Team" +--- + +## How can we effectively work together on the same code? + +**This is an introductory course, teaching the git and GitHub skills required to manage research code over it's development lifecycle. These skills are essential for collaborative research teams.** + +*This event is for University of Sheffield researchers and research students only. Please register with an **@shef.ac.uk** or **@sheffield.ac.uk** email address to ensure your ticket request is accepted.* + +**Prerequisite skills:** Some programming experience. + +**Learning Objectives** +* Version controlling your own project through Git & GitHub. +* Basic collaboration through forks on GitHub. +* Advanced team collaboration through branches on GitHub. +* Using the GitKraken GUI for a smooth version control experience. + +This course will be run online. + +
+ +We are delighted to be able to make free at point of use training available to the research community, to enable better software and more open, reproducible research. However, **free at point of use training is not free**. The cost of a course can easily run to thousands of pounds, if preparation costs are taken into account. + +**If you sign up for a course, please make sure you either attend or cancel your booking.** Bookings can usually be cancelled using [eventbrite.com](https://www.eventbrite.com) or, failing that, by emailing [rse@sheffield.ac.uk](mailto:rse@sheffield.ac.uk). + +Running courses that are not fully attended wastes our funding (which is provided by taxpayers, charities and students, amongst others) and reduces our collective capacity to improve research outputs and researcher experiences. + +Persistent failure to attend booked courses might result in you being excluded from future training opportunities. + +
+ +More details and registration via [eventbrite](https://www.eventbrite.co.uk/e/git-github-through-gitkraken-from-zero-to-hero-registration-305733546267). + +**Course material:** + +
Together, We Create

Photo by Jeremy Bishop on Unsplash

diff --git a/_events/workshop-2022-09-14-deep-learning-with-tensorflow-in-python.md b/_events/workshop-2022-09-14-deep-learning-with-tensorflow-in-python.md new file mode 100644 index 00000000..659cc2e5 --- /dev/null +++ b/_events/workshop-2022-09-14-deep-learning-with-tensorflow-in-python.md @@ -0,0 +1,48 @@ +--- +title: "Introduction to Deep Learning with Tensorflow in Python" +category: dltraining +tags: deep-learning, python +permalink: /training/workshop/2022-09-14-deep-learning-with-tensorflow-in-python +date: 2022-09-14 +from: "09:00" +to: "17:00" +location: "Online" +speaker: "Twin Karmakharm, Max Gamill" +--- + +#### Course Description + +Recent advances in deep neural networks coupled with an increasing amount and complexity of scientific data collected in a wide array of domains provide many [exciting opportunities for deep learning applications in scientific settings](https://arxiv.org/abs/2003.11755). Furthermore, libraries such as Google’s Tensorflow python library have made building deep learning models more accessible through common tools, freely available to researchers. + +In this course, we’ll introduce some basic neural network and deep learning theory and give participants practical experience in some popular deep learning models and techniques. + +**Content includes:** + +- Introduction to Regression and Classification using neural networks +- Image classification with Convolutional neural networks +- Speeding up the training process of your own models using existing neural network + +#### Course Delivery + +The course will be delivered online through blackboard collaborate. There will be a significant practical element to the course and we will be working online in [Google Colab](https://colab.research.google.com/) notebooks. + +#### Course Requirements + +Familiarity with python programming basics. + +#### Please cancel if you cannot attend + +We are delighted to be able to make free at point of use training available to the research community, to enable better software and more open, reproducible research. However, free at point of use training is not free. The cost of a course can easily run to thousands of pounds, if preparation costs are taken into account. + +If you sign up for a course, please make sure you either attend or cancel your booking. Bookings can usually be cancelled using eventbrite.com or, failing that, by emailing rse@sheffield.ac.uk. + +Running courses that are not fully attended wastes our funding (which is provided by taxpayers, charities and students, amongst others) and reduces our collective capacity to improve research outputs and researcher experiences. + +Persistent failure to attend booked courses might result in you being excluded from future training opportunities. + + + diff --git a/_events/workshop-2022-10-03-git-zero-hero.md b/_events/workshop-2022-10-03-git-zero-hero.md new file mode 100644 index 00000000..212c217e --- /dev/null +++ b/_events/workshop-2022-10-03-git-zero-hero.md @@ -0,0 +1,63 @@ +--- +title: "git & GitHub through GitKraken - from Zero to Hero!" +category: gitzerohero +tags: collaboration, git, github, gitkraken +permalink: /training/workshop/2022-10-03-git-zero-hero +date: 2022-10-03 +end-date: 2022-10-04 +from: "09:30" +to: "13:00" +location: "Online" +speaker: "RSE Team" +--- + +## How can we effectively work together on the same code? + +**This is an introductory course, teaching the git and GitHub skills required to manage research code over it's +development lifecycle. These skills are essential for collaborative research teams.** + + +*This event is for University of Sheffield researchers and research students only. Please register with an +**@shef.ac.uk** or **@sheffield.ac.uk** email address to ensure your ticket request is accepted.* + + +**Prerequisite skills:** Some programming experience. + +**Learning Objectives** +* Version controlling your own project through Git & GitHub. +* Basic collaboration through forks on GitHub. +* Advanced team collaboration through branches on GitHub. +* Using the GitKraken GUI for a smooth version control experience. + +This course will be run online. + +
+ +We are delighted to be able to make free at point of use training available to the research community, to enable better +software and more open, reproducible research. However, **free at point of use training is not free**. The cost of a +course can easily run to thousands of pounds, if preparation costs are taken into account. + + +**If you sign up for a course, please make sure you either attend or cancel your booking.** Bookings can usually be +cancelled using [eventbrite.com](https://www.eventbrite.com) or, failing that, by emailing +[rse@sheffield.ac.uk](mailto:rse@sheffield.ac.uk). + + +Running courses that are not fully attended wastes our funding (which is provided by taxpayers, charities and students, +amongst others) and reduces our collective capacity to improve research outputs and researcher experiences. + + +Persistent failure to attend booked courses might result in you being excluded from future training opportunities. + +
+ +More details and registration via +[eventbrite](https://www.eventbrite.com/e/git-github-through-gitkraken-from-zero-to-hero-registration-406105320947). + + +**Please note:** This workshop will run over 2 half days from 09:30-13:00 on Monday 3rd and Tuesday 4th October 2022. + +**Course material:** + +
Together, We Create

Photo by +Jeremy Bishop on Unsplash

diff --git a/_events/workshop-2022-10-31-git-zero-hero.md b/_events/workshop-2022-10-31-git-zero-hero.md new file mode 100644 index 00000000..7bcd89b6 --- /dev/null +++ b/_events/workshop-2022-10-31-git-zero-hero.md @@ -0,0 +1,63 @@ +--- +title: "git & GitHub through GitKraken - from Zero to Hero!" +category: gitzerohero +tags: collaboration, git, github, gitkraken +permalink: /training/workshop/2022-10-31-git-zero-hero +date: 2022-10-31 +end-date: 2022-11-01 +from: "09:30" +to: "13:00" +location: "Online" +speaker: "RSE Team" +--- + +## How can we effectively work together on the same code? + +**This is an introductory course, teaching the git and GitHub skills required to manage research code over it's +development lifecycle. These skills are essential for collaborative research teams.** + + +*This event is for University of Sheffield researchers and research students only. Please register with an +**@shef.ac.uk** or **@sheffield.ac.uk** email address to ensure your ticket request is accepted.* + + +**Prerequisite skills:** Some programming experience. + +**Learning Objectives** +* Version controlling your own project through Git & GitHub. +* Basic collaboration through forks on GitHub. +* Advanced team collaboration through branches on GitHub. +* Using the GitKraken GUI for a smooth version control experience. + +This course will be run online. + +
+ +We are delighted to be able to make free at point of use training available to the research community, to enable better +software and more open, reproducible research. However, **free at point of use training is not free**. The cost of a +course can easily run to thousands of pounds, if preparation costs are taken into account. + + +**If you sign up for a course, please make sure you either attend or cancel your booking.** Bookings can usually be +cancelled using [eventbrite.com](https://www.eventbrite.com) or, failing that, by emailing +[rse@sheffield.ac.uk](mailto:rse@sheffield.ac.uk). + + +Running courses that are not fully attended wastes our funding (which is provided by taxpayers, charities and students, +amongst others) and reduces our collective capacity to improve research outputs and researcher experiences. + + +Persistent failure to attend booked courses might result in you being excluded from future training opportunities. + +
+ +More details and registration via +[eventbrite](https://www.eventbrite.com/e/git-github-through-gitkraken-from-zero-to-hero-registration-406112592697). + + +**Please note:** This workshop will run over 2 half days from 09:30-13:00 on Monday 31st October and Tuesday 1st November 2022. + +**Course material:** + +
Together, We Create

Photo by +Jeremy Bishop on Unsplash

diff --git a/_events/workshop-2022-11-16-deep-learning-with-tensorflow-in-python.md b/_events/workshop-2022-11-16-deep-learning-with-tensorflow-in-python.md new file mode 100644 index 00000000..1af54bbc --- /dev/null +++ b/_events/workshop-2022-11-16-deep-learning-with-tensorflow-in-python.md @@ -0,0 +1,48 @@ +--- +title: "Introduction to Deep Learning with Tensorflow in Python" +category: dltraining +tags: deep-learning, python +permalink: /training/workshop/2022-11-16-deep-learning-with-tensorflow-in-python +date: 2022-11-16 +from: "09:00" +to: "17:00" +location: "Online" +speaker: "Twin Karmakharm, Max Gamill" +--- + +#### Course Description + +Recent advances in deep neural networks coupled with an increasing amount and complexity of scientific data collected in a wide array of domains provide many [exciting opportunities for deep learning applications in scientific settings](https://arxiv.org/abs/2003.11755). Furthermore, libraries such as Google’s Tensorflow python library have made building deep learning models more accessible through common tools, freely available to researchers. + +In this course, we’ll introduce some basic neural network and deep learning theory and give participants practical experience in some popular deep learning models and techniques. + +**Content includes:** + +- Introduction to Regression and Classification using neural networks +- Image classification with Convolutional neural networks +- Speeding up the training process of your own models using existing neural network + +#### Course Delivery + +The course will be delivered online through blackboard collaborate. There will be a significant practical element to the course and we will be working online in [Google Colab](https://colab.research.google.com/) notebooks. + +#### Course Requirements + +Familiarity with python programming basics. + +#### Please cancel if you cannot attend + +We are delighted to be able to make free at point of use training available to the research community, to enable better software and more open, reproducible research. However, free at point of use training is not free. The cost of a course can easily run to thousands of pounds, if preparation costs are taken into account. + +If you sign up for a course, please make sure you either attend or cancel your booking. Bookings can usually be cancelled using eventbrite.com or, failing that, by emailing rse@sheffield.ac.uk. + +Running courses that are not fully attended wastes our funding (which is provided by taxpayers, charities and students, amongst others) and reduces our collective capacity to improve research outputs and researcher experiences. + +Persistent failure to attend booked courses might result in you being excluded from future training opportunities. + + + diff --git a/_events/workshop-2022-11-28-git-zero-hero.md b/_events/workshop-2022-11-28-git-zero-hero.md new file mode 100644 index 00000000..c2b118cd --- /dev/null +++ b/_events/workshop-2022-11-28-git-zero-hero.md @@ -0,0 +1,63 @@ +--- +title: "git & GitHub through GitKraken - from Zero to Hero!" +category: gitzerohero +tags: collaboration, git, github, gitkraken +permalink: /training/workshop/2022-11-28-git-zero-hero +date: 2022-11-28 +end-date: 2022-11-29 +from: "09:30" +to: "13:00" +location: "Online" +speaker: "RSE Team" +--- + +## How can we effectively work together on the same code? + +**This is an introductory course, teaching the git and GitHub skills required to manage research code over it's +development lifecycle. These skills are essential for collaborative research teams.** + + +*This event is for University of Sheffield researchers and research students only. Please register with an +**@shef.ac.uk** or **@sheffield.ac.uk** email address to ensure your ticket request is accepted.* + + +**Prerequisite skills:** Some programming experience. + +**Learning Objectives** +* Version controlling your own project through Git & GitHub. +* Basic collaboration through forks on GitHub. +* Advanced team collaboration through branches on GitHub. +* Using the GitKraken GUI for a smooth version control experience. + +This course will be run online. + +
+ +We are delighted to be able to make free at point of use training available to the research community, to enable better +software and more open, reproducible research. However, **free at point of use training is not free**. The cost of a +course can easily run to thousands of pounds, if preparation costs are taken into account. + + +**If you sign up for a course, please make sure you either attend or cancel your booking.** Bookings can usually be +cancelled using [eventbrite.com](https://www.eventbrite.com) or, failing that, by emailing +[rse@sheffield.ac.uk](mailto:rse@sheffield.ac.uk). + + +Running courses that are not fully attended wastes our funding (which is provided by taxpayers, charities and students, +amongst others) and reduces our collective capacity to improve research outputs and researcher experiences. + + +Persistent failure to attend booked courses might result in you being excluded from future training opportunities. + +
+ +More details and registration via +[eventbrite](https://www.eventbrite.com/e/git-github-through-gitkraken-from-zero-to-hero-registration-406116594667). + + +**Please note:** This workshop will run over 2 half days from 09:30-13:00 on Monday 28th and Tuesday 29th June 2022. + +**Course material:** + +
Together, We Create

Photo by +Jeremy Bishop on Unsplash

diff --git a/_events/workshop-2023-01-18-deep-learning-with-tensorflow-in-python.md b/_events/workshop-2023-01-18-deep-learning-with-tensorflow-in-python.md new file mode 100644 index 00000000..d5804746 --- /dev/null +++ b/_events/workshop-2023-01-18-deep-learning-with-tensorflow-in-python.md @@ -0,0 +1,48 @@ +--- +title: "Introduction to Deep Learning with Tensorflow in Python" +category: dltraining +tags: deep-learning, python +permalink: /training/workshop/2023-01-18-deep-learning-with-tensorflow-in-python +date: 2023-01-18 +from: "09:00" +to: "17:00" +location: "Online" +speaker: "Twin Karmakharm, Max Gamill" +--- + +#### Course Description + +Recent advances in deep neural networks coupled with an increasing amount and complexity of scientific data collected in a wide array of domains provide many [exciting opportunities for deep learning applications in scientific settings](https://arxiv.org/abs/2003.11755). Furthermore, libraries such as Google’s Tensorflow python library have made building deep learning models more accessible through common tools, freely available to researchers. + +In this course, we’ll introduce some basic neural network and deep learning theory and give participants practical experience in some popular deep learning models and techniques. + +**Content includes:** + +- Introduction to Regression and Classification using neural networks +- Image classification with Convolutional neural networks +- Speeding up the training process of your own models using existing neural network + +#### Course Delivery + +The course will be delivered online through blackboard collaborate. There will be a significant practical element to the course and we will be working online in [Google Colab](https://colab.research.google.com/) notebooks. + +#### Course Requirements + +Familiarity with python programming basics. + +#### Please cancel if you cannot attend + +We are delighted to be able to make free at point of use training available to the research community, to enable better software and more open, reproducible research. However, free at point of use training is not free. The cost of a course can easily run to thousands of pounds, if preparation costs are taken into account. + +If you sign up for a course, please make sure you either attend or cancel your booking. Bookings can usually be cancelled using eventbrite.com or, failing that, by emailing rse@sheffield.ac.uk. + +Running courses that are not fully attended wastes our funding (which is provided by taxpayers, charities and students, amongst others) and reduces our collective capacity to improve research outputs and researcher experiences. + +Persistent failure to attend booked courses might result in you being excluded from future training opportunities. + + + diff --git a/_events/workshop-2023-01-26-git-zero-hero.md b/_events/workshop-2023-01-26-git-zero-hero.md new file mode 100644 index 00000000..8315d36c --- /dev/null +++ b/_events/workshop-2023-01-26-git-zero-hero.md @@ -0,0 +1,66 @@ +--- +title: "git & GitHub through GitKraken - from Zero to Hero!" +category: gitzerohero +tags: collaboration, git, github, gitkraken +permalink: /training/workshop/2023-01-26-git-zero-hero +date: 2023-01-26 +end-date: 2023-01-27 +from: "09:30" +to: "13:00" +location: "Room PC-C28 IT Room, Protobello Centre, 1 Pitt Street, Sheffield" +speaker: "RSE Team" +--- + +## How can we effectively work together on the same code? + +**This is an introductory course, teaching the git and GitHub skills required to manage research code over it's +development lifecycle. These skills are essential for collaborative research teams.** + + +*This event is for University of Sheffield researchers and research students only. Please register with an +**@shef.ac.uk** or **@sheffield.ac.uk** email address to ensure your ticket request is accepted.* + + +**Prerequisite skills:** Some programming experience. + +**Learning Objectives** +* Version controlling your own project through Git & GitHub. +* Basic collaboration through forks on GitHub. +* Advanced team collaboration through branches on GitHub. +* Using the GitKraken GUI for a smooth version control experience. + +This course will be run online. + +
+ +We are delighted to be able to make free at point of use training available to the research community, to enable better +software and more open, reproducible research. However, **free at point of use training is not free**. The cost of a +course can easily run to thousands of pounds, if preparation costs are taken into account. + + +**If you sign up for a course, please make sure you either attend or cancel your booking.** Bookings can usually be +cancelled using [eventbrite.com](https://www.eventbrite.com) or, failing that, by emailing +[rse@sheffield.ac.uk](mailto:rse@sheffield.ac.uk). + + +Running courses that are not fully attended wastes our funding (which is provided by taxpayers, charities and students, +amongst others) and reduces our collective capacity to improve research outputs and researcher experiences. + + +Persistent failure to attend booked courses might result in you being excluded from future training opportunities. + +
+ +More details and registration via +[eventbrite](https://www.eventbrite.co.uk/e/git-github-through-gitkraken-from-zero-to-hero-registration-483146122057). + + +**Please note:** This workshop is **in person** and will run over 2 half days from 09:30-13:00 on Thursday 26th and +Friday 27th January 2023. If you would like to attend online instead please register for the course running +[2022-03-06 / 2022-03-07](/training/workshop/2023-01-26-git-zero-hero). + + +**Course material:** + +
Together, We Create

Photo by +Jeremy Bishop on Unsplash

diff --git a/_events/workshop-2023-03-03-intro-to-conda.md b/_events/workshop-2023-03-03-intro-to-conda.md new file mode 100644 index 00000000..da364827 --- /dev/null +++ b/_events/workshop-2023-03-03-intro-to-conda.md @@ -0,0 +1,81 @@ +--- +title: "[PILOT] Introduction to Conda for (Data) Scientists" +category: introconda +tags: computing, conda, python, reproducibility, research, virtual environment +permalink: /training/workshop/2023-03-03-intro-to-conda +date: 2023-03-03 +end-date: 2023-03-03 +from: "09:30" +to: "13:30" +location: "Computer Room B56 (38), Firth Court" +speaker: "RSE Team" +--- + +## How can we undertake research work in a consistent and reproducible computing environment? + +**This is an intermediate course, teaching the use of Conda virtual environments for reproducible research environments.** + + +*This event is for University of Sheffield researchers and research students only. Please register with an +**@shef.ac.uk** or **@sheffield.ac.uk** email address to ensure your ticket request is accepted.* + + +### Prerequisite skills + +- Basic shell commands (bash/zsh (Linux/MacOS); Powershell (Windows). +- Some Python programming experience. + +### Learning Objectives + +- Understand what Conda is and why it is useful for managing packages and environments in research workflows. +- How to create, activate and delete Conda environments. +- How to install and manage packages in Conda environments. +- What Conda channels and packages are and how to use them. +- How to use pip in Conda environments. +- How to share your Conda environment. +- How to manage packages that have GPU dependencies. + +This course will be run in person. + +**NB** This is a pilot session of the course and is the first time the RSE team will have run it and there may be some +teething issues. Please don't let this put you off signing up, we need participants and would appreciate honest +feedback. + +### Setup + +Prior to attending, you need to install the software we are going to use. **Please ensure you have completed setup +before the course begins**. + +Instructions on how to install all the software required can be found on the [Setup +chapter](https://rse.shef.ac.uk/introduction-to-conda-for-data-scientists/setup/) of the course materials. If you have +any problems with your setup, please get in touch with us for assistance *before* the course begins. + + +
+ +We are delighted to be able to make free at point of use training available to the research community, to enable better +software and more open, reproducible research. However, **free at point of use training is not free**. The cost of a +course can easily run to thousands of pounds, if preparation costs are taken into account. + + +**If you sign up for a course, please make sure you either attend or cancel your booking.** Bookings can usually be +cancelled using [eventbrite.com](https://www.eventbrite.com) or, failing that, by emailing +[rse@sheffield.ac.uk](mailto:rse@sheffield.ac.uk). + + +Running courses that are not fully attended wastes our funding (which is provided by taxpayers, charities and students, +amongst others) and reduces our collective capacity to improve research outputs and researcher experiences. + + +Persistent failure to attend booked courses might result in you being excluded from future training opportunities. + +
+ +More details and registration via +[eventbrite](https://www.eventbrite.co.uk/e/pilot-introduction-to-conda-for-data-scientists-tickets-552625396437). + + +**Course material:** + + diff --git a/_events/workshop-2023-03-06-git-zero-hero.md b/_events/workshop-2023-03-06-git-zero-hero.md new file mode 100644 index 00000000..48347bc2 --- /dev/null +++ b/_events/workshop-2023-03-06-git-zero-hero.md @@ -0,0 +1,63 @@ +--- +title: "git & GitHub through GitKraken - from Zero to Hero!" +category: gitzerohero +tags: collaboration, git, github, gitkraken +permalink: /training/workshop/2023-03-06-git-zero-hero +date: 2023-03-06 +end-date: 2023-03-07 +from: "09:30" +to: "13:00" +location: "Online" +speaker: "RSE Team" +--- + +## How can we effectively work together on the same code? + +**This is an introductory course, teaching the git and GitHub skills required to manage research code over it's +development lifecycle. These skills are essential for collaborative research teams.** + + +*This event is for University of Sheffield researchers and research students only. Please register with an +**@shef.ac.uk** or **@sheffield.ac.uk** email address to ensure your ticket request is accepted.* + + +**Prerequisite skills:** Some programming experience. + +**Learning Objectives** +* Version controlling your own project through Git & GitHub. +* Basic collaboration through forks on GitHub. +* Advanced team collaboration through branches on GitHub. +* Using the GitKraken GUI for a smooth version control experience. + +This course will be run online. + +
+ +We are delighted to be able to make free at point of use training available to the research community, to enable better +software and more open, reproducible research. However, **free at point of use training is not free**. The cost of a +course can easily run to thousands of pounds, if preparation costs are taken into account. + + +**If you sign up for a course, please make sure you either attend or cancel your booking.** Bookings can usually be +cancelled using [eventbrite.com](https://www.eventbrite.com) or, failing that, by emailing +[rse@sheffield.ac.uk](mailto:rse@sheffield.ac.uk). + + +Running courses that are not fully attended wastes our funding (which is provided by taxpayers, charities and students, +amongst others) and reduces our collective capacity to improve research outputs and researcher experiences. + + +Persistent failure to attend booked courses might result in you being excluded from future training opportunities. + +
+ +More details and registration via +[eventbrite](https://www.eventbrite.co.uk/e/git-github-through-gitkraken-from-zero-to-hero-registration-483170204087). + + +**Please note:** This workshop will run over 2 half days from 09:30-13:00 on Monday 6th and Tuesday 7th March 2023. + +**Course material:** + +
Together, We Create

Photo by +Jeremy Bishop on Unsplash

diff --git a/_events/workshop-2023-03-23-unix-shell.md b/_events/workshop-2023-03-23-unix-shell.md new file mode 100644 index 00000000..bd23fcb8 --- /dev/null +++ b/_events/workshop-2023-03-23-unix-shell.md @@ -0,0 +1,44 @@ +--- +title: "Unix Shell Fundamentals" +category: workshop +tags: unix shell +permalink: /training/workshop/2023-03-03-unix-shell +date: 2023-04-06 +end-date: 2023-04-06 +from: "12:30" +to: "16:30" +location: "Online" +speaker: "David Wilby, Neil Shephard" +social_image: /assets/images/hacker.jpg +--- + +**Please note: this workshop has been rearranged for Thursday 6th April. Apologies for any inconvenience caused.** + +Wallpapersden.com anonymous-hacker-working 1280x720 + +The Unix shell (which you may know as the terminal, console, or 'bash') has been around longer than most of its users have been alive. It has survived because it’s a powerful tool that allows users to perform complex and powerful tasks, often with just a few keystrokes or lines of code. It helps users automate repetitive tasks and easily combine smaller tasks into larger, more powerful workflows. Use of the shell is fundamental to a wide range of advanced computing tasks, including high-performance computing. This lesson will introduce you to this powerful tool. + +[**Register Here** via Eventbrite](https://www.eventbrite.co.uk/e/unix-shell-fundamentals-tickets-579026613187) + +Please register using a University of Sheffield email address to ensure that your reservation is accepted. + +## Who is this lesson for? +This lesson is for any and all researchers at the University of Sheffield who use computing in their research. The shell is an important and useful tool for anyone in this area and is vital for use of HPC systems, but it is commonly used for interacting with git and python among other tools as well as managing a computer and its files and folders. Whilst the Unix shell is particularly relevant to MacOS and Linux users, it is now commonly used in Windows as well. + +## What will we learn? +This is a fundamental lesson in which you will learn to use the shell for: + +* Navigating and working with files and directories, +* Combining commands to automate workflows, +* Speed up and streamline your workflow. + +We'll be teaching from [the Unix Shell lesson](https://swcarpentry.github.io/shell-novice/) from [The Carpentries](https://carpentries.org/). + +## How will it be taught? +This will be a online lesson taught via live coding and demonstration, you will get the most out of it by participating in the live exercises. + +## Prerequisite knowledge +There is very little prerequisite knowledge for this lesson except being familiar with your computer and the concepts of files and directories (folders). + +## Technical Requirements +Users of Windows, MacOS or Linux can take part in this lesson. Setup instructions will be circulated ahead of time. \ No newline at end of file diff --git a/_events/workshop-2023-05-02-sql.md b/_events/workshop-2023-05-02-sql.md new file mode 100644 index 00000000..89b5e387 --- /dev/null +++ b/_events/workshop-2023-05-02-sql.md @@ -0,0 +1,60 @@ +--- +title: "Data management with SQL for researchers" +category: workshop +tags: unix shell +permalink: /training/workshop/2023-05-02-sql +date: 2023-05-02 +end-date: 2023-05-02 +from: "12:30" +to: "16:30" +location: "G29 Computer Room, Hicks Building" +speaker: "Joe Heffer, Christopher Wild" +social_image: +--- + +[**Register Here** via Eventbrite](https://www.eventbrite.co.uk/e/data-management-with-sql-for-researchers-tickets-609308577357) + +Please register using a University of Sheffield email address to ensure that your reservation is accepted. + +# Data management with SQL for researchers + +**Please note that this is an in-person workshop on site in Sheffield** + +Databases are useful for both storing and using data effectively. Using a relational database serves several purposes. + +* It keeps your data separate from your analysis. This means there’s no risk of accidentally changing data when you analyze it. +* If we get new data we can rerun a query to find all the data that meets certain criteria. +* It’s fast, even for large amounts of data. +* It improves quality control of data entry (type constraints and use of forms in Access, Filemaker, etc.) +* The concepts of relational database querying are core to understanding how to do similar things using programming languages such as R or Python. + +This lesson will teach you what relational databases are, how you can load data into them and how you can query databases to extract just the information that you need. + + +## Who is this lesson for? +This lesson is for all researchers working with relatively large amounts of data. + +## What will we learn? +You will learn: +* What a relational database is and when to use it, +* What SQL is, +* How to query, aggregate, filter and combine data with SQL. + +## How will it be taught? +This will be a hands-on in-person workshop. + +## Prerequisite knowledge +There is no prerequisite knowledge for this lesson short of knowing how to use your computer. + +## Technical Requirements +You will need a working installation of DB Browser for SQLite which is available for all major operating systems, instructions will be circulated prior to the event. + +## Statement on free at point of use training + +We are delighted to be able to make free at point of use training available to the research community, to enable better software and more open, reproducible research. However, free at point of use training is not free. The cost of a course can easily run to thousands of pounds, if preparation costs are taken into account. + +If you sign up for a course, please make sure you either attend or cancel your booking. Bookings can usually be cancelled using eventbrite.com or, failing that, by emailing rse@sheffield.ac.uk. + +Running courses that are not fully attended wastes our funding (which is provided by taxpayers, charities and students, amongst others) and reduces our collective capacity to improve research outputs and researcher experiences. + +Persistent failure to attend booked courses might result in you being excluded from future training opportunities. diff --git a/_events/workshop-2023-05-09-python.md b/_events/workshop-2023-05-09-python.md new file mode 100644 index 00000000..f83bb1c8 --- /dev/null +++ b/_events/workshop-2023-05-09-python.md @@ -0,0 +1,51 @@ +--- +title: "Plotting and Programming with Python" +category: workshop +tags: unix shell +permalink: /training/workshop/2023-05-09-python +date: 2023-05-09 +end-date: 2023-05-10 +from: "14:00" +to: "17:00" +location: "Training Room 108, Computing Centre" +speaker: "Norbert Gyenge, Joe Heffer, Christopher Wild" +social_image: +--- + +[**Register Here** via Eventbrite](https://www.eventbrite.co.uk/e/plotting-and-programming-with-python-tickets-609605936767) + +Please note that this workshop will take place over 2 days from from 2-5pm on 9th May and 1-5pm on 10th May. + +## Who is this lesson for? +This lesson is an introduction to programming in Python 3 for people with little or no previous programming experience. It uses plotting as its motivating example but will teach you the essential foundations of programming in python. + +## What will we learn? +This workshop will use [software carpentry's plotting and programming in python lesson](http://swcarpentry.github.io/python-novice-gapminder/) which includes everything you need to get started with python via sections on: +- variables +- data types +- functions +- libraries/packages +- tabular data with pandas +- plotting +- lists +- for loops +- conditionals + +## How will it be taught? +This will be a practical and hands on, in-person workshop lead by expert instructors. + +## Prerequisite knowledge +No previous programming experience is required but you should have some knowledge of files and directories/folders. + +## Technical Requirements +You will need to install some software, all major operating systems (windows, macos and linux) are suitable and instructions will be send out prior to the workshop. + +## Statement on free at point of use training + +We are delighted to be able to make free at point of use training available to the research community, to enable better software and more open, reproducible research. However, free at point of use training is not free. The cost of a course can easily run to thousands of pounds, if preparation costs are taken into account. + +If you sign up for a course, please make sure you either attend or cancel your booking. Bookings can usually be cancelled using eventbrite.com or, failing that, by emailing rse@sheffield.ac.uk. + +Running courses that are not fully attended wastes our funding (which is provided by taxpayers, charities and students, amongst others) and reduces our collective capacity to improve research outputs and researcher experiences. + +Persistent failure to attend booked courses might result in you being excluded from future training opportunities. diff --git a/_events/workshop-2023-05-23-git.md b/_events/workshop-2023-05-23-git.md new file mode 100644 index 00000000..14def5fb --- /dev/null +++ b/_events/workshop-2023-05-23-git.md @@ -0,0 +1,60 @@ +--- +title: "Supercharge your research code with Git and GitHub" +category: workshop +tags: unix shell +permalink: /training/workshop/2023-05-23-git +date: 2023-05-23 +end-date: 2023-05-23 +from: "12:30" +to: "16:30" +location: "Online" +speaker: "David Wilby, Christopher Wild" +social_image: +--- + +[**Register Here** via Eventbrite](https://www.eventbrite.co.uk/e/supercharge-your-research-code-with-git-and-github-tickets-609326400667) + +# Supercharge your research code with Git and GitHub + +Git and GitHub have become essential tools in programming. +In this practical workshop, we will begin to learn how to use them for managing your code projects, +developing rapidly and safely on branches, tracking changes to your code and using GitHub for collaborative development, +remote backups and distributing your code openly. + +## Who is this lesson for? +Any researchers who write code will find something in this lesson that they will benefit from. +Whether you're a new PhD student, Postdoc, Fellow or Academic, it's always a good time to learn about source code management and version control with git. Once you've learned these skills, you'll never look back. + +## What will we learn? +We'll be working from the [Carpentries lesson on Version Control with Git](https://swcarpentry.github.io/git-novice/). +This lesson includes: + * Tracking the changes that are made to your code, + * Recovering older versions of files, + * Work on new ideas safely using branches, without messing up your working code, + * Sending your changes to GitHub, + * Working collaboratively, + * Making your work more open, + * Licensing your code. + +## How will it be taught? +This will be a practical online workshop in which you'll work through exercises along with the instructors. + +## Prerequisite knowledge +In this lesson we use Git from the Unix Shell. Some previous experience with the shell is expected, but isn’t _mandatory_. +There are some shell lessons scheduled, but if you'd like to brush up, we'd recommend [the Carpentries lesson on the Unix Shell](https://swcarpentry.github.io/shell-novice/). + +Note, that if you would prefer to use git from a graphical user interface, the Research Software Engineering Team at the University of Sheffield teach a workshop using GitKraken client. Look out for upcoming workshops at + +## Technical Requirements +Users of Windows, MacOS or any Linux distribution can take part in this course. If at all possible, we recommend using two monitors if you have them available. Some software may need to be installed prior to the course, instructions will be circulated to attendees beforehand. + + +## Statement on free at point of use training + +We are delighted to be able to make free at point of use training available to the research community, to enable better software and more open, reproducible research. However, free at point of use training is not free. The cost of a course can easily run to thousands of pounds, if preparation costs are taken into account. + +If you sign up for a course, please make sure you either attend or cancel your booking. Bookings can usually be cancelled using eventbrite.com or, failing that, by emailing rse@sheffield.ac.uk. + +Running courses that are not fully attended wastes our funding (which is provided by taxpayers, charities and students, amongst others) and reduces our collective capacity to improve research outputs and researcher experiences. + +Persistent failure to attend booked courses might result in you being excluded from future training opportunities. diff --git a/_events/workshop-2023-05-24-R.md b/_events/workshop-2023-05-24-R.md new file mode 100644 index 00000000..3d8688fa --- /dev/null +++ b/_events/workshop-2023-05-24-R.md @@ -0,0 +1,38 @@ +--- +title: "Data Analysis and Visualisation in R" +category: workshop +tags: unix shell +permalink: /training/workshop/2023-05-24-R +date: 2023-05-24 +end-date: 2023-05-24 +from: "12:30" +to: "16:30" +location: "Online" +speaker: "Elizabeth Oladapo, Joe Molloy" +social_image: +--- + +[**Register Here** via Eventbrite](https://www.eventbrite.co.uk/e/data-analysis-and-visualisation-in-r-tickets-609337814807) +**Currently Sold Out** + +This is an introduction to R designed for participants with no programming experience. These lessons can be taught in a day (~ 6 hours). They start with some basic information about R syntax, the RStudio interface, and move through how to import CSV files, the structure of data frames, how to deal with factors, how to add/remove rows and columns, how to calculate summary statistics from a data frame, and a brief introduction to plotting. The last lesson demonstrates how to work with databases directly from R. + +## What will we learn? +We will be learning from [the Carpentries lesson on data analysis and visualisation with R](https://datacarpentry.org/R-ecology-lesson/). + +## Prerequisite knowledge +This lesson assumes no prior knowledge of R or RStudio and no programming experience. + +## Technical Requirements +This lesson will require an installation of R and RStudio, instructions will be circulated prior. +Both are available for all major operating systems. + +## Statement on free at point of use training + +We are delighted to be able to make free at point of use training available to the research community, to enable better software and more open, reproducible research. However, free at point of use training is not free. The cost of a course can easily run to thousands of pounds, if preparation costs are taken into account. + +If you sign up for a course, please make sure you either attend or cancel your booking. Bookings can usually be cancelled using eventbrite.com or, failing that, by emailing rse@sheffield.ac.uk. + +Running courses that are not fully attended wastes our funding (which is provided by taxpayers, charities and students, amongst others) and reduces our collective capacity to improve research outputs and researcher experiences. + +Persistent failure to attend booked courses might result in you being excluded from future training opportunities. diff --git a/_events/workshop-2023-05-30-git-zero-hero.md b/_events/workshop-2023-05-30-git-zero-hero.md new file mode 100644 index 00000000..da796d18 --- /dev/null +++ b/_events/workshop-2023-05-30-git-zero-hero.md @@ -0,0 +1,64 @@ +--- +title: "git & GitHub through GitKraken - from Zero to Hero!" +category: gitzerohero +tags: collaboration, git, github, gitkraken +permalink: /training/workshop/2023-05-30-git-zero-hero +date: 2023-05-30 +end-date: 2023-06-01 +from: "09:30" +to: "13:00" +location: "Online" +speaker: "RSE Team" +--- + +## How can we effectively work together on the same code? + +**This is an introductory course, teaching the git and GitHub skills required to manage research code over it's +development lifecycle. These skills are essential for collaborative research teams.** + + +*This event is for University of Sheffield researchers and research students only. Please register with an +**@shef.ac.uk** or **@sheffield.ac.uk** email address to ensure your ticket request is accepted.* + + +**Prerequisite skills:** Some programming experience. + +**Learning Objectives** + +* Version controlling your own project through Git & GitHub. +* Basic collaboration through forks on GitHub. +* Advanced team collaboration through branches on GitHub. +* Using the GitKraken GUI for a smooth version control experience. + +This course will be run online. + +
+ +We are delighted to be able to make free at point of use training available to the research community, to enable better +software and more open, reproducible research. However, **free at point of use training is not free**. The cost of a +course can easily run to thousands of pounds, if preparation costs are taken into account. + + +**If you sign up for a course, please make sure you either attend or cancel your booking.** Bookings can usually be +cancelled using [eventbrite.com](https://www.eventbrite.com) or, failing that, by emailing +[rse@sheffield.ac.uk](mailto:rse@sheffield.ac.uk). + + +Running courses that are not fully attended wastes our funding (which is provided by taxpayers, charities and students, +amongst others) and reduces our collective capacity to improve research outputs and researcher experiences. + + +Persistent failure to attend booked courses might result in you being excluded from future training opportunities. + +
+ +More details and registration via +[eventbrite](https://www.eventbrite.co.uk/e/git-github-through-gitkraken-from-zero-to-hero-registration-626271082667). + + +**Please note:** This workshop will run over 2 half days from 09:30-13:00 on Tuesday 30th May and Thursday 1st June 2023. + +**Course material:** + +
Together, We Create

Photo by +Jeremy Bishop on Unsplash

diff --git a/_events/workshop-2023-06-05-intro-to-conda.md b/_events/workshop-2023-06-05-intro-to-conda.md new file mode 100644 index 00000000..96892751 --- /dev/null +++ b/_events/workshop-2023-06-05-intro-to-conda.md @@ -0,0 +1,77 @@ +--- +title: "Conda Environments for Effective and Reproducible Research" +category: introconda +tags: computing, conda, python, reproducibility, research, virtual environment +permalink: /training/workshop/2023-06-05-intro-to-conda +date: 2023-06-05 +end-date: 2023-06-05 +from: "09:30" +to: "13:30" +location: "Online Blackboard Virtual Learning Environment" +speaker: "RSE Team" +--- + +## How can we undertake research work in a consistent and reproducible computing environment? + +**This is an intermediate course, teaching the use of Conda virtual environments for reproducible research environments.** + + +*This event is for University of Sheffield researchers and research students only. Please register with a +University of Sheffield email address to ensure your ticket request is accepted.* + + +### Prerequisite skills + +- Basic shell commands (bash/zsh (Linux/MacOS); Powershell (Windows)). +- Some Python programming experience. + +### Learning Objectives + +- Understand what Conda is and why it is useful for managing packages and environments in research workflows. +- How to create, activate and delete Conda environments. +- How to install and manage packages in Conda environments. +- What Conda channels and packages are and how to use them. +- How to use pip in Conda environments. +- How to share your Conda environment. + +This course will be run online via the Blackboard Virtual Learning Environment. + + +### Setup + +Prior to attending, you need to install the software we are going to use. **Please ensure you have completed setup +before the course begins**. + +Instructions on how to install all the software required can be found on the [Setup +chapter](https://rse.shef.ac.uk/introduction-to-conda-for-data-scientists/setup/) of the course materials. If you have +any problems with your setup, please get in touch with us for assistance *before* the course begins. + + +
+ +We are delighted to be able to make free at point of use training available to the research community, to enable better +software and more open, reproducible research. However, **free at point of use training is not free**. The cost of a +course can easily run to thousands of pounds, if preparation costs are taken into account. + + +**If you sign up for a course, please make sure you either attend or cancel your booking.** Bookings can usually be +cancelled using [eventbrite.com](https://www.eventbrite.com) or, failing that, by emailing +[rse@sheffield.ac.uk](mailto:rse@sheffield.ac.uk). + + +Running courses that are not fully attended wastes our funding (which is provided by taxpayers, charities and students, +amongst others) and reduces our collective capacity to improve research outputs and researcher experiences. + + +Persistent failure to attend booked courses might result in you being excluded from future training opportunities. + +
+ +More details and registration via +[Eventbrite](https://www.eventbrite.co.uk/e/conda-environments-for-effective-and-reproducible-research-tickets-638698593687). + + +**Course material:** + + diff --git a/_events/workshop-2023-06-13-unix-shell.md b/_events/workshop-2023-06-13-unix-shell.md new file mode 100644 index 00000000..74cce65c --- /dev/null +++ b/_events/workshop-2023-06-13-unix-shell.md @@ -0,0 +1,42 @@ +--- +title: "Unix Shell Fundamentals" +category: workshop +tags: unix shell +permalink: /training/workshop/2023-03-03-unix-shell +date: 2023-04-06 +end-date: 2023-04-06 +from: "12:30" +to: "16:30" +location: "Online" +speaker: "Elizabeth Oladapo, Neil Shephard" +social_image: /assets/images/hacker.jpg +--- + +[**Register Here** via Eventbrite](https://www.eventbrite.co.uk/e/unix-shell-fundamentals-tickets-609588404327) + +Wallpapersden.com anonymous-hacker-working 1280x720 + +The Unix shell (which you may know as the terminal, console, or 'bash') has been around longer than most of its users have been alive. It has survived because it’s a powerful tool that allows users to perform complex and powerful tasks, often with just a few keystrokes or lines of code. It helps users automate repetitive tasks and easily combine smaller tasks into larger, more powerful workflows. Use of the shell is fundamental to a wide range of advanced computing tasks, including high-performance computing. This lesson will introduce you to this powerful tool. + +Please register using a University of Sheffield email address to ensure that your reservation is accepted. + +## Who is this lesson for? +This lesson is for any and all researchers at the University of Sheffield who use computing in their research. The shell is an important and useful tool for anyone in this area and is vital for use of HPC systems, but it is commonly used for interacting with git and python among other tools as well as managing a computer and its files and folders. Whilst the Unix shell is particularly relevant to MacOS and Linux users, it is now commonly used in Windows as well. + +## What will we learn? +This is a fundamental lesson in which you will learn to use the shell for: + +* Navigating and working with files and directories, +* Combining commands to automate workflows, +* Speed up and streamline your workflow. + +We'll be teaching from [the Unix Shell lesson](https://swcarpentry.github.io/shell-novice/) from [The Carpentries](https://carpentries.org/). + +## How will it be taught? +This will be a online lesson taught via live coding and demonstration, you will get the most out of it by participating in the live exercises. + +## Prerequisite knowledge +There is very little prerequisite knowledge for this lesson except being familiar with your computer and the concepts of files and directories (folders). + +## Technical Requirements +Users of Windows, MacOS or Linux can take part in this lesson. Setup instructions will be circulated ahead of time. \ No newline at end of file diff --git a/_events/workshop-2023-06-14-image-processing.md b/_events/workshop-2023-06-14-image-processing.md new file mode 100644 index 00000000..7135b9cc --- /dev/null +++ b/_events/workshop-2023-06-14-image-processing.md @@ -0,0 +1,52 @@ +--- +title: "Image Processing with Python" +category: workshop +tags: unix shell +permalink: /training/workshop/2023-06-14-image-processing +date: 2023-06-14 +end-date: 2023-06-16 +from: "10:00" +to: "16:00" +location: "Training Room 108, Computing Centre" +speaker: "Norbert Gyenge" +social_image: +--- + +[**Register Here** via Eventbrite](https://www.eventbrite.co.uk/e/image-processing-with-python-tickets-609579708317) + +_This workshop is for University of Sheffield researchers. Please ensure that you sign up using a University of Sheffield email address so that your booking is accepted._ + +**Note** This event will take place over two days 14th & 16th June from 10am to 4pm each day. + +This workshop uses Python and a variety of example images to teach the foundational concepts of image processing, and the skills needed to programmatically extract information from image data. + +## What will we learn? +This lesson will be taught from [the data carpentry Image Processing with Python lesson](https://datacarpentry.org/image-processing/) and includes: +- Scikit-image +- Masking +- Histograms +- Blurring +- Thresholding +- Automatic counting + +## How will it be taught? +This will be a practical, hands-on in-person workshop lead by expert instructors. + +## Prerequisite knowledge +This lesson assumes you have a working knowledge of Python and some previous exposure to the Bash shell. +Workshops are currently scheduled on the following dates: + - Python: 9-10 May + - Shell: 13 June + +## Technical Requirements +This lesson uses python, scikit-image. Installation instructions will be circulated prior. All major operating systems are suitable for this lesson. + +## Statement on free at point of use training + +We are delighted to be able to make free at point of use training available to the research community, to enable better software and more open, reproducible research. However, free at point of use training is not free. The cost of a course can easily run to thousands of pounds, if preparation costs are taken into account. + +If you sign up for a course, please make sure you either attend or cancel your booking. Bookings can usually be cancelled using eventbrite.com or, failing that, by emailing rse@sheffield.ac.uk. + +Running courses that are not fully attended wastes our funding (which is provided by taxpayers, charities and students, amongst others) and reduces our collective capacity to improve research outputs and researcher experiences. + +Persistent failure to attend booked courses might result in you being excluded from future training opportunities. diff --git a/_events/workshop-2023-06-26-bioinformatics.md b/_events/workshop-2023-06-26-bioinformatics.md new file mode 100644 index 00000000..156a6fe1 --- /dev/null +++ b/_events/workshop-2023-06-26-bioinformatics.md @@ -0,0 +1,51 @@ +--- +title: "Introduction to the Command Line for Bioinformatics" +category: workshop +tags: unix shell +permalink: /training/workshop/2023-06-26-bioinformatics +date: 2023-06-26 +end-date: 2023-06-26 +from: "09:30" +to: "16:30" +location: "The Diamond - Workroom 2" +speaker: "Mark Dunning" +social_image: +--- + +[**Register Here** via Eventbrite](https://www.eventbrite.co.uk/e/introduction-to-the-command-line-for-bioinformatics-tickets-609611884557) + +_This workshop is for University of Sheffield researchers. Please ensure that you sign up using a University of Sheffield email address so that your booking is accepted._ + +This course offers an introduction to working with Linux. We will describe the Linux environment so that participants can start to utilize command-line tools and feel comfortable using a text-based way of interacting with a computer. We give example of processing data arising from Next-Generation Sequencing experiments, in particular an RNA-seq experiment. However, the tools presented should be applicable to other types of high-throughput biological data. + + +## Pre-requisites +No prior programming experience is required. **You will need to bring your own laptop to the session**, but there is no software to install. Some familiarity with the experimental techniques used in Next-Generation Sequencing experiments would be advantageous. + +## Learning Outcomes +After this course you should be able to: + +* Connect to a Unix / Linux system +* Navigate around a file system by issuing commands; rather than using a Desktop environment +* Move and copy files and directories within the Linux system +* Work with text files +* Run programs from the command-line +* Configure a pipeline using the nextflow workflow manager + +## Aims +During this course you will learn about: + +* Interacting with a Linux system using a command-line interface +* A best-practice workflow for RNA-seq analysis +* The importance of reproducible analysis pipelines +* The nextflow system as an example of a workflow manager + +## Statement on free at point of use training + +We are delighted to be able to make free at point of use training available to the research community, to enable better software and more open, reproducible research. However, free at point of use training is not free. The cost of a course can easily run to thousands of pounds, if preparation costs are taken into account. + +If you sign up for a course, please make sure you either attend or cancel your booking. Bookings can usually be cancelled using eventbrite.com or, failing that, by emailing rse@sheffield.ac.uk. + +Running courses that are not fully attended wastes our funding (which is provided by taxpayers, charities and students, amongst others) and reduces our collective capacity to improve research outputs and researcher experiences. + +Persistent failure to attend booked courses might result in you being excluded from future training opportunities. diff --git a/_events/workshop-2023-07-12-astro.md b/_events/workshop-2023-07-12-astro.md new file mode 100644 index 00000000..672be782 --- /dev/null +++ b/_events/workshop-2023-07-12-astro.md @@ -0,0 +1,43 @@ +--- +title: "Foundations of Astronomical Data Science" +category: workshop +tags: unix shell +permalink: /training/workshop/2023-07-12-astro +date: 2023-07-12 +end-date: 2023-07-13 +from: "10:00" +to: "16:00" +location: "Training Room 108, Computing Centre" +speaker: "Norbert Gyenge, Joe Heffer" +social_image: +--- + +[**Register Here** via Eventbrite](https://www.eventbrite.co.uk/e/foundations-of-astronomical-data-science-tickets-609551172967) + + +_This workshop is for University of Sheffield researchers. Please ensure that you sign up using a University of Sheffield email address so that your booking is accepted._ + +The Foundations of Astronomical Data Science curriculum covers a range of core concepts necessary to efficiently study the ever-growing datasets developed in modern astronomy. In particular, this curriculum teaches learners to perform database operations (SQL queries, joins, filtering) and to create publication-quality data visualisations. Learners will use software packages common to the general and astronomy-specific data science communities (Pandas, Astropy, Astroquery combined with two astronomical datasets: the large, all-sky, multi-dimensional dataset from the Gaia satellite, which measures the positions, motions, and distances of approximately a billion stars in our Milky Way galaxy with unprecedented accuracy and precision; and the Pan-STARRS photometric survey, which precisely measures light output and distribution from many stars. + +## How will it be taught? +This will be an in-person practical workshop using [the Data Carpentry Foundations of Astronomical Data Science lesson](https://datacarpentry.org/astronomy-python/). + +## Prerequisite knowledge +This workshop assumes a working knowledge of python and some exposure to the bash shell. +There lessons available on the following dates: +* Python +* Bash Shell + +## Technical Requirements +You will need to install Python, Jupyter, and some additional libraries. Instructions will be circulated prior to the workshop. +Installations are available for all major operating systems. + +## Statement on free at point of use training + +We are delighted to be able to make free at point of use training available to the research community, to enable better software and more open, reproducible research. However, free at point of use training is not free. The cost of a course can easily run to thousands of pounds, if preparation costs are taken into account. + +If you sign up for a course, please make sure you either attend or cancel your booking. Bookings can usually be cancelled using eventbrite.com or, failing that, by emailing rse@sheffield.ac.uk. + +Running courses that are not fully attended wastes our funding (which is provided by taxpayers, charities and students, amongst others) and reduces our collective capacity to improve research outputs and researcher experiences. + +Persistent failure to attend booked courses might result in you being excluded from future training opportunities. diff --git a/_includes/contact.html b/_includes/contact.html index b20588ba..2ee937eb 100644 --- a/_includes/contact.html +++ b/_includes/contact.html @@ -10,7 +10,7 @@

Contact Us

- To contact the RSE team about seminars, training or JADE: rse-team-group@sheffield.ac.uk + Information and access to JADE II and Bede.

@@ -20,7 +20,7 @@

Contact Us

Queries regarding free research computing support/guidance should be raised via our Code clinic or - directed to University central IT support. + directed to the University IT helpdesk.

diff --git a/_includes/events_list_top10.html b/_includes/events_list_top10.html new file mode 100644 index 00000000..94ae5bb4 --- /dev/null +++ b/_includes/events_list_top10.html @@ -0,0 +1,17 @@ +{% assign events = (site.events | sort: 'date' | reverse) %} +
+ {% if events and events.size > 0 %} + {% for event in events limit:10 %} + {% if include.category %} + {% assign categories = include.category | split: "," %} + {% for category in categories %} + {% if category == event.category %} + {% include events_list_item.html event=event %} + {% endif %} + {% endfor %} + {% else %} + {% include events_list_item.html event=event %} + {% endif %} + {% endfor %} + {% endif %} +
\ No newline at end of file diff --git a/_includes/events_list_upcoming.html b/_includes/events_list_upcoming.html index e5eda425..64b89681 100644 --- a/_includes/events_list_upcoming.html +++ b/_includes/events_list_upcoming.html @@ -1,10 +1,25 @@ {% assign current_date = site.time | date: '%F' | date: '%s' %} {% assign events = site.events | sort: "date" %} +{% assign event_exists = false %}
-{% for evt in events %} - {% assign event_date = evt.date | date: '%s' %} +{% for event in events %} + {% assign event_date = event.date | date: '%s' %} {% if event_date >= current_date %} - {% include events_list_item.html event=evt %} + {% if include.category %} + {% assign categories = include.category | split: "," %} + {% for category in categories %} + {% if category == event.category %} + {% include events_list_item.html event=event %} + {% assign event_exists = true %} + {% endif %} + {% endfor %} + {% else %} + {% include events_list_item.html event=event %} + {% assign event_exists = true %} + {% endif %} {% endif %} {% endfor %} +{% unless event_exists %} + No events are currently scheduled, please join our mailing list to hear about new events. +{% endunless %}
diff --git a/_layouts/default.html b/_layouts/default.html index 0940c1f7..c16cad07 100644 --- a/_layouts/default.html +++ b/_layouts/default.html @@ -21,9 +21,11 @@ + {% if page.social_image %} + {% else %}{% endif %} - - + + @@ -35,6 +37,17 @@ + + + + + + + + + + + {% feed_meta %} @@ -45,13 +58,9 @@

- - The University of Sheffield - - Research Software Engineering Sheffield + The University of Sheffield Research Software Engineering

@@ -78,9 +87,29 @@

@@ -93,7 +122,7 @@

- + diff --git a/_layouts/event.html b/_layouts/event.html index 4f75b5f4..0eaffcdf 100644 --- a/_layouts/event.html +++ b/_layouts/event.html @@ -8,13 +8,15 @@
+ +

{{ page.title }}

Date -
{{ page.date | date: "%-d %B %Y" }} {% if page.end-date %} to {{ page.end-date | date: "%-d %B %Y" }}{% endif %} - {{ page.from}}{% if page.to %}-{{page.to}}{% endif %}
+
{{ page.date | date: "%-d %B %Y" }} {% if page.end-date %} to {{ page.end-date | date: "%-d %B %Y" }}{% endif %}{% if page.from %} - {{page.from}}{% endif %}{% if page.to %}-{{page.to}}{% endif %}
{% if page.location %}
@@ -30,7 +32,7 @@

{{ page.title }}

{% endif %} - +

All of our events may be recorded and shared via the University of Sheffield Kaltura platform so those who cannot attend may still benefit. We will consider your attendance implict consent to this.

{{ content }} diff --git a/_layouts/home.html b/_layouts/home.html index 898dbd43..e74eb9f5 100644 --- a/_layouts/home.html +++ b/_layouts/home.html @@ -5,97 +5,61 @@
-
-
-
- - Research Software Engineering Sheffield - - - Research - Software - Engineering - Sheffield - - -
+
+ RSE hero element
-
-

- Research Software Engineers (RSEs) are the people behind research software. This website is designed as a hub for Sheffield academics seeking help with research software and as a community for research software engineers. -

+
+

+ University of Sheffield
Research Software Engineering +

+

Supported by the Department of Computer Science and IT Services.

-
-
+
+
-
+

Newsletters

-
+
{% include newsletters_latest.html %}

Previous newsletters >> @@ -103,7 +67,7 @@

Newsletters


Blog

-
+
{% include post_list_prev10.html %}

@@ -113,9 +77,7 @@

Blog

-

Upcoming Events

-
- {% include events_list_upcoming.html %} + {% include events_list_top10.html %}

All of our upcoming and previous events >> @@ -127,6 +89,4 @@

Upcoming Events

-{% include contact.html %} - - +{% include contact.html %} \ No newline at end of file diff --git a/_layouts/post.html b/_layouts/post.html index 154f3693..283faa67 100644 --- a/_layouts/post.html +++ b/_layouts/post.html @@ -21,16 +21,23 @@ {{ content }} - -
-
+ +
+ -
{% if page.next.url %} - + + {% else %} + Next {% endif %}
+
+ Blog Home +
diff --git a/_layouts/sample.html b/_layouts/sample.html index ef2d4c15..8dbca838 100644 --- a/_layouts/sample.html +++ b/_layouts/sample.html @@ -9,8 +9,6 @@ - - diff --git a/_newsletters/2021-04-12-newsletter.md b/_newsletters/2021-04-12-newsletter.md new file mode 100644 index 00000000..5b295b97 --- /dev/null +++ b/_newsletters/2021-04-12-newsletter.md @@ -0,0 +1,221 @@ +--- +layout: post +title: April 2021 Newsletter +editor: Peter Heywood +slug: 2021-04-12-newsletter +date: 2021-04-12T11:00:00Z+0100 +tags: +category: +link: +description: +type: text +--- + +## University of Sheffield Research Software Engineering Team Newsletter April 2021 + +This is the 10th monthly newsletter from +the [Research Software Engineering Team][rses] at The University of Sheffield. +We aim to share our experiences and information of other communities for those using software for research. +This newsletter collects interesting events and opportunities over the coming month. +It also signposts to other resources that we find beneficial or interesting. +You may find the content interesting if you are someone in research using software, +are a person paid to develop software (like a Research Software Engineer (RSE)). +or are somewhere in-between (a *research developer*). + +To receive this newsletter as an email each month, please sign up to our [Google Group][rses-mail-list]. + +*All times are BST (UTC+01)* + + +### News + +**[New software TopoStats accelerates DNA discoveries](https://www.sheffield.ac.uk/news/new-software-topostats-accelerates-dna-discoveries)** + +A new software package allowing scientists to quantify how small circles of DNA change their structure has been developed by researchers at universities in the UK and Germany.
+[Bob Turner](https://rse.shef.ac.uk/contact/bob-turner/) of the UoS RSE team has been involved with this project. + + +### Future events + +**[GPU Technology Conference 2021](https://www.nvidia.com/en-us/gtc/), 12th - 16th April** + +The Spring 2021 edition of NVIDIA's GPU Technology Conference is being held as an online event from the 12th to the 16th of April. + +Registration for the event is free, providing access to live and recorded sessions, research posters, interactive panels, demos, podcasts, technical sessions, and more. +DLI training workshops can be purchased for an additional fee. + +[Dr Paul Richmond](https://paulrichmond.shef.ac.uk/) of the UoS RSE team is presenting a session "[Simulate the World and Everything in it: Complex Systems Simulations with FGPU2 [E31281] (Registration Required)](https://gtc21.event.nvidia.com/media/Simulate%20the%20World%20and%20Everything%20in%20it%3A%20Complex%20Systems%20Simulations%20with%20FGPU2%20%5BE31281%5D/1_jq4vdfcg) at 9AM on Tuesday April 13th. + +[Register Online for free](https://gtc21.event.nvidia.com/) + +--- + +**Introduction to Deep Learning Course with Tensorflow Keras (in Python), 15th April** + +A one-day introduction to deep learning with practical labs using Tensorflow Keras in Python. The session is led by [Twin Karmakharm](https://twin.uk.com). + +[Register with eventbrite](https://www.eventbrite.co.uk/e/144990036101) + +--- + +**Software Sustainability in Practice, 20th April** + +This is an informal event by the [Open Research Team at the University of York](https://www.york.ac.uk/library/info-for/researchers/support/), aimed at getting researchers together to hear +talks on and discuss the value of engaging in software sustainability +practices. It's quite short, and worth a listen in if you're interested! +There will be lots of overlap with stuff that has been discussed at +Coding Club, but different perspectives being presented. + +The host will be Emma Barnes (Research & High-performance Computing Team +Leader), and the speakers are as follows: +* [Prof Simon Hettrick](https://www.software.ac.uk/about/staff/person/simon-hettrick) +(Software Sustainability Institute Deputy Director) +* [Dr Jon Hill](https://www.york.ac.uk/environment/our-staff/jon-hill/) +(SSI Fellow and Senior Lecturer in Environment and Geography) +* [Emma Rand](https://www.york.ac.uk/biology/our-staff/emma-rand/) (SSI +Fellow and Senior Lecturer, Biology) +* Dr Peter Hill (EPSRC RSE Fellow, York Plasma Institute, OUR VERY OWN) +(reposted from N8 CIR list) + +[Register with eventbrite](https://www.eventbrite.co.uk/e/software-sustainability-in-practice-tickets-149685997849) + +--- + +**Introduction to Deep Learning Course with Keras (in R), 22nd April** + +A one-day introduction to deep learning with practical labs using Keras (Tensorflow) in R. The session is led by [Anna Krystalli](https://annakrystalli.me/). + +[Register with eventbrite](https://www.eventbrite.co.uk/e/144987819471) + +--- + +**Open Research Conversations: Electronic Lab Notebooks, 22nd April** + +A session of talks and discussions about the use of electronic lab notebooks in the research process and beyond. + +This is part of a [series of Open Research Conversations](https://www.eventbrite.co.uk/o/scholarly-communications-team-the-university-of-sheffield-library-7528476001) facilitated by [The University of Sheffield Library](https://www.sheffield.ac.uk/library), which include talks from researchers and other experts to share their experiences, promote best practices and discuss the challenges they are facing. + +[Register with eventbrite](https://www.eventbrite.co.uk/e/open-research-conversation-electronic-lab-notebooks-tickets-139420096261) + +--- + +**[GUIs-for-RS: Workshop on Graphical User Interfaces for Research Software](https://imperialcollegelondon.github.io/GUIs-for-RS/), 27th-29th April** + + +Research software has been a driving force behind the birth and rapid growth of informatics, but it was the appearance of graphical user interfaces (GUI) in the 1980s that made computers accessible to everyone. A GUI helps to reduce the learning curve for using software, increases the base of potential users and can ultimately increase citations and impact. Moreover, a well-designed GUI can perform validation and increase the robustness and reproducibility of the results, productively decoupling developers from users. + +The goal of these workshops is to help developers lose their fear - or reluctance - to invest time creating a GUI for their research software, and help them to give those first steps in the development of graphical user interfaces. The target audience is anyone who develops research software as part of their work, in any role, academic level and department. + +This event is organised by the [RSE team at Imperial College London](http://www.imperial.ac.uk/admin-services/ict/self-service/research-support/rcs/research-software-engineering/). + +[Register with eventbrite](https://guis4rs_april21.eventbrite.co.uk/) + +--- + +**Upcoming ARCHER 2 training events:** + +* Shared Memory programming with OpenMP, online self-service course. +* Understanding Package Performance, 19th April +* Efficient use of the HPE Cray EX Supercomputer ARCHER2, 20th - 22nd April +* High Performance Containers?, 21st April + +Details and registration for the courses can be found on their [upcoming training page](https://www.archer2.ac.uk/training/#upcoming-training). + + +--- + +**Upcoming [N8 CIR](https://n8cir.org.uk/) training events:** + +* Data Visualisation for Cultural Heritage Collections, 19th April. Registration closes on the 15th of April. + +Details and registration for the courses and events can be found on their [events page](https://n8cir.org.uk/events/). + +--- + +[**LunchBytes**](https://rse.shef.ac.uk/community/lunch-bytes/) is a monthly series of **short talks for those in the research community at TUOS who work with/write code, use/manage research data and use/manage research infrastructure**. Through these talks we come together as a community to discuss best practices and useful methods/tools. If you're interested in curating a session or giving a talk, get in touch at: lunchbytes-organisers-group@sheffield.ac.uk + +The **next LunchBytes event** is scheduled for the 12th of May, with a provisional theme of **Good practice in R**. +The exact date and details of talks will be advertised soon via the RSE team's [mailing list][rses-mail-list]. + +--- + +**csv,conf,v6 May 4-5 2021** + +The 6th edition of [`csv,conf`](https://csvconf.com/), a community conference for data makers everywhere, is being held online on the 4th and 5th of may. + +[Register with eventbrite](https://www.eventbrite.com/e/csvconfv6-tickets-144250211265) + +--- + +**DAFNI (Data and Analytics Facility for National Infrastructure) Launch Event, 5th July** + +The Data and Analytics Facility for National Infrastructure (DAFNI) is recognised as a world leader in infrastructure system research. DAFNI is based in Rutherford Appleton Laboratory in Harwell, Oxfordshire. Using advanced computing, DAFNI provides world leading infrastructure systems research capabilities to collate infrastructure data from multiple sources, map and model it, and use advanced visualisations to demonstrate and explore scenarios. + +[Register with eventbrite](https://www.eventbrite.co.uk/e/official-dafni-launch-event-registration-148644631093) + +### Previous events + +A recording of the **last LunchBytes event** (**Making GPU programming more accessible** on 2021-01-13) [is now available](https://rse.shef.ac.uk/events/lunchbytes-2021-04-01.html). + +--- + +The [Alan Turing Institute](https://www.turing.ac.uk/) is starting to upload videos from its recent [AI UK event](https://www.turing.ac.uk/ai-uk) on to its [Youtube channel](https://www.youtube.com/c/TheAlanTuringInstituteUK/videos). + +--- + +**IBM Training For Bede** During spring 2021 IBM delivered three training sessions on N8 CIR's new high-performance computing platform Bede. Recordings and slides from these sessions can be found on the [N8 CIR website](https://n8cir.org.uk/events/event-resource/ibm-training-bede/). + + +### Opportunities + + +**[SIGHPC](https://www.sighpc.org/) Computational and Data Science Fellowships are now open** + +SIGHPC fellowships funds up to $15K per year for a student in a graduate (masters or PhD) program anywhere in the world. +Nominations close April 30. + +More information can be found on the [Research IT News blogspot](https://newsrcg.blogspot.com/2021/03/sighpc-computational-and-data-science.html) and from [SIGHPC directly](https://www.sighpc.org/for-your-career/fellowships/). + +--- + +For RSE vacancies across the UK and elsewhere see the Society of RSE's [jobs board](https://society-rse.org/careers/vacancies/). + +### Web and Blogs + + +**[A Prime Case Study for Making MATLAB Code Go Faster](https://blogs.mathworks.com/loren/2021/03/16/a-prime-case-study-for-making-matlab-code-go-faster/)**. + + [Mike Croucher](https://www.mathworks.com/matlabcentral/profile/authors/20789457) (A former member of RSE Sheffield) presents a case study improving the performance of a MATLAB code. + +### Software and Updates + +--- + +**[Readme.so - The easiest way to create a README](https://readme.so/)** + +A simple web-based editor which allows you to quickly add and customize all the sections you need for your project's readme. + +### Resources + +Need access to managed desktop software? The University provides a **[Find a pc website](https://www.sheffield.ac.uk/findapc/now)** allowing students to remotely access PCs running University Desktop. + +--- + +If you think there are other great training resources we should advertise, please get in contact (`rse@sheffield.ac.uk`). + +### RSE Sheffield's Services + +The RSE Sheffield team aims to collaborate with you to help improve your research software. +We can provide dedicated staff to ensure that you can deliver excellent research software engineering on your research projects. + +The RSE Sheffield team provides free [Code Clinics][CCs] (in collaboration with [IT Services](its-res-it)), plus +[paid services][rse-service] that allow us to collaborate longer term. + + +[CCs]: https://rse.shef.ac.uk/support/code-clinic/ +[EPCC]: https://www.epcc.ed.ac.uk/ +[its-res-it]: https://www.sheffield.ac.uk/it-services/research/ +[its-workshops]: https://www.sheffield.ac.uk/it-services/research/one-day-sessions +[rse-service]: https://rse.shef.ac.uk/service/ +[rses-mail-list]: https://groups.google.com/a/sheffield.ac.uk/forum/#!forum/rse-group +[rses]: https://rse.shef.ac.uk/ diff --git a/_newsletters/2021-05-01-newsletter.md b/_newsletters/2021-05-01-newsletter.md new file mode 100644 index 00000000..112a1162 --- /dev/null +++ b/_newsletters/2021-05-01-newsletter.md @@ -0,0 +1,145 @@ +--- +layout: post +title: May 2021 Newsletter +editor: Robert (Bob) Turner +slug: 2021-05-01-newsletter +date: 2021-05-01T11:00:00Z+0100 +tags: +category: +link: +description: +type: text +--- + +## University of Sheffield Research Software Engineering Team Newsletter May 2021 + +Hi everyone! + +I wrote the introduction to our first newsletter slightly less than a year ago - **this is our twelfth monthly newsletter**. You may fire off a party popper, if it's safe to do so. I'm in the middle of helping the RSE team's [Anna Krystalli](https://rse.shef.ac.uk/contact/anna-krystalli/) deliver a [four day training course on reproducible research using R](https://annakrystalli.me/rrresearchACCE20/) to people beginning PhDs with the [ACCE DTP](https://acce.shef.ac.uk/). We'd love to bring this to more people and offer the option of a Python version in future. + +Another big thing this month... + +**[Hidden REF](https://hidden-ref.org) closes on the 14th May** - our [David Wilby](https://rse.shef.ac.uk/contact/david-wilby/) has done a tight [blog post](/https://rse.shef.ac.uk/blog/2021-04-15-hidden-ref/) on this. To my shame, I've not yet submitted anything to this excellent channel for recognising research contributions beyond papers, capturing work done by a diverse range of people and roles of real value inside or outside academia. Please consider a submission. + +All the best for May! + +Bob + +To receive this newsletter as an email each month, please sign up to our [Google Group][rses-mail-list]. **Tell you friends!** + +*All times are BST (UTC+01)* + + +### News + +**[Announcing the 2021 Software Sustainability Institute Fellows](https://software.ac.uk/news/announcing-2021-software-sustainability-institute-fellows)** SSI announces its 2021 fellows. + +--- + +**[Fortran Package Manager](https://github.com/fortran-lang/fpm)** A new FORTRAN package manager release - apparently this is big news in the FORTRAN community! + +### Future events + +**[Python for the Humanities](https://n8cir.org.uk/events/)** + +10-11 May + +**Registration is closed :(** + +> This two-part course will see participants learn the basics of the Python language before using these skills on Humanities projects rather than more generic programming examples. + +--- + +**[Lunch bytes: Putting the R into Reproducible Research](https://rse.shef.ac.uk/events/lunchbytes-2021-05-12.html)** + +12 May 2021 - 12:00-13:00 + +> R and its ecosystem of packages offers a wide variety of statistical and graphical techniques and is increasing in popularity as the tool of choice for data analysis in academia. In addition to its powerful analytical features, the R ecosystem provides a large number of tools and conventions to help support more open, robust and reproducible research. This includes tools for managing research projects, building robust analysis workflows, documenting data and code, testing code and disseminating and sharing analyses. In this talk we’ll take a whistle-stop tour of the breadth of available tools, demonstrating the ways R and the Rstudio integrated development environment can be used to underpin more open reproducible research and facilitate best practice + +--- + +**[Lunch bytes: Clinical Research Software](https://rse.shef.ac.uk/events/lunchbytes-2021-06-09.html)** + +9 June 2021 - 12:00-13:00 + +> Short talks on how University of Sheffield researchers and RSEs, and collaborators worldwide, are using REDCap and other platforms to handle clinical research data. The clinical research we will focus on here relates gathering data on people (e.g. evaluating interventions) rather than more fundamental laboratory research. + +--- + +**[Graphical User Interfaces for Research Software](https://imperialcollegelondon.github.io/GUIs-for-RS/)** + +Next running 22nd-24th June 2021 + +> Research software has been a driving force behind the birth and rapid growth of informatics, but it was the appearance of graphical user interfaces (GUI) in the 1980s that made computers accessible to everyone. + +--- + +**[SciPy2021](https://www.scipy2021.scipy.org/about)** + +July 12 - 18th + +> SciPy 2021, the 20th annual Scientific Computing with Python Conference will be a virtual conference July 12-18. SciPy® is a community dedicated to the advancement of scientific computing through open source Python software for mathematics, science, and engineering. The annual SciPy Conference allows participants from all types of organizations to showcase their latest projects, learn from skilled users and developers, and collaborate on code development. The full program will consist of two days of tutorials followed by three days of presentations, and concludes with two days of developer sprints on projects of interest to attendees. + +### Opportunities + +**[ARCHER2 eCSE Programme](https://www.archer2.ac.uk/ecse/)** + +> The 4th ARCHER2 eCSE call (ARCHER2 eCSE04) opened on the 20 Apr 2021. The deadline for submitting documents for technical evaluations is **16:00 on 18 May 2021**, with the final deadline for proposal submission being **16:00 on 08 Jun 2021**. + +> Through a series of regular calls, Embedded CSE (eCSE) support provides funding to the ARCHER2 user community to develop software in a sustainable manner to improve research on the ARCHER2 service. The funding allows the employment of a Research Software Engineer (RSE) to carry out software development of ARCHER2 software. This development work may include the implementation of algorithmic improvements, improvements to scalability, portability, sustainability or maintainability, or may include the addition of new functionality to a code which in turn will allow new science to be carried out. + +--- + +**[Submissions open for a PeerJ special issue on software](https://peerj.com/special-issues/84-software)** + +> **Submission deadline: July 16th, 2021** + +> Submit now to this PeerJ Computer Science Special Issue investigating the importance of - and best practice for - citing, indexing, and discovering software used as a scholarly research tool. + +### Web and Blogs + +**[The Hidden REF](https://rse.shef.ac.uk/blog/2021-04-15-hidden-ref/)** Find out more from an RSE perspective. + +--- + +**[Software is part of research and research software engineers should be part of how it is assessed](https://society-rse.org/software-is-part-of-research-and-research-software-engineers-should-be-part-of-how-it-is-assessed/)** Paul makes the case for RSEs to be more involved in review. + +--- + +**[Blog: On the Importance of Software to Research](https://blogs.mathworks.com/community/2021/04/22/on-the-importance-of-software-to-research/)** former team member Mike Croucher discusses this important topic. + +--- + +**[Using git cherry-pick to split up a branch (video)](https://rse.shef.ac.uk/blog/2021-04-23-cherry-pick/)** Bob did a vlog - it's had 23,000,000 views. Sorry, 23. Can we make it 24? It'll be useful information when you need it! + +--- + +**[Simulate the world and Everything in it with FLAME GPU 2](https://www.youtube.com/watch?v=NRRW6EDClYM&t=19s)** Never to be outdone, Paul and the FLAME team also have a video. Do they make good on their ambitious title. 28 viewers say "maybe". If you're looking for an agent-based modelling framework - check it. + +--- + +**[Major CodeCov security issue](https://www.theregister.com/2021/04/19/codecov_warns_of_stolen_credentials/)** A lot of us have been spending time trying to fix this in our Continuous Integration (CI) this month. In retrospect, downloading and executing a script without looking at it is maybe not a great plan. But there has to be trust at some point. + +--- + +**[Introduction to PyKale, a library for knowledge-aware machine learning from multiple sources](https://www.youtube.com/watch?v=i5BYdMfbpMQ)** The PyKale team introduces its new software! + +--- + +**[GUIs for research software: Why are they relevant?](https://zenodo.org/record/4722579#.YJOm5rVKhPY)** Slides and recording. + +### RSE Sheffield's Services + +The RSE Sheffield team aims to collaborate with you to help improve your research software. +We can provide dedicated staff to ensure that you can deliver excellent research software engineering on your research projects. + +The RSE Sheffield team provides free [Code Clinics][CCs] (in collaboration with [IT Services](its-res-it)), plus +[paid services][rse-service] that allow us to collaborate longer term. + +[CCs]: https://rse.shef.ac.uk/support/code-clinic/ +[EPCC]: https://www.epcc.ed.ac.uk/ +[its-res-it]: https://www.sheffield.ac.uk/it-services/research/ +[its-workshops]: https://www.sheffield.ac.uk/it-services/research/one-day-sessions +[rse-service]: https://rse.shef.ac.uk/service/ +[rses-mail-list]: https://groups.google.com/a/sheffield.ac.uk/forum/#!forum/rse-group +[rses]: https://rse.shef.ac.uk/ diff --git a/_newsletters/2021-06-07-newsletter.md b/_newsletters/2021-06-07-newsletter.md new file mode 100644 index 00000000..46e01ae8 --- /dev/null +++ b/_newsletters/2021-06-07-newsletter.md @@ -0,0 +1,227 @@ +--- +layout: post +title: June 2021 Newsletter +editor: Robert Chisholm +slug: 2021-06-07-newsletter +date: 2021-06-07T11:00:00Z+0100 +tags: +category: +link: +description: +type: text +--- + +## University of Sheffield Research Software Engineering Team Newsletter June 2021 + + +This is the 12th monthly newsletter from the [Research Software Engineering Team](https://rse.shef.ac.uk/) at The University of Sheffield. + +We aim to share our experiences and information of other communities for those using software for research. This newsletter collects interesting events and opportunities over the coming month. It also signposts to other resources that we find beneficial or interesting. You may find the content interesting if you are someone in research using software, are a person paid to develop software (like a Research Software Engineer (RSE)), or are somewhere in-between (a research developer). + +To receive this newsletter as an email each month, please sign up to our [Google Group][rses-mail-list]. **Tell you friends!** + +To suggest content for a future newsletter either complete [this short form](https://forms.gle/YyQiNjg79tXaLZHq8) or drop us an [email](mailto:rse@sheffield.ac.uk). We can’t promise that we’ll publish everything that’s proposed but we are keen to feature submissions from the research community at the University of Sheffield. + +*All times are BST (UTC+01)* + + +### News + +#### SeptembRSE + +The [Conference of Research Software Engineers](https://septembrse.society-rse.org/) is returning this year with a fully online event. + +6 - 30th September 2021 + +> On Monday 6th September 2021, the RSE Community will reunite for SeptembRSE, the Fifth Conference of Research Software Engineers. The conference is a chance for anyone, whether you consider yourself a Research Software Engineer or not, to meet and discuss the development and recognition of research software. + +> This year the entire conference has moved online. The flexibility achievable with online events allows the sessions to be spread out so that they occupy the whole of September. All sessions will be streamed, recorded and published, meaning that you will have a whole month of material to explore throughout September at a time that is best for you! + +> Submissions are now being taken for; Talks, Posters, Walkthroughs, Workshops, Panels and Discussions. So if you have an idea and want to get involved with the wider RSE community submit your proposal now! + +[Submission Deadline](https://septembrse.society-rse.org/calls/): July 2nd 2021 *(Discussion topic submission closes early on June 18th 2021). + +#### AHRC Software Requirements Survey + +The SSI, with the help of others in the Arts and Humanities Research Council (AHRC) community has put together a survey of digital / software requirements for the AHRC. Complete if it’s relevant to your work, e.g. you are in the AHRC funding remit and please forward it to others who could provide input. + +They are working to improve the understanding of the digital practices people undertake or wish they could undertake in the arts, humanities and GLAM (galleries, libraries, archives and libraries) communities so that they can tailor their approach to supporting this community, and make recommendations to others working in the field. + +The survey asks about your views on digital-tools/software, your experience of developing digital-tools/software, and your practices and preferences for recruiting help with digital tool/software development. + +This survey’s focus is the AHRC Research Community and therefore it has a UK focus; participants should be connected with a UK based institution. They will share the findings with AHRC to help them direct their digital infrastructure funding to better align with the communities’ needs. Note they will not share any Personally Identifiable Information (PII) as defined by GDPR with the AHRC. + +They are actively seeking views from people who do not develop digital tools / software. They are seeking input from all roles, including senior decision makers, researchers, curators, librarians and software developers in the AHRC remit. As the survey is filled in from an individual perspective, we ask that you also forward it to members of your teams / network. + +The survey is available at: [http://bit.ly/ahrc-digital-requirements-survey](http://bit.ly/ahrc-digital-requirements-survey), and should only take 15 minutes to complete. It closes at the end July 2021 after which there will be a prize draw. You will have a chance to win one of four £50 shopping vouchers (please opt-in during the survey). + +### Future Events + +**[Lunch bytes: Clinical Research Software](https://rse.shef.ac.uk/events/lunchbytes-2021-06-09.html)** + +9 June 2021 - 12:00-13:00 + +> Short talks on how University of Sheffield researchers and RSEs, and collaborators worldwide, are using [REDCap](https://www.project-redcap.org/) and other platforms to handle clinical research data. The clinical research we will focus on here relates gathering data on people (e.g. evaluating interventions) rather than more fundamental laboratory research. + +Planned talks: + +* *REDCap features, setup and maintenance* +* *Transcriptomic Responses for the Identification of Pathogens* +* *Using REDCap to capture the economic impact on households of seeking care for children sick with, or exposed to, tuberculosis in three sub-Saharan African countries* +* *Using REDCap alongside an existing Electronic Data Capture (EDC) system: Fitting in with existing processes and comparing functionality between systems* + +--- + +**[Funder panel: Challenges & opportunities of funding research software](https://www.eventbrite.co.uk/e/funder-panel-challenges-opportunities-of-funding-research-software-tickets-157219609083?aff=ebdssbonlinesearch)** + +14 June 2021 - 10:00-11:15 + +Software is used across research cycle - from controlling equipment to collect research data to enabling visualisation of complex simulations. Developing good research software engineering (RSE) practices to create better software can improve the reproducibility, reusability and quality of your research. + +The panel discussion which will focus on: + +Opportunities available to support research software from funders including the Wellcome Trust (e.g. [Open Research Fund](https://wellcome.org/what-we-do/our-work/open-research#funding-opportunities--b7c8)) and Sage Publishing (e.g . [software tools for social science research](https://group.sagepub.com/blog/sage-concept-grants-applications-open-for-new-research-software-proposals)). + +*Part of the UCL Festival of Code* + +--- + +**[Coding In The Open: A week of lunchtime talks on working with open principles](https://codingedi.github.io/)** + +14-18 June 2021 - 13:00-1400 *each day* + +Coding In The Open is a week of 1 hour seminars happening June 14th - 18th, online. + +They aim to bring the discussion around Open Source practices - that is, the collaboration across organisations to achieve bigger things - to a new audience. + +They've some fantastic speakers lined up from public, private, charity and academic sectors to talk about what being “open” means to them, and how it improves their world. + +The schedule is yet to be announced, but you can sign up [here](https://meetup.com/EdinbR/events/278595242). + +*Hosted by the Edinburgh R UserGroup* + +--- + +**[Research-IT forum: Image Processing Techniques and Technology](https://www.scipy2021.scipy.org/about)** + +16 June 2021 - 09:30-12:15 + +> The Research-IT forum is a regular event providing updates on developments relating to research computing covering research software, computational science, data science, qualitative and quantitative analysis and the management of research outputs. It is a forum where researchers can showcase their work in an environment conducive to creative discussion + +> This event will explore image processing at the University of Sheffield. As well as presenting an overview of the research topic, each of our speakers will discuss their image processing techniques. This can include; image generation, image comparison, image transformations, image registration, data extraction from images, image classification or image segmentation. + +--- + +**[AHUG Hackathon: Cloud Hackathon for Arm-based HPC](https://aws.amazon.com/blogs/hpc/aws-arm-hpc-hackathon-2021/)** + +Registration closes 25th June 2021 +12 - 16th July 2021 + +> The Arm HPC User Group (AHUG) has announced the latest Arm HPC hackathon in collaboration with Arm and AWS. A week long interactive, and competitive, hackathon addressing HPC application porting and optimizing in the cloud. + +> This event will challenge teams to get open-source HPC software running on Arm HPC systems (specifically AWS Graviton2). There are some great prizes up for grabs if this takes your interest. + +--- + +**[SciPy2021](https://www.scipy2021.scipy.org/about)** + +12 - 18th July 2021 + +> SciPy 2021, the 20th annual Scientific Computing with Python Conference will be a virtual conference July 12-18. SciPy® is a community dedicated to the advancement of scientific computing through open source Python software for mathematics, science, and engineering. The annual SciPy Conference allows participants from all types of organizations to showcase their latest projects, learn from skilled users and developers, and collaborate on code development. The full program will consist of two days of tutorials followed by three days of presentations, and concludes with two days of developer sprints on projects of interest to attendees. + +--- + +**[N8 CIR RSE Meet-Up](https://n8cir.org.uk/events/rse-meet-2021/)** + +21 June 2021 - 10:00-13:00 + +N8 CIR’s annual RSE meet-up returns in June! + +Of necessity the event will take place online and will feature RSE case studies, a speed networking session before groups discuss ways and means of enhancing collaboration between RSEs and groups across the N8 Research Partnership. + +If you would like to present your work as a ten-minute RSE case study please get in touch with [marion.weinzierl@durham.ac.uk](mailto:marion.weinzierl@durham.ac.uk) + +--- + +**[SeptembRSE](https://septembrse.society-rse.org/)** + +[Submission Deadline](https://septembrse.society-rse.org/calls/): July 2nd 2021 *(Discussion topic submission closes early on June 18th 2021). + +6 - 30th September 2021 + +*2021 Research Software Engineers (online) Conference. See News section above for full details.* + +### Previous Events + +**[Lunch bytes: Putting the R into Reproducible Research](https://rse.shef.ac.uk/events/lunchbytes-2021-05-12.html)** + +In May, our Anna delivered a great talk about how R can be used for reproducibile research. If you weren't able to attend, a [video](https://digitalmedia.sheffield.ac.uk/media/Lunch+bytes+6A+Putting+the+R+into+Reproducible+Research/1_kwofatj6) of the event and the [Slides](http://bit.ly/r-in-repro-research-dc-srse) are now available. + +### Opportunities + +**[ELIXIR-UK Vacancies in Training and Community Coordination](https://elixiruknode.org/uncategorized/we-are-hiring-three-new-roles-in-data-steward-training-and-fellowship-coordination/)** + +> **Application deadline: June 21st, 2021** + +> The university of Bradford has three new roles as part of their new ELIXIR-UK UKRI funded FAIR Data Stewardship Training Project. These roles are a great opportunity for people passionate about training to join the ELIXIR-UK team and work with experts in the area of Data Management to help us deliver this project. + +**[University of Sheffield Library's Open Research Prize](https://www.sheffield.ac.uk/library/research/openresearchprize)** + +> **Submission deadline: 5pm June 23rd, 2021** + +> All reserach students and staff can enter this competition with the chance to win cash prizes. Submit a 750 word case study describing how you've engaged with open research, the challenges faced and impact. + + +**[Submissions open for a PeerJ special issue on software](https://peerj.com/special-issues/84-software)** + +> **Submission deadline: July 16th, 2021** + +> Submit now to this PeerJ Computer Science Special Issue investigating the importance of - and best practice for - citing, indexing, and discovering software used as a scholarly research tool. + +### Web and Blogs + +* [JuptyerLab now has collaboriative editing!](https://twitter.com/kevin_jahns/status/1391766296937832453?s=19) +* [Methods in Research Software Engineering](https://rse.shef.ac.uk/blog/2021-05-25-methods-ug-talk/): David W from our team delivered a talk to the COmputer Science undergrads, however it works as a good introduction to research software engineering for any level. +* [Git useful resources](https://rse.shef.ac.uk/blog/2021-05-07-git-useful-resources/): Fariba from our team has curated a great list of resources for learning Git. +* [How COVID broke the evidence pipeline](https://www.nature.com/articles/d41586-021-01246-x): The pandemic stress-tested the way the world produces evidence — and revealed all the flaws. +* [Rhumba: the fast R distribution is available on Windows!](https://adelsalle.medium.com/rhumba-the-fast-r-distribution-is-available-on-windows-fa975b2aefa2): New features, cross-platform +* [Flat Data](https://octo.github.com/projects/flat-data): Bring working datasets into your repositories (and version them), because local datasets are faster and easier than remote ones. +* [Mental Health in Research Software Engineering](https://society-rse.org/mental-health-in-research-software-engineering/): Dave Horsfall discusses the actions he's taking to support the mental health of early career researchers. +* [Building a career path for research software engineers](https://iris-hep.org/2021/05/12/career-path-rse.html): The origins and future of the research software engineer role. +* [How Europe’s €100-billion science fund will shape 7 years of research](https://www.nature.com/articles/d41586-021-00496-z): As Horizon Europe issues its first call for grants, Nature reviews some big changes — from open science to goal-oriented ‘missions’. + +### Training + +**[Archer Message-Passing with MPI](https://www.archer2.ac.uk/training/courses/210000-mpi-self-service/)** + +This new online self-service course uses the de facto standard for message passing, the Message Passing Interface (MPI). It covers: + +* point-to-point communication +* non-blocking operations +* derived datatypes +* virtual topologies +* collective communication +* general design issues + +This self-service course includes a series of Lecture videos (with closed captions and downloadable PDF slides) which you can work through at your own pace and in your own time. + +Hands-on practical programming exercises are included, with the option of working in either C, C++ or Fortran. + +Access to ARCHER2 is provided for participants to build and run the exercises. + + +### RSE Sheffield's Services + +The RSE Sheffield team aims to collaborate with you to help improve your research software. +We can provide dedicated staff to ensure that you can deliver excellent research software engineering on your research projects. + +The RSE Sheffield team provides free [Code Clinics][CCs] (in collaboration with [IT Services][its-res-it]), plus +[paid services][rse-service] that allow us to collaborate longer term. + +[CCs]: https://rse.shef.ac.uk/support/code-clinic/ +[EPCC]: https://www.epcc.ed.ac.uk/ +[its-res-it]: https://www.sheffield.ac.uk/it-services/research/ +[its-workshops]: https://www.sheffield.ac.uk/it-services/research/one-day-sessions +[rse-service]: https://rse.shef.ac.uk/service/ +[rses-mail-list]: https://groups.google.com/a/sheffield.ac.uk/forum/#!forum/rse-group +[rses]: https://rse.shef.ac.uk/ diff --git a/_newsletters/2021-07-07-newsletter.md b/_newsletters/2021-07-07-newsletter.md new file mode 100644 index 00000000..fee89235 --- /dev/null +++ b/_newsletters/2021-07-07-newsletter.md @@ -0,0 +1,187 @@ +--- +layout: post +title: July 2021 Newsletter +editor: David Wilby +slug: 2021-07-07-newsletter +date: 2021-07-07T16:00:00Z+0100 +tags: +category: +link: +description: +type: text +--- + +## University of Sheffield Research Software Engineering Team Newsletter July 2021 + +Firstly, welcome to the >100 new members of the RSE mailing list this month. This is the monthly newsletter from the [Research Software Engineering Team](https://rse.shef.ac.uk/) at The University of Sheffield. + +We aim to share our experiences and information of other communities for those using software for research. This newsletter collects interesting events and opportunities over the coming month. It also signposts to other resources that we find beneficial or interesting. You may find the content interesting if you are someone in research using software, are a person paid to develop software (like a Research Software Engineer (RSE)), or are somewhere in-between (a research developer). + +To receive this newsletter as an email each month, please sign up to our [Google Group][rses-mail-list]. **Tell your friends!** + +To suggest content for a future newsletter either complete [this short form](https://forms.gle/YyQiNjg79tXaLZHq8) or drop us an [email](mailto:rse@sheffield.ac.uk). We can’t promise that we’ll publish everything that’s proposed but we are keen to feature submissions from the research community at the University of Sheffield. + +*All times are BST (UTC+01)* + + +### News + +#### BBSRC Review of Technology Development in the Biosciences + +> As part of UKRI-BBSRC’s review of support for technology development for the biosciences, we are launching a community survey in order to begin collating views and to provide an early-stage opportunity for input from across the bioscience/technology development community. + +Submit your contributions to the [survey here](https://www.surveymonkey.co.uk/r/SCHGKDZ) + +#### SeptembRSE + +The [Conference of Research Software Engineers](https://septembrse.society-rse.org/) is returning this year with a fully online event. + +6 - 30th September 2021 + +> On Monday 6th September 2021, the RSE Community will reunite for SeptembRSE, the Fifth Conference of Research Software Engineers. The conference is a chance for anyone, whether you consider yourself a Research Software Engineer or not, to meet and discuss the development and recognition of research software. + +> This year the entire conference has moved online. The flexibility achievable with online events allows the sessions to be spread out so that they occupy the whole of September. All sessions will be streamed, recorded and published, meaning that you will have a whole month of material to explore throughout September at a time that is best for you! + + + +#### Research Software Camp “Beyond the spreadsheet”: call for ideas +>Do you use spreadsheets to conduct your research? Do you prefer a specific tool or approach when using spreadsheets? What events would you run to help other researchers using spreadsheets? Are you interested in sharing your experience or stories of research data management and analysis with spreadsheets? We’d like to hear from you! + +> We have a few ideas for running our live sessions and commissioning content for the Camp, but we’re asking our community about what would be useful to hear/read about and learn from around the use of spreadsheets in research, what works, and taking the first steps into other computation techniques. + +[Submit ideas by the end of July](https://www.software.ac.uk/news/research-software-camp-beyond-spreadsheet-call-ideas) + +#### FAIR Principles for Research Software +The [Research Data Alliance](https://www.rd-alliance.org/) has developed a set of principles for research software inspired by the FAIR principles for research data (findable, accessible, interoperable, reusable). + +The community review period for the guiding document is open until the 11th July [here](https://www.rd-alliance.org/group/fair-research-software-fair4rs-wg/outcomes/fair-principles-research-software-fair4rs) + +#### AHRC Software Requirements Survey + +The SSI, with the help of others in the Arts and Humanities Research Council (AHRC) community has put together a survey of digital / software requirements for the AHRC. Complete if it’s relevant to your work, e.g. you are in the AHRC funding remit and please forward it to others who could provide input. + +They are working to improve the understanding of the digital practices people undertake or wish they could undertake in the arts, humanities and GLAM (galleries, libraries, archives and libraries) communities so that they can tailor their approach to supporting this community, and make recommendations to others working in the field. + +The survey asks about your views on digital-tools/software, your experience of developing digital-tools/software, and your practices and preferences for recruiting help with digital tool/software development. + +This survey’s focus is the AHRC Research Community and therefore it has a UK focus; participants should be connected with a UK based institution. They will share the findings with AHRC to help them direct their digital infrastructure funding to better align with the communities’ needs. Note they will not share any Personally Identifiable Information (PII) as defined by GDPR with the AHRC. + +They are actively seeking views from people who do not develop digital tools / software. They are seeking input from all roles, including senior decision makers, researchers, curators, librarians and software developers in the AHRC remit. As the survey is filled in from an individual perspective, we ask that you also forward it to members of your teams / network. + +The survey is available at: [http://bit.ly/ahrc-digital-requirements-survey](http://bit.ly/ahrc-digital-requirements-survey), and should only take 15 minutes to complete. It closes at the end July 2021 after which there will be a prize draw. You will have a chance to win one of four £50 shopping vouchers (please opt-in during the survey). + +### Future Events + +**Juliacon 2021** + +28-30th July 2021 (online) + + + +The annual conference championing the Julia language is here, online and everywhere at the end of July. + +[Register here](https://juliacon.org/2021/tickets/) + +--- + +**LunchBytes: SeptembRSE Satellite Special** + +Topic: TBD + +As part of this year's [SeptembRSE](https://septembrse.society-rse.org/) conference (details above), our very own LunchBytes series will be taking part as a satellite session. [Get your topic suggestions in on the JamBoard](https://jamboard.google.com/d/1-51cRf0pwZl8O10CnLeJGAqKcnbww-QGaYjszFK-H38/) and [watch this space](https://rse.shef.ac.uk/community/lunch-bytes/) for details. + +--- + +**[SciPy2021](https://www.scipy2021.scipy.org/about)** + +12 - 18th July 2021 + +> SciPy 2021, the 20th annual Scientific Computing with Python Conference will be a virtual conference July 12-18. SciPy® is a community dedicated to the advancement of scientific computing through open source Python software for mathematics, science, and engineering. The annual SciPy Conference allows participants from all types of organizations to showcase their latest projects, learn from skilled users and developers, and collaborate on code development. The full program will consist of two days of tutorials followed by three days of presentations, and concludes with two days of developer sprints on projects of interest to attendees. + +--- + +**[SeptembRSE](https://septembrse.society-rse.org/)** + +[Submission Deadline](https://septembrse.society-rse.org/calls/): July 2nd 2021 + +6 - 30th September 2021 + +*2021 Research Software Engineers (online) Conference. See News section above for full details.* + +### Previous Events + +In the last month, we've held not one but two LunchBytes sessions, recordings of the sessions can be found at the links below: + +* [Lunch bytes: Clinical Research Software](https://rse.shef.ac.uk/events/lunchbytes-2021-06-09.html) +* [Lunch bytes: Challenges in Deploying Machine Learning, or What is rarely talked about at ML conferences.](https://rse.shef.ac.uk/events/lunchbytes-2021-07-05.html) (Video to follow) + +### Opportunities + +**[EPSRC Call: Software for Research Communities](https://www.ukri.org/opportunity/software-for-research-communities/)** + + +The Research Software Engineering (RSE) Team () are delighted to see the new call from the EPSRC: “Software for research communities” (). +It is something we’ve been advocating for for some time and it’s great to see it finally happening! The call specifically is specifically looking for inclusion of RSEs as part of the project delivery and we would be very happy to discuss with PIs about inclusion of RSEs from our team. + +Researchers can cost our engineers in funding applications at a proportion of full time equivalent, bringing in software engineering expertise without the need to hire a dedicated RSE. If this is of interest to you in the context of this call, or any other funding application, please contact at the earliest opportunity to talk about the project. We can provide useful advice even at an early stage, and we need to know well in advance about applications being submitted so we can do our best to arrange engineers with the best skills and experience when the project is (fingers-crossed!) funded. + +--- + +**[Submissions open for a PeerJ special issue on software](https://peerj.com/special-issues/84-software)** + +> **Submission deadline: July 16th, 2021** + +> Submit now to this PeerJ Computer Science Special Issue investigating the importance of - and best practice for - citing, indexing, and discovering software used as a scholarly research tool. + +--- + +**[FAIR Data Stewardship Training Fellowship](https://www.eventbrite.co.uk/e/high-performance-computing-for-healthcare-tickets-144650454403)** +>ELIXIR-UK has partnered with the Software Sustainability Institute to build a Fellowship Programme to support and fund Data Stewards to train researchers in how to manage and share data in the life sciences. This programme is funded by the UKRI innovation scholars award and we look to recruit a total cohort of 20 Data Stewards in the Life Sciences through 2 rounds of applications through 2021-2022. + +>Each Fellow will receive a £3,000 honorarium, subject to tax, to support activities focused on writing and delivering training material in the arena of data management to a target audience of individuals working in the Life Sciences. This Fellowship aims to recruit applicants who work with data day-to-day, to build a community of Data Stewards with practical experience of contemporary life science data management in the UK. + +>This is a fantastic opportunity for those passionate about data management and training. We envisage that this programme will contribute to the professionalisation of data stewardship, which has often been underrepresented in the life science community. Join us and become empowered to develop communities, network with others who share your goals and learn new skills that will benefit you and your collaborators. + +>Fellows will be given training, develop teaching material in their area of specialism and take our data steward training into their own institutions. We hope that this will expand the reach of data steward training across the UK and to provide a network for people working in this area. + +### Web and Blogs + +* [Better performative reproducibility [Nature]](https://www.nature.com/articles/d41586-021-01824-z) - "Well-meant changes to improve science could become empty gestures unless underlying values change. " +* [Machine Learning in the RSE Team [RSE Sheffield Blog]](https://rse.shef.ac.uk/blog/2021-06-18-ml-intro-vid/) - A brief intro to where Machine Learning fits into the work of the University of Sheffield RSE team. +* [Impact factor abandoned by Dutch university in hiring and promotion decisions [Nature]](https://www.nature.com/articles/d41586-021-01759-5) - "Faculty and staff members at Utrecht University will be evaluated by their commitment to open science." + +### Training + +**[Archer Message-Passing with MPI](https://www.archer2.ac.uk/training/courses/210000-mpi-self-service/)** + +This new online self-service course uses the de facto standard for message passing, the Message Passing Interface (MPI). It covers: + +* point-to-point communication +* non-blocking operations +* derived datatypes +* virtual topologies +* collective communication +* general design issues + +This self-service course includes a series of Lecture videos (with closed captions and downloadable PDF slides) which you can work through at your own pace and in your own time. + +Hands-on practical programming exercises are included, with the option of working in either C, C++ or Fortran. + +Access to ARCHER2 is provided for participants to build and run the exercises. + + +### RSE Sheffield's Services + +The RSE Sheffield team aims to collaborate with you to help improve your research software. +We can provide dedicated staff to ensure that you can deliver excellent research software engineering on your research projects. + +The RSE Sheffield team provides free [Code Clinics][CCs] (in collaboration with [IT Services][its-res-it]), plus +[paid services][rse-service] that allow us to collaborate longer term. + +[CCs]: https://rse.shef.ac.uk/support/code-clinic/ +[EPCC]: https://www.epcc.ed.ac.uk/ +[its-res-it]: https://www.sheffield.ac.uk/it-services/research/ +[its-workshops]: https://www.sheffield.ac.uk/it-services/research/one-day-sessions +[rse-service]: https://rse.shef.ac.uk/service/ +[rses-mail-list]: https://groups.google.com/a/sheffield.ac.uk/forum/#!forum/rse-group +[rses]: https://rse.shef.ac.uk/ diff --git a/_newsletters/2021-08-11-newsletter.md b/_newsletters/2021-08-11-newsletter.md new file mode 100644 index 00000000..6d051ffd --- /dev/null +++ b/_newsletters/2021-08-11-newsletter.md @@ -0,0 +1,102 @@ +--- +layout: post +title: August 2021 Newsletter +editor: Bob Turner +slug: 2021-08-11-newsletter +date: 2021-08-11T16:00:00Z+0100 +tags: +category: +link: +description: +type: text +--- + +## University of Sheffield Research Software Engineering Team Newsletter August 2021 + +Hi everyone! + +Welcome to the monthly newsletter from the [Research Software Engineering Team](https://rse.shef.ac.uk/) at The University of Sheffield. + +Quite a lot of developments on **open research** this month with France's [Second National Plan for Open Science](https://www.ouvrirlascience.fr/second-national-plan-for-open-science/) and the UK's [Research councils policy on open access](Research councils policy on open access) being published, along with a demo version of [Octopus](https://science-octopus.org/) - a new publishing model supported by UK Reproducibility Network, eLife and mozilla Science Lab. Closer to home, the University of Sheffield's Open Research Prize winner [has been announced](http://librarysupport.group.shef.ac.uk/libraryblog/2021/08/04/the-university-of-sheffield-open-research-prize-2021/) along with an [event to celebrate the occasion](https://www.eventbrite.co.uk/e/celebration-of-open-research-at-the-university-of-sheffield-tickets-163679197887). + +We aim to share our experiences and information of other communities for those using software for research. This newsletter collects interesting events and opportunities over the coming month. It also signposts to other resources that we find beneficial or interesting. You may find the content interesting if you are someone in research using software, are a person paid to develop software (like a Research Software Engineer (RSE)), or are somewhere in-between (a research developer). + +To receive this newsletter as an email each month, please sign up to our [Google Group][rses-mail-list]. **Tell your friends!** + +To suggest content for a future newsletter either complete [this short form](https://forms.gle/YyQiNjg79tXaLZHq8) or drop us an [email](mailto:rse@sheffield.ac.uk). We can’t promise that we’ll publish everything that’s proposed but we are keen to feature submissions from the research community at the University of Sheffield. + +*All times are BST (UTC+01)* + +## Future Events and Training + +--- + +### LunchBytes: SeptembRSE Satellite Special + +Topic: TBD + +As part of this year's [SeptembRSE](https://septembrse.society-rse.org/) conference (details above), our very own LunchBytes series will be taking part as a satellite session. [Get your topic suggestions in on the JamBoard](https://jamboard.google.com/d/1-51cRf0pwZl8O10CnLeJGAqKcnbww-QGaYjszFK-H38/) and [watch this space](https://rse.shef.ac.uk/community/lunch-bytes/) for details. + +--- + +### SeptembRSE + +The [Conference of Research Software Engineers](https://septembrse.society-rse.org/) is returning this year with a fully online event. + +6 - 30th September 2021 + +[Registration is now open](https://septembrse.society-rse.org/registration/)! + +--- + +### [The Open Research Prize](https://www.eventbrite.co.uk/e/celebration-of-open-research-at-the-university-of-sheffield-tickets-163679197887) + +Tue, 14 September 2021 09:30 – 11:00 BST + +From the Library: + +> This spring we were delighted to launch our inaugural open research prize, supporting the University of Sheffield’s Open Research Statement. Join us for a celebration of the winners who will present on their approach to open research, with remarks from Prof Sue Hartley, Vice President for Research, and Anna Clements, University Librarian + +--- + +### [git & GitHub through GitKraken - from Zero to Hero!](https://rse.shef.ac.uk/training/workshop/2021-10-01-git-zero-hero) + +1st October 2021 - 10:00-16:30 + +How can we effectively work together on the same code? + +This is an introductory course, teaching the git and GitHub skills required to manage research code over it’s development lifecycle. These skills are essential for collaborative research teams. + +--- + +### [Write better research software (in Python)](https://rse.shef.ac.uk/training/workshop/2021-10-07-good-soft) + +7 October 2021 - 12:30-16:30 + +How can we write better research software? + +If you want the software you make for research to produce trustworthy results and to be reusable by others on different computers, this course will help. + +--- + +### LunchBytes: Better MATLAB, better research + +13 October 2021 - 12:00-13:00 + +[Save the date - more details will be announced soon.](https://rse.shef.ac.uk/events/lunchbytes-2021-10-13.html) + +## RSE Sheffield + +The RSE Sheffield team aims to collaborate with you to help improve your research software. +We can provide dedicated staff to ensure that you can deliver excellent research software engineering on your research projects. + +The RSE Sheffield team provides free [Code Clinics][CCs] (in collaboration with [IT Services][its-res-it]), plus +[paid services][rse-service] that allow us to collaborate longer term. + +[CCs]: https://rse.shef.ac.uk/support/code-clinic/ +[EPCC]: https://www.epcc.ed.ac.uk/ +[its-res-it]: https://www.sheffield.ac.uk/it-services/research/ +[its-workshops]: https://www.sheffield.ac.uk/it-services/research/one-day-sessions +[rse-service]: https://rse.shef.ac.uk/service/ +[rses-mail-list]: https://groups.google.com/a/sheffield.ac.uk/forum/#!forum/rse-group +[rses]: https://rse.shef.ac.uk/ diff --git a/_newsletters/2021-10-18-newsletter.md b/_newsletters/2021-10-18-newsletter.md new file mode 100644 index 00000000..c16fff53 --- /dev/null +++ b/_newsletters/2021-10-18-newsletter.md @@ -0,0 +1,96 @@ +--- +layout: post +title: October 2021 Newsletter +editor: Anna Krystalli, Fariba Yousefi +slug: 2021-10-18-newsletter +date: 2021-10-18T16:00:00Z+0100 +tags: +category: +link: +description: +type: text +--- + +## University of Sheffield Research Software Engineering Team Newsletter October 2021 + +Hi everyone! + +Welcome to the monthly newsletter from the [Research Software Engineering Team](https://rse.shef.ac.uk/) at The University of Sheffield. + +## Opportunities + +- [Software Sunstainability Institute Fellowship 2022](https://software.ac.uk/blog/2021-09-09-applications-ssi-fellowship-programme-2022-now-open). These Fellowships are a great opportunity for RSEs and Academics alike to receive funding and support for projects that promote software sustainability in research. The University of Sheffield has had representiatives in SSI cohorts for a few years. This round will also be a pilot for opening up the programme to international applicants. The deadline to apply is 31 October 2021. + +- [UKRI: Support the development of research software engineering](https://www.ukri.org/opportunity/support-the-development-of-research-software-engineering/?utm_medium=email&utm_source=govdelivery). Funding from the UKRI is available for activities to support the development of research software engineering in the UK. The closing Dateis 2nd of Dec 2021 +You must be either: + - a researcher or research software engineer at an eligible research organisation + - an employee of an eligible public sector research establishment. + +- [Research Software Engineer](https://www.jobs.ac.uk/job/CJK740/research-software-engineer). An opening is available to join the growing research software engineering team on an open-ended contract. Ideally you will have a PhD level education with experiments in data analytics, numerical computing and high-performance computing. The closing date is 22nd of October 2021. + + +### LunchBytes + +We had two highly successfull LunchBytes sessions in September and October! + +- **LunchBytes × SeptembRSE Special: Python Virtual Environment Showdown (15th Sep 2021)** + To coincide with this year’s online RSE conference, SeptembRSE, LunchBytes “colocated” on Zoom as part of the conference programme. + + The topic was a showdown between some of the different options for managing virtual environments when working with Python. Will Conda come out on top? Or will the favourite be venv or Poetry? + + More details about the event, including a video of the session can be found on our [blog](https://rse.shef.ac.uk/events/lunchbytes-2021-09-15.html). + +- **LunchBytes: Better MATLAB, Better Research (13th October 2021)** + Short talks on how University of Sheffield researchers are using Matlab features old and new, straightforward and complex. A chance to get perspectives from researchers and from MathWorks, and to discuss Matlab in the research software ecosystem. + + More details about the event, including a video of the session can be found on our [blog](https://rse.shef.ac.uk/events/lunchbytes-2021-10-13.html). + + +### News + +- On the 14th September 2021, at an [online event](https://www.eventbrite.co.uk/e/celebration-of-open-research-at-the-university-of-sheffield-tickets-163679197887), the University of Sheffield Library announced the winners of the inaugural Open Research Prize, supporting the University of Sheffield’s Open Research Statement. Find out more about the [prize and winners!](http://librarysupport.group.shef.ac.uk/libraryblog/2021/08/04/the-university-of-sheffield-open-research-prize-2021/). +- On the 6th of August, the [Science Minister announced UKRI’s open access policy](https://www.gov.uk/government/speeches/science-minister-announces-ukris-open-access-policy). See also [details of the policy](https://www.ukri.org/publications/research-councils-policy-on-open-access/) and [UKRI Open Research Resources](https://www.ukri.org/publications/research-councils-policy-on-open-access/). +- **Hacktoberfest!** Although the team haven't organised specific sessions for Hacktoberfest hacking this year, we did kick off the month with a free workshop on [GIT & GITHUB THROUGH GITKRAKEN - FROM ZERO TO HERO!](https://srse-git-github-zero2hero.netlify.app/). The materials are openly available and include an introduction to version control and collaborating on GitHub. So don't forget to sign up for Hacktoberfest and make 4 valid pull request to particpating projects to get an awesome hacktoberfest t-shirt! Sign up and check out rules on the [Hacktoberfest website](https://hacktoberfest.digitalocean.com/). +- **RSdropinUK:** An exciting new service of free Research software technical drop-in sessions for researchers and Research Software Engineers based at organisations in the UK has been launched by members of the RSE community! Each fornightly drop-in session will also include an informal tutorial/walkthrough of a research software engineering tool, aimed at absolute beginners. Check out [their website](https://rsdropin.github.io/RSdropinUK/) for details of the types of problems they can help with and information on how to join the sessions. And don't forget, your friendly local Sheffield RSE team, in collaboration with IT Services, also offer similar [code clinic sessions](https://rse.shef.ac.uk/support/code-clinic/). +- **ReproHack Hub Launch:** Join the ReproHack Core Team, in collaboration with the N8 CIR on the **18th November 2021** in the [inaugural event using their brand sparkling new ReproHack Hub](https://bit.ly/reprohack-hub-launch)! ReproHack events are sandbox environments for practicing research reproducibility where participants attempt to reproduce published research of their choice from a list of proposed papers with publicly available associated code and data. There are two ways to get involved: + - **As an author:** [Submit your paper for reproduction and review](https://www.reprohack.org/paper/)! + - **As a participant:** [Join on us on this celebratory day](https://bit.ly/reprohack-hub-launch) and get practical experience in reproducibility with real published materials! +- **Matlab 2021b is now out** ([see Release Highlights](https://uk.mathworks.com/products/new_products/latest_features.html)) which [includes enhanced python support](https://uk.mathworks.com/help/matlab/ref/pyrun.html?searchHighlight=pyrun&s_tid=srchtitle). +- **How augmented clinical trials are accelerating a vaccine for tuberculosis:** Press release about [exciting work using the latest techniques in mathematical modelling and augmented clinical trials to help researchers develop an affordable vaccine](https://www.sheffield.ac.uk/maths/news/how-augmented-clinical-trials-are-accelerating-vaccine-tuberculosis) which has benefited by Sheffield RSE support. + + +### Talks +- On 10th September, our own Bob Turner presented the results of the University of Sheffield Research Software Survey (2020) at SeptembRSE. More details about the talk, including a video of the session can be found on our [blog](https://rse.shef.ac.uk/blog/2021-09-10-bob-septrse/). +- On the 25th September, our own Anna Krystalli participated on a panel entitled [Engaging the community in research reproduction](https://metascience2021.org/events/engaging-the-community-in-research-reproduction/) at [Metascience 2021 Conference](https://metascience2021.org/). A video of the session can be found on the [Centre for Open Science's YouTube channel](https://www.youtube.com/watch?v=nUWFYSF_l9k&t=1s). + + +### Training + +- There's a bunch of **upcoming free training courses from the Hartree Centre** including: + - Introduction to data collection and preparation | 21 Oct 2021 – FULLY BOOKED + - Data analysis and systems integration | 22 Oct 2021 – FULLY BOOKED + - Beginner’s Guide to Cloud for Industry | 2 Nov 2021 : https://www.cvent.com/c/express/e200899b-0a57-435a-9c3f-2e88e22bdcf2 + - Infrastructure as Code (IaC) in the Cloud | 3 Nov 2021 : https://www.cvent.com/c/express/b373a50e-ba6c-4245-aae0-4f561847bff6 + - Building and testing apps for the Cloud | 10-11 Nov 2021 : https://www.cvent.com/c/express/20ece454-1faf-467d-b654-4bfc1c69377f + - Mixed language programming – From Python to C | 9 Dec 2021 : https://www.cvent.com/c/express/1e0034b8-643f-4862-a8a3-3db7575cd88d + + For more details on the courses, check out their [Accessible supercomputing​, data analytics and AI training with industry context](https://www.hartree.stfc.ac.uk/Pages/Explain.aspx?utm_source=Twitter&utm_medium=social&utm_campaign=Orlo) page. +- Matlab Academy is an online resource for learning MATLAB for free with MATLAB Onramp and accessing interactive self-paced online courses and tutorials on Deep Learning, Machine Learning and more: https://matlabacademy.mathworks.com/. As an example, a new course on Matlab academy demonstrates [how to simulate electronic circuits](https://matlabacademy.mathworks.com/details/circuit-simulation-onramp/circuits). +- Performance analysis methodology workshop | 15 Dec 2021 09:00-12:00. This workshop aims to give a solid understanding of the basics of performance analysis for research and simulation codes, using high- and low-level metrics. +https://www.dur.ac.uk/arc/training/workshop/ + +## RSE Sheffield + +The RSE Sheffield team aims to collaborate with you to help improve your research software. +We can provide dedicated staff to ensure that you can deliver excellent research software engineering on your research projects. + +The RSE Sheffield team provides free [Code Clinics][CCs] (in collaboration with [IT Services][its-res-it]), plus +[paid services][rse-service] that allow us to collaborate longer term. + +[CCs]: https://rse.shef.ac.uk/support/code-clinic/ +[EPCC]: https://www.epcc.ed.ac.uk/ +[its-res-it]: https://www.sheffield.ac.uk/it-services/research/ +[its-workshops]: https://www.sheffield.ac.uk/it-services/research/one-day-sessions +[rse-service]: https://rse.shef.ac.uk/service/ +[rses-mail-list]: https://groups.google.com/a/sheffield.ac.uk/forum/#!forum/rse-group +[rses]: https://rse.shef.ac.uk/ diff --git a/_newsletters/2021-11-18-newsletter.md b/_newsletters/2021-11-18-newsletter.md new file mode 100644 index 00000000..cb9d6f6b --- /dev/null +++ b/_newsletters/2021-11-18-newsletter.md @@ -0,0 +1,78 @@ +--- +layout: post +title: November 2021 Newsletter +editor: Matthew Leach +slug: 2021-11-18-newsletter +date: 2021-11-18T16:00:00Z+0100 +tags: +category: +link: +description: +type: text +--- + +## University of Sheffield Research Software Engineering Team Newsletter November 2021 + +Hi everyone! + +Welcome to the monthly newsletter from the [Research Software Engineering Team](https://rse.shef.ac.uk/) at The University of Sheffield. + +## Opportunities +- [Research Software Engineer](https://rse.shef.ac.uk/blog/2021-11-12-rse-roles/). Come and join us! This is an open-ended position at the University of Sheffield Research Software Engineering team. The role is ideal for someone with a passion for research and for good software engineering looking to use their skills in collaborative software development and reproducible research to make an impact on research projects across the whole of the University of Sheffield and beyond. Closing date 6th December 2021. +- [UKRI: Support the development of research software engineering](https://www.ukri.org/opportunity/support-the-development-of-research-software-engineering/?utm_medium=email&utm_source=govdelivery). Funding from the UKRI is available for activities to support the development of research software engineering in the UK. The closing Date is 2nd of Dec 2021 +You must be either: + - a researcher or research software engineer at an eligible research organisation + - an employee of an eligible public sector research establishment. +- [REDCap System Administrator](https://www.jobs.ac.uk/job/CKL306/system-administrator). System Administrator position within the Clinical Infection Research Group (CIRG) at the University of Sheffield, working on the REDCap project which has been supported by our RSE team. Closing date 19th November 2021. + + +### LunchBytes + +We have our December edition of LunchBytes coming up very soon, which will be discussing parallelisation! + +- **LunchBytes: Parallelisation: an easy trick to speed up your code? 13th January 2022 12:00-13:00** + Parallelisation - running multiple pieces of work at the same time - can be a great way to speed up research code, but requires an appreciation of the costs introduced by distributing work concurrently over computational assets. This session will be made up of short talks introducing both fundamental concepts needed for successful use of parallelisation, and state of the art technologies available for researchers. + + More details about the event are available [on our website](https://rse.shef.ac.uk/events/lunchbytes-2021-12-02.html). + + +### News + +- **RSdropinUK:** An exciting new service of free Research software technical drop-in sessions for researchers and Research Software Engineers based at organisations in the UK has been launched by members of the RSE community! Each fornightly drop-in session will also include an informal tutorial/walkthrough of a research software engineering tool, aimed at absolute beginners. Check out [their website](https://rsdropin.github.io/RSdropinUK/) for details of the types of problems they can help with and information on how to join the sessions. And don't forget, your friendly local Sheffield RSE team, in collaboration with IT Services, also offer similar [code clinic sessions](https://rse.shef.ac.uk/support/code-clinic/). +- **ReproHack Hub Launch:** Join the ReproHack Core Team, in collaboration with the N8 CIR on the **18th November 2021** in the [inaugural event using their brand sparkling new ReproHack Hub](https://bit.ly/reprohack-hub-launch)! ReproHack events are sandbox environments for practicing research reproducibility where participants attempt to reproduce published research of their choice from a list of proposed papers with publicly available associated code and data. There are two ways to get involved: + - **As an author:** [Submit your paper for reproduction and review](https://www.reprohack.org/paper/)! + - **As a participant:** [Join on us on this celebratory day](https://bit.ly/reprohack-hub-launch) and get practical experience in reproducibility with real published materials! +- **GitHub Citation Files:** GitHub have introduced support for [citation files](https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-citation-files). These are simple to use and ensure users of your work can easily cite it correctly! +- **N8CIR High Performance Community Event**: An in-person event on the 13th of December to celebrate the work of the N8 CIR over the last 12 months, including keynotes, presentations and lightning talks. Both Anna Krystalli and Paul Richmond of RSE Sheffield will be presenting lightning talks at this event! + - [Visit the n8cir.org.uk website](https://n8cir.org.uk/events/high-performance-community/) for more information and to register for the event. + +### Selected Articles + +This is a small selection of recent articles from the Software Sustainability Institute which may be of interest! + +- [Don’t be afraid - anyone can learn to code](https://www.software.ac.uk/blog/2021-11-02-dont-be-afraid-anyone-can-learn-code?mc_cid=94afd68d24&mc_eid=f09318bc47) +- [Using Python to double check your work](https://www.software.ac.uk/blog/2021-11-01-using-python-double-check-your-work?mc_cid=94afd68d24&mc_eid=f09318bc47) +- [5 Popular Myths of Learning to Code](https://www.software.ac.uk/blog/2021-11-01-guide-5-popular-myths-learning-code?mc_cid=94afd68d24&mc_eid=f09318bc47) + +### Training + +- Matlab Academy is an online resource for learning MATLAB for free with MATLAB Onramp and accessing interactive self-paced online courses and tutorials on Deep Learning, Machine Learning and more: [https://matlabacademy.mathworks.com/](https://matlabacademy.mathworks.com/). As an example, a new course on Matlab academy demonstrates [how to simulate electronic circuits](https://matlabacademy.mathworks.com/details/circuit-simulation-onramp/circuits). +- Performance analysis methodology workshop | 15 Dec 2021 09:00-12:00. This workshop aims to give a solid understanding of the basics of performance analysis for research and simulation codes, using high- and low-level metrics. +[https://www.dur.ac.uk/arc/training/workshop/](https://www.dur.ac.uk/arc/training/workshop/) +- Git & GitHub through GitKraken - from Zero to Hero! | [9th Dec 2021](https://rse.shef.ac.uk/training/workshop/2021-12-09-git-zero-hero), [1st Feb 2022](https://rse.shef.ac.uk/training/workshop/2022-02-01-git-zero-hero), [5th April 2022](https://rse.shef.ac.uk/training/workshop/2022-04-05-git-zero-hero) 10:00-16:30. An introductory course delivered by the Sheffield RSE team, teaching the git and GitHub skills required to manage research code over it’s development lifecycle. These skills are essential for collaborative research teams. Please note that we have very high demand for these events so they may fill up very quickly, but please still register your interest so we can gauge demand and provide an appropriate number of sessions! + +## RSE Sheffield + +The RSE Sheffield team aims to collaborate with you to help improve your research software. +We can provide dedicated staff to ensure that you can deliver excellent research software engineering on your research projects. + +The RSE Sheffield team provides free [Code Clinics][CCs] (in collaboration with [IT Services][its-res-it]), plus +[paid services][rse-service] that allow us to collaborate longer term. + +[CCs]: https://rse.shef.ac.uk/support/code-clinic/ +[EPCC]: https://www.epcc.ed.ac.uk/ +[its-res-it]: https://www.sheffield.ac.uk/it-services/research/ +[its-workshops]: https://www.sheffield.ac.uk/it-services/research/one-day-sessions +[rse-service]: https://rse.shef.ac.uk/service/ +[rses-mail-list]: https://groups.google.com/a/sheffield.ac.uk/forum/#!forum/rse-group +[rses]: https://rse.shef.ac.uk/ diff --git a/_newsletters/2021-12-14-newsletter.md b/_newsletters/2021-12-14-newsletter.md new file mode 100644 index 00000000..e8a78eb6 --- /dev/null +++ b/_newsletters/2021-12-14-newsletter.md @@ -0,0 +1,98 @@ +--- +layout: post +title: December 2021 Newsletter +editor: Twin Karmakharm +slug: 2021-12-14-newsletter +date: 2021-12-14T16:00:00Z+0100 +tags: +category: +link: +description: +type: text +--- + +## University of Sheffield Research Software Engineering Team Newsletter December 2021 + +Hi everyone! + +Welcome to the monthly newsletter from the [Research Software Engineering Team](https://rse.shef.ac.uk/) at The University of Sheffield. + + +### LunchBytes + +We have lunchbytes sessions scheduled for January and February, save the date! + +* **Parallelisation: an easy trick to speed up your code?, 13th January 2022 12:00-13:00 (rescheduled from December)** + Parallelisation - running multiple pieces of work at the same time - can be a great way to speed up research code, but requires an appreciation of the costs introduced by distributing work concurrently over computational assets. This session will be made up of short talks introducing both fundamental concepts needed for successful use of parallelisation, and state of the art technologies available for researchers. + + More details about the event are available [on our website](https://rse.shef.ac.uk/events/lunchbytes-2021-12-02.html). + + +* **High Performance Computing (HPC) at Sheffield and Beyond, 17th February 2022 12:00-13:00** + If you find yourself running simulations that take days, struggling to fit datasets in your computer’s memory, training deep learning models or wish you had more computational resource for doing research, HPC might be the solution! + + More details about the event are available [on our website](https://rse.shef.ac.uk/events/lunchbytes-2022-02-17.html). + + +### News + +* [Funders need to credit open science](https://www.nature.com/articles/d41586-021-03418-1) - The Dutch Research Council (NWO) makes a push towards more open science by launching the Open Science Fund initiative. Encouraging open access publications, accessible data, and the use of open-source tools and software. + +* [The 2021 RSE survey is now open](https://softwaresaved.limequery.com/386272?lang=en) - Please help complete the survey so that we can get a better picture of the state of RSEs around the world. + +* [Archer 2 full system open to users](https://www.archer2.ac.uk/news/2021/11/22/full-system-access.html) - After delays due to covid restrictions, the national-scale cluster was open to users on the 22nd of November. The article provides an introduction to the hardware and software of the system. + +* [OLS-5 Cohort is open for applications](https://openlifesci.org/) : The Open Life Science (OLS) program helps individuals and stakeholders in research to become Open Science ambassadors. The program offers 16-week long personal mentorship and cohort-based training. The call for applications closes January 15, 2022. + + +### Events + +* [UK National GPU Hackathon 2022, 28th February and 7-9th March](https://www.gpuhackathons.org/event/uk-national-gpu-hackathon-2022) - There's still time to register for the 2022 GPU Hackathon. Team up with experienced GPU mentors to learn and apply accelerated and parallel computing to your project. **Application deadline is on 10th of January.** + + +* [SSI Collaborations Workshop 2022, 4-7th April](https://software.ac.uk/cw22) - The Software Sustainability Institute’s Collaborations Workshop series brings together researchers, developers, innovators, managers, funders, publishers, policy makers, leaders and educators to explore best practices and the future of research software. + + +* [Software engineering in High Energy/Particle Physics Seminar, 13th Jan 12:00-13:00](https://rse.shef.ac.uk/events/lunchbytes-2022-03-17.html) - Epic tales of ways in which improved software has helped progress High Energy/Particle Physics research. + +* [RSE Conference 2022, 5th September](https://twitter.com/ResearchSoftEng/status/1468969952489082892) - The date of the next RSE conference has just been announced! The conference will be held in Newcastle and chaired by Mark Turner of Newcastle University's Digital Institute. + +### Web and Blogs + + + +* [Applications of paraview](https://dataviz.shef.ac.uk/blog/05/10/2021/Paraview) - ParaView is free software that can visualise both observational and numerical data. Through this blog article, Suzana Silva provides us with practical examples of how ParaView can be applied to generate beautiful visualisation for various scientific domains. + + +* [FortranCon 2021](https://www.youtube.com/playlist?list=PLeKbr7eYHjt5UaV9zQtY24oEbne9_uFni) - Keynote and sessions from FortranCon are now available to watch through this youtube playlist. + + + +### Training + +* [CodeRefinery twitch channel](https://www.twitch.tv/coderefinery) - CodeRefinery offers training opportunities to researchers from Nordic research groups and projects to learn basic-to-advanced research computing skills and become confident in using state-of-the-art tools and practices from modern collaborative software engineering. + + +* Git & GitHub through GitKraken - from Zero to Hero! - Four more sessions of our popular version control course have been confirmed for next year. Visit the links below for more information and to register. + * [20th January 10:00-16:30](https://rse.shef.ac.uk/training/workshop/2022-01-20-git-zero-hero) + * [1st February 10:00-16:30](https://rse.shef.ac.uk/training/workshop/2022-02-01-git-zero-hero) + * [10th March 10:00-16:30](https://rse.shef.ac.uk/training/workshop/2022-03-10-git-zero-hero) + * [5th April 10:00-16:30](https://rse.shef.ac.uk/training/workshop/2022-04-05-git-zero-hero) + + + +## RSE Sheffield + +The RSE Sheffield team aims to collaborate with you to help improve your research software. +We can provide dedicated staff to ensure that you can deliver excellent research software engineering on your research projects. + +The RSE Sheffield team provides free [Code Clinics][CCs] (in collaboration with [IT Services][its-res-it]), plus +[paid services][rse-service] that allow us to collaborate longer term. + +[CCs]: https://rse.shef.ac.uk/support/code-clinic/ +[EPCC]: https://www.epcc.ed.ac.uk/ +[its-res-it]: https://www.sheffield.ac.uk/it-services/research/ +[its-workshops]: https://www.sheffield.ac.uk/it-services/research/one-day-sessions +[rse-service]: https://rse.shef.ac.uk/service/ +[rses-mail-list]: https://groups.google.com/a/sheffield.ac.uk/forum/#!forum/rse-group +[rses]: https://rse.shef.ac.uk/ diff --git a/_newsletters/2022-02-10-newsletter.md b/_newsletters/2022-02-10-newsletter.md new file mode 100644 index 00000000..06068fc1 --- /dev/null +++ b/_newsletters/2022-02-10-newsletter.md @@ -0,0 +1,152 @@ +--- +layout: post +title: February 2022 Newsletter +editor: David Wilby +slug: 2022-02-10-newsletter +date: 2022-02-10T16:00:00Z+0100 +tags: +category: +link: +description: +type: text +--- + +## The University of Sheffield Research Software Engineering Community Newsletter February 2022 + +Hi everyone! + +Welcome to the monthly newsletter for the [Research Software Engineering Community](https://rse.shef.ac.uk/) at The University of Sheffield. + + +### Code Clinics +Code Clinics are fortnightly support sessions run on alternate Wednesdays by the RSE Team and IT Services’ Research and Innovation IT (ITS R&I) team. They are open to anyone at TUOS writing code for research to get help with programming problems and general advice on best practice. + +At each session, members of the RSE and/or ITS R&I teams will be available to review code, advise, troubleshoot and suggest ways to improve your computational workflows. + +To find out more and book a slot [click here](https://rse.shef.ac.uk/support/code-clinic/) + + +### LunchBytes + +[LunchBytes](https://rse.shef.ac.uk/community/lunch-bytes/) are a monthly series of short talks from the research community on research software, data and infrastructure. + +We have LunchBytes sessions scheduled for February and March, save the date! + +* **High Performance Computing (HPC) at Sheffield and Beyond, 17th February 2022 12:00-13:00** +If you find yourself running simulations that take days, struggling to fit datasets in your computer’s memory, training deep learning models or wish you had more computational resource for doing research, HPC might be the solution! + +More details about the event are available [on our website](https://rse.shef.ac.uk/events/lunchbytes-2022-02-17.html). + + +* **Software engineering in High Energy / Particle Physics, 17th March 2022 12:00-13:00** +Talks include: +* Migrating 4 million lines of C++ code to multi threading +* A new era of computing at the Large Hadron Collider + +More details about the event are available [on our website](https://rse.shef.ac.uk/events/lunchbytes-2022-03-17.html). + + +**Previously scheduled event cancelled, watch this space** +* **Parallelisation: an easy trick to speed up your code?** +Parallelisation - running multiple pieces of work at the same time - can be a great way to speed up research code, but requires an appreciation of the costs introduced by distributing work concurrently over computational assets. This session will be made up of short talks introducing both fundamental concepts needed for successful use of parallelisation, and state of the art technologies available for researchers. + +More details about the event are available [on our website](https://rse.shef.ac.uk/events/lunchbytes-2021-12-02.html). + + +#### LunchBytes needs YOU! +LunchBytes are organised by and for the research software community at The University of Sheffield. If you'd like to curate a session on a topic or present something, get in touch by emailing [lunchbytes-organisers-group@sheffield.ac.uk](mailto:lunchbytes-organisers-group@sheffield.ac.uk) - Or suggest topics [on the jamboard](https://jamboard.google.com/d/1-51cRf0pwZl8O10CnLeJGAqKcnbww-QGaYjszFK-H38/) + + +### News + +* [Software Sustainability Institute Fellows 2022 Announced](https://www.software.ac.uk/news/announcing-2022-software-sustainability-institute-fellows) - Among this year's cohort is Sheffield RSE Team member, Dr David Wilby. During his fellowship, David will be developing guidance and training resources around best practices for sustainable research software development in MATLAB, watch this space! + +* [Enabling Access to UK Environmental Data](https://research-it.manchester.ac.uk/news/2022/02/01/enabling-access-uk-environmental-data/) - University of Manchester Research IT is to a play a major role in a £7 million project, led by The University of Manchester, to provide easy access to an extensive range of the UK’s environmental data. + +* [Call for computationally-intensive papers for review at the first HPC ReproHack](https://www.reprohack.org/event/14/) +[ReproHacks](https://www.reprohack.org/) are one-day hackathons providing a sandbox environment for practicing reproducibility. + * Authors submit their papers, and publicly available code and data for review prior to the event. On the day, participants attempt to reproduce submitted papers and feed back their experiences to the authors. + + * The format of these events so far has precluded the examination of computationally intensive research. However, with support from the EPSRC, we are excited to partner up with the University of Warwick, UK, who have allocated a large portion of the Sulis tier 2 service (both CPU and GPU resource) to run a *pilot HPC ReproHack event focusing on computationally intensive research* for students of three of their Centers for Doctoral Training in late March 2021! + + * We invite authors who would like feedback on the reproducibility of computationally intensive research to submit details of their paper, code and data for reproduction and review. You can submit your paper on the ReproHack Hub. To ensure your paper is associated with this event, please make sure to select the event on the form during submission. If you would like to make your work available for future HPC ReproHacks, we recommend including an HPC tag. Please see our [Author Guidelines](https://www.reprohack.org/author_guidelines) for more information. + +* [French government has awarded Open Science prizes for research software](https://www.enseignementsup-recherche.gouv.fr/fr/remise-des-prix-science-ouverte-du-logiciel-libre-de-la-recherche-83576) (en Français) - Top prizes were awarded to: [Coq (Scientific and Technical Category)](https://coq.inria.fr/), [Scikit-learn (Community)](https://scikit-learn.org/), [Faust](https://faust.grame.fr/), and [Gammapy (Jury Prize)](https://gammapy.org/). + + +### Featured Software + +[**semantic-release**](https://github.com/semantic-release/semantic-release) automates the whole package release workflow including: determining the next version number, generating the release notes, and publishing the package. + +This removes the immediate connection between human emotions and version numbers, strictly following the Semantic Versioning specification and communicating the impact of changes to consumers. + + +### Events + +* [UK National GPU Hackathon 2022, 28th February and 7-9th March](https://www.gpuhackathons.org/event/uk-national-gpu-hackathon-2022) - Team up with experienced GPU mentors to learn and apply accelerated and parallel computing to your project. **Application deadline has passed.** + +* [N8CIR Digital Research Infrastructure Retreat 28th March - 1st April](https://n8cir.org.uk/news/dri-retreat/) - N8 CIR is hosting a five-day retreat to support the development of soft skills amongst the research computing support community. + +* [SSI Collaborations Workshop 2022, 4-7th April](https://software.ac.uk/cw22) - The Software Sustainability Institute’s Collaborations Workshop series brings together researchers, developers, innovators, managers, funders, publishers, policy makers, leaders and educators to explore best practices and the future of research software. + + +### Web, Blogs & Articles + +* [US-RSE: A kind-of brief shared early history of US-RSE](https://us-rse.org/2022-02-06-a-brief-history-of-usrse/) + +* [PloS Comp Bio: Ten simple rules to make your computing more environmentally sustainable](https://journals.plos.org/ploscompbiol/article?id=10.1371/journal.pcbi.1009324) + +* [The Register: £42k for a top-class software engineer? It's no wonder uni research teams can't recruit](https://www.theregister.com/2021/12/16/academia_underfunding_software_engineers/) + +* [Science: Everyday objects can run artificial intelligence programs](https://www.science.org/content/article/everyday-objects-can-run-artificial-intelligence-software) + + +### Training + +* Git & GitHub through GitKraken - from Zero to Hero! - There are still a few spaces available on our popular version control course in March and April. Visit the links below for more information and to register. + * [10th March 10:00-16:30](https://rse.shef.ac.uk/training/workshop/2022-03-10-git-zero-hero) + * [5th April 10:00-16:30](https://rse.shef.ac.uk/training/workshop/2022-04-05-git-zero-hero) + + +* 12-week Parallel Computing with GPUs Course: + * The course has started but late registrations are available until week 4 when the GPU content starts. The course has been designed as an undergraduate 4th year (and MSc) module for Computer Science but is available to staff and PhD Students (as part of the DDP program) and regularly has staff and PhD student enrolment. The first 3 weeks are focused on teaching C and OpenMP followed by GPU programming with CUDA C. Lectures are provided as pre-recorded mini lectures and there are 2 hours of scheduled support per week to undertake practical lab classes. Assessment is not required for DDP or staff participants. If you are interested in enrolling as staff or a PhD student then please contact the module leader [p.richmond@sheffield.ac.uk](mailto: p.richmond@sheffield.ac.uk) + + +### Opportunities + +* [PhD in GPU computing at CERN - see link for details](https://docs.google.com/document/d/1tq21-XzqbrG_nMpWDxisXLAAzIeE0AQ46Y5mE5othPI) - deadline 21st March + +* [Research Data Scientist/Research Software Engineer @ The Alan Turing Institute](https://cezanneondemand.intervieweb.it/turing/jobs/research_data_scientistresearch_software_engineer_20259/en/) - rolling hire. + +* [RSE @ Cardiff](https://krb-sjobs.brassring.com/TGnewUI/Search/Home/HomeWithPreLoad?partnerid=30011&siteid=5460&PageType=searchResults&SearchType=linkquery&LinkID=6#jobDetails=1919917_5460) - closing date 18th Feb + +* [Research IT Infrastructure Analyst @ Manchester](https://www.jobs.manchester.ac.uk/displayjob.aspx?jobid=21611) - closing date 14th Feb (next week!) + +* [HPC Solution Area Specialist @ Microsoft](https://careers.microsoft.com/us/en/job/1239668/EMEA-GBB-HPC-Solution-Area-Specialist) + +* [Senior RSE @ Imperial](https://www.imperial.ac.uk/jobs/description/FOG00559/senior-research-software-engineer) - closing date 21st Feb + +* [Head of RSE @ Exeter](https://jobs.exeter.ac.uk/hrpr_webrecruitment/wrd/run/ETREC107GF.open?VACANCY_ID=307457YUr1&WVID=3817591jNg&LANG=USA) - closing date 23rd Feb + +* 2 Roles at UCL + * [Research Fellow / Senior Research Fellow in Machine Learning for Synthetic Surgical Data](https://atsv7.wcn.co.uk/search_engine/jobs.cgi?SID=amNvZGU9MTg4MjA2MiZ2dF90ZW1wbGF0ZT05NjYmb3duZXI9NTA0MTE3OCZvd25lcnR5cGU9ZmFpciZicmFuZF9pZD0wJnZhY3R5cGU9MTI3NiZwb3N0aW5nX2NvZGU9MjI0) - closing date 6th Mar + * [Research Fellow / Senior Research Fellow in Software for Synthetic Surgical Data](https://atsv7.wcn.co.uk/search_engine/jobs.cgi?SID=amNvZGU9MTg4MjA2NyZ2dF90ZW1wbGF0ZT05NjYmb3duZXI9NTA0MTE3OCZvd25lcnR5cGU9ZmFpciZicmFuZF9pZD0wJnZhY3R5cGU9MTI3NiZwb3N0aW5nX2NvZGU9MjI0) - closing date 6th Mar + +Many of these opportunities are shared in the [UKRSE slack channel](https://ukrse.slack.com) run by the [Society of Research Software Engineering](https://society-rse.org/) - join to get the latest news and discussions in the RSE community in the UK and globally. + + +## Sheffield RSE Team + +The Sheffield RSE Team aims to collaborate with you to help improve your research software. +They can provide dedicated staff to ensure that you can deliver excellent research software engineering on your research projects. + +The Sheffield RSE Team provides free [Code Clinics][CCs] (in collaboration with [IT Services][its-res-it]), plus +[paid services][rse-service] that allow us to collaborate longer term. + +[CCs]: https://rse.shef.ac.uk/support/code-clinic/ +[EPCC]: https://www.epcc.ed.ac.uk/ +[its-res-it]: https://www.sheffield.ac.uk/it-services/research/ +[its-workshops]: https://www.sheffield.ac.uk/it-services/research/one-day-sessions +[rse-service]: https://rse.shef.ac.uk/service/ +[rses-mail-list]: https://groups.google.com/a/sheffield.ac.uk/forum/#!forum/rse-group +[rses]: https://rse.shef.ac.uk/ diff --git a/_newsletters/2022-03-10-newsletter.md b/_newsletters/2022-03-10-newsletter.md new file mode 100644 index 00000000..e8997ba5 --- /dev/null +++ b/_newsletters/2022-03-10-newsletter.md @@ -0,0 +1,110 @@ +--- +layout: post +title: March 2022 Newsletter +editor: Robert "Bob" Turner +slug: 2022-03-11-newsletter +date: 2022-03-11T16:00:00Z+0100 +tags: +category: +link: +description: +type: text +--- + +## The University of Sheffield Research Software Engineering Community Newsletter March 2022 + +Welcome to the monthly newsletter for the [Research Software Engineering Community](https://rse.shef.ac.uk/) at The University of Sheffield. + +### News from the RSE Team + +Some sad news for the team - Anna Krystalli, who has been with us since the start, is going to be leaving in mid-April. Anna's contribution to the university has been huge, particularly through the development and delivery of training which creates a legacy of reproducible, open research, and through sharing and using her deep knowledge of `R`. + +Happier news: We'll have a new team member joining us at the beginning of April, more details to follow. And we plan to recruit another team member in the next few months to partially replace Anna's `R` skills. + +### Come to a Code Clinic + +Why not come to a [Code Clinic](https://docs.google.com/forms/d/e/1FAIpQLScGXS55qjU0D0Zcz-KHOVcNTahcr3YC3H0OpoKBo3lWXWED5A/viewform)? We're keen to hear from you. Previous "cases" have included: + +* Understanding or compiling someone else's code. +* Moving a small amount of code into a different language (e.g. from matlab to python). +* Speeding code up. +* Changing from an obsolete dependency. +* Putting code onto GitHub. +* Changing IDE (e.g. vscode to pycharm). + +I think Code Clinics are good for the types of problems I can't frame as a Google search as they're just a bit to complex, or I don't know the right terms! + + +### LunchBytes + +[LunchBytes](https://rse.shef.ac.uk/community/lunch-bytes/) are a monthly series of short talks from the research community on research software, data and infrastructure. + +**Software engineering in High Energy / Particle Physics, 17th March 2022 12:00-13:00** +Talks include: + * Migrating 4 million lines of C++ code to multi threading + * A new era of computing at the Large Hadron Collider + +More details about the event are available [on our website](https://rse.shef.ac.uk/events/lunchbytes-2022-03-17.html). + + +#### LunchBytes needs YOU! +LunchBytes are organised by and for the research software community at The University of Sheffield. If you'd like to curate a session on a topic or present something, get in touch by emailing [lunchbytes-organisers-group@sheffield.ac.uk](mailto:lunchbytes-organisers-group@sheffield.ac.uk) - Or suggest topics [on the jamboard](https://jamboard.google.com/d/1-51cRf0pwZl8O10CnLeJGAqKcnbww-QGaYjszFK-H38/) + + +### News + +* [NIH issues a seismic mandate: share data publicly](https://www.nature.com/articles/d41586-022-00402-1) The data-sharing policy could set a global standard for biomedical research, scientists say, but they have questions about logistics and equity. + +* [Time to celebrate science’s ‘hidden’ contributors](https://www.nature.com/articles/d41586-022-00454-3%C2%A0) Street children in Africa and a site engineer at a marine-biology research station are among those recognized in an alternative to the United Kingdom’s Research Excellence Framework. **Hidden REF.** + +* [Research and Innovation (R&I) Workforce Survey](https://ipsos.uk/RIworkforce) Department for Business, Energy & Industrial Strategy (BEIS) are running the first Research and Innovation (R&I) Workforce Survey in the UK - your chance to help shape UK government R&I policies and government funding decisions. + + +### From the Web + +* ['ffmpeg for beginners' tutorial](http://www.statsmapsnpix.com/2021/12/map-animations-with-ffmpeg.html) Tutorial on making "animated map things". + +* Free book [Scientific Visualization: Python + Matplotlib](https://github.com/rougier/scientific-visualization-book) An open access book on scientific visualization using python and matplotlib + +* [Engineering at AirQo: Who we are and What we do](https://medium.com/@airqo.engineering/engineering-at-airqo-who-we-are-and-what-we-do-f4e2ee7aabd3) "For those who don’t know AirQo, we are Africa’s leading air quality monitoring, research and analytics network." + + +### Funding Opportunities + +* [Investigate high-priority use cases for exascale software: phase two](https://www.ukri.org/opportunity/investigate-high-priority-use-cases-for-exascale-software-phase-two/) Apply for funding to investigate high priority use cases for future supercomputers. + +* [Unleash Your Data and Software](https://www.sheffield.ac.uk/library/rdm/unleashdatasoftware) Research students and staff at The University of Sheffield can now apply for an award of up to £5000 to make their research data or software more visible and reusable. **Deadline 30th March.** + +* [Essential Open Source Software for Science (Cycle 5)](https://chanzuckerberg.com/rfa/essential-open-source-software-for-science/) The Chan Zuckerberg Initiative invites applications in support of open source software projects that are essential to biomedical research. + + +### Events + +* [N8CIR Digital Research Infrastructure Retreat 28th March - 1st April](https://n8cir.org.uk/news/dri-retreat/) - N8 CIR is hosting a five-day retreat to support the development of soft skills amongst the research computing support community. The deadline for registration for in-person attendance is Thursday 17 March, with remote registration closing on Thursday 24 March. Register now at [https://n8cir.org.uk/dri-retreat/](https://n8cir.org.uk/dri-retreat/). + +* [SSI Collaborations Workshop 2022, 4-7th April](https://software.ac.uk/cw22) - The Software Sustainability Institute’s Collaborations Workshop series brings together researchers, developers, innovators, managers, funders, publishers, policy makers, leaders and educators to explore best practices and the future of research software. + +* [rstudio::conf(2022)](https://www.rstudio.com/blog/rstudio-conf-2022-is-open-for-registration/) rstudio::conf, the conference for all things R and RStudio, will take place July 25-28 in National Harbor, DC! + + +### Training + +Git & GitHub through GitKraken - from Zero to Hero! - There are still a few spaces available on our popular version control course in April. Visit the links below for more information and to register. + * [12th April 10:00-16:30](https://rse.shef.ac.uk/training/workshop/2022-04-05-git-zero-hero) + +We will be scheduling more of these courses in the coming months. + +## Sheffield RSE Team + +The Sheffield RSE Team aims to collaborate with you to help improve your research software. +They can provide dedicated staff to ensure that you can deliver excellent research software engineering on your research projects. + +The Sheffield RSE Team provides free [Code Clinics][CCs] (in collaboration with [IT Services][its-res-it]), plus [paid services][rse-service] that allow us to collaborate longer term. + +[CCs]: https://rse.shef.ac.uk/support/code-clinic/ +[EPCC]: https://www.epcc.ed.ac.uk/ +[its-res-it]: https://www.sheffield.ac.uk/it-services/research/ +[its-workshops]: https://www.sheffield.ac.uk/it-services/research/one-day-sessions +[rse-service]: https://rse.shef.ac.uk/service/ +[rses-mail-list]: https://groups.google.com/a/sheffield.ac.uk/forum/#!forum/rse-group +[rses]: https://rse.shef.ac.uk/ diff --git a/_newsletters/2022-04-25-newsletter.md b/_newsletters/2022-04-25-newsletter.md new file mode 100644 index 00000000..e278352f --- /dev/null +++ b/_newsletters/2022-04-25-newsletter.md @@ -0,0 +1,90 @@ +--- +layout: post +title: April 2022 Newsletter +editor: Fariba Yousefi +slug: 2022-04-26-newsletter +date: 2022-04-26T16:00:00Z+0100 +tags: +category: +link: +description: +type: text +--- + +## The University of Sheffield Research Software Engineering Community Newsletter April 2022 + +Welcome to the monthly newsletter for the [Research Software Engineering Community](https://rse.shef.ac.uk/) at The University of Sheffield. + + +### Come to a Code Clinic + +Why not come to a [Code Clinic](https://docs.google.com/forms/d/e/1FAIpQLScGXS55qjU0D0Zcz-KHOVcNTahcr3YC3H0OpoKBo3lWXWED5A/viewform)? We're keen to hear from you. + +Code Clinics are fortnightly supported sessions run by the RSE team and IT Services’ [Research and Innovation IT](https://www.sheffield.ac.uk/it-services/research) (ITS R&I) team. They are open to anyone at TUOS writing code for research to get help with programming problems and general advice on best practices. + +At each session, members of the RSE and/or ITS R&I teams will be available to review code, advise, troubleshoot, and suggest ways to improve your computational workflows. + + +### LunchBytes + +[LunchBytes](https://rse.shef.ac.uk/community/lunch-bytes/) are a monthly series of short talks from the research community on research software, data, and infrastructure. + +In [May's edition of LunchBytes](https://rse.shef.ac.uk/events/lunchbytes-2022-05-19.html) on the 19th of May, we’ll be getting together to show off our favourite tools that help with using git and GitHub. Think: command-line tools, IDE plugins, GitHub/Lab features, etc. + +If you have a git tool you’d like to let others know about - get in touch with the host at d.wilby [at] sheffield.ac.uk + + +#### LunchBytes needs YOU! +LunchBytes are organised by and for the research software community at The University of Sheffield. If you'd like to curate a session on a topic or present something, get in touch by emailing [lunchbytes-organisers-group@sheffield.ac.uk](mailto:lunchbytes-organisers-group@sheffield.ac.uk) - Or suggest topics [on the jamboard](https://jamboard.google.com/d/1-51cRf0pwZl8O10CnLeJGAqKcnbww-QGaYjszFK-H38/). + + +### News + +* [Jupyter everywhere](https://blog.jupyter.org/jupyter-everywhere-f8151c2cc6e8) - Embed Jupyter notebooks in any web page with Jupyterlite. + +* [What's next for AlphaFold and the AI protein-folding revolution](https://www.nature.com/articles/d41586-022-00997-5) - DeepMind software that can predict the 3D shape of proteins is already changing biology. + +* [Linting - What is all the fluff about?](https://rse.shef.ac.uk/blog/2022-04-19-linting/) - This blogpost is written by the newest member of the RSE team. If you’ve been dabbling in programming for a while you may have heard of “linting your code” which is a process of static code analysis to remove the “fluff” from your code. + +### Volunteers + +* [Calling for RSE volunteers](https://www.software.ac.uk/news/calling-rse-volunteers-join-research-software-camps-software-surgery) - Volunteers needed to join Research Software Camp’s software surgery. + + +### Funding Opportunities + +* [Better methods, better research](https://www.ukri.org/opportunity/better-methods-better-research/) - Apply for funding to improve the methods used by others in biomedical and health research. **The closing date is 15 June 2022.** + + +### Events + +* [RSECon22](https://rsecon2022.society-rse.org/) - RSECon2022 will be held in the Frederick Douglass Centre at Newcastle University. + +* [Archive of Tomorrow – Health (Mis)Information on the Web](https://www.eventbrite.co.uk/e/archive-of-tomorrow-health-misinformation-on-the-web-tickets-293789350857) - Join The Archive of Tomorrow project for a half-day event exploring the issues involved in archiving online health information. **Thursday, 28 April.** + +* [The Turing Way Project](https://twitter.com/turingway/status/1516826435243102212?t=YysHikMGiAIrPp4pAetdVA&s=19) - Join our speakers to talk about the role of conferences in scientific collaboration, and the trade-offs involved in this shift back to in-person conferences. **Friday, 29 April.** + +### Training + +Git & GitHub through GitKraken workshop - from Zero to Hero! Visit the links below for more information and to register. +* [Tuesday 10th May 09:30-16:30](https://rse.shef.ac.uk/training/workshop/2022-04-05-git-zero-hero) - [Register here](https://www.eventbrite.co.uk/e/git-github-through-gitkraken-from-zero-to-hero-registration-305676375267). + +* [Monday 6th and Tuesday 7th of June 12:30-16:30](https://rse.shef.ac.uk/training/workshop/2022-06-06-git-zero-hero) - [Register here](https://www.eventbrite.co.uk/e/git-github-through-gitkraken-from-zero-to-hero-registration-305736765897). + +* [Tuesday 26th July 09:30-16:30](https://rse.shef.ac.uk/training/workshop/2022-07-26-git-zero-hero) - [Register here](https://www.eventbrite.co.uk/e/git-github-through-gitkraken-from-zero-to-hero-registration-305733546267). + + +## Sheffield RSE Team + +The Sheffield RSE Team aims to [collaborate](https://rse.shef.ac.uk/collaboration/guide/) with you to help improve your research software. +They can provide dedicated staff to ensure that you can deliver excellent research software engineering on your research projects. + +The Sheffield RSE Team provides free [Code Clinics][CCs] (in collaboration with [IT Services][its-res-it]), plus [paid services][rse-service] that allow us to collaborate longer term. + +[CCs]: https://rse.shef.ac.uk/support/code-clinic/ +[EPCC]: https://www.epcc.ed.ac.uk/ +[its-res-it]: https://www.sheffield.ac.uk/it-services/research/ +[its-workshops]: https://www.sheffield.ac.uk/it-services/research/one-day-sessions +[rse-service]: https://rse.shef.ac.uk/collaboration/ +[rses-mail-list]: https://groups.google.com/a/sheffield.ac.uk/forum/#!forum/rse-group +[rses]: https://rse.shef.ac.uk/ diff --git a/_newsletters/2022-05-16-newsletter.md b/_newsletters/2022-05-16-newsletter.md new file mode 100644 index 00000000..02e7d68c --- /dev/null +++ b/_newsletters/2022-05-16-newsletter.md @@ -0,0 +1,124 @@ +--- +layout: post +title: May 2022 Newsletter +editor: Peter Heywood +slug: 2022-05-22-newsletter +date: 2022-05-22T15:00:00Z+0100 +tags: +category: +link: +description: +type: text +--- + +## The University of Sheffield Research Software Engineering Community Newsletter May 2022 + +Welcome to the monthly newsletter for the [Research Software Engineering Community](https://rse.shef.ac.uk/) at The University of Sheffield. + +### Come to a Code Clinic + +Why not come to a [Code Clinic](https://docs.google.com/forms/d/e/1FAIpQLScGXS55qjU0D0Zcz-KHOVcNTahcr3YC3H0OpoKBo3lWXWED5A/viewform)? We're keen to hear from you. + +Code Clinics are fortnightly supported sessions run by the RSE team and IT Services’ [Research and Innovation IT](https://www.sheffield.ac.uk/it-services/research) (ITS R&I) team. They are open to anyone at TUoS writing code for research to get help with programming problems and general advice on best practices. + +At each session, members of the RSE and/or ITS R&I teams will be available to review code, advise, troubleshoot, and suggest ways to improve your computational workflows. + +### LunchBytes + +[LunchBytes](https://rse.shef.ac.uk/community/lunch-bytes/) are a monthly series of short talks from the research community on research software, data, and infrastructure. + +In [May's edition of LunchBytes](https://rse.shef.ac.uk/events/lunchbytes-2022-05-19.html) on the 19th of May, we’ll be getting together to show off our favourite tools that help with using git and GitHub. Think: command-line tools, IDE plugins, GitHub/Lab features, etc. + +If you have a git tool you’d like to let others know about - get in touch with the host at d.wilby [at] sheffield.ac.uk + +#### LunchBytes needs YOU! + +LunchBytes are organised by and for the research software community at The University of Sheffield. If you'd like to curate a session on a topic or present something, get in touch by emailing [lunchbytes-organisers-group@sheffield.ac.uk](mailto:lunchbytes-organisers-group@sheffield.ac.uk) - Or suggest topics [on the jamboard](https://jamboard.google.com/d/1-51cRf0pwZl8O10CnLeJGAqKcnbww-QGaYjszFK-H38/). + +### Join the RSE team! + + + +We have a [job advert out for an RSE](https://www.jobs.ac.uk/job/CPR556/research-software-engineer)! Here are six reasons to apply: + +1. **Varied projects.** We work on research in areas such as astrophysics, healthcare, molecular biology, civil engineering and many more. Maybe you've been working on one area for years and you're keen to work with researchers in diverse fields? +2. **We don't need an expert in everything right away.** Lots of people have joined our team having developed coding skills working on research, and learned more software engineering once in the team. Our team is made up of people who specialise in sharing software engineering skills with researchers. +3. **Make a difference.** Our team works with public/private sector organisations, and charities to give our output the best chance of making a positive difference outside the university. We also enthuse about and participate in open research wherever possible. +4. **Flexibility.** We're happy to discuss flexible and part time working options. One of our team has recently reduced their hours from 100% to 80%. Working as a pool makes this much more practicable. Furthermore, in contrast to most RA roles this position is open-ended. +5. **Do useful stuff with code.** We are most interested in your ability to do useful things with code and work with other people. We don’t tend to ask questions about the theory of computer science in interviews. The interest is in modern software technology, code you’ve written, how it was used and how it could be improved. +6. **Reward and recognition.** All of the Sheffield RSE team are employed within the academic careers pathway, a new flexible career development structure which recognises a broad range of research outputs including software. The pathway provides a clear route for promotion up to the level of professor. + +Please [view the advert to apply](https://www.jobs.ac.uk/job/CPR556/research-software-engineer), and see contact details for enquiries about the job. General enquires about the team are welcome at [rse@sheffield.ac.uk](mailto:rse@sheffield.ac.uk). +Applications close on the 9th of June 2022. + +### News & Blogs + +* [PyScript](https://engineering.anaconda.com/2022/04/welcome-pyscript.html) - A framework that allows users to run Python and create rich applications in the browser. + +* [RSE Sheffield: A concise guide to reproducible MATLAB projects](https://rse.shef.ac.uk/blog/2022-05-05-concise-guide-to-reproducible-matlab/) + +* [Mathworks: Exploring the MATLAB beta for Native Apple Silicon](https://blogs.mathworks.com/matlab/2022/05/05/exploring-the-matlab-beta-for-native-apple-silicon/) + +### Funding Opportunities + +* [Better methods, better research](https://www.ukri.org/opportunity/better-methods-better-research/) - Apply for funding to improve the methods used by others in biomedical and health research. **The closing date is 15 June 2022.** + +### Events + +* [SSI Research Software Camp: Next steps in coding](https://www.software.ac.uk/research-software-camps) - The Software Sustainability Institute runs free online Research Software Camps twice a year over the course of two weeks. Each Camp focusses on introducing and exploring a topic around research software, thus starting discussions among various research communities. + * The event runs from the 16 to 27 of May 2022 and the [Programme is available online](https://www.software.ac.uk/programme-research-software-camp-next-steps-coding) + +* [SSI Software Surgery](https://www.software.ac.uk/software-surgery) - The Software Sustainability Institute are running a free Software Surgery which aims to provide a safe and welcoming space for people to get advice on their software challenges. + * The drop-in surgery is open Tuesday 17 to Thursday 19 May, and Tuesday 24 to Thursday 26 May, 10-11 am BST. + +* [Making the Magic Happen with research data, software & infrastructure](https://www.eventbrite.co.uk/e/making-the-magic-happen-with-research-data-software-infrastructure-registration-327177144647) - The aim of this event is to enable you to explore the opportunities and career pathways for Research Technology Professionals (RTPs), which focus on supporting research data, research software, and research computing facilities. + * Thu, 26 May 2022 10:00–15:30 BST, [Register via eventbrite](https://www.eventbrite.co.uk/e/making-the-magic-happen-with-research-data-software-infrastructure-registration-327177144647) + +* [RSECon22](https://rsecon2022.society-rse.org/) - RSECon2022 will be held in the Frederick Douglass Centre at Newcastle University. + * Calls for volunteers and mentors closes on the 18th of May, and registration opens on 8th of June. + +* [HPC and RSE Workshop - ExCALIBUR RSEs meet HPC Champions](https://www.eventbrite.co.uk/e/hpc-and-rse-workshop-excalibur-rses-meet-hpc-champions-registration-335229679997) - In this hybrid (online and in-person) workshop we will hear about research software challenges in current ExCALIBUR projects, HPC developments from across the UK presented by the HPC Champions network, and discuss training and development for research software engineering in the high-performance computing space. + * Friday 9 September 2022 09:00–16:00 BST co-located with RSECon22 + * In-person registration closes on the 25th of August, Online registration closes on the 9th of September + +### Training + +**Git & GitHub through GitKraken workshop - from Zero to Hero!** + +Visit the links below for more information. These events are now fully booked, but you can join the waiting list in case any spaces become available. +If you sign up for a course, please make sure you either attend or cancel your booking. Bookings can usually be cancelled via eventbrite. + +* [Monday 6th and Tuesday 7th of June 12:30-16:30](https://rse.shef.ac.uk/training/workshop/2022-06-06-git-zero-hero) - [Register here](https://www.eventbrite.co.uk/e/git-github-through-gitkraken-from-zero-to-hero-registration-305736765897). + +* [Tuesday 26th July 09:30-16:30](https://rse.shef.ac.uk/training/workshop/2022-07-26-git-zero-hero) - [Register here](https://www.eventbrite.co.uk/e/git-github-through-gitkraken-from-zero-to-hero-registration-305733546267). + +**[Introduction to Deep Learning Course with Tensorflow Keras (in Python), 8th June](https://rse.shef.ac.uk/training/workshop/2022-06-08-deep-learning-with-tensorflow-in-python)** + +A one-day introduction to deep learning with practical labs using Tensorflow in Python. The session is led by [Twin Karmakharm](https://rse.shef.ac.uk/contact/twin-karmakharm/) and [Fariba Yousefi](https://rse.shef.ac.uk/contact/fariba-yousefi/). +[Register on eventbrite](https://www.eventbrite.co.uk/e/introduction-to-deep-learning-with-tensorflow-in-python-tickets-319715606987) + +**[Faster Matlab, 16th June](https://www.eventbrite.co.uk/e/faster-matlab-tickets-337068580197)** + +Do you write MATLAB code and wish it went a little faster? In this hands-on workshop, you will learn a range of techniques in how to make MATLAB go faster including modern MATLAB programming techniques, conversion and interfacing to C/C++, GPU and parallel computing. + +The workshop is on Thursday 16th June, presented by Mike Croucher, Customer Success Engineer at MathWorks. It is free and exclusively for University of Sheffield PGRs, researchers and lecturers. + +**[Hartree Centre EXPLAIN Training Programme](https://www.eventbrite.com/cc/hartree-centre-explain-training-programme-259399)** + +Part of the Hartree National Centre for Digital Innovation, the EXPLAIN training programme is fully-funded to upskill UK businesses and individuals to use supercomputing, data analytics & AI technologies for enhanced productivity and innovation. +Events are running throughout May and June. + +## Sheffield RSE Team + +The Sheffield RSE Team aims to [collaborate](https://rse.shef.ac.uk/collaboration/guide/) with you to help improve your research software. +They can provide dedicated staff to ensure that you can deliver excellent research software engineering on your research projects. + +The Sheffield RSE Team provides free [Code Clinics][CCs] (in collaboration with [IT Services][its-res-it]), plus [paid services][rse-service] that allow us to collaborate longer term. + +[CCs]: https://rse.shef.ac.uk/support/code-clinic/ +[EPCC]: https://www.epcc.ed.ac.uk/ +[its-res-it]: https://www.sheffield.ac.uk/it-services/research/ +[its-workshops]: https://www.sheffield.ac.uk/it-services/research/one-day-sessions +[rse-service]: https://rse.shef.ac.uk/collaboration/ +[rses-mail-list]: https://groups.google.com/a/sheffield.ac.uk/forum/#!forum/rse-group +[rses]: https://rse.shef.ac.uk/ diff --git a/_newsletters/2022-07-05-newsletter.md b/_newsletters/2022-07-05-newsletter.md new file mode 100644 index 00000000..016da68f --- /dev/null +++ b/_newsletters/2022-07-05-newsletter.md @@ -0,0 +1,104 @@ +--- +layout: post +title: June/July 2022 Newsletter +editor: Norbert Gyenge, Robert Chisholm +slug: 2022-07-05-newsletter +date: 2022-07-05T00:00:00Z+0100 +tags: +category: +link: +description: +type: text +--- +## The University of Sheffield Joint newsletter from RSE and Research IT for June / July 2022 +### Support +#### Code Clinics +Why not come to a [Code Clinic](https://docs.google.com/forms/d/e/1FAIpQLScGXS55qjU0D0Zcz-KHOVcNTahcr3YC3H0OpoKBo3lWXWED5A/viewform)? We're keen to hear from you. + +Code Clinics are fortnightly supported sessions run by the RSE team and IT Services’ [Research and Innovation IT](https://www.sheffield.ac.uk/it-services/research) (ITS R&I) team. They are open to anyone at TUoS writing code for research to get help with programming problems and general advice on best practices. + +At each session, members of the RSE and/or ITS R&I teams will be available to review code, advise, troubleshoot, and suggest ways to improve your computational workflows. + +#### Research IT HPC Drop In +HPC Drop-In sessions are providing assistance with HPC related user issues such as challenges in scaling an application from desktop to supercomputer. We are considering extending the number of our sessions to two or three weekly. These interactive sessions could provide a better interface with our users than our non-interactive ticketing system. These sessions are advertised on the [HPC mailing list](https://groups.google.com/u/1/a/sheffield.ac.uk/g/hpc). + +#### Research IT Consultations +Alongside the HPC Drop-In sessions, we are also running one to one consultations to solve in depth user specific problems. These consultations can be booked via our webpage. If you are interested please visit the following link: [https://students.sheffield.ac.uk/it-services/research/support](https://students.sheffield.ac.uk/it-services/research/support). + +### LunchBytes: Workflow Managers + +The next [LunchBytes session](https://rse.shef.ac.uk/events/lunchbytes-2022-07-21.html) is from 13:30 on the 21st July. + +Scientific workflows (for example in bioinformatics) often require several different scripts or pieces of software to be run and their outputs fed into each other. Ideally, we’d like to be able to understand the provenance of the output, without having to re-run the entire workflow every time a minor change is made to code or data. This is often difficult to achieve with bash or Python scripts (for example), but workflow managers can help. + +#### LunchBytes needs YOU! +LunchBytes are organised by and for the research software community at The University of Sheffield. If you'd like to curate a session on a topic or present something, get in touch by emailing [lunchbytes-organisers-group@sheffield.ac.uk](mailto:lunchbytes-organisers-group@sheffield.ac.uk) - Or suggest topics [on the jamboard](https://jamboard.google.com/d/1-51cRf0pwZl8O10CnLeJGAqKcnbww-QGaYjszFK-H38/). + +### Research IT Forum +Research IT Forum is primarily to engage the research computing community and share research carried out in specific departments. We also use the Forum to signpost new HPC resources. Previous Fora included GPU accelerated and AI/Machine Learning research, image processing and analysing human language. The recordings are available for all attendees. The next Forum is targeted for October. + +### Events +* [DiveRSE talk series: Lessons from Diversity, Equity and Inclusion in open source software](https://diverse-rse.github.io/events/2022-07-05) 16:00-17:00 5th July +* [CarpentryCon 2022](https://2022.carpentrycon.org/) 1-12th August - The Carpentries Community's online conference, this year's theme is expanding data frontiers. +* [RSECon22](https://rsecon2022.society-rse.org/registration/) 6-8th September - The annual UK conference is hosted in Newcastle this year, **registration for attendees closes 6th July!** +* [Digital Humanities Congress 2022](https://www.dhi.ac.uk/dhc2022/) 8-10th September - This Sheffield conference aims to promote the sharing of knowledge, ideas and techniques within the digital humanities, registration for attendees closes 31st August. +* [OpenFest 2022](https://www.sheffield.ac.uk/library/research/openfest-2022) 14-15th September - The University library is hosting this conference on the topic of open research practices. +* [GitKon 2022](https://gitkon.com) 11-13th October - GitKraken is hosting an online conference filled with sessions on everything important to Git users. +* [Computing Insight UK 2022](https://www.scd.stfc.ac.uk/Pages/CIUK-2022-Presentations.aspx) 1-2nd December - A HPC focused conference in Manchester, this year's key theme is Sustainable HPC, abstract submission closes 16th September. + +### News, Web & Blogs +* [Why Science Needs More Research Software Engineers](https://www.nature.com/articles/d41586-022-01516-2) (featuring Shef RSE’s Paul Richmond) +* [Aim For Understandability If You Want To Write Good Research Software](https://www.software.ac.uk/blog/2022-07-04-aim-understandability-if-you-want-write-good-research-software) (featuring Shef RSE’s David Wilby) +* [N8 CIR: RSE Career Event – A Review](https://n8cir.org.uk/events/event-resource/rse-career-event/) +* [The Carpentries: Image Processing with Python - Call for Beta Pilot Applications](https://carpentries.org/blog/2022/05/image-processing-beta-announcement/) +* [GitHub Markdown now has support for mathematical expressions](https://github.blog/2022-05-19-math-support-in-markdown/) +* [GitHub Actions for R Developers (v2)](https://www.tidyverse.org/blog/2022/06/actions-2-0-0/) +* [Microbiology Society Launches an Innovative Open Research Platform](https://microbiologysociety.org/news/society-news/microbiology-society-launches-an-innovative-open-research-platform.html) +* [A Researcher Guide to Writing a Climate Justice Oriented Data Management Plan](https://zenodo.org/record/6451499) + +### Opportunities +* [Enabling Human Centred Decision Making Through Data Visualisation Grant](https://www.ukri.org/opportunity/enabling-human-centred-decision-making-through-data-visualisation/) - Intention to Submit Deadline 8th July +* [UK Gov Knowledge Transfer Partnerships (KTP): 2022 to 2023 Round 3 Funding Competition](https://apply-for-innovation-funding.service.gov.uk/competition/1222/overview/63827061-eb42-4f00-855a-319f88d2a41f) - Closes 14th September + +### Research IT news +#### A100 GPU nodes +Bessemer is now [temporarily upgraded with 64 A100 GPUs](https://changelog.hpc.shef.ac.uk/bessemer-a100-nodes/). The resource is available for immediate use, however, it will be moved to Stanage (see below) in due course. For more information please visit [https://docs.hpc.shef.ac.uk/en/latest/bessemer/GPUComputingBessemer.html#gpucomputing-bessemer](https://docs.hpc.shef.ac.uk/en/latest/bessemer/GPUComputingBessemer.html#gpucomputing-bessemer). + +#### Introduction of our new HPC facility, Stanage +Our new HPC facility, named Stanage, will allow access to ~12,000 cores and 64 GPU (A100). The facility will come online at the end of July/early August. + + +### Training + +Research IT is providing a place for beginners or advanced users to expand their knowledge of HPC and different programming languages. The courses are part of the Doctoral Development Programme. For more information please visit our training registration web page (via VPN): [https://crs.shef.ac.uk](crs.shef.ac.uk). + +**Git & GitHub through GitKraken workshop - from Zero to Hero!** + +Visit the links below for more information. These events are now fully booked, but you can join the waiting list in case any spaces become available. +If you sign up for a course, please make sure you either attend or cancel your booking. Bookings can usually be cancelled via eventbrite. + +* [Tuesday 26th July 09:30-16:30](https://rse.shef.ac.uk/training/workshop/2022-07-26-git-zero-hero) - [Register here](https://www.eventbrite.co.uk/e/git-github-through-gitkraken-from-zero-to-hero-registration-305733546267). + + +## Sheffield RSE Team + +The Sheffield RSE Team aims to [collaborate](https://rse.shef.ac.uk/collaboration/guide/) with you to help improve your research software. + +They can provide dedicated staff to ensure that you can deliver excellent research software engineering on your research projects. + +The Sheffield RSE Team provides free [Code Clinics][CCs] (in collaboration with [IT Services][its-res-it]), plus [paid services][rse-service] that allow us to collaborate longer term. + +## Research IT + +The Research and Innovation Team within IT directly supports research, both academic and commercial. +We provide large scale HPC systems, advice on everything from statistics to ML to data pipelines and training for both students and staff. +Working with academics, our staff are embedded within research groups on both long and short term engagements. + + +[CCs]: https://rse.shef.ac.uk/support/code-clinic/ +[EPCC]: https://www.epcc.ed.ac.uk/ +[its-res-it]: https://www.sheffield.ac.uk/it-services/research/ +[its-workshops]: https://www.sheffield.ac.uk/it-services/research/one-day-sessions +[rse-service]: https://rse.shef.ac.uk/collaboration/ +[rses-mail-list]: https://groups.google.com/a/sheffield.ac.uk/forum/#!forum/rse-group +[rses]: https://rse.shef.ac.uk/ diff --git a/_newsletters/2022-08-15-newsletter.md b/_newsletters/2022-08-15-newsletter.md new file mode 100644 index 00000000..152e2074 --- /dev/null +++ b/_newsletters/2022-08-15-newsletter.md @@ -0,0 +1,125 @@ +--- +layout: post +title: August 2022 Newsletter +editor: David Wilby +slug: 2022-08-15-newsletter +date: 2022-08-15T00:10:00Z+0100 +tags: +category: +link: +description: +type: text +--- +## The University of Sheffield Research Software Engineering Community Newsletter August 2022 + +Welcome to this month's newsletter for the research software community at The University of Sheffield, featuring news, opportunities, events and training for you. + +### News, Web & Blogs +* ‘The entire protein universe’: AI predicts shape of nearly every known protein [(Nature)](https://www.nature.com/articles/d41586-022-02083-2) - DeepMind’s AlphaFold tool has determined the structures of around 200 million proteins. +* [How to create a Python package in 2022](https://mathspp.com/blog/how-to-create-a-python-package-in-2022) - Useful tutorial/blog summarising the current state of python packaging, using Poetry. +* [Welcome to Quarto Workshop](https://www.youtube.com/watch?v=yvi5uXQMvu4) - 2hr webcast walking you through [Quarto](https://quarto.org), the evolution of RMarkdown, supporting Python, Julia and much, much more. +* Code for Thought Podcast + * [Code for Thought is going Live](https://software.ac.uk/blog/2022-08-01-code-thought-going-live) - Peter Schmidt reflects on the progress of the Code for Thought podcast and its future development. + * [Drones, shrubs and ecology](https://codeforthought.buzzsprout.com/1326658/10852099-drones-and-ecology) Listen to SSI Fellow Isla Myers-Smiths who tells us how they measure climate change in arctic ecosystems and the technical challenges involved. + * [Open Science and Research Software](https://codeforthought.buzzsprout.com/1326658/10822132-open-science-and-research-software) Teresa Gomez-Diaz from the University Gustave Eiffel in Paris takes us through open science, open software and the importance of software licensing (often forgotten by engineers). + + +### Events +* [Research Software Hour](https://researchsoftwarehour.github.io/) weekly, Thursdays 19:30 UK time / 20:30 Oslo time / 21:30 Helsinki time - Hosted by members of the Nordic-RSE community, this continues weekly on Twitch. Research Software Hour is an online stream/show about scientific computing and research software. It is designed to provide the skills typically picked up via informal networks; each week, they do some combination of exploring new tools, analyzing and improving someone’s research code, and discussion. Watchers can take part and contribute code to us which they analyze and discuss on stream. +* [RSECon22](https://rsecon2022.society-rse.org/registration/) 6-8th September - The annual UK conference is hosted in Newcastle this year, registration is closed. +* [Digital Humanities Congress 2022](https://www.dhi.ac.uk/dhc2022/) 8-10th September - This Sheffield conference aims to promote the sharing of knowledge, ideas and techniques within the digital humanities, registration for attendees closes 31st August. +* [Sheffield DevOps Meetup](https://www.sheffielddevops.org.uk/september-2022/) 8th September - Speaker: Tom Hoyland with *Metaphors, Monitoring and Metrics: How a Platform Team changed the way they communicated to change the way they delivered products and services*. +* [Write the Docs 2022](https://www.writethedocs.org/conf/prague/2022/) 11-13 September 2022 - Write the Docs brings everyone who writes the docs together in the same room: Programmers, Tech Writers, Support, Designers, Developer Advocates, and more. We all have things to learn from each other, and there’s no better way than sitting together and talking. We invite you to join 300 other folks in our event to explore the art and science of documentation. +* OpenFest 2022 14-15th September - The University library is hosting this conference on the topic of open research practices. [Programme Here](https://docs.google.com/document/d/1_Eo3uOoUv3tcUUK_YUTmWcc-YTszpAQ3JFVHs-C-e9c/edit?usp=sharing) - [Register Here](https://www.eventbrite.co.uk/e/openfest-2022-tickets-383818570677) +* [GitKon 2022](https://gitkon.com) 11-13th October - GitKraken is hosting an online conference filled with sessions on everything important to Git users. +* [1st International Conference on FAIR Digital Objects](https://www.fdo2022.org/) 26-28 October +* [Computing Insight UK 2022](https://www.scd.stfc.ac.uk/Pages/CIUK-2022-Presentations.aspx) 1-2nd December - A HPC focused conference in Manchester, this year's key theme is Sustainable HPC, abstract submission closes 16th September. + +### Training + +#### Introduction to Deep Learning with Tensorflow in Python + +14 September 2022 - 09:00-17:00 + +Details: + +Recent advances in deep neural networks coupled with an increasing amount and complexity of scientific data collected in a wide array of domains provide many exciting opportunities for deep learning applications in scientific settings. Furthermore, libraries such as Google’s Tensorflow python library have made building deep learning models more accessible through common tools, freely available to researchers. + +In this course, we’ll introduce some basic neural network and deep learning theory and give participants practical experience in some popular deep learning models and techniques. + +Content includes: + +* Introduction to Regression and Classification using neural networks +* Image classification with Convolutional neural networks +* Speeding up the training process of your own models using existing neural network + +Register via eventbrite: + + +#### Research IT Training +Research IT is providing a place for beginners or advanced users to expand their knowledge of HPC and different programming languages. The courses are part of the Doctoral Development Programme. For more information please visit our training registration web page (via VPN): [https://crs.shef.ac.uk](crs.shef.ac.uk). + +#### Git & GitHub through GitKraken workshop - from Zero to Hero! + +This highly popular workshop will run again in September, October and November. [Join the RSE mailing list][rses-mail-list] to be the first to get the details. +### Opportunities +#### Funding +* [Software Sustainability Institute Fellowships](https://software.ac.uk/news/applications-ssi-fellowship-programme-2023-now-open) - 2023 applications now open! The Institute’s Fellowship Programme provides funding for individuals who want to improve how research software is done in their domains, fields and/or areas of work. Being a Fellow also helps individuals develop skills and knowledge in their area of software sustainability, empowers them to speak about software sustainability issues and network with like-minded individuals from a wide variety of backgrounds. [See here for more details!](https://software.ac.uk/news/applications-ssi-fellowship-programme-2023-now-open) Deadline 3rd October. +* [Sony Research Award Program](https://www.sony.com/en/SonyInfo/research-award-program) - The Sony Research Award Program provides funding for cutting-edge academic research and helps build a collaborative relationship between faculty and Sony researchers. Application deadline 15th September. +* [Get up to 12 days of software engineering support for your HPC/ML/GPU project](https://rse.shef.ac.uk/collaboration/tier2/). The Research Software Engineering team is offering to support researchers with the use of High Performance Computing (HPC), Machine Learning (ML) and Graphics Processors (GPUs) in their research projects. All researchers at our University can receive up to £5,000 of support time, or roughly 12 days of support, provided by a Research Software Engineer (RSE). This call aims to increase the uptake of the University's Tier 2 HPC resources, which are national facilities available to researchers in all faculties. This is an open call and applications are considered on a first-come-first-served basis. The deadline for submitting your application is Friday 16 September 2022. Applications received after this date will be reviewed in the next round. Find out more about this opportunity at: + +#### Jobs +* [2 RSE Roles at University of Exeter](https://jobs.exeter.ac.uk/hrpr_webrecruitment/wrd/run/ETREC107GF.open?VACANCY_ID=374483aYvJ&WVID=3817591jNg&LANG=USA) - Closes 17th August +* [CTO at Beautiful Canoe, Aston University spinout](https://jobs.aston.ac.uk/Vacancy.aspx?ref=R220487) - closes 19th August +* [UK Gov Knowledge Transfer Partnerships (KTP): 2022 to 2023 Round 3 Funding Competition](https://apply-for-innovation-funding.service.gov.uk/competition/1222/overview/63827061-eb42-4f00-855a-319f88d2a41f) - Closes 14th September + +### LunchBytes: Workflow Managers + +The recording from last month's [LunchBytes session](https://rse.shef.ac.uk/events/lunchbytes-2022-07-21.html) on workflow managers is now available [on the event's webpage](https://rse.shef.ac.uk/events/lunchbytes-2022-07-21.html). + +Featuring: +* Will Furnass: The Trouble with Scripts - setting the scene by showing us how, without workflow management, stitching several pieces of software together can present some challenges. +* Magda Dabrowska: [Nextflow](https://www.nextflow.io/) - a relatively new workflow manager which allows for writing scalable computational pipelines. +* Ian Sudbery: [Ruffus](http://www.ruffus.org.uk/) - one of the oldest of the modern style workflow management systems. Ruffus pipelines consist of a series of python functions that are linked together using a python feature known as decorators. +* Joe Heffer: [Common Workflow Language](https://www.commonwl.org/) - an open standard for describing how to run command line tools and connect them to create workflows. + + +#### LunchBytes needs YOU! +LunchBytes are organised by and for the research software community at The University of Sheffield. If you'd like to curate a session on a topic or present something, get in touch by emailing [lunchbytes-organisers-group@sheffield.ac.uk](mailto:lunchbytes-organisers-group@sheffield.ac.uk) - Or suggest topics [on the jamboard](https://jamboard.google.com/d/1-51cRf0pwZl8O10CnLeJGAqKcnbww-QGaYjszFK-H38/). + +### Support +#### Code Clinics +Why not come to a [Code Clinic](https://docs.google.com/forms/d/e/1FAIpQLScGXS55qjU0D0Zcz-KHOVcNTahcr3YC3H0OpoKBo3lWXWED5A/viewform)? We're keen to hear from you. + +Code Clinics are fortnightly supported sessions run by the RSE team and IT Services’ [Research and Innovation IT](https://www.sheffield.ac.uk/it-services/research) (ITS R&I) team. They are open to anyone at TUoS writing code for research to get help with programming problems and general advice on best practices. + +At each session, members of the RSE and/or ITS R&I teams will be available to review code, advise, troubleshoot, and suggest ways to improve your computational workflows. + +#### Research IT HPC Drop In +HPC Drop-In sessions are providing assistance with HPC related user issues such as challenges in scaling an application from desktop to supercomputer. We are considering extending the number of our sessions to two or three weekly. These interactive sessions could provide a better interface with our users than our non-interactive ticketing system. These sessions are advertised on the [HPC mailing list](https://groups.google.com/u/1/a/sheffield.ac.uk/g/hpc). + +#### Research IT Consultations +Alongside the HPC Drop-In sessions, Research IT are also running one to one consultations to solve in depth user specific problems. These consultations can be booked via our webpage. If you are interested please visit the following link: . + +## Sheffield RSE Team + +The Sheffield RSE Team aims to [collaborate](https://rse.shef.ac.uk/collaboration/guide/) with you to help improve your research software. + +They can provide dedicated staff to ensure that you can deliver excellent research software engineering on your research projects. + +The Sheffield RSE Team provides free [Code Clinics][CCs] (in collaboration with [IT Services][its-res-it]), plus [paid services][rse-service] that allow us to collaborate longer term. + +## Research IT + +The Research and Innovation Team within IT directly supports research, both academic and commercial. +We provide large scale HPC systems, advice on everything from statistics to ML to data pipelines and training for both students and staff. +Working with academics, our staff are embedded within research groups on both long and short term engagements. + + +[CCs]: https://rse.shef.ac.uk/support/code-clinic/ +[EPCC]: https://www.epcc.ed.ac.uk/ +[its-res-it]: https://www.sheffield.ac.uk/it-services/research/ +[its-workshops]: https://www.sheffield.ac.uk/it-services/research/one-day-sessions +[rse-service]: https://rse.shef.ac.uk/collaboration/ +[rses-mail-list]: https://groups.google.com/a/sheffield.ac.uk/forum/#!forum/rse-group +[rses]: https://rse.shef.ac.uk/ diff --git a/_newsletters/2022-09-20-newsletter.md b/_newsletters/2022-09-20-newsletter.md new file mode 100644 index 00000000..1b6460a2 --- /dev/null +++ b/_newsletters/2022-09-20-newsletter.md @@ -0,0 +1,106 @@ +--- +layout: post +title: September 2022 Newsletter +editor: Peter Heywood +slug: 2022-09-20-newsletter +date: 2022-09-20T00:16:00Z+0100 +tags: +category: +link: +description: +type: text +--- +## The University of Sheffield Research Software Engineering Community Newsletter September 2022 + +Welcome to this month's newsletter for the research software community at The University of Sheffield, featuring news, opportunities, events and training for you. + +### News, Web & Blogs + +* [White Rose Open Educational Resources (OER) Toolkit](https://sites.google.com/york.ac.uk/oertoolkit/) +* [GitHub - SSH commit verification now supported](https://github.blog/changelog/2022-08-23-ssh-commit-verification-now-supported/) +* [Research IT Manchester - Meet Our Year in Industry Students!](https://research-it.manchester.ac.uk/news/2022/07/29/meet-our-year-in-industry-students/) +* [rstudio::conf(2022)](https://www.rstudio.com/conference/) talks are [available on-demand](https://www.rstudio.com/conference/2022/2022-conf-talks/). +* [Python Package Index - targetted phishing campaign](https://twitter.com/pypi/status/1562442188285308929) +* [PLOS partners with DataSeer to develop Open Science Indicators](https://theplosblog.plos.org/2022/09/plos-partners-with-dataseer-to-develop-open-science-indicators/) +* [2022 RSE Survey initial analysis is complete and online](https://softwaresaved.github.io/international-survey-2022/). [Results](https://softwaresaved.github.io/international-survey-2022/), [GitHub](https://github.com/softwaresaved/international-survey-2022) +* [Python Packaging User Survey](https://www.surveymonkey.co.uk/r/M5XKQCT). The objective of this survey is to help the Python Software Foundation (PSF), Packaging Working Group and Python Packaging Authority (PyPA) better understand the challenges and opportunities within the Python packaging ecosystem. Closes 2022-09-30. +* The Sheffield RSE webpages on [Researcher Programming Resources](https://rse.shef.ac.uk/training/programming) have been updated to include a number of new additional resources. + +### Events + +* [NVIDIA GPU Technology Conference (#GTC22)](https://www.nvidia.com/gtc/?ncid=ref-dli-435814) - Join NVIDIA #GTC22 online (2022-09-19 to 2022-09-22) to discover the innovations that will impact your life’s work. Explore over 200 sessions from some of the brightest minds solving the world’s greatest challenges. Register for free now. +* [Hacktoberfest 2022](https://hacktoberfest.com/) - Hacktoberfest is DigitalOcean’s annual event that encourages people to contribute to open source throughout October. New for 2022 Low or Non-Code contributions are being encouraged! Registration begins 2022-09-26. +* [N8 CIR Ally Skills Training by Open Life Science](https://n8cir.org.uk/events/ally-skills/) - 2022-10-07 (Online). In this interactive workshop, you will learn about your own privileges and how to use them to step up for others. +* [Investing in Code Reviews for Better Research Software](http://ideas-productivity.org/events/hpc-best-practices-webinars/) - 2022-10-12 (Online). +* [1st International Conference on FAIR Digital Objects](https://www.fdo2022.org/) - 2022-10-26 to 2022-10-28 (Leiden, The Netherlands). We have been living a data revolution for decades now. Every day, peta bytes of information of all kinds are generated and made accessible on the Internet. The amount of information is so massive that soon, it will no longer be feasible for us to process it manually. What to do then? +* [N8 CIR Machine Learning Theme Launch](https://n8cir.org.uk/events/machine-learning-theme-launch/) - 2022-11-01, The University of Leeds. Open to all researchers, PGRs and anyone involved in Machine Learning at an N8 institution, this event will bring the Machine Learning community from across N8 together to find out more about N8 CIR, plans for the theme and all-important networking opportunities. +* [PyData Global 2022](https://pdg22.wpengine.com) - 2022-12-01 to 2022-12-03, Online. The PyData Global conference is an opportunity to listen, learn, and share knowledge about best practices, new approaches, and emerging technologies for data management, processing, analytics, and visualization. + +### Training + +#### Research IT Training + +Research IT is providing a place for beginners or advanced users to expand their knowledge of HPC and different programming languages. The courses are part of the Doctoral Development Programme. For more information please visit our training registration web page (via VPN): [crs.shef.ac.uk](https://crs.shef.ac.uk). + +#### Git & GitHub through GitKraken workshop - from Zero to Hero! + +This is an introductory course, teaching the git and GitHub skills required to manage research code over it’s development lifecycle. These skills are essential for collaborative research teams. +This two half-day course is being ran multiple times in the coming months: + +* [2022-10-03 & 2022-10-04](https://rse.shef.ac.uk/training/workshop/2022-10-03-git-zero-hero) (Sold Out) +* [2022-10-31 & 2022-11-01](https://rse.shef.ac.uk/training/workshop/2022-10-31-git-zero-hero) ([Register via eventbrite](https://www.eventbrite.co.uk/e/git-github-through-gitkraken-from-zero-to-hero-registration-406112592697)) +* [2022-11-28 & 2022-11-29](https://rse.shef.ac.uk/training/workshop/2022-11-28-git-zero-hero) ([Register via eventbrite](https://www.eventbrite.co.uk/e/git-github-through-gitkraken-from-zero-to-hero-registration-406116594667)) + +### Opportunities + +#### Funding + +* [Software Sustainability Institute Fellowships](https://software.ac.uk/news/applications-ssi-fellowship-programme-2023-now-open) - 2023 applications now open! The Institute’s Fellowship Programme provides funding for individuals who want to improve how research software is done in their domains, fields and/or areas of work. Being a Fellow also helps individuals develop skills and knowledge in their area of software sustainability, empowers them to speak about software sustainability issues and network with like-minded individuals from a wide variety of backgrounds. [See here for more details!](https://software.ac.uk/news/applications-ssi-fellowship-programme-2023-now-open) Deadline 2022-10-03. +* [Get up to 12 days of software engineering support for your HPC/ML/GPU project](https://rse.shef.ac.uk/collaboration/tier2/). The Research Software Engineering team is offering to support researchers with the use of High Performance Computing (HPC), Machine Learning (ML) and Graphics Processors (GPUs) in their research projects. All researchers at our University can receive up to £5,000 of support time, or roughly 12 days of support, provided by a Research Software Engineer (RSE). This call aims to increase the uptake of the University's Tier 2 HPC resources, which are national facilities available to researchers in all faculties. This is an open call and applications are considered on a first-come-first-served basis. The deadline for submitting your application is 2022-09-16. Applications received after this date will be reviewed in the next round. +* [ARCHER2 Embedded CSE (eCSE) Support Call](https://www.archer2.ac.uk/ecse/calls/). The ARCHER2 eCSE call provides funding for up to 18 person months of an RSE/PDRA to work on codes to run on ARCHER2. The deadline for submitting documents for technical evaluations is 2022-10-04 16:00 BST with a final proposal deadline of 2022-10-25 16:00 BST. +* [ARCHER2 Early Career eCSE Panel Observers Call](https://www.archer2.ac.uk/ecse/observers/). The eCSE Panel Meeting is the meeting where eCSE proposals are reviewed and decisions are made on which proposals to fund. As part of our commitment to encouraging and developing Early Career Researchers, we are offering a small number of places to such researchers to attend the eCSE panel meeting as Early Career Observers. The aim is to give Early Career Researchers a better insight into this competitive selection process, to assist them in the preparation of future funding proposals. The deadline for applying to attend the panel meeting as an observer is 2022-10-04 16:00 BST. +* [CHIST-ERA Open & Re-usable Research Data & Software](https://www.chistera.eu/call-ord-announcement). This call tackles the challenge of open research data and software from the perspective of their possible reuse. The objective is to create the conditions for research in any domain based on open or shared data and software. Call deadline: 2022-12-14 17:00 CET + + + +### LunchBytes + +#### LunchBytes needs YOU! + +LunchBytes are organised by and for the research software community at The University of Sheffield. If you'd like to curate a session on a topic or present something, get in touch by emailing [lunchbytes-organisers-group@sheffield.ac.uk](mailto:lunchbytes-organisers-group@sheffield.ac.uk) - Or suggest topics [on the jamboard](https://jamboard.google.com/d/1-51cRf0pwZl8O10CnLeJGAqKcnbww-QGaYjszFK-H38/). + +### Support + +#### Code Clinics + +Why not come to a [Code Clinic](https://docs.google.com/forms/d/e/1FAIpQLScGXS55qjU0D0Zcz-KHOVcNTahcr3YC3H0OpoKBo3lWXWED5A/viewform)? We're keen to hear from you. + +Code Clinics are fortnightly supported sessions run by the RSE team and IT Services’ [Research and Innovation IT](https://www.sheffield.ac.uk/it-services/research) (ITS R&I) team. They are open to anyone at TUoS writing code for research to get help with programming problems and general advice on best practices. + +At each session, members of the RSE and/or ITS R&I teams will be available to review code, advise, troubleshoot, and suggest ways to improve your computational workflows. + +#### Research IT HPC Drop In + +HPC Drop-In sessions are providing assistance with HPC related user issues such as challenges in scaling an application from desktop to supercomputer. We are considering extending the number of our sessions to two or three weekly. These interactive sessions could provide a better interface with our users than our non-interactive ticketing system. These sessions are advertised on the [HPC mailing list](https://groups.google.com/u/1/a/sheffield.ac.uk/g/hpc). + +#### Research IT Consultations + +Alongside the HPC Drop-In sessions, Research IT are also running one to one consultations to solve in depth user specific problems. These consultations can be booked via our webpage. If you are interested please visit the following link: . + +## Sheffield RSE Team + +The Sheffield RSE Team aims to [collaborate](https://rse.shef.ac.uk/collaboration/guide/) with you to help improve your research software. + +They can provide dedicated staff to ensure that you can deliver excellent research software engineering on your research projects. + +The Sheffield RSE Team provides free [Code Clinics][CCs] (in collaboration with [IT Services][its-res-it]), plus [paid services][rse-service] that allow us to collaborate longer term. + +## Research IT + +The Research and Innovation Team within IT directly supports research, both academic and commercial. +We provide large scale HPC systems, advice on everything from statistics to ML to data pipelines and training for both students and staff. +Working with academics, our staff are embedded within research groups on both long and short term engagements. + +[CCs]: https://rse.shef.ac.uk/support/code-clinic/ +[its-res-it]: https://www.sheffield.ac.uk/it-services/research/ +[rse-service]: https://rse.shef.ac.uk/collaboration/ diff --git a/_newsletters/2022-10-26-newsletter.md b/_newsletters/2022-10-26-newsletter.md new file mode 100644 index 00000000..cc442182 --- /dev/null +++ b/_newsletters/2022-10-26-newsletter.md @@ -0,0 +1,139 @@ +--- +layout: post +title: October 2022 Newsletter +editor: Robert (Bob) Turner +slug: 2022-10-26-newsletter +date: 2022-10-26T00:00:00Z+0100 +tags: +category: +link: +description: +type: text +--- +## The University of Sheffield Research Software Engineering Community Newsletter October 2022 + +Welcome to this month's newsletter for the research software community at The University of Sheffield, featuring news, opportunities, events and training for you. + +> It's been an action packed month. Three new blog posts on the RSE Team website, two focussed on making quality code easy to achieve and one on valuing the outputs of RSEs and others. We've had the launch of the [MATLAB User survey](https://docs.google.com/forms/d/e/1FAIpQLSfackAnztuL1fQ_l66XLdEKSIuCIie6T-XrA7srTsmRiiVq_w/viewform) helping push forward better research practises in this vitally important language for research coders. The RSE Team has a new member, [Edwin Brown](https://rse.shef.ac.uk/contact/edwin-brown/), who will boost the teams capacity, particularly around AI and Machine Learning. And news that [Paul Richmond is a winner](https://www.sheffield.ac.uk/dcs/news/paul-richmond-honoured-contribution-society-research-software-engineers) of an award from the RSE Society recognising his contribution as president of the organisation. +> +> Looking ahead to November, please come along to the next LunchBytes event on ["Teaching Code"](https://rse.shef.ac.uk/events/lunchbytes-2022-11-24). + +*Bob* + +### News, Web & Blogs + +#### Blogs from the RSE Team: + +* [pre-commit : Protecting your future self](https://rse.shef.ac.uk/blog/pre-commit) Pre-commit is a powerful tool for executing a range of hooks prior to making commits to your Git history. This is useful because it means you can automatically run a range of linting tools on your code across an array of languages to ensure your code is up-to-scratch before you make the commit. +* [Demonstrating Importance and Value in Research Software](https://rse.shef.ac.uk/blog/2022-10-13-quality-value-research-software) As research software engineers (RSEs) or researchers who develop software & code, at some point we will need to provide evidence that our software actually has some positive effect on the world. Whether this is for career progression, the REF, just for your own peace of mind... +* [Writing better and more shareable code](https://rse.shef.ac.uk/blog/2022-10-20-better-code) If you know how to write code, it’s not actually that hard to make it better! You just need to know how. + +#### New LunchBytes recording online + +* [LunchBytes: From Eyes to Apps](https://rse.shef.ac.uk/events/lunchbytes-2022-10-20) Our speaker this month was Dr Ilse Daly who told us about her journey from vision scientist to start-up founder at her company Blackdog Biomechanics. + +#### Web and publications + +* [Introducing the FAIR Principles for research software](https://www.nature.com/articles/s41597-022-01710-x) Research software is a fundamental and vital part of research, yet significant challenges to discoverability, productivity, quality, reproducibility, and sustainability exist. Improving the practice of scholarship is a common goal of the open science, open source, and FAIR (Findable, Accessible, Interoperable and Reusable) communities and research software is now being understood as a type of digital object to which FAIR should be applied. +* [Champions Program — A mentoring & training program for Scientific Open Source Champions](https://ropensci.org/champions/) Research software should serve everyone in our communities, which means it needs to be sustainable, open, and built by and for all groups. Currently, however, there is a dismaying lack of diversity in open source communities in general... +* [Announcing the 2022 Table Contest](https://www.rstudio.com/blog/rstudio-table-contest-2022/) This contest aims to highlight the many great ways people transform and present data. +* [Best Practices for HPC Software Developers (Webinars)](http://ideas-productivity.org/events/hpc-best-practices-webinars/) The HPC Best Practices webinars address issues faced by developers of computational science and engineering (CSE) software on high-performance computers (HPC). The sessions are independent, so join any or all. + +### Events + +* [Climate Justice and Open Research online event](https://www.eventbrite.co.uk/e/climate-justice-and-open-research-online-event-tickets-431743094217) October 27th. In this session, TUoS researchers explore the value of open research practices in the response to climate challenges and inequalities. +* [N8 CIR Machine Learning Theme Launch](https://n8cir.org.uk/events/machine-learning-theme-launch/) - 2022-11-01, The University of Leeds. Open to all researchers, PGRs and anyone involved in Machine Learning at an N8 institution, this event will bring the Machine Learning community from across N8 together to find out more about N8 CIR, plans for the theme and all-important networking opportunities. +* [ODI Summit 2022: Data Decade](https://summit2022.theodi.org/) Join the Summit virtually on 8 November 2022 from 10:00 – 22:00 GMT, where you will hear from world-leading data and AI experts, including the inventor of the World Wide Web, Sir Tim Berners-Lee and AI expert Sir Nigel Shadbolt addressing the data challenges we will face in the years ahead. +* [NHS-R Community Conference 2022](https://nhsrcommunity.com/events/nhs-r-community-conference-2022/) 16th and 17th November 2022. The main conference is a hybrid conference with the opportunity to join in person at Edgbaston Stadium, Birmingham or to join online via Zoom. +* [LunchBytes Panel: Teaching Code](https://rse.shef.ac.uk/events/lunchbytes-2022-11-24) As code and software become an ever bigger part of research (its likely that around 1/3 of researchers write code), coding and other digital skills become ever more important to researchers. In this online panel discussion, we will explore this with a few questions. +* [Computing Insight UK 2022](https://www.scd.stfc.ac.uk/Pages/CIUK2022.aspx) Manchester Central Convention Complex on Thursday 1 and Friday 2 December. The theme for the conference this year is "Sustainable HPC" with sub-themes including "Sustainable Skills", "Sustainable Funding" and "Net Zero Computing". +* [PyData Global 2022](https://pdg22.wpengine.com) - 2022-12-01 to 2022-12-03, Online. The PyData Global conference is an opportunity to listen, learn, and share knowledge about best practices, new approaches, and emerging technologies for data management, processing, analytics, and visualization. +* [Reproducible Analytical Pipelines Webinar](https://www.eventbrite.co.uk/e/reproducible-analytical-pipelines-webinar-tickets-428453535057) November 3rd. Join HDR UK and DNAnexus for a free webinar on reproducible analytical pipelines. +* [UK National Open Hackathon 2023](https://www.openhackathons.org/s/siteevent/a0C5e000005V6EDEA0/se000151) Application Deadline January 16, 2023. Open Hackathons are multi-day intensive hands-on events designed to help computational scientists and researchers port and optimize their applications using GPUs. + +### Training + +#### Research IT Training + +Research IT is providing a place for beginners or advanced users to expand their knowledge of HPC and different programming languages. The courses are part of the Doctoral Development Programme. For more information please visit our training registration web page (via VPN): [crs.shef.ac.uk](https://crs.shef.ac.uk). + +#### RSE Team: Git & GitHub through GitKraken workshop - from Zero to Hero! + +This is an introductory course, teaching the git and GitHub skills required to manage research code over it’s development lifecycle. These skills are essential for collaborative research teams. + +This two half-day course is being run multiple times in the coming months: + +* [31 October 2022 and 1 November 2022](https://rse.shef.ac.uk/training/workshop/2022-10-31-git-zero-hero) "sold out" +* [28 November 2022 and 29 November 2022](https://rse.shef.ac.uk/training/workshop/2022-11-28-git-zero-hero) + +If a course is "sold out" please join the wait list - we regularly email people to encourage those that can no longer attend to cancel. + +#### RSE Team: Introduction to Deep Learning Course with Tensorflow Keras (in Python) + +A one-day introduction to deep learning with practical labs using Tensorflow in Python: + +* [16 November 2022](https://rse.shef.ac.uk/training/workshop/2022-11-16-deep-learning-with-tensorflow-in-python) +* [18 January 2023](https://rse.shef.ac.uk/training/workshop/2023-01-18-deep-learning-with-tensorflow-in-python) + +If a course is "sold out" please join the wait list - we regularly email people to encourage those that can no longer attend to cancel. + +#### Bioinformatics Training + +* [Introduction to RNA-seq analysis in R](https://sbc.shef.ac.uk/training/rna-seq-in-r-2022-12-12/) Monday 12th December 13:00 - 16:00, Wednesday 14th December 13:00 - 16:00, Friday 16th December 13:00 - 16:00 + +### Opportunities + +#### Funding + +* [Get up to 12 days of software engineering support for your HPC/ML/GPU project](https://rse.shef.ac.uk/collaboration/tier2/). The Research Software Engineering team is offering to support researchers with the use of High Performance Computing (HPC), Machine Learning (ML) and Graphics Processors (GPUs) in their research projects. All researchers at our University can receive up to £5,000 of support time, or roughly 12 days of support, provided by a Research Software Engineer (RSE). This call aims to increase the uptake of the University's Tier 2 HPC resources, which are national facilities available to researchers in all faculties. This is an open call and applications are considered on a first-come-first-served basis. There is no current deadline and applications will be reviewed on an ongoing basis. +* [ARCHER2 Embedded CSE (eCSE) Support Call](https://www.archer2.ac.uk/ecse/calls/). The ARCHER2 eCSE call provides funding for up to 18 person months of an RSE/PDRA to work on codes to run on ARCHER2. The deadline for submitting documents for technical evaluations is 2022-10-04 16:00 BST with a final proposal deadline of 2022-10-25 16:00 BST. +* [Digital Infrastructure Incubator](https://www.codeforsociety.org/incubator/accepting-proposals) Deadline December 2, 2022. Code for Science & Society (CS&S) solicits expressions of interest from open source digital infrastructure teams to participate in the second cohort of the Digital Infrastructure Incubator (DII). +* [CHIST-ERA Open & Re-usable Research Data & Software](https://www.chistera.eu/call-ord-announcement). This call tackles the challenge of open research data and software from the perspective of their possible reuse. The objective is to create the conditions for research in any domain based on open or shared data and software. Call deadline: 2022-12-14 17:00 CET +* [Oracle for Research Project Awards](https://www.oracle.com/research/project-awards/) Oracle Research (this years sponsors of the RSE conference) have an open grants program to sponsor research projects with free cloud credits to tackle computational challenges. The majority of cloud providers no longer offer free credits however Oracle grants include access to a variety of Oracle Cloud technologies including compute, GPUs, and HPC. In addition to cloud credits, they also provide researchers and supporting RSEs with technical cloud support to transition and optimize their workflows on an Oracle Cloud environment. If interested then apply directly. + + + +### LunchBytes + +[LunchBytes](https://rse.shef.ac.uk/community/lunch-bytes/) are a monthly series of short talks from the research community on research software, data, and infrastructure. [November's LunchBytes (24 November 2022 - 12:00-13:00), will be a panel discussion on "Teaching Code"](https://rse.shef.ac.uk/events/lunchbytes-2022-11-24). + + +#### LunchBytes needs YOU! + +LunchBytes are organised by and for the research software community at The University of Sheffield. If you'd like to curate a session on a topic or present something, get in touch by emailing [lunchbytes-organisers-group@sheffield.ac.uk](mailto:lunchbytes-organisers-group@sheffield.ac.uk) - Or suggest topics [on the jamboard](https://jamboard.google.com/d/1-51cRf0pwZl8O10CnLeJGAqKcnbww-QGaYjszFK-H38/). + +### Support + +#### Code Clinics + +Why not come to a [Code Clinic](https://docs.google.com/forms/d/e/1FAIpQLScGXS55qjU0D0Zcz-KHOVcNTahcr3YC3H0OpoKBo3lWXWED5A/viewform)? We're keen to hear from you. + +Code Clinics are fortnightly supported sessions run by the RSE team and IT Services’ [Research and Innovation IT](https://www.sheffield.ac.uk/it-services/research) (ITS R&I) team. They are open to anyone at TUoS writing code for research to get help with programming problems and general advice on best practices. + +At each session, members of the RSE and/or ITS R&I teams will be available to review code, advise, troubleshoot, and suggest ways to improve your computational workflows. + +#### Research IT HPC Drop In + +HPC Drop-In sessions are providing assistance with HPC related user issues such as challenges in scaling an application from desktop to supercomputer. We are considering extending the number of our sessions to two or three weekly. These interactive sessions could provide a better interface with our users than our non-interactive ticketing system. These sessions are advertised on the [HPC mailing list](https://groups.google.com/u/1/a/sheffield.ac.uk/g/hpc). + +#### Research IT Consultations + +Alongside the HPC Drop-In sessions, Research IT are also running one to one consultations to solve in depth user specific problems. These consultations can be booked via our webpage. If you are interested please visit the following link: . + +## Sheffield RSE Team + +The Sheffield RSE Team aims to [collaborate](https://rse.shef.ac.uk/collaboration/guide/) with you to help improve your research software. + +They can provide dedicated staff to ensure that you can deliver excellent research software engineering on your research projects. + +The Sheffield RSE Team provides free [Code Clinics][CCs] (in collaboration with [IT Services][its-res-it]), plus [paid services][rse-service] that allow us to collaborate longer term. + +## Research IT + +The Research and Innovation Team within IT directly supports research, both academic and commercial. +We provide large scale HPC systems, advice on everything from statistics to ML to data pipelines and training for both students and staff. +Working with academics, our staff are embedded within research groups on both long and short term engagements. + +[CCs]: https://rse.shef.ac.uk/support/code-clinic/ +[its-res-it]: https://www.sheffield.ac.uk/it-services/research/ +[rse-service]: https://rse.shef.ac.uk/collaboration/ diff --git a/_newsletters/2022-11-25-newsletter.md b/_newsletters/2022-11-25-newsletter.md new file mode 100644 index 00000000..977417c0 --- /dev/null +++ b/_newsletters/2022-11-25-newsletter.md @@ -0,0 +1,136 @@ +--- +layout: post +title: November 2022 Newsletter +editor: Edwin Brown +slug: 2022-11-29-newsletter +date: 2022-11-29T00:00:00Z+0100 +tags: +category: +link: +description: +type: text +--- +## The University of Sheffield Research Software Engineering Community Newsletter November 2022 + +Welcome to this month's newsletter for the research software community at The University of Sheffield, featuring news, opportunities, events and training for you. + +### News, Web & Blogs + +#### New LunchBytes recording online + +* [LunchBytes Panel: Teaching Code](https://rse.shef.ac.uk/events/lunchbytes-2022-11-24.html) - As code and software become an ever bigger part of research (its likely that around 1/3 of researchers write code), coding and other digital skills become ever more important to researchers. Questions around teaching code were put to an online panel. The panel included [Emma Norling](https://www.sheffield.ac.uk/dcs/people/academic/emma-norling) (Director of Learning and Teaching in the Department of Computer Science at the University of Sheffield), [Shangshang Gu](https://www.linkedin.com/in/%E5%B0%9A%E5%B0%9A-%E9%A1%BE-89935b129) (School of Health and Related Research, University of Sheffield), [Ashley Cadby](https://www.sheffield.ac.uk/physics/people/academic/ashley-cadby) who plays a key role in teaching code in the Department of Physics and Astronomy at the University of Sheffield and [Norbert Gyenge](https://www.linkedin.com/in/norbert-g-gyenge-7ba718201) (IT Services) with expertise in shorter courses. Thanks to Bob for organising the event! + +#### Web and Publications + + +* [RSE mentoring scheme](https://forms.coachmentoring.co.uk/socrse/application/) - Registration deadline is 30th November. +* [15 new Fellows to start training in data stewardship and management](https://elixiruknode.org/news/2022/15-new-fellows-dash-project/) - 15 Fellows are joining the fellowship of the ELIXIR-UK DaSH project to seed local data steward communities across the UK. Fellows will work with ELIXIR-UK to produce and deliver training in Research Data Management (RDM) within their host Universities and Institutes. +* [Amsterdam Declaration on Funding Research Software Sustainability](https://zenodo.org/record/7330542#.Y4DP7nbP3tU) - The Research Software Alliance (ReSA) and the Netherlands eScience Center hosted a two-day international workshop in Amsterdam (the Netherlands) on 8-9 November 2023 to set the future agenda for national and international funders to support sustainable research software. As the importance of software in research has become increasingly apparent, so has the urgent need to sustain it. +* [Ten simple rules for funding scientific open source software](https://journals.plos.org/ploscompbiol/article?id=10.1371/journal.pcbi.1010627) - Scientific research increasingly relies on open source software (OSS). Funding OSS development requires intentional focus on issues of scholarly credit, unique forms of labor, maintenance, governance, and inclusive community-building. Such issues cut across different scientific disciplines that make them of interest to a variety of funders and institutions but may present challenges in understanding generalized needs. Here we present 10 simple rules for investing in scientific OSS and the teams who build and maintain it. +* [Case study: Asynchronous task scheduling for the Music #AI project](https://casestudiesrcg.blogspot.com/2022/11/asynchronous-task-scheduling-for-music.html) - Research Innovation and IT have been working on an exciting project with researchers from the Department of Computer Science. The goal of this project was to improve the existing music AI web application in terms of usability, maintainability, and scalability. +* [Code Reproducibility Training initiative](https://docs.google.com/document/d/1STVrPjk0djjavBIYIderU2rvD0lPXuHodey4O5KK6qU/edit#heading=h.y2o8qp1gtdb1) - The Code Reproducibility Training initiative which is part of the ELIXIR-CONVERGE WP2 project, aims to create training materials to learn how to develop sustainable and reproducible code. +* [I-X Centre for AI in Science](https://ix.imperial.ac.uk/research-centre/aiscience/) - Imperial’s I-X Centre for AI in Science. I-X is Imperial’s flagship AI initiative bringing AI together with interdisciplinarity and grand challenges. Our centre is dedicated to using AI to disrupt and advance Science, Engineering and Mathematics and is underpinned by core support from Schmidt Futures. + + +### Events + +* [R course for Digital Humanities](https://n8cir.org.uk/events/r-digital-humanities/) - 2022-11-29 and 2022-1-06, Online. Following a similar format to the 2021 workshop, the course is a gentle introduction to R for text analysis. Over the course of two sessions you will be taught the basics of the powerful programming language before being provided with hands-on experience analysing long-form text in the RStudio development environment. +* [Computing Insight UK 2022](https://www.scd.stfc.ac.uk/Pages/CIUK2022.aspx) - 2022-12-01 to 2022-12-02, Manchester Central Convention Complex. The theme for the conference this year is "Sustainable HPC" with sub-themes including "Sustainable Skills", "Sustainable Funding" and "Net Zero Computing". +* [PyData Global 2022](https://pdg22.wpengine.com) - 2022-12-01 to 2022-12-03, Online. The PyData Global conference is an opportunity to listen, learn, and share knowledge about best practices, new approaches, and emerging technologies for data management, processing, analytics, and visualization. +* [Free ARCHER2 course at Newcastle University covering Docker and Singularity](https://www.archer2.ac.uk/training/courses/221207-containers/) - 2022-12-07 to 2022-12-08, Newcastle University. This course is a run of the Docker and Singularity lessons in the Carpentries Incubator. +* [University of Sheffield Inaugural Annual Open Research Lecture](https://www.eventbrite.co.uk/e/university-of-sheffield-inaugural-annual-open-research-lecture-tickets-440984976937) - 2022-12-09, The Diamond, Lecture Theatre 5. Lecture given by Dr Tom Stafford titled 'Wide Open?'. Dr Tom Stafford will review concerns about Open Research practices: that they are unnecessary, performative, exclusive, neocolonial, a distracting example of data positivism, undermine scholarly societies, slow down research, generate confidentiality risks, amongst others. + +* [Lab Notebooks for Computational Mathematics, Sciences & Engineering Wednesday](http://ideas-productivity.org/events/hpc-best-practices-webinars/) - 2022-12-14, Online. The HPC Best Practices webinars address issues faced by developers of computational science and engineering (CSE) software on high-performance computers (HPC). + +* [UK National Open Hackathon 2023](https://www.openhackathons.org/s/siteevent/a0C5e000005V6EDEA0/se000151) - Application Deadline 2023-01-16, Online. Open Hackathons are multi-day intensive hands-on events designed to help computational scientists and researchers port and optimize their applications using GPUs. + +* [Intermediate Software Development Skills for Earth and Environmental Scientists: Reproducible Research through Reusable, Reliable Code in Python](https://www.qualtrics.manchester.ac.uk/jfe/form/SV_87F94dIoT1aRwto) - 2023-03-27 to 2023-03-31, University of Manchester. Fancy improving your research techniques within the Earth, atmospheric and oceanic sciences? For any questions about the course and application, please contact Anja Le Blanc via e-mail at anja.leblanc@manchester.ac.uk. + + + +### Training + +#### Research IT Training + +Research IT is providing a place for beginners or advanced users to expand their knowledge of HPC and different programming languages. The courses are part of the Doctoral Development Programme. For more information please visit our training registration web page (via VPN): [crs.shef.ac.uk](https://crs.shef.ac.uk). + +#### Bioinformatics Training + +* [Introduction to RNA-seq analysis in R](https://sbc.shef.ac.uk/training/rna-seq-in-r-2022-12-12/) - Monday 12th December 13:00 - 16:00, Wednesday 14th December 13:00 - 16:00, Friday 16th December 13:00 - 16:00 + +#### RSE Team: Introduction to Deep Learning Course with Tensorflow Keras (in Python) + +A one-day introduction to deep learning with practical labs using Tensorflow in Python: + +* [18 January 2023](https://rse.shef.ac.uk/training/workshop/2023-01-18-deep-learning-with-tensorflow-in-python) + +If a course is "sold out" please join the wait list - we regularly email people to encourage those that can no longer attend to cancel. + +#### RSE Team: Git & GitHub through GitKraken workshop - from Zero to Hero! + +This is an introductory course, teaching the git and GitHub skills required to manage research code over it’s development lifecycle. These skills are essential for collaborative research teams. + +**Please keep an eye out for new dates being released shortly via our mailing list!** + +If a course is "sold out" please join the wait list - we regularly email people to encourage those that can no longer attend to cancel. + + +### Opportunities + +#### Funding + +* [Digital Infrastructure Incubator](https://www.codeforsociety.org/incubator/accepting-proposals) Deadline 2022-12-02. Code for Science & Society (CS&S) solicits expressions of interest from open source digital infrastructure teams to participate in the second cohort of the Digital Infrastructure Incubator (DII). +* [CHIST-ERA Open & Re-usable Research Data & Software](https://www.chistera.eu/call-ord-announcement). Deadline 2022-12-14. This call tackles the challenge of open research data and software from the perspective of their possible reuse. The objective is to create the conditions for research in any domain based on open or shared data and software. +* [Wellcome PhD studentships](https://pheds-dtc.ac.uk/). Deadline 2022-12-16. Training the next generation of researchers in high-quality research of complex multi-component public health interventions and policies to reduce non-communicable or chronic diseases. +* [PhD at University of Bristol: Open spectroscopy in Environmental Sciences: Machine-learningaugmented analysis and interpretation ](https://www.bristol.ac.uk/media-library/sites/earthsciences/documents/phd-projects/2023-start/Byrne_UOB_2023_Studentships.pdf) - Deadline 2023-01-23. PhD that is associated with the Bristol RSE group. The project title is “Open spectroscopy in Environmental Sciences: Machine-learning- augmented analysis and interpretation”. The aim is to help develop machine learning models and software that can aid in the interpretation of spectra. Analysis of this data seeks to address specific environmental questions, such as how soil bacteria are connected to the release of greenhouse gases, or how changes in geochemistry influences the release of pollutants into drinking water. +* [Artificial intelligence hubs for real data and for scientific and engineering research](https://www.ukri.org/opportunity/artificial-intelligence-hubs-for-real-data-and-for-scientific-and-engineering-research/) - Deadline 2023-02-09. Apply for funding for a research hub in either artificial intelligence (AI) for real data or AI for scientific and engineering research. +* [Mathematical and computational foundations of artificial intelligence](https://www.ukri.org/opportunity/mathematical-and-computational-foundations-of-artificial-intelligence/) - Deadline 2023-02-09. Apply for funding to advance the fundamental mathematical, statistical, and computational concepts that underpin artificial intelligence (AI). +* [Get up to 12 days of software engineering support for your HPC/ML/GPU project](https://rse.shef.ac.uk/collaboration/tier2/). Deadline N/A. The Research Software Engineering team is offering to support researchers with the use of High Performance Computing (HPC), Machine Learning (ML) and Graphics Processors (GPUs) in their research projects. All researchers at our University can receive up to £5,000 of support time, or roughly 12 days of support, provided by a Research Software Engineer (RSE). This call aims to increase the uptake of the University's Tier 2 HPC resources, which are national facilities available to researchers in all faculties. This is an open call and applications are considered on a first-come-first-served basis. There is no current deadline and applications will be reviewed on an ongoing basis. +* [Oracle for Research Project Awards](https://www.oracle.com/research/project-awards/) - Deadline N/A. Oracle Research (this years sponsors of the RSE conference) have an open grants program to sponsor research projects with free cloud credits to tackle computational challenges. The majority of cloud providers no longer offer free credits however Oracle grants include access to a variety of Oracle Cloud technologies including compute, GPUs, and HPC. In addition to cloud credits, they also provide researchers and supporting RSEs with technical cloud support to transition and optimize their workflows on an Oracle Cloud environment. If interested then apply directly. + + + +### LunchBytes + +[LunchBytes](https://rse.shef.ac.uk/community/lunch-bytes/) are a monthly series of short talks from the research community on research software, data, and infrastructure. + + +#### LunchBytes needs YOU! + +LunchBytes are organised by and for the research software community at The University of Sheffield. If you'd like to curate a session on a topic or present something, get in touch by emailing [lunchbytes-organisers-group@sheffield.ac.uk](mailto:lunchbytes-organisers-group@sheffield.ac.uk) - Or suggest topics [on the jamboard](https://jamboard.google.com/d/1-51cRf0pwZl8O10CnLeJGAqKcnbww-QGaYjszFK-H38/). + +### Support + +#### Code Clinics + +Why not come to a [Code Clinic](https://docs.google.com/forms/d/e/1FAIpQLScGXS55qjU0D0Zcz-KHOVcNTahcr3YC3H0OpoKBo3lWXWED5A/viewform)? We're keen to hear from you. + +Code Clinics are fortnightly supported sessions run by the RSE team and IT Services’ [Research and Innovation IT](https://www.sheffield.ac.uk/it-services/research) (ITS R&I) team. They are open to anyone at TUoS writing code for research to get help with programming problems and general advice on best practices. + +At each session, members of the RSE and/or ITS R&I teams will be available to review code, advise, troubleshoot, and suggest ways to improve your computational workflows. + +#### Research IT HPC Drop In + +HPC Drop-In sessions are providing assistance with HPC related user issues such as challenges in scaling an application from desktop to supercomputer. We are considering extending the number of our sessions to two or three weekly. These interactive sessions could provide a better interface with our users than our non-interactive ticketing system. These sessions are advertised on the [HPC mailing list](https://groups.google.com/u/1/a/sheffield.ac.uk/g/hpc). + +#### Research IT Consultations + +Alongside the HPC Drop-In sessions, Research IT are also running one to one consultations to solve in depth user specific problems. These consultations can be booked via our webpage. If you are interested please visit the following link: . + +## Sheffield RSE Team + +The Sheffield RSE Team aims to [collaborate](https://rse.shef.ac.uk/collaboration/guide/) with you to help improve your research software. + +They can provide dedicated staff to ensure that you can deliver excellent research software engineering on your research projects. + +The Sheffield RSE Team provides free [Code Clinics][CCs] (in collaboration with [IT Services][its-res-it]), plus [paid services][rse-service] that allow us to collaborate longer term. + +## Research IT + +The Research and Innovation Team within IT directly supports research, both academic and commercial. +We provide large scale HPC systems, advice on everything from statistics to ML to data pipelines and training for both students and staff. +Working with academics, our staff are embedded within research groups on both long and short term engagements. + +[CCs]: https://rse.shef.ac.uk/support/code-clinic/ +[its-res-it]: https://www.sheffield.ac.uk/it-services/research/ +[rse-service]: https://rse.shef.ac.uk/collaboration/ diff --git a/_newsletters/2023-01-25-newsletter.md b/_newsletters/2023-01-25-newsletter.md new file mode 100644 index 00000000..7a0b91e2 --- /dev/null +++ b/_newsletters/2023-01-25-newsletter.md @@ -0,0 +1,110 @@ +--- +layout: post +title: January 2023 Newsletter +editor: Bob Turner +slug: 2023-01-25-newsletter +date: 2023-01-25T00:00:00Z+0100 +tags: +category: +link: +description: +type: text +--- +## The University of Sheffield Research Software Engineering Community Newsletter January 2023 + +Welcome to this month's newsletter for the research software community at The University of Sheffield, featuring news, opportunities, events and training for you. + +### News, Web & Blogs + +#### Web and Publications + +* From the RSE Team blog [Who's to Blame?](https://rse.shef.ac.uk/blog/git-blame/) - Neil writes about using this unfortunately titled feature of `git` to better understand the history of code in a project. +* A new book with Sheffield-based co-authors "[Live Coding: A User's Manual](https://livecodingbook.toplap.org/)" Performative, improvised, on the fly: live coding is about how people interact with the world and each other via code. In the last few decades, live coding has emerged as a dynamic creative practice, gaining attention across cultural and technical fields—from music and the visual arts to computer science. +* [Announcing the 2023 Software Sustainability Institute Fellows](https://software.ac.uk/blog/2022-12-15-announcing-2023-software-sustainability-institute-fellows) - Read this blog post from the Software Sustainability Institute to find out more about the fellowships they have awarded. +* A comprehensive [Online Rust Course](https://google.github.io/comprehensive-rust/) has been made available by the Android team. +* A really valuable perspective on [convincing academics to use git](https://www.youtube.com/watch?v=KgxKJjzh-Y4) (video) from Juulia Suvilehto at NormConf. More useful and interesting videos from [NormConf 2022](https://normconf.com/) are available see the [main track](https://www.youtube.com/watch?v=C9OlkY87vf8&list=PLYXaKIsOZBsu3h2SSKEovRn7rGy7wkUAV) and [lightning talks](https://www.youtube.com/watch?v=-6sS3wVYpM8&list=PLYXaKIsOZBstGUTXZXp2azDk8UJhpVVq3). +* [Invest 5% of research funds in ensuring data are reusable](https://www.nature.com/articles/d41586-020-00505-7) It is irresponsible to support research but not data stewardship, says Barend Mons. +* MathWorks have added a new MATLAB training course to the catalogue of courses available to everyone at University of Sheffield. If you already know the basics of MATLAB programming, the Object-Oriented Programming OnRamp [Object-Oriented Programming Onramp - Self-Paced Online Courses - MATLAB & Simulink](https://matlabacademy.mathworks.com/details/object-oriented-programming-onramp/oroop) (mathworks.com) should take you around 2 hours to complete and will lead to a certificate that you can add to online profiles such as LinkedIn. +* [UKRI is looking for 3 people to join their infrastructure advisory committee](https://www.ukri.org/about-us/work-for-us/join-an-advisory-committee-panel-or-network/ukri-infrastructure-advisory-committee/) - Closing date 12 February 2023 + +### Events + +* [Open Research Conversations](https://www.eventbrite.com/cc/open-research-conversations-springsummer-2023-1345889) The University Library is holding a series of Open Research Conversations throughout the spring semester. These are lunchtime online seminars featuring talks from 2-3 speakers followed by discussion. _Lots of interesting stuff here!_ +* [Love Data Week 2023: Exploring Dryad (webinar)](https://www.eventbrite.co.uk/e/love-data-week-2023-exploring-dryad-webinar-tickets-517737054467) - 17th Feb 2023 - ... explore how University of Sheffield researchers can get the most out of our membership of Dryad. +* [Introduction to Synthetic Data for Researchers](https://n8cir.org.uk/events/introduction-synthetic-data-researchers/) - 21st Feb 2023 - N8CIR event: This interactive workshop has two parts, the first of which introduces the basic concepts of synthetic data, shows examples, and explores why researchers need to be aware of what synthetic data is. +* [The Call for Proposals for DjangoCon Europe 2023 Is Now Open!](https://2023.djangocon.eu/news/announcing-call-for-proposals/) - closes 26th Febuary 2023 +* [Python GPU Programming Workshop](https://n8cir.org.uk/events/python-gpu-programming-workshop/) - 18th Feb and 28th April 2023 - N8CIR event: Want to learn more about how to write code in Python that can take advantage of graphical processing units (GPUs)? Sign up for this two-part course introducing GPU programming through Python. +* [ShinyConf 2023](https://shinyconf.appsilon.com/) - 15-17th March, 2023, all-virtual. +* [Intermediate Software Development Skills for Earth and Environmental Scientists: Reproducible Research through Reusable, Reliable Code in Python](https://www.qualtrics.manchester.ac.uk/jfe/form/SV_87F94dIoT1aRwto) - 27th-31st March 2023, University of Manchester. Fancy improving your research techniques within the Earth, atmospheric and oceanic sciences? For any questions about the course and application, please contact Anja Le Blanc via e-mail at anja.leblanc@manchester.ac.uk. +* [Symposium: Perspectives on teaching reproducibility](https://shefmethods.qualtrics.com/jfe/form/SV_3yBUDlfuDoeNuM6) - 20th June 2023, Sheffield, UK - Reproducibility has gained a lot of attention in research and many disciplines have adopted policies recognizing the value of open scholarship. The teaching of reproducible methods has received somewhat less attention, but is no less important. Some excellent examples are documented in the November 2022 issue of Journal of Statistics and Data Science Education, where a number of instructors reflect on "Teaching reproducibility and responsible workflow" and how to embed reproducible workflows, data management and transparent reporting in courses and programmes. +* [Centre for Open Science 2023 Unconference on Open Scholarship Practices in Education Research](https://www.cos.io/unconference) - 9th to 10th March 2023 - The 2023 Unconference will be a virtual participation event featuring participant-led sessions analyzing the current state of open scholarship practice seeking solutions to identified problems. Participants will assess barriers to adoption of open scholarship practices unique to the education community and brainstorm strategies for promoting greater awareness. + + +### Training + +#### Research IT Training + +Research IT is providing a place for beginners or advanced users to expand their knowledge of HPC and different programming languages. The courses are part of the Doctoral Development Programme. For more information please visit our training registration web page (via VPN): [crs.shef.ac.uk](https://crs.shef.ac.uk). + +#### RSE Team: Git & GitHub through GitKraken workshop - from Zero to Hero! + +This is an introductory course, teaching the git and GitHub skills required to manage research code over it’s development lifecycle. These skills are essential for collaborative research teams. + +* [Git & GitHub through GitKraken workshop 2023-03-06 & 2023-03-07](https://rse.shef.ac.uk/training/workshop/2023-03-06-git-zero-hero) + +If a course is "sold out" please join the wait list by signing up - we regularly email people to encourage those that can no longer attend to cancel. Those on the wait list get early notification when the courses are run again. + +### Opportunities + +#### Funding + +* [Artificial intelligence hubs for real data and for scientific and engineering research](https://www.ukri.org/opportunity/artificial-intelligence-hubs-for-real-data-and-for-scientific-and-engineering-research/) - Deadline 9th February 2023. Apply for funding for a research hub in either artificial intelligence (AI) for real data or AI for scientific and engineering research. +* [Artificial intelligence innovation to accelerate health research](https://www.ukri.org/opportunity/artificial-intelligence-innovation-to-accelerate-health-research/) - Closing date: 28th March 2023 - Apply for funding to develop innovative artificial intelligence (AI) technologies to be applied to health challenges. +* [Mathematical and computational foundations of artificial intelligence](https://www.ukri.org/opportunity/mathematical-and-computational-foundations-of-artificial-intelligence/) - Deadline 2023-02-09. Apply for funding to advance the fundamental mathematical, statistical, and computational concepts that underpin artificial intelligence (AI). +* [Get up to 12 days of software engineering support for your HPC/ML/GPU project](https://rse.shef.ac.uk/collaboration/tier2/). Deadline N/A. The Research Software Engineering team is offering to support researchers with the use of High Performance Computing (HPC), Machine Learning (ML) and Graphics Processors (GPUs) in their research projects. All researchers at our University can receive up to £5,000 of support time, or roughly 12 days of support, provided by a Research Software Engineer (RSE). This call aims to increase the uptake of the University's Tier 2 HPC resources, which are national facilities available to researchers in all faculties. This is an open call and applications are considered on a first-come-first-served basis. There is no current deadline and applications will be reviewed on an ongoing basis. + + + +### LunchBytes + +[LunchBytes](https://rse.shef.ac.uk/community/lunch-bytes/) are a monthly series of short talks from the research community on research software, data, and infrastructure. + +#### LunchBytes needs YOU! + +LunchBytes are organised by and for the research software community at The University of Sheffield. If you'd like to curate a session on a topic or present something, get in touch by emailing [lunchbytes-organisers-group@sheffield.ac.uk](mailto:lunchbytes-organisers-group@sheffield.ac.uk) - Or suggest topics [on the jamboard](https://jamboard.google.com/d/1-51cRf0pwZl8O10CnLeJGAqKcnbww-QGaYjszFK-H38/). + +### Support + +#### Code Clinics + +Why not come to a [Code Clinic](https://docs.google.com/forms/d/e/1FAIpQLScGXS55qjU0D0Zcz-KHOVcNTahcr3YC3H0OpoKBo3lWXWED5A/viewform)? We're keen to hear from you. + +Code Clinics are fortnightly supported sessions run by the RSE team and IT Services’ [Research IT](https://www.sheffield.ac.uk/it-services/research) team. They are open to anyone at TUoS writing code for research to get help with programming problems and general advice on best practices. + +At each session, members of the RSE and/or Research IT teams will be available to review code, advise, troubleshoot, and suggest ways to improve your computational workflows. + +#### Research IT HPC Drop In + +HPC Drop-In sessions are providing assistance with HPC related user issues such as challenges in scaling an application from desktop to supercomputer. We are considering extending the number of our sessions to two or three weekly. These interactive sessions could provide a better interface with our users than our non-interactive ticketing system. These sessions are advertised on the [HPC mailing list](https://groups.google.com/u/1/a/sheffield.ac.uk/g/hpc). + +#### Research IT Consultations + +Alongside the HPC Drop-In sessions, Research IT are also running one to one consultations to solve in depth user specific problems. These consultations can be booked via our webpage. If you are interested please visit the following link: . + +## Sheffield RSE Team + +The Sheffield RSE Team aims to [collaborate](https://rse.shef.ac.uk/collaboration/guide/) with you to help improve your research software. + +They can provide dedicated staff to ensure that you can deliver excellent research software engineering on your research projects. + +The Sheffield RSE Team provides free [Code Clinics][CCs] (in collaboration with [IT Services][its-res-it]), plus [paid services][rse-service] that allow us to collaborate longer term. + +## Research IT + +[Research IT](https://students.sheffield.ac.uk/it-services/research) directly supports research, both academic and commercial. +We provide large scale HPC systems, advice on everything from statistics to ML to data pipelines and training for both students and staff. +Working with academics, our staff are embedded within research groups on both long and short term engagements. + +[CCs]: https://rse.shef.ac.uk/support/code-clinic/ +[its-res-it]: https://www.sheffield.ac.uk/it-services/research/ +[rse-service]: https://rse.shef.ac.uk/collaboration/ diff --git a/_newsletters/2023-02-24-newsletter.md b/_newsletters/2023-02-24-newsletter.md new file mode 100644 index 00000000..cccc94a0 --- /dev/null +++ b/_newsletters/2023-02-24-newsletter.md @@ -0,0 +1,119 @@ +--- +layout: post +title: February 2023 Newsletter +editor: Edwin Brown +slug: 2023-02-24-newsletter +date: 2023-02-24T00:00:00Z+0100 +tags: +category: +link: +description: +type: text +--- +## The University of Sheffield Research Software Engineering Community Newsletter February 2023 + +Welcome to this month's newsletter for the research software community at The University of Sheffield, featuring news, opportunities, events and training for you. + +### News, Web & Blogs + +#### Web and Publications + +* [Applications open for the University of Sheffield’s Open Research Prize 2023](https://www.sheffield.ac.uk/library/research/open-research-prize-2023) - Deadline is 31st May. We want to recognise and celebrate the excellent work University of Sheffield researchers are doing to make their research discoverable and reusable by a wider audience. _Prizes up for grabs!_ +* [RSECon22 Q&A Extra Time - Society of Research Software Engineering](https://society-rse.org/rsecon22-qa-extra-time/) - At RSECon22 last year there were a number of talks where there were additional questions that we didn't have time for during the speaker slots. We're very pleased that some speakers have taken the time to do a more extended Q&A with these additional questions and have written it up on the blog. +* [Apply for the current round of Carpentries Maintainer Onboarding!](https://carpentries.org/blog/2023/02/Apply-for-the-current-round-of-Carpentries-Maintainer-Onboarding/) - Applications due 1st March. - The Carpentries is preparing to onboard the next cohort of Maintainers. Currently we have 109 Maintainers serving across 56 core lessons. To keep the community healthy, we need to plan for offboarding people who want to step down from their current positions and finding new people to step into the role. +* [Official MathWorks MATLAB kernel for Jupyter released](https://blogs.mathworks.com/matlab/2023/01/30/official-mathworks-matlab-kernel-for-jupyter-released/) +* [Launching Data Carpentry: Image Processing with Python](https://carpentries.org/blog/2023/01/dc-image-processing-stable-release/) - Announcing the stable release of a new curriculum teaching image processing skills. Sign up to host a workshop today! +* [Tutorials on Citation File Format](https://www.youtube.com/watch?v=zcgLIT5Qd4M) - In this tutorial, the [cffinit v2.2.0 tool](https://citation-file-format.github.io/cff-initializer-javascript/#/) is used to create a CITATION.cff file. +* [Pull request merge queue](https://github.blog/changelog/2023-02-08-pull-request-merge-queue-public-beta/) - Announcing the public beta of pull request merge queue for repos on GitHub Enterprise Cloud and open source organizations! Merge queue helps increase velocity in software delivery by automating pull request merges into your busiest branches. +* [Avoiding the success trap: Toward policy for open-source software as infrastructure](https://www.atlanticcouncil.org/in-depth-research-reports/report/open-source-software-as-infrastructure/) - This report compares open-source software (OSS) to three infrastructure systems—water management systems, capital markets, and networks of roads and bridges—and draws on existing policy vehicles from each to suggest policy that supports the sustainability and security of OSS as a communally beneficial resource. +* [What Is ChatGPT Doing … and Why Does It Work?](https://writings.stephenwolfram.com/2023/02/what-is-chatgpt-doing-and-why-does-it-work/) - Excellent blog detailing how ChatGPT works in simple, readable terms. +* [Data access and the Online Safety Bill](https://www.theodi.org/article/data-access-and-the-online-safety-bill/) - The Online Safety Bill, which the government says delivers its ‘manifesto commitment to make the UK the safest place in the world to be online while defending free expression’, is back in Parliament after some revision and delay. Having made it through the House of Commons, it is now at Committee Stage in the House of Lords, where peers will examine the Bill line by line. +* [Advancing Software Citation Implementation (Software Citation Workshop 2022)](https://arxiv.org/abs/2302.07500) - Software is foundationally important to scientific and social progress, however, traditional acknowledgment of the use of others' work has not adapted in step with the rapid development and use of software in research. +This report outlines a series of collaborative discussions that brought together an international group of stakeholders and experts representing many communities, forms of labor, and expertise. +* [Could There Be Some Viable Challengers to Google Scholar on the Horizon?](https://absolutelymaybe.plos.org/2023/02/16/could-there-be-some-viable-challengers-to-google-scholar-on-the-horizon/) +* [Want early access to our new 'Stanage' HPC system? ](https://twitter.com/RIT_Sheffield/status/1628370968157605888) - Stanage is the University’s newest HPC system. It is well suited to a variety of research workloads, including large jobs or jobs requiring GPUs. It is intended to be the logical successor to the ShARC HPC system, but is much larger. Get in touch for early access! + + +### Events + +* [The Call for Proposals for DjangoCon Europe 2023 Is Now Open!](https://2023.djangocon.eu/news/announcing-call-for-proposals/) - Closes 26th Febuary 2023 +* [The UK’s national showcase of data science and artificial intelligence (AI)](https://ai-uk.turing.ac.uk/) - 21st and 22nd March - Hosted by The Alan Turing Institute, AI UK 2023 will be an in-depth exploration of how data science and AI can be used to solve real-world challenges. +* [Open Research Conversations](https://www.eventbrite.com/cc/open-research-conversations-springsummer-2023-1345889) Next seminar is 8th March. The University Library is holding a series of Open Research Conversations throughout the spring semester. These are lunchtime online seminars featuring talks from 2-3 speakers followed by discussion. _Lots of interesting stuff here!_ +* [Digifest 2023](https://www.jisc.ac.uk/events/digifest-2023/about) - 7th to 8th March - Join us - in person or online - to immerse yourself in the latest innovation in learning, teaching and assessment, leadership and culture, and research. We are still finalising our programme and will be adding more sessions in the coming weeks. +* [Python GPU Programming Workshop](https://n8cir.org.uk/events/python-gpu-programming-workshop/) - 9th March and 28th April 2023 - N8CIR event: Want to learn more about how to write code in Python that can take advantage of graphical processing units (GPUs)? Sign up for this two-part course introducing GPU programming through Python. +* [Centre for Open Science 2023 Unconference on Open Scholarship Practices in Education Research](https://www.cos.io/unconference) - 9th to 10th March 2023 - The 2023 Unconference will be a virtual participation event featuring participant-led sessions analyzing the current state of open scholarship practice seeking solutions to identified problems. Participants will assess barriers to adoption of open scholarship practices unique to the education community and brainstorm strategies for promoting greater awareness. +* [ShinyConf 2023](https://shinyconf.appsilon.com/) - 15-17th March, 2023, all-virtual. +* [Intermediate Software Development Skills for Earth and Environmental Scientists: Reproducible Research through Reusable, Reliable Code in Python](https://www.qualtrics.manchester.ac.uk/jfe/form/SV_87F94dIoT1aRwto) - 27th-31st March 2023, University of Manchester. Fancy improving your research techniques within the Earth, atmospheric and oceanic sciences? For any questions about the course and application, please contact Anja Le Blanc via e-mail at anja.leblanc@manchester.ac.uk. +* [Reproducibility in Bioinformatics](https://www.physalia-courses.org/courses-workshops/bioinformatics-reproducibility/) - 3rd to 5th April. - This course aims at increasing awareness and introduces strategies on how to improve reproducibility in bioinformatic analyses. Through a mixture of theoretical blocks and hands-on exercises the instructors will guide participants to develop skills to increase reproducibility of bioinformatic analyses and workflows using containers, versioning and virtual environments. +* [Symposium: Perspectives on teaching reproducibility](https://shefmethods.qualtrics.com/jfe/form/SV_3yBUDlfuDoeNuM6) - 20th June 2023, Sheffield, UK - Reproducibility has gained a lot of attention in research and many disciplines have adopted policies recognizing the value of open scholarship. The teaching of reproducible methods has received somewhat less attention, but is no less important. Some excellent examples are documented in the November 2022 issue of Journal of Statistics and Data Science Education, where a number of instructors reflect on "Teaching reproducibility and responsible workflow" and how to embed reproducible workflows, data management and transparent reporting in courses and programmes. + + +### Training + +#### Research IT Training + +Research IT courses will be adopting a hybrid approach from March. The team will be providing their courses both online and in person for the first time since March 2020. The team provides a place for beginners or advanced users to expand their knowledge of HPC and different programming languages. The courses are part of the Doctoral Development Programme. For more information please visit our training registration web page (via VPN): [crs.shef.ac.uk](https://crs.shef.ac.uk). + + +#### RSE Team: Git & GitHub through GitKraken workshop - from Zero to Hero! + +This is an introductory course, teaching the git and GitHub skills required to manage research code over it’s development lifecycle. These skills are essential for collaborative research teams. +* [Introduction to Conda for (Data) Scientists 2023-03-03](https://rse.shef.ac.uk/training/workshop/2023-03-03-intro-to-conda) +* [Git & GitHub through GitKraken workshop 2023-03-06 & 2023-03-07](https://rse.shef.ac.uk/training/workshop/2023-03-06-git-zero-hero) + +If a course is "sold out" please join the wait list by signing up - we regularly email people to encourage those that can no longer attend to cancel. Those on the wait list get early notification when the courses are run again. + +### Opportunities + +#### Funding + +* [Artificial intelligence innovation to accelerate health research](https://www.ukri.org/opportunity/artificial-intelligence-innovation-to-accelerate-health-research/) - Closing date: 28th March 2023 - Apply for funding to develop innovative artificial intelligence (AI) technologies to be applied to health challenges. +* [Future Leaders Fellowships: round 8 +](https://www.ukri.org/opportunity/future-leaders-fellowships-round-8/) - Closing date: 4th July 2023 - Apply for funding to support ambitious research or innovation across UK Research and Innovation’s (UKRI) remit. +* [Get up to 12 days of software engineering support for your HPC/ML/GPU project](https://rse.shef.ac.uk/collaboration/tier2/). Deadline N/A. The Research Software Engineering team is offering to support researchers with the use of High Performance Computing (HPC), Machine Learning (ML) and Graphics Processors (GPUs) in their research projects. All researchers at our University can receive up to £5,000 of support time, or roughly 12 days of support, provided by a Research Software Engineer (RSE). This call aims to increase the uptake of the University's Tier 2 HPC resources, which are national facilities available to researchers in all faculties. This is an open call and applications are considered on a first-come-first-served basis. There is no current deadline and applications will be reviewed on an ongoing basis. + + + +### LunchBytes + +[LunchBytes](https://rse.shef.ac.uk/community/lunch-bytes/) are a monthly series of short talks from the research community on research software, data, and infrastructure. + +#### LunchBytes needs YOU! + +LunchBytes are organised by and for the research software community at The University of Sheffield. If you'd like to curate a session on a topic or present something, get in touch by emailing [lunchbytes-organisers-group@sheffield.ac.uk](mailto:lunchbytes-organisers-group@sheffield.ac.uk) - Or suggest topics [on the jamboard](https://jamboard.google.com/d/1-51cRf0pwZl8O10CnLeJGAqKcnbww-QGaYjszFK-H38/). + +### Support + +#### Code Clinics + +Why not come to a [Code Clinic](https://docs.google.com/forms/d/e/1FAIpQLScGXS55qjU0D0Zcz-KHOVcNTahcr3YC3H0OpoKBo3lWXWED5A/viewform)? We're keen to hear from you. + +Code Clinics are fortnightly supported sessions run by the RSE team and IT Services’ [Research IT](https://www.sheffield.ac.uk/it-services/research) team. They are open to anyone at TUoS writing code for research to get help with programming problems and general advice on best practices. + +At each session, members of the RSE and/or Research IT teams will be available to review code, advise, troubleshoot, and suggest ways to improve your computational workflows. + +#### Research IT HPC Drop In + +HPC Drop-In sessions are providing assistance with HPC related user issues such as challenges in scaling an application from desktop to supercomputer. We are considering extending the number of our sessions to two or three weekly. These interactive sessions could provide a better interface with our users than our non-interactive ticketing system. These sessions are advertised on the [HPC mailing list](https://groups.google.com/u/1/a/sheffield.ac.uk/g/hpc). + +#### Research IT Consultations + +Alongside the HPC Drop-In sessions, Research IT are also running one to one consultations to solve in depth user specific problems. These consultations can be booked via our webpage. If you are interested please visit the following link: . + +## Sheffield RSE Team + +The Sheffield RSE Team aims to [collaborate](https://rse.shef.ac.uk/collaboration/guide/) with you to help improve your research software. + +They can provide dedicated staff to ensure that you can deliver excellent research software engineering on your research projects. + +The Sheffield RSE Team provides free [Code Clinics][CCs] (in collaboration with [IT Services][its-res-it]), plus [paid services][rse-service] that allow us to collaborate longer term. + +## Research IT + +[Research IT](https://students.sheffield.ac.uk/it-services/research) directly supports research, both academic and commercial. +We provide large scale HPC systems, advice on everything from statistics to ML to data pipelines and training for both students and staff. +Working with academics, our staff are embedded within research groups on both long and short term engagements. + +[CCs]: https://rse.shef.ac.uk/support/code-clinic/ +[its-res-it]: https://www.sheffield.ac.uk/it-services/research/ +[rse-service]: https://rse.shef.ac.uk/collaboration/ diff --git a/_newsletters/2023-03-30-newletter.md b/_newsletters/2023-03-30-newletter.md new file mode 100644 index 00000000..5b3478be --- /dev/null +++ b/_newsletters/2023-03-30-newletter.md @@ -0,0 +1,162 @@ +--- +layout: post +title: March 2023 Newsletter +editor: Neil +slug: 2023-03-30-newsletter +date: 2023-03-30T00:00:00Z+0100 +tags: +category: +link: +description: +type: text +--- +## The University of Sheffield Research Software Engineering Community Newsletter March 2023 + +Welcome to this month's newsletter for the research software community at The University of Sheffield, featuring news, opportunities, events and training for you. + +### News, Web & Blogs + +#### Web and Publications + ++ [Intro to MLOps: Data and Model + Versioning](https://wandb.ai/iamleonie/Intro-to-MLOps/reports/Intro-to-MLOps-Data-and-Model-Versioning--VmlldzozMzU2NzQw) - + this article will give you a quick refresher on version control in general and explain how it's used in Machine Learning. ++ [Evaluating research software + proposals](https://danielskatzblog.wordpress.com/2023/02/27/evaluating-research-software-proposals/) – Daniel S. Katz + proposes a set of aspects that funders might choose to collectively address research software funding. ++ [What should you use ChatGPT for?](https://vickiboykis.com/2023/02/26/what-should-you-use-chatgpt-for/) - Vicki Boykis + takes a considered approach to the utility of ChatGPT. ++ [Better incentives are needed to reward academic software + development](https://www.nature.com/articles/s41559-023-02008-w) - article in Nature Ecology & Evolution on the incentives + required in academic software development. ++ [Independent Review of The Future of Compute: Final report and recommendations - + GOV.UK](https://www.gov.uk/government/publications/future-of-compute-review/the-future-of-compute-report-of-the-review-of-independent-panel-of-experts) - + UK Government Department for Science, Innovation & Technology report. ++ [Unleash your potential with GitHub Octernships: a path to a thriving tech + career](https://github.blog/2023-03-06-unleash-your-potential-with-github-octernships-a-path-to-a-thriving-tech-career/) - + get paid to work on real-world projects whilst studying as part of GitHub's newly launched Octernships program. ++ [Guidelines for a healthy code review culture + MediaWiki](https://www.mediawiki.org/wiki/Guidelines_for_a_healthy_code_review_culture) - useful advice for developing + a code review culture in which feedback is welcomed without fear from [Mediawiki](https://www.mediawiki.org/). ++ [Why we need Research Software Engineers for Reproducible + Research](https://heidiseibold.ck.page/posts/why-we-need-research-software-engineers-for-reproducible-research) - Dr + Heidi Seibold on the utility of Research Software Engineers. ++ [PyTorch 2.0](https://pytorch.org/blog/pytorch-2.0-release/) - the next iteration of the popular open-source machine + learning framework is "_faster, more Pythonic and Dynamic as ever_". ++ [Indicators of Open Research - Call for Priorities](https://osf.io/jgb6q) - UK Reproducibility Network is looking for + your input on metrics for monitoring indicators of open research so have your say ([direct link to + survey](https://forms.office.com/pages/responsepage.aspx?id=MH_ksn3NTkql2rGM8aQVG83drixFredPnFQN6NWRAQ5UNjU1STFYMlNGVFJCWEMzWEs0V1ZVTzNQUyQlQCN0PWcu)). ++ [Research Software Engineers: Career Entry Points and Training Gaps](https://ieeexplore.ieee.org/document/10075674) - + for those considering or already working in Research Software Engineering this is well worth reading. ++ [Try Dark Mode on Desktop MATLAB with the ‘New Desktop for MATLAB’ + beta](https://blogs.mathworks.com/matlab/2023/03/17/try-dark-mode-on-desktop-matlab-with-the-new-desktop-for-matlab/) - + Dark Mode is on its way to MATLAB. + + +### Events + ++ [SYCL practitioners + hackathon](https://scicomp.webspace.durham.ac.uk/events/code_performance_series/sycl-practitioners-hackathon-2022-user-group-meeting/) - + Cambridge 17th April 2023. ++ [Stanage HPC launch Tickets](https://www.eventbrite.co.uk/e/stanage-hpc-launch-tickets-566515461997) - Firth Hall, + Firth Court, Western Bank, Sheffield 14:30-18:30 19th April 2023. ++ [Performance Analysis Workshop Series + 2023](https://tobiasweinzierl.webspace.durham.ac.uk/research/workshops/performance-analysis-workshop-series-2023/) + Durham University, Department of Computer Science, Durham, UK, and online 20th April - 18th May 2023. ++ [RSE Midlands 2023 Annual Conference](https://rse-midlands.github.io/docs/event-24th-april-2023/) - hosted by the Digital + Research Service at the University of Nottingham's on Monday 24th April 2023. ++ [Teaching Reproducible Research and Open Science + Conference](https://www.sheffield.ac.uk/smi/events/teaching-reproducible-research-and-open-science-conference) - The + University of Sheffield, 20th-22nd June 2023. ++ [BigDat 2023 Summer – 7th International School of Big Data](https://bigdat.irdta.eu/2023su/) - Las Palmas de Gran + Canaria 17th-21st July 2023. Online participation possible. ++ [RSE Conference 2023](https://rsecon23.society-rse.org/) - the UK Society of Research Software Engineering is holding + its 2023 conference in Swansea 5th-7th September 2023. ++ [OpenFest 2023](https://www.sheffield.ac.uk/library/research/open-research/openfest2023) - OpenFest at The University + of Sheffield returns after the success of 2022's event for a two day event 6th-7th September 2023, including an online + symposium _New Perspectives on Open Research_. ++ [US-RSE'23](https://us-rse.org/usrse23/) - The first US-RSE Conference ever! Chicago, 16th-18th October 2023. + +### Training + ++ [Learning to Code mentorship programme: improve your computational skills for conducting + research](https://www.software.ac.uk/news/join-our-learning-code-mentorship-programme-improve-your-computational-skills-conducting) - + as part of their [Research Software Camp](https://www.software.ac.uk/research-software-camps) the Software + Sustainability Institute is running this mentorship programme from 24th April to 26th June 2023. + +#### Research IT Training + +Research IT courses have adopted a hybrid approach. The team will be providing their courses both online and in person for the first time since March 2020. The team provides a place for beginners or advanced users to expand their knowledge of HPC and different programming languages. The courses are part of the Doctoral Development Programme. For more information please visit our training registration web page (via VPN): [crs.shef.ac.uk](https://crs.shef.ac.uk). + +If a course is "sold out" please join the wait list by signing up - we regularly email people to encourage those that can no longer attend to cancel. Those on the wait list get early notification when the courses are run again. + +#### UNIX Shell Fundamentals + +The Unix shell (which you may know as the terminal, console, or ‘bash’) has been around longer than most of its users have been alive. It has survived because it’s a powerful tool that allows users to perform complex and powerful tasks, often with just a few keystrokes or lines of code. It helps users automate repetitive tasks and easily combine smaller tasks into larger, more powerful workflows. Use of the shell is fundamental to a wide range of advanced computing tasks, including high-performance computing. This lesson will introduce you to this powerful tool. + ++ [Research Software Engineering Sheffield - Unix Shell Fundamentals](https://rse.shef.ac.uk/training/workshop/2023-03-03-unix-shell) + + + +### Opportunities + + + + +#### Jobs + ++ [Head of Research Software Engineering (RSE) at University of + Sheffield](https://www.jobs.ac.uk/job/CYD056/head-of-research-software-engineering-rse) - with the departure of + RSE Sheffield co-founder Paul Richmond we're looking for a new Head of Research Software Engineering. Applications + close 16th April 2023. ++ [Research Software Engineer / Senior Software Engineer for Machine Learning and AI at University of + Sheffield](https://www.jobs.ac.uk/job/CYL522/research-software-engineer-senior-software-engineer-for-machine-learning-and-ai) - + Are you interested in facilitating or leading the development of reproducible software and Artificial Intelligence / + Machine Learning (AI/ML) workflows through collaborations across the whole spectrum of university research areas and + by working on secondment with Alan Turing Institute (ATI)? Then come and work with us! We've two posts available at + Grade 7 or Grade 8 with virtual secondment jointly funded by the [Alan Turing + Institute](https://www.turing.ac.uk/). Applications close 20th April 2023. + +### LunchBytes + +[LunchBytes](https://rse.shef.ac.uk/community/lunch-bytes/) are a monthly series of short talks from the research community on research software, data, and infrastructure. + +#### LunchBytes needs YOU! + +LunchBytes are organised by and for the research software community at The University of Sheffield. If you'd like to curate a session on a topic or present something, get in touch by emailing [lunchbytes-organisers-group@sheffield.ac.uk](mailto:lunchbytes-organisers-group@sheffield.ac.uk) - Or suggest topics [on the jamboard](https://jamboard.google.com/d/1-51cRf0pwZl8O10CnLeJGAqKcnbww-QGaYjszFK-H38/). + +### Support + +#### Code Clinics + +Why not come to a [Code Clinic](https://docs.google.com/forms/d/e/1FAIpQLScGXS55qjU0D0Zcz-KHOVcNTahcr3YC3H0OpoKBo3lWXWED5A/viewform)? We're keen to hear from you. + +Code Clinics are fortnightly supported sessions run by the RSE team and IT Services’ [Research IT](https://www.sheffield.ac.uk/it-services/research) team. They are open to anyone at TUoS writing code for research to get help with programming problems and general advice on best practices. + +At each session, members of the RSE and/or Research IT teams will be available to review code, advise, troubleshoot, and suggest ways to improve your computational workflows. + +#### Research IT HPC Drop In + +HPC Drop-In sessions are providing assistance with HPC related user issues such as challenges in scaling an application from desktop to supercomputer. We are considering extending the number of our sessions to two or three weekly. These interactive sessions could provide a better interface with our users than our non-interactive ticketing system. These sessions are advertised on the [HPC mailing list](https://groups.google.com/u/1/a/sheffield.ac.uk/g/hpc). + +#### Research IT Consultations + +Alongside the HPC Drop-In sessions, Research IT are also running one to one consultations to solve in depth user specific problems. These consultations can be booked via our webpage. If you are interested please visit the following link: . + +## Sheffield RSE Team + +The Sheffield RSE Team aims to [collaborate](https://rse.shef.ac.uk/collaboration/guide/) with you to help improve your research software. + +They can provide dedicated staff to ensure that you can deliver excellent research software engineering on your research projects. + +The Sheffield RSE Team provides free [Code Clinics][CCs] (in collaboration with [IT Services][its-res-it]), plus [paid services][rse-service] that allow us to collaborate longer term. + +## Research IT + +[Research IT](https://students.sheffield.ac.uk/it-services/research) directly supports research, both academic and commercial. +We provide large scale HPC systems, advice on everything from statistics to ML to data pipelines and training for both students and staff. +Working with academics, our staff are embedded within research groups on both long and short term engagements. + +[CCs]: https://rse.shef.ac.uk/support/code-clinic/ +[its-res-it]: https://www.sheffield.ac.uk/it-services/research/ +[rse-service]: https://rse.shef.ac.uk/collaboration/ diff --git a/_newsletters/2023-04-28-newsletter.md b/_newsletters/2023-04-28-newsletter.md new file mode 100644 index 00000000..3ca13c2a --- /dev/null +++ b/_newsletters/2023-04-28-newsletter.md @@ -0,0 +1,123 @@ +--- +layout: post +title: April 2023 Newsletter +editor: Peter Heywood +slug: 2023-04-28-newsletter +date: 2023-04-28T00:18:00Z+0100 +tags: +category: +link: +description: +type: text +--- + +## The University of Sheffield Research Software Engineering Community Newsletter April 2023 + +Welcome to this month's newsletter for the research software community at The University of Sheffield, featuring news, opportunities, events and training for you. + +### News, Web & Blogs + +#### Web and Publications + ++ [Stanage - The University of Sheffield's new HPC cluster is now accessible to all users](https://mailchi.mp/3ffddf67273e/new-hpc-stanage-is-live?e=efb44934e0) ++ [University of Sheffield becomes member of newly-established Turing University Network](https://www.sheffield.ac.uk/news/university-sheffield-becomes-member-newly-established-turing-university-network) ++ [The Research Software Alliance (ReSA)](https://upstream.force11.org/the-research-software-alliance-resa/) ++ [Code4thought: ByteSized RSE: Integrated Development Environments](https://soundcloud.com/code4thought-615691925/en-bytesized-rse-integrated-development-environments) ++ [Code4thought: Funding it all](https://soundcloud.com/code4thought-615691925/en-funding-it-all) ++ [Code4thought: Who are We?](https://soundcloud.com/code4thought-615691925/en-who-are-we) ++ [MathWorks releases MATLAB extension for Visual Studio Code](https://blogs.mathworks.com/matlab/2023/04/26/do-you-use-visual-studio-code-matlab-is-now-there-too/) ++ [Jisc: Association for Computing Machinery agreement "a significant step forward for open access in the UK"](https://www.jisc.ac.uk/news/association-for-computing-machinery-agreement-a-significant-step-forward-for-open-access-in-the-uk-12-apr-2023?utm_campaign=headlines&utm_content=Headlines%2019%2F04%2F2023&utm_medium=email&utm_source=adestra) ++ [Erasmus University Rotterdam: Dilemma Game App](https://www.eur.nl/en/about-eur/policy-and-regulations/integrity/research-integrity/dilemma-game) ++ [arXiv preprint: "Journey to the Center of Software Supply Chain Attacks."](https://arxiv.org/abs/2304.05200) - [Interactive Taxonomy Website](https://sap.github.io/risk-explorer-for-software-supply-chains/) ++ [PsyArXiv preprint: "Using ChatGPT to Fight Misinformation: ChatGPT Nails 72% of 12,000 Verified Claims"](https://psyarxiv.com/qnjkf/) ++ [Vicki Boykis: Everything I learned about accidentally running a successful tech conference (Normconf)](https://vickiboykis.com/2022/12/22/everything-i-learned-about-accidentally-running-a-successful-tech-conference/) ++ [tidyverse 2.0.0 released](https://www.tidyverse.org/blog/2023/03/tidyverse-2-0-0/) ++ [Twitter Recommendation Algorithm Open-sourced](https://blog.twitter.com/engineering/en_us/topics/open-source/2023/twitter-recommendation-algorithm) + +### Events + ++ [SSI Collaborations Workshop 2023](https://software.ac.uk/cw23) - Manchester, 2nd-4th May 2023 ++ [Bitesize webinar: Introduction to Open Access](https://sheffield.libcal.com/calendar/ext-staff-training/bitesizeOA) - Online (Scholarly Communications Team from the University of Sheffield Library), 10th May 2023. ++ [Bitesize webinar: Introduction to data sharing & the ORDA repository](https://sheffield.libcal.com/event/4028679) - Online (Scholarly Communications Team from the University of Sheffield Library), 24th May 2023. ++ [Bitesize webinar: Creative Commons licences](https://sheffield.libcal.com/calendar/ext-staff-training/bitesize-cc-licences) - Online (Scholarly Communications Team from the University of Sheffield Library), 7th June 2023. ++ [N8 CIR RSE Day](https://www.eventbrite.co.uk/e/n8-cir-rse-day-tickets-597753365407) - Durham, 13th June 2023. Register by 30th May. ++ [N8 CIR Digital Health Community Day](https://n8cir.org.uk/events/digital-health-community-day/) - The University of Leeds, 22 June 2023. Register by 8th June. ++ [ELLIS Summer School on Machine Learning for Healthcare and Biology](https://www.idsai.manchester.ac.uk/connect/events/ellis-summer-school-2023/schedule/) - The University of Manchester, 14th-16th June 2023. Booking closes 23rd May 2023. ++ [Teaching Reproducible Research and Open Science Conference](https://www.sheffield.ac.uk/smi/events/teaching-reproducible-research-and-open-science-conference) - The University of Sheffield, 20th-22nd June 2023. ++ [BigDat 2023 Summer – 7th International School of Big Data](https://bigdat.irdta.eu/2023su/) - Las Palmas de Gran Canaria 17th-21st July 2023. Online participation possible. ++ [Cambridge Digital Humanities: Digital Humanities Research Software Engineering (RSE) Summer School 2023](https://www.cdh.cam.ac.uk/events/36442/). Online, 24th-25th July 2023 and in-person (Cambridge) 27th-28th July 2023. Register by 23rd May 2023. ++ [RSE Conference 2023](https://rsecon23.society-rse.org/) - the UK Society of Research Software Engineering is holding its 2023 conference in Swansea 5th-7th September 2023. + + **Submission Deadline extended to Wednesday 3rd May 2023** ++ [OpenFest 2023](https://www.sheffield.ac.uk/library/research/open-research/openfest2023) - OpenFest at The University of Sheffield returns after the success of 2022's event for a two day event 6th-7th September 2023, including an online symposium *New Perspectives on Open Research*. ++ [The Festival of Hidden REF](https://hidden-ref.org/festival-of-hidden-ref/) - M Shed, Bristol, 21st September 2023. ++ [US-RSE'23](https://us-rse.org/usrse23/) - The first US-RSE Conference ever! Chicago, 16th-18th October 2023. + +### Training + ++ [Data management with SQL for researchers](https://rse.shef.ac.uk/training/workshop/2023-05-02-sql) - 2 May 2023 to 2 May 2023 - 12:30-16:30 ++ [Plotting and Programming with Python](https://rse.shef.ac.uk/training/workshop/2023-05-09-python) - 9 May 2023 to 10 May 2023 - 14:00-17:00 ++ [Supercharge your research code with Git and GitHub](https://rse.shef.ac.uk/training/workshop/2023-05-23-git) - 23 May 2023 to 23 May 2023 - 12:30-16:30 ++ [Data Analysis and Visualisation in R](https://rse.shef.ac.uk/training/workshop/2023-05-24-R) - 24 May 2023 to 24 May 2023 - 12:30-16:30 ++ [Image Processing with Python](https://rse.shef.ac.uk/training/workshop/2023-06-14-image-processing) - 14 June 2023 to 16 June 2023 - 12:30-16:30 ++ [Unix Shell Fundamentals](https://rse.shef.ac.uk/training/workshop/2023-06-26-bioinformatics) - 26 June 2023 to 26 June 2023 - 10:00-16030 ++ [Foundations of Astronomical Data Science +](https://rse.shef.ac.uk/training/workshop/2023-07-12-astro) - 12 July 2023 to 13 July 2023 - 12:30-16:30 + +#### Research IT Training + +Research IT courses have adopted a hybrid approach. The team will be providing their courses both online and in person for the first time since March 2020. The team provides a place for beginners or advanced users to expand their knowledge of HPC and different programming languages. The courses are part of the Doctoral Development Programme. For more information please visit our training registration web page (via VPN): [crs.shef.ac.uk](https://crs.shef.ac.uk). + +If a course is "sold out" please join the wait list by signing up - we regularly email people to encourage those that can no longer attend to cancel. Those on the wait list get early notification when the courses are run again. + +### Opportunities + + + +#### Jobs + ++ [The University of Leeds: 2 Research Software Engineers](https://jobs.leeds.ac.uk/vacancy.aspx?ref=ITRES1004). Applications close 9th May 2023. ++ [The University of Sheffield: Professor and Director of the Centre for Machine Intelligence](https://www.jobs.ac.uk/job/CZC875/professor-and-director-of-the-centre-for-machine-intelligence). Applications close 25th May 2023. + +### LunchBytes + +[LunchBytes](https://rse.shef.ac.uk/community/lunch-bytes/) are a monthly series of short talks from the research community on research software, data, and infrastructure. + +#### LunchBytes needs YOU! + +LunchBytes are organised by and for the research software community at The University of Sheffield. If you'd like to curate a session on a topic or present something, get in touch by emailing [lunchbytes-organisers-group@sheffield.ac.uk](mailto:lunchbytes-organisers-group@sheffield.ac.uk) - Or suggest topics [on the jamboard](https://jamboard.google.com/d/1-51cRf0pwZl8O10CnLeJGAqKcnbww-QGaYjszFK-H38/). + +### Support + +#### Code Clinics + +Why not come to a [Code Clinic](https://docs.google.com/forms/d/e/1FAIpQLScGXS55qjU0D0Zcz-KHOVcNTahcr3YC3H0OpoKBo3lWXWED5A/viewform)? We're keen to hear from you. + +Code Clinics are fortnightly supported sessions run by the RSE team and IT Services’ [Research IT](https://www.sheffield.ac.uk/it-services/research) team. They are open to anyone at TUoS writing code for research to get help with programming problems and general advice on best practices. + +At each session, members of the RSE and/or Research IT teams will be available to review code, advise, troubleshoot, and suggest ways to improve your computational workflows. + +#### Research IT HPC Drop In + +HPC Drop-In sessions are providing assistance with HPC related user issues such as challenges in scaling an application from desktop to supercomputer. We are considering extending the number of our sessions to two or three weekly. These interactive sessions could provide a better interface with our users than our non-interactive ticketing system. These sessions are advertised on the [HPC mailing list](https://groups.google.com/u/1/a/sheffield.ac.uk/g/hpc). + +#### Research IT Consultations + +Alongside the HPC Drop-In sessions, Research IT are also running one to one consultations to solve in depth user specific problems. These consultations can be booked via our webpage. If you are interested please visit the following link: . + +## Sheffield RSE Team + +The Sheffield RSE Team aims to [collaborate](https://rse.shef.ac.uk/collaboration/guide/) with you to help improve your research software. + +They can provide dedicated staff to ensure that you can deliver excellent research software engineering on your research projects. + +The Sheffield RSE Team provides free [Code Clinics][CCs] (in collaboration with [IT Services][its-res-it]), plus [paid services][rse-service] that allow us to collaborate longer term. + +## Research IT + +[Research IT](https://students.sheffield.ac.uk/it-services/research) directly supports research, both academic and commercial. +We provide large scale HPC systems, advice on everything from statistics to ML to data pipelines and training for both students and staff. +Working with academics, our staff are embedded within research groups on both long and short term engagements. + +[CCs]: https://rse.shef.ac.uk/support/code-clinic/ +[its-res-it]: https://www.sheffield.ac.uk/it-services/research/ +[rse-service]: https://rse.shef.ac.uk/collaboration/ diff --git a/_newsletters/2023-07-21-newsletter.md b/_newsletters/2023-07-21-newsletter.md new file mode 100644 index 00000000..85a1bb10 --- /dev/null +++ b/_newsletters/2023-07-21-newsletter.md @@ -0,0 +1,150 @@ +--- +layout: post +title: Summer 2023 Newsletter +editor: Robert Chisholm +slug: 2023-07-21-newsletter +date: 2023-07-21T00:00:00Z+0100 +tags: +category: +link: +description: +type: text +--- + +## The University of Sheffield Research Software Engineering Community Newsletter Summer 2023 + +Welcome to the summer newsletter for the research software community at The University of Sheffield, featuring news, opportunities, events and training for you. + +### News, Web & Blogs + +#### Web & Publications + +* [University of Sheffield's request for REF 2028 feedback](https://staff.sheffield.ac.uk/news/share-your-views-about-ref-2028) +* Shiny apps can now easily integrate with [hugging face](https://shiny.posit.co/blog/posts/shiny-on-hugging-face/)! +* Fostering an Inclusive Culture: [Call for Participation](https://contributor-experience.org/docs/posts/dei-report/) +* The [NASA JPL Observational Products for End-Users from Remote Sensing Analysis (OPERA)](https://www.jpl.nasa.gov/news/nasa-led-project-tracking-changes-to-water-ecosystems-land-surface) datasets are [starting to be released this year](https://www.jpl.nasa.gov/go/opera/products). These are satellite-based water-surface and topography maps through time. +* [Quarto-based template for university courses](https://github.com/jonjoncardoso/quarto-template-for-university-courses) +* StackOverflow has published the [results of their 2023 developer survey](https://stackoverflow.blog/2023/06/13/developer-survey-results-are-in/). +* [The binary split between academic and professional services staff is too simple for today's complex research environment.](https://twitter.com/sjh5000/status/1678747143656357889) +* Check out the [Code for Thought Podcast](https://codeforthought.buzzsprout.com/1326658), weekly episodes covering Research, (Open) Science & Engineering. + +#### RSE Advocacy + +* [Research software engineering accelerates the translation of biomedical research for health](https://www.nature.com/articles/s41591-023-02353-0) - D. Horsfall et al. +* [Advocating for Equality of Contribution: The Research Software Engineer (RSE) (Heliophysics Decadal Survery 2024)](https://essopenarchive.org/users/564792/articles/618963-advocating-for-equality-of-contribution-the-research-software-engineer-rse-heliophysics-decadal-survey-2024) + +#### MATLAB + +* Our own [David Wilby](/contact/david-wilby) has published the results of his survey of researchers using MATLAB on [his blog](https://reproduciblematlab.github.io/blog/posts/2023-05-02-survey/). +* [MATLAB toolbox development best practices guide](https://github.com/mathworks/toolboxdesign). +* Open and run any public MATLAB code from GitHub in MATLAB Online and run *without a license* Big news for reproducibility in the world of MATLAB. Details in Mike Croucher's blog: [Open science and reusable research with MATLAB Online and GitHub](https://blogs.mathworks.com/matlab/2023/07/20/open-science-and-reusable-research-with-matlab-online-and-github/) + +#### Open Research + +* [How Can Open Source Program Offices (OSPOs) Support Research Software?](https://www.researchsoft.org/blog/2023-06/) +* The Library's open research team have put together a thorough [guide to understanding the FAIR principles of publishing research outputs and data](https://sites.google.com/sheffield.ac.uk/fair-guidance/home). +* [Open Science: A Practical Guide for Early-Career Researchers](https://zenodo.org/record/7716153#.ZFzsHuxByLp) - L. Brinkman et al. +* [FAIR for Jupyter Notebooks: A Practical Guide](https://ardc.edu.au/resource/fair-for-jupyter-notebooks-a-practical-guide/) +* [Materials from CERN/NASAs Summit on Accelerating the Adoption of Open Science](https://zenodo.org/communities/cern-nasa-open-science-summit-july-2023/?page=1&size=20) +* [ROSiE General Guidelines on Responsible Open Science are now available!](https://rosie-project.eu/two-important-milestones-of-the-rosie-project-are-now-available/) +* [ResearchEquals](https://www.researchequals.com/) is a platform to support the open publishing of research at all stages. +* [Eleven Strategies for Making Reproducible Research and Open Science Training the Norm at Research Institutions](https://osf.io/kcvra/) - F. E. Kohrs et al. + +#### Blogs + +* Lost and Frustrated but Persistent: ([Part 1](https://software.ac.uk/blog/2023-07-03-lost-and-frustrated-persistent-part-1-personal-narratives-about-usability), [Part 2](https://software.ac.uk/blog/2023-07-04-lost-and-frustrated-persistent-part-2-personal-narratives-about-usability)) +* [Research Software Security Snippets #2](https://software.ac.uk/blog/2023-07-17-research-software-security-snippets-2) - Alex Coleman +* [Hire a Data Manager](https://cghlewis.com/blog/hire_datamgr/) - Crystal Lewis +* [Open source is a hard requirement for reproducibility](https://www.r-bloggers.com/2022/11/open-source-is-a-hard-requirement-for-reproducibility/) + +#### Publications + +* [Better Research Software Tools to Elevate the Rate of Scientific Discovery -- or why we need to invest in research software engineering](https://arxiv.org/abs/2307.03934) - J. Deschamps, D. D. Nogare, F. Jug +* [The Future of Academic Publishing](https://www.nature.com/articles/s41562-023-01637-2) - A. Ahmed et al. + +### Events + +* [FAIR faculty seminars](https://www.eventbrite.com/cc/fair-faculty-seminars-summer-2023-2394899) - The University's Library team are holding seminars over summer to introduce FAIR principles and their new website, 1st-10th August 2023 (Check the link for your own Faculty's date/location). ++ [RSE Conference 2023](https://rsecon23.society-rse.org/) - the UK Society of Research Software Engineering is holding its 2023 conference in Swansea 5th-7th September 2023. ([draft program](https://virtual.oxfordabstracts.com/#/e/RSECon23/program)) ++ [OpenFest 2023](https://www.sheffield.ac.uk/library/research/open-research/openfest2023) - OpenFest at The University of Sheffield returns after the success of 2022's event for a two day event 6th-7th September 2023, including an online symposium *New Perspectives on Open Research*. ++ [1st Conference On Research Data Infrastructure (CORDI)](https://www.eosc.eu/events/1st-conference-research-data-infrastructure-cordi) - Karlsruhe, Germany, 12th-14th September 2023. ++ [The Festival of Hidden REF](https://hidden-ref.org/festival-of-hidden-ref/) - M Shed, Bristol, 21st September 2023. ++ [Open Science Fair](https://www.opensciencefair.eu/) - Madrid, Spain, 25th-27th September 2023. ++ [deRSE unConference](https://un-derse23.sciencesconf.org/) - Jena, Germany, 26th-29th September 2023 (Applications open until July 24th) ++ [US-RSE'23](https://us-rse.org/usrse23/) - The first US-RSE Conference ever! Chicago, 16th-18th October 2023. ++ [AoIR 2024](https://aoir.org/aoir2024/) - The associate of Internet Researchers' next conference is in Sheffield, 30th October - 2nd November 2024. + +### Training + +With summer coming up, there aren't currently any training courses scheduled. Look out for new sessions in early September. RSE training courses can be found [here](https://rse.shef.ac.uk/events/) and are normally announced to our mailing list, whereas Research IT courses can be found at [crs.shef.ac.uk](https://crs.shef.ac.uk). + + + + + + + +### Opportunities + ++ [Open Infrastructure Fund](https://investinopen.org/blog/open-infrastructure-fund-pilot-cfp/) is taking applications from projects that support the development of open research infrastructure services, for upto $25,000. - Closes July 31st 2023 ++ [Journal of Systems and Software : Special Issue call for papers](https://www.sciencedirect.com/journal/journal-of-systems-and-software/about/call-for-papers#gender-equality-diversity-and-inclusion-in-software-engineering): Gender Equality, Diversity, and Inclusion in Software Engineering - Closes 1st November 2023 + + + +#### Jobs + +No jobs were submitted this period as typically hiring slows during summer, however you can always check for advertised RSE and RSE-adjacent roles over at the [RSE society's vacancies board](https://society-rse.org/careers/vacancies/). + + +### Digital Research Practice Support Community + +The DRPS community is a group for people that support researchers in carrying out research in the digital age. Meetings are held monthly, with discussions around events, training and opportunities related to the field. + +You can join the google group [here](https://groups.google.com/u/1/a/sheffield.ac.uk/g/digital-research-practice-support-community-group/about) to stay informed. + +The next meeting is scheduled for 2pm on Wednesday 9th August. + + +### LunchBytes + +[LunchBytes](https://rse.shef.ac.uk/community/lunch-bytes/) are a monthly series of short talks from the research community on research software, data, and infrastructure. + +#### LunchBytes needs YOU! + +LunchBytes are organised by and for the research software community at The University of Sheffield. If you'd like to curate a session on a topic or present something, get in touch by emailing [lunchbytes-organisers-group@sheffield.ac.uk](mailto:lunchbytes-organisers-group@sheffield.ac.uk) - Or suggest topics [on the jamboard](https://jamboard.google.com/d/1-51cRf0pwZl8O10CnLeJGAqKcnbww-QGaYjszFK-H38/). + +### Support + +#### Code Clinics + +Why not come to a [Code Clinic](https://docs.google.com/forms/d/e/1FAIpQLScGXS55qjU0D0Zcz-KHOVcNTahcr3YC3H0OpoKBo3lWXWED5A/viewform)? We're keen to help you. + +Code Clinics are fortnightly supported sessions run by the RSE team and IT Services’ [Research IT](https://www.sheffield.ac.uk/it-services/research) team. They are open to anyone at TUoS writing code for research to get help with programming problems and general advice on best practices. + +At each session, members of the RSE and/or Research IT teams will be available to review code, advise, troubleshoot, and suggest ways to improve your computational workflows. + +#### Research IT HPC Drop In + +HPC Drop-In sessions are providing assistance with HPC related user issues such as challenges in scaling an application from desktop to supercomputer. We are considering extending the number of our sessions to two or three weekly. These interactive sessions could provide a better interface with our users than our non-interactive ticketing system. These sessions are advertised on the [HPC mailing list](https://groups.google.com/u/1/a/sheffield.ac.uk/g/hpc). + +#### Research IT Consultations + +Alongside the HPC Drop-In sessions, Research IT are also running one to one consultations to solve in depth user specific problems. These consultations can be booked via our webpage. If you are interested please visit the following link: . + +## Sheffield RSE Team + +The Sheffield RSE Team aims to [collaborate](https://rse.shef.ac.uk/collaboration/guide/) with you to help improve your research software. + +They can provide dedicated staff to ensure that you can deliver excellent research software engineering on your research projects. + +The Sheffield RSE Team provides free [Code Clinics][CCs] (in collaboration with [IT Services][its-res-it]), plus [paid services][rse-service] that allow us to collaborate longer term. + +## Research IT + +[Research IT](https://students.sheffield.ac.uk/it-services/research) directly supports research, both academic and commercial. +We provide large scale HPC systems, advice on everything from statistics to ML to data pipelines and training for both students and staff. +Working with academics, our staff are embedded within research groups on both long and short term engagements. + +[CCs]: https://rse.shef.ac.uk/support/code-clinic/ +[its-res-it]: https://www.sheffield.ac.uk/it-services/research/ +[rse-service]: https://rse.shef.ac.uk/collaboration/ diff --git a/_people/anna-krystalli.md b/_people/anna-krystalli.md index bb7710d9..8575b887 100644 --- a/_people/anna-krystalli.md +++ b/_people/anna-krystalli.md @@ -1,5 +1,5 @@ --- -alumnum: false +alumnum: true level: 2 published: true @@ -19,5 +19,4 @@ Key interests include: * Reproducible research * Open source research technologies and culture enabling next generation open science. -* Email: a.krystalli (at) sheffield.ac.uk * Twitter: [@annakrystalli](https://twitter.com/annakrystalli) diff --git a/_people/bob-turner.md b/_people/bob-turner.md index 7f394aff..0d54840f 100644 --- a/_people/bob-turner.md +++ b/_people/bob-turner.md @@ -1,6 +1,6 @@ --- -alumnum: false -level: 2 +alumnum: true +level: 1 published: true othernames: Bob @@ -9,18 +9,18 @@ role: Research Software Engineer --- -Bob is a research software engineer who started his career in software and databases after completing a degree in *Applied Physics* at the *University of Durham*. After four years in the private sector, he did a *PhD in Biophysics* at the *University of Leeds*, before working as a postdoc researcher at the *University of Sheffield* in several departments, including Physics and Astronomy, Molecular Biology and Biotechnology Mechanical Engineering and the Dental School, reflecting an unusually broad range of research interests spanning microscopy, microbiology, engineering and healthcare. +Bob was a senior research software engineer who started his career in software and databases after completing a degree in *Applied Physics* at the *University of Durham*. After four years in the private sector, he did a *PhD in Biophysics* at the *University of Leeds*, before working as a postdoc researcher at the *University of Sheffield* in several departments, including Physics and Astronomy, Molecular Biology and Biotechnology Mechanical, Engineering and the Dental School, reflecting an unusually broad range of research interests spanning microscopy, microbiology, engineering and healthcare. -An accomplished researcher with some [important publications](https://scholar.google.com/citations?hl=en&user=JdHx1A8AAAAJ), as a software engineer Bob collaborates with researchers to develop and improve software. This of course involves writing code, but also lots of liaison, discussion, leadership and, most importantly, listening! +An accomplished researcher with some [important publications](https://scholar.google.com/citations?hl=en&user=JdHx1A8AAAAJ), as a software engineer Bob collaborates with researchers to develop and improve software. This of course involved writing code, but also lots of liaison, discussion, leadership and, most importantly, listening! -Bob codes in *Python*, *R* and *Matlab* using version control with *git* and applying good software engineering practices such as *documentation*, *automated testing* and *continuous integration*. He enjoys working with a diverse range of collaborators in different disciplines. Current and recent work includes: +Bob's role included contributing to the management of the RSE team, under Paul Richmond's leadership. His work included: -- Porting code for identification of the polar sea ice edge from *Matlab* to *Python* and deploying this using *Docker*. -- Documenting and developing [*GPy*](https://sheffieldml.github.io/GPy/), a *Gaussian Process* based *machine learning* framework for *Python*. -- Reviewing research software and developing formal processes for this. -- Leading a software engineering team building [epidemiological modelling software](https://github.com/ScottishCovidResponse/simple_network_sim) (*Python*) as part of the Royal Society's [Rapid Assistance in Modelling the Pandemic](https://royalsociety.org/topics-policy/Health%20and%20wellbeing/ramp/) initiative. -- Supporting *RedCAP* database infrastructure (using *Vagrant* and *Ansible*) for clinical trials in collaboration with *INSIGNEO*, the *Biomedical Research Centre* and the *Hallamshire Hospital*. -- Delivering training on reproducible research, version control, Python and R. +- Advising and helping researchers to implement good software engineering practises (e.g. testing, version control, documentation, reproducible execution, packaging, licensing) +- Writing research software (e.g. in Python, MATLAB, R) +- Training +- Line management of five team members +- Establishing new externally-funded collaborations +- Advocating and acting to improve the standards of research software (e.g. running or delivering talks, communication via social media, engagement with university committees) Contact: diff --git a/_people/dan-brady.md b/_people/dan-brady.md new file mode 100644 index 00000000..c396a942 --- /dev/null +++ b/_people/dan-brady.md @@ -0,0 +1,16 @@ +--- +alumnum: false +level: 2 +published: true + +othernames: Dan +surname: Brady +role: Research Software Engineer + +--- + +Dan joined the RSE team in December 2022. His background is in Cognitive Neuroscience, completing his PhD at Goldsmiths in 2016. Since then he has worked as a Research Fellow at Birkbeck and the University of Surrey and as Research Technician at the University of Reading. He has experience of writing research software and analysis pipelines using R, Python and Julia. He is also a keen advocate of open and reproducible research practices. + +* Email: daniel.brady (at) sheffield.ac.uk +* Github: [@ubdbra001](https://github.com/ubdbra001) +* Twitter: [@DanTBrady](https://twitter.com/DanTBrady) \ No newline at end of file diff --git a/_people/david-jones.md b/_people/david-jones.md index b1bb9fb2..308425bd 100644 --- a/_people/david-jones.md +++ b/_people/david-jones.md @@ -1,5 +1,5 @@ --- -alumnum: false +alumnum: true level: 2 published: true @@ -9,7 +9,7 @@ role: Research Software Engineer --- -David is a Research Software Engineer in +David was a Research Software Engineer in the University of Sheffield's RSE group. David graduated from the University of Cambridge with @@ -23,6 +23,5 @@ embedded microcontrollers, programming language runtimes, Software Engineering Management, /bin/awk, and the PNG image format. -- Email: David.R.Jones@sheffield.ac.uk - Twitter: [@drjtwit](https://twitter.com/drjtwit) - GitLab: [gitlab.com/drj11](https://gitlab.com/drj11) diff --git a/_people/david-wilby.md b/_people/david-wilby.md index af366bbc..3d06d99d 100644 --- a/_people/david-wilby.md +++ b/_people/david-wilby.md @@ -1,6 +1,6 @@ --- alumnum: false -level: 2 +level: 1 published: true othernames: David @@ -9,14 +9,17 @@ role: Research Software Engineer --- -Following a PhD in Physics & Biology at the University of Bristol employing HPC-based optical simulation techniques and postdoctoral research at Bristol and Lund Universities in behavioural experimentation and ray tracing simulation in sensory biology, David made the transition to research software engineering in 2019. He is experienced in Python and MATLAB, with developing interest also in the languages R and Go. +David is a Senior Research Software Engineer with a research background in optical physics and sensory biology. Following a PhD and postdoc at the University of Bristol and a postdoc at Lund University David made the transition to research software engineering in 2019. -David's interests in research software relate to: impact enhancement, reproducibility and sustainability, best practice and environmental and social responsibility. +His interests in research software relate to: impact enhancement, reproducibility and sustainability, best practice and environmental and social responsibility, in addition to interests in training researchers in research software. -He has been involved with projects in: python packaging, web dashboards for data visualisation, service containerisation, API development and data visualisation. +In 2022, David became a fellow of the Software Sustainability Institute with a project on developing guidance and training around reproducible research in MATLAB. -Other technologies that David has worked with are: Django, TensorFlow, Docker, Jupyter notebooks, Javascript & Google App Script. +He has been involved in numerous research projects including: +* building Django-based web apps, +* apps for medical research proof of principle in clinical trials, +* COVID modelling software quality at the UK Joint Biosecurity Centre, +* dockerising and python packaging NLP tools. * Email: d.wilby (at) sheffield.ac.uk -* Twitter: [@DrDavidWilby](https://twitter.com/drdavidwilby) -* Web: [davidwilby.github.io/](https://davidwilby.github.io/) +* Website: [davidwilby.dev](https://davidwilby.dev) diff --git a/_people/edwin-brown.md b/_people/edwin-brown.md new file mode 100644 index 00000000..78dc1f23 --- /dev/null +++ b/_people/edwin-brown.md @@ -0,0 +1,18 @@ +--- +alumnum: false +level: 2 +published: true + +othernames: Edwin +surname: Brown +role: Research Software Engineer + +--- + +Edwin joined the RSE team in October 2022. He comes from a background in geophysics following a BSc and MSc in Geophysical Sciences at the University of Leeds. After university, he worked in the private sector, developing machine learning (ML) workflows to solve geophysical imaging and inversion problems. + +Edwin has practical experience in the designing, training and evaluation of ML models. He is experienced in Python having worked with data science libraries such as Numpy, Pandas, Scikit-learn, Tensorflow and Keras. He has a growing interest in MLOps (Machine Learning Operations) and the practical challenges of scaling up ML practices. + +* Email: w.e.brown (at) sheffield.ac.uk +* Github: [@EdwinB12](https://github.com/EdwinB12) +* [LinkedIn](https://www.linkedin.com/in/edwin-brown-214471108/) diff --git a/_people/fariba-yousefi.md b/_people/fariba-yousefi.md index 8853c433..1917484d 100644 --- a/_people/fariba-yousefi.md +++ b/_people/fariba-yousefi.md @@ -1,5 +1,5 @@ --- -alumnum: false +alumnum: true level: 2 published: true @@ -11,11 +11,14 @@ role: Research Software Engineer Fariba Yousefi is in the process of completing her PhD in Machine Learning at the department of Computer Science, University of Sheffield. She recently joined the research software engineering team as a machine learning research engineer at the university of Sheffield. -Her research interests are Bayesian non-parametrics, Gaussian Processes, data scarcity, imbalanced data and multi-task learning. She enjoys working on healthcare applications, especially medical images. -She also contributes to open source projects such as [GPy](https://github.com/SheffieldML/GPy). +Her research interests are Gaussian Processes, data scarcity, imbalanced data and multi-task learning. She enjoys working on healthcare applications. + +Fariba’s experience in chairing and organizing scientific events include: the Gaussian processes summer school (http://gpss.cc/) and the Women in Machine Learning (WiML https://wimlworkshop.org/), where she was the senior programme chair at the affinity workshop for ICML 2020. +She also contributes to open source projects such as [GPy](https://github.com/SheffieldML/GPy). * Email: f.yousefi (at) sheffield.ac.uk * Twitter: [@frb_yousefi](https://twitter.com/frb_yousefi) * LinkedIn: [Fariba Yousefi](https://www.linkedin.com/in/fariba-yousefi-2b4b5818/) * Github: [frb-yousefi](https://github.com/frb-yousefi) +* Scholar: [Fariba Yousefi](https://scholar.google.com/citations?user=rF9GU-EAAAAJ&hl=en) diff --git a/_people/john-charlton.md b/_people/john-charlton.md index e53721ea..1d72c59a 100644 --- a/_people/john-charlton.md +++ b/_people/john-charlton.md @@ -1,5 +1,5 @@ --- -alumnum: false +alumnum: true level: 2 published: true @@ -9,8 +9,8 @@ role: Research Software Engineer --- -John is a current PhD student and Research Software Engineer. Previous work has involved simulating dense crowds of virtual pedestrians, using GPUs to model many tens of thousands of people in real time. -His interested include agent-based modelling, visualisation and interaction of simulations. Expertise includes GPU-accelerated computing and agent-based modelling approaches. +John was a PhD student and Research Software Engineer. Previous work had involved simulating dense crowds of virtual pedestrians, using GPUs to model many tens of thousands of people in real time. +His interests included agent-based modelling, visualisation and interaction of simulations. Expertise includes GPU-accelerated computing and agent-based modelling approaches. He is currently working on a [RateSetter project](https://rssb.wavecast.io/platformtraininterface/ratesetter-improving-passenger-boarding-rate-and-reducing-risk-at-the-platform-train-interface) examining the boarding rate and risk at the Platform-Train interface. diff --git a/_people/matthew-leach.md b/_people/matthew-leach.md index 1ee57062..a751f010 100644 --- a/_people/matthew-leach.md +++ b/_people/matthew-leach.md @@ -12,7 +12,7 @@ role: Research Software Engineer in Complex Systems Matt is a Research Software Engineer in Complex Systems. He has a background in computer graphics, using physical-modelling to produce animations. He has recently completed his PhD on modelling the human mouth using the finite element method and also has experience with fluid simulation. Aside from physical-modelling, he also has research experience working with virtual and augmented reality. -Matt's work on the team primarily revolves around the development of [FLAMEGPU] (http://www.flamegpu.com/) and advocating the use of GPU computing to support research. +Matt's work on the team primarily revolves around the development of [FLAMEGPU](http://www.flamegpu.com/) and advocating the use of GPU computing to support research. He is currently improving the performance of a model of tuberculosis spread. diff --git a/_people/neil-shephard.md b/_people/neil-shephard.md new file mode 100644 index 00000000..08ed4985 --- /dev/null +++ b/_people/neil-shephard.md @@ -0,0 +1,47 @@ +--- +alumnum: false +level: 2 +published: true + +othernames: Neil +surname: Shephard +role: Research Software Engineer +--- + +Neil has taken a convoluted path to reach his current role as research software engineer. After completing his +undergraduate (_BSc Zoology and Genetics_) and post-graduate (_MSc in Genetic Epidemiology_) at _The University +of Sheffield_ he spent a number of years as a _Genetics Statistician_ researching the aetiology of complex human +diseases at _University of Manchester_, and _University of Western Australia_ before returning to _University +of Sheffield_ learning UNIX system administration and [literate +programming](https://en.wikipedia.org/wiki/Literate_programming) along the way. He then shifted careers to medical +statistics and spent eight years working at the [Clinical Trials Research +Unit](https://www.sheffield.ac.uk/scharr/research/centres/ctru) at the _University of Sheffield_. Throughout this time +Neil developed and became enthusiastic about reproducible research and developed practical approaches to achieving +reproducible research in [R](https://www.r-project.org) using [RMarkdown](https://rmarkdown.rstudio.com). + +In 2018 he left academia for the private sector working for a telematics company using data captured from +mobile phones and "_black boxes_" to quantify driver behaviour. Here he developed an understanding of working +with geo-spatial data and learnt [Python](https://www.python.org) along with various aspects of good software +development practices including working collaboratively using [Git](https://git-scm.com) for version control. + +Current projects: + +* [AFM-SPM/TopoStats](https://github.com/AFM-SPM/TopoStats) (see also [TopoStats](https://pyne-lab.uk/topostats)) +* [Mesnage-org/pgfinder](https://github.com/Mesnage-Org/pgfinder) + +Interests include: + +* Reproducible research and literate progrmaming +* Open Science +* Python, R and Bash +* Evolutionary Genetics +* Emacs and Org-mode + +Contact: + +* Email: n.shephard (at) sheffield.ac.uk +* GitHub: [@ns-rse](https://github.com/ns-rse/) +* Blog: [ns-rse](https://ns-rse.github.io/) +* Web: [https://kimura.no-ip.info](https://kimura.no-ip.info) +* Twitter: [@nshephardRSE](https://twitter.com/nshephardRSE) +* Mastodon: [@nshephard@fosstodon.org](https://fosstodon.org/@nshephard) diff --git a/_people/paul-richmond.md b/_people/paul-richmond.md index ce2355e2..4a46db07 100644 --- a/_people/paul-richmond.md +++ b/_people/paul-richmond.md @@ -1,16 +1,15 @@ --- -alumnum: false +alumnum: true level: 0 published: true othernames: Paul surname: Richmond -role: Group Director +role: Former Group Director --- -Paul is an [EPSRC Research Software Engineering Fellow](https://rse.ac.uk/community/epsrc-rse-fellows/). Paul's career as an academic researcher has always been focused on the development of software to support research, predominantly through the application of emerging hardware architectures to complex systems simulation. His technical expertise in GPU computing has led him to work more broadly, engaging with researchers in a wide range of domains to embed accelerated and GPU computing into their research ecosystems. His background in independent research means that he self-identifies as a [Research Software Engineer](https://rse.ac.uk/) with a strong emphasis on research relating to the application of GPUs. He is the director of the RSE group and oversees and manages team members and their more broad contribution to projects around research software development. +Paul was a co-founder of the RSE team and led its growth and development from three staff to a team of roughly 12 full time employees over a period of six years. He is the RSE team lead at the [Cambridge Institute of Computing for Climate Science](https://cambridge-iccs.github.io/) but holds a part time role at the University of Sheffield as a Professor of Research Software Engineering in the Department of Computer Science. He no longer oversees the RSE team but is actively engaged in research projects and impact work relating to the application of research software, in particular the [FLAME GPU](http://www.flamegpu.com) software for GPU accelerated agent based simulation. Paul was formally an [EPSRC Research Software Engineering Fellow](https://rse.ac.uk/community/epsrc-rse-fellows/) and President of the society of Research Software Engineering](https://society-rse.org/about/governance/rse-society-trustees-2020-2021/). He is actively engaged in the national RSE community and retains interest in advancing the national provision of RSE collaboration including within the University of Sheffield. * Email: P.Richmond (at) Sheffield.ac.uk * Web: [http://paulrichmond.shef.ac.uk](http://paulrichmond.shef.ac.uk) -* GPUComputing: [http://gpucomputing.shef.ac.uk/](http://gpucomputing.shef.ac.uk) diff --git a/_people/robert-chisholm.md b/_people/robert-chisholm.md index fce8cd65..89e9d22c 100644 --- a/_people/robert-chisholm.md +++ b/_people/robert-chisholm.md @@ -9,15 +9,19 @@ role: Research Software Engineer/Research Associate in Large Scale Simulation --- -Robert is a Research Software Engineer in the process of completing his PhD at the University of Sheffield. +Robert is a Research Software Engineer that previously completed his PhD at the University of Sheffield. He specialises in GPU accelerated computing and complex system simulations, following his PhD's focus on improving the performance of spatial communication in GPU accelerated algorithms. -He is currently working on the [PRIMAGE project](https://www.primageproject.eu/), -which proposes an open cloud-based platform to support decision making in the clinical management of two paediatric cancers. -In particular, wokring towards the development of a cell scale model of neuroblastoma to be scaled across multiple GPUs and distributed HPC resources. +He is a developer of the [FLAMEGPU](http://www.flamegpu.com/) software framework, facilitating wider access to complex systems modelling on GPUs. -He is also contributing towards the new version of [FLAMEGPU](http://www.flamegpu.com/) software framework, facilitating wider access to complex systems modelling on GPUs. +Previously he worked on the [PRIMAGE project](https://www.primageproject.eu/), +which proposed an open cloud-based platform to support decision making in the clinical management of two paediatric cancers. +In particular, working towards the development of a cell scale model of neuroblastoma to be scaled across multiple GPUs and distributed HPC resources. + +Currently he is working with [Fujitsu Research Europe](https://www.fujitsu.com/uk/about/local/corporate/subsidiaries/fle/) developing a GPU accelerated transport model. + +Since the 2022/2023 academic year he has been the module leader for [COM4521/COM6521](/training/com4521) that covers parallel programming with OpenMP and CUDA. * Email: r.chisholm (at) sheffield.ac.uk -* Twitter: [@_robadob](https://twitter.com/_robadob) +* Twitter: [@robadob](https://twitter.com/robadob) * Github: [@robadob](https://github.com/Robadob) diff --git a/_people/will-furnass.md b/_people/will-furnass.md index a330c41c..a945cbe8 100644 --- a/_people/will-furnass.md +++ b/_people/will-furnass.md @@ -1,5 +1,5 @@ --- -alumnum: false +alumnum: true level: 1 published: true @@ -8,7 +8,7 @@ surname: Furnass role: Research Software Engineer --- -Will is a Research Software Engineer who is currently: +Will was a Research Software Engineer who was previously: - Helping Paul Richmond lead the RSE team - Contributing to the development and maintenance of University research computing platforms (inc. HPC) diff --git a/_posts/2020-01-09-gpu-course.md b/_posts/2020-01-09-gpu-course.md index 10480bd3..9e1f52d9 100644 --- a/_posts/2020-01-09-gpu-course.md +++ b/_posts/2020-01-09-gpu-course.md @@ -9,12 +9,15 @@ category: link: description: type: text +excerpt_separator: --- The following 12 week course in "Parallel Computing with GPUs" is available to PhD students and research staff (including academic staff). Course Details: [https://paulrichmond.shef.ac.uk/teaching/COM4521/](https://paulrichmond.shef.ac.uk/teaching/COM4521/) + + The module is traditionally taught as a 4th year undergraduate and masters course but is typically has a high update of research students and staff who are wanting to learn about shared memory parallel and GPU computing. The course goes beyond a simple 1 or 2 day introduction and provides advanced material on GPU programming and optimisation. There is a 2 hour lecture each week followed by a 2 hour lab class which can be conducted remotely or in person (subject to lab space availability). There is also a course google group monitored by lab demonstrators and members of the RSE team. diff --git a/_posts/2020-01-22-love-data-week.md b/_posts/2020-01-22-love-data-week.md index 5910a313..68db67cc 100644 --- a/_posts/2020-01-22-love-data-week.md +++ b/_posts/2020-01-22-love-data-week.md @@ -9,6 +9,7 @@ category: link: description: type: text +excerpt_separator: --- [Love Data Week](https://lovedataweek.org/about-ldw/) is an annual global event designed to @@ -16,6 +17,8 @@ type: text The [University of Sheffield's Library](https://www.sheffield.ac.uk/library) have organised several events for this year's Love Data Week (10-14 February 2020): + + * 11th Feb, 10:00 - 12:00: DDP workshop on *Looking after your Research Data*. NB now **fully booked** but [spaces available for subsequent sessions](http://ris.dept.shef.ac.uk/skills_seminars/listings/view/122) diff --git a/_posts/2020-02-04-vacancies.md b/_posts/2020-02-04-vacancies.md index 65289d41..b1c806c0 100644 --- a/_posts/2020-02-04-vacancies.md +++ b/_posts/2020-02-04-vacancies.md @@ -9,6 +9,7 @@ category: link: description: type: text +excerpt_separator: --- We're looking for two people to join our team: @@ -16,6 +17,8 @@ We're looking for two people to join our team: * A Research Software Engineer to work on complex systems modelling accelerated using GPUs; * A Community Engagement and Training Officer + + ## Research Software Engineer (Complex Systems Simulation using GPUs) * Closes: 14th February 2020 diff --git a/_posts/2020-02-28-hpc-sig-champions.md b/_posts/2020-02-28-hpc-sig-champions.md index d0b52b5f..2eee01c9 100644 --- a/_posts/2020-02-28-hpc-sig-champions.md +++ b/_posts/2020-02-28-hpc-sig-champions.md @@ -9,11 +9,13 @@ category: link: description: type: text +excerpt_separator: --- I've just come back from [HPC Special Interest Group (HPC-SIG)][hpc-sig] and [HPC Champions][hpc-champions] (formerly ARCHER Champions) events on the 25th and 26th of Feb in Bath, so thought I'd do a write-up. There's updates on Liverpool and Bath's cloud HPC, ARCHER 2, Tier-2 HPC refresh and how you can get extra GPU compute for your research! + ## Liverpool and Bath's Journey to the Clouds Cliff Addison (Liverpool) and Steven Chapman (Bath) gave talks on their respective university's integration of cloud infrastructure diff --git a/_posts/2020-03-17-code-clinics-online.md b/_posts/2020-03-17-code-clinics-online.md index 5db4be54..0f003bc3 100644 --- a/_posts/2020-03-17-code-clinics-online.md +++ b/_posts/2020-03-17-code-clinics-online.md @@ -9,12 +9,15 @@ category: link: description: type: text +excerpt_separator: --- In response to the need for increased remote working as a result of the current Covid-19 situation, we're going to be doing our [Code Clinics](/support/code-clinic) remotely using Google Hangouts for now. Code Clinics remain a great way to get help with writing and maintaining code and with reduced physical access to labs, perhaps now is good time to focus on this aspect of research. **We can offer advice on working with and executing code remotely.** + + We'll do our best to help with: - Short scripts diff --git a/_posts/2020-03-24-configuring-cuda-and-opengl-courses-in-the-cloud.md b/_posts/2020-03-24-configuring-cuda-and-opengl-courses-in-the-cloud.md index 732c7c2c..9257d279 100644 --- a/_posts/2020-03-24-configuring-cuda-and-opengl-courses-in-the-cloud.md +++ b/_posts/2020-03-24-configuring-cuda-and-opengl-courses-in-the-cloud.md @@ -9,12 +9,15 @@ category: link: description: type: text +excerpt_separator: --- Academics and RSEs have been very busy over the last few weeks coming up with creative solutions to move teaching and training online. My own under/post graduate GPU module [Parallel Computing with GPUs](https://paulrichmond.shef.ac.uk/teaching/COM4521/) has posed a significant problem. The course was designed to be run within the University of Sheffield's High Specification teaching lab which is equipped with CUDA enabled GPUs. Moving this course online clearly requires a mechanism for students to access GPUs, without presenting a significant change to their current working practice (e.g. Visual Studio development in Windows). Ideally this cold be done using the [university's high performance computing facilities](https://www.sheffield.ac.uk/it-services/research/hpc) but the provision for GPUs is currently insufficient to support 100 students (although new GPUs are on the way). The obvious solution is to move this to the cloud however there are a number of challenges to solve which are the topic of this blog post which also serves as a reference for when I forget all of this in 6 months time. *Note: This blog specifically targets AWS as it is what I have used on the [InstanceHub](https://www.instancehub.com) website which is part of the solution to Problem 3.* + + ## Problem 1: GPU Accelerated Instances with Graphical Displays Creating an AWS image with accelerated Rendering and CUDA support is surprisingly more difficult than you might imagine. Having a GPU backed Windows instance still requires a driver install. The are some subtle things to watch out for here. E.g. Most GPU backed based cloud machine types use Tesla GPUs. These will support the NVIDIA CUDA driver but will run as headless devices using [TCC driver mode in Windows](https://docs.nvidia.com/gameworks/content/developertools/desktop/nsight/tesla_compute_cluster.htm). Essentially, this means that they will run CUDA applications and support debugging and profiling but won't be involved in driving the display over remote desktop (or VNC). The built in windows display driver will instead be used which has OpenGL 1.0 support only. diff --git a/_posts/2020-03-29-git-github-remote.md b/_posts/2020-03-29-git-github-remote.md index f85d9f23..6d4bf691 100644 --- a/_posts/2020-03-29-git-github-remote.md +++ b/_posts/2020-03-29-git-github-remote.md @@ -9,10 +9,13 @@ category: link: description: type: text +excerpt_separator: --- As software engineers, we were lucky to have a running start at shifting to remote working practices as part of our institutional response to COVID-19. We have very little physical infrastructure in the team and can access most of what we need to do through the internet, even each other through video calls, emails and text chat. We can rely on our I.T. Services to provide a virtual network (VPN) and virtual machines for hosted applications. However, there is one area where I feel like we've made our own luck - collaborating on developing software. A big part of our ethos is to identify good practices, put them into action and share them with others. So I'm going to talk a bit here about how we use [git](https://git-scm.com/) and [GitHub](https://github.com/) not just to track changes and contributions to code, but to manage projects. And, as it turns out, this is actually pretty easy if you have a little time to invest. The difficulty, for many of us, is finding that time, but that's kind of another story! + + ## **git** and **GitHub** - what's the difference? **git** is software that you install locally to track changes to code on your machine, in a *repository* (this is all in a folder / directory). It can connect to a *remote* repository, sending or receiving changes. Many developers can collaborate and share via a single remote repository. This can be hosted on a 3rd party website such as **GitHub**. [GitLab](https://about.gitlab.com/) is an alternative - some say it's better. **GitHub** provides a web interface to your repository and a bunch of other features that interact with it and extend the functionality of **git**. It's worth making the point here that even if I'm not connecting to a remote repository, I always use **git** locally to control my code. diff --git a/_posts/2020-04-06-announce-gpu-hackathon-2020.md b/_posts/2020-04-06-announce-gpu-hackathon-2020.md index e295e008..53b7ca15 100644 --- a/_posts/2020-04-06-announce-gpu-hackathon-2020.md +++ b/_posts/2020-04-06-announce-gpu-hackathon-2020.md @@ -9,6 +9,7 @@ category: link: description: type: text +excerpt_separator: --- Following the success of our 2019 event, @@ -18,6 +19,8 @@ as part of the NVIDIA international GPU Hackathon Series. This event will take place between **27 – 31 July 2020**, most likely as an online event unless government restrictions around COVID-19 are significantly altered. + + Prior GPU experience is not required, as those selected will be paired with experienced mentors who will teach them how to leverage accelerated computing in their own applications or further optimize their codes. diff --git a/_posts/2020-05-20-ssh-best-prac.md b/_posts/2020-05-20-ssh-best-prac.md index 7af3302e..30357412 100644 --- a/_posts/2020-05-20-ssh-best-prac.md +++ b/_posts/2020-05-20-ssh-best-prac.md @@ -9,6 +9,7 @@ category: link: description: type: text +excerpt_separator: --- *Including High-Performance Computing clusters* @@ -28,6 +29,8 @@ University of Sheffield as poorly managed keys/passwords could allow others to impersonate you, which could result in further cyberattacks, data theft/loss and reputational damage to you and the University. + + If you **typically use a password to authenticate via SSH** then consider what damage could be done should someone else acquire/guess your password.  This is why it is sensible to authenticate using two distinct pieces of private diff --git a/_posts/2020-09-03-agile.md b/_posts/2020-09-03-agile.md index 6043b4e3..f45c2971 100644 --- a/_posts/2020-09-03-agile.md +++ b/_posts/2020-09-03-agile.md @@ -16,6 +16,8 @@ I formally led a software development team for the first time as part of the [Sc This post is about management and leadership on the project. + + ## Our software Simple Network Sim models a covid-19 pandemic by breaking a population down into nodes (representing specific geographic areas) in a network. Each node has numbers of people in various states (e.g. exposed, infected, recovered, dead) and the model is parameterised with rates of transition between these states. This is modified by levels of mixing between people of different age groups. People also move between the geographic nodes so changes in movement patterns can be simulated. This means it's possible to simulate things like: diff --git a/_posts/2020-09-22-slt-cdt-hpc-pres.md b/_posts/2020-09-22-slt-cdt-hpc-pres.md index 2617b9dd..f15c96e9 100644 --- a/_posts/2020-09-22-slt-cdt-hpc-pres.md +++ b/_posts/2020-09-22-slt-cdt-hpc-pres.md @@ -10,6 +10,7 @@ link: description: type: text social_image: /assets/images/cluster-diag-plain.svg +excerpt_separator: --- Two challenges PhD students encounter are: @@ -20,6 +21,8 @@ To help address the above for a particular case I spoke with a new cohort of PhD to explain what high-performance computing (HPC) is and why they might care. The hope is that they will now be able to include HPC in their training plans once they recognise problems that HPC might be well-suited to helping with. + + The talk covered: - Pros and cons of HPC vs personal laptops/desktops - Local HPC resources diff --git a/_posts/2020-12-07-reproducibility-resources.md b/_posts/2020-12-07-reproducibility-resources.md index c22514be..4d723341 100644 --- a/_posts/2020-12-07-reproducibility-resources.md +++ b/_posts/2020-12-07-reproducibility-resources.md @@ -9,11 +9,17 @@ category: link: description: type: text +excerpt_separator: --- +This blog post provides a copy of my recent talk at the Royal Microscopical Society's [Virtual Data Analysis in Atomic Force Microscopy Meeting](https://www.rms.org.uk/data-analysis-in-atomic-force-microscopy.html) ([Event Page](/events/talk-2020-12-10-afmanalysis)): How can we make AFM data analysis more open and reproducible? + +I've also put together what I hope will be some useful links: + + + -To go along with my talk at the Royal Microscopical Society's [Virtual Data Analysis in Atomic Force Microscopy Meeting](https://www.rms.org.uk/data-analysis-in-atomic-force-microscopy.html) ([Event Page](/events/talk-2020-12-10-afmanalysis)), I've put together what I hope will be some useful links: ## If you’re a researcher at the University of Sheffield... diff --git a/_posts/2021-01-25-datavis-cpp.md b/_posts/2021-01-25-datavis-cpp.md index 48eec5a0..243106d4 100644 --- a/_posts/2021-01-25-datavis-cpp.md +++ b/_posts/2021-01-25-datavis-cpp.md @@ -10,6 +10,7 @@ link: description: social_image: /assets/images/2021-01-25-datavis-cpp/image1.png type: text +excerpt_separator: --- *A guest post by [Seb James](https://www.sheffield.ac.uk/psychology/people/research/sebastian-james-0), Research Associate, Department of Psychology ([GitHub](https://github.com/sebjameswml); [Twitter](https://twitter.com/sebjames)).* @@ -18,6 +19,8 @@ type: text In this blog post I'm going to talk about data visualisation - making graphs - within C++ programs. I'll describe why you might want to do this and I'll try to justify why I've spent a sizeable part of my time over the last couple of years developing graphing code in C++, rather than using Python or R like everyone else! The code I'll discuss is available at [https://github.com/ABRG-Models/morphologica](https://github.com/ABRG-Models/morphologica). + + {% include image_caption.html url="/assets/images/2021-01-25-datavis-cpp/image0.png" description="A selection of visualisations made with morphologica. A: 2D graphs. B A: self-organising map simulation (orientation preference maps). C: Three dimensional quiver plot. D: gene driven reaction diffusion model. E: Debugging a large model."%} Most of the academic blog posts and videos about data visualisation that I see refer to scripted languages like Python, R or MATLAB. These languages have the ability to render high quality graphs and they provide convenient function calls to create standard graphs such as scatter plots and bar graphs, as well as more esoteric visualisations such as Sankey plots or Dendrograms (see the [d3 graph gallery](https://www.d3-graph-gallery.com/index.html) for lots of interesting examples). It's easy to generate output in a standard format like PNG or PDF and so if you’re visualising an existing dataset then one of these scripted languages – Python with [matplotlib](https://matplotlib.org/) or R with [ggplot2](https://www.r-graph-gallery.com/ggplot2-package.html) – is probably the best way to communicate information about the data to your audience. diff --git a/_posts/2021-01-25-secondment-opportunity.md b/_posts/2021-01-25-secondment-opportunity.md index 27fd4f66..1b244320 100644 --- a/_posts/2021-01-25-secondment-opportunity.md +++ b/_posts/2021-01-25-secondment-opportunity.md @@ -9,12 +9,15 @@ category: link: description: type: text +excerpt_separator: --- Are you currently working or studying at the University of Sheffield and interested in a secondment to the Research Software Engineering (RSE) team to develop sustainable research software? The RSE team has grown in the last couple of years but there is currently unprecedented demand for RSE support on research projects. We are urgently looking for someone to join our team of twelve on a short to medium term basis to work on one or two specific projects, the most significant being a role in the Scottish Covid Response Consortium ([https://scottishcovidresponse.github.io](https://scottishcovidresponse.github.io)). The main activities in that project include improving some modelling software, developing a data pipeline and an API, and integrating the modelling software within a framework. **Python** development experience, a working knowledge of version control with **git**/**GitHub** and of **software testing** are key; experience of developing/using **web services** and **databases** would also be useful. We want this secondment to be an opportunity for growth and we will support and mentor you in this role. + + This would be a great opportunity for someone who is considering a career in research software (or infrastructure/data) engineering and is wanting first-hand experience of how it might compare to a traditional research career. This placement would be suitable for staff already employed elsewhere within the university either on a research contract or on core funding (subject to agreement with your line manager). Similarly the post would be suitable for a PhD student in their final year looking for part time employment. See [https://rse.shef.ac.uk/](https://rse.shef.ac.uk/) for more about us and what we do. diff --git a/_posts/2021-02-04-GPU-course.md b/_posts/2021-02-04-GPU-course.md index 74135d78..a5977341 100644 --- a/_posts/2021-02-04-GPU-course.md +++ b/_posts/2021-02-04-GPU-course.md @@ -9,10 +9,13 @@ category: link: description: type: text +excerpt_separator: --- Starting Monday 7th Feb is a 12 week course on *Parallel Computing with GPUs*. The course has been designed as an undergraduate 4th year module for Computer Science but is available to staff and PhD Students (as part of the DDP program) and regularly has staff and PhD student enrollment. + + The first 3 weeks are focused on teaching C and OpenMP followed by GPU programming with CUDA C. Lectures are provided as pre-recorded mini lectures and there are 2 hours of scheduled support per week to undertake practical lab classes. Assessment is not required for DDP or staff participants. Virtual Remote machines will be provided with dedicated GPUs. If you are interested in enrolling as a PhD student then please do so via [DDP](https://www.sheffield.ac.uk/rs/ddpportal/reg). You will need to [contact the DDP team](https://www.sheffield.ac.uk/rs/ddpportal/enquiry) to enroll. diff --git a/_posts/2021-04-14-hidden-ref.md b/_posts/2021-04-14-hidden-ref.md new file mode 100644 index 00000000..6186afb9 --- /dev/null +++ b/_posts/2021-04-14-hidden-ref.md @@ -0,0 +1,26 @@ +--- +layout: post +title: "The Hidden REF" +author: David Wilby +slug: 2021-04-15-hidden-ref +date: 2021-04-15 12:00:00 UTC +tags: +category: +link: +description: +type: text +excerpt_separator: +--- + +The Research Excellence Framework (REF) is the UK government's scheme for assessing the quality of research in UK universities. Every few years, UK universities are asked to submit examples of their research for review, following an internal review process. In short, universities submit their best examples of: + * published articles, + * case studies of research impact, and + * data on doctoral degrees awarded and research income. + + + +Ultimately, the outcome of the REF dictates central government funding provided to Universities - which, as a result, are incentivised to place value predominantly on research activities and outputs which result in high quality rankings in the REF. (See an explanation of these competing demands here: https://hidden-ref.org/about/) + +To challenge preconceptions about what is important in research, the organisers of [*The Hidden REF*](https://hidden-ref.org/) aim to recognise all research outputs and roles within research that make it possible. The Hidden REF is a competition taking submissions in a broad set of [categories](https://hidden-ref.org/categories/) (many of which are community contributed) across the research spectrum, including but not limited to: hidden roles such as data stewards, librarians and *ahem* RSEs; citizen science; software; and research datasets. + +Submissions are in the form of 300 word nominations and the competition is open until 14th May 2021. Submissions will be judged by panels of experts drawn from the research community. diff --git a/_posts/2021-04-23-cherry-pick.md b/_posts/2021-04-23-cherry-pick.md new file mode 100644 index 00000000..2151bc56 --- /dev/null +++ b/_posts/2021-04-23-cherry-pick.md @@ -0,0 +1,19 @@ +--- +layout: post +title: "Using git cherry-pick to split up a branch (video)" +author: Robert (Bob) Turner +slug: 2021-04-23-cherry-pick +date: 2021-04-23 12:00:00 UTC +tags: +category: +link: +description: +type: text +excerpt_separator: +--- + +Software engineer / developer / coder / RSE? Ever find there's a branch with just too many commits to review effectively? RSE Sheffield's Bob Turner may have the answer! + + + + \ No newline at end of file diff --git a/_posts/2021-05-07-git-resources.md b/_posts/2021-05-07-git-resources.md new file mode 100644 index 00000000..ae0d50e5 --- /dev/null +++ b/_posts/2021-05-07-git-resources.md @@ -0,0 +1,96 @@ +--- +layout: post +slug: 2021-05-07-git-useful-resources +title: Git useful resources +author: Fariba Yousefi +date: 2021-05-07 09:00:00 UTC +category: +tags: support +type: text +excerpt_separator: +--- +In this blog post we will introduce Git and talk about some terminologies related to Git and version control in general. We will also introduce some resources that might be helpful to read or watch. + + + +If you are new to the Git world, you might hear some words that sound very similar and sometimes confusing. Below are a few definitions that might be useful; + +## What is the difference between **Git** and **GitHub**? +Git is a version control protocol and a tool that is effectively the reference implementation for interacting with repositories in that format. + +Git currently is the most popular distributed version control system. It allows you to have your own local repositories. You can work on your code without having access to the internet, for example, committing new versions, viewing logs and comparing versions. Git Graphical User Interfaces (**GitGUI**) such as GitHub Desktop, SourceTree, GitKraken are Git clients/tools. + +**GitHub**, **GitLab** and **Atlassian's BitBucket** are public hosting services for Git repositories with web interfaces and many common collaboration workflows for software projects depend on functionality provided by these services. +So they are not the same thing: Git is the tool, GitHub is the service for projects that use Git and it is built on top of Git. Git is installed locally while GitHub is hosted on a remote server e.g. in the cloud. + +**GitLab** is very similar to Github, however, it was initially designed with a built-in Continuous Integration (CI)/Continues Development (CD) tool. The Continuous Integration framework inside GitLab is ranked as one of the best tools out there, if not the best. + +Previously, to use CI/CD with a Github repository would require a 3rd party tool such as Jenkins, however GitHub has now introduced its own built in CI/CD called **Github Actions**. Github Actions enable users to quickly automate tests (CI), and deploy (CD) code. If you are interested, very thorough explanation can be found [here](https://blog.codegiant.io/gitlab-vs-github-which-one-is-better-2020-d8ec7fb9542c). + +Another distinction between GitHub and GitLab is that the software that runs on GitHub.com is not open source and it means that you can not have GitHub.com like services on your own infrastructure although GitHub enterprise offers a licence to deploy to your own servers, AWS, Azure or Google Cloud. However, GitLab is an open source project and you can install and run GitLab services on your own servers (only community edition is free). + +**GitHub Pages** is a static hosting service that auto-generates and commits HTML using Jekyll. Jekyll is a static site generator and GitHub Pages has built-in support for Jekyll. GitHub Pages can also directly take HTML, CSS and JavaScript files from a repositories on GitHub. More information can be found [here](https://docs.github.com/en/github/working-with-github-pages/about-github-pages#about-github-pages). + + +## **Related RSE blog posts** +* [Remote working with git and GitHub](https://rse.shef.ac.uk/blog/2020-03-29-git-github-remote/) +* [Git: rebase vs merge](https://rse.shef.ac.uk/blog/2020-06-23-git-rebase-vs-merge/) + +## **Web-based guides** +This website is a simple guide for getting started with Git and it has translations in a few other languages: +* [Git - the simple guide](https://rogerdudler.github.io/git-guide/) + +This website is also introductory, however it also has screenshots to ease understanding: +* [Hello world](https://guides.github.com/activities/hello-world/) + +This website is from the the GitHub training team, it provides an introduction to both Git and Github Pages: +* [The GitHub training team](https://lab.github.com/githubtraining/introduction-to-github) + +This website covers many common git topics which it categorises by experience level, from beginners to advanced: +* [Git ready](http://gitready.com/) + +This website explores how Git commands affect the structure of a repository. You can try commands from your browser: +* [Resources to learn Git](http://try.github.io/) + +This website is for Advanced beginners with Git. You should know how to create a repository, add and commit files to it, and you should probably have some idea of why you might want to use a branch: +* [Git shouldn't be so hard to learn](http://think-like-a-git.net/) + +This website is specifically designed for Computer Scientists and is using terms that they are familiar with: +* [Git for computer scientists](https://eagain.net/articles/git-for-computer-scientists/) + +## **Free books** +This book has 522 pages and it has everything you need to know about Git: +* [Pro Git book](http://git-scm.com/book/en/v2) + +This book is 31 pages and it has a bottom up approach rather than looking at it only in terms of high-level commands: +* [Git from the bottom up](http://ftp.newartisans.com/pub/git.from.bottom.up.pdf) + +This book is 44 pages and provides many Git command examples for common tasks, rather than focusing on the technical details of git commands: +* [Git magic](http://www-cs-students.stanford.edu/~blynn/gitmagic/) + +## **Zines** +This zine contains a list of issues people commonly encounter when using Git along with concise ways of addressing them: +* [Oh shit, git](https://jvns.ca/blog/2018/10/27/new-zine--oh-shit--git-/) + +## **Videos** +This video is an introduction to Git for beginners. You will learn Git and all the Git commands to create repositories on your local machine & GitHub, commit changes, push & pull files. Also you will get your hands on with some advanced operations in Git like branching, merging, rebasing. It is a long video at 1 hour and 44 minutes: +* [Git tutorial](https://www.youtube.com/watch?v=xuB1Id2Wxak&ab_channel=edureka%21) + +This video is Git & GitHub crash course for beginners and is about 30 minutes: +* [Git & GitHub crash course for beginners](https://www.youtube.com/watch?v=SWYqp7iY_Tc&ab_channel=TraversyMedia) + +This is a very long video and it is a complete Git and GitHub Tutorial for beginners: +* [Git and GitHub tutorial for beginners - 11 hours](https://www.youtube.com/watch?v=3FKrszHcIsA&ab_channel=BogdanStashchuk) + +This video is from the creator of the distributed version control system Git: +* [Tech Talk: Linus Torvalds on git](https://www.youtube.com/watch?v=4XpnKHJAok8&ab_channel=Google) + +This video is for more advanced users. They introduce the obscure commands that will reveal a sort of internal API that is there for you to use: +* [Git from the bits up](https://www.youtube.com/watch?v=MYP56QJpDr4&ab_channel=InfoQ) + +This video is advanced Git and covers graphs, hashes and compression: +* [Advanced Git: graphs, hashes, and compression](https://www.youtube.com/watch?v=ig5E8CcdM9g&ab_channel=InfoQ) + +## **Cheat sheets** +This cheat sheet contains common tasks: +* [Git cheat sheet](https://education.github.com/git-cheat-sheet-education.pdf) diff --git a/_posts/2021-05-25-RSE-methods-talk.md b/_posts/2021-05-25-RSE-methods-talk.md new file mode 100644 index 00000000..17fa2167 --- /dev/null +++ b/_posts/2021-05-25-RSE-methods-talk.md @@ -0,0 +1,23 @@ +--- +layout: post +title: "Methods in Research Software Engineering for Undergraduates (video)" +author: David Wilby +slug: 2021-05-25-methods-ug-talk +date: 2021-05-25 12:00:00 UTC +tags: +category: +link: +description: +type: text +excerpt_separator: +--- + +The team was recently asked to speak to a first year undergraduate Computer Science course with a view to introducing students to concepts in research software engineering, including some which they might use in their upcoming projects. The talk recording is embedded below, it starts at the beginning of the video and ends at roughly 55 mins. Alternatively, [watch on The University of Sheffield digital media platform](https://digitalmedia.sheffield.ac.uk/media/Methods%20in%20Research%20Software%20Engineering%20%20-%20Dr%20David%20Wilby/1_3dtqe94z). + + + +The slides from the talk are built by the code in [this repository](https://github.com/davidwilby/ResearchSoftwareMethods/tree/DCS_May_2021) - which *hopefully* also demonstrates many of the principles of good practice from the talk itself. + +They're also [available as a PDF](https://github.com/davidwilby/ResearchSoftwareMethods/releases/download/DCS_May_2021/presentation.pdf). + + \ No newline at end of file diff --git a/_posts/2021-06-18-ml-intro-vid.md b/_posts/2021-06-18-ml-intro-vid.md new file mode 100644 index 00000000..e4bc947b --- /dev/null +++ b/_posts/2021-06-18-ml-intro-vid.md @@ -0,0 +1,21 @@ +--- +layout: post +title: "Short Video: Machine Learning in the RSE Team" +author: Robert (Bob) Turner +slug: 2021-06-18-ml-intro-vid +date: 2021-06-18 10:00:00 UTC +tags: +category: +link: +description: +type: text +excerpt_separator: +--- + + + +A brief intro to where Machine Learning fits into the work of the University of Sheffield RSE team. + +See some examples of [Machine Learning projects](/service/projects/#machine-learning) and training [Introduction to Deep Learning](/pages/training/courses/Intro_DL.html), [Fundamentals of Deep Learning for Computer Vision Workshop](/training/deeplearning/2019-02-15-dli-sheffield/). \ No newline at end of file diff --git a/_posts/2021-07-16-hiring-srse.md b/_posts/2021-07-16-hiring-srse.md new file mode 100644 index 00000000..c11baedc --- /dev/null +++ b/_posts/2021-07-16-hiring-srse.md @@ -0,0 +1,62 @@ +--- +layout: post +title: "We're hiring - Senior Research Software Engineer" +author: RSE Team +slug: 2021-07-16-hiring-srse +date: 2021-07-16 10:00:00 UTC +tags: +category: +link: +description: +type: text +excerpt_separator: +--- + +Are you interested in leading a team to develop and facilitate reproducible software through collaborations across the whole +spectrum of university research areas? + + + +An opening is available to join the growing Research Software Engineering (RSE) group as a senior RSE on an open ended +contract. The role is ideal for someone with a passion for research software looking to lead a team to drive collaborative +software development and reproducible research to make an impact on research projects across the whole of the University +of Sheffield. + +We are looking for applicants who are highly passionate about reproducible research through development of robust +software and are committed to advocating software best practice through engagement with the academic community. A key +responsibility of the role will be to advocate the RSE group within the academic community to strengthen the provision of +RSE support including collaborative working and facilitation of training. Applicants should have extensive experience of +collaborative software development and an appreciation of how to work with academics and researchers to specify, develop, +improve and deliver research software. You will work within and provide management with in the existing RSE team to +deliver services across a range of research projects, departments and institutes across the university, as well as free at the +point of use support to assist in the development of new strategic collaborations. + +You will enhance the university’s capability and expertise in developing research software as part of academic research and +will collaborate closely with IT services and the RSE steering panel to ensure the RSE group delivers services which +implement aspects of the university’s overarching Research IT strategy. The RSE team in Sheffield is led by an EPSRC +Research Software Engineering Fellow and is guided by a steering panel of senior university staff who are committed to +supporting the role of RSEs within the research community. This leadership role offers the opportunity to contribute +towards the direction and growth of the group. + +The post provides an excellent opportunity for research software skills development. You will actively support the wider +community of research software developers and will be encouraged to represent the group in national/international +activities. E.g. Current team members hold positions and qualifications including; RSE conference organisation committee, +rOpenSci Editor, NVIDIA Deep Learning Institute accredited trainers, ARCHER champions and Software Carpentry Trainers. +Educated to PhD level (equivalent experience or be close to completion), you will have a proven track record of reproducible +software development and effective line management. Applications are welcome from both software development +generalists and from RSEs with inter-disciplinary technology focused skills which either complement or extend our existing +portfolio. E.g. data analytics (including statistical computing, machine learning and deep learning), numerical computing, HPC +(including multi-core and GPUs), etc. + +We are committed to exploring flexible working opportunities which benefit the individual and University. +We’re one of the best not-for-profit organisations to work for in the UK. The University’s Total Reward Package includes a +competitive salary, a generous Pension Scheme and annual leave entitlement, as well as access to a range of learning and +development courses to support your personal and professional development. +We build teams of people from different heritages and lifestyles from across the world, whose talent and contributions +complement each other to greatest effect. We believe diversity in all its forms delivers greater impact through research, +teaching and student experience. + +To find out what makes the University of Sheffield a remarkable place to work, watch this short film: +, and follow [@sheffielduni](https://twitter.com/sheffielduni) and [@ShefUniJobs](https://twitter.com/shefunijobs) on Twitter for more information. + +**[Apply here](https://jobs.shef.ac.uk/sap/bc/webdynpro/sap/hrrcf_a_posting_apply?PARAM=cG9zdF9pbnN0X2d1aWQ9NjBFRTI0NEE3RTY5Mzg4MkUxMDAwMDAwQUMxRTg4NzgmY2FuZF90eXBlPUVYVA%3d%3d&sap-client=400&sap-language=EN&sap-accessibility=X&sap-ep-themeroot=%2fSAP%2fPUBLIC%2fBC%2fUR%2fuos#)** \ No newline at end of file diff --git a/_posts/2021-09-10-bob-septrse.md b/_posts/2021-09-10-bob-septrse.md new file mode 100644 index 00000000..b2b2b242 --- /dev/null +++ b/_posts/2021-09-10-bob-septrse.md @@ -0,0 +1,28 @@ +--- +layout: post +title: "SeptembRSE - University of Sheffield Research Software Survey (2020)" +author: Bob +slug: 2021-09-10-bob-septrse +date: 2021-09-10 10:00:00 UTC +tags: +category: +link: +description: +type: text +excerpt_separator: +--- + +**Bob Turner** from the RSE Team gave a talk at [SeptembRSE](https://septembrse.github.io/#/session/N16)! Video is now available... + +Software is an important part of research and a key research output. We conducted a survey at the University of Sheffield in October 2020, similar to previous surveys conducted nationally and at the University of Southampton, to find out about how software was being used in research. + + + +Our preliminary results indicate that, of 382 respondents, 92% used research software and 65% reported that it was essential to their research. We found 69% of respondents (who responded to the specific question) did not feel they had sufficient training to develop reliable software. We found that while 45% of respondents involved in writing funding applications expected to write software, 40% of these did not request funding for this. + +This indicates that there is a need to investigate why respondents feel that they lack training and are not costing software development on funding applications as much as they might. It likely means that a greater availability of training and better communication of the role of the RSE team are needed. + +Here, we will report our major findings and our recommendations for the future based on these. We will explain our research methods (and make suggestions for improvements) and how we have used Python-based tools to analyse the data. + + + diff --git a/_posts/2021-11-12-rse-roles.md b/_posts/2021-11-12-rse-roles.md new file mode 100644 index 00000000..1531eccf --- /dev/null +++ b/_posts/2021-11-12-rse-roles.md @@ -0,0 +1,38 @@ +--- +layout: post +title: "We're hiring - A fixed term and open-ended Research Software Engineer" +author: RSE Team +slug: 2021-11-12-rse-roles +date: 2021-11-12 16:30:00 UTC +tags: +category: +link: +description: +type: text +--- + +Are you interested in joining a team to develop and facilitate reproducible software through collaborations across the whole spectrum of university research areas? + +There are openings available to join the growing Research Software Engineering (RSE) team on an open-ended contract or fixed term contract. The RSE role is ideal for someone with a passion for research and for good software engineering looking to use their skills in collaborative software development and reproducible research to make an impact on research projects across the whole of the University of Sheffield and beyond. + +A key responsibility of the role will be embedding software engineering skills through collaboration and training/teaching. Applicants should have experience of collaborating with key stakeholders/clients to specify, develop, improve and deliver technical software and the ability to undertake such collaborations in a research environment. You will work within the existing RSE team across a range of research projects, departments, and institutes within the university, as well as advocating good practice, providing free at the point of use support and assisting in the development of new strategic collaborations. + +Educated to PhD level (close to completion, or equivalent experience), you will have a track record of high-quality software development (using a research relevant language such as R, Python, MATLAB, C, C++) and a commitment to open, reproducible research. Applications are welcome from both software development generalists and from RSEs with inter-disciplinary technology focused skills which either complement or extend our existing portfolio, such as data analytics (including statistical computing, machine learning and deep learning), numerical computing, High-Performance Computing (HPC; including multi-core and GPUs), etc. + +You will enhance the university’s capability and expertise in developing research software as part of academic research and will collaborate closely with IT Services to ensure the delivery of RSE team aspects of the university’s overarching Research IT strategy. The RSE team of 13 at the University of Sheffield is led by a former EPSRC Research Software Engineering Fellow and is guided by a steering panel of senior university staff who are committed to supporting the role of RSEs within the research community. + +The post provides an excellent opportunity for research software skills development. You will actively support the wider research community and will be encouraged to represent the team in national/international activities. For example, current team members hold positions and qualifications including: membership of the Society of RSE, rOpenSci Editor, reviewers for JOSS, NVIDIA Deep Learning Institute accredited trainers, and Software Carpentries maintainers. + +We are committed to exploring flexible working opportunities which benefit the individual and University. + +We’re one of the best not-for-profit organisations to work for in the UK. The University’s Total Reward Package includes a competitive salary, a generous Pension Scheme and annual leave entitlement, as well as access to a range of learning and development courses to support your personal and professional development. + +We build teams of people from different heritages and lifestyles from across the world, whose talent and contributions complement each other to greatest effect. We believe diversity in all its forms delivers greater impact through research, teaching and student experience. + +To find out what makes the University of Sheffield a remarkable place to work, watch this short film: www.youtube.com/watch?v=7LblLk18zmo, and follow @sheffielduni and @ShefUniJobs on Twitter for more information. + +Note: There is both an open-ended and fixed term role available with the intention to extend the fixed term role in the future. + +**[Apply for the open-ended role here](https://jobs.shef.ac.uk/sap/bc/erecruiting/posting_apply?param=cG9zdF9pbnN0X2d1aWQ9NjE4NThFRkE3RkRFMTBGM0UxMDAwMDAwQUMxRTg4NzgmY2FuZF90eXBlPSZwb3N0aW5nX3RleHQ9eWVz&sap-client=400&sap-language=EN)** + +**[Apply for the fixed term role here](https://jobs.shef.ac.uk/sap/bc/erecruiting/posting_apply?param=cG9zdF9pbnN0X2d1aWQ9NjE4OUE3RUIwNTVBNjFBQkUxMDAwMDAwQUMxRTg4NzgmY2FuZF90eXBlPSZwb3N0aW5nX3RleHQ9eWVz&sap-client=400&sap-language=EN)** diff --git a/_posts/2022-03-29-rse-r.md b/_posts/2022-03-29-rse-r.md new file mode 100644 index 00000000..aa4eff8c --- /dev/null +++ b/_posts/2022-03-29-rse-r.md @@ -0,0 +1,16 @@ +--- +layout: post +title: "We're hiring - Research Software Engineer, R skills, open ended" +author: RSE Team +slug: 2022-03-29-rse-role-r +date: 2022-03-29 09:30:00 UTC +tags: +category: +link: +description: +type: text +--- + +Due to team member relocating to another country (😥) we have an RSE role in the team at the University of Sheffield. It is role where we are specifically looking to recruit someone with skills in R. + +[More information and application form.](https://www.jobs.ac.uk/job/COK027/research-software-engineer) diff --git a/_posts/2022-04-19-linting.md b/_posts/2022-04-19-linting.md new file mode 100644 index 00000000..7a6f2f1a --- /dev/null +++ b/_posts/2022-04-19-linting.md @@ -0,0 +1,425 @@ +--- +layout: post +title: "Linting - What is all the fluff about?" +author: Neil Shephard +slug: 2022-04-19-linting +date: 2022-04-19 12:00:00 UTC +tags: python linting +category: +link: +description: +social_image: /assets/images/open_sign.jpg +type: text +excerpt_separator: +--- + + +If you've been dabbling in programming for a while you may have heard of "linting your code" which is a process of +static code analysis to remove the "fluff" from your code. Just as physically linting your clothes removes unwanted +fluff, linting your code removes "fluff" and can help... + +- Reduce bugs. +- Improve performance. +- Mitigate against some security flaws. +- Improve coding skills. +- Consistent coding style. + +This helps reduce the [technical debt](https://en.wikipedia.org/wiki/Technical_debt) which impacts the amount of +time required for maintenance and further development of a code base. The main focus of this article is the use of +linting to ensure consistent coding style, it focuses on Python under Linux but similar tools are available for other +operating systems and languages. + + + +## Style Matters + +What has style got to do with writing code? Trends come and go in fashion but coding styles are meant to be relatively +static and not change with the season, although they can and do evolve over time. This is because using a consistent and +widely used style when writing code makes it easier for other people, often your future self, to read and understand the +code you have written. If code is easier to understand then its easier to modify, update, extend, improve and in general +maintain. + +A useful insight from [Gudio van Rossum](https://en.wikipedia.org/wiki/Guido_van_Rossum), the creator of +[Python](https://www.python.org) is that "[_code is read much more often than it is +written_](https://peps.python.org/pep-0008/#a-foolish-consistency-is-the-hobgoblin-of-little-minds)" and so it should +be easy to understand and not obfuscate its intent. Python is quite good for this as it is an expressive language which +encourages coders to be explicit when naming variables, functions, classes and so forth so that their purpose +and intention is clear, although the same is true of most modern languages. However, going a step further and using +consistent styles to format and layout code helps enhance this. + + +## Linting in Python + +The most widely used Python style is defined in the long established [PEP 8: The Style Guide for Python +Code](https://pep8.org/). There are a number of tools available that will lint your Python code for you and +most integrate with your IDE, whether that is [Visual Studio Code](https://code.visualstudio.com/), +[PyCharm](https://www.jetbrains.com/pycharm/) or [Emacs](https://www.gnu.org/software/emacs/). Some of the formatting +and linting tools available for Python are... + +- [Pylint](https://pylint.pycqa.org/en/latest/index.html) - checks for errors in Python code, tries to enforce a + coding standard and looks for code smells. + +- [YAPF](https://pypi.org/project/yapf/) - takes the code and reformats it to the best formatting that conforms to the style + guide. + +- [Black](https://github.com/psf/black) - The Uncompromising Code Formatter + +- [Flake8](https://flake8.pycqa.org/en/latest/) - Your Tool For Style Guide Enforcement + +- [Prospector](https://prospector.landscape.io/en/master/index.html) - Python Static Analysis + +- [mypy](http://mypy-lang.org/) - Optional Static Typing for Python + +Here we will work through linting and formatting the simple file below (available as a download +[here](/assets/python/save_random_numbers.py)) using PyLint and Black. + +```python +import numpy as np +from pathlib import Path +from typing import Union +import csv + +def save_random_numbers(size: int, seed: int = 87653546, save_as: Union[str, Path] = "./random_numbers.txt") -> None: + """Save a list of random numbers (floats) to the given file. + + The stated number of random numbers will be saved to the given target file, if the directory structure + doesn't exist it will be created. Output will by default be over-written. + Parameters + ---------- + size : int + Number of random numbers to generate + seed: int + Seed for random number generation + save_as : Union[str, Path] + Directory/file to save numbers to. + """ + rng = np.random.default_rng() + random_numbers = rng.random(size) + + with Path(save_as).open('w') as out: + writer = csv.write(out) + writer.writerows(random_numbers) +``` + +### Linting with PyLint + +We will lint this file using [Pylint](https://pylint.pycqa.org/en/latest/index.html) to find out what errors there are +and how its style can be improved to conform with PEP8 guidelines. + +First you need to install `pylint`, typically in your [virtual +environment](https://realpython.com/python-virtual-environments-a-primer/). + +```bash +pip install pylint +``` + +Pylint can be configured using a `~/.pylintrc` file in your home directory and over time this will grow as you customise your +configuration but for now we will make one simple change from the default which is to increase the accepted line +length. Create the file and save it with the following content. + +```bash +[FORMAT] +## Maximum number of characters on a single line. +max-line-length=120 +``` + +Open a terminal and navigate to the location you saved the example file `save_random_numbers.py` activate the virtual +environment you installed pylint under if its not already being used and then type the following to run Pylint against +your code... + +```bash +pylint save_random_numbers.py +``` + +You should see output similar to the following... + +```bash + ❱ pylint save_random_numbers.py +************* Module save_random_numbers +save_random_numbers.py:1:0: C0114: Missing module docstring (missing-module-docstring) +save_random_numbers.py:5:66: E0602: Undefined variable 'Union' (undefined-variable) +save_random_numbers.py:5:35: W0613: Unused argument 'seed' (unused-argument) +save_random_numbers.py:2:0: C0411: standard import "from pathlib import Path" should be placed before "import numpy as np" (wrong-import-order) +save_random_numbers.py:3:0: C0411: standard import "import csv" should be placed before "import numpy as np" (wrong-import-order) + +------------------------------------------------------------------- +Your code has been rated at 0.00/10 +``` + +The output tells us which module has been inspected on the first line. Each subsequent line indicates + +* The file. +* The line the problem has been encountered on. +* The column. +* A somewhat cryptic error code and then a message about the problem +* A more descriptive generic message associated with the error code. + +At the moment we are only looking at one file, but when using PyLint against larger code bases this information is vital +in helping direct you to the location of code that needs changing. At the end PyLint rates your code, ideally you should aim to get a score of `10.0/10`. + +The messages are quite informative, taking each in turn we can work through resolving them. + +#### `Missing module docstring (missing-module-docstring)` + +Each Python module should have a docstring as the very first line that describes what it does. In this example it might +be considered superflous but its good practice to get in the habit of writing these as it comes in useful when +documentation is automatically generated from the docstrings in the code. To fix it we can add a short docstring at the top. + +```python +"""Module for saving randomly generated numbers.""" +import numpy as np +from pathlib import Path +``` + +#### `Undefined variable 'Union' (undefined-variable)` + +This error arises because the [type hint](https://www.pythontutorial.net/python-basics/python-type-hints/) +uses `Union` but it hasn't been imported. It's from the +[typing](https://www.pythontutorial.net/python-basics/python-type-hints/) module so we can import it. + +```python +"""Module for saving randomly generated numbers.""" +import numpy as np +from pathlib import Path +from typing import Union +``` + +#### `Unused argument 'seed' (unused-argument)` + +This is very useful to be informed about because the `seed` argument, according to the docstring, is meant to be used in +the call to the random number generator and ensures we will get the same set of random numbers generated each time we +call the function with that seed, however, as Pylint has informed us we haven't actually used it within the +`save_random_number()` function. We can correct that by adding it when we instantiate the random number generator. + +```python +rng = np.random.default_rng(seed=seed) +``` + +#### `standard import "from pathlib import Path" should be placed before "import numpy as np" (wrong-import-order)` + +This message, like the one that follows it, is telling us that the order in which we have imported modules is incorrect, +because the PEP8 guide recommends that core modules, which both `csv` and `pathlib` are, should be imported before other +modules. We can correct this by changing the order (and because we have added an import from the `typing` module which +is also a core module we move that too). + +```python +"""Module for saving randomly generated numbers.""" +import csv +from pathlib import Path +from typing import Union + +import numpy as np +``` + +Once corrected your file should look like this... + +```python +"""Module for saving randomly generated numbers.""" +import csv +from pathlib import Path +from typing import Union +import numpy as np + +def save_random_numbers(size: int, seed: int = 87653546, save_as: Union[str, Path] = "./random_numbers.txt") -> None: + """Save a list of random numbers (floats) to the given file. + + The stated number of random numbers will be saved to the given target file, if the directory structure + doesn't exist it will be created. Output will by default be over-written. + + Parameters + ---------- + size : int + Number of random numbers to generate + seed: int + Seed for random number generation + save_as : Union[str, Path] + Directory/file to save numbers to. + """ + rng = np.random.default_rng(seed) + random_numbers = rng.random(size) + + with Path(save_as).open('w') as out: + writer = csv.write(out) + writer.writerows(random_numbers) +``` + +...and you can now run PyLint against it to see if you've improved your score. + +```bash + ❱ pylint save_random_numbers.py +************* Module save_random_numbers +save_random_numbers.py:7:66: E1136: Value 'Union' is unsubscriptable (unsubscriptable-object) + +------------------------------------------------------------------ +Your code has been rated at 5.00/10 (previous run: 4.00/10, +1.00) +``` + +That is an improvement in score (of `+1.00`) but we now have another error telling us that `E1136: Value 'Union' is +unsubscriptable (unsubscriptable-object)`. You are unlikely to know what all the error codes mean, but there are a +few handy on-line lists [all PyLint codes](http://pylint-messages.wikidot.com/all-codes) or [all PyLint +messages](http://pylint-messages.wikidot.com/all-messages) and what they are telling you are worth consulting ([The +Little Book of Python Anti-Patterns](https://docs.quantifiedcode.com/python-anti-patterns/index.html) is also +useful). In this instance PyLint has returned a false-positive because `Union` can and should be subscripted here +because it means the argument can be either a string (`str`) or a +[pathlib](https://docs.python.org/3/library/pathlib.html) Path (`Path`). So how do we get around this complaint? + +You can disable PyLint from complaining about specific error codes/messages on a per-file basis by adding a line that +disables them. You can use either codes or messages (the bit in the brackets at the end of the line, in this case +`unsubscriptable-object`) and it is advisable to use the message form as it is more informative to those who read your +code subequently. + +If we add the following line it prevents PyLint from reporting the specific error... + +```python +import numpy as np + +# pylint: disable=unsubscriptable-object + +def save_random_numbers(size: int, seed: int = 87653546, save_as: Union[str, Path] = "./random_numbers.txt") -> None: +``` + +...running PyLint against our code again we get a much better score. + +```bash + ❱ pylint save_random_numbers_tidy.py + +------------------------------------------------------------------- +Your code has been rated at 10.00/10 (previous run: 5.00/10, +5.00) +``` + +### Configuring PyLint + +The last error we encountered is something that is likely to crop up again if you use Typehints liberally throughout +your Python code (and I would encourage you to do so). Rather than having to remember to disable the error in each +file/module we create we can configure PyLint via its configuration file `~/.pylintrc` to always ignore this error. To +do so add the following... + +```bash +[MESSAGES CONTROL] +# Disable the message, report, category or checker with the given id(s). You +# can either give multiple identifiers separated by comma (,) or put this +# option multiple times (only on the command line, not in the configuration +# file where it should appear only once). +disable=unsubscriptable-object +``` + +For more on configuriong PyLint refer to the [documentation](https://pylint.pycqa.org/en/latest/user_guide/options.html) +and also details of how to [integrate with your editor and +IDE](https://pylint.pycqa.org/en/latest/user_guide/ide-integration.html) + + +### Automated Formatting with Black + +[Black](https://github.com/psf/black) is *The Uncompromising Code Formatter* and is very strict about the way in which +it formats code. This could be a good or bad thing depending on your point of view, but it does result in highly +consistent code when applied to all files. It formats files in place, so be mindful of this if you run it against one of +your files it *will* change it. + +Install `black` in your virtual environment and make a backup of your `save_random_number.py` file that you have just +tidied up with linting. + +```bash +pip install black +cp save_random_numbers.py tidy_save_random_numbers.py +``` + +To run black against your code pass it the input file, it will re-write it and you can then compare it against the +backup you just made... + +```bash +black save_random_numbers.py +❱ diff save_random_numbers.py tidy_save_random_numbers.py +5,8c5 +< +< def save_random_numbers( + < size: int, seed: int = 87653546, save_as: Union[str, Path] = "./random_numbers.txt" + < ) -> None: +--- +> def save_random_numbers(size: int, seed: int = 87653546, save_as: Union[str, Path] = "./random_numbers.txt") -> None: +27c24 +< with Path(save_as).open("w") as out: +--- +> with Path(save_as).open('w') as out: +``` + +In this instance Black hasn't changed much but it has reformatted the `def save~randomnumbers~(...)` line and moved the +`with Path()` line as a consequence. + +## When to Lint + +It is worth linting your code from the outset of a project as not only does it result in a consistent style across +your code base it also avoids the problem that can arise when applying linting retrospectively. If an existing code base +has linting applied then the [`git blame`](https://www.git-scm.com/docs/git-blame), which indicates who the last person +to edit a section was, then resides with the person who applied the linting, rather than the original author of the +code. Its possible though that the person who applied the linting knows very little about the underlying functionality +of the code but they may receive questions about it if they are indicated as the last person to have modified particular +lines. + +Fortunately there are a number of ways to automate and integrate linting into your workflow. + +## Automating Linting + +### IDE Integration + +When programming it is really useful to use an [Integrated Development Environment +(IDE)](https://en.wikipedia.org/wiki/Integrated_development_environment) as most allow the integration of linting tools +and apply them to your code automatically, whether its using PyLint, YAPF, Black or otherwise. Setup and configuration +is beyond the scope of this article but some links are provided to useful resources to get you started. + +### VSCode + +VSCode supports linting in most languages, and both [Python](https://code.visualstudio.com/docs/python/linting) and +[R](https://docs.microsoft.com/en-us/visualstudio/rtvs/linting-r-code?view=vs-2017) are supported along with other +languages. + + +### PyCharm + +PyCharm supports automated formatting of code, for more information please refer to [Reformat and rearrange code \| +PyCharm](https://www.jetbrains.com/help/pycharm/reformat-and-rearrange-code.html). + +### Emacs + +There are various options available for linting within Emacs, which you use depends on your preferences but [LSP +mode](https://emacs-lsp.github.io/lsp-mode/) integrates with YAPF (via [yapfify](https://github.com/JorisE/yapfify)), +Flake8 (via [flycheck](https://www.flycheck.org/en/latest/)) and Black (via +[blacken](https://github.com/pythonic-emacs/blacken)). + +## Git Integration + +If you are using an IDE then if configured correctly your code should be linted automatically for you, but an additional +step that can capture anything that hasn't been correctly formatted is to use a [git hook](https://githooks.com/) to +run linting on your code prior to making commits. There is +[git-pylint-commit-hook](https://github.com/sebdah/git-pylint-commit-hook) available on PyPi which runs automatically +when you make commits to `.py` files. + +## Continuous Integration + +Including a linting stage in your Continuous Integration (CI) pipeline pays dividends as we all make mistakes and +sometimes forget to lint our code before making pushes. + +## Megalinter + +Perhaps not necessary for everyone but worth mentioning the beast that is +[MegaLinter](https://megalinter.github.io/latest/) which will lint code across multiple languages and integrates easily +into your pipeline (GitHub Action, CI on GitLab, Jenkins etc.). A useful article on doing so is +[Limit your technical debt and secure your code base using +MegaLinter](https://nicolas.vuillamy.fr/improve-uniformize-and-secure-your-code-base-with-megalinter-62ebab422c1). + +## Links + +### Python + +- [Flake8](https://flake8.pycqa.org/en/latest/) - Your Tool For Style Guide Enforcement +- [Black](https://github.com/psf/black) - The Uncompromising Code Formatter +- [Linting Python in Visual Studio Code](https://code.visualstudio.com/docs/python/linting) +- [Pylint - Overview of all Pylint messages](https://pylint.pycqa.org/en/latest/messages/messages_list.html) + +### R + +- [GitHub - r-lib/lintr: Static Code Analysis for R](https://github.com/r-lib/lintr) +- [Introduction to R: Linting R (and R Markdown)](https://rowannicholls.github.io/R/intro/linting.html) + +### C++ + +- [cpplint](https://github.com/cpplint/cpplint) diff --git a/_posts/2022-05-05-reproducible-matlab.md b/_posts/2022-05-05-reproducible-matlab.md new file mode 100644 index 00000000..20ddf684 --- /dev/null +++ b/_posts/2022-05-05-reproducible-matlab.md @@ -0,0 +1,319 @@ +--- +layout: post +title: "A concise guide to reproducible MATLAB projects" +author: David Wilby +slug: 2022-05-05-concise-guide-to-reproducible-matlab +date: 2022-05-05 10:00:00 UTC +tags: matlab, reproducibility, version control, git +category: +link: +description: +type: text +excerpt_separator: +--- + +In research, it is of utmost importance to the scientific process to be able to reproduce research findings in order to establish their validity. However, more often than not, the code that is written for research purposes cannot be easily run again, sometimes even by the code's authour (yours truly included!). + +This year, I've been awarded a fellowship by the [Software Sustainability Institute](https://software.ac.uk/) to develop guidance and training to help researchers who use MATLAB to find and learn the tools that they need to easily produce better research by making their code reproducible. + +During my PhD and postdoctoral research, I used MATLAB, among other languages, to analyse data, run simulations, make figures and control instrumentation. However, at the time, I didn't know about the concepts required to make my code reproducible for myself and others. Over the last few years, as a Research Software Engineer, I've gained the experience needed to develop reproducible software in a range of languages including MATLAB. Now it's time to share what I've learned with everyone! + +This blog post should serve as a _very_ brief set of signposts to some of the concepts you can use to develop a reproducible project in MATLAB. You can expect more to come throughout my fellowship, so watch this space. + + + +## What is reproducibility? +{:.no_toc} +When performing some research via any method, the most basic expectation is that the results should be able to be validated somehow, otherwise how can they be trusted? The most basic version of this is that by following the same methods of the researchers who originally performed a piece of work, you should be able to get to the same conclusions. This is essentially the concept of reproducibility, research should be able to be reproduced in order to validate its conclusions. + +When it comes to research code, it should be relatively easy to reproduce, right? There are no complicated _experiments_ to run again, or data to collect, so it should be a given, shouldn't it? + +In practice, we find that exact versions of software dependencies or the toolboxes required are not documented alongside a project, or it isn't even clear how to get the right data into the software or run the code at all. This means that even with the original code available to you, it might not be possible to run the code, or _worse_, it could produce incorrect results. + +The goal of crafting a reproducible software project should be to produce a compendium of code, data and documentation that anyone should be able to pick up and run, generating the same results that you did initially. Reproducible software development practices are also just good practice in general, if you've followed good practice in the first place, when you come back to a project in several months' or years' time (or just on Monday morning), you should be able to make improvements, re-run the code or validate your results. + +## How to write reproducible MATLAB? +{:.no_toc} +Here are some tools and concepts you can use to improve the reproducibility of your MATLAB project. Many are the same concepts you'll find recommended for most research software (and most _software_) projects, with some specific guidance on how to implement these in MATLAB. + +## Contents +{:.no_toc} + +* TOC +{:toc} + +### Coding style +Writing code that is readable should be your very first port of call for reproducibility. Not just for your colleagues and collaborators, but for yourself. + +In brief, you should: +1. Include comments that explain what your code is doing, +1. Use self-explanatory variable, function and class names, +1. Write modular code. Each function, for instance, should just do one job and be reusable at other places in your code, +1. Avoid duplication. Write the code that does one job just once and write a function that you can call. + +A useful online resource for MATLAB coding style is the [MATLAB Programming Style Guide][style-guide], based on Richard Johnson's book, [The Elements of MATLAB style](https://www.google.co.uk/books/edition/The_Elements_of_MATLAB_Style/awORkNlgiZoC?hl=en&gbpv=1&printsec=frontcover), also available [on MATLAB's FileExchange](https://uk.mathworks.com/matlabcentral/fileexchange/46056-matlab-style-guidelines-2-0). Why not have a skim through this succinct resource before starting your next project? + +### Project organisation +The first thing that makes a project difficult to reproduce is when you open the project folder to find a big heap of confusingly named scripts. + +Use folders/directories to organise your project, so that it is obvious (to you and anyone else who uses your code) where to find what is needed. + +At the very top level of your project, why not have something like the following structure? + +``` +├── data/ # directory to contain your data +│ └── raw/ # all your raw, unprocessed data +│ └── processed/ # any data that you have altered +├── figures/ # keep the figures that you produce from your code here +├── reports/ # a clear folder for your papers or reports for the project +├── src/ # source code +│ └── @MyClass/ # a class directory +│ └── a_module/ # a directory containing a group of functions or classes with some commonality +│ └── utils/ # a directory containing utility functions +├── docs/ # documentation +├── tests/ # software tests for the project +├── README # readme file! (essential) +└── my.prj # MATLAB project file (read on for more details) +``` + +For more in depth guidance on how to organise a project (and loads of other excellent advice) check out the [BES' guide to Reproducible Code][bes-guide] - I still refer to this guide regularly. + +### Documentation +Your users (_**that includes you**_) will thank you when they encounter some actual guidance on how to use your code - maybe they'll actually use it! Imagine that! + +It's a great idea to version control your documentation alongside your project (see [version control section below](#version-control)) so that it remains up to date with changes in your code and the two don't get out of sync with each other. + +Therefore, you need to write your documentation in a format that can be handled by your version control system (most likely, `git`) - e.g. as text files, and not a PDF, word document or google doc. A number of tools exist for doing this outside of MATLAB, be it [read the docs](https://readthedocs.org/), [roxygen2](https://cran.r-project.org/web/packages/roxygen2/vignettes/roxygen2.html) or another documentation generator. You could even just write your documentation in LaTeX and combine with a tool to automatically render a pdf ([see CI/CD below]((#continuous-integration-and-continuous-deployment))). + +Of course, you can use these tools for your MATLAB project. Your documentation is written in a raw text format such as markdown (like this blog post), or reStructuredText, MATLAB itself isn't being used to execute code in the documentation. A documentation generator will process your raw text into a nice PDF or webpage. You could even run your documentation generator just using a [continuous deployment](#continuous-integration-and-continuous-deployment) tool such as github actions and never install or run the tool on your local machine at all! + +[See this MATLAB Answers thread](https://uk.mathworks.com/matlabcentral/answers/58438-which-tool-are-you-using-to-create-the-documentation-of-your-matlab-codes) for a few examples of documentation generators to use with MATLAB. + +However, if you want to work purely in MATLAB, it has the tools to generate HTML or PDF (or even powerpoint) from an m-file, which can be version controlled alongside your code. + +#### Generating documentation with MATLAB +The tools for generating documentation from MATLAB are relatively immature, however there are plenty of functions available as part of the [MATLAB Report Generator](https://uk.mathworks.com/help/rptgen/) which you can use for building documentation. + +Take, for example, a file called `docs.m` which uses the [MATLAB markup syntax](https://uk.mathworks.com/help/matlab/matlab_prog/marking-up-matlab-comments-for-publishing.html) to format some documentation. +```matlab +%% My User Documentation + +%% Section 1: Writing some text + +%% +% One space after the comment symbol (|%|) renders some ordinary text. +% +% Whereas two spaces creates a monospaced font output. +% +% Three spaces between the |%| and text outputs syntax highlighted code: +% +% +% for i = 1:10 +% disp(x) +% end +% +% You can format _bold_, *italic* and |monospaced| inline as well. +``` + +Try copying this code into a new m-file now. You can then publish your new documentation to an HTML file or PDF from the `Publish` tab in MATLAB: + +![On the Publish tab, go to publish](/assets/images/matlab-repro-blog/matlab-publish.png) + +Clicking the down arrow opens a menu, with the bottom option being `Edit publishing options...` where you can edit the publishing options on a per-file basis. You can choose to output HTML, PDF, latex or XML as well as edit a number of other options. + +If you output to PDF, you'll get some output that looks like this: + +![PDF rendered output](/assets/images/matlab-repro-blog/pdf-output.png) + +You can also publish programmatically, using the `publish` function ([documentation here](https://uk.mathworks.com/help/matlab/ref/publish.html)) + +```matlab +options = struct('format', 'pdf', 'outputDir', 'docs'); +publish("docs.m", options); +``` + +Whilst not shown here, these files can contain executable code, [see this blog article for an example](http://ricopic.one/publishing-matlab-code/), and there are many other tools for generating reports and documents from within MATLAB. + + +### Version control + +Version control is far more than these two words suggest, and enables a far more secure, dynamic and collaborative approach to developing code than without it. Of course, this is far more wide-ranging than just MATLAB, and as RSEs our first recommendation to researchers is to employ a version control system if they don't already. Spending time learning how to use `git`, for instance, will pay dividends. + +#### Why use version control? +A version control system (VCS) allows you to capture snapshots of your code as you develop, meaning that you can go back if you want to. Furthermore, you can create _branches_ to try out new ideas without fear of breaking your existing code - your main branch is still there! All this without making numerous copies and archives of your code. A VCS also allows you to merge one branch into another; so when you're happy with your feature branch (where you try out a new idea), you can combine it with your main branch! + +Using a VCS simply for developing code on your own machine is a great idea. But online platforms such as GitHub and GitLab add a host of excellent tools to facilitate collaboration, project management and distribution of your code. + +#### Which version control system? +At the time of writing, there is one answer to this question, namely [`git`](https://git-scm.com). Originally developed in 2006, `git` has become the _de facto_ standard VCS and for many developers is synonymous with the concept. As a researcher you may, however, come across older codebases controlled with other systems such as Subversion (SVN) or Mercurial, but `git` is the way to go for new projects at present. + +#### How? +This is the one point here in which I can not currently (April 2022, MATLAB release R2022a) recommend the tools provided within MATLAB and would advise alternatives for version control. It may be that MathWorks will put out some improvements in the future, at which time I'll aim to revise this post. + +Far better (and free) alternatives to MATLAB's tools exist for interacting with `git`, my current favourite is the [_GitKraken Client_][gitkraken-client] - it provides a great user interface with access to most (if not all) of the major operations you're likely to want to do both with `git` and GitHub (or GitLab, BitBucket or Azure DevOps). Not to mention it has a great name. Helpfully, most of the terminology used (_pull, fetch, rebase, fork, clone_) comes from the core tools (`git` & GitHub) themselves, so anything you learn can generalise to other tools. + +It would be irresponsible to attempt to provide instruction on using `git` here and there are many resources to learn from, not least the [courses](https://rse.shef.ac.uk/events/) run by RSE teams! + +### Testing +Software testing means writing code that checks that your code is doing its job correctly. Most languages have a method for doing this and it's an excellent habit to get into. + +At first, stopping to write a test may seem like a hinderance, however you'll soon find that an automated check to your code will save you time and confusion in the long-run. + +Let's have a look at writing some simple tests in MATLAB, so you can see what I mean. + +#### Script-based 'testing' +Ideally your code should be organised into functions and/or classes, however it is possible to do some level of validation with scripts, by using the `assert` function. `assert` checks a condition and throws an error if the condition is false, _asserting_ that the condition is true. + +For example (from the [`assert` documentation](https://uk.mathworks.com/help/matlab/ref/assert.html)) + +```matlab +minVal = 7; +x = 26; + +assert(minVal < x) +``` +will throw an error if `minVal` is greater than `x`. + +You can use these throughout your scripts to check for some sources of errors and use any condition that returns a logical such as `isa()` to check a variable's type or `size` to check the dimensions of an array. + +`assert` can also take a string argument as a message to print if the condition is not met. + +```matlab +assert(minVal < x, 'value is not greater than minVal') +``` + +For information on script-based unit testing in MATLAB, [see the official docs here](https://uk.mathworks.com/help/matlab/script-based-unit-tests.html) + +#### Function-based testing +If your code is organised into functions (and/or classes), you can use the function-based and class-based testing frameworks to test those functions with a test suite. The function-based testing framework is a little simpler, but a big improvement on the use of `assert` above. + +Types of test can briefly be categorised as: +* **Unit tests** - test individual 'units' of code, most often a function. +* **Integration tests** - test the operation of multiple units integrated together. +* **Regression tests** - test that the overall operation of the code is not damaged by new changes, in other words, that the code has not regressed. + +For a simple example of a *unit* test, let's say you have a function called `add` which adds together two values and returns the result that looks like this: + +```matlab +function result = add(a,b) + result = a + b; +end +``` + +Generally, you might have a folder in your project called `tests`, inside which you put a file called, for instance, `test_add.m` with the contents: + +```matlab +%% Main function to generate tests - you don't need to change this +function tests = exampleTest +tests = functiontests(localfunctions); +end + +%% Test Functions +function test_add(testCase) + a = 1; + b = 2; + actual_result = add(a,b); + expected_result = a + b; + verifyEqual(testCase, actual_result, expected_result) +end +``` + +Similarly to what we saw above, an error will be raised if the wrong result is produced. However in this case, rather than running as part of your main code, this test suite is run during development when making changes to verify that everything is still working as expected. (Perhaps as part of [continuous integration below](#continuous-integration-and-continuous-deployment)). + +We can run all of our tests for a project from the MATLAB desktop under the *Editor* tab, including running tests with the debugger. + +![](/assets/images/matlab-repro-blog/run-tests.png) + +#### Next steps in testing +As mentioned above, MATLAB provides more featureful tools for testing under the [class-based testing framework](https://uk.mathworks.com/help/matlab/class-based-unit-tests.html); tools for [testing applications](https://uk.mathworks.com/help/matlab/app-testing-framework.html) and more. I may put together a blog post on these in the future. + + +### Licensing/open source +It is a common misconception that MATLAB code can not be released as open source because MATLAB itself is a proprietary language. This is not the case at all, just look at [MATLAB's File Exchange][file-exchange] to see thousands of examples of users sharing their code. + +Software licensing is perhaps too big a discussion to be a subsection of a blog post, but the takeaway points here should be: +1. Release your code publicly, let others use it and cite your research and build upon it, have a bigger impact on the research community, +1. If you do not include a license at all, nobody can legally use your code, include a license that permits the kind of use that you want to, check out to help you pick one, + + +### Collaborative hosting/GitHub/GitLab +Hosting your code on an online hosting platform such as GitHub or GitLab brings a tremendous number of benefits, including (but not limited to): + +* Acting as a reliable, remote backup, +* Facilitating collaboration and sharing of code, +* A plethora of project management tools alongside your code, making it easier to keep track of what work needs doing, +* Public hosting of your code, making it easier to share, +* Continuous Integration/Deployment tools (e.g. GitHub Actions) which, for instance, can be used to render documentation, run tests and many more things, + +Whilst not difficult to learn, there is too much to cover here, but in essence the basic process is: +1. Start a new repository on GitHub, +1. Push your local repository (version controlled by `git`) to the remote on GitHub, +1. Make changes on a new branch locally and push them to GitHub, +1. Open a pull request to discuss merging your branch into the main one, +1. Merge the changes, +1. Locally, pull the new changes on the main branch, +1. Continue working with the new changes and repeat! + + +### MATLAB "Projects" +Since R2019a, MATLAB has included the [`Projects` tool](https://uk.mathworks.com/help/matlab/projects.html) with the goal of improving collaboration and portability. Have you ever been sent code by a colleague and found that you can't run it at all because you're missing a bunch of dependent toolboxes and functions? This is one of the problems that `Projects` attempt to solve. + +By creating a `Project` and adding all the relevant files needed to run the code, you should be able to pass on the code and project file (`.prj`) to someone else; they can open the `Project` and all the right files will be added to the path, any particular actions that you specify can be run, among other actions. + +`Projects` also allow you to run a dependency analysis, to report which other code yours depends on, and therefore needs to be considered for reproducibility. + +**Remember!** include your `.prj` file under version control. + + +### Continuous integration and continuous deployment +These might sound pretty scary, but all I really mean is: "**actions that run automatically**", maybe when you make changes to your code, or on a particular schedule for instance. These can do things such as running tests or updating the documentation. There are lots of tools for this such as _Travis_, _CircleCI_, _Jenkins_ _etc_. but here I'm going to concentrate on _GitHub Actions_ because it's an increasingly popular tool and one that I've used with MATLAB myself. + +In brief, GitHub actions is a really, really, _really_ useful tool! Some examples of things I've done with actions when using MATLAB are: running tests when a pull request is made so that we can see that the new code works and doesn't break anything before we merge it; automatically compiling a standalone application and an installer for any new releases; and at the same time publishing a PDF of user documentation and uploading it to the project's release page automatically. + +MathWorks have made a number of actions available for use on GitHub under the [matlab-actions](https://github.com/matlab-actions) organisation, for an overview, [see this repo](https://github.com/matlab-actions/overview). + +To learn more about GitHub actions, have a look at [this learning resource](https://docs.github.com/en/actions/learn-github-actions). _Basically_ all you have to do is include a `.yml` file in the `.github/workflows/` folder of your project hosted on GitHub. + +The actions available for MATLAB at present are reasonably limited, but versatile, at the moment they're available to: +* [Run Tests](https://github.com/matlab-actions/run-tests) - to automatically run a test suite, and +* [Run a MATLAB command](https://github.com/matlab-actions/run-command) - which allows you to do anything you can write the MATLAB code for, for instance: + * you could run MATLAB's [`checkcode` function](https://uk.mathworks.com/help/matlab/ref/checkcode.html) against the repo to look for problems in the code so you don't have to look for them manually, + * or publish your [documentation][#Documentation] as HTML and use it to make a [GitHub pages](https://pages.github.com/) website containing docs for your code, + * or when a new release is made, build and share your toolbox to the MATLAB file exchange! + +You can also combine these with one of the many actions from the [GitHub actions marketplace](https://github.com/marketplace?type=actions) even further extending the possibilities! + +These MATLAB-specific actions can be run on GitHub actions' cloud computing for free for _public_ projects hosted on GitHub (just another reason to go open source! :grinning:), but if your project is private, you can still use GitHub actions by setting up a _self-hosted_ runner on your own computing infrastructure, I used a VM hosted by my university to do this for a private project. Note that other actions can be run on GitHub for private repos, but private projects only get a limited amount of free time per month. + + +### Compiling standalone applications +One way to solve the challenge of getting your code to run on other people's computers, particularly if they don't have a MATLAB license, is to consider building your code as a standalone application. This takes your MATLAB source code and bundles it in such a way that it can be run on a machine without a MATLAB license, and without MATLAB installed - helpful in a number of situations. + +This can be achieved through [point and click menus](https://uk.mathworks.com/help/compiler/create-and-install-a-standalone-application-from-matlab-code.html) or, better yet, by [writing a script to run](https://uk.mathworks.com/help/compiler/standalone-applications.html) that runs the build operation. + +**Note** the application must be built for each operating system (Windows, Mac OS, Linux etc) and generally the build process must be run on a compatible operating system. For instance, if you want to build your program to run on Windows, the build command should be run from within MATLAB on Windows. + +This is a useful tool, for instance if you want to run analysis on a machine without MATLAB installed - but isn't a complete solution to reproducibility, and openly sharing your source code should be the first thing you think of, in my opinion. + + +### Publishing your code with a research paper +Once you've done all this, how do we get to the business of actually publishing code alongside our research?! Well fortunately, everything is fairly straightforward from this point! + +The first thing I'd recommend is asking a friend or colleague to attempt to reproduce your results following the instructions provided in your online repository. Remember to document where to get your data from! You could even consider submitting your work to a [reprohack event](https://www.reprohack.org/)! Essentially, this process of getting someone else who doesn't know about the code to try and run it and get the same results should highlight gaps in your documentation, allowing you to fix them before sending your code out to the world. + +By hosting your code on a public repository with a tool like GitHub, you'll be able to link to the code as it was at the time of submission. At this stage, I'd recommend creating a tag to indicate the commit that the repository was at when you produced the final results. On GitHub, you can alternatively create a 'release'. You can just use a version number and quote this in the description of your methods. + +Furthermore, it's possible to [use Zenodo to create a DOI for your GitHub release](https://docs.github.com/en/repositories/archiving-a-github-repository/referencing-and-citing-content) so that there is a persistent identifier for that version of the codebase. + + + +### And finally... +Just try your best! Most researchers still don't publish their code and very few projects are reproducible, so anything you can do to improve your work will get you closer. + +If you want to discuss how to make your code more reproducible and don't know what to do, [book a code clinic](/support/code-clinic/) with the RSE and Research IT teams at The University of Sheffield to see how we can help! + + +[style-guide]: https://sites.google.com/site/matlabstyleguidelines/home +[bes-guide]: https://www.britishecologicalsociety.org/wp-content/uploads/2019/06/BES-Guide-Reproducible-Code-2019.pdf +[file-exchange]: https://uk.mathworks.com/matlabcentral/fileexchange/ +[gitkraken-client]: https://www.gitkraken.com/git-client diff --git a/_posts/2022-05-12-rrse.md b/_posts/2022-05-12-rrse.md new file mode 100644 index 00000000..2c988397 --- /dev/null +++ b/_posts/2022-05-12-rrse.md @@ -0,0 +1,24 @@ +--- +layout: post +title: "Join our team!" +author: RSE Team +slug: 2022-05-12-rrse +date: 2022-05-12 10:00:00 UTC +tags: recruitment, R +category: +link: +description: +type: text +excerpt_separator: +--- + +We have a [job advert out for an RSE](https://www.jobs.ac.uk/job/CRL803/research-software-engineer-rse-associate-rse-for-machine-learning/)! Here are six reasons to apply: + +1. **Varied projects.** We work on research in areas such as astrophysics, healthcare, molecular biology, civil engineering and many more. Maybe you've been working on one area for years and you're keen to work with researchers in diverse fields? +2. **We don't need an expert in everything right away.** Lots of people have joined our team having developed coding skills working on research, and learned more software engineering once in the team. Our team is made up of people who specialise in sharing software engineering skills with researchers. +3. **Make a difference.** Our team works with public/private sector organisations, and charities to give our output the best chance of making a positive difference outside the university. We also enthuse about and participate in open research wherever possible. +4. **Flexibility.** We're happy to discuss flexible and part time working options. One of our team has recently reduced their hours from 100% to 80%. Working as a pool makes this much more practicable. Furthermore, in contrast to most RA roles this position is open-ended. +5. **Do useful stuff with code.** We are most interested in your ability to do useful things with code and work with other people. We don’t tend to ask questions about the theory of computer science in interviews. The interest is in modern software technology, code you’ve written, how it was used and how it could be improved. +6. **Reward and recognition.** All of the Sheffield RSE team are employed within the academic careers pathway, a new flexible career development structure which recognises a broad range of research outputs including software. The pathway provides a clear route for promotion up to the level of professor. + +Please [view the advert to apply](https://www.jobs.ac.uk/job/CRL803/research-software-engineer-rse-associate-rse-for-machine-learning/), and see contact details for enquiries about the job. General enquires about the team are welcome at [rse@sheffield.ac.uk](mailto:rse@sheffield.ac.uk). diff --git a/_posts/2022-05-23-interview.md b/_posts/2022-05-23-interview.md new file mode 100644 index 00000000..0e604c42 --- /dev/null +++ b/_posts/2022-05-23-interview.md @@ -0,0 +1,62 @@ +--- +layout: post +title: "We're hiring - how do we assess candidates for RSE jobs?" +author: RSE Team +slug: 2022-07-18-interview +date: 2022-07-18 10:00:00 UTC +tags: recruitment +category: +link: +description: +type: text +excerpt_separator: +--- + +We want to make our candidate selection process as open as possible. Generally we’re not trying to hire people who can solve software problems on the acute timescale and in the pressured situation of a job interview, so maybe it’s best to share some example interview questions and assessment tools with everyone? + +**This is a representative example, and gives an idea of what to expect, but the process we use for any specific role may differ somewhat.** + + + +## Before the interview + +Once we have approval to advertise a post, the RSE Team agrees a job advert with “Human Resources” and this is listed on the University of Sheffield website and [jobs.ac.uk](https://jobs.ac.uk). Once advertised we are bound to select candidates based on the advertised “About the Job” document. We promote these adverts using a variety of means, including the RSE Society Slack channel and Twitter. Applicants are welcome to ask informal questions via , and can apply using the University of Sheffield website. + +Prior to the interview the RSE Team will convene a panel (usually three people) including members with management responsibility and with relevant technical skills. These will review and rank applications primarily against the “essential” and “desirable” person specification criteria in the “About the Job” document, and select candidates for interview on this basis. + +## Interview + +The purpose of the interview is to further assess and validate a candidate's skills in relation to the job specification criteria. The interviewers have this in mind when asking standard or follow up questions. We often ask candidates to share some code with us before the interview. Sometimes this isn’t possible, particularly if their previous work has been in an environment where software engineering isn’t done in the open. That’s fine. At the start of the interview we might ask candidates to give a short presentation on this code, we’ll ask that the talk covers a few things such as: + +- What were the challenges with regard to your development effort? +- Who has used (or is still using) the code? +- What is it used for and what you like and dislike about the code (with regards to good software engineering practice)? + +We will then follow up with questions on this. Some of these will be to clarify points the panel don’t understand and others might be more standard such as: + +- How does this code ensure that the results are reproducible? How could it be extended/used to do so? +- What programming language did you develop the code in? Why did you make this choice? +- How could this code be sustained long term? + +Some of these are a bit challenging and might not have a simple answer that solves the problem. We might then ask some questions about working with others, and how the candidate develops and applies their skills, such as: + +- How does your previous experience demonstrate a track record of collaborating with people on software? +- In your view, how does writing code from scratch differ from improving existing code? What are the issues involved in each case? +- What was the last technical skill that you learnt and why? + +The last questions could be on planning and relating to others, like: + +- What approaches could you use in this role to plan time on projects effectively and manage competing demands? +- How would you advocate for the importance of Research Software Engineering as a role and software as a research output? +- How would you motivate a reluctant academic to use version control? + +## After the interview + +After the interview, the panel will rank interviewees, again this is against the criteria in the person specification and the job description, before recommending that “Human Resources” make offers. + +--- + +Hopefully by sharing this we take some of the stress out of the interview process and encourage people to apply for jobs in the team! + +We haven’t perfected this and would welcome feedback on aspects that we could improve. + diff --git a/_posts/2022-08-18-git-tools.md b/_posts/2022-08-18-git-tools.md new file mode 100644 index 00000000..0876226d --- /dev/null +++ b/_posts/2022-08-18-git-tools.md @@ -0,0 +1,169 @@ +--- +layout: post +title: "Handy tools for git(s)" +author: David Wilby, Will Furnass, Joe Heffer, Neil Shephard, Bob Turner, Mark Dunning +slug: 2022-08-18-git-tools +date: 2022-08-18 10:00:00 UTC +tags: version control, git, github +category: +link: +description: +type: text +excerpt_separator: +--- + + +`git` is an exceptionally popular and useful tool in developing software. In the RSE team we've been running a regular course on using git and GitHub via a great interface called GitKraken client. Recently, we got together as part of one of our [LunchBytes events](/community/lunch-bytes) to share our favourite tools and tips for working with git and GitHub, so here are some of the tools that we saw demonstrations of! You can also see demos of each tool in the video from the LunchBytes session below, time codes are provided in each section. + + + + +
+ +
+ +# IDE integrations +Many of us use integrated development environments (IDEs) in which to write our code. Some are general purpose and others are predominantly language-specific. No matter which IDE you use, there's likely to be a set of tools for you to use git easily from within it. + +## VS Code + +:bust_in_silhouette: Bob Turner, RSE Team + +:movie_camera: :stopwatch: 29:20 + +[VSCode](https://code.visualstudio.com/) is an open source Integrated +Development Environment that can be used to code in lots of different +languages, including Python. It has some core git features built in, +making it easy to see what branch you're on, make new branches, commit +and push. The [Git Graph](https://marketplace.visualstudio.com/items?itemName=mhutchie.git-graph) +extension lets you visualise your repository and, by clicking on +commits, carry out more complex operations - I find this particularly +useful for selecting commits to move between branches by "cherry +picking". + + +## PyCharm + +:bust_in_silhouette: Joe Heffer, [Research & Innovation Team, IT Services](https://sheffield.ac.uk/it-services/research) + +:movie_camera: :stopwatch: 33:49 + +PyCharm is an integrated development environment (IDE) for computer programming in the Python language that offers integration with version control systems such as Git (and the hosting service Github.) PyCharm helps you manage your code projects by providing file management and code editing features such as highlighting, linting, autocomplete, etc. + +You can clone repositories from Github into new projects within the IDE. Common versioning operations such as commits, pulling changes, resolving merge conflicts, may be done using interactive tools within the software. This can be particularly useful when working on complex, collaborative projects that involve many changes and branches to your code (or other documents.) See the PyCharm documentation for Version Control for more details. + +See Joe's demo in the video above for more! + +## RStudio + +:bust_in_silhouette: Mark Dunning, [Bioinformatics Core](https://sbc.shef.ac.uk/) + +:movie_camera: :stopwatch: 40:15 + +RStudio is the IDE favoured by many developers who write in the R programming language. Git can be used right from RStudio too! + +To link up RStudio to the repository, when you create a new project, there's an option to create from an existing repository or when you create a new project in a new directory, there's an option to create a new git repository at the same time. Note that you'll need to have git installed on your system to do this. + +Once this is done, there's an extra tap in the top right panel of RStudio, which provides you with all the git functionality that you need including detecting new or changed files, staging and commiting them, branch management and pushing/pulling to/from GitHub. + +See Mark's demo in the video for more! + +* [More info from RStudio](https://support.rstudio.com/hc/en-us/articles/200532077-Version-Control-with-Git-and-SVN) + + +## Emacs/Magit + +:bust_in_silhouette: Neil Shephard, RSE Team + +:movie_camera: :stopwatch: 12:00 + +[Emacs](https://www.gnu.org/software/emacs/) is a text editor, IDE and much, much more. As an IDE though it offers +complete integration with your Git workflow via the [Magit](https://magit.vc) package which provides a key-driven +system for working with your Git version controlled files and interacting with remote repositories. Anything you can do +at the command line with Git you can achieve with Magit. Bring up a status buffer of a repository when viewing/editing +a version controlled files with `C-x g` and you are shown untracked, unstaged and staged files and can view the +changes to each along with the log history of the current branch. + +Graphs, cherry-picking, rebasing and more are all available but the best feature of Magit is that it holds your hand +through all stages by providing transient buffers which show the options available and their associated key bindings at +each step of the process. It works like Magit! + +See Neil's demo in the video above for more! + +* [Emacs](https://www.gnu.org/software/emacs/) +* [Magit](https://magit.vc) +* [Emacsdocs.org](https://emacsdocs.org) - modern stylized versions of manuals for Emacs, Magit, Org-mode and more + + +# GitKraken Client + +:bust_in_silhouette: David Wilby, RSE Team + +:movie_camera: :stopwatch: 27:10 + +GitKraken Client is one of [very many local interfaces to git](https://git-scm.com/downloads/guis) but in my experience is one of the best available. It's free and academic users can get a free Pro account along with a [free GitHub pro account](https://docs.github.com/en/education/explore-the-benefits-of-teaching-and-learning-with-github-education/github-global-campus-for-teachers/apply-to-github-global-campus-as-a-teacher). + +GitKraken client provides all the tools you need for working with git locally as well as remote repositories hosted on GitHub, GitLab, BitBucket or Azure. It has an aesthetically-pleasing and very visual interface which can be used to: make and push commits, manage branches and remotes, manage pull requests and even has a basic text file editor built in. I'd highly recommend it as a user-friendly way of working with version control. + +![](/assets/images/blog-git-tools/gitkrakenclient.png) + +* [GitKraken Client](https://www.gitkraken.com/git-client) + +# GitHub Suggestions + +:bust_in_silhouette: David Wilby, RSE Team + +:movie_camera: :stopwatch: 25:28 + +On GitHub, when reviewing a pull request, often we want to suggest some small changes to be made to the code. Ordinarily, in order to make those changes, someone would have to go back to their local copy of the repo, make changes to the code, stage and commit them, then push them up to GitHub and resolve the conversation. + +With suggestions, this process can be made much shorter. This is particularly useful for making very small edits to minor errors such as typos. It works like this: + +When reviewing a line of code, among the text formatting options (bold, italic, etc.) there's a 'make a suggestion' button on the left-hand side, which puts the line of code into your comment for you to edit. Looking at the preview for the comment shows us the diff that your suggestion generates and once the comment is submitted, the change can be committed directly from the comment, saving valuable time. You can even create a whole set of changes as a batch and commit them together. + +See David's demo in the video above for more! + +screenshot from github showing a suggested change being committed + +* [GitHub suggestions docs](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/reviewing-changes-in-pull-requests/incorporating-feedback-in-your-pull-request) + +# Command-line utilities +The traditional (and still popular) way of using git is through the terminal, so it can be useful to have some extra functionality provided by other tools to enhance the experience and productivity of using git. + +## Bash Prompt + +:bust_in_silhouette: Will Furnass, Research Platforms Systems Administrator, Research Platforms Team, IT Services + +:movie_camera: :stopwatch: 06:09 + +[bash-git-prompt][bgp] is a neat tool for those who use git at the command line. It modifies your (bash) shell prompt to concisely and colourfully inform you of whether you're in a git repository and if so, of the status of the repository (current branch, whether in sync with remote repository, uncommitted work etc). This allows you to see what's going on in your git repo without running `git status` all the time and see all the information you need at a glance. + +It's specific to the bash shell but there's similar functionality in '[ohmyzsh][ohmyzsh]' for zsh shell users (zsh is now the default shell on macOS). + +See Will's demo in the video above for more! + +[bgp]: https://github.com/magicmonty/bash-git-prompt +[ohmyzsh]: https://github.com/ohmyzsh/ohmyzsh + + +## GitHub command-line interface + +:bust_in_silhouette: David Wilby, RSE Team + +:movie_camera: :stopwatch: 18:14 + +The GitHub command line interface (cli), `gh` allows you to interact with GitHub features right from the comfort of the terminal. It has lots of features, almost anything you would normally do through the browser on GitHub including: + +* opening [pull requests](https://cli.github.com/manual/gh_pr_create) and [issues](https://cli.github.com/manual/gh_issue_create) `gh issue create` or `gh pr create` +* seeing the status of GitHub actions `gh workflow list [flags]` +* opening the repo's webpage in the browser [`gh repo view -w`](https://cli.github.com/manual/gh_pr_view) or [`gh browse`](https://cli.github.com/manual/gh_browse) +* [checking out the branch associate with a pull request](https://cli.github.com/manual/gh_pr_checkout) e.g. `gh pr checkout 42` - really useful if you want to test someone's code from a pull request locally +* you can even [create and manage gists!](https://cli.github.com/manual/gh_gist) +* and [many many more](https://cli.github.com/manual/) + +See David's demo in the video above for more! + +mockup of command-line interface running gh pr status command which outputs the details of all open pull requests in a repository + +* [GitHub CLI](https://github.com/cli/cli) +* [Manual](https://cli.github.com/manual/) \ No newline at end of file diff --git a/_posts/2022-08-23-upcoming-git-zero-to-hero.md b/_posts/2022-08-23-upcoming-git-zero-to-hero.md new file mode 100644 index 00000000..61eaf3f7 --- /dev/null +++ b/_posts/2022-08-23-upcoming-git-zero-to-hero.md @@ -0,0 +1,50 @@ +--- +layout: post +title: "Upcoming : Git & GitHub through GitKraken - Zero to Hero!" +author: Neil Shephard +slug: 2022-8-22-upcoming-git-zero-to-hero +date: 2022-8-23 12:00:00 UTC +tags: git github gitkraken +category: +link: +description: +social_image: /assets/images/open_sign.jpg +type: text +excerpt_separator: +--- + +The RSE Team are pleased to announce three scheduled sessions of the increasingly popular [Git & GitHub through +GitKraken - Zero to Hero!](https://srse-git-github-zero2hero.netlify.app/). These courses will run over two consecutive +days in morning sessions from 09:30 to 13:00 on the following days. + +* [Monday 3rd/Tuesday 4th October 2022](/training/workshop/2022-10-03-git-zero-hero) +* [Monday 31st October/Tuesday 1st November 2022](/training/workshop/2022-10-31-git-zero-hero) +* [Monday 28th/Tuesday 29th November 2022](/training/workshop/2022-11-28-git-zero-hero) + +## What are Git, GitHub and GitKraken? + +[Git](https://git-scm.com) is a system of version controlling your code. Think of it as a lab-book or doctors notes that +are taken as you progress through your work, recording conditions, saving what has worked and correcting what doesn't. + +[GitHub](https://github.com) is a website that allows people to work collaboratively on version controlled code. + +[GitKraken](https://www.gitkraken.com) is a client for working with Git and GitHub that includes both a GUI (Graphical +User Interface) and a CLI (Command Line Interface) + +## Who is the course for? + +Everyone who writes code! If you write scripts to analyse your code in R, Stata or Matlab you would benefit from using +Git to version control your code and GitHub to share your code and make it open. If you write Python, JavaScript, C/++ +code as part of a team in your research group you would benefit from using Git and GitHub to work together. + +Getting started with these tools can be overwhelming but by taking this course you will be introduced to the concepts +behind them and how to use them effectively to not just version control your own work but work with others on the same +code. + +The course material is available [online](https://srse-git-github-zero2hero.netlify.app/) if you want to take a peek and +the first half using Git and publishing web-pages can be worked through in your own time. The real benefit comes from +participating in the collaborative exercises in the second half where you work together on projects making Pull Requests +and resolving problems that arise. + +If you've never used Git, GitHub or GitKraken or have only just started then sign-up and come and learn more about these +powerful tools. diff --git a/_posts/2022-09-23-code-cheats.md b/_posts/2022-09-23-code-cheats.md new file mode 100644 index 00000000..aa9cc0bf --- /dev/null +++ b/_posts/2022-09-23-code-cheats.md @@ -0,0 +1,66 @@ +--- +layout: post +title: "Five secret research code cheats" +author: Bob Turner +slug: code-cheats +date: 2022-09-22 12:00:00 UTC +tags: git github gitkraken +category: +link: +description: +social_image: assets/images/jose-aljovin-l6dnswlRZyE-unsplash.jpg +type: text +excerpt_separator: +--- + +*Thanks 🙏 to Neil Shephard for checking though this!* + +Research Software Engineers are often not much better at actually writing code than any other researcher, we just know a lot of cheats, shortcuts and ways to automate things. I'm going to risk the wrath of my fellow engineers and share some of these here. They will mean you can work a bit faster, but mostly will stop you throwing code away when you come back to it after a few months and can't figure out what the flip it's supposed to do. + + + +## Auto-format your code + +Often a programming language gives you a choice of how to format your code. Do you use single or double quotes? Spread long lines over several lines using a separator? Where you you split these? Empty line before a function definition? **Consistently formatted code is easier to read and will save you time when you come back to it.** An auto-formatting tool will take care of this. In Python, where formatting choices abound, [black](https://github.com/psf/black) is this tool. I've not used it but [formatR](https://cran.r-project.org/web/packages/formatR/index.html) seems to be a close R equivalent. Most popular IDEs such as [VSCode](https://marketplace.visualstudio.com/items?itemName=ms-python.python), [PyCharm](https://plugins.jetbrains.com/plugin/10563-black-pycharm) (and less popular ones such as [Emacs](https://github.com/wbolster/emacs-python-black)) include plugins and extensions to apply formatting automatically when saving files. + +## Run a code checker + +People tell me they write "bad code". I think they generally underestimate their abilities, but this is a little beside the point. There are good and bad practises when coding - a function with 27 input variables named `a`, `b`, `default`, `sAm`, `a2`, etc. is not likely to be good practise in any language. You probably know this. But there are hundreds of bad practises and no-one can even remember them all! Probably. So we have tools to automatically check code for these. [pylint](https://pypi.org/project/pylint/) is a good choice in Python, and R has [lintR](https://github.com/r-lib/lintr). **Use these and your code will be easier to read and maintain.** You may even prevent some bugs! + +## Make a regression test + +Software tests can be extremely unpalatable to researchers. I can see why - you have to select and learn a "test framework", then maybe end up writing more test code than actual code and start having to worry about "coverage". However, it's not all or nothing. A single regression test can make a huge difference. This just tests that for a given input, you get a given output. So if you change some bit of code that you haven't looked at for 6 months to try and make things run faster, this test will tell you if your results have changed. I bet you're doing this anyway without automation and without being 100% sure what the results were last time. Aren't you? Automating this in Python with [pytest](https://docs.pytest.org/en/7.1.x/) (this extension also helps: [pytest-regtest](https://pypi.org/project/pytest-regtest/)) or the R package [testthat](https://testthat.r-lib.org/) (not that I've used the latter) means that **the anxiety about code producing the wrong results (which you might be presenting at a conference next week) goes away**. You may then find you see the value of unit tests which will tell you *where* things have gone wrong. + +## Do easy version control + +`git` is intimidating and uses wild terminology like "fetch" and "pull" which do different things. However, it is the best way to keep track of which version of your code is current, which version you shared with your collaborator, which version produced the results in your poster. It doesn't have to be used in a complicated way with multiple contributors and "branches" and "forks" and "releases" and such. **All that's really needed is to make the folder with your code in a repository and use "commit" regularly to log changes with little messages.** You can then go back to any of these points. If the command line isn't your jam [VSCode](https://code.visualstudio.com/) and [RStudio](https://www.rstudio.com/) have nice git integration, and [GitKraken](https://www.gitkraken.com/) is a good stand alone tool. + +## Use continuous integration + +If you're in a position to have your code backed up to a site like [GitHub](https://github.com/) or [Gitlab](https://about.gitlab.com/), **you can automate running checks and tests on your code every time you upload changes**. This is "Continuous Integration" and is set up on GitHub by adding a small file to your repository that specifies what checks to run. [This example](https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python) is probably a bit more complex than it needs to be for a Python project, but I think it's still fairly easy to see what's going on. + +
+ +## Further resources + +### Python + +* [pytest](https://pytest.org) +* [pylint](https://pylint.pycqa.org/en/latest/) a useful reference is also the [pylint messages overview](https://pylint.pycqa.org/en/latest/user_guide/messages/messages_overview.html) which includes examples for each message. +* [Python Extensions for VSCode](https://marketplace.visualstudio.com/items?itemName=ms-python.python) provides support for Black, PyLint, Flake8 and more. +* [PyCharm : Black](https://plugins.jetbrains.com/plugin/10563-black-pycharm) +* [PyCharm : PyLint](https://plugins.jetbrains.com/plugin/11084-pylint) + +### R + +* [RStudio](https://rstudio.org) +* [Format R Code Automatically](https://yihui.org/formatr/) +* [lintr](https://cran.r-project.org/web/packages/lintr/) +* [lintr : Editor Configuration](https://cran.r-project.org/web/packages/lintr/vignettes/editors.html) +* [lintr : Continuous Integration](https://cran.r-project.org/web/packages/lintr/vignettes/continuous-integration.html) +* [R Packages : 13 Testing Basics](https://r-pkgs.org/testing-basics.html) + +
+ +
Coder doing a card trick

Photo by +jose aljovin on Unsplash

\ No newline at end of file diff --git a/_posts/2022-10-10-pre-commit.md b/_posts/2022-10-10-pre-commit.md new file mode 100644 index 00000000..ec82f799 --- /dev/null +++ b/_posts/2022-10-10-pre-commit.md @@ -0,0 +1,288 @@ +--- +layout: post +title: "pre-commit : Protecting your future self" +author: Neil Shephard +slug: pre-commit +date: 2022-10-10 12:00:00 UTC +tags: git pre-commit github gitlab linting +category: +link: +description: +social_image: assets/images/watchful_eye.jpg +type: text +excerpt_separator: +--- + +[Pre-commit](https://pre-commit.com/) is a powerful tool for executing a range of hooks prior to making commits to your +Git history. This is useful because it means you can automatically run a range of linting tools on your code across an +array of languages to ensure your code is up-to-scratch _before_ you make the commit. + + + +
Close-up of eye on an elephant
+sculpture

Photo by Neil Shephard.

+ +Pre-commit is written in Python but that isn't a limitation as it will lint YAML, JSON, C, JavaScript, Go, Rust, TOML, +Terraform, Jupyter Notebooks, and so on. The list of [supported hooks](https://pre-commit.com/hooks.html) is vast. + +## Background + +For those unfamiliar with version control and Git in particular this will likely all sound alien. If you are new to the +world of version control and Git I can highly recommend the [Git & Github through GitKraken Client - From Zero to +Hero!](https://srse-git-github-zero2hero.netlify.app/) course offered by the [Research Software +Engineering](https://rse.shef.ac.uk) at the University of Sheffield and developed by Alumni [Anna +Krystalli](https://www.r-rse.eu/). + +### What is a "hook"? + +In computing a "hook" refers to something that is run prior to or in response to a requested action. In the context of +the current discussion we are talking about hooks that relate to actions undertaken in Git version control and +specifically actions that are run before a "commit" is made. + +When you have initialised a directory to be under Git version control the settings and configuration are stored in the +`.git/` sub-directory. There is the `.git/config` file for the repositories configuration but also the `.git/hooks/` +directory that is populated with a host of `*.sample` files with various different names that give you an in-road into +what different hooks you might want to run. Its worth spending a little time reading through these if you haven't done +so yet as they provide useful examples of how various hooks work. + +### Why pre-commit hooks? + +Typically when writing code you should [lint](https://ns-rse.github.io/posts/linting/) your code to ensure it +conforms to agreed style guides and remove any "[code smells](https://en.wikipedia.org/wiki/Code_smell)" that may be +lingering (code that violates design principles). It won't guarantee that your code is perfect but its a good starting +point to improving it. People who write a lot of code have good habits of doing these checks manually prior to making +commits. Experienced coders will have configured their Integrated Development Environment (IDE) to apply many such +"hooks" on saving a file they have been working on. + +At regular points in your workflow you save your work and check it into Git by making a commit and that is +where `pre-commit` comes in to play because it will run all the hooks it has been configured to run against the files +you are including in your commit. If any of the hooks fail then your commit is _not_ made. In some cases `pre-commit` +will automatically correct the errors (e.g. removing trailing white-space; applying +[black](https://github.com/psf/black) formatting if configured) but in others you have to correct them yourself before a +commit can be successfully made. + +Initially this can be jarring, but it saves you, and more importantly those who you are asking to review your code, time +and effort. Your code meets the required style and is a little bit cleaner before being sent out for review. Long term +linting your code is beneficial (see [Linting - What is all the fluff about?](2022-04-19-linting)). + +## Installation + +Pre-commit is written in Python and so you will need Python installed on your system in order to use it. Aside from that +there is little else extra that is required to be manually installed as pre-commit installs virtual environments +specific for each enabled hook. + +Most systems provide `pre-commit` in their package management system but typically you should install `pre-commit` +within your virtual environment or under your user account. + +```bash +pip install pre-commit +conda install -c conda-forge pre-commit +``` + +If you are working on a Python project then you should include `pre-commit` as a requirement (either in +`requirements-dev.txt`) or under the `dev` section of `[options.extras_require]` in your `setup.cfg` as shown below. + +``` +[options.extras_require] +dev = + pre-commit + pytest + pytest-cov +``` + + +## Configuration + +Configuration of pre-commit is via a file in the root of your Git version controlled directory called +`.pre-commit-config.yaml`. This file should be included in your Git repository, you can create a blank file or +`pre-commit` can generate a sample configuration for you. + +```bash +# Empty configuration +touch .pre-commit-config.yaml +# Auto-generate basic configuration +pre-commit sample-config +git add .pre-commit-config.yaml +``` + +### Hooks + +Each hook is associated with a repository (`repo`) and a version (`rev`) within it. Many are available from the +`https://github.com/pre-commit/pre-commit-hooks`. The default set of `pre-commit` hooks might look like the following. + + +```yaml +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.3.0 # Use the ref you want to point at + hooks: + - id: trailing-whitespace + types: [file, text] + - id: check-docstring-first + - id: check-case-conflict + - id: end-of-file-fixer + types: [python] + - id: requirements-txt-fixer + - id: mixed-line-ending + types: [python] + args: [--fix=no] + - id: debug-statements + - id: fix-byte-order-marker + - id: check-yaml +``` + +### Hooks from External Repositories + +Some hooks are available from dedicated repositories, for example the following runs +[Black](https://github.com/psf/black), [Flake8](https://flake8.pycqa.org/en/latest/) and +[Pylint](https://pylint.pycqa.org/en/latest/) on your code and should follow under the above (with the same level of +indenting to be valid YAML). + +```yaml + - repo: https://github.com/psf/black + rev: 22.6.0 + hooks: + - id: black + types: [python] + + - repo: https://github.com/pycqa/flake8.git + rev: 3.9.2 + hooks: + - id: flake8 + additional_dependencies: [flake8-print] + types: [python] + - repo: https://github.com/pycqa/pylint + rev: v2.15.3 + hooks: + - id: pylint +``` + +An extensive list of [supported hooks](https://pre-commit.com/hooks.html) is available. It lists the repository from +which the hook is derived along with its name. + +### Local Hooks + +You can also define [new hook](https://pre-commit.com/#new-hooks) and configure them under the `- repo: local`. + +```yaml + - repo: local + hooks: + - id: + name: + language: python + entry: + types: [python] + +``` + +For some examples of locally defined hooks see the [Pandas +.pre-commit-config.yaml](https://github.com/pandas-dev/pandas/blob/main/.pre-commit-config.yaml). + +## Usage + +Before `pre-commit` will run you need to install it within your repository. This puts the file +`.git/hooks/pre-commit` in place that contains the hooks you have configured to run. To install this you should have +your `.pre-commit-config.yaml` in place and then run the following. + +```bash +pre-commit install +``` + +Once installed and configured there really isn't much to be said for using `pre-commit`, just make commits and before +you can make a successful commit `pre-commit` must run with all the hooks you have configured passing. By default +`pre-commit` only runs on files that are staged and ready to be committed, if you have unstaged files these will be +stashed prior to running the `pre-commit` hook and restored afterwards. Should you wish to run these manually without +making a commit then, after activating a virtual environment if you are using one simply, or you can make a `git commit`. + +```bash +pre-commit run +``` + +If any of the configured hooks fail then the commit will not be made. Some hooks such as +[black](https://github.com/psf/black) may reformat files in place and you can then make another commit recording those +changes and the hook should pass. Its important to pay close attention to the output. + +If you want to run a specific hook you simply add the `` after `run`. + +```bash +pre-commit run +``` + +Or if you want to force running against all files (except unstaged ones) you can do so. + +```bash +pre-commit run --all-files # Across all files/hooks +``` + +And these two options can be combined to run a specific hook against all files. + +```bash +pre-commit run --all-files +``` + + +You may find that you wish to switch branches to work on another feature or fix a bug but that your current work doesn't +pass the `pre-commit` and you don't wish to sort that out immediately. The solution to this is to use `git stash` to +temporarily save your current uncommitted work and restore the working directory and index to its previous state. You +are then free to switch branches and work on another feature or fix a bug, commit and push those changes and then switch +back. + +Imagine you are working on branch `a` but are asked to fix a bug on branch `b`. You go to commit your work but find that +`a` does not pass `pre-commit` but you wish to work on `b` anyway. Starting on branch `a` you stash your changes, switch +branches, make and commit your changes to branch `b` then switch back to `a` and unstash your work there. + +``` bash +git stash +git checkout b +... # Work on branch b +git add +git commit -m "Fixing bug on branch b" +git push +git checkout a +git stash apply +``` + + +## Updating + +You can update hooks locally by running `pre-commit autoupdate`. This will update your `.pre-commit-config.yaml` with +the latest version of repositories you have configured and these will run both locally and if you use CI/CD as described +below. However this will _not_ update any packages that are part of the `- repo: local` that you may have implemented +and it is your responsibility to handle these. + + +## Pre-commit CI/CD + +Ideally contributors will have setup their system to work with pre-commit and be running such checks prior to making +pushes. It is however useful to enable running pre-commit as part of your Continuous Integration/Development +pipeline (CI/CD). This can be done with both [GitLab](https://gitlab.com) and [GitHub](https://github.com) although +similar methods are available for many [continuous integration +systems](https://pre-commit.com/#usage-in-continuous-integration). + +### GitHub + +GitHub actions reside in the `.github/workflows/` directory of your project. A simple pre-commit action is available on +the Marketplace at [pre-commit/action](https://github.com/marketplace/actions/pre-commit). Copy this template to +`.github/workflows/pre-commit.yml` and include it in your Git repository. + +```bash +git add .github/workflows/pre-commit.yml +git commit -m "Adding pre-commit GitHub Action" && git push +``` + + +### GitLab + +If you use GitLab the following article describes how to configure a CI job to run as part of your repository. + +* [How to use pre-commit to automatically correct commits and merge requests with GitLab CI](https://stackoverflow.com/collectives/gitlab/articles/71270196/how-to-use-pre-commit-to-automatically-correct-commits-and-merge-requests-with-g) + + + + +## Links + +* [Pre-commit](https://pre-commit.com/) +* [Supported hooks](https://pre-commit.com/hooks.html) +* [GitHub Action](https://github.com/marketplace/actions/pre-commit) +* [GitLab CI](https://stackoverflow.com/collectives/gitlab/articles/71270196/how-to-use-pre-commit-to-automatically-correct-commits-and-merge-requests-with-g) diff --git a/_posts/2022-10-13-evidence.md b/_posts/2022-10-13-evidence.md new file mode 100644 index 00000000..8e1f1226 --- /dev/null +++ b/_posts/2022-10-13-evidence.md @@ -0,0 +1,137 @@ +--- +layout: post +title: "Demonstrating Importance and Value in Research Software" +author: David Wilby +slug: 2022-10-13-quality-value-research-software +date: 2022-10-13 09:00:00 UTC +tags: research, software, community, evidence, career +category: +link: +description: +social_image: +type: text +excerpt_separator: +--- + +As research software engineers (RSEs) or researchers who develop software & code, at some point we will need to provide evidence that our software actually has some positive effect on the world. Whether this is for career progression, the REF, just for your own peace of mind or any of a whole host of reasons, collecting usage data takes many forms but can often come as an afterthought. + +This International RSE day (Thursday 13th October 2022) let's have a look at how we can plan to collect some evidence to demonstrate the value of our work and hopefully mitigate some potential stumbling blocks in our career progression. + +When it comes to 'traditional research outputs' (i.e. peer-reviewed publications), the dreaded journal impact factor[^impactfactor] has come to be the _de facto_ standard measure of the quality of a piece of research, however flawed we know it to be.[^dora] Along with numbers of citations[^citations], these measures are a big part of what's used to determine how worthy the author of some research is of: promotion, funding, recognition _etc_. But with software, we don't implicitly have the \*ahem\* *"luxury"* of impact factors and numbers of citations so using other ways of showing that our work has merit is something of a necessity, but how do we do that? + + + +### The dangers of metricization + +I want to preface this blog by pointing out that simplifying a complex topic such as research quality down to a set of easily digestible metrics is a terrible idea. Publication itself demonstrates to us how dangerous this is, with researchers vying to publish in the top journals. Retraction rates actually scale with impact factors[^Fang2011],[^Nature2014] - an indication of how poorly these metrics can represent research quality. Of course, much research published in the 'top' journals is of high importance (though quality may vary) and the authors should be recognised accordingly, but simple metrics can do a disservice to researchers when seeking funding, promotion and so on. + +James Hetherington, now Director of UCL's Advanced Computing Research Centre discussed these dangers in this talk a few years ago: + +

+ +What I'm discussing here, is not a reduction of research (software) down to a set of simple metrics, but the gathering of evidence to assist your demonstration to the decision makers that your work is of good quality. And perhaps that's a matter of presentation. More on this later. + +### Importance, quality & impact +The concepts discussed in this article apply similarly to what one may term: research "importance", "quality" and "impact", referring to the influence a research output has on academia, the standard to which it is produced and the effect it has on world outside academia, respectively. These terms may be used differently in different settings but the distinction is often drawn in more or less the same way. + +We often conflate importance and quality in academic output. For instance, if a paper has a lot of citations or is published in a high impact factor journal, it is deemed to be good. In this case the research may be important, but these facts don't speak to its quality. Academic progression applications may ask for demonstration of high *quality* research output, but generally they are likely to value high impact factors and citations more than the standards to which research is done.[^REF] Here, by these definitions, I'll mainly be considering how to demonstrate *importance* and *impact*. + +For software, the evidence you use may have some similarities, but it's important to make the distinction between academia and the rest of the world. Some kinds of evidence are fairly straightforward, e.g. citations are academic and software sales are likely to be impact, but for package downloads or numbers of users it may be difficult or impossible to differentiate between the two. Depending on your approach for gathering statistics, you may be able to manage some way of telling the difference between academic and non-academic uses. + +For impact: remember to think even further outside of your bubble, you may be able to find some useful evidence that you wouldn't immmediately expect. Do some hunting via your search engine of choice, google scholar or similar every now and then and you may find an article, report, derivative work, youtube tutorial or something else entirely that will help you out. + +### Why do we need evidence at all? +In an ideal world, assessors would have the time to assess your software on its own particular merits: code quality, extensibility, robustness and so on. But frankly, in all likelihood your software won't be evaluated at all, let alone by anyone with the expertise to understand the important characteristics you've worked so hard on. So what we're trying to achieve here is to make it easier for others to understand the standard of the work we produce. + +Note that software specific journals such as the [Journal of Open Souce Software](https://joss.theoj.org/) *do* review software and act as a demonstration of quality. + +By using numbers of downloads, values of grants supported, users, volumes of data processed or other relevant metrics alongside our claims of research excellence, this can crystallize the point you're making much more immediately. Think about these two statements: + +> I was the lead developer on the project producing an all singing, all dancing python package published to PyPI. + +> I was the lead developer on the project (GBP1.2M) producing a python package published to PyPI (20k downloads a week). + +Whilst overly simplistic (and perhaps slightly misrepresentative in the case of frequency of downloads) a reader will get a much quicker and clearer idea of how great your software is from the latter. Fortunately for us, we have much more leeway at present in evidencing software than we do with publications, so we can choose the evidence that best supports our particular project best. + +Actually, the above example doesn't do the best job of presenting the evidence in a way that doesn't concentrate on the metrics themselves. Instead, we could avoid this by just using our evidence to back up our claims, perhaps + +> I was lead developer of software that was developed to enable research on a GBP1.2M project, supporting 2 PhD Students and 2 PDRAs to publish 3 papers. The software also supports a community of researchers in the discipline and is publicly available as open source software with 20k downloads a week. + +## Types of evidence to collect.. +Some useful evidence is there for the taking without a developer needing to collect it: values of grants supported, publications (!), other research roles that your work enables, _etc_. Some other evidence has to be gathered more deliberately, whether via a technical mechanism, or through collecting testimonials and other feedback from users and PIs. + +* **Qualitative evidence** - Easily overlooked but also easily achieved, qualitative evidence such as testimonials from researchers or PIs or feedback from users can form strong evidence for the usefulness and quality of software. You could even include some utility to gather this in your code, if suitable. Ask the researchers on the project to send you a paragraph or sentence explaining the importance of the software, let them know how valuable this will be and that 'traditional' metrics aren't so useful for research software and they'll be glad to help, I'm sure. + +* **Users, Downloads, Data** - Numbers, numbers, numbers. Easier said than done but get these if you can, write them to logs or store them in a database, whatever works for your software. Having numbers to illustrate the scale of use of your software will make any claims of research excellence or impact significantly more salient. + +* **Money, Money, Money** - Money talks. So whether it's the value of a grant or something more commercial such as sales of the software itself or a product enabled, monetary values can be very strong evidence. + +* **Publications & Citations** - Depending on whether your software is used exclusively by researchers in your immediate network or more widely, the ease of keeping track of publications will vary. All you can really do here is make it easy for people to cite your repository and/or paper and keep track of the citations. Of course you could always ask users to let you know when they publish work that uses your software, but if it's very popular, you may not want hundreds of emails a year about this! + +One approach is to encourage citation of your software in publications, which will clearly show its value. The strategy here is to lower the barrier for others to cite your work. +If there's a paper associated with the software, encourage its citation in your documentation and provide _pro forma_ citation text that can be used in publications. +Additionally/alternatively, for citation of the software itself provide a citation file (`CITATION.cff`) with your code (info at [citation-file-format.github.io](https://citation-file-format.github.io/)) which can help to smooth the citation process and provide citations in various formats. + +* **Last Resorts** - If your project is on GitHub, stars on the repository or number of clones are collected by default, but I wouldn't rely on this. Stars are a really unreliable measure of quality and certainly most academics are unlikely to use them, I imagine. Currently GitHub only shows the last two weeks of clones for a repository and as far as I can work out there is no way of boosting this, at least for free accounts. Also it's not clear if continuous integration runs count towards this, which may mean the number of repo clones is over-represented (arguably not a bad thing for this purpose though..). + +## And how to get it + +A lot of these types of evidence you'll just have to keep track of and get hold of manually, but for usage statistics you can use something more sophisticated. + +* **Third party usage tracking** - Say your software is a web app, you could employ a tool like [Google Analytics](https://analytics.google.com/) or [Plausible](https://plausible.io/) to gather and aggregate usage data. + +* **Roll-your-own usage tracking** - If you'd rather keep your usage tracking under your own control, you could consider including a utility in your code for it to send data back to a web server at some useful points such as installations or downloads. You should of course inform users of this and allow them to opt in/out, but in an open source project for instance, you can provide users with the peace of mind that you aren't collecting any nefarious data. + +Some examples of projects using this approach I was recently made aware of are [Sire](https://github.com/michellab/Sire) and [BioSimSpace](https://github.com/michellab/BioSimSpace), both open source research software. Sire collects and reports some basic information such as operating system, processor and software version which are described publicly and visualised [here](https://siremol.org/analytics/index.html). + +## Considerations for different types of software +Depending on what your software *does* and how, the approach for collecting evidence may vary wildly, so you'll have to tailor your approach. + +### Open Source +If your work is open source (and many funders now stipulate this) there are some elements to evidencing quality that can be easier. + +For one, you can simply demonstrate that your code **actually exists** - which is a good start! For this reason, it can be a good idea to discuss with the project PI and explain the manifold benefits of open source software if it's appropriate. Most PIs will be receptive and understand that being able to show the quality of your work is vital for career progression. It's harder to evidence your work if it has no publicly visible element whatsoever. + +Depending on the project, being open source might enable much wider use outside of your immediate network of contacts, increase the impact within the academic community and potentially increase citations. + +### Closed Source +Ideally, I personally would advise against keeping research software closed source unless absolutely necessary, but there are lots of valid reasons to do so. So in this case it's absolutely vital to collect some evidence, whether it's numbers of users or whatever is relevant to the project. A strong testimonial from the project PI or other stakeholders will go a long way. + +### Packages +If your project is a package that's available via a public package repository like [PyPI](https://pypi.org/) or [CRAN](https://cran.r-project.org/) there are likely services available to provide stats for package downloads, for example [PyPI Stats](https://pypistats.org/) or [META CRAN](https://cranlogs.r-pkg.org/). In addition, it may be that merely making a package available via a major package repository is good evidence of quality in and of itself, since they typically enforce a certain standard and require proficiency to have published there. + +### Commercial software +Commercial software almost intrinsically has evidence metrics associated with it. If the software is the product itself you might already be collecting numbers of customers and fiscal measures that might be able to be used as evidence, or if the software is used inside a commercial organisation you have some involvement with (a spin-out for example) then numbers of sales, customers _etc_. might already be available for you to use. + +It's possible that just the simple fact of having customers at all could count as some pretty strong evidence for quality research software! + +## Software with small user bases +Of course not everything is a whizzy package or web app with a public face, perhaps the essential software you've been working on is specific to a single project or research group. In this case your software is every bit as important but it can be harder to show evidence of this since it will be likely to have a very small user base. + +The approach is much the same here too, but qualitative evidence may prove to be very important indeed. Ask the PI for a very, *very* strong testimonial and collect grant values, numbers of students, publications _etc_. as well. + +On the other hand, consider early on in the project whether or not it can be designed in such a way that it can be used by a more general user base and/or be open source. This can require a bit more effort but in the grand scheme of things you could end up with a much larger group of users or even a community of user/developers, generating a far greater impact. + +## Finally + +Some final words: + +**Try to collect evidence proactively** - It's easier said than done, but try to plan ahead for a project how you might collect some evidence, it's not much fun but it will pay off in the future when you don't have to desperately scrabble for it - take it from me! + +**Disclaimer** - This certainly isn't a comprehensive guide, so if you think something is missing you can get in touch with me at `d.wilby [at] sheffield.ac.uk` and I'll update the post accordingly. + + +**Acknowledgements**: Many thanks to colleagues Bob Turner, Neil Shephard and Robert Chisholm for their useful input. + + +[^dora]: See the [Declaration on Research Assessment (DORA)](https://sfdora.org/) for more on the movement to improve the way researchers and scholarly work are evaluated. + +[^citations]: Flawed for many reasons as well, not least because of the massive disparity in citation rates across disciplines. + +[^Fang2011]: F.C. Fang, A. Casadevall (2011) *Retracted Science and the Retraction Index*. *Infection and Immunity* + +[^Nature2014]: *Why high-profile journals have more retractions.* *Nature* (2014). https://doi.org/10.1038/nature.2014.15951 + +[^REF]: Here in the UK, the government's [Research Excellence Framework](http://www.ref.ac.uk) (REF) has a major effect on the way research is assessed. In short, the REF asks universities to submit their best pieces of research output and demonstrations of research impact, ultimately determining how much government funding universities receive from government. This has a downstream effect on how academics are assessed for career progression. + +[^impactfactor]: Originally conceived as a metric to help librarians select journals to subscribe to, the impact factor is a measure of a journal's ratio of citations to papers published. \ No newline at end of file diff --git a/_posts/2022-10-20-better-code.md b/_posts/2022-10-20-better-code.md new file mode 100644 index 00000000..1bb46774 --- /dev/null +++ b/_posts/2022-10-20-better-code.md @@ -0,0 +1,104 @@ +--- +layout: post +title: "Writing better and more shareable code" +author: David Wilby +slug: 2022-10-20-better-code +date: 2022-10-20 12:00:00 UTC +tags: +category: +link: +description: +social_image: +type: text +excerpt_separator: +--- + +If you know how to write code, it's not actually that hard to make it better! You just need to know how. + +This quick blog is intended to be fairly non-specific with regard to programming language, my experience is mainly with Python & MATLAB, but I believe the principles should extend to any language. In theory. + +Firstly, what do I mean by "better" here? I mean: +* more readable +* less repetetive +* easier to debug +* less prone to errors +* simpler for others to use + +Let's get into it. + + + +## 0. Keep variable names descriptive +I've heard the terrible advice to "keep your variable names short, it saves memory and is quicker to type" - maybe this is the case if you have RAM that's measured in kiloBytes, but in most applications these days we aren't worried about the sizes of our source code files. So make your variable names clear and descriptive. + +I was once given a script where each variable was just called `A`, `B`, `C` and so on. Let me tell you, it was incredibly difficult to follow. + +Instead, use a variable name that describes its content, such as `temperature_recordings` or `raw_data_frame` - a variable should only contain one sort of data, which shouldn't really change throughout your code's execution. Which brings me on to.. + +## 1. Don't reuse variables +This concept may follow from using well-named variables. For instance, if your code performs some data cleaning and validation, each operation should assign a new variable. + +``` +data = "data/data.csv" + +data = read_data(data) + +data = clean_data(data) + +data = validate_data(data) +``` + +is a lot less readable than + +``` +data_path = "raw_data/01readings.csv" + +raw_data = read_data(data_path) + +cleaned_data = clean_data(raw_data) + +validated_data = validate_data(cleaned_data) +``` + +This may be especially true if you're writing your code in notebooks, in which the cells could be run in any order, meaning that if the same variable names are used throughout, it's very difficult to tell what they contain at any stage of execution. + +## 2. Use functions for repeated tasks +If you do the same job at many places throughout your code, instead of copying the same lines of code, write a function! +Functions take input variables (known as arguments), perform some operation and return a result. +In the above pseudocode example, `read_data()` might look like this: + +``` +function read_data(filepath): + data = read_csv(filepath) + return data +``` + +This is a very simple example, which already uses some imaginary built-in function called `read_csv()`, but if you need do do an operation numerous times, even with only a few lines of code, functions are the answer. This means that if you need to make a change, it only needs to be changed once in your code, and saves the mistake of missing one instance out. + +Functions also have the benefit, in many cases, of making software testing possible. This is a strategy which helps you to validate the correctness of your code and is a great next step for writing better code. + +## 3. Give functions sensible names +When you write a function, give it a sensible name, meaning that when reading your code it's easier to tell what that function is doing, just from its name, without having to go and read its source code. + +Sometimes a language or community (or even within a project) may have a convention on function names. For example, if the function acquires the value of a variable, its name may begin with `get_`. Look up the conventions or style guide for the language you're using. Following standard practice also makes your code easier to follow. + +Function names may also be a good indicator of whether you need to split your function down into smaller logical chunks. If you end up giving a function a very long name e.g. `add_numbers_and_export_them_to_spreadsheet`, then these steps may not logically go together, so should live in different functions. + +## 4. Comments? +Writing comments inline with code is something that most people writing code know about. But is it always the answer? +Yes, comments can help to explain what's going on in your code and all code should have some. +But if you find you are writing large amounts of comments in your code what might be better is to write your code in a way that inherently makes it easier to understand. +If you follow the steps discussed so far, you may find that your code explains itself and comments are only needed in a few places. + +## 5. Consider dependencies +If your code relies on another library, package or toolbox, that's what we call a dependency. Dependencies are needed to run your code, but aren't actually part of your codebase. In order for somone else to use your code (think about openly sharing your research) then they'll need to have those dependencies as well. +When writing your code, consider which depdendencies are required and make sure that when your code is shared, you also document which other dependencies are required and how to get hold of them. +One useful approach to dealing with dependencies is to turn you code into a package which will typically pull in the required dependencies when it is installed. +## Next steps? +These are all great steps to take and principles to consider when writing code. But how can we go further to write even better code? + +Examples of best practice in writing code include: +* software testing +* documentation +* dependency management +* version control \ No newline at end of file diff --git a/_posts/2022-12-20-upcoming-git-zero-to-hero.md b/_posts/2022-12-20-upcoming-git-zero-to-hero.md new file mode 100644 index 00000000..21065b0e --- /dev/null +++ b/_posts/2022-12-20-upcoming-git-zero-to-hero.md @@ -0,0 +1,49 @@ +--- +layout: post +title: "Upcoming : Git & GitHub through GitKraken - Zero to Hero!" +author: Neil Shephard +slug: 2022-12-20-upcoming-git-zero-to-hero +date: 2022-12-20 12:00:00 UTC +tags: git github gitkraken +category: +link: +description: +social_image: /assets/images/open_sign.jpg +type: text +excerpt_separator: +--- + +The RSE Team are pleased to announce three scheduled sessions of the increasingly popular [Git & GitHub through +GitKraken - Zero to Hero!](https://srse-git-github-zero2hero.netlify.app/). These courses will run over two consecutive +days in morning sessions from 09:30 to 13:00 on the following days. + +* [Thursday 26th/Friday 27th January 2023](/training/workshop/2023-01-26-git-zero-hero) +* [Monday 6th/Tuesday 7th March 2023](/training/workshop/2023-03-06-git-zero-hero) + +## What are Git, GitHub and GitKraken? + +[Git](https://git-scm.com) is a system of version controlling your code. Think of it as a lab-book or doctors notes that +are taken as you progress through your work, recording conditions, saving what has worked and correcting what doesn't. + +[GitHub](https://github.com) is a website that allows people to work collaboratively on version controlled code. + +[GitKraken](https://www.gitkraken.com) is a client for working with Git and GitHub that includes both a GUI (Graphical +User Interface) and a CLI (Command Line Interface) + +## Who is the course for? + +Everyone who writes code! If you write scripts to analyse your code in R, Stata or Matlab you would benefit from using +Git to version control your code and GitHub to share your code and make it open. If you write Python, JavaScript, C/++ +code as part of a team in your research group you would benefit from using Git and GitHub to work together. + +Getting started with these tools can be overwhelming but by taking this course you will be introduced to the concepts +behind them and how to use them effectively to not just version control your own work but work with others on the same +code. + +The course material is available [online](https://srse-git-github-zero2hero.netlify.app/) if you want to take a peek and +the first half using Git and publishing web-pages can be worked through in your own time. The real benefit comes from +participating in the collaborative exercises in the second half where you work together on projects making Pull Requests +and resolving problems that arise. + +If you've never used Git, GitHub or GitKraken or have only just started then sign-up and come and learn more about these +powerful tools. diff --git a/_posts/2022-12-22-git-blame.md b/_posts/2022-12-22-git-blame.md new file mode 100644 index 00000000..c87b02da --- /dev/null +++ b/_posts/2022-12-22-git-blame.md @@ -0,0 +1,101 @@ +--- +layout: post +title: "Who's to Blame?" +author: Neil Shephard +slug: git-blame +date: 2022-12-22 12:00:00 UTC +tags: git github gitlab +category: +link: +description: +social_image: assets/images/spider.jpg +type: text +excerpt_separator: +--- + +[Git blame](https://www.git-scm.com/docs/git-blame) shows who made changes to which line of code for a given point in +its history. This is useful if you are struggling to understand changes to a section of code as you can potentially +contact the author and gain some insight. + + + +# Usage + +Git blame works on individual files and so requires a filename, there are a host of options, for example `-e` prints the +authors email address `-w` ignores changes to white space and `-L 10,20` restricts output to the specified line +range. If you want a the blame for a specific revision then you must include the hash. + +```bash +git blame -e -w -L 10,20 f923la git_blame.org +``` + + + +For more detailed information on the array of options refer to the [official +documentation](https://www.git-scm.com/docs/git-blame) or see `git blame --help`. + +# Alias + +Some people don't like the pejorative nature of the word _blame_. That's ok though, with a tweak to your configuration +its possible to use the alias _praise_ or simply _who_ instead. + +```bash +# blame alias +git config --global alias.praise blame +git praise -L1,30 git_blame.org +# who alias +git config --global alias.who blame +git who -L1,30 git_blame.org +``` + + +# Ignoring blame + +Sometimes the case arises where you want to ignore blame. Perhaps the most common example is when an existing code base +has been [linted](pre-commit) to conform to a particular style guide. Looking at who performed these changes is not +informative and masks who made the changes and why. Its possible to ignore specific commits on the command line with +`--ignore-revs `, but it will quickly become tedious to remember to ignore all blame across multiple +commits. Fortunately you can save the commits to ignore to the file `.git-blame-ignore-revs` (along with comments) so +that they are stored. The full commit (40 characters) of hashes should be used. + +```bash +# PEP8 compliance for module X +c00177a6121f86c001f338feff3280fd576fdbf3 + +# PEP8 compliance for module Y +db27fa5f18299ca631efc430512a3f358c2b154f +``` + +Now that you have the revisions in place to be ignored when reporting blame you can choose not to use it. + +```bash +git blame --ignore-revs-file .gitblame-ignore-revs git_blame.org +``` + +...but this is tedious to remember to have to do each time and ideally others on your team should use this file too. You +can configure Git to use this file by modifying the local configuration. Make sure to add it to your repository so that +others can use it. + +```bash +git config blame.ignoreRevsFile .git-blame-ignore-revs +git add .git-blame-ignore-revs +``` + +As of [2022-03-08](https://github.com/orgs/community/discussions/5033#discussioncomment-2318478) GitHub will also +[ignore commits in the blame +view](https://docs.github.com/en/repositories/working-with-files/using-files/viewing-a-file#ignore-commits-in-the-blame-view) +that are listed in `.git-blame-ignore-revs` providing this file is in the root of your project folder. + +# Links + +## General + +* [Atlassian : git blame](https://www.atlassian.com/git/tutorials/inspecting-a-repository/git-blame) + +## Resources + +* [Ignoring bulk change commits with git + blame](https://www.moxio.com/blog/43/ignoring-bulk-change-commits-with-git-blame) +* [Little things I like to do with + Git](https://csswizardry.com/2017/05/little-things-i-like-to-do-with-git/#praise-people) +* [Is there a way to customize the output of git blame](https://stackoverflow.com/a/3959409/1444043) diff --git a/_posts/2023-04-17-training.md b/_posts/2023-04-17-training.md new file mode 100644 index 00000000..3e357fec --- /dev/null +++ b/_posts/2023-04-17-training.md @@ -0,0 +1,29 @@ +--- +layout: post +title: "Upcoming Training Courses" +author: David Wilby +slug: 2023-04-17-upcoming-training-courses +date: 2023-04-17 12:00:00 UTC +tags: git github training +category: +link: +description: +social_image: +type: text +excerpt_separator: +--- + +Exciting news! We have an upcoming series of training courses, free to researchers (including PhD Students) at the University of Sheffield. + +Follow the links below to find out more and register! + +* 2nd May: [Data management with SQL for researchers](/training/workshop/2023-05-02-sql) +* 9-10th May: [Plotting and Programming in Python](/training/workshop/2023-05-09-python) +* 23rd May: [Supercharge your research code with Git and GitHub](/training/workshop/2023-05-23-git) +* 24th May: [Data Analysis and Visualisation in R](/training/workshop/2023-05-24-R) (Sold Out) +* 13th June: [Unix Shell Fundamentals](/training/workshop/2023-03-03-unix-shell) (Sold Out) +* 14th/16th June: [Image Processing with Python](/training/workshop/2023-06-14-image-processing) +* 26th June: [Introduction to the Command Line for Bioinformatics](/training/workshop/2023-06-26-bioinformatics) +* 12-13th July: [Foundations of Astronomical Data Science](/training/workshop/2023-07-12-astro) + +More courses will be announced in the future so keep your eyes peeled for announcements, or [join the RSE community mailing list](https://groups.google.com/a/sheffield.ac.uk/g/rse-group) to be the first to find out! diff --git a/_posts/2023-08-18-benchmarking-flamegpu2-on-h100-a100-and-v100-gpus.md b/_posts/2023-08-18-benchmarking-flamegpu2-on-h100-a100-and-v100-gpus.md new file mode 100644 index 00000000..0c561fee --- /dev/null +++ b/_posts/2023-08-18-benchmarking-flamegpu2-on-h100-a100-and-v100-gpus.md @@ -0,0 +1,216 @@ +--- +layout: post +title: "Benchmarking FLAME GPU 2 on H100, A100 and V100 GPUs" +author: Peter Heywood +slug: 2023-08-18-benchmarking-flamegpu2-on-h100-a100-and-v100-gpus +date: 2023-08-18 12:00:00 UTC +tags: GPU FLAMEGPU benchmarking +category: +link: +description: +social_image: +type: text +excerpt_separator: +--- + +## H100 GPUs now available at the University of Sheffield + +Members of the University of Sheffield have access to a range of GPU resources for carrying out their research, available in local (Tier 3) and affiliated regional (Tier 2) HPC systems. + +**As of the 7th of August 2023, [12 new H100 PCIe GPUs][h100-live-email] (6 nodes, 2 GPUs per node) have been added to the [Stanage Tier 3 HPC facility][stanage] and are available for all users**. + +At the time of writing, the following GPUs are available for members of the university, free at the point of use: + ++ [Stanage][stanage-gpus] (Tier 3, The University of Sheffield): + + 60 public NVIDIA A100 SXM4 80GB GPUs + + 12 public NVIDIA H100 PCIe 80GB GPUs ++ [Bessemer][bessemer] (Tier 3, The University of Sheffield): + + [4 public][bessemer-gpus] NVIDIA Tesla V100 SXM2 32GB GPUs + + [32 private (Computer Science)][bessemer-dcs-gpus] NVIDIA Tesla V100 SXM2 32GB GPUS ++ [JADE 2][jade2] (Tier 2 - Machine Learning and Molecular Dynamics): + + 504 NVIDIA Tesla V100 MAXQ 32GB GPUs ++ [N8 CIR Bede][bede] (Tier 2 - PPC64LE CPUs & Multi-node jobs): + + 136 NVIDIA Tesla V100 SXM2 32GB GPUs with host-device NVLink + + 16 NVIDIA Tesla T4 16GB PCIe GPUs + +The newly available H100 GPUs in Stanage are the [300W PCIe variant][nvidia-h100-architecture], this means that for some workloads the university's 500W A100 SXM4 GPUs may offer higher performance (with higher power consumption). +For example, multi-GPU workloads which perform a large volume of GPU to GPU communication may be better suited to the A100 nodes than the H100 nodes. +The new H100 nodes in Stanage each contain 2 GPUs which are only connected via PCIe to the host. +The existing A100 nodes each contain 4 GPUs which are directly connected to one another via NVLink and are connected to the host via PCIe. +The NVLink interconnect offers higher memory bandwidth for GPU to GPU communication, which combined with twice as many GPUs per node may lead to shorter application run-times than offered by the H100 nodes. +If even more GPUs are required moving to the Tier 2 systems may be required, with Jade 2 offering up to 8 GPUs per Job, and Bede being the only current option for multi-node GPU jobs, with up to 128 GPUs per job. + + + +Within Stanage, software may need recompiling to run on the H100 nodes, or new versions of libraries may be required. For more information see the [HPC Documentation][stanage-using-gpus]. + +Carl Kennedy and Nicholas Musembi of the Research and Innovation Team in IT Services have [benchmarked these new GPUs using popular machine learning frameworks][h100-rcg-ml-benchmark], however not all HPC workloads exhibit the same performance characteristics as machine learning. + +## FLAME GPU 2 + + + +[![FLAME GPU 2 Logo](/assets/images/2023-08-18-benchmarking-flamegpu2-on-h100-a100-and-v100-gpus/flamegpu2-icon-256.png){: .img-fluid max-width="256px "}][flamegpu-website]{: .float-right .ml-2} + +[FLAME GPU 2][flamegpu2-repo] is an open-source GPU accelerated simulator for domain independent complex systems simulations using an agent-based modelling approach. +Models are implemented using CUDA C++ or Python 3, with modellers describing the behaviours of individuals within the simulation and how they interact with one another through message lists. +From these relatively simple agent behaviours and interactions, complex behaviours can emerge and be observed. +The underlying use of GPUs allows for much larger scale Agent Based Simulations than traditional CPU-based frameworks with high levels of performance, while abstracting the complexities of GPU programming away from the modeller. +A recent [NVIDIA blog][nvidia-blog-flamegpu2] post showed how, in certain scenarios, FLAME GPU is able to operate thousands of times faster than CPU alternatives. + +The default `BruteForce` communication pattern in FLAME GPU 2 provides global communication, with all agents reading all messages in the message list. +At large scales, this can be very costly and inefficient, so FLAME GPU 2 includes a number of specialised communication patterns to improve work-efficiency and performance where appropriate. +`Spatial3D` messaging is one of the available specialisations, which associates each message with a location in 3D space, and agents will only read messages from within a certain radius of their position, reducing the number of messages they read. + +FLAME GPU 2 also supports two methods of compilation / optimisation for agent functions. +When using the CUDA C++ interface, agent functions can be compiled off-line by NVCC like a typical CUDA / C++ program. +However, as the FLAME GPU 2 API allows model details to be defined at runtime, it is possible to generate more efficient code at run-time via Run-Time Compilation (RTC), which also enables writing agent functions in (a subset) of python 3. +RTC does add a one-time cost per agent function when executing the simulation for the first time, but long-running or repeated simulations amortize this cost. + +A more in-depth look at the design and use of FLAME GPU 2, with NVIDIA V100 and CUDA 11.0 benchmarking of a number of features is provided by our [recent publication][doi.org/10.1002/spe.3207]: + +> Richmond, P, Chisholm, R, Heywood, P, Chimeh, MK, Leach, M. "FLAME GPU 2: A framework for flexible and performant agent based simulation on GPUs". Softw: Pract Exper. 2023; 53(8): 1659–1680. [doi: 10.1002/spe.3207][doi.org/10.1002/spe.3207] + +## FLAME GPU 2 Circles Benchmark + +To understand how FLAME GPU 2 performs across the range of GPUs available at the University, and to further guide the development of FLAME GPU 2, we have re-benchmarked the "circles" model across the GPUs available in Stanage and Bessemer. + +The FLAME GPU 2 Circles model is a force-based particle model, where each particle (agent) has a position in 3D space. +The position is updated each time step by a "force" acting on the particle from other nearby particles. +The closer the particles, the greater the force they exert on each other. + +With random (uniform) initialisation of particles, the observed emergent behaviour of the model is that the particles will gradually form spheres over time, the scale of which depend on model parameters, as shown in the following figure. + +A more thorough description of the model is provided in Section 4.1 of ["FLAME GPU 2: A framework for flexible and performant agent based simulation on GPUs"][doi.org/10.1002/spe.3207]. + +![Figure 1: FLAME GPU 2 Circles Benchmark visualisation screenshots](/assets/images/2023-08-18-benchmarking-flamegpu2-on-h100-a100-and-v100-gpus/flamegpu2-circles-progression-1800-1200.png) + +The `circles-benchmark` binary runs multiple benchmark experiments to evaluate the performance under different conditions. +For this blog post, we are only interested in the `fixed-density` benchmark, which initialises the simulation with randomly positioned circles agents, with a fixed initial density as the size of the simulated environment is scaled. +The benchmark configuration runs simulations of with `10648` to `1000000` agents. + +4 Versions of the circles model were included, varying the communication strategy (BruteForce, Spatial3D) and optimisation/compilation method (non-RTC, RTC). +Each simulation was executed for `200` time steps, and was repeated `3` times to produce mean simulation execution times. + +Source code for the FLAME GPU 2 Circles benchmark can be found in the [FLAMEGPU/FLAMEGPU2-circles-benchmark][flamegpu2-circles-repo] GitHub repository. +Benchmark data was generated using FLAME GPU `2.0.0-rc`, with the `v2.0.0-rc` tag of the circles repository. + +CUDA 11.8 was used for all GPUs (via Apptainer for the V100s in Bessemer) with CMake configured for the appropriate CUDA Compute Capabilities. +`FLAMEGPU_SEATBELTS`, which provides better error messages and bounds checking, was disabled in the interest of performance. +All benchmarks were performed using a single GPU. + +| GPU | CPU | CUDA | CMAKE_CUDA_ARCHITECTURES | FLAMEGPU_SEATBELTS | +|:--------------|:---------------------|:-----|:-------------------------|--------------------| +| H100 PCIe 80G | AMD EPYC 7413 | 11.8 | `80;90` | `OFF` | +| A100 SXM4 80G | AMD EPYC 7413 | 11.8 | `80;90` | `OFF` | +| V100 SXM2 32G | Intel Xeon Gold 6138 | 11.8 | `70` | `OFF` | +{:.table.table-bordered.table-striped.table-hovered} + +For example, the `FLAMEGPU2-circles-benchmark` repository can be cloned, configured and compiled for A100 and H100 GPUs via: + +```bash +# Clone the benchmark repository and cd into it +git clone git@github.com:FLAMEGPU/FLAMEGPU2-circles-benchmark +cd FLAMEGPU2-circles-benchmark +# Create a build directory +mkdir -p build && cd build +# Configure CMake +cmake .. -DCMAKE_CUDA_ARCHITECTURES="80;90" -DFLAMEGPU_SEATBELTS=OFF +# Compile the binary +cmake --build . -j `nproc` +``` + +The binary was then executed within a slurm batch job (see [FLAMEGPU2-circles-benchmark/scripts/slurm](https://github.com/FLAMEGPU/FLAMEGPU2-circles-benchmark/tree/master/scripts/slurm)) containing: + +```bash +# Ensure run time compilation can find the correct include directory, ideally this wouldn't be required +export FLAMEGPU2_INC_DIR=_deps/flamegpu2-src/include +# Run the benchmark experiment, outputting csv files into the working directory +./bin/Release/circles-benchmark +``` + +### Brute Force Communication Performance + +Brute Force communication is the slower of the two communication patterns used for the 3D circles model, which only needs local interaction. +As each agent reads each message, complexity is quadratic with respect to the population size, and the most time consuming agent function will be limited by memory bandwidth. +Broadly speaking the newer the GPU and the higher the global memory bandwidth, the faster the simulation, with larger differences at larger scales. + +When using Run-time compilation, performance improves significantly. This is in part due to a reduction in the number of dependent global memory reads required to access agent data. + +![Figure 2: Circles Bruteforce - Mean Simulation Time (s) against Population Size](/assets/images/2023-08-18-benchmarking-flamegpu2-on-h100-a100-and-v100-gpus/plot-h100-a100-v100-cuda-118-fixed-density-circles_bruteforce.png) + +![Figure 3: Circles Bruteforce RTC - Mean Simulation Time (s) against Population Size](/assets/images/2023-08-18-benchmarking-flamegpu2-on-h100-a100-and-v100-gpus/plot-h100-a100-v100-cuda-118-fixed-density-circles_bruteforce_rtc.png) + +## Spatial 3D Communication Performance + +Using the much more work efficient Spatial 3D communication strategy, simulation run-times are significantly quicker than any of the brute-force benchmarks, with the largest simulations taking at most `0.944`s rather than `1457`s. +On average, each agent is only reading `204.5` messages, rather than all `1000000` messages each agent must read in the bruteforce case. +This greatly reduces the number of global memory reads performed and subsequently the impact of RTC is diminished although still significant. +As the initial density of the simulations and communication radius are maintained as the population is scaled, the average number of relevant messages is roughly comparable at each scale, resulting in a more linear relationship between simulation time and population size. + +![Figure 4: Circles Spatial3D - Mean Simulation Time (s) against Population Size](/assets/images/2023-08-18-benchmarking-flamegpu2-on-h100-a100-and-v100-gpus/plot-h100-a100-v100-cuda-118-fixed-density-circles_spatial3D.png) + +![Figure 5: Circles Spatial3D RTC - Mean Simulation Time (s) against Population Size](/assets/images/2023-08-18-benchmarking-flamegpu2-on-h100-a100-and-v100-gpus/plot-h100-a100-v100-cuda-118-fixed-density-circles_spatial3D_rtc.png) + +### Relative Performance against V100 SXM2 + +For simulations at the largest scale benchmarked, containing 1 million agents, compared to the V100 GPUs in Bessemer, the A100 and H100 GPUs in Stanage were up to `1.38` and `1.75` times faster respectively, as shown in the following figure and table. +The relative performance improvement is model and compilation method dependent. + +![Figure 6: Circles Benchmark relative Speedup against V100 SXM2 CUDA 11.8](/assets/images/2023-08-18-benchmarking-flamegpu2-on-h100-a100-and-v100-gpus/plot-speedup-v100-fixed-density-max-pop-V100_SXM2.png) + +| Benchmark | V100 SXM2 | A100 SXM4 | H100 PCIe | +|:-----------------------|------------:|------------:|------------:| +| circles_bruteforce | 1456.716 | 1071.347 | 944.221 | +| circles_bruteforce_rtc | 668.745 | 648.341 | 481.789 | +| circles_spatial3D | 0.944 | 0.685 | 0.551 | +| circles_spatial3D_rtc | 0.747 | 0.544 | 0.428 | +{:.table.table-bordered.table-striped.table-hovered} + +| Benchmark | V100 SXM2 | A100 SXM4 | H100 PCIe | +|:-----------------------|------------:|------------:|------------:| +| circles_bruteforce | 1.000 | 1.360 | 1.543 | +| circles_bruteforce_rtc | 1.000 | 1.031 | 1.388 | +| circles_spatial3D | 1.000 | 1.377 | 1.714 | +| circles_spatial3D_rtc | 1.000 | 1.374 | 1.746 | +{:.table.table-bordered.table-striped.table-hovered} + +## Summary + +Newer GPU architectures typically offer improved performance, and improved power efficiency. +Stanage, the University of Sheffield's newest Tier 3 HPC facility now contains NVIDIA A100 SXM4 80GB and NVIDIA H100 PCIe GPUs. +Using an artificial agent based modelling benchmark (circles) implemented using FLAME GPU 2, simulations of up to 1 million individual agents were benchmarked using GPUs in Stanage and Bessemer. +Relative performance improvements of up to `1.38`x and `1.75`x were demonstrated using the A100 and H100 GPUs respectively compared to the V100 GPUs in Bessemer, demonstrating some of the capabilities of these newer GPUs. + +### More information + +For more information on the GPU resources available at the University of Sheffield, please see the HPC documentation for [Stanage][stanage-gpus], [Bessemer][bessemer-gpus], [JADE 2][jade2] & [Bede][bede]. +The [ITS Research and Innovation Team "Machine Benchmarking A100 and H100 GPUs on Stanage" blog post][h100-rcg-ml-benchmark] provides benchmarking of some Machine Learning frameworks within Stanage. + +More information on FLAME GPU 2 can be found at [flamegpu.com][flamegpu-website], the [FLAMEGPU/FLAMEGPU2 GitHub repository][flamegpu2-repo], in the [FLAME GPU 2 documentation][flamegpu2-docs] and in our recent publication ["FLAME GPU 2: A framework for flexible and performant agent based simulation on GPUs"][doi.org/10.1002/spe.3207]. + +The benchmark model, raw data and plotting scripts can be found in the [FLAMEGPU/FLAMEGPU2-circles-benchmark GitHub repository][flamegpu2-circles-repo]. + +If you have any questions regarding FLAME GPU 2, feel free to [open a discussion topic on GitHub][flamegpu2-discussions] or [contact us][rse-contact-us]. + + +[doi.org/10.1002/spe.3207]: https://doi.org/10.1002/spe.3207 + +[flamegpu-website]: https://flamegpu.com +[flamegpu2-docs]: https://docs.flamegpu.com +[flamegpu2-repo]: https://github.com/FLAMEGPU/FLAMEGPU2 +[flamegpu2-discussions]: https://github.com/FLAMEGPU/FLAMEGPU2/discussions +[flamegpu2-circles-repo]: https://github.com/FLAMEGPU/FLAMEGPU2-circles-benchmark +[stanage]: https://docs.hpc.shef.ac.uk/en/latest/stanage/ +[stanage-gpus]: https://docs.hpc.shef.ac.uk/en/latest/stanage/cluster_specs.html#gpu-nodes +[stanage-using-gpus]: https://docs.hpc.shef.ac.uk/en/latest/stanage/GPUComputingStanage.html +[bessemer]: https://docs.hpc.shef.ac.uk/en/latest/bessemer/index.html +[bessemer-gpus]: https://docs.hpc.shef.ac.uk/en/latest/bessemer/cluster_specs.html#gpu-node-specifications +[bessemer-dcs-gpus]: https://docs.hpc.shef.ac.uk/en/latest/bessemer/groupnodes/dcs-gpu-nodes.html +[jade2]: https://docs.hpc.shef.ac.uk/en/latest/other-uk-hpc-resources/jade2.html +[bede]: https://docs.hpc.shef.ac.uk/en/latest/other-uk-hpc-resources/bede.html +[h100-live-email]: https://mailchi.mp/dfcdc60d2faa/new-hpc-stanage-is-live-17068304 +[h100-rcg-ml-benchmark]: https://notesrcg.blogspot.com/2023/08/Stanage-HPC-new-h100-gpus-available-benchmarking.html +[nvidia-h100-architecture]: https://resources.nvidia.com/en-us-tensor-core +[rse-contact-us]: https://rse.shef.ac.uk/contact/ +[nvidia-blog-flamegpu2]: https://developer.nvidia.com/blog/fast-large-scale-agent-based-simulations-on-nvidia-gpus-with-flame-gpu/ diff --git a/_project_descriptions/airqo.md b/_project_descriptions/airqo.md index f067bc2a..fa8fb4dd 100644 --- a/_project_descriptions/airqo.md +++ b/_project_descriptions/airqo.md @@ -8,4 +8,4 @@ AirQo has a strong team of academics and software engineers, mostly based at Mak AirQo shares its code via its [GitHub organisation](https://github.com/airqo-platform). In addition to live air quality data, [blog posts](https://www.airqo.net/blog) describe some recent milestones. -The project outputs are hoped to include improved descisions based on newly available air quality data and information derived from machine learning. Ultimately this will improve air quality and health in Kampala and other African cities. \ No newline at end of file +The project outputs are hoped to include improved decisions based on newly available air quality data and information derived from machine learning. Ultimately this will improve air quality and health in Kampala and other African cities. \ No newline at end of file diff --git a/_project_descriptions/flamegpu2.md b/_project_descriptions/flamegpu2.md new file mode 100644 index 00000000..a4745c73 --- /dev/null +++ b/_project_descriptions/flamegpu2.md @@ -0,0 +1,18 @@ +--- +key: flamegpu2 +--- + +[FLAME GPU 2](https://flamegpu.com/) (Flexible Large Scale Agent Modelling Environment for GPUs) is a framework for developing highly parallel complex system simulations, allowing modellers to write their models using C++ or Python without an explicit understanding of CUDA or GPU optimisation strategies. Version 2 follows on from the original FLAME GPU developed by Dr Paul Richmond, and has been rewritten from the ground up to provide greater flexibility and replaces the template driven architecture with modern C++ and Python APIs. The software currently underpins exciting research into crowd modelling under social distancing, simulation of tumour growth in cancer research, and modelling of the immune system. + +FLAME GPU 2 adds a range of new features which ensure performant model simulation. E.g. + +* **Support for Big GPUs** - Support for concurrent execution of agents functions which ensures that heterogenous models do not necessarily result in poor device utilisation. +* **Model Ensembles** - The ability to run ensembles of models. I.e. the same model with different parameters or random seeds. This is necessary within stochastic simulation and FLAME GPU allows the specification of ensembles to occupy multiple devices on a single computing node. +* **Sub models** - Certain behaviours in FLAME GPU require iterative processes to ensure reproducibility with serial counterparts (e.g. conflict resolution for resources). FLAME GPU 2 allows re-usable sub models to be described for such behaviours so that it can be abstracted from the rest of the model function. + +Development and maintenance of FLAME GPU 2 has and continues to be supported by other projects taken on by the team which use FLAME GPU and/or FLAME GPU 2, and an ESPRC fellowship granted to Dr Paul Richmond. + +This talk from GTC 2021 by Dr Paul Richmond provides a thorough introduction to FLAME GPU 2: + + + diff --git a/_project_descriptions/floodfotm.md b/_project_descriptions/floodfotm.md new file mode 100644 index 00000000..88724527 --- /dev/null +++ b/_project_descriptions/floodfotm.md @@ -0,0 +1,7 @@ +--- +key: floodfotm +--- + +The [Festival of the Mind](https://festivalofthemind.sheffield.ac.uk/2020/) is an annual festival hosted by the University of Sheffield with the aim of bringing together academics, professionals and the public to bring research to life. The 2020 festival featured the [Futurecade](https://festivalofthemind.sheffield.ac.uk/2020/futurecade/) which showcased work using virtual reality and environments. One such project was simulating crowd responses to flooding. The work titled [Planning for the Next Great Flood](https://festivalofthemind.sheffield.ac.uk/2020/futurecade/planning-for-the-next-great-flood/) was led by research student Mohammad Shirvani. + +The University of Sheffield's [RSE team](https://rse.shef.ac.uk/) provided technical advice and software engineering support. The simulation was built using [FLAMEGPU](http://www.flamegpu.com/), an agent based modelling framework by the Sheffield RSE team which simplifies leveraging high performance GPUs. Advice was given on implementation using FLAMEGPU, and the RSE team's developer integrated the simulation with a custom visualisation using Unreal Engine 4. \ No newline at end of file diff --git a/_project_descriptions/gpy.md b/_project_descriptions/gpy.md index 35e8375d..ae0b7606 100644 --- a/_project_descriptions/gpy.md +++ b/_project_descriptions/gpy.md @@ -4,7 +4,7 @@ key: gpy Multiple output Gaussian processes are useful where several different measurements are made at different points in a parameter space, but not all measurements are made at each point. For example: - + A Gaussian process model can be created that allows prediction, with a measure of uncertainty, of any of the measurements at any point in the space. Furthermore, [inference of underlying functions driving the measurements](http://proceedings.mlr.press/v5/alvarez09a/alvarez09a.pdf) is also possible. diff --git a/_project_descriptions/holeintheroad.md b/_project_descriptions/holeintheroad.md new file mode 100644 index 00000000..0021c42a --- /dev/null +++ b/_project_descriptions/holeintheroad.md @@ -0,0 +1,7 @@ +--- +key: holeintheroad +--- + +The [Festival of the Mind](https://digitalmedia.sheffield.ac.uk/media/Festival+of+the+Mind+2016/1_0n59ye7o) is an annual festival hosted by the University of Sheffield with the aim of bringing together academics, professionals and the public to bring research to life. The 2016 festival featured the [Virtual Hole in the Road](https://digitalmedia.sheffield.ac.uk/media/The+Virtual+Hole+in+the+Road/1_lgoq4e7q) exhibit, which showcased a virtual reality recreation of the much loved "Hole in the Road", a former open-air underground complex set beneath a roundabout in Sheffield. + +The University of Sheffield's [Visual Computing group](https://www.sheffield.ac.uk/dcs/research/groups/visual-computing) and [RSE team](https://rse.shef.ac.uk/) worked to provide virtual reality and software development expertise, bringing the 3D model created by [Human](https://humanstudio.com/) to life. The project was incredibly popular with the public and has been used as a demonstration of the VR technology many times since its initial presentation at the Festival of the Mind in 2016. \ No newline at end of file diff --git a/_sass/theme/_base.scss b/_sass/theme/_base.scss index 2798ae45..a0f2de8a 100644 --- a/_sass/theme/_base.scss +++ b/_sass/theme/_base.scss @@ -1,15 +1,28 @@ /* ======= Base ======= */ + @font-face { - font-family: 'tuos_stephensonbold'; - src: url('/assets/fonts/stephbd-webfont.woff2') format('woff2'), - url('/assets/fonts/stephbd-webfont.woff') format('woff'); + font-family: uos-sans; + src: url('../fonts/SourceSansPro-Regular.ttf') format("truetype"); font-weight: normal; font-style: normal; + } -} +@font-face { + font-family: uos-serif; + src: url('../fonts/SourceSerifPro-Regular.ttf') format("truetype"); + font-weight: normal; + font-style: normal; + } + +@font-face { + font-family: uos-mono; + src: url('../fonts/SourceCodePro-VariableFont_wght.ttf') format("truetype"); + font-weight: normal; + font-style: monospace; + } body { - font-family: 'Lato', arial, sans-serif; + font-family: 'uos-sans', arial, sans-serif; color: $text-color; font-size: 16px; -webkit-font-smoothing: antialiased; @@ -18,7 +31,7 @@ body { } h1, h2, h3, h4, h5, h6 { - font-family: 'Montserrat', sans-serif; + font-family: 'uos-sans', sans-serif; font-weight: 700; color: $color; } @@ -34,7 +47,7 @@ a { .btn, a.btn { @include transition (all 0.4s ease-in-out); - font-family: 'Montserrat', arial, sans-serif; + font-family: 'uos-sans', arial, sans-serif; padding: 8px 16px; font-weight:bold; .svg-inline--fa { @@ -157,12 +170,11 @@ pre code { .nav-item { font-weight: bold; margin-right: 30px; - font-family: 'Montserrat', sans-serif; + font-family: 'uos-sans', sans-serif; .nav-link { color: darken($color, 25%); @include transition (none); - font-size: 14px; padding: 15px 10px; &.active { color: $color; @@ -239,7 +251,6 @@ pre code { } .social-media { - background: darken($color, 15%); padding: 10px 0; margin: 0 auto; li { diff --git a/assets/css/custom.css b/assets/css/custom.css index 2876134d..e064ddfb 100644 --- a/assets/css/custom.css +++ b/assets/css/custom.css @@ -12,12 +12,73 @@ xl @media (min-width:1200px) */ +:root { + --uos-deep-violet: #440099; + --uos-deep-violet-90: #541aa4; + --uos-deep-violet-80: #6431ac; + --uos-deep-violet-70: #784bb6; + --uos-powder-blue: #9ADBE8; + --uos-powder-blue-90: #9fddea; + --uos-powder-blue-80: #ade0eb; + --uos-powder-blue-70: #b6e6ee; + --uos-midnight-black: #131E29; + --uos-midnight-black-90: #2c3841; + --uos-midnight-black-80: #424a54; + --uos-midnight-black-70: #57636b; + --uos-teal: #005A8F; + --uos-aqua: #00BBCC; + --uos-mint-green: #00CE7C; + --uos-coral: #E7004C; + --uos-peach: #FF9664; +} + +body { + color: var(--uos-midnight-black-90) +} + +.header{ + background-color: var(--white); +} + +.promo{ + background: var(--uos-midnight-black); +} + +.footer{ + background: var(--uos-midnight-black); +} + +/* Sizes for h1 to h6, overriding bootstrap css */ +h1, .h1 { font-size: 2.5rem; } +h2, .h2 { font-size: 2rem; } +h3, .h3 { font-size: 1.75rem; } +h4, .h4 { font-size: 1.5rem; } +h5, .h5 { font-size: 1.25rem; } +h6, .h6 { font-size: 1rem; } + +h1, h2, h3, h4, h5, h6 { + color: var(--uos-deep-violet); +} + +a { + color: var(--uos-deep-violet); +} + .nav-link{ - color: #1c3248 !important; + color: var(--uos-midnight-black) !important; +} + +.contact { + background: var(--uos-midnight-black); } .contact-inner a { - color: #1c3248 !important; + color: var(--uos-powder-blue); + text-decoration: underline; +} + +.contact-inner h2 { + color: var(--white) !important; } .seminar-section { @@ -40,7 +101,7 @@ img { /* Visually distinguish past events.*/ .event-item-previous a { - color: #656565; + color: var(--uos-deep-violet-70); } .event-item-previous > div >img { opacity: 0.40; @@ -52,10 +113,54 @@ figcaption { font-size: small; } +/* Style Pagination of Blogposts */ +.pagination a, .pagination span { + padding: 7px 18px; + border: 1px solid #eee; + margin-left: -2px; + margin-right: -2px; + margin-bottom: 0px; + background-color: var(--white)fff; + display: inline-block; +} +.pagination a:hover { + background-color: #f1f1f1; + text-decoration: none; +} +.pagination a { + cursor: pointer; +} +.pagination { + text-align: center; +} +/* Adjust heading sizes for blog-excerpts */ +.blog-excerpt h1, .blog-excerpt .h1 { font-size: 2rem; } +.blog-excerpt h2, .blog-excerpt .h2 { font-size: 1.75rem; } +.blog-excerpt h3, .blog-excerpt .h3 { font-size: 1.5rem; } +.blog-excerpt h4, .blog-excerpt .h4 { font-size: 1.25rem; } +.blog-excerpt h5, .blog-excerpt .h5 { font-size: 1rem; } +.blog-excerpt h6, .blog-excerpt .h6 { font-size: 1rem; } /* No h7 to steal a size from */ + + hr.blog-post-seperator { + width: 50%; /*Differentiate hr, to those used within markdown/blog posts*/ + border-top: 2px solid; + margin-top: 32px; /*2 rem, double end of paragraph*/ + margin-bottom: 32px; +} +div.pagination-wrapper { + justify-content: center; + flex-flow:row wrap; + display: flex; +} +div.all-posts { + flex-basis: 100%; + text-align: center; + margin-bottom: 16px; /*1 rem, same as end of paragraph*/ +} /* Extra custom styling for pre / code blocks */ pre { - background-color: #282a36; + background-color: var(--uos-midnight-black); padding: 1em; margin: 0 0 1em 0; border-radius: 0.4em; @@ -71,6 +176,16 @@ pre { } +/* comments in code blocks */ +pre.highlight > code > span.c, pre.highlight > code > span.c1 { + color: var(--uos-peach); +} + +code { + color: var(--uos-coral); + font-family: monospace; +} + .highlight { border-radius: 0.4em; } @@ -84,8 +199,8 @@ pre.highlight{ blockquote { margin: 0 0 1rem 0; padding: 0 1rem; - color: #6a6a6a; - border-left: .3rem solid #6a6a6a; + color: var(--uos-midnight-black-80); + border-left: .3rem solid var(--uos-midnight-black-80); } /* optionally make .btn's wrap text */ @@ -93,10 +208,44 @@ blockquote { white-space: normal; } +.btn-primary { + background-color: var(--uos-powder-blue); + border-color: var(--uos-powder-blue); + color: var(--uos-midnight-black); +} + +.btn-primary:hover { + background-color: var(--uos-deep-violet); + border-color: var(--uos-deep-violet); + color: var(--white); +} + +.btn-success { + background-color: var(--uos-mint-green); + border-color: var(--uos-mint-green); + color: var(--uos-midnight-black); +} + +.btn-success:hover { + background-color: var(--uos-deep-violet); + border-color: var(--uos-deep-violet); + color: var(--white); +} + .sm-a { - color: #b0ea44; + color: var(--uos-powder-blue); + text-decoration: underline; } .sm-a:hover{ - color: #e2e2e2; + color: var(--uos-powder-blue); +} + +a:hover { + color: var(--uos-deep-violet); +} + +/* project page tag cloud */ +a.tag-link.selected, a.filter-link.selected{ + font-weight: bold; } diff --git a/assets/css/theme-3.scss b/assets/css/theme-3.scss index cc096a65..7229bbc2 100644 --- a/assets/css/theme-3.scss +++ b/assets/css/theme-3.scss @@ -12,7 +12,7 @@ //*************************** Theme Colours ****************************/ // Define theme colour scheme -$color: #6690b9; +$color: #507aa3; $color-2: #f46fa3; $text-color: #444; diff --git a/assets/fonts/SourceCodePro-VariableFont_wght.ttf b/assets/fonts/SourceCodePro-VariableFont_wght.ttf new file mode 100644 index 00000000..cd96a614 Binary files /dev/null and b/assets/fonts/SourceCodePro-VariableFont_wght.ttf differ diff --git a/assets/fonts/SourceSansPro-Regular.ttf b/assets/fonts/SourceSansPro-Regular.ttf new file mode 100644 index 00000000..98e85797 Binary files /dev/null and b/assets/fonts/SourceSansPro-Regular.ttf differ diff --git a/assets/fonts/SourceSerifPro-Regular.ttf b/assets/fonts/SourceSerifPro-Regular.ttf new file mode 100644 index 00000000..5c593b99 Binary files /dev/null and b/assets/fonts/SourceSerifPro-Regular.ttf differ diff --git a/assets/fonts/StephIt.ttf b/assets/fonts/StephIt.ttf deleted file mode 100644 index 028e9147..00000000 Binary files a/assets/fonts/StephIt.ttf and /dev/null differ diff --git a/assets/fonts/stephbd-webfont.woff b/assets/fonts/stephbd-webfont.woff deleted file mode 100644 index c1928f3f..00000000 Binary files a/assets/fonts/stephbd-webfont.woff and /dev/null differ diff --git a/assets/fonts/stephbd-webfont.woff2 b/assets/fonts/stephbd-webfont.woff2 deleted file mode 100644 index a2f32e5c..00000000 Binary files a/assets/fonts/stephbd-webfont.woff2 and /dev/null differ diff --git a/assets/images/2023-08-18-benchmarking-flamegpu2-on-h100-a100-and-v100-gpus/flamegpu2-circles-progression-1800-1200.png b/assets/images/2023-08-18-benchmarking-flamegpu2-on-h100-a100-and-v100-gpus/flamegpu2-circles-progression-1800-1200.png new file mode 100644 index 00000000..6be5c86c Binary files /dev/null and b/assets/images/2023-08-18-benchmarking-flamegpu2-on-h100-a100-and-v100-gpus/flamegpu2-circles-progression-1800-1200.png differ diff --git a/assets/images/2023-08-18-benchmarking-flamegpu2-on-h100-a100-and-v100-gpus/flamegpu2-icon-256.png b/assets/images/2023-08-18-benchmarking-flamegpu2-on-h100-a100-and-v100-gpus/flamegpu2-icon-256.png new file mode 100644 index 00000000..29167dba Binary files /dev/null and b/assets/images/2023-08-18-benchmarking-flamegpu2-on-h100-a100-and-v100-gpus/flamegpu2-icon-256.png differ diff --git a/assets/images/2023-08-18-benchmarking-flamegpu2-on-h100-a100-and-v100-gpus/plot-h100-a100-v100-cuda-118-fixed-density-circles_bruteforce.png b/assets/images/2023-08-18-benchmarking-flamegpu2-on-h100-a100-and-v100-gpus/plot-h100-a100-v100-cuda-118-fixed-density-circles_bruteforce.png new file mode 100644 index 00000000..151df3c7 Binary files /dev/null and b/assets/images/2023-08-18-benchmarking-flamegpu2-on-h100-a100-and-v100-gpus/plot-h100-a100-v100-cuda-118-fixed-density-circles_bruteforce.png differ diff --git a/assets/images/2023-08-18-benchmarking-flamegpu2-on-h100-a100-and-v100-gpus/plot-h100-a100-v100-cuda-118-fixed-density-circles_bruteforce_rtc.png b/assets/images/2023-08-18-benchmarking-flamegpu2-on-h100-a100-and-v100-gpus/plot-h100-a100-v100-cuda-118-fixed-density-circles_bruteforce_rtc.png new file mode 100644 index 00000000..3e49fcad Binary files /dev/null and b/assets/images/2023-08-18-benchmarking-flamegpu2-on-h100-a100-and-v100-gpus/plot-h100-a100-v100-cuda-118-fixed-density-circles_bruteforce_rtc.png differ diff --git a/assets/images/2023-08-18-benchmarking-flamegpu2-on-h100-a100-and-v100-gpus/plot-h100-a100-v100-cuda-118-fixed-density-circles_spatial3D.png b/assets/images/2023-08-18-benchmarking-flamegpu2-on-h100-a100-and-v100-gpus/plot-h100-a100-v100-cuda-118-fixed-density-circles_spatial3D.png new file mode 100644 index 00000000..5b536413 Binary files /dev/null and b/assets/images/2023-08-18-benchmarking-flamegpu2-on-h100-a100-and-v100-gpus/plot-h100-a100-v100-cuda-118-fixed-density-circles_spatial3D.png differ diff --git a/assets/images/2023-08-18-benchmarking-flamegpu2-on-h100-a100-and-v100-gpus/plot-h100-a100-v100-cuda-118-fixed-density-circles_spatial3D_rtc.png b/assets/images/2023-08-18-benchmarking-flamegpu2-on-h100-a100-and-v100-gpus/plot-h100-a100-v100-cuda-118-fixed-density-circles_spatial3D_rtc.png new file mode 100644 index 00000000..a4bbdf31 Binary files /dev/null and b/assets/images/2023-08-18-benchmarking-flamegpu2-on-h100-a100-and-v100-gpus/plot-h100-a100-v100-cuda-118-fixed-density-circles_spatial3D_rtc.png differ diff --git a/assets/images/2023-08-18-benchmarking-flamegpu2-on-h100-a100-and-v100-gpus/plot-speedup-v100-fixed-density-max-pop-V100_SXM2.png b/assets/images/2023-08-18-benchmarking-flamegpu2-on-h100-a100-and-v100-gpus/plot-speedup-v100-fixed-density-max-pop-V100_SXM2.png new file mode 100644 index 00000000..4f5ea118 Binary files /dev/null and b/assets/images/2023-08-18-benchmarking-flamegpu2-on-h100-a100-and-v100-gpus/plot-speedup-v100-fixed-density-max-pop-V100_SXM2.png differ diff --git a/assets/images/blog-git-tools/gitkrakenclient.png b/assets/images/blog-git-tools/gitkrakenclient.png new file mode 100644 index 00000000..2abae446 Binary files /dev/null and b/assets/images/blog-git-tools/gitkrakenclient.png differ diff --git a/assets/images/coffee-pexels-pixabay-414630.jpg b/assets/images/coffee-pexels-pixabay-414630.jpg new file mode 100644 index 00000000..cdd1eae1 Binary files /dev/null and b/assets/images/coffee-pexels-pixabay-414630.jpg differ diff --git a/assets/images/colab.jfif b/assets/images/colab.jfif new file mode 100644 index 00000000..9324dd5e Binary files /dev/null and b/assets/images/colab.jfif differ diff --git a/assets/images/containers.jpg b/assets/images/containers.jpg new file mode 100644 index 00000000..9c70e860 Binary files /dev/null and b/assets/images/containers.jpg differ diff --git a/assets/images/favicons/android-chrome-192x192.png b/assets/images/favicons/android-chrome-192x192.png new file mode 100644 index 00000000..c87a53c9 Binary files /dev/null and b/assets/images/favicons/android-chrome-192x192.png differ diff --git a/assets/images/favicons/android-chrome-256x256.png b/assets/images/favicons/android-chrome-256x256.png new file mode 100644 index 00000000..2bdc5a10 Binary files /dev/null and b/assets/images/favicons/android-chrome-256x256.png differ diff --git a/assets/images/favicons/apple-touch-icon.png b/assets/images/favicons/apple-touch-icon.png new file mode 100644 index 00000000..d48a5aae Binary files /dev/null and b/assets/images/favicons/apple-touch-icon.png differ diff --git a/assets/images/favicons/browserconfig.xml b/assets/images/favicons/browserconfig.xml new file mode 100644 index 00000000..c6bf18bc --- /dev/null +++ b/assets/images/favicons/browserconfig.xml @@ -0,0 +1,9 @@ + + + + + + #da532c + + + diff --git a/assets/images/favicons/favicon-16x16.png b/assets/images/favicons/favicon-16x16.png new file mode 100644 index 00000000..adda1f8a Binary files /dev/null and b/assets/images/favicons/favicon-16x16.png differ diff --git a/assets/images/favicons/favicon-32x32.png b/assets/images/favicons/favicon-32x32.png new file mode 100644 index 00000000..a9cfa5cb Binary files /dev/null and b/assets/images/favicons/favicon-32x32.png differ diff --git a/assets/images/favicons/favicon.ico b/assets/images/favicons/favicon.ico new file mode 100644 index 00000000..cb450c5c Binary files /dev/null and b/assets/images/favicons/favicon.ico differ diff --git a/assets/images/favicons/mstile-150x150.png b/assets/images/favicons/mstile-150x150.png new file mode 100644 index 00000000..613d3496 Binary files /dev/null and b/assets/images/favicons/mstile-150x150.png differ diff --git a/assets/images/favicons/site.webmanifest b/assets/images/favicons/site.webmanifest new file mode 100644 index 00000000..e538f7d8 --- /dev/null +++ b/assets/images/favicons/site.webmanifest @@ -0,0 +1,19 @@ +{ + "name": "", + "short_name": "", + "icons": [ + { + "src": "/assets/images/favicons/android-chrome-192x192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "/assets/images/favicons/android-chrome-256x256.png", + "sizes": "256x256", + "type": "image/png" + } + ], + "theme_color": "#ffffff", + "background_color": "#ffffff", + "display": "standalone" +} diff --git a/assets/images/hacker.jpg b/assets/images/hacker.jpg new file mode 100644 index 00000000..28d828a0 Binary files /dev/null and b/assets/images/hacker.jpg differ diff --git a/assets/images/jose-aljovin-l6dnswlRZyE-unsplash.jpg b/assets/images/jose-aljovin-l6dnswlRZyE-unsplash.jpg new file mode 100644 index 00000000..ede42d5a Binary files /dev/null and b/assets/images/jose-aljovin-l6dnswlRZyE-unsplash.jpg differ diff --git a/assets/images/logo/TUOS_PRIMARY_LOGO_FULL_COLOUR.png b/assets/images/logo/TUOS_PRIMARY_LOGO_FULL_COLOUR.png deleted file mode 100644 index 6e624bd8..00000000 Binary files a/assets/images/logo/TUOS_PRIMARY_LOGO_FULL_COLOUR.png and /dev/null differ diff --git a/assets/images/logo/UoS_Violet_RSE.png b/assets/images/logo/UoS_Violet_RSE.png new file mode 100644 index 00000000..6b2f0738 Binary files /dev/null and b/assets/images/logo/UoS_Violet_RSE.png differ diff --git a/assets/images/matlab-repro-blog/matlab-publish.png b/assets/images/matlab-repro-blog/matlab-publish.png new file mode 100644 index 00000000..aa722d0d Binary files /dev/null and b/assets/images/matlab-repro-blog/matlab-publish.png differ diff --git a/assets/images/matlab-repro-blog/pdf-output.png b/assets/images/matlab-repro-blog/pdf-output.png new file mode 100644 index 00000000..20951fec Binary files /dev/null and b/assets/images/matlab-repro-blog/pdf-output.png differ diff --git a/assets/images/matlab-repro-blog/run-tests.png b/assets/images/matlab-repro-blog/run-tests.png new file mode 100644 index 00000000..866df328 Binary files /dev/null and b/assets/images/matlab-repro-blog/run-tests.png differ diff --git a/assets/images/museums-victoria-G9Yy-iitjjg-unsplash.jpg b/assets/images/museums-victoria-G9Yy-iitjjg-unsplash.jpg new file mode 100644 index 00000000..117994f7 Binary files /dev/null and b/assets/images/museums-victoria-G9Yy-iitjjg-unsplash.jpg differ diff --git a/assets/images/spider.jpg b/assets/images/spider.jpg new file mode 100644 index 00000000..9879a850 Binary files /dev/null and b/assets/images/spider.jpg differ diff --git a/assets/images/watchful_eye.jpg b/assets/images/watchful_eye.jpg new file mode 100644 index 00000000..33944f9c Binary files /dev/null and b/assets/images/watchful_eye.jpg differ diff --git a/assets/js/main.js b/assets/js/main.js index 82fd35a7..81105293 100644 --- a/assets/js/main.js +++ b/assets/js/main.js @@ -1,77 +1,79 @@ -jQuery(document).ready(function($) { +jQuery(document).ready(function ($) { + // Set the dayjs locale, datetimes are all in gmt/bst + dayjs.locale('en') /* ======= Scrollspy ======= */ - $('body').scrollspy({ target: '#header', offset: 400}); - + $('body').scrollspy({ target: '#header', offset: 400 }); + /* ======= Fixed header when scrolled ======= */ - - $(window).bind('scroll', function() { - if ($(window).scrollTop() > 50) { - $('#header').addClass('navbar-fixed-top'); - } - else { - $('#header').removeClass('navbar-fixed-top'); - } + + $(window).bind('scroll', function () { + if ($(window).scrollTop() > 50) { + $('#header').addClass('navbar-fixed-top'); + } + else { + $('#header').removeClass('navbar-fixed-top'); + } }); - + /* ======= ScrollTo ======= */ - $('a.scrollto').on('click', function(e){ - + $('a.scrollto').on('click', function (e) { + //store hash var target = this.hash; - + e.preventDefault(); - - $('body').scrollTo(target, 800, {offset: -70, 'axis':'y', easing:'easeOutQuad'}); + + $('body').scrollTo(target, 800, { offset: -70, 'axis': 'y', easing: 'easeOutQuad' }); //Collapse mobile menu after clicking - if ($('.navbar-collapse').hasClass('show')){ - $('.navbar-collapse').removeClass('show'); - } - - }); + if ($('.navbar-collapse').hasClass('show')) { + $('.navbar-collapse').removeClass('show'); + } + + }); /* ======= Upcoming/Previous events ======= */ //We assume that events have already been sorted in a reverse chronological order, if headings are being inserted. - $('.event-listing').each(function(index){ - var eventListing = $(this); + $('.event-listing').each(function (index) { + var eventListing = $(this); - var displayUpcoming = true; - var displayPrevious = true; - var displayHeaders = false; - var chronologicalUpcoming = true; + var displayUpcoming = true; + var displayPrevious = true; + var displayHeaders = false; + var chronologicalUpcoming = true; - if(eventListing.hasClass("event-upcoming-previous")){ - displayUpcoming = true; - displayPrevious = true; + if (eventListing.hasClass("event-upcoming-previous")) { + displayUpcoming = true; + displayPrevious = true; } - else if(eventListing.hasClass("event-upcoming")){ + else if (eventListing.hasClass("event-upcoming")) { displayUpcoming = true; displayPrevious = false; } - if(eventListing.hasClass("event-insert-header")){ + if (eventListing.hasClass("event-insert-header")) { displayHeaders = true; } - var currentTime = moment(); + var currentTime = dayjs(); var upcomingNotAdded = true; var prevNotAdded = true; //Events filtering - eventListing.find(".event-item").each(function(){ + eventListing.find(".event-item").each(function () { var eventItem = $(this); - var eventDate = moment(eventItem.data("date")); + var eventDate = dayjs(eventItem.data("date")); - if(eventDate.isSameOrAfter(currentTime)){ - if(displayUpcoming){ + if (eventDate.isSame(currentTime) || eventDate.isAfter(currentTime)) { + if (displayUpcoming) { eventItem.addClass("event-item-upcoming"); } else { eventItem.remove(); } } - if(eventDate.isBefore(currentTime)){ - if(displayPrevious){ + if (eventDate.isBefore(currentTime)) { + if (displayPrevious) { eventItem.addClass("event-item-previous"); } else { eventItem.remove(); @@ -80,32 +82,32 @@ jQuery(document).ready(function($) { }); //Adding headers - if(displayHeaders){ - eventListing.find(".event-item").each(function(){ + if (displayHeaders) { + eventListing.find(".event-item").each(function () { var eventItem = $(this); - var eventDate = moment(eventItem.data("date")); + var eventDate = dayjs(eventItem.data("date")); - if(upcomingNotAdded && eventDate.isSameOrAfter(currentTime)){ + if (upcomingNotAdded && (eventDate.isSame(currentTime) || eventDate.isAfter(currentTime))) { $('

Upcoming Events

').insertBefore(eventItem); upcomingNotAdded = false; } - if(prevNotAdded && eventDate.isBefore(currentTime)){ - $('

Previous Events

').insertBefore(eventItem); + if (prevNotAdded && eventDate.isBefore(currentTime)) { + $('

Previous Events

Includes slides and recordings.

').insertBefore(eventItem); prevNotAdded = false; } }); } // Make upcoming events in forward chronological order, rather than reverse chronological order. - if(displayUpcoming && displayHeaders && chronologicalUpcoming){ + if (displayUpcoming && displayHeaders && chronologicalUpcoming) { // Get the location of the upcoming header as an anchor. var anchorElement = document.getElementById("upcoming"); - if(anchorElement){ + if (anchorElement) { // For each upcoming element, move it to after the heading. // As elements are in reverse-chrono order, the order of execution results in forward chrono order. - eventListing.find(".event-item-upcoming").each(function(){ + eventListing.find(".event-item-upcoming").each(function () { var eventItem = $(this); anchorElement.insertAdjacentElement('afterend', this); }); @@ -114,4 +116,28 @@ jQuery(document).ready(function($) { }); + /* ======= Projects Tag Cloud ======= */ + $("a.tag-link").on("click", function (e) { + var tag = $(this).attr("href").substring($(this).attr("href").indexOf('#') + 1); + $("a.tag-link.selected").removeClass("selected"); + $("a.filter-link.selected").removeClass("selected"); + $(this).addClass("selected"); + $('.project.tag-' + tag).show(); + $('.project:not(.tag-' + tag + ')').hide(); + }); + $("a.filter-link").on("click", function (e) { + $("a.tag-link.selected").removeClass("selected"); + $("a.filter-link.selected").removeClass("selected"); + $(this).addClass("selected"); + if (!$(this).attr("href")) { + // Show all + $('.project').show(); + } else { + // Show active/completed + var tag = $(this).attr("href").substring($(this).attr("href").indexOf('#') + 1); + $('.project.' + tag).show(); + $('.project:not(.' + tag + ')').hide(); + } + }); + }); diff --git a/assets/plugins/dayjs.min.js b/assets/plugins/dayjs.min.js new file mode 100644 index 00000000..5b4e6d6b --- /dev/null +++ b/assets/plugins/dayjs.min.js @@ -0,0 +1,2 @@ +// day.min.js 1.11.0, MIT Licence https://github.com/iamkun/dayjs +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).dayjs=e()}(this,(function(){"use strict";var t=1e3,e=6e4,n=36e5,r="millisecond",i="second",s="minute",u="hour",a="day",o="week",f="month",h="quarter",c="year",d="date",$="Invalid Date",l=/^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/,y=/\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,M={name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_")},m=function(t,e,n){var r=String(t);return!r||r.length>=e?t:""+Array(e+1-r.length).join(n)+t},g={s:m,z:function(t){var e=-t.utcOffset(),n=Math.abs(e),r=Math.floor(n/60),i=n%60;return(e<=0?"+":"-")+m(r,2,"0")+":"+m(i,2,"0")},m:function t(e,n){if(e.date()1)return t(u[0])}else{var a=e.name;D[a]=e,i=a}return!r&&i&&(v=i),i||!r&&v},w=function(t,e){if(p(t))return t.clone();var n="object"==typeof e?e:{};return n.date=t,n.args=arguments,new _(n)},O=g;O.l=S,O.i=p,O.w=function(t,e){return w(t,{locale:e.$L,utc:e.$u,x:e.$x,$offset:e.$offset})};var _=function(){function M(t){this.$L=S(t.locale,null,!0),this.parse(t)}var m=M.prototype;return m.parse=function(t){this.$d=function(t){var e=t.date,n=t.utc;if(null===e)return new Date(NaN);if(O.u(e))return new Date;if(e instanceof Date)return new Date(e);if("string"==typeof e&&!/Z$/i.test(e)){var r=e.match(l);if(r){var i=r[2]-1||0,s=(r[7]||"0").substring(0,3);return n?new Date(Date.UTC(r[1],i,r[3]||1,r[4]||0,r[5]||0,r[6]||0,s)):new Date(r[1],i,r[3]||1,r[4]||0,r[5]||0,r[6]||0,s)}}return new Date(e)}(t),this.$x=t.x||{},this.init()},m.init=function(){var t=this.$d;this.$y=t.getFullYear(),this.$M=t.getMonth(),this.$D=t.getDate(),this.$W=t.getDay(),this.$H=t.getHours(),this.$m=t.getMinutes(),this.$s=t.getSeconds(),this.$ms=t.getMilliseconds()},m.$utils=function(){return O},m.isValid=function(){return!(this.$d.toString()===$)},m.isSame=function(t,e){var n=w(t);return this.startOf(e)<=n&&n<=this.endOf(e)},m.isAfter=function(t,e){return w(t)>> 0; - - for (var i = 0; i < len; i++) { - if (i in t && fun.call(this, t[i], i, t)) { - return true; - } - } - - return false; - }; - } - - function isValid(m) { - if (m._isValid == null) { - var flags = getParsingFlags(m); - var parsedParts = some.call(flags.parsedDateParts, function (i) { - return i != null; - }); - var isNowValid = !isNaN(m._d.getTime()) && - flags.overflow < 0 && - !flags.empty && - !flags.invalidMonth && - !flags.invalidWeekday && - !flags.weekdayMismatch && - !flags.nullInput && - !flags.invalidFormat && - !flags.userInvalidated && - (!flags.meridiem || (flags.meridiem && parsedParts)); - - if (m._strict) { - isNowValid = isNowValid && - flags.charsLeftOver === 0 && - flags.unusedTokens.length === 0 && - flags.bigHour === undefined; - } - - if (Object.isFrozen == null || !Object.isFrozen(m)) { - m._isValid = isNowValid; - } - else { - return isNowValid; - } - } - return m._isValid; - } - - function createInvalid (flags) { - var m = createUTC(NaN); - if (flags != null) { - extend(getParsingFlags(m), flags); - } - else { - getParsingFlags(m).userInvalidated = true; - } - - return m; - } - - // Plugins that add properties should also add the key here (null value), - // so we can properly clone ourselves. - var momentProperties = hooks.momentProperties = []; - - function copyConfig(to, from) { - var i, prop, val; - - if (!isUndefined(from._isAMomentObject)) { - to._isAMomentObject = from._isAMomentObject; - } - if (!isUndefined(from._i)) { - to._i = from._i; - } - if (!isUndefined(from._f)) { - to._f = from._f; - } - if (!isUndefined(from._l)) { - to._l = from._l; - } - if (!isUndefined(from._strict)) { - to._strict = from._strict; - } - if (!isUndefined(from._tzm)) { - to._tzm = from._tzm; - } - if (!isUndefined(from._isUTC)) { - to._isUTC = from._isUTC; - } - if (!isUndefined(from._offset)) { - to._offset = from._offset; - } - if (!isUndefined(from._pf)) { - to._pf = getParsingFlags(from); - } - if (!isUndefined(from._locale)) { - to._locale = from._locale; - } - - if (momentProperties.length > 0) { - for (i = 0; i < momentProperties.length; i++) { - prop = momentProperties[i]; - val = from[prop]; - if (!isUndefined(val)) { - to[prop] = val; - } - } - } - - return to; - } - - var updateInProgress = false; - - // Moment prototype object - function Moment(config) { - copyConfig(this, config); - this._d = new Date(config._d != null ? config._d.getTime() : NaN); - if (!this.isValid()) { - this._d = new Date(NaN); - } - // Prevent infinite loop in case updateOffset creates new moment - // objects. - if (updateInProgress === false) { - updateInProgress = true; - hooks.updateOffset(this); - updateInProgress = false; - } - } - - function isMoment (obj) { - return obj instanceof Moment || (obj != null && obj._isAMomentObject != null); - } - - function absFloor (number) { - if (number < 0) { - // -0 -> 0 - return Math.ceil(number) || 0; - } else { - return Math.floor(number); - } - } - - function toInt(argumentForCoercion) { - var coercedNumber = +argumentForCoercion, - value = 0; - - if (coercedNumber !== 0 && isFinite(coercedNumber)) { - value = absFloor(coercedNumber); - } - - return value; - } - - // compare two arrays, return the number of differences - function compareArrays(array1, array2, dontConvert) { - var len = Math.min(array1.length, array2.length), - lengthDiff = Math.abs(array1.length - array2.length), - diffs = 0, - i; - for (i = 0; i < len; i++) { - if ((dontConvert && array1[i] !== array2[i]) || - (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) { - diffs++; - } - } - return diffs + lengthDiff; - } - - function warn(msg) { - if (hooks.suppressDeprecationWarnings === false && - (typeof console !== 'undefined') && console.warn) { - console.warn('Deprecation warning: ' + msg); - } - } - - function deprecate(msg, fn) { - var firstTime = true; - - return extend(function () { - if (hooks.deprecationHandler != null) { - hooks.deprecationHandler(null, msg); - } - if (firstTime) { - var args = []; - var arg; - for (var i = 0; i < arguments.length; i++) { - arg = ''; - if (typeof arguments[i] === 'object') { - arg += '\n[' + i + '] '; - for (var key in arguments[0]) { - arg += key + ': ' + arguments[0][key] + ', '; - } - arg = arg.slice(0, -2); // Remove trailing comma and space - } else { - arg = arguments[i]; - } - args.push(arg); - } - warn(msg + '\nArguments: ' + Array.prototype.slice.call(args).join('') + '\n' + (new Error()).stack); - firstTime = false; - } - return fn.apply(this, arguments); - }, fn); - } - - var deprecations = {}; - - function deprecateSimple(name, msg) { - if (hooks.deprecationHandler != null) { - hooks.deprecationHandler(name, msg); - } - if (!deprecations[name]) { - warn(msg); - deprecations[name] = true; - } - } - - hooks.suppressDeprecationWarnings = false; - hooks.deprecationHandler = null; - - function isFunction(input) { - return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]'; - } - - function set (config) { - var prop, i; - for (i in config) { - prop = config[i]; - if (isFunction(prop)) { - this[i] = prop; - } else { - this['_' + i] = prop; - } - } - this._config = config; - // Lenient ordinal parsing accepts just a number in addition to - // number + (possibly) stuff coming from _dayOfMonthOrdinalParse. - // TODO: Remove "ordinalParse" fallback in next major release. - this._dayOfMonthOrdinalParseLenient = new RegExp( - (this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) + - '|' + (/\d{1,2}/).source); - } - - function mergeConfigs(parentConfig, childConfig) { - var res = extend({}, parentConfig), prop; - for (prop in childConfig) { - if (hasOwnProp(childConfig, prop)) { - if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) { - res[prop] = {}; - extend(res[prop], parentConfig[prop]); - extend(res[prop], childConfig[prop]); - } else if (childConfig[prop] != null) { - res[prop] = childConfig[prop]; - } else { - delete res[prop]; - } - } - } - for (prop in parentConfig) { - if (hasOwnProp(parentConfig, prop) && - !hasOwnProp(childConfig, prop) && - isObject(parentConfig[prop])) { - // make sure changes to properties don't modify parent config - res[prop] = extend({}, res[prop]); - } - } - return res; - } - - function Locale(config) { - if (config != null) { - this.set(config); - } - } - - var keys; - - if (Object.keys) { - keys = Object.keys; - } else { - keys = function (obj) { - var i, res = []; - for (i in obj) { - if (hasOwnProp(obj, i)) { - res.push(i); - } - } - return res; - }; - } - - var defaultCalendar = { - sameDay : '[Today at] LT', - nextDay : '[Tomorrow at] LT', - nextWeek : 'dddd [at] LT', - lastDay : '[Yesterday at] LT', - lastWeek : '[Last] dddd [at] LT', - sameElse : 'L' - }; - - function calendar (key, mom, now) { - var output = this._calendar[key] || this._calendar['sameElse']; - return isFunction(output) ? output.call(mom, now) : output; - } - - var defaultLongDateFormat = { - LTS : 'h:mm:ss A', - LT : 'h:mm A', - L : 'MM/DD/YYYY', - LL : 'MMMM D, YYYY', - LLL : 'MMMM D, YYYY h:mm A', - LLLL : 'dddd, MMMM D, YYYY h:mm A' - }; - - function longDateFormat (key) { - var format = this._longDateFormat[key], - formatUpper = this._longDateFormat[key.toUpperCase()]; - - if (format || !formatUpper) { - return format; - } - - this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) { - return val.slice(1); - }); - - return this._longDateFormat[key]; - } - - var defaultInvalidDate = 'Invalid date'; - - function invalidDate () { - return this._invalidDate; - } - - var defaultOrdinal = '%d'; - var defaultDayOfMonthOrdinalParse = /\d{1,2}/; - - function ordinal (number) { - return this._ordinal.replace('%d', number); - } - - var defaultRelativeTime = { - future : 'in %s', - past : '%s ago', - s : 'a few seconds', - ss : '%d seconds', - m : 'a minute', - mm : '%d minutes', - h : 'an hour', - hh : '%d hours', - d : 'a day', - dd : '%d days', - M : 'a month', - MM : '%d months', - y : 'a year', - yy : '%d years' - }; - - function relativeTime (number, withoutSuffix, string, isFuture) { - var output = this._relativeTime[string]; - return (isFunction(output)) ? - output(number, withoutSuffix, string, isFuture) : - output.replace(/%d/i, number); - } - - function pastFuture (diff, output) { - var format = this._relativeTime[diff > 0 ? 'future' : 'past']; - return isFunction(format) ? format(output) : format.replace(/%s/i, output); - } - - var aliases = {}; - - function addUnitAlias (unit, shorthand) { - var lowerCase = unit.toLowerCase(); - aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit; - } - - function normalizeUnits(units) { - return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined; - } - - function normalizeObjectUnits(inputObject) { - var normalizedInput = {}, - normalizedProp, - prop; - - for (prop in inputObject) { - if (hasOwnProp(inputObject, prop)) { - normalizedProp = normalizeUnits(prop); - if (normalizedProp) { - normalizedInput[normalizedProp] = inputObject[prop]; - } - } - } - - return normalizedInput; - } - - var priorities = {}; - - function addUnitPriority(unit, priority) { - priorities[unit] = priority; - } - - function getPrioritizedUnits(unitsObj) { - var units = []; - for (var u in unitsObj) { - units.push({unit: u, priority: priorities[u]}); - } - units.sort(function (a, b) { - return a.priority - b.priority; - }); - return units; - } - - function zeroFill(number, targetLength, forceSign) { - var absNumber = '' + Math.abs(number), - zerosToFill = targetLength - absNumber.length, - sign = number >= 0; - return (sign ? (forceSign ? '+' : '') : '-') + - Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber; - } - - var formattingTokens = /(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g; - - var localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g; - - var formatFunctions = {}; - - var formatTokenFunctions = {}; - - // token: 'M' - // padded: ['MM', 2] - // ordinal: 'Mo' - // callback: function () { this.month() + 1 } - function addFormatToken (token, padded, ordinal, callback) { - var func = callback; - if (typeof callback === 'string') { - func = function () { - return this[callback](); - }; - } - if (token) { - formatTokenFunctions[token] = func; - } - if (padded) { - formatTokenFunctions[padded[0]] = function () { - return zeroFill(func.apply(this, arguments), padded[1], padded[2]); - }; - } - if (ordinal) { - formatTokenFunctions[ordinal] = function () { - return this.localeData().ordinal(func.apply(this, arguments), token); - }; - } - } - - function removeFormattingTokens(input) { - if (input.match(/\[[\s\S]/)) { - return input.replace(/^\[|\]$/g, ''); - } - return input.replace(/\\/g, ''); - } - - function makeFormatFunction(format) { - var array = format.match(formattingTokens), i, length; - - for (i = 0, length = array.length; i < length; i++) { - if (formatTokenFunctions[array[i]]) { - array[i] = formatTokenFunctions[array[i]]; - } else { - array[i] = removeFormattingTokens(array[i]); - } - } - - return function (mom) { - var output = '', i; - for (i = 0; i < length; i++) { - output += isFunction(array[i]) ? array[i].call(mom, format) : array[i]; - } - return output; - }; - } - - // format date using native date object - function formatMoment(m, format) { - if (!m.isValid()) { - return m.localeData().invalidDate(); - } - - format = expandFormat(format, m.localeData()); - formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format); - - return formatFunctions[format](m); - } - - function expandFormat(format, locale) { - var i = 5; - - function replaceLongDateFormatTokens(input) { - return locale.longDateFormat(input) || input; - } - - localFormattingTokens.lastIndex = 0; - while (i >= 0 && localFormattingTokens.test(format)) { - format = format.replace(localFormattingTokens, replaceLongDateFormatTokens); - localFormattingTokens.lastIndex = 0; - i -= 1; - } - - return format; - } - - var match1 = /\d/; // 0 - 9 - var match2 = /\d\d/; // 00 - 99 - var match3 = /\d{3}/; // 000 - 999 - var match4 = /\d{4}/; // 0000 - 9999 - var match6 = /[+-]?\d{6}/; // -999999 - 999999 - var match1to2 = /\d\d?/; // 0 - 99 - var match3to4 = /\d\d\d\d?/; // 999 - 9999 - var match5to6 = /\d\d\d\d\d\d?/; // 99999 - 999999 - var match1to3 = /\d{1,3}/; // 0 - 999 - var match1to4 = /\d{1,4}/; // 0 - 9999 - var match1to6 = /[+-]?\d{1,6}/; // -999999 - 999999 - - var matchUnsigned = /\d+/; // 0 - inf - var matchSigned = /[+-]?\d+/; // -inf - inf - - var matchOffset = /Z|[+-]\d\d:?\d\d/gi; // +00:00 -00:00 +0000 -0000 or Z - var matchShortOffset = /Z|[+-]\d\d(?::?\d\d)?/gi; // +00 -00 +00:00 -00:00 +0000 -0000 or Z - - var matchTimestamp = /[+-]?\d+(\.\d{1,3})?/; // 123456789 123456789.123 - - // any word (or two) characters or numbers including two/three word month in arabic. - // includes scottish gaelic two word and hyphenated months - var matchWord = /[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i; - - var regexes = {}; - - function addRegexToken (token, regex, strictRegex) { - regexes[token] = isFunction(regex) ? regex : function (isStrict, localeData) { - return (isStrict && strictRegex) ? strictRegex : regex; - }; - } - - function getParseRegexForToken (token, config) { - if (!hasOwnProp(regexes, token)) { - return new RegExp(unescapeFormat(token)); - } - - return regexes[token](config._strict, config._locale); - } - - // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript - function unescapeFormat(s) { - return regexEscape(s.replace('\\', '').replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) { - return p1 || p2 || p3 || p4; - })); - } - - function regexEscape(s) { - return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); - } - - var tokens = {}; - - function addParseToken (token, callback) { - var i, func = callback; - if (typeof token === 'string') { - token = [token]; - } - if (isNumber(callback)) { - func = function (input, array) { - array[callback] = toInt(input); - }; - } - for (i = 0; i < token.length; i++) { - tokens[token[i]] = func; - } - } - - function addWeekParseToken (token, callback) { - addParseToken(token, function (input, array, config, token) { - config._w = config._w || {}; - callback(input, config._w, config, token); - }); - } - - function addTimeToArrayFromToken(token, input, config) { - if (input != null && hasOwnProp(tokens, token)) { - tokens[token](input, config._a, config, token); - } - } - - var YEAR = 0; - var MONTH = 1; - var DATE = 2; - var HOUR = 3; - var MINUTE = 4; - var SECOND = 5; - var MILLISECOND = 6; - var WEEK = 7; - var WEEKDAY = 8; - - // FORMATTING - - addFormatToken('Y', 0, 0, function () { - var y = this.year(); - return y <= 9999 ? '' + y : '+' + y; - }); - - addFormatToken(0, ['YY', 2], 0, function () { - return this.year() % 100; - }); - - addFormatToken(0, ['YYYY', 4], 0, 'year'); - addFormatToken(0, ['YYYYY', 5], 0, 'year'); - addFormatToken(0, ['YYYYYY', 6, true], 0, 'year'); - - // ALIASES - - addUnitAlias('year', 'y'); - - // PRIORITIES - - addUnitPriority('year', 1); - - // PARSING - - addRegexToken('Y', matchSigned); - addRegexToken('YY', match1to2, match2); - addRegexToken('YYYY', match1to4, match4); - addRegexToken('YYYYY', match1to6, match6); - addRegexToken('YYYYYY', match1to6, match6); - - addParseToken(['YYYYY', 'YYYYYY'], YEAR); - addParseToken('YYYY', function (input, array) { - array[YEAR] = input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input); - }); - addParseToken('YY', function (input, array) { - array[YEAR] = hooks.parseTwoDigitYear(input); - }); - addParseToken('Y', function (input, array) { - array[YEAR] = parseInt(input, 10); - }); - - // HELPERS - - function daysInYear(year) { - return isLeapYear(year) ? 366 : 365; - } - - function isLeapYear(year) { - return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0; - } - - // HOOKS - - hooks.parseTwoDigitYear = function (input) { - return toInt(input) + (toInt(input) > 68 ? 1900 : 2000); - }; - - // MOMENTS - - var getSetYear = makeGetSet('FullYear', true); - - function getIsLeapYear () { - return isLeapYear(this.year()); - } - - function makeGetSet (unit, keepTime) { - return function (value) { - if (value != null) { - set$1(this, unit, value); - hooks.updateOffset(this, keepTime); - return this; - } else { - return get(this, unit); - } - }; - } - - function get (mom, unit) { - return mom.isValid() ? - mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN; - } - - function set$1 (mom, unit, value) { - if (mom.isValid() && !isNaN(value)) { - if (unit === 'FullYear' && isLeapYear(mom.year()) && mom.month() === 1 && mom.date() === 29) { - mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value, mom.month(), daysInMonth(value, mom.month())); - } - else { - mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value); - } - } - } - - // MOMENTS - - function stringGet (units) { - units = normalizeUnits(units); - if (isFunction(this[units])) { - return this[units](); - } - return this; - } - - - function stringSet (units, value) { - if (typeof units === 'object') { - units = normalizeObjectUnits(units); - var prioritized = getPrioritizedUnits(units); - for (var i = 0; i < prioritized.length; i++) { - this[prioritized[i].unit](units[prioritized[i].unit]); - } - } else { - units = normalizeUnits(units); - if (isFunction(this[units])) { - return this[units](value); - } - } - return this; - } - - function mod(n, x) { - return ((n % x) + x) % x; - } - - var indexOf; - - if (Array.prototype.indexOf) { - indexOf = Array.prototype.indexOf; - } else { - indexOf = function (o) { - // I know - var i; - for (i = 0; i < this.length; ++i) { - if (this[i] === o) { - return i; - } - } - return -1; - }; - } - - function daysInMonth(year, month) { - if (isNaN(year) || isNaN(month)) { - return NaN; - } - var modMonth = mod(month, 12); - year += (month - modMonth) / 12; - return modMonth === 1 ? (isLeapYear(year) ? 29 : 28) : (31 - modMonth % 7 % 2); - } - - // FORMATTING - - addFormatToken('M', ['MM', 2], 'Mo', function () { - return this.month() + 1; - }); - - addFormatToken('MMM', 0, 0, function (format) { - return this.localeData().monthsShort(this, format); - }); - - addFormatToken('MMMM', 0, 0, function (format) { - return this.localeData().months(this, format); - }); - - // ALIASES - - addUnitAlias('month', 'M'); - - // PRIORITY - - addUnitPriority('month', 8); - - // PARSING - - addRegexToken('M', match1to2); - addRegexToken('MM', match1to2, match2); - addRegexToken('MMM', function (isStrict, locale) { - return locale.monthsShortRegex(isStrict); - }); - addRegexToken('MMMM', function (isStrict, locale) { - return locale.monthsRegex(isStrict); - }); - - addParseToken(['M', 'MM'], function (input, array) { - array[MONTH] = toInt(input) - 1; - }); - - addParseToken(['MMM', 'MMMM'], function (input, array, config, token) { - var month = config._locale.monthsParse(input, token, config._strict); - // if we didn't find a month name, mark the date as invalid. - if (month != null) { - array[MONTH] = month; - } else { - getParsingFlags(config).invalidMonth = input; - } - }); - - // LOCALES - - var MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/; - var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'); - function localeMonths (m, format) { - if (!m) { - return isArray(this._months) ? this._months : - this._months['standalone']; - } - return isArray(this._months) ? this._months[m.month()] : - this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format) ? 'format' : 'standalone'][m.month()]; - } - - var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'); - function localeMonthsShort (m, format) { - if (!m) { - return isArray(this._monthsShort) ? this._monthsShort : - this._monthsShort['standalone']; - } - return isArray(this._monthsShort) ? this._monthsShort[m.month()] : - this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()]; - } - - function handleStrictParse(monthName, format, strict) { - var i, ii, mom, llc = monthName.toLocaleLowerCase(); - if (!this._monthsParse) { - // this is not used - this._monthsParse = []; - this._longMonthsParse = []; - this._shortMonthsParse = []; - for (i = 0; i < 12; ++i) { - mom = createUTC([2000, i]); - this._shortMonthsParse[i] = this.monthsShort(mom, '').toLocaleLowerCase(); - this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase(); - } - } - - if (strict) { - if (format === 'MMM') { - ii = indexOf.call(this._shortMonthsParse, llc); - return ii !== -1 ? ii : null; - } else { - ii = indexOf.call(this._longMonthsParse, llc); - return ii !== -1 ? ii : null; - } - } else { - if (format === 'MMM') { - ii = indexOf.call(this._shortMonthsParse, llc); - if (ii !== -1) { - return ii; - } - ii = indexOf.call(this._longMonthsParse, llc); - return ii !== -1 ? ii : null; - } else { - ii = indexOf.call(this._longMonthsParse, llc); - if (ii !== -1) { - return ii; - } - ii = indexOf.call(this._shortMonthsParse, llc); - return ii !== -1 ? ii : null; - } - } - } - - function localeMonthsParse (monthName, format, strict) { - var i, mom, regex; - - if (this._monthsParseExact) { - return handleStrictParse.call(this, monthName, format, strict); - } - - if (!this._monthsParse) { - this._monthsParse = []; - this._longMonthsParse = []; - this._shortMonthsParse = []; - } - - // TODO: add sorting - // Sorting makes sure if one month (or abbr) is a prefix of another - // see sorting in computeMonthsParse - for (i = 0; i < 12; i++) { - // make the regex if we don't have it already - mom = createUTC([2000, i]); - if (strict && !this._longMonthsParse[i]) { - this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i'); - this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i'); - } - if (!strict && !this._monthsParse[i]) { - regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, ''); - this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i'); - } - // test the regex - if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) { - return i; - } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) { - return i; - } else if (!strict && this._monthsParse[i].test(monthName)) { - return i; - } - } - } - - // MOMENTS - - function setMonth (mom, value) { - var dayOfMonth; - - if (!mom.isValid()) { - // No op - return mom; - } - - if (typeof value === 'string') { - if (/^\d+$/.test(value)) { - value = toInt(value); - } else { - value = mom.localeData().monthsParse(value); - // TODO: Another silent failure? - if (!isNumber(value)) { - return mom; - } - } - } - - dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value)); - mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth); - return mom; - } - - function getSetMonth (value) { - if (value != null) { - setMonth(this, value); - hooks.updateOffset(this, true); - return this; - } else { - return get(this, 'Month'); - } - } - - function getDaysInMonth () { - return daysInMonth(this.year(), this.month()); - } - - var defaultMonthsShortRegex = matchWord; - function monthsShortRegex (isStrict) { - if (this._monthsParseExact) { - if (!hasOwnProp(this, '_monthsRegex')) { - computeMonthsParse.call(this); - } - if (isStrict) { - return this._monthsShortStrictRegex; - } else { - return this._monthsShortRegex; - } - } else { - if (!hasOwnProp(this, '_monthsShortRegex')) { - this._monthsShortRegex = defaultMonthsShortRegex; - } - return this._monthsShortStrictRegex && isStrict ? - this._monthsShortStrictRegex : this._monthsShortRegex; - } - } - - var defaultMonthsRegex = matchWord; - function monthsRegex (isStrict) { - if (this._monthsParseExact) { - if (!hasOwnProp(this, '_monthsRegex')) { - computeMonthsParse.call(this); - } - if (isStrict) { - return this._monthsStrictRegex; - } else { - return this._monthsRegex; - } - } else { - if (!hasOwnProp(this, '_monthsRegex')) { - this._monthsRegex = defaultMonthsRegex; - } - return this._monthsStrictRegex && isStrict ? - this._monthsStrictRegex : this._monthsRegex; - } - } - - function computeMonthsParse () { - function cmpLenRev(a, b) { - return b.length - a.length; - } - - var shortPieces = [], longPieces = [], mixedPieces = [], - i, mom; - for (i = 0; i < 12; i++) { - // make the regex if we don't have it already - mom = createUTC([2000, i]); - shortPieces.push(this.monthsShort(mom, '')); - longPieces.push(this.months(mom, '')); - mixedPieces.push(this.months(mom, '')); - mixedPieces.push(this.monthsShort(mom, '')); - } - // Sorting makes sure if one month (or abbr) is a prefix of another it - // will match the longer piece. - shortPieces.sort(cmpLenRev); - longPieces.sort(cmpLenRev); - mixedPieces.sort(cmpLenRev); - for (i = 0; i < 12; i++) { - shortPieces[i] = regexEscape(shortPieces[i]); - longPieces[i] = regexEscape(longPieces[i]); - } - for (i = 0; i < 24; i++) { - mixedPieces[i] = regexEscape(mixedPieces[i]); - } - - this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i'); - this._monthsShortRegex = this._monthsRegex; - this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i'); - this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i'); - } - - function createDate (y, m, d, h, M, s, ms) { - // can't just apply() to create a date: - // https://stackoverflow.com/q/181348 - var date = new Date(y, m, d, h, M, s, ms); - - // the date constructor remaps years 0-99 to 1900-1999 - if (y < 100 && y >= 0 && isFinite(date.getFullYear())) { - date.setFullYear(y); - } - return date; - } - - function createUTCDate (y) { - var date = new Date(Date.UTC.apply(null, arguments)); - - // the Date.UTC function remaps years 0-99 to 1900-1999 - if (y < 100 && y >= 0 && isFinite(date.getUTCFullYear())) { - date.setUTCFullYear(y); - } - return date; - } - - // start-of-first-week - start-of-year - function firstWeekOffset(year, dow, doy) { - var // first-week day -- which january is always in the first week (4 for iso, 1 for other) - fwd = 7 + dow - doy, - // first-week day local weekday -- which local weekday is fwd - fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7; - - return -fwdlw + fwd - 1; - } - - // https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday - function dayOfYearFromWeeks(year, week, weekday, dow, doy) { - var localWeekday = (7 + weekday - dow) % 7, - weekOffset = firstWeekOffset(year, dow, doy), - dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset, - resYear, resDayOfYear; - - if (dayOfYear <= 0) { - resYear = year - 1; - resDayOfYear = daysInYear(resYear) + dayOfYear; - } else if (dayOfYear > daysInYear(year)) { - resYear = year + 1; - resDayOfYear = dayOfYear - daysInYear(year); - } else { - resYear = year; - resDayOfYear = dayOfYear; - } - - return { - year: resYear, - dayOfYear: resDayOfYear - }; - } - - function weekOfYear(mom, dow, doy) { - var weekOffset = firstWeekOffset(mom.year(), dow, doy), - week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1, - resWeek, resYear; - - if (week < 1) { - resYear = mom.year() - 1; - resWeek = week + weeksInYear(resYear, dow, doy); - } else if (week > weeksInYear(mom.year(), dow, doy)) { - resWeek = week - weeksInYear(mom.year(), dow, doy); - resYear = mom.year() + 1; - } else { - resYear = mom.year(); - resWeek = week; - } - - return { - week: resWeek, - year: resYear - }; - } - - function weeksInYear(year, dow, doy) { - var weekOffset = firstWeekOffset(year, dow, doy), - weekOffsetNext = firstWeekOffset(year + 1, dow, doy); - return (daysInYear(year) - weekOffset + weekOffsetNext) / 7; - } - - // FORMATTING - - addFormatToken('w', ['ww', 2], 'wo', 'week'); - addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek'); - - // ALIASES - - addUnitAlias('week', 'w'); - addUnitAlias('isoWeek', 'W'); - - // PRIORITIES - - addUnitPriority('week', 5); - addUnitPriority('isoWeek', 5); - - // PARSING - - addRegexToken('w', match1to2); - addRegexToken('ww', match1to2, match2); - addRegexToken('W', match1to2); - addRegexToken('WW', match1to2, match2); - - addWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) { - week[token.substr(0, 1)] = toInt(input); - }); - - // HELPERS - - // LOCALES - - function localeWeek (mom) { - return weekOfYear(mom, this._week.dow, this._week.doy).week; - } - - var defaultLocaleWeek = { - dow : 0, // Sunday is the first day of the week. - doy : 6 // The week that contains Jan 6th is the first week of the year. - }; - - function localeFirstDayOfWeek () { - return this._week.dow; - } - - function localeFirstDayOfYear () { - return this._week.doy; - } - - // MOMENTS - - function getSetWeek (input) { - var week = this.localeData().week(this); - return input == null ? week : this.add((input - week) * 7, 'd'); - } - - function getSetISOWeek (input) { - var week = weekOfYear(this, 1, 4).week; - return input == null ? week : this.add((input - week) * 7, 'd'); - } - - // FORMATTING - - addFormatToken('d', 0, 'do', 'day'); - - addFormatToken('dd', 0, 0, function (format) { - return this.localeData().weekdaysMin(this, format); - }); - - addFormatToken('ddd', 0, 0, function (format) { - return this.localeData().weekdaysShort(this, format); - }); - - addFormatToken('dddd', 0, 0, function (format) { - return this.localeData().weekdays(this, format); - }); - - addFormatToken('e', 0, 0, 'weekday'); - addFormatToken('E', 0, 0, 'isoWeekday'); - - // ALIASES - - addUnitAlias('day', 'd'); - addUnitAlias('weekday', 'e'); - addUnitAlias('isoWeekday', 'E'); - - // PRIORITY - addUnitPriority('day', 11); - addUnitPriority('weekday', 11); - addUnitPriority('isoWeekday', 11); - - // PARSING - - addRegexToken('d', match1to2); - addRegexToken('e', match1to2); - addRegexToken('E', match1to2); - addRegexToken('dd', function (isStrict, locale) { - return locale.weekdaysMinRegex(isStrict); - }); - addRegexToken('ddd', function (isStrict, locale) { - return locale.weekdaysShortRegex(isStrict); - }); - addRegexToken('dddd', function (isStrict, locale) { - return locale.weekdaysRegex(isStrict); - }); - - addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) { - var weekday = config._locale.weekdaysParse(input, token, config._strict); - // if we didn't get a weekday name, mark the date as invalid - if (weekday != null) { - week.d = weekday; - } else { - getParsingFlags(config).invalidWeekday = input; - } - }); - - addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) { - week[token] = toInt(input); - }); - - // HELPERS - - function parseWeekday(input, locale) { - if (typeof input !== 'string') { - return input; - } - - if (!isNaN(input)) { - return parseInt(input, 10); - } - - input = locale.weekdaysParse(input); - if (typeof input === 'number') { - return input; - } - - return null; - } - - function parseIsoWeekday(input, locale) { - if (typeof input === 'string') { - return locale.weekdaysParse(input) % 7 || 7; - } - return isNaN(input) ? null : input; - } - - // LOCALES - - var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'); - function localeWeekdays (m, format) { - if (!m) { - return isArray(this._weekdays) ? this._weekdays : - this._weekdays['standalone']; - } - return isArray(this._weekdays) ? this._weekdays[m.day()] : - this._weekdays[this._weekdays.isFormat.test(format) ? 'format' : 'standalone'][m.day()]; - } - - var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'); - function localeWeekdaysShort (m) { - return (m) ? this._weekdaysShort[m.day()] : this._weekdaysShort; - } - - var defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'); - function localeWeekdaysMin (m) { - return (m) ? this._weekdaysMin[m.day()] : this._weekdaysMin; - } - - function handleStrictParse$1(weekdayName, format, strict) { - var i, ii, mom, llc = weekdayName.toLocaleLowerCase(); - if (!this._weekdaysParse) { - this._weekdaysParse = []; - this._shortWeekdaysParse = []; - this._minWeekdaysParse = []; - - for (i = 0; i < 7; ++i) { - mom = createUTC([2000, 1]).day(i); - this._minWeekdaysParse[i] = this.weekdaysMin(mom, '').toLocaleLowerCase(); - this._shortWeekdaysParse[i] = this.weekdaysShort(mom, '').toLocaleLowerCase(); - this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase(); - } - } - - if (strict) { - if (format === 'dddd') { - ii = indexOf.call(this._weekdaysParse, llc); - return ii !== -1 ? ii : null; - } else if (format === 'ddd') { - ii = indexOf.call(this._shortWeekdaysParse, llc); - return ii !== -1 ? ii : null; - } else { - ii = indexOf.call(this._minWeekdaysParse, llc); - return ii !== -1 ? ii : null; - } - } else { - if (format === 'dddd') { - ii = indexOf.call(this._weekdaysParse, llc); - if (ii !== -1) { - return ii; - } - ii = indexOf.call(this._shortWeekdaysParse, llc); - if (ii !== -1) { - return ii; - } - ii = indexOf.call(this._minWeekdaysParse, llc); - return ii !== -1 ? ii : null; - } else if (format === 'ddd') { - ii = indexOf.call(this._shortWeekdaysParse, llc); - if (ii !== -1) { - return ii; - } - ii = indexOf.call(this._weekdaysParse, llc); - if (ii !== -1) { - return ii; - } - ii = indexOf.call(this._minWeekdaysParse, llc); - return ii !== -1 ? ii : null; - } else { - ii = indexOf.call(this._minWeekdaysParse, llc); - if (ii !== -1) { - return ii; - } - ii = indexOf.call(this._weekdaysParse, llc); - if (ii !== -1) { - return ii; - } - ii = indexOf.call(this._shortWeekdaysParse, llc); - return ii !== -1 ? ii : null; - } - } - } - - function localeWeekdaysParse (weekdayName, format, strict) { - var i, mom, regex; - - if (this._weekdaysParseExact) { - return handleStrictParse$1.call(this, weekdayName, format, strict); - } - - if (!this._weekdaysParse) { - this._weekdaysParse = []; - this._minWeekdaysParse = []; - this._shortWeekdaysParse = []; - this._fullWeekdaysParse = []; - } - - for (i = 0; i < 7; i++) { - // make the regex if we don't have it already - - mom = createUTC([2000, 1]).day(i); - if (strict && !this._fullWeekdaysParse[i]) { - this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\\.?') + '$', 'i'); - this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\\.?') + '$', 'i'); - this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\\.?') + '$', 'i'); - } - if (!this._weekdaysParse[i]) { - regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, ''); - this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i'); - } - // test the regex - if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) { - return i; - } else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) { - return i; - } else if (strict && format === 'dd' && this._minWeekdaysParse[i].test(weekdayName)) { - return i; - } else if (!strict && this._weekdaysParse[i].test(weekdayName)) { - return i; - } - } - } - - // MOMENTS - - function getSetDayOfWeek (input) { - if (!this.isValid()) { - return input != null ? this : NaN; - } - var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay(); - if (input != null) { - input = parseWeekday(input, this.localeData()); - return this.add(input - day, 'd'); - } else { - return day; - } - } - - function getSetLocaleDayOfWeek (input) { - if (!this.isValid()) { - return input != null ? this : NaN; - } - var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7; - return input == null ? weekday : this.add(input - weekday, 'd'); - } - - function getSetISODayOfWeek (input) { - if (!this.isValid()) { - return input != null ? this : NaN; - } - - // behaves the same as moment#day except - // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6) - // as a setter, sunday should belong to the previous week. - - if (input != null) { - var weekday = parseIsoWeekday(input, this.localeData()); - return this.day(this.day() % 7 ? weekday : weekday - 7); - } else { - return this.day() || 7; - } - } - - var defaultWeekdaysRegex = matchWord; - function weekdaysRegex (isStrict) { - if (this._weekdaysParseExact) { - if (!hasOwnProp(this, '_weekdaysRegex')) { - computeWeekdaysParse.call(this); - } - if (isStrict) { - return this._weekdaysStrictRegex; - } else { - return this._weekdaysRegex; - } - } else { - if (!hasOwnProp(this, '_weekdaysRegex')) { - this._weekdaysRegex = defaultWeekdaysRegex; - } - return this._weekdaysStrictRegex && isStrict ? - this._weekdaysStrictRegex : this._weekdaysRegex; - } - } - - var defaultWeekdaysShortRegex = matchWord; - function weekdaysShortRegex (isStrict) { - if (this._weekdaysParseExact) { - if (!hasOwnProp(this, '_weekdaysRegex')) { - computeWeekdaysParse.call(this); - } - if (isStrict) { - return this._weekdaysShortStrictRegex; - } else { - return this._weekdaysShortRegex; - } - } else { - if (!hasOwnProp(this, '_weekdaysShortRegex')) { - this._weekdaysShortRegex = defaultWeekdaysShortRegex; - } - return this._weekdaysShortStrictRegex && isStrict ? - this._weekdaysShortStrictRegex : this._weekdaysShortRegex; - } - } - - var defaultWeekdaysMinRegex = matchWord; - function weekdaysMinRegex (isStrict) { - if (this._weekdaysParseExact) { - if (!hasOwnProp(this, '_weekdaysRegex')) { - computeWeekdaysParse.call(this); - } - if (isStrict) { - return this._weekdaysMinStrictRegex; - } else { - return this._weekdaysMinRegex; - } - } else { - if (!hasOwnProp(this, '_weekdaysMinRegex')) { - this._weekdaysMinRegex = defaultWeekdaysMinRegex; - } - return this._weekdaysMinStrictRegex && isStrict ? - this._weekdaysMinStrictRegex : this._weekdaysMinRegex; - } - } - - - function computeWeekdaysParse () { - function cmpLenRev(a, b) { - return b.length - a.length; - } - - var minPieces = [], shortPieces = [], longPieces = [], mixedPieces = [], - i, mom, minp, shortp, longp; - for (i = 0; i < 7; i++) { - // make the regex if we don't have it already - mom = createUTC([2000, 1]).day(i); - minp = this.weekdaysMin(mom, ''); - shortp = this.weekdaysShort(mom, ''); - longp = this.weekdays(mom, ''); - minPieces.push(minp); - shortPieces.push(shortp); - longPieces.push(longp); - mixedPieces.push(minp); - mixedPieces.push(shortp); - mixedPieces.push(longp); - } - // Sorting makes sure if one weekday (or abbr) is a prefix of another it - // will match the longer piece. - minPieces.sort(cmpLenRev); - shortPieces.sort(cmpLenRev); - longPieces.sort(cmpLenRev); - mixedPieces.sort(cmpLenRev); - for (i = 0; i < 7; i++) { - shortPieces[i] = regexEscape(shortPieces[i]); - longPieces[i] = regexEscape(longPieces[i]); - mixedPieces[i] = regexEscape(mixedPieces[i]); - } - - this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i'); - this._weekdaysShortRegex = this._weekdaysRegex; - this._weekdaysMinRegex = this._weekdaysRegex; - - this._weekdaysStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i'); - this._weekdaysShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i'); - this._weekdaysMinStrictRegex = new RegExp('^(' + minPieces.join('|') + ')', 'i'); - } - - // FORMATTING - - function hFormat() { - return this.hours() % 12 || 12; - } - - function kFormat() { - return this.hours() || 24; - } - - addFormatToken('H', ['HH', 2], 0, 'hour'); - addFormatToken('h', ['hh', 2], 0, hFormat); - addFormatToken('k', ['kk', 2], 0, kFormat); - - addFormatToken('hmm', 0, 0, function () { - return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2); - }); - - addFormatToken('hmmss', 0, 0, function () { - return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2) + - zeroFill(this.seconds(), 2); - }); - - addFormatToken('Hmm', 0, 0, function () { - return '' + this.hours() + zeroFill(this.minutes(), 2); - }); - - addFormatToken('Hmmss', 0, 0, function () { - return '' + this.hours() + zeroFill(this.minutes(), 2) + - zeroFill(this.seconds(), 2); - }); - - function meridiem (token, lowercase) { - addFormatToken(token, 0, 0, function () { - return this.localeData().meridiem(this.hours(), this.minutes(), lowercase); - }); - } - - meridiem('a', true); - meridiem('A', false); - - // ALIASES - - addUnitAlias('hour', 'h'); - - // PRIORITY - addUnitPriority('hour', 13); - - // PARSING - - function matchMeridiem (isStrict, locale) { - return locale._meridiemParse; - } - - addRegexToken('a', matchMeridiem); - addRegexToken('A', matchMeridiem); - addRegexToken('H', match1to2); - addRegexToken('h', match1to2); - addRegexToken('k', match1to2); - addRegexToken('HH', match1to2, match2); - addRegexToken('hh', match1to2, match2); - addRegexToken('kk', match1to2, match2); - - addRegexToken('hmm', match3to4); - addRegexToken('hmmss', match5to6); - addRegexToken('Hmm', match3to4); - addRegexToken('Hmmss', match5to6); - - addParseToken(['H', 'HH'], HOUR); - addParseToken(['k', 'kk'], function (input, array, config) { - var kInput = toInt(input); - array[HOUR] = kInput === 24 ? 0 : kInput; - }); - addParseToken(['a', 'A'], function (input, array, config) { - config._isPm = config._locale.isPM(input); - config._meridiem = input; - }); - addParseToken(['h', 'hh'], function (input, array, config) { - array[HOUR] = toInt(input); - getParsingFlags(config).bigHour = true; - }); - addParseToken('hmm', function (input, array, config) { - var pos = input.length - 2; - array[HOUR] = toInt(input.substr(0, pos)); - array[MINUTE] = toInt(input.substr(pos)); - getParsingFlags(config).bigHour = true; - }); - addParseToken('hmmss', function (input, array, config) { - var pos1 = input.length - 4; - var pos2 = input.length - 2; - array[HOUR] = toInt(input.substr(0, pos1)); - array[MINUTE] = toInt(input.substr(pos1, 2)); - array[SECOND] = toInt(input.substr(pos2)); - getParsingFlags(config).bigHour = true; - }); - addParseToken('Hmm', function (input, array, config) { - var pos = input.length - 2; - array[HOUR] = toInt(input.substr(0, pos)); - array[MINUTE] = toInt(input.substr(pos)); - }); - addParseToken('Hmmss', function (input, array, config) { - var pos1 = input.length - 4; - var pos2 = input.length - 2; - array[HOUR] = toInt(input.substr(0, pos1)); - array[MINUTE] = toInt(input.substr(pos1, 2)); - array[SECOND] = toInt(input.substr(pos2)); - }); - - // LOCALES - - function localeIsPM (input) { - // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays - // Using charAt should be more compatible. - return ((input + '').toLowerCase().charAt(0) === 'p'); - } - - var defaultLocaleMeridiemParse = /[ap]\.?m?\.?/i; - function localeMeridiem (hours, minutes, isLower) { - if (hours > 11) { - return isLower ? 'pm' : 'PM'; - } else { - return isLower ? 'am' : 'AM'; - } - } - - - // MOMENTS - - // Setting the hour should keep the time, because the user explicitly - // specified which hour they want. So trying to maintain the same hour (in - // a new timezone) makes sense. Adding/subtracting hours does not follow - // this rule. - var getSetHour = makeGetSet('Hours', true); - - var baseConfig = { - calendar: defaultCalendar, - longDateFormat: defaultLongDateFormat, - invalidDate: defaultInvalidDate, - ordinal: defaultOrdinal, - dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse, - relativeTime: defaultRelativeTime, - - months: defaultLocaleMonths, - monthsShort: defaultLocaleMonthsShort, - - week: defaultLocaleWeek, - - weekdays: defaultLocaleWeekdays, - weekdaysMin: defaultLocaleWeekdaysMin, - weekdaysShort: defaultLocaleWeekdaysShort, - - meridiemParse: defaultLocaleMeridiemParse - }; - - // internal storage for locale config files - var locales = {}; - var localeFamilies = {}; - var globalLocale; - - function normalizeLocale(key) { - return key ? key.toLowerCase().replace('_', '-') : key; - } - - // pick the locale from the array - // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each - // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root - function chooseLocale(names) { - var i = 0, j, next, locale, split; - - while (i < names.length) { - split = normalizeLocale(names[i]).split('-'); - j = split.length; - next = normalizeLocale(names[i + 1]); - next = next ? next.split('-') : null; - while (j > 0) { - locale = loadLocale(split.slice(0, j).join('-')); - if (locale) { - return locale; - } - if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) { - //the next array item is better than a shallower substring of this one - break; - } - j--; - } - i++; - } - return globalLocale; - } - - function loadLocale(name) { - var oldLocale = null; - // TODO: Find a better way to register and load all the locales in Node - if (!locales[name] && (typeof module !== 'undefined') && - module && module.exports) { - try { - oldLocale = globalLocale._abbr; - var aliasedRequire = require; - aliasedRequire('./locale/' + name); - getSetGlobalLocale(oldLocale); - } catch (e) {} - } - return locales[name]; - } - - // This function will load locale and then set the global locale. If - // no arguments are passed in, it will simply return the current global - // locale key. - function getSetGlobalLocale (key, values) { - var data; - if (key) { - if (isUndefined(values)) { - data = getLocale(key); - } - else { - data = defineLocale(key, values); - } - - if (data) { - // moment.duration._locale = moment._locale = data; - globalLocale = data; - } - else { - if ((typeof console !== 'undefined') && console.warn) { - //warn user if arguments are passed but the locale could not be set - console.warn('Locale ' + key + ' not found. Did you forget to load it?'); - } - } - } - - return globalLocale._abbr; - } - - function defineLocale (name, config) { - if (config !== null) { - var locale, parentConfig = baseConfig; - config.abbr = name; - if (locales[name] != null) { - deprecateSimple('defineLocaleOverride', - 'use moment.updateLocale(localeName, config) to change ' + - 'an existing locale. moment.defineLocale(localeName, ' + - 'config) should only be used for creating a new locale ' + - 'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.'); - parentConfig = locales[name]._config; - } else if (config.parentLocale != null) { - if (locales[config.parentLocale] != null) { - parentConfig = locales[config.parentLocale]._config; - } else { - locale = loadLocale(config.parentLocale); - if (locale != null) { - parentConfig = locale._config; - } else { - if (!localeFamilies[config.parentLocale]) { - localeFamilies[config.parentLocale] = []; - } - localeFamilies[config.parentLocale].push({ - name: name, - config: config - }); - return null; - } - } - } - locales[name] = new Locale(mergeConfigs(parentConfig, config)); - - if (localeFamilies[name]) { - localeFamilies[name].forEach(function (x) { - defineLocale(x.name, x.config); - }); - } - - // backwards compat for now: also set the locale - // make sure we set the locale AFTER all child locales have been - // created, so we won't end up with the child locale set. - getSetGlobalLocale(name); - - - return locales[name]; - } else { - // useful for testing - delete locales[name]; - return null; - } - } - - function updateLocale(name, config) { - if (config != null) { - var locale, tmpLocale, parentConfig = baseConfig; - // MERGE - tmpLocale = loadLocale(name); - if (tmpLocale != null) { - parentConfig = tmpLocale._config; - } - config = mergeConfigs(parentConfig, config); - locale = new Locale(config); - locale.parentLocale = locales[name]; - locales[name] = locale; - - // backwards compat for now: also set the locale - getSetGlobalLocale(name); - } else { - // pass null for config to unupdate, useful for tests - if (locales[name] != null) { - if (locales[name].parentLocale != null) { - locales[name] = locales[name].parentLocale; - } else if (locales[name] != null) { - delete locales[name]; - } - } - } - return locales[name]; - } - - // returns locale data - function getLocale (key) { - var locale; - - if (key && key._locale && key._locale._abbr) { - key = key._locale._abbr; - } - - if (!key) { - return globalLocale; - } - - if (!isArray(key)) { - //short-circuit everything else - locale = loadLocale(key); - if (locale) { - return locale; - } - key = [key]; - } - - return chooseLocale(key); - } - - function listLocales() { - return keys(locales); - } - - function checkOverflow (m) { - var overflow; - var a = m._a; - - if (a && getParsingFlags(m).overflow === -2) { - overflow = - a[MONTH] < 0 || a[MONTH] > 11 ? MONTH : - a[DATE] < 1 || a[DATE] > daysInMonth(a[YEAR], a[MONTH]) ? DATE : - a[HOUR] < 0 || a[HOUR] > 24 || (a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0)) ? HOUR : - a[MINUTE] < 0 || a[MINUTE] > 59 ? MINUTE : - a[SECOND] < 0 || a[SECOND] > 59 ? SECOND : - a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND : - -1; - - if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) { - overflow = DATE; - } - if (getParsingFlags(m)._overflowWeeks && overflow === -1) { - overflow = WEEK; - } - if (getParsingFlags(m)._overflowWeekday && overflow === -1) { - overflow = WEEKDAY; - } - - getParsingFlags(m).overflow = overflow; - } - - return m; - } - - // Pick the first defined of two or three arguments. - function defaults(a, b, c) { - if (a != null) { - return a; - } - if (b != null) { - return b; - } - return c; - } - - function currentDateArray(config) { - // hooks is actually the exported moment object - var nowValue = new Date(hooks.now()); - if (config._useUTC) { - return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()]; - } - return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()]; - } - - // convert an array to a date. - // the array should mirror the parameters below - // note: all values past the year are optional and will default to the lowest possible value. - // [year, month, day , hour, minute, second, millisecond] - function configFromArray (config) { - var i, date, input = [], currentDate, expectedWeekday, yearToUse; - - if (config._d) { - return; - } - - currentDate = currentDateArray(config); - - //compute day of the year from weeks and weekdays - if (config._w && config._a[DATE] == null && config._a[MONTH] == null) { - dayOfYearFromWeekInfo(config); - } - - //if the day of the year is set, figure out what it is - if (config._dayOfYear != null) { - yearToUse = defaults(config._a[YEAR], currentDate[YEAR]); - - if (config._dayOfYear > daysInYear(yearToUse) || config._dayOfYear === 0) { - getParsingFlags(config)._overflowDayOfYear = true; - } - - date = createUTCDate(yearToUse, 0, config._dayOfYear); - config._a[MONTH] = date.getUTCMonth(); - config._a[DATE] = date.getUTCDate(); - } - - // Default to current date. - // * if no year, month, day of month are given, default to today - // * if day of month is given, default month and year - // * if month is given, default only year - // * if year is given, don't default anything - for (i = 0; i < 3 && config._a[i] == null; ++i) { - config._a[i] = input[i] = currentDate[i]; - } - - // Zero out whatever was not defaulted, including time - for (; i < 7; i++) { - config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i]; - } - - // Check for 24:00:00.000 - if (config._a[HOUR] === 24 && - config._a[MINUTE] === 0 && - config._a[SECOND] === 0 && - config._a[MILLISECOND] === 0) { - config._nextDay = true; - config._a[HOUR] = 0; - } - - config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input); - expectedWeekday = config._useUTC ? config._d.getUTCDay() : config._d.getDay(); - - // Apply timezone offset from input. The actual utcOffset can be changed - // with parseZone. - if (config._tzm != null) { - config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm); - } - - if (config._nextDay) { - config._a[HOUR] = 24; - } - - // check for mismatching day of week - if (config._w && typeof config._w.d !== 'undefined' && config._w.d !== expectedWeekday) { - getParsingFlags(config).weekdayMismatch = true; - } - } - - function dayOfYearFromWeekInfo(config) { - var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow; - - w = config._w; - if (w.GG != null || w.W != null || w.E != null) { - dow = 1; - doy = 4; - - // TODO: We need to take the current isoWeekYear, but that depends on - // how we interpret now (local, utc, fixed offset). So create - // a now version of current config (take local/utc/offset flags, and - // create now). - weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(createLocal(), 1, 4).year); - week = defaults(w.W, 1); - weekday = defaults(w.E, 1); - if (weekday < 1 || weekday > 7) { - weekdayOverflow = true; - } - } else { - dow = config._locale._week.dow; - doy = config._locale._week.doy; - - var curWeek = weekOfYear(createLocal(), dow, doy); - - weekYear = defaults(w.gg, config._a[YEAR], curWeek.year); - - // Default to current week. - week = defaults(w.w, curWeek.week); - - if (w.d != null) { - // weekday -- low day numbers are considered next week - weekday = w.d; - if (weekday < 0 || weekday > 6) { - weekdayOverflow = true; - } - } else if (w.e != null) { - // local weekday -- counting starts from beginning of week - weekday = w.e + dow; - if (w.e < 0 || w.e > 6) { - weekdayOverflow = true; - } - } else { - // default to beginning of week - weekday = dow; - } - } - if (week < 1 || week > weeksInYear(weekYear, dow, doy)) { - getParsingFlags(config)._overflowWeeks = true; - } else if (weekdayOverflow != null) { - getParsingFlags(config)._overflowWeekday = true; - } else { - temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy); - config._a[YEAR] = temp.year; - config._dayOfYear = temp.dayOfYear; - } - } - - // iso 8601 regex - // 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00) - var extendedIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/; - var basicIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/; - - var tzRegex = /Z|[+-]\d\d(?::?\d\d)?/; - - var isoDates = [ - ['YYYYYY-MM-DD', /[+-]\d{6}-\d\d-\d\d/], - ['YYYY-MM-DD', /\d{4}-\d\d-\d\d/], - ['GGGG-[W]WW-E', /\d{4}-W\d\d-\d/], - ['GGGG-[W]WW', /\d{4}-W\d\d/, false], - ['YYYY-DDD', /\d{4}-\d{3}/], - ['YYYY-MM', /\d{4}-\d\d/, false], - ['YYYYYYMMDD', /[+-]\d{10}/], - ['YYYYMMDD', /\d{8}/], - // YYYYMM is NOT allowed by the standard - ['GGGG[W]WWE', /\d{4}W\d{3}/], - ['GGGG[W]WW', /\d{4}W\d{2}/, false], - ['YYYYDDD', /\d{7}/] - ]; - - // iso time formats and regexes - var isoTimes = [ - ['HH:mm:ss.SSSS', /\d\d:\d\d:\d\d\.\d+/], - ['HH:mm:ss,SSSS', /\d\d:\d\d:\d\d,\d+/], - ['HH:mm:ss', /\d\d:\d\d:\d\d/], - ['HH:mm', /\d\d:\d\d/], - ['HHmmss.SSSS', /\d\d\d\d\d\d\.\d+/], - ['HHmmss,SSSS', /\d\d\d\d\d\d,\d+/], - ['HHmmss', /\d\d\d\d\d\d/], - ['HHmm', /\d\d\d\d/], - ['HH', /\d\d/] - ]; - - var aspNetJsonRegex = /^\/?Date\((\-?\d+)/i; - - // date from iso format - function configFromISO(config) { - var i, l, - string = config._i, - match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string), - allowTime, dateFormat, timeFormat, tzFormat; - - if (match) { - getParsingFlags(config).iso = true; - - for (i = 0, l = isoDates.length; i < l; i++) { - if (isoDates[i][1].exec(match[1])) { - dateFormat = isoDates[i][0]; - allowTime = isoDates[i][2] !== false; - break; - } - } - if (dateFormat == null) { - config._isValid = false; - return; - } - if (match[3]) { - for (i = 0, l = isoTimes.length; i < l; i++) { - if (isoTimes[i][1].exec(match[3])) { - // match[2] should be 'T' or space - timeFormat = (match[2] || ' ') + isoTimes[i][0]; - break; - } - } - if (timeFormat == null) { - config._isValid = false; - return; - } - } - if (!allowTime && timeFormat != null) { - config._isValid = false; - return; - } - if (match[4]) { - if (tzRegex.exec(match[4])) { - tzFormat = 'Z'; - } else { - config._isValid = false; - return; - } - } - config._f = dateFormat + (timeFormat || '') + (tzFormat || ''); - configFromStringAndFormat(config); - } else { - config._isValid = false; - } - } - - // RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3 - var rfc2822 = /^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/; - - function extractFromRFC2822Strings(yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr) { - var result = [ - untruncateYear(yearStr), - defaultLocaleMonthsShort.indexOf(monthStr), - parseInt(dayStr, 10), - parseInt(hourStr, 10), - parseInt(minuteStr, 10) - ]; - - if (secondStr) { - result.push(parseInt(secondStr, 10)); - } - - return result; - } - - function untruncateYear(yearStr) { - var year = parseInt(yearStr, 10); - if (year <= 49) { - return 2000 + year; - } else if (year <= 999) { - return 1900 + year; - } - return year; - } - - function preprocessRFC2822(s) { - // Remove comments and folding whitespace and replace multiple-spaces with a single space - return s.replace(/\([^)]*\)|[\n\t]/g, ' ').replace(/(\s\s+)/g, ' ').replace(/^\s\s*/, '').replace(/\s\s*$/, ''); - } - - function checkWeekday(weekdayStr, parsedInput, config) { - if (weekdayStr) { - // TODO: Replace the vanilla JS Date object with an indepentent day-of-week check. - var weekdayProvided = defaultLocaleWeekdaysShort.indexOf(weekdayStr), - weekdayActual = new Date(parsedInput[0], parsedInput[1], parsedInput[2]).getDay(); - if (weekdayProvided !== weekdayActual) { - getParsingFlags(config).weekdayMismatch = true; - config._isValid = false; - return false; - } - } - return true; - } - - var obsOffsets = { - UT: 0, - GMT: 0, - EDT: -4 * 60, - EST: -5 * 60, - CDT: -5 * 60, - CST: -6 * 60, - MDT: -6 * 60, - MST: -7 * 60, - PDT: -7 * 60, - PST: -8 * 60 - }; - - function calculateOffset(obsOffset, militaryOffset, numOffset) { - if (obsOffset) { - return obsOffsets[obsOffset]; - } else if (militaryOffset) { - // the only allowed military tz is Z - return 0; - } else { - var hm = parseInt(numOffset, 10); - var m = hm % 100, h = (hm - m) / 100; - return h * 60 + m; - } - } - - // date and time from ref 2822 format - function configFromRFC2822(config) { - var match = rfc2822.exec(preprocessRFC2822(config._i)); - if (match) { - var parsedArray = extractFromRFC2822Strings(match[4], match[3], match[2], match[5], match[6], match[7]); - if (!checkWeekday(match[1], parsedArray, config)) { - return; - } - - config._a = parsedArray; - config._tzm = calculateOffset(match[8], match[9], match[10]); - - config._d = createUTCDate.apply(null, config._a); - config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm); - - getParsingFlags(config).rfc2822 = true; - } else { - config._isValid = false; - } - } - - // date from iso format or fallback - function configFromString(config) { - var matched = aspNetJsonRegex.exec(config._i); - - if (matched !== null) { - config._d = new Date(+matched[1]); - return; - } - - configFromISO(config); - if (config._isValid === false) { - delete config._isValid; - } else { - return; - } - - configFromRFC2822(config); - if (config._isValid === false) { - delete config._isValid; - } else { - return; - } - - // Final attempt, use Input Fallback - hooks.createFromInputFallback(config); - } - - hooks.createFromInputFallback = deprecate( - 'value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' + - 'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' + - 'discouraged and will be removed in an upcoming major release. Please refer to ' + - 'http://momentjs.com/guides/#/warnings/js-date/ for more info.', - function (config) { - config._d = new Date(config._i + (config._useUTC ? ' UTC' : '')); - } - ); - - // constant that refers to the ISO standard - hooks.ISO_8601 = function () {}; - - // constant that refers to the RFC 2822 form - hooks.RFC_2822 = function () {}; - - // date from string and format string - function configFromStringAndFormat(config) { - // TODO: Move this to another part of the creation flow to prevent circular deps - if (config._f === hooks.ISO_8601) { - configFromISO(config); - return; - } - if (config._f === hooks.RFC_2822) { - configFromRFC2822(config); - return; - } - config._a = []; - getParsingFlags(config).empty = true; - - // This array is used to make a Date, either with `new Date` or `Date.UTC` - var string = '' + config._i, - i, parsedInput, tokens, token, skipped, - stringLength = string.length, - totalParsedInputLength = 0; - - tokens = expandFormat(config._f, config._locale).match(formattingTokens) || []; - - for (i = 0; i < tokens.length; i++) { - token = tokens[i]; - parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0]; - // console.log('token', token, 'parsedInput', parsedInput, - // 'regex', getParseRegexForToken(token, config)); - if (parsedInput) { - skipped = string.substr(0, string.indexOf(parsedInput)); - if (skipped.length > 0) { - getParsingFlags(config).unusedInput.push(skipped); - } - string = string.slice(string.indexOf(parsedInput) + parsedInput.length); - totalParsedInputLength += parsedInput.length; - } - // don't parse if it's not a known token - if (formatTokenFunctions[token]) { - if (parsedInput) { - getParsingFlags(config).empty = false; - } - else { - getParsingFlags(config).unusedTokens.push(token); - } - addTimeToArrayFromToken(token, parsedInput, config); - } - else if (config._strict && !parsedInput) { - getParsingFlags(config).unusedTokens.push(token); - } - } - - // add remaining unparsed input length to the string - getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength; - if (string.length > 0) { - getParsingFlags(config).unusedInput.push(string); - } - - // clear _12h flag if hour is <= 12 - if (config._a[HOUR] <= 12 && - getParsingFlags(config).bigHour === true && - config._a[HOUR] > 0) { - getParsingFlags(config).bigHour = undefined; - } - - getParsingFlags(config).parsedDateParts = config._a.slice(0); - getParsingFlags(config).meridiem = config._meridiem; - // handle meridiem - config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem); - - configFromArray(config); - checkOverflow(config); - } - - - function meridiemFixWrap (locale, hour, meridiem) { - var isPm; - - if (meridiem == null) { - // nothing to do - return hour; - } - if (locale.meridiemHour != null) { - return locale.meridiemHour(hour, meridiem); - } else if (locale.isPM != null) { - // Fallback - isPm = locale.isPM(meridiem); - if (isPm && hour < 12) { - hour += 12; - } - if (!isPm && hour === 12) { - hour = 0; - } - return hour; - } else { - // this is not supposed to happen - return hour; - } - } - - // date from string and array of format strings - function configFromStringAndArray(config) { - var tempConfig, - bestMoment, - - scoreToBeat, - i, - currentScore; - - if (config._f.length === 0) { - getParsingFlags(config).invalidFormat = true; - config._d = new Date(NaN); - return; - } - - for (i = 0; i < config._f.length; i++) { - currentScore = 0; - tempConfig = copyConfig({}, config); - if (config._useUTC != null) { - tempConfig._useUTC = config._useUTC; - } - tempConfig._f = config._f[i]; - configFromStringAndFormat(tempConfig); - - if (!isValid(tempConfig)) { - continue; - } - - // if there is any input that was not parsed add a penalty for that format - currentScore += getParsingFlags(tempConfig).charsLeftOver; - - //or tokens - currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10; - - getParsingFlags(tempConfig).score = currentScore; - - if (scoreToBeat == null || currentScore < scoreToBeat) { - scoreToBeat = currentScore; - bestMoment = tempConfig; - } - } - - extend(config, bestMoment || tempConfig); - } - - function configFromObject(config) { - if (config._d) { - return; - } - - var i = normalizeObjectUnits(config._i); - config._a = map([i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond], function (obj) { - return obj && parseInt(obj, 10); - }); - - configFromArray(config); - } - - function createFromConfig (config) { - var res = new Moment(checkOverflow(prepareConfig(config))); - if (res._nextDay) { - // Adding is smart enough around DST - res.add(1, 'd'); - res._nextDay = undefined; - } - - return res; - } - - function prepareConfig (config) { - var input = config._i, - format = config._f; - - config._locale = config._locale || getLocale(config._l); - - if (input === null || (format === undefined && input === '')) { - return createInvalid({nullInput: true}); - } - - if (typeof input === 'string') { - config._i = input = config._locale.preparse(input); - } - - if (isMoment(input)) { - return new Moment(checkOverflow(input)); - } else if (isDate(input)) { - config._d = input; - } else if (isArray(format)) { - configFromStringAndArray(config); - } else if (format) { - configFromStringAndFormat(config); - } else { - configFromInput(config); - } - - if (!isValid(config)) { - config._d = null; - } - - return config; - } - - function configFromInput(config) { - var input = config._i; - if (isUndefined(input)) { - config._d = new Date(hooks.now()); - } else if (isDate(input)) { - config._d = new Date(input.valueOf()); - } else if (typeof input === 'string') { - configFromString(config); - } else if (isArray(input)) { - config._a = map(input.slice(0), function (obj) { - return parseInt(obj, 10); - }); - configFromArray(config); - } else if (isObject(input)) { - configFromObject(config); - } else if (isNumber(input)) { - // from milliseconds - config._d = new Date(input); - } else { - hooks.createFromInputFallback(config); - } - } - - function createLocalOrUTC (input, format, locale, strict, isUTC) { - var c = {}; - - if (locale === true || locale === false) { - strict = locale; - locale = undefined; - } - - if ((isObject(input) && isObjectEmpty(input)) || - (isArray(input) && input.length === 0)) { - input = undefined; - } - // object construction must be done this way. - // https://github.com/moment/moment/issues/1423 - c._isAMomentObject = true; - c._useUTC = c._isUTC = isUTC; - c._l = locale; - c._i = input; - c._f = format; - c._strict = strict; - - return createFromConfig(c); - } - - function createLocal (input, format, locale, strict) { - return createLocalOrUTC(input, format, locale, strict, false); - } - - var prototypeMin = deprecate( - 'moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/', - function () { - var other = createLocal.apply(null, arguments); - if (this.isValid() && other.isValid()) { - return other < this ? this : other; - } else { - return createInvalid(); - } - } - ); - - var prototypeMax = deprecate( - 'moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/', - function () { - var other = createLocal.apply(null, arguments); - if (this.isValid() && other.isValid()) { - return other > this ? this : other; - } else { - return createInvalid(); - } - } - ); - - // Pick a moment m from moments so that m[fn](other) is true for all - // other. This relies on the function fn to be transitive. - // - // moments should either be an array of moment objects or an array, whose - // first element is an array of moment objects. - function pickBy(fn, moments) { - var res, i; - if (moments.length === 1 && isArray(moments[0])) { - moments = moments[0]; - } - if (!moments.length) { - return createLocal(); - } - res = moments[0]; - for (i = 1; i < moments.length; ++i) { - if (!moments[i].isValid() || moments[i][fn](res)) { - res = moments[i]; - } - } - return res; - } - - // TODO: Use [].sort instead? - function min () { - var args = [].slice.call(arguments, 0); - - return pickBy('isBefore', args); - } - - function max () { - var args = [].slice.call(arguments, 0); - - return pickBy('isAfter', args); - } - - var now = function () { - return Date.now ? Date.now() : +(new Date()); - }; - - var ordering = ['year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond']; - - function isDurationValid(m) { - for (var key in m) { - if (!(indexOf.call(ordering, key) !== -1 && (m[key] == null || !isNaN(m[key])))) { - return false; - } - } - - var unitHasDecimal = false; - for (var i = 0; i < ordering.length; ++i) { - if (m[ordering[i]]) { - if (unitHasDecimal) { - return false; // only allow non-integers for smallest unit - } - if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) { - unitHasDecimal = true; - } - } - } - - return true; - } - - function isValid$1() { - return this._isValid; - } - - function createInvalid$1() { - return createDuration(NaN); - } - - function Duration (duration) { - var normalizedInput = normalizeObjectUnits(duration), - years = normalizedInput.year || 0, - quarters = normalizedInput.quarter || 0, - months = normalizedInput.month || 0, - weeks = normalizedInput.week || normalizedInput.isoWeek || 0, - days = normalizedInput.day || 0, - hours = normalizedInput.hour || 0, - minutes = normalizedInput.minute || 0, - seconds = normalizedInput.second || 0, - milliseconds = normalizedInput.millisecond || 0; - - this._isValid = isDurationValid(normalizedInput); - - // representation for dateAddRemove - this._milliseconds = +milliseconds + - seconds * 1e3 + // 1000 - minutes * 6e4 + // 1000 * 60 - hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978 - // Because of dateAddRemove treats 24 hours as different from a - // day when working around DST, we need to store them separately - this._days = +days + - weeks * 7; - // It is impossible to translate months into days without knowing - // which months you are are talking about, so we have to store - // it separately. - this._months = +months + - quarters * 3 + - years * 12; - - this._data = {}; - - this._locale = getLocale(); - - this._bubble(); - } - - function isDuration (obj) { - return obj instanceof Duration; - } - - function absRound (number) { - if (number < 0) { - return Math.round(-1 * number) * -1; - } else { - return Math.round(number); - } - } - - // FORMATTING - - function offset (token, separator) { - addFormatToken(token, 0, 0, function () { - var offset = this.utcOffset(); - var sign = '+'; - if (offset < 0) { - offset = -offset; - sign = '-'; - } - return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~(offset) % 60, 2); - }); - } - - offset('Z', ':'); - offset('ZZ', ''); - - // PARSING - - addRegexToken('Z', matchShortOffset); - addRegexToken('ZZ', matchShortOffset); - addParseToken(['Z', 'ZZ'], function (input, array, config) { - config._useUTC = true; - config._tzm = offsetFromString(matchShortOffset, input); - }); - - // HELPERS - - // timezone chunker - // '+10:00' > ['10', '00'] - // '-1530' > ['-15', '30'] - var chunkOffset = /([\+\-]|\d\d)/gi; - - function offsetFromString(matcher, string) { - var matches = (string || '').match(matcher); - - if (matches === null) { - return null; - } - - var chunk = matches[matches.length - 1] || []; - var parts = (chunk + '').match(chunkOffset) || ['-', 0, 0]; - var minutes = +(parts[1] * 60) + toInt(parts[2]); - - return minutes === 0 ? - 0 : - parts[0] === '+' ? minutes : -minutes; - } - - // Return a moment from input, that is local/utc/zone equivalent to model. - function cloneWithOffset(input, model) { - var res, diff; - if (model._isUTC) { - res = model.clone(); - diff = (isMoment(input) || isDate(input) ? input.valueOf() : createLocal(input).valueOf()) - res.valueOf(); - // Use low-level api, because this fn is low-level api. - res._d.setTime(res._d.valueOf() + diff); - hooks.updateOffset(res, false); - return res; - } else { - return createLocal(input).local(); - } - } - - function getDateOffset (m) { - // On Firefox.24 Date#getTimezoneOffset returns a floating point. - // https://github.com/moment/moment/pull/1871 - return -Math.round(m._d.getTimezoneOffset() / 15) * 15; - } - - // HOOKS - - // This function will be called whenever a moment is mutated. - // It is intended to keep the offset in sync with the timezone. - hooks.updateOffset = function () {}; - - // MOMENTS - - // keepLocalTime = true means only change the timezone, without - // affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]--> - // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset - // +0200, so we adjust the time as needed, to be valid. - // - // Keeping the time actually adds/subtracts (one hour) - // from the actual represented time. That is why we call updateOffset - // a second time. In case it wants us to change the offset again - // _changeInProgress == true case, then we have to adjust, because - // there is no such time in the given timezone. - function getSetOffset (input, keepLocalTime, keepMinutes) { - var offset = this._offset || 0, - localAdjust; - if (!this.isValid()) { - return input != null ? this : NaN; - } - if (input != null) { - if (typeof input === 'string') { - input = offsetFromString(matchShortOffset, input); - if (input === null) { - return this; - } - } else if (Math.abs(input) < 16 && !keepMinutes) { - input = input * 60; - } - if (!this._isUTC && keepLocalTime) { - localAdjust = getDateOffset(this); - } - this._offset = input; - this._isUTC = true; - if (localAdjust != null) { - this.add(localAdjust, 'm'); - } - if (offset !== input) { - if (!keepLocalTime || this._changeInProgress) { - addSubtract(this, createDuration(input - offset, 'm'), 1, false); - } else if (!this._changeInProgress) { - this._changeInProgress = true; - hooks.updateOffset(this, true); - this._changeInProgress = null; - } - } - return this; - } else { - return this._isUTC ? offset : getDateOffset(this); - } - } - - function getSetZone (input, keepLocalTime) { - if (input != null) { - if (typeof input !== 'string') { - input = -input; - } - - this.utcOffset(input, keepLocalTime); - - return this; - } else { - return -this.utcOffset(); - } - } - - function setOffsetToUTC (keepLocalTime) { - return this.utcOffset(0, keepLocalTime); - } - - function setOffsetToLocal (keepLocalTime) { - if (this._isUTC) { - this.utcOffset(0, keepLocalTime); - this._isUTC = false; - - if (keepLocalTime) { - this.subtract(getDateOffset(this), 'm'); - } - } - return this; - } - - function setOffsetToParsedOffset () { - if (this._tzm != null) { - this.utcOffset(this._tzm, false, true); - } else if (typeof this._i === 'string') { - var tZone = offsetFromString(matchOffset, this._i); - if (tZone != null) { - this.utcOffset(tZone); - } - else { - this.utcOffset(0, true); - } - } - return this; - } - - function hasAlignedHourOffset (input) { - if (!this.isValid()) { - return false; - } - input = input ? createLocal(input).utcOffset() : 0; - - return (this.utcOffset() - input) % 60 === 0; - } - - function isDaylightSavingTime () { - return ( - this.utcOffset() > this.clone().month(0).utcOffset() || - this.utcOffset() > this.clone().month(5).utcOffset() - ); - } - - function isDaylightSavingTimeShifted () { - if (!isUndefined(this._isDSTShifted)) { - return this._isDSTShifted; - } - - var c = {}; - - copyConfig(c, this); - c = prepareConfig(c); - - if (c._a) { - var other = c._isUTC ? createUTC(c._a) : createLocal(c._a); - this._isDSTShifted = this.isValid() && - compareArrays(c._a, other.toArray()) > 0; - } else { - this._isDSTShifted = false; - } - - return this._isDSTShifted; - } - - function isLocal () { - return this.isValid() ? !this._isUTC : false; - } - - function isUtcOffset () { - return this.isValid() ? this._isUTC : false; - } - - function isUtc () { - return this.isValid() ? this._isUTC && this._offset === 0 : false; - } - - // ASP.NET json date format regex - var aspNetRegex = /^(\-|\+)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/; - - // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html - // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere - // and further modified to allow for strings containing both week and day - var isoRegex = /^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/; - - function createDuration (input, key) { - var duration = input, - // matching against regexp is expensive, do it on demand - match = null, - sign, - ret, - diffRes; - - if (isDuration(input)) { - duration = { - ms : input._milliseconds, - d : input._days, - M : input._months - }; - } else if (isNumber(input)) { - duration = {}; - if (key) { - duration[key] = input; - } else { - duration.milliseconds = input; - } - } else if (!!(match = aspNetRegex.exec(input))) { - sign = (match[1] === '-') ? -1 : 1; - duration = { - y : 0, - d : toInt(match[DATE]) * sign, - h : toInt(match[HOUR]) * sign, - m : toInt(match[MINUTE]) * sign, - s : toInt(match[SECOND]) * sign, - ms : toInt(absRound(match[MILLISECOND] * 1000)) * sign // the millisecond decimal point is included in the match - }; - } else if (!!(match = isoRegex.exec(input))) { - sign = (match[1] === '-') ? -1 : 1; - duration = { - y : parseIso(match[2], sign), - M : parseIso(match[3], sign), - w : parseIso(match[4], sign), - d : parseIso(match[5], sign), - h : parseIso(match[6], sign), - m : parseIso(match[7], sign), - s : parseIso(match[8], sign) - }; - } else if (duration == null) {// checks for null or undefined - duration = {}; - } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) { - diffRes = momentsDifference(createLocal(duration.from), createLocal(duration.to)); - - duration = {}; - duration.ms = diffRes.milliseconds; - duration.M = diffRes.months; - } - - ret = new Duration(duration); - - if (isDuration(input) && hasOwnProp(input, '_locale')) { - ret._locale = input._locale; - } - - return ret; - } - - createDuration.fn = Duration.prototype; - createDuration.invalid = createInvalid$1; - - function parseIso (inp, sign) { - // We'd normally use ~~inp for this, but unfortunately it also - // converts floats to ints. - // inp may be undefined, so careful calling replace on it. - var res = inp && parseFloat(inp.replace(',', '.')); - // apply sign while we're at it - return (isNaN(res) ? 0 : res) * sign; - } - - function positiveMomentsDifference(base, other) { - var res = {milliseconds: 0, months: 0}; - - res.months = other.month() - base.month() + - (other.year() - base.year()) * 12; - if (base.clone().add(res.months, 'M').isAfter(other)) { - --res.months; - } - - res.milliseconds = +other - +(base.clone().add(res.months, 'M')); - - return res; - } - - function momentsDifference(base, other) { - var res; - if (!(base.isValid() && other.isValid())) { - return {milliseconds: 0, months: 0}; - } - - other = cloneWithOffset(other, base); - if (base.isBefore(other)) { - res = positiveMomentsDifference(base, other); - } else { - res = positiveMomentsDifference(other, base); - res.milliseconds = -res.milliseconds; - res.months = -res.months; - } - - return res; - } - - // TODO: remove 'name' arg after deprecation is removed - function createAdder(direction, name) { - return function (val, period) { - var dur, tmp; - //invert the arguments, but complain about it - if (period !== null && !isNaN(+period)) { - deprecateSimple(name, 'moment().' + name + '(period, number) is deprecated. Please use moment().' + name + '(number, period). ' + - 'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.'); - tmp = val; val = period; period = tmp; - } - - val = typeof val === 'string' ? +val : val; - dur = createDuration(val, period); - addSubtract(this, dur, direction); - return this; - }; - } - - function addSubtract (mom, duration, isAdding, updateOffset) { - var milliseconds = duration._milliseconds, - days = absRound(duration._days), - months = absRound(duration._months); - - if (!mom.isValid()) { - // No op - return; - } - - updateOffset = updateOffset == null ? true : updateOffset; - - if (months) { - setMonth(mom, get(mom, 'Month') + months * isAdding); - } - if (days) { - set$1(mom, 'Date', get(mom, 'Date') + days * isAdding); - } - if (milliseconds) { - mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding); - } - if (updateOffset) { - hooks.updateOffset(mom, days || months); - } - } - - var add = createAdder(1, 'add'); - var subtract = createAdder(-1, 'subtract'); - - function getCalendarFormat(myMoment, now) { - var diff = myMoment.diff(now, 'days', true); - return diff < -6 ? 'sameElse' : - diff < -1 ? 'lastWeek' : - diff < 0 ? 'lastDay' : - diff < 1 ? 'sameDay' : - diff < 2 ? 'nextDay' : - diff < 7 ? 'nextWeek' : 'sameElse'; - } - - function calendar$1 (time, formats) { - // We want to compare the start of today, vs this. - // Getting start-of-today depends on whether we're local/utc/offset or not. - var now = time || createLocal(), - sod = cloneWithOffset(now, this).startOf('day'), - format = hooks.calendarFormat(this, sod) || 'sameElse'; - - var output = formats && (isFunction(formats[format]) ? formats[format].call(this, now) : formats[format]); - - return this.format(output || this.localeData().calendar(format, this, createLocal(now))); - } - - function clone () { - return new Moment(this); - } - - function isAfter (input, units) { - var localInput = isMoment(input) ? input : createLocal(input); - if (!(this.isValid() && localInput.isValid())) { - return false; - } - units = normalizeUnits(units) || 'millisecond'; - if (units === 'millisecond') { - return this.valueOf() > localInput.valueOf(); - } else { - return localInput.valueOf() < this.clone().startOf(units).valueOf(); - } - } - - function isBefore (input, units) { - var localInput = isMoment(input) ? input : createLocal(input); - if (!(this.isValid() && localInput.isValid())) { - return false; - } - units = normalizeUnits(units) || 'millisecond'; - if (units === 'millisecond') { - return this.valueOf() < localInput.valueOf(); - } else { - return this.clone().endOf(units).valueOf() < localInput.valueOf(); - } - } - - function isBetween (from, to, units, inclusivity) { - var localFrom = isMoment(from) ? from : createLocal(from), - localTo = isMoment(to) ? to : createLocal(to); - if (!(this.isValid() && localFrom.isValid() && localTo.isValid())) { - return false; - } - inclusivity = inclusivity || '()'; - return (inclusivity[0] === '(' ? this.isAfter(localFrom, units) : !this.isBefore(localFrom, units)) && - (inclusivity[1] === ')' ? this.isBefore(localTo, units) : !this.isAfter(localTo, units)); - } - - function isSame (input, units) { - var localInput = isMoment(input) ? input : createLocal(input), - inputMs; - if (!(this.isValid() && localInput.isValid())) { - return false; - } - units = normalizeUnits(units) || 'millisecond'; - if (units === 'millisecond') { - return this.valueOf() === localInput.valueOf(); - } else { - inputMs = localInput.valueOf(); - return this.clone().startOf(units).valueOf() <= inputMs && inputMs <= this.clone().endOf(units).valueOf(); - } - } - - function isSameOrAfter (input, units) { - return this.isSame(input, units) || this.isAfter(input, units); - } - - function isSameOrBefore (input, units) { - return this.isSame(input, units) || this.isBefore(input, units); - } - - function diff (input, units, asFloat) { - var that, - zoneDelta, - output; - - if (!this.isValid()) { - return NaN; - } - - that = cloneWithOffset(input, this); - - if (!that.isValid()) { - return NaN; - } - - zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4; - - units = normalizeUnits(units); - - switch (units) { - case 'year': output = monthDiff(this, that) / 12; break; - case 'month': output = monthDiff(this, that); break; - case 'quarter': output = monthDiff(this, that) / 3; break; - case 'second': output = (this - that) / 1e3; break; // 1000 - case 'minute': output = (this - that) / 6e4; break; // 1000 * 60 - case 'hour': output = (this - that) / 36e5; break; // 1000 * 60 * 60 - case 'day': output = (this - that - zoneDelta) / 864e5; break; // 1000 * 60 * 60 * 24, negate dst - case 'week': output = (this - that - zoneDelta) / 6048e5; break; // 1000 * 60 * 60 * 24 * 7, negate dst - default: output = this - that; - } - - return asFloat ? output : absFloor(output); - } - - function monthDiff (a, b) { - // difference in months - var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()), - // b is in (anchor - 1 month, anchor + 1 month) - anchor = a.clone().add(wholeMonthDiff, 'months'), - anchor2, adjust; - - if (b - anchor < 0) { - anchor2 = a.clone().add(wholeMonthDiff - 1, 'months'); - // linear across the month - adjust = (b - anchor) / (anchor - anchor2); - } else { - anchor2 = a.clone().add(wholeMonthDiff + 1, 'months'); - // linear across the month - adjust = (b - anchor) / (anchor2 - anchor); - } - - //check for negative zero, return zero if negative zero - return -(wholeMonthDiff + adjust) || 0; - } - - hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ'; - hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]'; - - function toString () { - return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ'); - } - - function toISOString(keepOffset) { - if (!this.isValid()) { - return null; - } - var utc = keepOffset !== true; - var m = utc ? this.clone().utc() : this; - if (m.year() < 0 || m.year() > 9999) { - return formatMoment(m, utc ? 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYYYY-MM-DD[T]HH:mm:ss.SSSZ'); - } - if (isFunction(Date.prototype.toISOString)) { - // native implementation is ~50x faster, use it when we can - if (utc) { - return this.toDate().toISOString(); - } else { - return new Date(this.valueOf() + this.utcOffset() * 60 * 1000).toISOString().replace('Z', formatMoment(m, 'Z')); - } - } - return formatMoment(m, utc ? 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYY-MM-DD[T]HH:mm:ss.SSSZ'); - } - - /** - * Return a human readable representation of a moment that can - * also be evaluated to get a new moment which is the same - * - * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects - */ - function inspect () { - if (!this.isValid()) { - return 'moment.invalid(/* ' + this._i + ' */)'; - } - var func = 'moment'; - var zone = ''; - if (!this.isLocal()) { - func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone'; - zone = 'Z'; - } - var prefix = '[' + func + '("]'; - var year = (0 <= this.year() && this.year() <= 9999) ? 'YYYY' : 'YYYYYY'; - var datetime = '-MM-DD[T]HH:mm:ss.SSS'; - var suffix = zone + '[")]'; - - return this.format(prefix + year + datetime + suffix); - } - - function format (inputString) { - if (!inputString) { - inputString = this.isUtc() ? hooks.defaultFormatUtc : hooks.defaultFormat; - } - var output = formatMoment(this, inputString); - return this.localeData().postformat(output); - } - - function from (time, withoutSuffix) { - if (this.isValid() && - ((isMoment(time) && time.isValid()) || - createLocal(time).isValid())) { - return createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix); - } else { - return this.localeData().invalidDate(); - } - } - - function fromNow (withoutSuffix) { - return this.from(createLocal(), withoutSuffix); - } - - function to (time, withoutSuffix) { - if (this.isValid() && - ((isMoment(time) && time.isValid()) || - createLocal(time).isValid())) { - return createDuration({from: this, to: time}).locale(this.locale()).humanize(!withoutSuffix); - } else { - return this.localeData().invalidDate(); - } - } - - function toNow (withoutSuffix) { - return this.to(createLocal(), withoutSuffix); - } - - // If passed a locale key, it will set the locale for this - // instance. Otherwise, it will return the locale configuration - // variables for this instance. - function locale (key) { - var newLocaleData; - - if (key === undefined) { - return this._locale._abbr; - } else { - newLocaleData = getLocale(key); - if (newLocaleData != null) { - this._locale = newLocaleData; - } - return this; - } - } - - var lang = deprecate( - 'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.', - function (key) { - if (key === undefined) { - return this.localeData(); - } else { - return this.locale(key); - } - } - ); - - function localeData () { - return this._locale; - } - - function startOf (units) { - units = normalizeUnits(units); - // the following switch intentionally omits break keywords - // to utilize falling through the cases. - switch (units) { - case 'year': - this.month(0); - /* falls through */ - case 'quarter': - case 'month': - this.date(1); - /* falls through */ - case 'week': - case 'isoWeek': - case 'day': - case 'date': - this.hours(0); - /* falls through */ - case 'hour': - this.minutes(0); - /* falls through */ - case 'minute': - this.seconds(0); - /* falls through */ - case 'second': - this.milliseconds(0); - } - - // weeks are a special case - if (units === 'week') { - this.weekday(0); - } - if (units === 'isoWeek') { - this.isoWeekday(1); - } - - // quarters are also special - if (units === 'quarter') { - this.month(Math.floor(this.month() / 3) * 3); - } - - return this; - } - - function endOf (units) { - units = normalizeUnits(units); - if (units === undefined || units === 'millisecond') { - return this; - } - - // 'date' is an alias for 'day', so it should be considered as such. - if (units === 'date') { - units = 'day'; - } - - return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms'); - } - - function valueOf () { - return this._d.valueOf() - ((this._offset || 0) * 60000); - } - - function unix () { - return Math.floor(this.valueOf() / 1000); - } - - function toDate () { - return new Date(this.valueOf()); - } - - function toArray () { - var m = this; - return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()]; - } - - function toObject () { - var m = this; - return { - years: m.year(), - months: m.month(), - date: m.date(), - hours: m.hours(), - minutes: m.minutes(), - seconds: m.seconds(), - milliseconds: m.milliseconds() - }; - } - - function toJSON () { - // new Date(NaN).toJSON() === null - return this.isValid() ? this.toISOString() : null; - } - - function isValid$2 () { - return isValid(this); - } - - function parsingFlags () { - return extend({}, getParsingFlags(this)); - } - - function invalidAt () { - return getParsingFlags(this).overflow; - } - - function creationData() { - return { - input: this._i, - format: this._f, - locale: this._locale, - isUTC: this._isUTC, - strict: this._strict - }; - } - - // FORMATTING - - addFormatToken(0, ['gg', 2], 0, function () { - return this.weekYear() % 100; - }); - - addFormatToken(0, ['GG', 2], 0, function () { - return this.isoWeekYear() % 100; - }); - - function addWeekYearFormatToken (token, getter) { - addFormatToken(0, [token, token.length], 0, getter); - } - - addWeekYearFormatToken('gggg', 'weekYear'); - addWeekYearFormatToken('ggggg', 'weekYear'); - addWeekYearFormatToken('GGGG', 'isoWeekYear'); - addWeekYearFormatToken('GGGGG', 'isoWeekYear'); - - // ALIASES - - addUnitAlias('weekYear', 'gg'); - addUnitAlias('isoWeekYear', 'GG'); - - // PRIORITY - - addUnitPriority('weekYear', 1); - addUnitPriority('isoWeekYear', 1); - - - // PARSING - - addRegexToken('G', matchSigned); - addRegexToken('g', matchSigned); - addRegexToken('GG', match1to2, match2); - addRegexToken('gg', match1to2, match2); - addRegexToken('GGGG', match1to4, match4); - addRegexToken('gggg', match1to4, match4); - addRegexToken('GGGGG', match1to6, match6); - addRegexToken('ggggg', match1to6, match6); - - addWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) { - week[token.substr(0, 2)] = toInt(input); - }); - - addWeekParseToken(['gg', 'GG'], function (input, week, config, token) { - week[token] = hooks.parseTwoDigitYear(input); - }); - - // MOMENTS - - function getSetWeekYear (input) { - return getSetWeekYearHelper.call(this, - input, - this.week(), - this.weekday(), - this.localeData()._week.dow, - this.localeData()._week.doy); - } - - function getSetISOWeekYear (input) { - return getSetWeekYearHelper.call(this, - input, this.isoWeek(), this.isoWeekday(), 1, 4); - } - - function getISOWeeksInYear () { - return weeksInYear(this.year(), 1, 4); - } - - function getWeeksInYear () { - var weekInfo = this.localeData()._week; - return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy); - } - - function getSetWeekYearHelper(input, week, weekday, dow, doy) { - var weeksTarget; - if (input == null) { - return weekOfYear(this, dow, doy).year; - } else { - weeksTarget = weeksInYear(input, dow, doy); - if (week > weeksTarget) { - week = weeksTarget; - } - return setWeekAll.call(this, input, week, weekday, dow, doy); - } - } - - function setWeekAll(weekYear, week, weekday, dow, doy) { - var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy), - date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear); - - this.year(date.getUTCFullYear()); - this.month(date.getUTCMonth()); - this.date(date.getUTCDate()); - return this; - } - - // FORMATTING - - addFormatToken('Q', 0, 'Qo', 'quarter'); - - // ALIASES - - addUnitAlias('quarter', 'Q'); - - // PRIORITY - - addUnitPriority('quarter', 7); - - // PARSING - - addRegexToken('Q', match1); - addParseToken('Q', function (input, array) { - array[MONTH] = (toInt(input) - 1) * 3; - }); - - // MOMENTS - - function getSetQuarter (input) { - return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3); - } - - // FORMATTING - - addFormatToken('D', ['DD', 2], 'Do', 'date'); - - // ALIASES - - addUnitAlias('date', 'D'); - - // PRIORITY - addUnitPriority('date', 9); - - // PARSING - - addRegexToken('D', match1to2); - addRegexToken('DD', match1to2, match2); - addRegexToken('Do', function (isStrict, locale) { - // TODO: Remove "ordinalParse" fallback in next major release. - return isStrict ? - (locale._dayOfMonthOrdinalParse || locale._ordinalParse) : - locale._dayOfMonthOrdinalParseLenient; - }); - - addParseToken(['D', 'DD'], DATE); - addParseToken('Do', function (input, array) { - array[DATE] = toInt(input.match(match1to2)[0]); - }); - - // MOMENTS - - var getSetDayOfMonth = makeGetSet('Date', true); - - // FORMATTING - - addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear'); - - // ALIASES - - addUnitAlias('dayOfYear', 'DDD'); - - // PRIORITY - addUnitPriority('dayOfYear', 4); - - // PARSING - - addRegexToken('DDD', match1to3); - addRegexToken('DDDD', match3); - addParseToken(['DDD', 'DDDD'], function (input, array, config) { - config._dayOfYear = toInt(input); - }); - - // HELPERS - - // MOMENTS - - function getSetDayOfYear (input) { - var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1; - return input == null ? dayOfYear : this.add((input - dayOfYear), 'd'); - } - - // FORMATTING - - addFormatToken('m', ['mm', 2], 0, 'minute'); - - // ALIASES - - addUnitAlias('minute', 'm'); - - // PRIORITY - - addUnitPriority('minute', 14); - - // PARSING - - addRegexToken('m', match1to2); - addRegexToken('mm', match1to2, match2); - addParseToken(['m', 'mm'], MINUTE); - - // MOMENTS - - var getSetMinute = makeGetSet('Minutes', false); - - // FORMATTING - - addFormatToken('s', ['ss', 2], 0, 'second'); - - // ALIASES - - addUnitAlias('second', 's'); - - // PRIORITY - - addUnitPriority('second', 15); - - // PARSING - - addRegexToken('s', match1to2); - addRegexToken('ss', match1to2, match2); - addParseToken(['s', 'ss'], SECOND); - - // MOMENTS - - var getSetSecond = makeGetSet('Seconds', false); - - // FORMATTING - - addFormatToken('S', 0, 0, function () { - return ~~(this.millisecond() / 100); - }); - - addFormatToken(0, ['SS', 2], 0, function () { - return ~~(this.millisecond() / 10); - }); - - addFormatToken(0, ['SSS', 3], 0, 'millisecond'); - addFormatToken(0, ['SSSS', 4], 0, function () { - return this.millisecond() * 10; - }); - addFormatToken(0, ['SSSSS', 5], 0, function () { - return this.millisecond() * 100; - }); - addFormatToken(0, ['SSSSSS', 6], 0, function () { - return this.millisecond() * 1000; - }); - addFormatToken(0, ['SSSSSSS', 7], 0, function () { - return this.millisecond() * 10000; - }); - addFormatToken(0, ['SSSSSSSS', 8], 0, function () { - return this.millisecond() * 100000; - }); - addFormatToken(0, ['SSSSSSSSS', 9], 0, function () { - return this.millisecond() * 1000000; - }); - - - // ALIASES - - addUnitAlias('millisecond', 'ms'); - - // PRIORITY - - addUnitPriority('millisecond', 16); - - // PARSING - - addRegexToken('S', match1to3, match1); - addRegexToken('SS', match1to3, match2); - addRegexToken('SSS', match1to3, match3); - - var token; - for (token = 'SSSS'; token.length <= 9; token += 'S') { - addRegexToken(token, matchUnsigned); - } - - function parseMs(input, array) { - array[MILLISECOND] = toInt(('0.' + input) * 1000); - } - - for (token = 'S'; token.length <= 9; token += 'S') { - addParseToken(token, parseMs); - } - // MOMENTS - - var getSetMillisecond = makeGetSet('Milliseconds', false); - - // FORMATTING - - addFormatToken('z', 0, 0, 'zoneAbbr'); - addFormatToken('zz', 0, 0, 'zoneName'); - - // MOMENTS - - function getZoneAbbr () { - return this._isUTC ? 'UTC' : ''; - } - - function getZoneName () { - return this._isUTC ? 'Coordinated Universal Time' : ''; - } - - var proto = Moment.prototype; - - proto.add = add; - proto.calendar = calendar$1; - proto.clone = clone; - proto.diff = diff; - proto.endOf = endOf; - proto.format = format; - proto.from = from; - proto.fromNow = fromNow; - proto.to = to; - proto.toNow = toNow; - proto.get = stringGet; - proto.invalidAt = invalidAt; - proto.isAfter = isAfter; - proto.isBefore = isBefore; - proto.isBetween = isBetween; - proto.isSame = isSame; - proto.isSameOrAfter = isSameOrAfter; - proto.isSameOrBefore = isSameOrBefore; - proto.isValid = isValid$2; - proto.lang = lang; - proto.locale = locale; - proto.localeData = localeData; - proto.max = prototypeMax; - proto.min = prototypeMin; - proto.parsingFlags = parsingFlags; - proto.set = stringSet; - proto.startOf = startOf; - proto.subtract = subtract; - proto.toArray = toArray; - proto.toObject = toObject; - proto.toDate = toDate; - proto.toISOString = toISOString; - proto.inspect = inspect; - proto.toJSON = toJSON; - proto.toString = toString; - proto.unix = unix; - proto.valueOf = valueOf; - proto.creationData = creationData; - proto.year = getSetYear; - proto.isLeapYear = getIsLeapYear; - proto.weekYear = getSetWeekYear; - proto.isoWeekYear = getSetISOWeekYear; - proto.quarter = proto.quarters = getSetQuarter; - proto.month = getSetMonth; - proto.daysInMonth = getDaysInMonth; - proto.week = proto.weeks = getSetWeek; - proto.isoWeek = proto.isoWeeks = getSetISOWeek; - proto.weeksInYear = getWeeksInYear; - proto.isoWeeksInYear = getISOWeeksInYear; - proto.date = getSetDayOfMonth; - proto.day = proto.days = getSetDayOfWeek; - proto.weekday = getSetLocaleDayOfWeek; - proto.isoWeekday = getSetISODayOfWeek; - proto.dayOfYear = getSetDayOfYear; - proto.hour = proto.hours = getSetHour; - proto.minute = proto.minutes = getSetMinute; - proto.second = proto.seconds = getSetSecond; - proto.millisecond = proto.milliseconds = getSetMillisecond; - proto.utcOffset = getSetOffset; - proto.utc = setOffsetToUTC; - proto.local = setOffsetToLocal; - proto.parseZone = setOffsetToParsedOffset; - proto.hasAlignedHourOffset = hasAlignedHourOffset; - proto.isDST = isDaylightSavingTime; - proto.isLocal = isLocal; - proto.isUtcOffset = isUtcOffset; - proto.isUtc = isUtc; - proto.isUTC = isUtc; - proto.zoneAbbr = getZoneAbbr; - proto.zoneName = getZoneName; - proto.dates = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth); - proto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth); - proto.years = deprecate('years accessor is deprecated. Use year instead', getSetYear); - proto.zone = deprecate('moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/', getSetZone); - proto.isDSTShifted = deprecate('isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information', isDaylightSavingTimeShifted); - - function createUnix (input) { - return createLocal(input * 1000); - } - - function createInZone () { - return createLocal.apply(null, arguments).parseZone(); - } - - function preParsePostFormat (string) { - return string; - } - - var proto$1 = Locale.prototype; - - proto$1.calendar = calendar; - proto$1.longDateFormat = longDateFormat; - proto$1.invalidDate = invalidDate; - proto$1.ordinal = ordinal; - proto$1.preparse = preParsePostFormat; - proto$1.postformat = preParsePostFormat; - proto$1.relativeTime = relativeTime; - proto$1.pastFuture = pastFuture; - proto$1.set = set; - - proto$1.months = localeMonths; - proto$1.monthsShort = localeMonthsShort; - proto$1.monthsParse = localeMonthsParse; - proto$1.monthsRegex = monthsRegex; - proto$1.monthsShortRegex = monthsShortRegex; - proto$1.week = localeWeek; - proto$1.firstDayOfYear = localeFirstDayOfYear; - proto$1.firstDayOfWeek = localeFirstDayOfWeek; - - proto$1.weekdays = localeWeekdays; - proto$1.weekdaysMin = localeWeekdaysMin; - proto$1.weekdaysShort = localeWeekdaysShort; - proto$1.weekdaysParse = localeWeekdaysParse; - - proto$1.weekdaysRegex = weekdaysRegex; - proto$1.weekdaysShortRegex = weekdaysShortRegex; - proto$1.weekdaysMinRegex = weekdaysMinRegex; - - proto$1.isPM = localeIsPM; - proto$1.meridiem = localeMeridiem; - - function get$1 (format, index, field, setter) { - var locale = getLocale(); - var utc = createUTC().set(setter, index); - return locale[field](utc, format); - } - - function listMonthsImpl (format, index, field) { - if (isNumber(format)) { - index = format; - format = undefined; - } - - format = format || ''; - - if (index != null) { - return get$1(format, index, field, 'month'); - } - - var i; - var out = []; - for (i = 0; i < 12; i++) { - out[i] = get$1(format, i, field, 'month'); - } - return out; - } - - // () - // (5) - // (fmt, 5) - // (fmt) - // (true) - // (true, 5) - // (true, fmt, 5) - // (true, fmt) - function listWeekdaysImpl (localeSorted, format, index, field) { - if (typeof localeSorted === 'boolean') { - if (isNumber(format)) { - index = format; - format = undefined; - } - - format = format || ''; - } else { - format = localeSorted; - index = format; - localeSorted = false; - - if (isNumber(format)) { - index = format; - format = undefined; - } - - format = format || ''; - } - - var locale = getLocale(), - shift = localeSorted ? locale._week.dow : 0; - - if (index != null) { - return get$1(format, (index + shift) % 7, field, 'day'); - } - - var i; - var out = []; - for (i = 0; i < 7; i++) { - out[i] = get$1(format, (i + shift) % 7, field, 'day'); - } - return out; - } - - function listMonths (format, index) { - return listMonthsImpl(format, index, 'months'); - } - - function listMonthsShort (format, index) { - return listMonthsImpl(format, index, 'monthsShort'); - } - - function listWeekdays (localeSorted, format, index) { - return listWeekdaysImpl(localeSorted, format, index, 'weekdays'); - } - - function listWeekdaysShort (localeSorted, format, index) { - return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort'); - } - - function listWeekdaysMin (localeSorted, format, index) { - return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin'); - } - - getSetGlobalLocale('en', { - dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/, - ordinal : function (number) { - var b = number % 10, - output = (toInt(number % 100 / 10) === 1) ? 'th' : - (b === 1) ? 'st' : - (b === 2) ? 'nd' : - (b === 3) ? 'rd' : 'th'; - return number + output; - } - }); - - // Side effect imports - - hooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', getSetGlobalLocale); - hooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', getLocale); - - var mathAbs = Math.abs; - - function abs () { - var data = this._data; - - this._milliseconds = mathAbs(this._milliseconds); - this._days = mathAbs(this._days); - this._months = mathAbs(this._months); - - data.milliseconds = mathAbs(data.milliseconds); - data.seconds = mathAbs(data.seconds); - data.minutes = mathAbs(data.minutes); - data.hours = mathAbs(data.hours); - data.months = mathAbs(data.months); - data.years = mathAbs(data.years); - - return this; - } - - function addSubtract$1 (duration, input, value, direction) { - var other = createDuration(input, value); - - duration._milliseconds += direction * other._milliseconds; - duration._days += direction * other._days; - duration._months += direction * other._months; - - return duration._bubble(); - } - - // supports only 2.0-style add(1, 's') or add(duration) - function add$1 (input, value) { - return addSubtract$1(this, input, value, 1); - } - - // supports only 2.0-style subtract(1, 's') or subtract(duration) - function subtract$1 (input, value) { - return addSubtract$1(this, input, value, -1); - } - - function absCeil (number) { - if (number < 0) { - return Math.floor(number); - } else { - return Math.ceil(number); - } - } - - function bubble () { - var milliseconds = this._milliseconds; - var days = this._days; - var months = this._months; - var data = this._data; - var seconds, minutes, hours, years, monthsFromDays; - - // if we have a mix of positive and negative values, bubble down first - // check: https://github.com/moment/moment/issues/2166 - if (!((milliseconds >= 0 && days >= 0 && months >= 0) || - (milliseconds <= 0 && days <= 0 && months <= 0))) { - milliseconds += absCeil(monthsToDays(months) + days) * 864e5; - days = 0; - months = 0; - } - - // The following code bubbles up values, see the tests for - // examples of what that means. - data.milliseconds = milliseconds % 1000; - - seconds = absFloor(milliseconds / 1000); - data.seconds = seconds % 60; - - minutes = absFloor(seconds / 60); - data.minutes = minutes % 60; - - hours = absFloor(minutes / 60); - data.hours = hours % 24; - - days += absFloor(hours / 24); - - // convert days to months - monthsFromDays = absFloor(daysToMonths(days)); - months += monthsFromDays; - days -= absCeil(monthsToDays(monthsFromDays)); - - // 12 months -> 1 year - years = absFloor(months / 12); - months %= 12; - - data.days = days; - data.months = months; - data.years = years; - - return this; - } - - function daysToMonths (days) { - // 400 years have 146097 days (taking into account leap year rules) - // 400 years have 12 months === 4800 - return days * 4800 / 146097; - } - - function monthsToDays (months) { - // the reverse of daysToMonths - return months * 146097 / 4800; - } - - function as (units) { - if (!this.isValid()) { - return NaN; - } - var days; - var months; - var milliseconds = this._milliseconds; - - units = normalizeUnits(units); - - if (units === 'month' || units === 'year') { - days = this._days + milliseconds / 864e5; - months = this._months + daysToMonths(days); - return units === 'month' ? months : months / 12; - } else { - // handle milliseconds separately because of floating point math errors (issue #1867) - days = this._days + Math.round(monthsToDays(this._months)); - switch (units) { - case 'week' : return days / 7 + milliseconds / 6048e5; - case 'day' : return days + milliseconds / 864e5; - case 'hour' : return days * 24 + milliseconds / 36e5; - case 'minute' : return days * 1440 + milliseconds / 6e4; - case 'second' : return days * 86400 + milliseconds / 1000; - // Math.floor prevents floating point math errors here - case 'millisecond': return Math.floor(days * 864e5) + milliseconds; - default: throw new Error('Unknown unit ' + units); - } - } - } - - // TODO: Use this.as('ms')? - function valueOf$1 () { - if (!this.isValid()) { - return NaN; - } - return ( - this._milliseconds + - this._days * 864e5 + - (this._months % 12) * 2592e6 + - toInt(this._months / 12) * 31536e6 - ); - } - - function makeAs (alias) { - return function () { - return this.as(alias); - }; - } - - var asMilliseconds = makeAs('ms'); - var asSeconds = makeAs('s'); - var asMinutes = makeAs('m'); - var asHours = makeAs('h'); - var asDays = makeAs('d'); - var asWeeks = makeAs('w'); - var asMonths = makeAs('M'); - var asYears = makeAs('y'); - - function clone$1 () { - return createDuration(this); - } - - function get$2 (units) { - units = normalizeUnits(units); - return this.isValid() ? this[units + 's']() : NaN; - } - - function makeGetter(name) { - return function () { - return this.isValid() ? this._data[name] : NaN; - }; - } - - var milliseconds = makeGetter('milliseconds'); - var seconds = makeGetter('seconds'); - var minutes = makeGetter('minutes'); - var hours = makeGetter('hours'); - var days = makeGetter('days'); - var months = makeGetter('months'); - var years = makeGetter('years'); - - function weeks () { - return absFloor(this.days() / 7); - } - - var round = Math.round; - var thresholds = { - ss: 44, // a few seconds to seconds - s : 45, // seconds to minute - m : 45, // minutes to hour - h : 22, // hours to day - d : 26, // days to month - M : 11 // months to year - }; - - // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize - function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) { - return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture); - } - - function relativeTime$1 (posNegDuration, withoutSuffix, locale) { - var duration = createDuration(posNegDuration).abs(); - var seconds = round(duration.as('s')); - var minutes = round(duration.as('m')); - var hours = round(duration.as('h')); - var days = round(duration.as('d')); - var months = round(duration.as('M')); - var years = round(duration.as('y')); - - var a = seconds <= thresholds.ss && ['s', seconds] || - seconds < thresholds.s && ['ss', seconds] || - minutes <= 1 && ['m'] || - minutes < thresholds.m && ['mm', minutes] || - hours <= 1 && ['h'] || - hours < thresholds.h && ['hh', hours] || - days <= 1 && ['d'] || - days < thresholds.d && ['dd', days] || - months <= 1 && ['M'] || - months < thresholds.M && ['MM', months] || - years <= 1 && ['y'] || ['yy', years]; - - a[2] = withoutSuffix; - a[3] = +posNegDuration > 0; - a[4] = locale; - return substituteTimeAgo.apply(null, a); - } - - // This function allows you to set the rounding function for relative time strings - function getSetRelativeTimeRounding (roundingFunction) { - if (roundingFunction === undefined) { - return round; - } - if (typeof(roundingFunction) === 'function') { - round = roundingFunction; - return true; - } - return false; - } - - // This function allows you to set a threshold for relative time strings - function getSetRelativeTimeThreshold (threshold, limit) { - if (thresholds[threshold] === undefined) { - return false; - } - if (limit === undefined) { - return thresholds[threshold]; - } - thresholds[threshold] = limit; - if (threshold === 's') { - thresholds.ss = limit - 1; - } - return true; - } - - function humanize (withSuffix) { - if (!this.isValid()) { - return this.localeData().invalidDate(); - } - - var locale = this.localeData(); - var output = relativeTime$1(this, !withSuffix, locale); - - if (withSuffix) { - output = locale.pastFuture(+this, output); - } - - return locale.postformat(output); - } - - var abs$1 = Math.abs; - - function sign(x) { - return ((x > 0) - (x < 0)) || +x; - } - - function toISOString$1() { - // for ISO strings we do not use the normal bubbling rules: - // * milliseconds bubble up until they become hours - // * days do not bubble at all - // * months bubble up until they become years - // This is because there is no context-free conversion between hours and days - // (think of clock changes) - // and also not between days and months (28-31 days per month) - if (!this.isValid()) { - return this.localeData().invalidDate(); - } - - var seconds = abs$1(this._milliseconds) / 1000; - var days = abs$1(this._days); - var months = abs$1(this._months); - var minutes, hours, years; - - // 3600 seconds -> 60 minutes -> 1 hour - minutes = absFloor(seconds / 60); - hours = absFloor(minutes / 60); - seconds %= 60; - minutes %= 60; - - // 12 months -> 1 year - years = absFloor(months / 12); - months %= 12; - - - // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js - var Y = years; - var M = months; - var D = days; - var h = hours; - var m = minutes; - var s = seconds ? seconds.toFixed(3).replace(/\.?0+$/, '') : ''; - var total = this.asSeconds(); - - if (!total) { - // this is the same as C#'s (Noda) and python (isodate)... - // but not other JS (goog.date) - return 'P0D'; - } - - var totalSign = total < 0 ? '-' : ''; - var ymSign = sign(this._months) !== sign(total) ? '-' : ''; - var daysSign = sign(this._days) !== sign(total) ? '-' : ''; - var hmsSign = sign(this._milliseconds) !== sign(total) ? '-' : ''; - - return totalSign + 'P' + - (Y ? ymSign + Y + 'Y' : '') + - (M ? ymSign + M + 'M' : '') + - (D ? daysSign + D + 'D' : '') + - ((h || m || s) ? 'T' : '') + - (h ? hmsSign + h + 'H' : '') + - (m ? hmsSign + m + 'M' : '') + - (s ? hmsSign + s + 'S' : ''); - } - - var proto$2 = Duration.prototype; - - proto$2.isValid = isValid$1; - proto$2.abs = abs; - proto$2.add = add$1; - proto$2.subtract = subtract$1; - proto$2.as = as; - proto$2.asMilliseconds = asMilliseconds; - proto$2.asSeconds = asSeconds; - proto$2.asMinutes = asMinutes; - proto$2.asHours = asHours; - proto$2.asDays = asDays; - proto$2.asWeeks = asWeeks; - proto$2.asMonths = asMonths; - proto$2.asYears = asYears; - proto$2.valueOf = valueOf$1; - proto$2._bubble = bubble; - proto$2.clone = clone$1; - proto$2.get = get$2; - proto$2.milliseconds = milliseconds; - proto$2.seconds = seconds; - proto$2.minutes = minutes; - proto$2.hours = hours; - proto$2.days = days; - proto$2.weeks = weeks; - proto$2.months = months; - proto$2.years = years; - proto$2.humanize = humanize; - proto$2.toISOString = toISOString$1; - proto$2.toString = toISOString$1; - proto$2.toJSON = toISOString$1; - proto$2.locale = locale; - proto$2.localeData = localeData; - - proto$2.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', toISOString$1); - proto$2.lang = lang; - - // Side effect imports - - // FORMATTING - - addFormatToken('X', 0, 0, 'unix'); - addFormatToken('x', 0, 0, 'valueOf'); - - // PARSING - - addRegexToken('x', matchSigned); - addRegexToken('X', matchTimestamp); - addParseToken('X', function (input, array, config) { - config._d = new Date(parseFloat(input, 10) * 1000); - }); - addParseToken('x', function (input, array, config) { - config._d = new Date(toInt(input)); - }); - - // Side effect imports - - //! moment.js - - hooks.version = '2.23.0'; - - setHookCallback(createLocal); - - hooks.fn = proto; - hooks.min = min; - hooks.max = max; - hooks.now = now; - hooks.utc = createUTC; - hooks.unix = createUnix; - hooks.months = listMonths; - hooks.isDate = isDate; - hooks.locale = getSetGlobalLocale; - hooks.invalid = createInvalid; - hooks.duration = createDuration; - hooks.isMoment = isMoment; - hooks.weekdays = listWeekdays; - hooks.parseZone = createInZone; - hooks.localeData = getLocale; - hooks.isDuration = isDuration; - hooks.monthsShort = listMonthsShort; - hooks.weekdaysMin = listWeekdaysMin; - hooks.defineLocale = defineLocale; - hooks.updateLocale = updateLocale; - hooks.locales = listLocales; - hooks.weekdaysShort = listWeekdaysShort; - hooks.normalizeUnits = normalizeUnits; - hooks.relativeTimeRounding = getSetRelativeTimeRounding; - hooks.relativeTimeThreshold = getSetRelativeTimeThreshold; - hooks.calendarFormat = getCalendarFormat; - hooks.prototype = proto; - - // currently HTML5 input type only supports 24-hour formats - hooks.HTML5_FMT = { - DATETIME_LOCAL: 'YYYY-MM-DDTHH:mm', // - DATETIME_LOCAL_SECONDS: 'YYYY-MM-DDTHH:mm:ss', // - DATETIME_LOCAL_MS: 'YYYY-MM-DDTHH:mm:ss.SSS', // - DATE: 'YYYY-MM-DD', // - TIME: 'HH:mm', // - TIME_SECONDS: 'HH:mm:ss', // - TIME_MS: 'HH:mm:ss.SSS', // - WEEK: 'GGGG-[W]WW', // - MONTH: 'YYYY-MM' // - }; - - //! moment.js locale configuration - - hooks.defineLocale('af', { - months : 'Januarie_Februarie_Maart_April_Mei_Junie_Julie_Augustus_September_Oktober_November_Desember'.split('_'), - monthsShort : 'Jan_Feb_Mrt_Apr_Mei_Jun_Jul_Aug_Sep_Okt_Nov_Des'.split('_'), - weekdays : 'Sondag_Maandag_Dinsdag_Woensdag_Donderdag_Vrydag_Saterdag'.split('_'), - weekdaysShort : 'Son_Maa_Din_Woe_Don_Vry_Sat'.split('_'), - weekdaysMin : 'So_Ma_Di_Wo_Do_Vr_Sa'.split('_'), - meridiemParse: /vm|nm/i, - isPM : function (input) { - return /^nm$/i.test(input); - }, - meridiem : function (hours, minutes, isLower) { - if (hours < 12) { - return isLower ? 'vm' : 'VM'; - } else { - return isLower ? 'nm' : 'NM'; - } - }, - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd, D MMMM YYYY HH:mm' - }, - calendar : { - sameDay : '[Vandag om] LT', - nextDay : '[Môre om] LT', - nextWeek : 'dddd [om] LT', - lastDay : '[Gister om] LT', - lastWeek : '[Laas] dddd [om] LT', - sameElse : 'L' - }, - relativeTime : { - future : 'oor %s', - past : '%s gelede', - s : '\'n paar sekondes', - ss : '%d sekondes', - m : '\'n minuut', - mm : '%d minute', - h : '\'n uur', - hh : '%d ure', - d : '\'n dag', - dd : '%d dae', - M : '\'n maand', - MM : '%d maande', - y : '\'n jaar', - yy : '%d jaar' - }, - dayOfMonthOrdinalParse: /\d{1,2}(ste|de)/, - ordinal : function (number) { - return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de'); // Thanks to Joris Röling : https://github.com/jjupiter - }, - week : { - dow : 1, // Maandag is die eerste dag van die week. - doy : 4 // Die week wat die 4de Januarie bevat is die eerste week van die jaar. - } - }); - - //! moment.js locale configuration - - hooks.defineLocale('ar-dz', { - months : 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'), - monthsShort : 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'), - weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'), - weekdaysShort : 'احد_اثنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'), - weekdaysMin : 'أح_إث_ثلا_أر_خم_جم_سب'.split('_'), - weekdaysParseExact : true, - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd D MMMM YYYY HH:mm' - }, - calendar : { - sameDay: '[اليوم على الساعة] LT', - nextDay: '[غدا على الساعة] LT', - nextWeek: 'dddd [على الساعة] LT', - lastDay: '[أمس على الساعة] LT', - lastWeek: 'dddd [على الساعة] LT', - sameElse: 'L' - }, - relativeTime : { - future : 'في %s', - past : 'منذ %s', - s : 'ثوان', - ss : '%d ثانية', - m : 'دقيقة', - mm : '%d دقائق', - h : 'ساعة', - hh : '%d ساعات', - d : 'يوم', - dd : '%d أيام', - M : 'شهر', - MM : '%d أشهر', - y : 'سنة', - yy : '%d سنوات' - }, - week : { - dow : 0, // Sunday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); - - //! moment.js locale configuration - - hooks.defineLocale('ar-kw', { - months : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'), - monthsShort : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'), - weekdays : 'الأحد_الإتنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'), - weekdaysShort : 'احد_اتنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'), - weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'), - weekdaysParseExact : true, - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd D MMMM YYYY HH:mm' - }, - calendar : { - sameDay: '[اليوم على الساعة] LT', - nextDay: '[غدا على الساعة] LT', - nextWeek: 'dddd [على الساعة] LT', - lastDay: '[أمس على الساعة] LT', - lastWeek: 'dddd [على الساعة] LT', - sameElse: 'L' - }, - relativeTime : { - future : 'في %s', - past : 'منذ %s', - s : 'ثوان', - ss : '%d ثانية', - m : 'دقيقة', - mm : '%d دقائق', - h : 'ساعة', - hh : '%d ساعات', - d : 'يوم', - dd : '%d أيام', - M : 'شهر', - MM : '%d أشهر', - y : 'سنة', - yy : '%d سنوات' - }, - week : { - dow : 0, // Sunday is the first day of the week. - doy : 12 // The week that contains Jan 12th is the first week of the year. - } - }); - - //! moment.js locale configuration - - var symbolMap = { - '1': '1', - '2': '2', - '3': '3', - '4': '4', - '5': '5', - '6': '6', - '7': '7', - '8': '8', - '9': '9', - '0': '0' - }, pluralForm = function (n) { - return n === 0 ? 0 : n === 1 ? 1 : n === 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5; - }, plurals = { - s : ['أقل من ثانية', 'ثانية واحدة', ['ثانيتان', 'ثانيتين'], '%d ثوان', '%d ثانية', '%d ثانية'], - m : ['أقل من دقيقة', 'دقيقة واحدة', ['دقيقتان', 'دقيقتين'], '%d دقائق', '%d دقيقة', '%d دقيقة'], - h : ['أقل من ساعة', 'ساعة واحدة', ['ساعتان', 'ساعتين'], '%d ساعات', '%d ساعة', '%d ساعة'], - d : ['أقل من يوم', 'يوم واحد', ['يومان', 'يومين'], '%d أيام', '%d يومًا', '%d يوم'], - M : ['أقل من شهر', 'شهر واحد', ['شهران', 'شهرين'], '%d أشهر', '%d شهرا', '%d شهر'], - y : ['أقل من عام', 'عام واحد', ['عامان', 'عامين'], '%d أعوام', '%d عامًا', '%d عام'] - }, pluralize = function (u) { - return function (number, withoutSuffix, string, isFuture) { - var f = pluralForm(number), - str = plurals[u][pluralForm(number)]; - if (f === 2) { - str = str[withoutSuffix ? 0 : 1]; - } - return str.replace(/%d/i, number); - }; - }, months$1 = [ - 'يناير', - 'فبراير', - 'مارس', - 'أبريل', - 'مايو', - 'يونيو', - 'يوليو', - 'أغسطس', - 'سبتمبر', - 'أكتوبر', - 'نوفمبر', - 'ديسمبر' - ]; - - hooks.defineLocale('ar-ly', { - months : months$1, - monthsShort : months$1, - weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'), - weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'), - weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'), - weekdaysParseExact : true, - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'D/\u200FM/\u200FYYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd D MMMM YYYY HH:mm' - }, - meridiemParse: /ص|م/, - isPM : function (input) { - return 'م' === input; - }, - meridiem : function (hour, minute, isLower) { - if (hour < 12) { - return 'ص'; - } else { - return 'م'; - } - }, - calendar : { - sameDay: '[اليوم عند الساعة] LT', - nextDay: '[غدًا عند الساعة] LT', - nextWeek: 'dddd [عند الساعة] LT', - lastDay: '[أمس عند الساعة] LT', - lastWeek: 'dddd [عند الساعة] LT', - sameElse: 'L' - }, - relativeTime : { - future : 'بعد %s', - past : 'منذ %s', - s : pluralize('s'), - ss : pluralize('s'), - m : pluralize('m'), - mm : pluralize('m'), - h : pluralize('h'), - hh : pluralize('h'), - d : pluralize('d'), - dd : pluralize('d'), - M : pluralize('M'), - MM : pluralize('M'), - y : pluralize('y'), - yy : pluralize('y') - }, - preparse: function (string) { - return string.replace(/،/g, ','); - }, - postformat: function (string) { - return string.replace(/\d/g, function (match) { - return symbolMap[match]; - }).replace(/,/g, '،'); - }, - week : { - dow : 6, // Saturday is the first day of the week. - doy : 12 // The week that contains Jan 12th is the first week of the year. - } - }); - - //! moment.js locale configuration - - hooks.defineLocale('ar-ma', { - months : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'), - monthsShort : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'), - weekdays : 'الأحد_الإتنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'), - weekdaysShort : 'احد_اتنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'), - weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'), - weekdaysParseExact : true, - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd D MMMM YYYY HH:mm' - }, - calendar : { - sameDay: '[اليوم على الساعة] LT', - nextDay: '[غدا على الساعة] LT', - nextWeek: 'dddd [على الساعة] LT', - lastDay: '[أمس على الساعة] LT', - lastWeek: 'dddd [على الساعة] LT', - sameElse: 'L' - }, - relativeTime : { - future : 'في %s', - past : 'منذ %s', - s : 'ثوان', - ss : '%d ثانية', - m : 'دقيقة', - mm : '%d دقائق', - h : 'ساعة', - hh : '%d ساعات', - d : 'يوم', - dd : '%d أيام', - M : 'شهر', - MM : '%d أشهر', - y : 'سنة', - yy : '%d سنوات' - }, - week : { - dow : 6, // Saturday is the first day of the week. - doy : 12 // The week that contains Jan 12th is the first week of the year. - } - }); - - //! moment.js locale configuration - - var symbolMap$1 = { - '1': '١', - '2': '٢', - '3': '٣', - '4': '٤', - '5': '٥', - '6': '٦', - '7': '٧', - '8': '٨', - '9': '٩', - '0': '٠' - }, numberMap = { - '١': '1', - '٢': '2', - '٣': '3', - '٤': '4', - '٥': '5', - '٦': '6', - '٧': '7', - '٨': '8', - '٩': '9', - '٠': '0' - }; - - hooks.defineLocale('ar-sa', { - months : 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'), - monthsShort : 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'), - weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'), - weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'), - weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'), - weekdaysParseExact : true, - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd D MMMM YYYY HH:mm' - }, - meridiemParse: /ص|م/, - isPM : function (input) { - return 'م' === input; - }, - meridiem : function (hour, minute, isLower) { - if (hour < 12) { - return 'ص'; - } else { - return 'م'; - } - }, - calendar : { - sameDay: '[اليوم على الساعة] LT', - nextDay: '[غدا على الساعة] LT', - nextWeek: 'dddd [على الساعة] LT', - lastDay: '[أمس على الساعة] LT', - lastWeek: 'dddd [على الساعة] LT', - sameElse: 'L' - }, - relativeTime : { - future : 'في %s', - past : 'منذ %s', - s : 'ثوان', - ss : '%d ثانية', - m : 'دقيقة', - mm : '%d دقائق', - h : 'ساعة', - hh : '%d ساعات', - d : 'يوم', - dd : '%d أيام', - M : 'شهر', - MM : '%d أشهر', - y : 'سنة', - yy : '%d سنوات' - }, - preparse: function (string) { - return string.replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) { - return numberMap[match]; - }).replace(/،/g, ','); - }, - postformat: function (string) { - return string.replace(/\d/g, function (match) { - return symbolMap$1[match]; - }).replace(/,/g, '،'); - }, - week : { - dow : 0, // Sunday is the first day of the week. - doy : 6 // The week that contains Jan 6th is the first week of the year. - } - }); - - //! moment.js locale configuration - - hooks.defineLocale('ar-tn', { - months: 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'), - monthsShort: 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'), - weekdays: 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'), - weekdaysShort: 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'), - weekdaysMin: 'ح_ن_ث_ر_خ_ج_س'.split('_'), - weekdaysParseExact : true, - longDateFormat: { - LT: 'HH:mm', - LTS: 'HH:mm:ss', - L: 'DD/MM/YYYY', - LL: 'D MMMM YYYY', - LLL: 'D MMMM YYYY HH:mm', - LLLL: 'dddd D MMMM YYYY HH:mm' - }, - calendar: { - sameDay: '[اليوم على الساعة] LT', - nextDay: '[غدا على الساعة] LT', - nextWeek: 'dddd [على الساعة] LT', - lastDay: '[أمس على الساعة] LT', - lastWeek: 'dddd [على الساعة] LT', - sameElse: 'L' - }, - relativeTime: { - future: 'في %s', - past: 'منذ %s', - s: 'ثوان', - ss : '%d ثانية', - m: 'دقيقة', - mm: '%d دقائق', - h: 'ساعة', - hh: '%d ساعات', - d: 'يوم', - dd: '%d أيام', - M: 'شهر', - MM: '%d أشهر', - y: 'سنة', - yy: '%d سنوات' - }, - week: { - dow: 1, // Monday is the first day of the week. - doy: 4 // The week that contains Jan 4th is the first week of the year. - } - }); - - //! moment.js locale configuration - - var symbolMap$2 = { - '1': '١', - '2': '٢', - '3': '٣', - '4': '٤', - '5': '٥', - '6': '٦', - '7': '٧', - '8': '٨', - '9': '٩', - '0': '٠' - }, numberMap$1 = { - '١': '1', - '٢': '2', - '٣': '3', - '٤': '4', - '٥': '5', - '٦': '6', - '٧': '7', - '٨': '8', - '٩': '9', - '٠': '0' - }, pluralForm$1 = function (n) { - return n === 0 ? 0 : n === 1 ? 1 : n === 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5; - }, plurals$1 = { - s : ['أقل من ثانية', 'ثانية واحدة', ['ثانيتان', 'ثانيتين'], '%d ثوان', '%d ثانية', '%d ثانية'], - m : ['أقل من دقيقة', 'دقيقة واحدة', ['دقيقتان', 'دقيقتين'], '%d دقائق', '%d دقيقة', '%d دقيقة'], - h : ['أقل من ساعة', 'ساعة واحدة', ['ساعتان', 'ساعتين'], '%d ساعات', '%d ساعة', '%d ساعة'], - d : ['أقل من يوم', 'يوم واحد', ['يومان', 'يومين'], '%d أيام', '%d يومًا', '%d يوم'], - M : ['أقل من شهر', 'شهر واحد', ['شهران', 'شهرين'], '%d أشهر', '%d شهرا', '%d شهر'], - y : ['أقل من عام', 'عام واحد', ['عامان', 'عامين'], '%d أعوام', '%d عامًا', '%d عام'] - }, pluralize$1 = function (u) { - return function (number, withoutSuffix, string, isFuture) { - var f = pluralForm$1(number), - str = plurals$1[u][pluralForm$1(number)]; - if (f === 2) { - str = str[withoutSuffix ? 0 : 1]; - } - return str.replace(/%d/i, number); - }; - }, months$2 = [ - 'يناير', - 'فبراير', - 'مارس', - 'أبريل', - 'مايو', - 'يونيو', - 'يوليو', - 'أغسطس', - 'سبتمبر', - 'أكتوبر', - 'نوفمبر', - 'ديسمبر' - ]; - - hooks.defineLocale('ar', { - months : months$2, - monthsShort : months$2, - weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'), - weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'), - weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'), - weekdaysParseExact : true, - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'D/\u200FM/\u200FYYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd D MMMM YYYY HH:mm' - }, - meridiemParse: /ص|م/, - isPM : function (input) { - return 'م' === input; - }, - meridiem : function (hour, minute, isLower) { - if (hour < 12) { - return 'ص'; - } else { - return 'م'; - } - }, - calendar : { - sameDay: '[اليوم عند الساعة] LT', - nextDay: '[غدًا عند الساعة] LT', - nextWeek: 'dddd [عند الساعة] LT', - lastDay: '[أمس عند الساعة] LT', - lastWeek: 'dddd [عند الساعة] LT', - sameElse: 'L' - }, - relativeTime : { - future : 'بعد %s', - past : 'منذ %s', - s : pluralize$1('s'), - ss : pluralize$1('s'), - m : pluralize$1('m'), - mm : pluralize$1('m'), - h : pluralize$1('h'), - hh : pluralize$1('h'), - d : pluralize$1('d'), - dd : pluralize$1('d'), - M : pluralize$1('M'), - MM : pluralize$1('M'), - y : pluralize$1('y'), - yy : pluralize$1('y') - }, - preparse: function (string) { - return string.replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) { - return numberMap$1[match]; - }).replace(/،/g, ','); - }, - postformat: function (string) { - return string.replace(/\d/g, function (match) { - return symbolMap$2[match]; - }).replace(/,/g, '،'); - }, - week : { - dow : 6, // Saturday is the first day of the week. - doy : 12 // The week that contains Jan 12th is the first week of the year. - } - }); - - //! moment.js locale configuration - - var suffixes = { - 1: '-inci', - 5: '-inci', - 8: '-inci', - 70: '-inci', - 80: '-inci', - 2: '-nci', - 7: '-nci', - 20: '-nci', - 50: '-nci', - 3: '-üncü', - 4: '-üncü', - 100: '-üncü', - 6: '-ncı', - 9: '-uncu', - 10: '-uncu', - 30: '-uncu', - 60: '-ıncı', - 90: '-ıncı' - }; - - hooks.defineLocale('az', { - months : 'yanvar_fevral_mart_aprel_may_iyun_iyul_avqust_sentyabr_oktyabr_noyabr_dekabr'.split('_'), - monthsShort : 'yan_fev_mar_apr_may_iyn_iyl_avq_sen_okt_noy_dek'.split('_'), - weekdays : 'Bazar_Bazar ertəsi_Çərşənbə axşamı_Çərşənbə_Cümə axşamı_Cümə_Şənbə'.split('_'), - weekdaysShort : 'Baz_BzE_ÇAx_Çər_CAx_Cüm_Şən'.split('_'), - weekdaysMin : 'Bz_BE_ÇA_Çə_CA_Cü_Şə'.split('_'), - weekdaysParseExact : true, - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD.MM.YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd, D MMMM YYYY HH:mm' - }, - calendar : { - sameDay : '[bugün saat] LT', - nextDay : '[sabah saat] LT', - nextWeek : '[gələn həftə] dddd [saat] LT', - lastDay : '[dünən] LT', - lastWeek : '[keçən həftə] dddd [saat] LT', - sameElse : 'L' - }, - relativeTime : { - future : '%s sonra', - past : '%s əvvəl', - s : 'birneçə saniyə', - ss : '%d saniyə', - m : 'bir dəqiqə', - mm : '%d dəqiqə', - h : 'bir saat', - hh : '%d saat', - d : 'bir gün', - dd : '%d gün', - M : 'bir ay', - MM : '%d ay', - y : 'bir il', - yy : '%d il' - }, - meridiemParse: /gecə|səhər|gündüz|axşam/, - isPM : function (input) { - return /^(gündüz|axşam)$/.test(input); - }, - meridiem : function (hour, minute, isLower) { - if (hour < 4) { - return 'gecə'; - } else if (hour < 12) { - return 'səhər'; - } else if (hour < 17) { - return 'gündüz'; - } else { - return 'axşam'; - } - }, - dayOfMonthOrdinalParse: /\d{1,2}-(ıncı|inci|nci|üncü|ncı|uncu)/, - ordinal : function (number) { - if (number === 0) { // special case for zero - return number + '-ıncı'; - } - var a = number % 10, - b = number % 100 - a, - c = number >= 100 ? 100 : null; - return number + (suffixes[a] || suffixes[b] || suffixes[c]); - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 7th is the first week of the year. - } - }); - - //! moment.js locale configuration - - function plural(word, num) { - var forms = word.split('_'); - return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]); - } - function relativeTimeWithPlural(number, withoutSuffix, key) { - var format = { - 'ss': withoutSuffix ? 'секунда_секунды_секунд' : 'секунду_секунды_секунд', - 'mm': withoutSuffix ? 'хвіліна_хвіліны_хвілін' : 'хвіліну_хвіліны_хвілін', - 'hh': withoutSuffix ? 'гадзіна_гадзіны_гадзін' : 'гадзіну_гадзіны_гадзін', - 'dd': 'дзень_дні_дзён', - 'MM': 'месяц_месяцы_месяцаў', - 'yy': 'год_гады_гадоў' - }; - if (key === 'm') { - return withoutSuffix ? 'хвіліна' : 'хвіліну'; - } - else if (key === 'h') { - return withoutSuffix ? 'гадзіна' : 'гадзіну'; - } - else { - return number + ' ' + plural(format[key], +number); - } - } - - hooks.defineLocale('be', { - months : { - format: 'студзеня_лютага_сакавіка_красавіка_траўня_чэрвеня_ліпеня_жніўня_верасня_кастрычніка_лістапада_снежня'.split('_'), - standalone: 'студзень_люты_сакавік_красавік_травень_чэрвень_ліпень_жнівень_верасень_кастрычнік_лістапад_снежань'.split('_') - }, - monthsShort : 'студ_лют_сак_крас_трав_чэрв_ліп_жнів_вер_каст_ліст_снеж'.split('_'), - weekdays : { - format: 'нядзелю_панядзелак_аўторак_сераду_чацвер_пятніцу_суботу'.split('_'), - standalone: 'нядзеля_панядзелак_аўторак_серада_чацвер_пятніца_субота'.split('_'), - isFormat: /\[ ?[Ууў] ?(?:мінулую|наступную)? ?\] ?dddd/ - }, - weekdaysShort : 'нд_пн_ат_ср_чц_пт_сб'.split('_'), - weekdaysMin : 'нд_пн_ат_ср_чц_пт_сб'.split('_'), - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD.MM.YYYY', - LL : 'D MMMM YYYY г.', - LLL : 'D MMMM YYYY г., HH:mm', - LLLL : 'dddd, D MMMM YYYY г., HH:mm' - }, - calendar : { - sameDay: '[Сёння ў] LT', - nextDay: '[Заўтра ў] LT', - lastDay: '[Учора ў] LT', - nextWeek: function () { - return '[У] dddd [ў] LT'; - }, - lastWeek: function () { - switch (this.day()) { - case 0: - case 3: - case 5: - case 6: - return '[У мінулую] dddd [ў] LT'; - case 1: - case 2: - case 4: - return '[У мінулы] dddd [ў] LT'; - } - }, - sameElse: 'L' - }, - relativeTime : { - future : 'праз %s', - past : '%s таму', - s : 'некалькі секунд', - m : relativeTimeWithPlural, - mm : relativeTimeWithPlural, - h : relativeTimeWithPlural, - hh : relativeTimeWithPlural, - d : 'дзень', - dd : relativeTimeWithPlural, - M : 'месяц', - MM : relativeTimeWithPlural, - y : 'год', - yy : relativeTimeWithPlural - }, - meridiemParse: /ночы|раніцы|дня|вечара/, - isPM : function (input) { - return /^(дня|вечара)$/.test(input); - }, - meridiem : function (hour, minute, isLower) { - if (hour < 4) { - return 'ночы'; - } else if (hour < 12) { - return 'раніцы'; - } else if (hour < 17) { - return 'дня'; - } else { - return 'вечара'; - } - }, - dayOfMonthOrdinalParse: /\d{1,2}-(і|ы|га)/, - ordinal: function (number, period) { - switch (period) { - case 'M': - case 'd': - case 'DDD': - case 'w': - case 'W': - return (number % 10 === 2 || number % 10 === 3) && (number % 100 !== 12 && number % 100 !== 13) ? number + '-і' : number + '-ы'; - case 'D': - return number + '-га'; - default: - return number; - } - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 7th is the first week of the year. - } - }); - - //! moment.js locale configuration - - hooks.defineLocale('bg', { - months : 'януари_февруари_март_април_май_юни_юли_август_септември_октомври_ноември_декември'.split('_'), - monthsShort : 'янр_фев_мар_апр_май_юни_юли_авг_сеп_окт_ное_дек'.split('_'), - weekdays : 'неделя_понеделник_вторник_сряда_четвъртък_петък_събота'.split('_'), - weekdaysShort : 'нед_пон_вто_сря_чет_пет_съб'.split('_'), - weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'), - longDateFormat : { - LT : 'H:mm', - LTS : 'H:mm:ss', - L : 'D.MM.YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY H:mm', - LLLL : 'dddd, D MMMM YYYY H:mm' - }, - calendar : { - sameDay : '[Днес в] LT', - nextDay : '[Утре в] LT', - nextWeek : 'dddd [в] LT', - lastDay : '[Вчера в] LT', - lastWeek : function () { - switch (this.day()) { - case 0: - case 3: - case 6: - return '[В изминалата] dddd [в] LT'; - case 1: - case 2: - case 4: - case 5: - return '[В изминалия] dddd [в] LT'; - } - }, - sameElse : 'L' - }, - relativeTime : { - future : 'след %s', - past : 'преди %s', - s : 'няколко секунди', - ss : '%d секунди', - m : 'минута', - mm : '%d минути', - h : 'час', - hh : '%d часа', - d : 'ден', - dd : '%d дни', - M : 'месец', - MM : '%d месеца', - y : 'година', - yy : '%d години' - }, - dayOfMonthOrdinalParse: /\d{1,2}-(ев|ен|ти|ви|ри|ми)/, - ordinal : function (number) { - var lastDigit = number % 10, - last2Digits = number % 100; - if (number === 0) { - return number + '-ев'; - } else if (last2Digits === 0) { - return number + '-ен'; - } else if (last2Digits > 10 && last2Digits < 20) { - return number + '-ти'; - } else if (lastDigit === 1) { - return number + '-ви'; - } else if (lastDigit === 2) { - return number + '-ри'; - } else if (lastDigit === 7 || lastDigit === 8) { - return number + '-ми'; - } else { - return number + '-ти'; - } - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 7th is the first week of the year. - } - }); - - //! moment.js locale configuration - - hooks.defineLocale('bm', { - months : 'Zanwuyekalo_Fewuruyekalo_Marisikalo_Awirilikalo_Mɛkalo_Zuwɛnkalo_Zuluyekalo_Utikalo_Sɛtanburukalo_ɔkutɔburukalo_Nowanburukalo_Desanburukalo'.split('_'), - monthsShort : 'Zan_Few_Mar_Awi_Mɛ_Zuw_Zul_Uti_Sɛt_ɔku_Now_Des'.split('_'), - weekdays : 'Kari_Ntɛnɛn_Tarata_Araba_Alamisa_Juma_Sibiri'.split('_'), - weekdaysShort : 'Kar_Ntɛ_Tar_Ara_Ala_Jum_Sib'.split('_'), - weekdaysMin : 'Ka_Nt_Ta_Ar_Al_Ju_Si'.split('_'), - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD/MM/YYYY', - LL : 'MMMM [tile] D [san] YYYY', - LLL : 'MMMM [tile] D [san] YYYY [lɛrɛ] HH:mm', - LLLL : 'dddd MMMM [tile] D [san] YYYY [lɛrɛ] HH:mm' - }, - calendar : { - sameDay : '[Bi lɛrɛ] LT', - nextDay : '[Sini lɛrɛ] LT', - nextWeek : 'dddd [don lɛrɛ] LT', - lastDay : '[Kunu lɛrɛ] LT', - lastWeek : 'dddd [tɛmɛnen lɛrɛ] LT', - sameElse : 'L' - }, - relativeTime : { - future : '%s kɔnɔ', - past : 'a bɛ %s bɔ', - s : 'sanga dama dama', - ss : 'sekondi %d', - m : 'miniti kelen', - mm : 'miniti %d', - h : 'lɛrɛ kelen', - hh : 'lɛrɛ %d', - d : 'tile kelen', - dd : 'tile %d', - M : 'kalo kelen', - MM : 'kalo %d', - y : 'san kelen', - yy : 'san %d' - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); - - //! moment.js locale configuration - - var symbolMap$3 = { - '1': '১', - '2': '২', - '3': '৩', - '4': '৪', - '5': '৫', - '6': '৬', - '7': '৭', - '8': '৮', - '9': '৯', - '0': '০' - }, - numberMap$2 = { - '১': '1', - '২': '2', - '৩': '3', - '৪': '4', - '৫': '5', - '৬': '6', - '৭': '7', - '৮': '8', - '৯': '9', - '০': '0' - }; - - hooks.defineLocale('bn', { - months : 'জানুয়ারী_ফেব্রুয়ারি_মার্চ_এপ্রিল_মে_জুন_জুলাই_আগস্ট_সেপ্টেম্বর_অক্টোবর_নভেম্বর_ডিসেম্বর'.split('_'), - monthsShort : 'জানু_ফেব_মার্চ_এপ্র_মে_জুন_জুল_আগ_সেপ্ট_অক্টো_নভে_ডিসে'.split('_'), - weekdays : 'রবিবার_সোমবার_মঙ্গলবার_বুধবার_বৃহস্পতিবার_শুক্রবার_শনিবার'.split('_'), - weekdaysShort : 'রবি_সোম_মঙ্গল_বুধ_বৃহস্পতি_শুক্র_শনি'.split('_'), - weekdaysMin : 'রবি_সোম_মঙ্গ_বুধ_বৃহঃ_শুক্র_শনি'.split('_'), - longDateFormat : { - LT : 'A h:mm সময়', - LTS : 'A h:mm:ss সময়', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY, A h:mm সময়', - LLLL : 'dddd, D MMMM YYYY, A h:mm সময়' - }, - calendar : { - sameDay : '[আজ] LT', - nextDay : '[আগামীকাল] LT', - nextWeek : 'dddd, LT', - lastDay : '[গতকাল] LT', - lastWeek : '[গত] dddd, LT', - sameElse : 'L' - }, - relativeTime : { - future : '%s পরে', - past : '%s আগে', - s : 'কয়েক সেকেন্ড', - ss : '%d সেকেন্ড', - m : 'এক মিনিট', - mm : '%d মিনিট', - h : 'এক ঘন্টা', - hh : '%d ঘন্টা', - d : 'এক দিন', - dd : '%d দিন', - M : 'এক মাস', - MM : '%d মাস', - y : 'এক বছর', - yy : '%d বছর' - }, - preparse: function (string) { - return string.replace(/[১২৩৪৫৬৭৮৯০]/g, function (match) { - return numberMap$2[match]; - }); - }, - postformat: function (string) { - return string.replace(/\d/g, function (match) { - return symbolMap$3[match]; - }); - }, - meridiemParse: /রাত|সকাল|দুপুর|বিকাল|রাত/, - meridiemHour : function (hour, meridiem) { - if (hour === 12) { - hour = 0; - } - if ((meridiem === 'রাত' && hour >= 4) || - (meridiem === 'দুপুর' && hour < 5) || - meridiem === 'বিকাল') { - return hour + 12; - } else { - return hour; - } - }, - meridiem : function (hour, minute, isLower) { - if (hour < 4) { - return 'রাত'; - } else if (hour < 10) { - return 'সকাল'; - } else if (hour < 17) { - return 'দুপুর'; - } else if (hour < 20) { - return 'বিকাল'; - } else { - return 'রাত'; - } - }, - week : { - dow : 0, // Sunday is the first day of the week. - doy : 6 // The week that contains Jan 6th is the first week of the year. - } - }); - - //! moment.js locale configuration - - var symbolMap$4 = { - '1': '༡', - '2': '༢', - '3': '༣', - '4': '༤', - '5': '༥', - '6': '༦', - '7': '༧', - '8': '༨', - '9': '༩', - '0': '༠' - }, - numberMap$3 = { - '༡': '1', - '༢': '2', - '༣': '3', - '༤': '4', - '༥': '5', - '༦': '6', - '༧': '7', - '༨': '8', - '༩': '9', - '༠': '0' - }; - - hooks.defineLocale('bo', { - months : 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split('_'), - monthsShort : 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split('_'), - weekdays : 'གཟའ་ཉི་མ་_གཟའ་ཟླ་བ་_གཟའ་མིག་དམར་_གཟའ་ལྷག་པ་_གཟའ་ཕུར་བུ_གཟའ་པ་སངས་_གཟའ་སྤེན་པ་'.split('_'), - weekdaysShort : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split('_'), - weekdaysMin : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split('_'), - longDateFormat : { - LT : 'A h:mm', - LTS : 'A h:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY, A h:mm', - LLLL : 'dddd, D MMMM YYYY, A h:mm' - }, - calendar : { - sameDay : '[དི་རིང] LT', - nextDay : '[སང་ཉིན] LT', - nextWeek : '[བདུན་ཕྲག་རྗེས་མ], LT', - lastDay : '[ཁ་སང] LT', - lastWeek : '[བདུན་ཕྲག་མཐའ་མ] dddd, LT', - sameElse : 'L' - }, - relativeTime : { - future : '%s ལ་', - past : '%s སྔན་ལ', - s : 'ལམ་སང', - ss : '%d སྐར་ཆ།', - m : 'སྐར་མ་གཅིག', - mm : '%d སྐར་མ', - h : 'ཆུ་ཚོད་གཅིག', - hh : '%d ཆུ་ཚོད', - d : 'ཉིན་གཅིག', - dd : '%d ཉིན་', - M : 'ཟླ་བ་གཅིག', - MM : '%d ཟླ་བ', - y : 'ལོ་གཅིག', - yy : '%d ལོ' - }, - preparse: function (string) { - return string.replace(/[༡༢༣༤༥༦༧༨༩༠]/g, function (match) { - return numberMap$3[match]; - }); - }, - postformat: function (string) { - return string.replace(/\d/g, function (match) { - return symbolMap$4[match]; - }); - }, - meridiemParse: /མཚན་མོ|ཞོགས་ཀས|ཉིན་གུང|དགོང་དག|མཚན་མོ/, - meridiemHour : function (hour, meridiem) { - if (hour === 12) { - hour = 0; - } - if ((meridiem === 'མཚན་མོ' && hour >= 4) || - (meridiem === 'ཉིན་གུང' && hour < 5) || - meridiem === 'དགོང་དག') { - return hour + 12; - } else { - return hour; - } - }, - meridiem : function (hour, minute, isLower) { - if (hour < 4) { - return 'མཚན་མོ'; - } else if (hour < 10) { - return 'ཞོགས་ཀས'; - } else if (hour < 17) { - return 'ཉིན་གུང'; - } else if (hour < 20) { - return 'དགོང་དག'; - } else { - return 'མཚན་མོ'; - } - }, - week : { - dow : 0, // Sunday is the first day of the week. - doy : 6 // The week that contains Jan 6th is the first week of the year. - } - }); - - //! moment.js locale configuration - - function relativeTimeWithMutation(number, withoutSuffix, key) { - var format = { - 'mm': 'munutenn', - 'MM': 'miz', - 'dd': 'devezh' - }; - return number + ' ' + mutation(format[key], number); - } - function specialMutationForYears(number) { - switch (lastNumber(number)) { - case 1: - case 3: - case 4: - case 5: - case 9: - return number + ' bloaz'; - default: - return number + ' vloaz'; - } - } - function lastNumber(number) { - if (number > 9) { - return lastNumber(number % 10); - } - return number; - } - function mutation(text, number) { - if (number === 2) { - return softMutation(text); - } - return text; - } - function softMutation(text) { - var mutationTable = { - 'm': 'v', - 'b': 'v', - 'd': 'z' - }; - if (mutationTable[text.charAt(0)] === undefined) { - return text; - } - return mutationTable[text.charAt(0)] + text.substring(1); - } - - hooks.defineLocale('br', { - months : 'Genver_C\'hwevrer_Meurzh_Ebrel_Mae_Mezheven_Gouere_Eost_Gwengolo_Here_Du_Kerzu'.split('_'), - monthsShort : 'Gen_C\'hwe_Meu_Ebr_Mae_Eve_Gou_Eos_Gwe_Her_Du_Ker'.split('_'), - weekdays : 'Sul_Lun_Meurzh_Merc\'her_Yaou_Gwener_Sadorn'.split('_'), - weekdaysShort : 'Sul_Lun_Meu_Mer_Yao_Gwe_Sad'.split('_'), - weekdaysMin : 'Su_Lu_Me_Mer_Ya_Gw_Sa'.split('_'), - weekdaysParseExact : true, - longDateFormat : { - LT : 'h[e]mm A', - LTS : 'h[e]mm:ss A', - L : 'DD/MM/YYYY', - LL : 'D [a viz] MMMM YYYY', - LLL : 'D [a viz] MMMM YYYY h[e]mm A', - LLLL : 'dddd, D [a viz] MMMM YYYY h[e]mm A' - }, - calendar : { - sameDay : '[Hiziv da] LT', - nextDay : '[Warc\'hoazh da] LT', - nextWeek : 'dddd [da] LT', - lastDay : '[Dec\'h da] LT', - lastWeek : 'dddd [paset da] LT', - sameElse : 'L' - }, - relativeTime : { - future : 'a-benn %s', - past : '%s \'zo', - s : 'un nebeud segondennoù', - ss : '%d eilenn', - m : 'ur vunutenn', - mm : relativeTimeWithMutation, - h : 'un eur', - hh : '%d eur', - d : 'un devezh', - dd : relativeTimeWithMutation, - M : 'ur miz', - MM : relativeTimeWithMutation, - y : 'ur bloaz', - yy : specialMutationForYears - }, - dayOfMonthOrdinalParse: /\d{1,2}(añ|vet)/, - ordinal : function (number) { - var output = (number === 1) ? 'añ' : 'vet'; - return number + output; - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); - - //! moment.js locale configuration - - function translate(number, withoutSuffix, key) { - var result = number + ' '; - switch (key) { - case 'ss': - if (number === 1) { - result += 'sekunda'; - } else if (number === 2 || number === 3 || number === 4) { - result += 'sekunde'; - } else { - result += 'sekundi'; - } - return result; - case 'm': - return withoutSuffix ? 'jedna minuta' : 'jedne minute'; - case 'mm': - if (number === 1) { - result += 'minuta'; - } else if (number === 2 || number === 3 || number === 4) { - result += 'minute'; - } else { - result += 'minuta'; - } - return result; - case 'h': - return withoutSuffix ? 'jedan sat' : 'jednog sata'; - case 'hh': - if (number === 1) { - result += 'sat'; - } else if (number === 2 || number === 3 || number === 4) { - result += 'sata'; - } else { - result += 'sati'; - } - return result; - case 'dd': - if (number === 1) { - result += 'dan'; - } else { - result += 'dana'; - } - return result; - case 'MM': - if (number === 1) { - result += 'mjesec'; - } else if (number === 2 || number === 3 || number === 4) { - result += 'mjeseca'; - } else { - result += 'mjeseci'; - } - return result; - case 'yy': - if (number === 1) { - result += 'godina'; - } else if (number === 2 || number === 3 || number === 4) { - result += 'godine'; - } else { - result += 'godina'; - } - return result; - } - } - - hooks.defineLocale('bs', { - months : 'januar_februar_mart_april_maj_juni_juli_august_septembar_oktobar_novembar_decembar'.split('_'), - monthsShort : 'jan._feb._mar._apr._maj._jun._jul._aug._sep._okt._nov._dec.'.split('_'), - monthsParseExact: true, - weekdays : 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'), - weekdaysShort : 'ned._pon._uto._sri._čet._pet._sub.'.split('_'), - weekdaysMin : 'ne_po_ut_sr_če_pe_su'.split('_'), - weekdaysParseExact : true, - longDateFormat : { - LT : 'H:mm', - LTS : 'H:mm:ss', - L : 'DD.MM.YYYY', - LL : 'D. MMMM YYYY', - LLL : 'D. MMMM YYYY H:mm', - LLLL : 'dddd, D. MMMM YYYY H:mm' - }, - calendar : { - sameDay : '[danas u] LT', - nextDay : '[sutra u] LT', - nextWeek : function () { - switch (this.day()) { - case 0: - return '[u] [nedjelju] [u] LT'; - case 3: - return '[u] [srijedu] [u] LT'; - case 6: - return '[u] [subotu] [u] LT'; - case 1: - case 2: - case 4: - case 5: - return '[u] dddd [u] LT'; - } - }, - lastDay : '[jučer u] LT', - lastWeek : function () { - switch (this.day()) { - case 0: - case 3: - return '[prošlu] dddd [u] LT'; - case 6: - return '[prošle] [subote] [u] LT'; - case 1: - case 2: - case 4: - case 5: - return '[prošli] dddd [u] LT'; - } - }, - sameElse : 'L' - }, - relativeTime : { - future : 'za %s', - past : 'prije %s', - s : 'par sekundi', - ss : translate, - m : translate, - mm : translate, - h : translate, - hh : translate, - d : 'dan', - dd : translate, - M : 'mjesec', - MM : translate, - y : 'godinu', - yy : translate - }, - dayOfMonthOrdinalParse: /\d{1,2}\./, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 7th is the first week of the year. - } - }); - - //! moment.js locale configuration - - hooks.defineLocale('ca', { - months : { - standalone: 'gener_febrer_març_abril_maig_juny_juliol_agost_setembre_octubre_novembre_desembre'.split('_'), - format: 'de gener_de febrer_de març_d\'abril_de maig_de juny_de juliol_d\'agost_de setembre_d\'octubre_de novembre_de desembre'.split('_'), - isFormat: /D[oD]?(\s)+MMMM/ - }, - monthsShort : 'gen._febr._març_abr._maig_juny_jul._ag._set._oct._nov._des.'.split('_'), - monthsParseExact : true, - weekdays : 'diumenge_dilluns_dimarts_dimecres_dijous_divendres_dissabte'.split('_'), - weekdaysShort : 'dg._dl._dt._dc._dj._dv._ds.'.split('_'), - weekdaysMin : 'dg_dl_dt_dc_dj_dv_ds'.split('_'), - weekdaysParseExact : true, - longDateFormat : { - LT : 'H:mm', - LTS : 'H:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM [de] YYYY', - ll : 'D MMM YYYY', - LLL : 'D MMMM [de] YYYY [a les] H:mm', - lll : 'D MMM YYYY, H:mm', - LLLL : 'dddd D MMMM [de] YYYY [a les] H:mm', - llll : 'ddd D MMM YYYY, H:mm' - }, - calendar : { - sameDay : function () { - return '[avui a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT'; - }, - nextDay : function () { - return '[demà a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT'; - }, - nextWeek : function () { - return 'dddd [a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT'; - }, - lastDay : function () { - return '[ahir a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT'; - }, - lastWeek : function () { - return '[el] dddd [passat a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT'; - }, - sameElse : 'L' - }, - relativeTime : { - future : 'd\'aquí %s', - past : 'fa %s', - s : 'uns segons', - ss : '%d segons', - m : 'un minut', - mm : '%d minuts', - h : 'una hora', - hh : '%d hores', - d : 'un dia', - dd : '%d dies', - M : 'un mes', - MM : '%d mesos', - y : 'un any', - yy : '%d anys' - }, - dayOfMonthOrdinalParse: /\d{1,2}(r|n|t|è|a)/, - ordinal : function (number, period) { - var output = (number === 1) ? 'r' : - (number === 2) ? 'n' : - (number === 3) ? 'r' : - (number === 4) ? 't' : 'è'; - if (period === 'w' || period === 'W') { - output = 'a'; - } - return number + output; - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); - - //! moment.js locale configuration - - var months$3 = 'leden_únor_březen_duben_květen_červen_červenec_srpen_září_říjen_listopad_prosinec'.split('_'), - monthsShort = 'led_úno_bře_dub_kvě_čvn_čvc_srp_zář_říj_lis_pro'.split('_'); - function plural$1(n) { - return (n > 1) && (n < 5) && (~~(n / 10) !== 1); - } - function translate$1(number, withoutSuffix, key, isFuture) { - var result = number + ' '; - switch (key) { - case 's': // a few seconds / in a few seconds / a few seconds ago - return (withoutSuffix || isFuture) ? 'pár sekund' : 'pár sekundami'; - case 'ss': // 9 seconds / in 9 seconds / 9 seconds ago - if (withoutSuffix || isFuture) { - return result + (plural$1(number) ? 'sekundy' : 'sekund'); - } else { - return result + 'sekundami'; - } - break; - case 'm': // a minute / in a minute / a minute ago - return withoutSuffix ? 'minuta' : (isFuture ? 'minutu' : 'minutou'); - case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago - if (withoutSuffix || isFuture) { - return result + (plural$1(number) ? 'minuty' : 'minut'); - } else { - return result + 'minutami'; - } - break; - case 'h': // an hour / in an hour / an hour ago - return withoutSuffix ? 'hodina' : (isFuture ? 'hodinu' : 'hodinou'); - case 'hh': // 9 hours / in 9 hours / 9 hours ago - if (withoutSuffix || isFuture) { - return result + (plural$1(number) ? 'hodiny' : 'hodin'); - } else { - return result + 'hodinami'; - } - break; - case 'd': // a day / in a day / a day ago - return (withoutSuffix || isFuture) ? 'den' : 'dnem'; - case 'dd': // 9 days / in 9 days / 9 days ago - if (withoutSuffix || isFuture) { - return result + (plural$1(number) ? 'dny' : 'dní'); - } else { - return result + 'dny'; - } - break; - case 'M': // a month / in a month / a month ago - return (withoutSuffix || isFuture) ? 'měsíc' : 'měsícem'; - case 'MM': // 9 months / in 9 months / 9 months ago - if (withoutSuffix || isFuture) { - return result + (plural$1(number) ? 'měsíce' : 'měsíců'); - } else { - return result + 'měsíci'; - } - break; - case 'y': // a year / in a year / a year ago - return (withoutSuffix || isFuture) ? 'rok' : 'rokem'; - case 'yy': // 9 years / in 9 years / 9 years ago - if (withoutSuffix || isFuture) { - return result + (plural$1(number) ? 'roky' : 'let'); - } else { - return result + 'lety'; - } - break; - } - } - - hooks.defineLocale('cs', { - months : months$3, - monthsShort : monthsShort, - monthsParse : (function (months, monthsShort) { - var i, _monthsParse = []; - for (i = 0; i < 12; i++) { - // use custom parser to solve problem with July (červenec) - _monthsParse[i] = new RegExp('^' + months[i] + '$|^' + monthsShort[i] + '$', 'i'); - } - return _monthsParse; - }(months$3, monthsShort)), - shortMonthsParse : (function (monthsShort) { - var i, _shortMonthsParse = []; - for (i = 0; i < 12; i++) { - _shortMonthsParse[i] = new RegExp('^' + monthsShort[i] + '$', 'i'); - } - return _shortMonthsParse; - }(monthsShort)), - longMonthsParse : (function (months) { - var i, _longMonthsParse = []; - for (i = 0; i < 12; i++) { - _longMonthsParse[i] = new RegExp('^' + months[i] + '$', 'i'); - } - return _longMonthsParse; - }(months$3)), - weekdays : 'neděle_pondělí_úterý_středa_čtvrtek_pátek_sobota'.split('_'), - weekdaysShort : 'ne_po_út_st_čt_pá_so'.split('_'), - weekdaysMin : 'ne_po_út_st_čt_pá_so'.split('_'), - longDateFormat : { - LT: 'H:mm', - LTS : 'H:mm:ss', - L : 'DD.MM.YYYY', - LL : 'D. MMMM YYYY', - LLL : 'D. MMMM YYYY H:mm', - LLLL : 'dddd D. MMMM YYYY H:mm', - l : 'D. M. YYYY' - }, - calendar : { - sameDay: '[dnes v] LT', - nextDay: '[zítra v] LT', - nextWeek: function () { - switch (this.day()) { - case 0: - return '[v neděli v] LT'; - case 1: - case 2: - return '[v] dddd [v] LT'; - case 3: - return '[ve středu v] LT'; - case 4: - return '[ve čtvrtek v] LT'; - case 5: - return '[v pátek v] LT'; - case 6: - return '[v sobotu v] LT'; - } - }, - lastDay: '[včera v] LT', - lastWeek: function () { - switch (this.day()) { - case 0: - return '[minulou neděli v] LT'; - case 1: - case 2: - return '[minulé] dddd [v] LT'; - case 3: - return '[minulou středu v] LT'; - case 4: - case 5: - return '[minulý] dddd [v] LT'; - case 6: - return '[minulou sobotu v] LT'; - } - }, - sameElse: 'L' - }, - relativeTime : { - future : 'za %s', - past : 'před %s', - s : translate$1, - ss : translate$1, - m : translate$1, - mm : translate$1, - h : translate$1, - hh : translate$1, - d : translate$1, - dd : translate$1, - M : translate$1, - MM : translate$1, - y : translate$1, - yy : translate$1 - }, - dayOfMonthOrdinalParse : /\d{1,2}\./, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); - - //! moment.js locale configuration - - hooks.defineLocale('cv', { - months : 'кӑрлач_нарӑс_пуш_ака_май_ҫӗртме_утӑ_ҫурла_авӑн_юпа_чӳк_раштав'.split('_'), - monthsShort : 'кӑр_нар_пуш_ака_май_ҫӗр_утӑ_ҫур_авн_юпа_чӳк_раш'.split('_'), - weekdays : 'вырсарникун_тунтикун_ытларикун_юнкун_кӗҫнерникун_эрнекун_шӑматкун'.split('_'), - weekdaysShort : 'выр_тун_ытл_юн_кӗҫ_эрн_шӑм'.split('_'), - weekdaysMin : 'вр_тн_ыт_юн_кҫ_эр_шм'.split('_'), - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD-MM-YYYY', - LL : 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ]', - LLL : 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm', - LLLL : 'dddd, YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm' - }, - calendar : { - sameDay: '[Паян] LT [сехетре]', - nextDay: '[Ыран] LT [сехетре]', - lastDay: '[Ӗнер] LT [сехетре]', - nextWeek: '[Ҫитес] dddd LT [сехетре]', - lastWeek: '[Иртнӗ] dddd LT [сехетре]', - sameElse: 'L' - }, - relativeTime : { - future : function (output) { - var affix = /сехет$/i.exec(output) ? 'рен' : /ҫул$/i.exec(output) ? 'тан' : 'ран'; - return output + affix; - }, - past : '%s каялла', - s : 'пӗр-ик ҫеккунт', - ss : '%d ҫеккунт', - m : 'пӗр минут', - mm : '%d минут', - h : 'пӗр сехет', - hh : '%d сехет', - d : 'пӗр кун', - dd : '%d кун', - M : 'пӗр уйӑх', - MM : '%d уйӑх', - y : 'пӗр ҫул', - yy : '%d ҫул' - }, - dayOfMonthOrdinalParse: /\d{1,2}-мӗш/, - ordinal : '%d-мӗш', - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 7th is the first week of the year. - } - }); - - //! moment.js locale configuration - - hooks.defineLocale('cy', { - months: 'Ionawr_Chwefror_Mawrth_Ebrill_Mai_Mehefin_Gorffennaf_Awst_Medi_Hydref_Tachwedd_Rhagfyr'.split('_'), - monthsShort: 'Ion_Chwe_Maw_Ebr_Mai_Meh_Gor_Aws_Med_Hyd_Tach_Rhag'.split('_'), - weekdays: 'Dydd Sul_Dydd Llun_Dydd Mawrth_Dydd Mercher_Dydd Iau_Dydd Gwener_Dydd Sadwrn'.split('_'), - weekdaysShort: 'Sul_Llun_Maw_Mer_Iau_Gwe_Sad'.split('_'), - weekdaysMin: 'Su_Ll_Ma_Me_Ia_Gw_Sa'.split('_'), - weekdaysParseExact : true, - // time formats are the same as en-gb - longDateFormat: { - LT: 'HH:mm', - LTS : 'HH:mm:ss', - L: 'DD/MM/YYYY', - LL: 'D MMMM YYYY', - LLL: 'D MMMM YYYY HH:mm', - LLLL: 'dddd, D MMMM YYYY HH:mm' - }, - calendar: { - sameDay: '[Heddiw am] LT', - nextDay: '[Yfory am] LT', - nextWeek: 'dddd [am] LT', - lastDay: '[Ddoe am] LT', - lastWeek: 'dddd [diwethaf am] LT', - sameElse: 'L' - }, - relativeTime: { - future: 'mewn %s', - past: '%s yn ôl', - s: 'ychydig eiliadau', - ss: '%d eiliad', - m: 'munud', - mm: '%d munud', - h: 'awr', - hh: '%d awr', - d: 'diwrnod', - dd: '%d diwrnod', - M: 'mis', - MM: '%d mis', - y: 'blwyddyn', - yy: '%d flynedd' - }, - dayOfMonthOrdinalParse: /\d{1,2}(fed|ain|af|il|ydd|ed|eg)/, - // traditional ordinal numbers above 31 are not commonly used in colloquial Welsh - ordinal: function (number) { - var b = number, - output = '', - lookup = [ - '', 'af', 'il', 'ydd', 'ydd', 'ed', 'ed', 'ed', 'fed', 'fed', 'fed', // 1af to 10fed - 'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'fed' // 11eg to 20fed - ]; - if (b > 20) { - if (b === 40 || b === 50 || b === 60 || b === 80 || b === 100) { - output = 'fed'; // not 30ain, 70ain or 90ain - } else { - output = 'ain'; - } - } else if (b > 0) { - output = lookup[b]; - } - return number + output; - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); - - //! moment.js locale configuration - - hooks.defineLocale('da', { - months : 'januar_februar_marts_april_maj_juni_juli_august_september_oktober_november_december'.split('_'), - monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'.split('_'), - weekdays : 'søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag'.split('_'), - weekdaysShort : 'søn_man_tir_ons_tor_fre_lør'.split('_'), - weekdaysMin : 'sø_ma_ti_on_to_fr_lø'.split('_'), - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD.MM.YYYY', - LL : 'D. MMMM YYYY', - LLL : 'D. MMMM YYYY HH:mm', - LLLL : 'dddd [d.] D. MMMM YYYY [kl.] HH:mm' - }, - calendar : { - sameDay : '[i dag kl.] LT', - nextDay : '[i morgen kl.] LT', - nextWeek : 'på dddd [kl.] LT', - lastDay : '[i går kl.] LT', - lastWeek : '[i] dddd[s kl.] LT', - sameElse : 'L' - }, - relativeTime : { - future : 'om %s', - past : '%s siden', - s : 'få sekunder', - ss : '%d sekunder', - m : 'et minut', - mm : '%d minutter', - h : 'en time', - hh : '%d timer', - d : 'en dag', - dd : '%d dage', - M : 'en måned', - MM : '%d måneder', - y : 'et år', - yy : '%d år' - }, - dayOfMonthOrdinalParse: /\d{1,2}\./, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); - - //! moment.js locale configuration - - function processRelativeTime(number, withoutSuffix, key, isFuture) { - var format = { - 'm': ['eine Minute', 'einer Minute'], - 'h': ['eine Stunde', 'einer Stunde'], - 'd': ['ein Tag', 'einem Tag'], - 'dd': [number + ' Tage', number + ' Tagen'], - 'M': ['ein Monat', 'einem Monat'], - 'MM': [number + ' Monate', number + ' Monaten'], - 'y': ['ein Jahr', 'einem Jahr'], - 'yy': [number + ' Jahre', number + ' Jahren'] - }; - return withoutSuffix ? format[key][0] : format[key][1]; - } - - hooks.defineLocale('de-at', { - months : 'Jänner_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'), - monthsShort : 'Jän._Feb._März_Apr._Mai_Juni_Juli_Aug._Sep._Okt._Nov._Dez.'.split('_'), - monthsParseExact : true, - weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'), - weekdaysShort : 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'), - weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'), - weekdaysParseExact : true, - longDateFormat : { - LT: 'HH:mm', - LTS: 'HH:mm:ss', - L : 'DD.MM.YYYY', - LL : 'D. MMMM YYYY', - LLL : 'D. MMMM YYYY HH:mm', - LLLL : 'dddd, D. MMMM YYYY HH:mm' - }, - calendar : { - sameDay: '[heute um] LT [Uhr]', - sameElse: 'L', - nextDay: '[morgen um] LT [Uhr]', - nextWeek: 'dddd [um] LT [Uhr]', - lastDay: '[gestern um] LT [Uhr]', - lastWeek: '[letzten] dddd [um] LT [Uhr]' - }, - relativeTime : { - future : 'in %s', - past : 'vor %s', - s : 'ein paar Sekunden', - ss : '%d Sekunden', - m : processRelativeTime, - mm : '%d Minuten', - h : processRelativeTime, - hh : '%d Stunden', - d : processRelativeTime, - dd : processRelativeTime, - M : processRelativeTime, - MM : processRelativeTime, - y : processRelativeTime, - yy : processRelativeTime - }, - dayOfMonthOrdinalParse: /\d{1,2}\./, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); - - //! moment.js locale configuration - - function processRelativeTime$1(number, withoutSuffix, key, isFuture) { - var format = { - 'm': ['eine Minute', 'einer Minute'], - 'h': ['eine Stunde', 'einer Stunde'], - 'd': ['ein Tag', 'einem Tag'], - 'dd': [number + ' Tage', number + ' Tagen'], - 'M': ['ein Monat', 'einem Monat'], - 'MM': [number + ' Monate', number + ' Monaten'], - 'y': ['ein Jahr', 'einem Jahr'], - 'yy': [number + ' Jahre', number + ' Jahren'] - }; - return withoutSuffix ? format[key][0] : format[key][1]; - } - - hooks.defineLocale('de-ch', { - months : 'Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'), - monthsShort : 'Jan._Feb._März_Apr._Mai_Juni_Juli_Aug._Sep._Okt._Nov._Dez.'.split('_'), - monthsParseExact : true, - weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'), - weekdaysShort : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'), - weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'), - weekdaysParseExact : true, - longDateFormat : { - LT: 'HH:mm', - LTS: 'HH:mm:ss', - L : 'DD.MM.YYYY', - LL : 'D. MMMM YYYY', - LLL : 'D. MMMM YYYY HH:mm', - LLLL : 'dddd, D. MMMM YYYY HH:mm' - }, - calendar : { - sameDay: '[heute um] LT [Uhr]', - sameElse: 'L', - nextDay: '[morgen um] LT [Uhr]', - nextWeek: 'dddd [um] LT [Uhr]', - lastDay: '[gestern um] LT [Uhr]', - lastWeek: '[letzten] dddd [um] LT [Uhr]' - }, - relativeTime : { - future : 'in %s', - past : 'vor %s', - s : 'ein paar Sekunden', - ss : '%d Sekunden', - m : processRelativeTime$1, - mm : '%d Minuten', - h : processRelativeTime$1, - hh : '%d Stunden', - d : processRelativeTime$1, - dd : processRelativeTime$1, - M : processRelativeTime$1, - MM : processRelativeTime$1, - y : processRelativeTime$1, - yy : processRelativeTime$1 - }, - dayOfMonthOrdinalParse: /\d{1,2}\./, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); - - //! moment.js locale configuration - - function processRelativeTime$2(number, withoutSuffix, key, isFuture) { - var format = { - 'm': ['eine Minute', 'einer Minute'], - 'h': ['eine Stunde', 'einer Stunde'], - 'd': ['ein Tag', 'einem Tag'], - 'dd': [number + ' Tage', number + ' Tagen'], - 'M': ['ein Monat', 'einem Monat'], - 'MM': [number + ' Monate', number + ' Monaten'], - 'y': ['ein Jahr', 'einem Jahr'], - 'yy': [number + ' Jahre', number + ' Jahren'] - }; - return withoutSuffix ? format[key][0] : format[key][1]; - } - - hooks.defineLocale('de', { - months : 'Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'), - monthsShort : 'Jan._Feb._März_Apr._Mai_Juni_Juli_Aug._Sep._Okt._Nov._Dez.'.split('_'), - monthsParseExact : true, - weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'), - weekdaysShort : 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'), - weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'), - weekdaysParseExact : true, - longDateFormat : { - LT: 'HH:mm', - LTS: 'HH:mm:ss', - L : 'DD.MM.YYYY', - LL : 'D. MMMM YYYY', - LLL : 'D. MMMM YYYY HH:mm', - LLLL : 'dddd, D. MMMM YYYY HH:mm' - }, - calendar : { - sameDay: '[heute um] LT [Uhr]', - sameElse: 'L', - nextDay: '[morgen um] LT [Uhr]', - nextWeek: 'dddd [um] LT [Uhr]', - lastDay: '[gestern um] LT [Uhr]', - lastWeek: '[letzten] dddd [um] LT [Uhr]' - }, - relativeTime : { - future : 'in %s', - past : 'vor %s', - s : 'ein paar Sekunden', - ss : '%d Sekunden', - m : processRelativeTime$2, - mm : '%d Minuten', - h : processRelativeTime$2, - hh : '%d Stunden', - d : processRelativeTime$2, - dd : processRelativeTime$2, - M : processRelativeTime$2, - MM : processRelativeTime$2, - y : processRelativeTime$2, - yy : processRelativeTime$2 - }, - dayOfMonthOrdinalParse: /\d{1,2}\./, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); - - //! moment.js locale configuration - - var months$4 = [ - 'ޖެނުއަރީ', - 'ފެބްރުއަރީ', - 'މާރިޗު', - 'އޭޕްރީލު', - 'މޭ', - 'ޖޫން', - 'ޖުލައި', - 'އޯގަސްޓު', - 'ސެޕްޓެމްބަރު', - 'އޮކްޓޯބަރު', - 'ނޮވެމްބަރު', - 'ޑިސެމްބަރު' - ], weekdays = [ - 'އާދިއްތަ', - 'ހޯމަ', - 'އަންގާރަ', - 'ބުދަ', - 'ބުރާސްފަތި', - 'ހުކުރު', - 'ހޮނިހިރު' - ]; - - hooks.defineLocale('dv', { - months : months$4, - monthsShort : months$4, - weekdays : weekdays, - weekdaysShort : weekdays, - weekdaysMin : 'އާދި_ހޯމަ_އަން_ބުދަ_ބުރާ_ހުކު_ހޮނި'.split('_'), - longDateFormat : { - - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'D/M/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd D MMMM YYYY HH:mm' - }, - meridiemParse: /މކ|މފ/, - isPM : function (input) { - return 'މފ' === input; - }, - meridiem : function (hour, minute, isLower) { - if (hour < 12) { - return 'މކ'; - } else { - return 'މފ'; - } - }, - calendar : { - sameDay : '[މިއަދު] LT', - nextDay : '[މާދަމާ] LT', - nextWeek : 'dddd LT', - lastDay : '[އިއްޔެ] LT', - lastWeek : '[ފާއިތުވި] dddd LT', - sameElse : 'L' - }, - relativeTime : { - future : 'ތެރޭގައި %s', - past : 'ކުރިން %s', - s : 'ސިކުންތުކޮޅެއް', - ss : 'd% ސިކުންތު', - m : 'މިނިޓެއް', - mm : 'މިނިޓު %d', - h : 'ގަޑިއިރެއް', - hh : 'ގަޑިއިރު %d', - d : 'ދުވަހެއް', - dd : 'ދުވަސް %d', - M : 'މަހެއް', - MM : 'މަސް %d', - y : 'އަހަރެއް', - yy : 'އަހަރު %d' - }, - preparse: function (string) { - return string.replace(/،/g, ','); - }, - postformat: function (string) { - return string.replace(/,/g, '،'); - }, - week : { - dow : 7, // Sunday is the first day of the week. - doy : 12 // The week that contains Jan 12th is the first week of the year. - } - }); - - //! moment.js locale configuration - - hooks.defineLocale('el', { - monthsNominativeEl : 'Ιανουάριος_Φεβρουάριος_Μάρτιος_Απρίλιος_Μάιος_Ιούνιος_Ιούλιος_Αύγουστος_Σεπτέμβριος_Οκτώβριος_Νοέμβριος_Δεκέμβριος'.split('_'), - monthsGenitiveEl : 'Ιανουαρίου_Φεβρουαρίου_Μαρτίου_Απριλίου_Μαΐου_Ιουνίου_Ιουλίου_Αυγούστου_Σεπτεμβρίου_Οκτωβρίου_Νοεμβρίου_Δεκεμβρίου'.split('_'), - months : function (momentToFormat, format) { - if (!momentToFormat) { - return this._monthsNominativeEl; - } else if (typeof format === 'string' && /D/.test(format.substring(0, format.indexOf('MMMM')))) { // if there is a day number before 'MMMM' - return this._monthsGenitiveEl[momentToFormat.month()]; - } else { - return this._monthsNominativeEl[momentToFormat.month()]; - } - }, - monthsShort : 'Ιαν_Φεβ_Μαρ_Απρ_Μαϊ_Ιουν_Ιουλ_Αυγ_Σεπ_Οκτ_Νοε_Δεκ'.split('_'), - weekdays : 'Κυριακή_Δευτέρα_Τρίτη_Τετάρτη_Πέμπτη_Παρασκευή_Σάββατο'.split('_'), - weekdaysShort : 'Κυρ_Δευ_Τρι_Τετ_Πεμ_Παρ_Σαβ'.split('_'), - weekdaysMin : 'Κυ_Δε_Τρ_Τε_Πε_Πα_Σα'.split('_'), - meridiem : function (hours, minutes, isLower) { - if (hours > 11) { - return isLower ? 'μμ' : 'ΜΜ'; - } else { - return isLower ? 'πμ' : 'ΠΜ'; - } - }, - isPM : function (input) { - return ((input + '').toLowerCase()[0] === 'μ'); - }, - meridiemParse : /[ΠΜ]\.?Μ?\.?/i, - longDateFormat : { - LT : 'h:mm A', - LTS : 'h:mm:ss A', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY h:mm A', - LLLL : 'dddd, D MMMM YYYY h:mm A' - }, - calendarEl : { - sameDay : '[Σήμερα {}] LT', - nextDay : '[Αύριο {}] LT', - nextWeek : 'dddd [{}] LT', - lastDay : '[Χθες {}] LT', - lastWeek : function () { - switch (this.day()) { - case 6: - return '[το προηγούμενο] dddd [{}] LT'; - default: - return '[την προηγούμενη] dddd [{}] LT'; - } - }, - sameElse : 'L' - }, - calendar : function (key, mom) { - var output = this._calendarEl[key], - hours = mom && mom.hours(); - if (isFunction(output)) { - output = output.apply(mom); - } - return output.replace('{}', (hours % 12 === 1 ? 'στη' : 'στις')); - }, - relativeTime : { - future : 'σε %s', - past : '%s πριν', - s : 'λίγα δευτερόλεπτα', - ss : '%d δευτερόλεπτα', - m : 'ένα λεπτό', - mm : '%d λεπτά', - h : 'μία ώρα', - hh : '%d ώρες', - d : 'μία μέρα', - dd : '%d μέρες', - M : 'ένας μήνας', - MM : '%d μήνες', - y : 'ένας χρόνος', - yy : '%d χρόνια' - }, - dayOfMonthOrdinalParse: /\d{1,2}η/, - ordinal: '%dη', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4st is the first week of the year. - } - }); - - //! moment.js locale configuration - - hooks.defineLocale('en-au', { - months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'), - monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), - weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'), - weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), - weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), - longDateFormat : { - LT : 'h:mm A', - LTS : 'h:mm:ss A', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY h:mm A', - LLLL : 'dddd, D MMMM YYYY h:mm A' - }, - calendar : { - sameDay : '[Today at] LT', - nextDay : '[Tomorrow at] LT', - nextWeek : 'dddd [at] LT', - lastDay : '[Yesterday at] LT', - lastWeek : '[Last] dddd [at] LT', - sameElse : 'L' - }, - relativeTime : { - future : 'in %s', - past : '%s ago', - s : 'a few seconds', - ss : '%d seconds', - m : 'a minute', - mm : '%d minutes', - h : 'an hour', - hh : '%d hours', - d : 'a day', - dd : '%d days', - M : 'a month', - MM : '%d months', - y : 'a year', - yy : '%d years' - }, - dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/, - ordinal : function (number) { - var b = number % 10, - output = (~~(number % 100 / 10) === 1) ? 'th' : - (b === 1) ? 'st' : - (b === 2) ? 'nd' : - (b === 3) ? 'rd' : 'th'; - return number + output; - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); - - //! moment.js locale configuration - - hooks.defineLocale('en-ca', { - months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'), - monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), - weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'), - weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), - weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), - longDateFormat : { - LT : 'h:mm A', - LTS : 'h:mm:ss A', - L : 'YYYY-MM-DD', - LL : 'MMMM D, YYYY', - LLL : 'MMMM D, YYYY h:mm A', - LLLL : 'dddd, MMMM D, YYYY h:mm A' - }, - calendar : { - sameDay : '[Today at] LT', - nextDay : '[Tomorrow at] LT', - nextWeek : 'dddd [at] LT', - lastDay : '[Yesterday at] LT', - lastWeek : '[Last] dddd [at] LT', - sameElse : 'L' - }, - relativeTime : { - future : 'in %s', - past : '%s ago', - s : 'a few seconds', - ss : '%d seconds', - m : 'a minute', - mm : '%d minutes', - h : 'an hour', - hh : '%d hours', - d : 'a day', - dd : '%d days', - M : 'a month', - MM : '%d months', - y : 'a year', - yy : '%d years' - }, - dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/, - ordinal : function (number) { - var b = number % 10, - output = (~~(number % 100 / 10) === 1) ? 'th' : - (b === 1) ? 'st' : - (b === 2) ? 'nd' : - (b === 3) ? 'rd' : 'th'; - return number + output; - } - }); - - //! moment.js locale configuration - - hooks.defineLocale('en-gb', { - months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'), - monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), - weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'), - weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), - weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd, D MMMM YYYY HH:mm' - }, - calendar : { - sameDay : '[Today at] LT', - nextDay : '[Tomorrow at] LT', - nextWeek : 'dddd [at] LT', - lastDay : '[Yesterday at] LT', - lastWeek : '[Last] dddd [at] LT', - sameElse : 'L' - }, - relativeTime : { - future : 'in %s', - past : '%s ago', - s : 'a few seconds', - ss : '%d seconds', - m : 'a minute', - mm : '%d minutes', - h : 'an hour', - hh : '%d hours', - d : 'a day', - dd : '%d days', - M : 'a month', - MM : '%d months', - y : 'a year', - yy : '%d years' - }, - dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/, - ordinal : function (number) { - var b = number % 10, - output = (~~(number % 100 / 10) === 1) ? 'th' : - (b === 1) ? 'st' : - (b === 2) ? 'nd' : - (b === 3) ? 'rd' : 'th'; - return number + output; - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); - - //! moment.js locale configuration - - hooks.defineLocale('en-ie', { - months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'), - monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), - weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'), - weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), - weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD-MM-YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd D MMMM YYYY HH:mm' - }, - calendar : { - sameDay : '[Today at] LT', - nextDay : '[Tomorrow at] LT', - nextWeek : 'dddd [at] LT', - lastDay : '[Yesterday at] LT', - lastWeek : '[Last] dddd [at] LT', - sameElse : 'L' - }, - relativeTime : { - future : 'in %s', - past : '%s ago', - s : 'a few seconds', - ss : '%d seconds', - m : 'a minute', - mm : '%d minutes', - h : 'an hour', - hh : '%d hours', - d : 'a day', - dd : '%d days', - M : 'a month', - MM : '%d months', - y : 'a year', - yy : '%d years' - }, - dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/, - ordinal : function (number) { - var b = number % 10, - output = (~~(number % 100 / 10) === 1) ? 'th' : - (b === 1) ? 'st' : - (b === 2) ? 'nd' : - (b === 3) ? 'rd' : 'th'; - return number + output; - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); - - //! moment.js locale configuration - - hooks.defineLocale('en-il', { - months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'), - monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), - weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'), - weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), - weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd, D MMMM YYYY HH:mm' - }, - calendar : { - sameDay : '[Today at] LT', - nextDay : '[Tomorrow at] LT', - nextWeek : 'dddd [at] LT', - lastDay : '[Yesterday at] LT', - lastWeek : '[Last] dddd [at] LT', - sameElse : 'L' - }, - relativeTime : { - future : 'in %s', - past : '%s ago', - s : 'a few seconds', - m : 'a minute', - mm : '%d minutes', - h : 'an hour', - hh : '%d hours', - d : 'a day', - dd : '%d days', - M : 'a month', - MM : '%d months', - y : 'a year', - yy : '%d years' - }, - dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/, - ordinal : function (number) { - var b = number % 10, - output = (~~(number % 100 / 10) === 1) ? 'th' : - (b === 1) ? 'st' : - (b === 2) ? 'nd' : - (b === 3) ? 'rd' : 'th'; - return number + output; - } - }); - - //! moment.js locale configuration - - hooks.defineLocale('en-nz', { - months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'), - monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), - weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'), - weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), - weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), - longDateFormat : { - LT : 'h:mm A', - LTS : 'h:mm:ss A', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY h:mm A', - LLLL : 'dddd, D MMMM YYYY h:mm A' - }, - calendar : { - sameDay : '[Today at] LT', - nextDay : '[Tomorrow at] LT', - nextWeek : 'dddd [at] LT', - lastDay : '[Yesterday at] LT', - lastWeek : '[Last] dddd [at] LT', - sameElse : 'L' - }, - relativeTime : { - future : 'in %s', - past : '%s ago', - s : 'a few seconds', - ss : '%d seconds', - m : 'a minute', - mm : '%d minutes', - h : 'an hour', - hh : '%d hours', - d : 'a day', - dd : '%d days', - M : 'a month', - MM : '%d months', - y : 'a year', - yy : '%d years' - }, - dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/, - ordinal : function (number) { - var b = number % 10, - output = (~~(number % 100 / 10) === 1) ? 'th' : - (b === 1) ? 'st' : - (b === 2) ? 'nd' : - (b === 3) ? 'rd' : 'th'; - return number + output; - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); - - //! moment.js locale configuration - - hooks.defineLocale('eo', { - months : 'januaro_februaro_marto_aprilo_majo_junio_julio_aŭgusto_septembro_oktobro_novembro_decembro'.split('_'), - monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aŭg_sep_okt_nov_dec'.split('_'), - weekdays : 'dimanĉo_lundo_mardo_merkredo_ĵaŭdo_vendredo_sabato'.split('_'), - weekdaysShort : 'dim_lun_mard_merk_ĵaŭ_ven_sab'.split('_'), - weekdaysMin : 'di_lu_ma_me_ĵa_ve_sa'.split('_'), - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'YYYY-MM-DD', - LL : 'D[-a de] MMMM, YYYY', - LLL : 'D[-a de] MMMM, YYYY HH:mm', - LLLL : 'dddd, [la] D[-a de] MMMM, YYYY HH:mm' - }, - meridiemParse: /[ap]\.t\.m/i, - isPM: function (input) { - return input.charAt(0).toLowerCase() === 'p'; - }, - meridiem : function (hours, minutes, isLower) { - if (hours > 11) { - return isLower ? 'p.t.m.' : 'P.T.M.'; - } else { - return isLower ? 'a.t.m.' : 'A.T.M.'; - } - }, - calendar : { - sameDay : '[Hodiaŭ je] LT', - nextDay : '[Morgaŭ je] LT', - nextWeek : 'dddd [je] LT', - lastDay : '[Hieraŭ je] LT', - lastWeek : '[pasinta] dddd [je] LT', - sameElse : 'L' - }, - relativeTime : { - future : 'post %s', - past : 'antaŭ %s', - s : 'sekundoj', - ss : '%d sekundoj', - m : 'minuto', - mm : '%d minutoj', - h : 'horo', - hh : '%d horoj', - d : 'tago',//ne 'diurno', ĉar estas uzita por proksimumo - dd : '%d tagoj', - M : 'monato', - MM : '%d monatoj', - y : 'jaro', - yy : '%d jaroj' - }, - dayOfMonthOrdinalParse: /\d{1,2}a/, - ordinal : '%da', - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 7th is the first week of the year. - } - }); - - //! moment.js locale configuration - - var monthsShortDot = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split('_'), - monthsShort$1 = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_'); - - var monthsParse = [/^ene/i, /^feb/i, /^mar/i, /^abr/i, /^may/i, /^jun/i, /^jul/i, /^ago/i, /^sep/i, /^oct/i, /^nov/i, /^dic/i]; - var monthsRegex$1 = /^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre|ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i; - - hooks.defineLocale('es-do', { - months : 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split('_'), - monthsShort : function (m, format) { - if (!m) { - return monthsShortDot; - } else if (/-MMM-/.test(format)) { - return monthsShort$1[m.month()]; - } else { - return monthsShortDot[m.month()]; - } - }, - monthsRegex: monthsRegex$1, - monthsShortRegex: monthsRegex$1, - monthsStrictRegex: /^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre)/i, - monthsShortStrictRegex: /^(ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i, - monthsParse: monthsParse, - longMonthsParse: monthsParse, - shortMonthsParse: monthsParse, - weekdays : 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'), - weekdaysShort : 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'), - weekdaysMin : 'do_lu_ma_mi_ju_vi_sá'.split('_'), - weekdaysParseExact : true, - longDateFormat : { - LT : 'h:mm A', - LTS : 'h:mm:ss A', - L : 'DD/MM/YYYY', - LL : 'D [de] MMMM [de] YYYY', - LLL : 'D [de] MMMM [de] YYYY h:mm A', - LLLL : 'dddd, D [de] MMMM [de] YYYY h:mm A' - }, - calendar : { - sameDay : function () { - return '[hoy a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; - }, - nextDay : function () { - return '[mañana a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; - }, - nextWeek : function () { - return 'dddd [a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; - }, - lastDay : function () { - return '[ayer a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; - }, - lastWeek : function () { - return '[el] dddd [pasado a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; - }, - sameElse : 'L' - }, - relativeTime : { - future : 'en %s', - past : 'hace %s', - s : 'unos segundos', - ss : '%d segundos', - m : 'un minuto', - mm : '%d minutos', - h : 'una hora', - hh : '%d horas', - d : 'un día', - dd : '%d días', - M : 'un mes', - MM : '%d meses', - y : 'un año', - yy : '%d años' - }, - dayOfMonthOrdinalParse : /\d{1,2}º/, - ordinal : '%dº', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); - - //! moment.js locale configuration - - var monthsShortDot$1 = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split('_'), - monthsShort$2 = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_'); - - hooks.defineLocale('es-us', { - months : 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split('_'), - monthsShort : function (m, format) { - if (!m) { - return monthsShortDot$1; - } else if (/-MMM-/.test(format)) { - return monthsShort$2[m.month()]; - } else { - return monthsShortDot$1[m.month()]; - } - }, - monthsParseExact : true, - weekdays : 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'), - weekdaysShort : 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'), - weekdaysMin : 'do_lu_ma_mi_ju_vi_sá'.split('_'), - weekdaysParseExact : true, - longDateFormat : { - LT : 'h:mm A', - LTS : 'h:mm:ss A', - L : 'MM/DD/YYYY', - LL : 'MMMM [de] D [de] YYYY', - LLL : 'MMMM [de] D [de] YYYY h:mm A', - LLLL : 'dddd, MMMM [de] D [de] YYYY h:mm A' - }, - calendar : { - sameDay : function () { - return '[hoy a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; - }, - nextDay : function () { - return '[mañana a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; - }, - nextWeek : function () { - return 'dddd [a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; - }, - lastDay : function () { - return '[ayer a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; - }, - lastWeek : function () { - return '[el] dddd [pasado a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; - }, - sameElse : 'L' - }, - relativeTime : { - future : 'en %s', - past : 'hace %s', - s : 'unos segundos', - ss : '%d segundos', - m : 'un minuto', - mm : '%d minutos', - h : 'una hora', - hh : '%d horas', - d : 'un día', - dd : '%d días', - M : 'un mes', - MM : '%d meses', - y : 'un año', - yy : '%d años' - }, - dayOfMonthOrdinalParse : /\d{1,2}º/, - ordinal : '%dº', - week : { - dow : 0, // Sunday is the first day of the week. - doy : 6 // The week that contains Jan 6th is the first week of the year. - } - }); - - //! moment.js locale configuration - - var monthsShortDot$2 = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split('_'), - monthsShort$3 = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_'); - - var monthsParse$1 = [/^ene/i, /^feb/i, /^mar/i, /^abr/i, /^may/i, /^jun/i, /^jul/i, /^ago/i, /^sep/i, /^oct/i, /^nov/i, /^dic/i]; - var monthsRegex$2 = /^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre|ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i; - - hooks.defineLocale('es', { - months : 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split('_'), - monthsShort : function (m, format) { - if (!m) { - return monthsShortDot$2; - } else if (/-MMM-/.test(format)) { - return monthsShort$3[m.month()]; - } else { - return monthsShortDot$2[m.month()]; - } - }, - monthsRegex : monthsRegex$2, - monthsShortRegex : monthsRegex$2, - monthsStrictRegex : /^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre)/i, - monthsShortStrictRegex : /^(ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i, - monthsParse : monthsParse$1, - longMonthsParse : monthsParse$1, - shortMonthsParse : monthsParse$1, - weekdays : 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'), - weekdaysShort : 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'), - weekdaysMin : 'do_lu_ma_mi_ju_vi_sá'.split('_'), - weekdaysParseExact : true, - longDateFormat : { - LT : 'H:mm', - LTS : 'H:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D [de] MMMM [de] YYYY', - LLL : 'D [de] MMMM [de] YYYY H:mm', - LLLL : 'dddd, D [de] MMMM [de] YYYY H:mm' - }, - calendar : { - sameDay : function () { - return '[hoy a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; - }, - nextDay : function () { - return '[mañana a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; - }, - nextWeek : function () { - return 'dddd [a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; - }, - lastDay : function () { - return '[ayer a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; - }, - lastWeek : function () { - return '[el] dddd [pasado a la' + ((this.hours() !== 1) ? 's' : '') + '] LT'; - }, - sameElse : 'L' - }, - relativeTime : { - future : 'en %s', - past : 'hace %s', - s : 'unos segundos', - ss : '%d segundos', - m : 'un minuto', - mm : '%d minutos', - h : 'una hora', - hh : '%d horas', - d : 'un día', - dd : '%d días', - M : 'un mes', - MM : '%d meses', - y : 'un año', - yy : '%d años' - }, - dayOfMonthOrdinalParse : /\d{1,2}º/, - ordinal : '%dº', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); - - //! moment.js locale configuration - - function processRelativeTime$3(number, withoutSuffix, key, isFuture) { - var format = { - 's' : ['mõne sekundi', 'mõni sekund', 'paar sekundit'], - 'ss': [number + 'sekundi', number + 'sekundit'], - 'm' : ['ühe minuti', 'üks minut'], - 'mm': [number + ' minuti', number + ' minutit'], - 'h' : ['ühe tunni', 'tund aega', 'üks tund'], - 'hh': [number + ' tunni', number + ' tundi'], - 'd' : ['ühe päeva', 'üks päev'], - 'M' : ['kuu aja', 'kuu aega', 'üks kuu'], - 'MM': [number + ' kuu', number + ' kuud'], - 'y' : ['ühe aasta', 'aasta', 'üks aasta'], - 'yy': [number + ' aasta', number + ' aastat'] - }; - if (withoutSuffix) { - return format[key][2] ? format[key][2] : format[key][1]; - } - return isFuture ? format[key][0] : format[key][1]; - } - - hooks.defineLocale('et', { - months : 'jaanuar_veebruar_märts_aprill_mai_juuni_juuli_august_september_oktoober_november_detsember'.split('_'), - monthsShort : 'jaan_veebr_märts_apr_mai_juuni_juuli_aug_sept_okt_nov_dets'.split('_'), - weekdays : 'pühapäev_esmaspäev_teisipäev_kolmapäev_neljapäev_reede_laupäev'.split('_'), - weekdaysShort : 'P_E_T_K_N_R_L'.split('_'), - weekdaysMin : 'P_E_T_K_N_R_L'.split('_'), - longDateFormat : { - LT : 'H:mm', - LTS : 'H:mm:ss', - L : 'DD.MM.YYYY', - LL : 'D. MMMM YYYY', - LLL : 'D. MMMM YYYY H:mm', - LLLL : 'dddd, D. MMMM YYYY H:mm' - }, - calendar : { - sameDay : '[Täna,] LT', - nextDay : '[Homme,] LT', - nextWeek : '[Järgmine] dddd LT', - lastDay : '[Eile,] LT', - lastWeek : '[Eelmine] dddd LT', - sameElse : 'L' - }, - relativeTime : { - future : '%s pärast', - past : '%s tagasi', - s : processRelativeTime$3, - ss : processRelativeTime$3, - m : processRelativeTime$3, - mm : processRelativeTime$3, - h : processRelativeTime$3, - hh : processRelativeTime$3, - d : processRelativeTime$3, - dd : '%d päeva', - M : processRelativeTime$3, - MM : processRelativeTime$3, - y : processRelativeTime$3, - yy : processRelativeTime$3 - }, - dayOfMonthOrdinalParse: /\d{1,2}\./, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); - - //! moment.js locale configuration - - hooks.defineLocale('eu', { - months : 'urtarrila_otsaila_martxoa_apirila_maiatza_ekaina_uztaila_abuztua_iraila_urria_azaroa_abendua'.split('_'), - monthsShort : 'urt._ots._mar._api._mai._eka._uzt._abu._ira._urr._aza._abe.'.split('_'), - monthsParseExact : true, - weekdays : 'igandea_astelehena_asteartea_asteazkena_osteguna_ostirala_larunbata'.split('_'), - weekdaysShort : 'ig._al._ar._az._og._ol._lr.'.split('_'), - weekdaysMin : 'ig_al_ar_az_og_ol_lr'.split('_'), - weekdaysParseExact : true, - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'YYYY-MM-DD', - LL : 'YYYY[ko] MMMM[ren] D[a]', - LLL : 'YYYY[ko] MMMM[ren] D[a] HH:mm', - LLLL : 'dddd, YYYY[ko] MMMM[ren] D[a] HH:mm', - l : 'YYYY-M-D', - ll : 'YYYY[ko] MMM D[a]', - lll : 'YYYY[ko] MMM D[a] HH:mm', - llll : 'ddd, YYYY[ko] MMM D[a] HH:mm' - }, - calendar : { - sameDay : '[gaur] LT[etan]', - nextDay : '[bihar] LT[etan]', - nextWeek : 'dddd LT[etan]', - lastDay : '[atzo] LT[etan]', - lastWeek : '[aurreko] dddd LT[etan]', - sameElse : 'L' - }, - relativeTime : { - future : '%s barru', - past : 'duela %s', - s : 'segundo batzuk', - ss : '%d segundo', - m : 'minutu bat', - mm : '%d minutu', - h : 'ordu bat', - hh : '%d ordu', - d : 'egun bat', - dd : '%d egun', - M : 'hilabete bat', - MM : '%d hilabete', - y : 'urte bat', - yy : '%d urte' - }, - dayOfMonthOrdinalParse: /\d{1,2}\./, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 7th is the first week of the year. - } - }); - - //! moment.js locale configuration - - var symbolMap$5 = { - '1': '۱', - '2': '۲', - '3': '۳', - '4': '۴', - '5': '۵', - '6': '۶', - '7': '۷', - '8': '۸', - '9': '۹', - '0': '۰' - }, numberMap$4 = { - '۱': '1', - '۲': '2', - '۳': '3', - '۴': '4', - '۵': '5', - '۶': '6', - '۷': '7', - '۸': '8', - '۹': '9', - '۰': '0' - }; - - hooks.defineLocale('fa', { - months : 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'), - monthsShort : 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'), - weekdays : 'یک\u200cشنبه_دوشنبه_سه\u200cشنبه_چهارشنبه_پنج\u200cشنبه_جمعه_شنبه'.split('_'), - weekdaysShort : 'یک\u200cشنبه_دوشنبه_سه\u200cشنبه_چهارشنبه_پنج\u200cشنبه_جمعه_شنبه'.split('_'), - weekdaysMin : 'ی_د_س_چ_پ_ج_ش'.split('_'), - weekdaysParseExact : true, - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd, D MMMM YYYY HH:mm' - }, - meridiemParse: /قبل از ظهر|بعد از ظهر/, - isPM: function (input) { - return /بعد از ظهر/.test(input); - }, - meridiem : function (hour, minute, isLower) { - if (hour < 12) { - return 'قبل از ظهر'; - } else { - return 'بعد از ظهر'; - } - }, - calendar : { - sameDay : '[امروز ساعت] LT', - nextDay : '[فردا ساعت] LT', - nextWeek : 'dddd [ساعت] LT', - lastDay : '[دیروز ساعت] LT', - lastWeek : 'dddd [پیش] [ساعت] LT', - sameElse : 'L' - }, - relativeTime : { - future : 'در %s', - past : '%s پیش', - s : 'چند ثانیه', - ss : 'ثانیه d%', - m : 'یک دقیقه', - mm : '%d دقیقه', - h : 'یک ساعت', - hh : '%d ساعت', - d : 'یک روز', - dd : '%d روز', - M : 'یک ماه', - MM : '%d ماه', - y : 'یک سال', - yy : '%d سال' - }, - preparse: function (string) { - return string.replace(/[۰-۹]/g, function (match) { - return numberMap$4[match]; - }).replace(/،/g, ','); - }, - postformat: function (string) { - return string.replace(/\d/g, function (match) { - return symbolMap$5[match]; - }).replace(/,/g, '،'); - }, - dayOfMonthOrdinalParse: /\d{1,2}م/, - ordinal : '%dم', - week : { - dow : 6, // Saturday is the first day of the week. - doy : 12 // The week that contains Jan 12th is the first week of the year. - } - }); - - //! moment.js locale configuration - - var numbersPast = 'nolla yksi kaksi kolme neljä viisi kuusi seitsemän kahdeksan yhdeksän'.split(' '), - numbersFuture = [ - 'nolla', 'yhden', 'kahden', 'kolmen', 'neljän', 'viiden', 'kuuden', - numbersPast[7], numbersPast[8], numbersPast[9] - ]; - function translate$2(number, withoutSuffix, key, isFuture) { - var result = ''; - switch (key) { - case 's': - return isFuture ? 'muutaman sekunnin' : 'muutama sekunti'; - case 'ss': - return isFuture ? 'sekunnin' : 'sekuntia'; - case 'm': - return isFuture ? 'minuutin' : 'minuutti'; - case 'mm': - result = isFuture ? 'minuutin' : 'minuuttia'; - break; - case 'h': - return isFuture ? 'tunnin' : 'tunti'; - case 'hh': - result = isFuture ? 'tunnin' : 'tuntia'; - break; - case 'd': - return isFuture ? 'päivän' : 'päivä'; - case 'dd': - result = isFuture ? 'päivän' : 'päivää'; - break; - case 'M': - return isFuture ? 'kuukauden' : 'kuukausi'; - case 'MM': - result = isFuture ? 'kuukauden' : 'kuukautta'; - break; - case 'y': - return isFuture ? 'vuoden' : 'vuosi'; - case 'yy': - result = isFuture ? 'vuoden' : 'vuotta'; - break; - } - result = verbalNumber(number, isFuture) + ' ' + result; - return result; - } - function verbalNumber(number, isFuture) { - return number < 10 ? (isFuture ? numbersFuture[number] : numbersPast[number]) : number; - } - - hooks.defineLocale('fi', { - months : 'tammikuu_helmikuu_maaliskuu_huhtikuu_toukokuu_kesäkuu_heinäkuu_elokuu_syyskuu_lokakuu_marraskuu_joulukuu'.split('_'), - monthsShort : 'tammi_helmi_maalis_huhti_touko_kesä_heinä_elo_syys_loka_marras_joulu'.split('_'), - weekdays : 'sunnuntai_maanantai_tiistai_keskiviikko_torstai_perjantai_lauantai'.split('_'), - weekdaysShort : 'su_ma_ti_ke_to_pe_la'.split('_'), - weekdaysMin : 'su_ma_ti_ke_to_pe_la'.split('_'), - longDateFormat : { - LT : 'HH.mm', - LTS : 'HH.mm.ss', - L : 'DD.MM.YYYY', - LL : 'Do MMMM[ta] YYYY', - LLL : 'Do MMMM[ta] YYYY, [klo] HH.mm', - LLLL : 'dddd, Do MMMM[ta] YYYY, [klo] HH.mm', - l : 'D.M.YYYY', - ll : 'Do MMM YYYY', - lll : 'Do MMM YYYY, [klo] HH.mm', - llll : 'ddd, Do MMM YYYY, [klo] HH.mm' - }, - calendar : { - sameDay : '[tänään] [klo] LT', - nextDay : '[huomenna] [klo] LT', - nextWeek : 'dddd [klo] LT', - lastDay : '[eilen] [klo] LT', - lastWeek : '[viime] dddd[na] [klo] LT', - sameElse : 'L' - }, - relativeTime : { - future : '%s päästä', - past : '%s sitten', - s : translate$2, - ss : translate$2, - m : translate$2, - mm : translate$2, - h : translate$2, - hh : translate$2, - d : translate$2, - dd : translate$2, - M : translate$2, - MM : translate$2, - y : translate$2, - yy : translate$2 - }, - dayOfMonthOrdinalParse: /\d{1,2}\./, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); - - //! moment.js locale configuration - - hooks.defineLocale('fo', { - months : 'januar_februar_mars_apríl_mai_juni_juli_august_september_oktober_november_desember'.split('_'), - monthsShort : 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'), - weekdays : 'sunnudagur_mánadagur_týsdagur_mikudagur_hósdagur_fríggjadagur_leygardagur'.split('_'), - weekdaysShort : 'sun_mán_týs_mik_hós_frí_ley'.split('_'), - weekdaysMin : 'su_má_tý_mi_hó_fr_le'.split('_'), - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd D. MMMM, YYYY HH:mm' - }, - calendar : { - sameDay : '[Í dag kl.] LT', - nextDay : '[Í morgin kl.] LT', - nextWeek : 'dddd [kl.] LT', - lastDay : '[Í gjár kl.] LT', - lastWeek : '[síðstu] dddd [kl] LT', - sameElse : 'L' - }, - relativeTime : { - future : 'um %s', - past : '%s síðani', - s : 'fá sekund', - ss : '%d sekundir', - m : 'ein minutt', - mm : '%d minuttir', - h : 'ein tími', - hh : '%d tímar', - d : 'ein dagur', - dd : '%d dagar', - M : 'ein mánaði', - MM : '%d mánaðir', - y : 'eitt ár', - yy : '%d ár' - }, - dayOfMonthOrdinalParse: /\d{1,2}\./, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); - - //! moment.js locale configuration - - hooks.defineLocale('fr-ca', { - months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'), - monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'), - monthsParseExact : true, - weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'), - weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'), - weekdaysMin : 'di_lu_ma_me_je_ve_sa'.split('_'), - weekdaysParseExact : true, - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'YYYY-MM-DD', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd D MMMM YYYY HH:mm' - }, - calendar : { - sameDay : '[Aujourd’hui à] LT', - nextDay : '[Demain à] LT', - nextWeek : 'dddd [à] LT', - lastDay : '[Hier à] LT', - lastWeek : 'dddd [dernier à] LT', - sameElse : 'L' - }, - relativeTime : { - future : 'dans %s', - past : 'il y a %s', - s : 'quelques secondes', - ss : '%d secondes', - m : 'une minute', - mm : '%d minutes', - h : 'une heure', - hh : '%d heures', - d : 'un jour', - dd : '%d jours', - M : 'un mois', - MM : '%d mois', - y : 'un an', - yy : '%d ans' - }, - dayOfMonthOrdinalParse: /\d{1,2}(er|e)/, - ordinal : function (number, period) { - switch (period) { - // Words with masculine grammatical gender: mois, trimestre, jour - default: - case 'M': - case 'Q': - case 'D': - case 'DDD': - case 'd': - return number + (number === 1 ? 'er' : 'e'); - - // Words with feminine grammatical gender: semaine - case 'w': - case 'W': - return number + (number === 1 ? 're' : 'e'); - } - } - }); - - //! moment.js locale configuration - - hooks.defineLocale('fr-ch', { - months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'), - monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'), - monthsParseExact : true, - weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'), - weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'), - weekdaysMin : 'di_lu_ma_me_je_ve_sa'.split('_'), - weekdaysParseExact : true, - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD.MM.YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd D MMMM YYYY HH:mm' - }, - calendar : { - sameDay : '[Aujourd’hui à] LT', - nextDay : '[Demain à] LT', - nextWeek : 'dddd [à] LT', - lastDay : '[Hier à] LT', - lastWeek : 'dddd [dernier à] LT', - sameElse : 'L' - }, - relativeTime : { - future : 'dans %s', - past : 'il y a %s', - s : 'quelques secondes', - ss : '%d secondes', - m : 'une minute', - mm : '%d minutes', - h : 'une heure', - hh : '%d heures', - d : 'un jour', - dd : '%d jours', - M : 'un mois', - MM : '%d mois', - y : 'un an', - yy : '%d ans' - }, - dayOfMonthOrdinalParse: /\d{1,2}(er|e)/, - ordinal : function (number, period) { - switch (period) { - // Words with masculine grammatical gender: mois, trimestre, jour - default: - case 'M': - case 'Q': - case 'D': - case 'DDD': - case 'd': - return number + (number === 1 ? 'er' : 'e'); - - // Words with feminine grammatical gender: semaine - case 'w': - case 'W': - return number + (number === 1 ? 're' : 'e'); - } - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); - - //! moment.js locale configuration - - hooks.defineLocale('fr', { - months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'), - monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'), - monthsParseExact : true, - weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'), - weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'), - weekdaysMin : 'di_lu_ma_me_je_ve_sa'.split('_'), - weekdaysParseExact : true, - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd D MMMM YYYY HH:mm' - }, - calendar : { - sameDay : '[Aujourd’hui à] LT', - nextDay : '[Demain à] LT', - nextWeek : 'dddd [à] LT', - lastDay : '[Hier à] LT', - lastWeek : 'dddd [dernier à] LT', - sameElse : 'L' - }, - relativeTime : { - future : 'dans %s', - past : 'il y a %s', - s : 'quelques secondes', - ss : '%d secondes', - m : 'une minute', - mm : '%d minutes', - h : 'une heure', - hh : '%d heures', - d : 'un jour', - dd : '%d jours', - M : 'un mois', - MM : '%d mois', - y : 'un an', - yy : '%d ans' - }, - dayOfMonthOrdinalParse: /\d{1,2}(er|)/, - ordinal : function (number, period) { - switch (period) { - // TODO: Return 'e' when day of month > 1. Move this case inside - // block for masculine words below. - // See https://github.com/moment/moment/issues/3375 - case 'D': - return number + (number === 1 ? 'er' : ''); - - // Words with masculine grammatical gender: mois, trimestre, jour - default: - case 'M': - case 'Q': - case 'DDD': - case 'd': - return number + (number === 1 ? 'er' : 'e'); - - // Words with feminine grammatical gender: semaine - case 'w': - case 'W': - return number + (number === 1 ? 're' : 'e'); - } - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); - - //! moment.js locale configuration - - var monthsShortWithDots = 'jan._feb._mrt._apr._mai_jun._jul._aug._sep._okt._nov._des.'.split('_'), - monthsShortWithoutDots = 'jan_feb_mrt_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'); - - hooks.defineLocale('fy', { - months : 'jannewaris_febrewaris_maart_april_maaie_juny_july_augustus_septimber_oktober_novimber_desimber'.split('_'), - monthsShort : function (m, format) { - if (!m) { - return monthsShortWithDots; - } else if (/-MMM-/.test(format)) { - return monthsShortWithoutDots[m.month()]; - } else { - return monthsShortWithDots[m.month()]; - } - }, - monthsParseExact : true, - weekdays : 'snein_moandei_tiisdei_woansdei_tongersdei_freed_sneon'.split('_'), - weekdaysShort : 'si._mo._ti._wo._to._fr._so.'.split('_'), - weekdaysMin : 'Si_Mo_Ti_Wo_To_Fr_So'.split('_'), - weekdaysParseExact : true, - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD-MM-YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd D MMMM YYYY HH:mm' - }, - calendar : { - sameDay: '[hjoed om] LT', - nextDay: '[moarn om] LT', - nextWeek: 'dddd [om] LT', - lastDay: '[juster om] LT', - lastWeek: '[ôfrûne] dddd [om] LT', - sameElse: 'L' - }, - relativeTime : { - future : 'oer %s', - past : '%s lyn', - s : 'in pear sekonden', - ss : '%d sekonden', - m : 'ien minút', - mm : '%d minuten', - h : 'ien oere', - hh : '%d oeren', - d : 'ien dei', - dd : '%d dagen', - M : 'ien moanne', - MM : '%d moannen', - y : 'ien jier', - yy : '%d jierren' - }, - dayOfMonthOrdinalParse: /\d{1,2}(ste|de)/, - ordinal : function (number) { - return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de'); - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); - - //! moment.js locale configuration - - var months$5 = [ - 'Am Faoilleach', 'An Gearran', 'Am Màrt', 'An Giblean', 'An Cèitean', 'An t-Ògmhios', 'An t-Iuchar', 'An Lùnastal', 'An t-Sultain', 'An Dàmhair', 'An t-Samhain', 'An Dùbhlachd' - ]; - - var monthsShort$4 = ['Faoi', 'Gear', 'Màrt', 'Gibl', 'Cèit', 'Ògmh', 'Iuch', 'Lùn', 'Sult', 'Dàmh', 'Samh', 'Dùbh']; - - var weekdays$1 = ['Didòmhnaich', 'Diluain', 'Dimàirt', 'Diciadain', 'Diardaoin', 'Dihaoine', 'Disathairne']; - - var weekdaysShort = ['Did', 'Dil', 'Dim', 'Dic', 'Dia', 'Dih', 'Dis']; - - var weekdaysMin = ['Dò', 'Lu', 'Mà', 'Ci', 'Ar', 'Ha', 'Sa']; - - hooks.defineLocale('gd', { - months : months$5, - monthsShort : monthsShort$4, - monthsParseExact : true, - weekdays : weekdays$1, - weekdaysShort : weekdaysShort, - weekdaysMin : weekdaysMin, - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd, D MMMM YYYY HH:mm' - }, - calendar : { - sameDay : '[An-diugh aig] LT', - nextDay : '[A-màireach aig] LT', - nextWeek : 'dddd [aig] LT', - lastDay : '[An-dè aig] LT', - lastWeek : 'dddd [seo chaidh] [aig] LT', - sameElse : 'L' - }, - relativeTime : { - future : 'ann an %s', - past : 'bho chionn %s', - s : 'beagan diogan', - ss : '%d diogan', - m : 'mionaid', - mm : '%d mionaidean', - h : 'uair', - hh : '%d uairean', - d : 'latha', - dd : '%d latha', - M : 'mìos', - MM : '%d mìosan', - y : 'bliadhna', - yy : '%d bliadhna' - }, - dayOfMonthOrdinalParse : /\d{1,2}(d|na|mh)/, - ordinal : function (number) { - var output = number === 1 ? 'd' : number % 10 === 2 ? 'na' : 'mh'; - return number + output; - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); - - //! moment.js locale configuration - - hooks.defineLocale('gl', { - months : 'xaneiro_febreiro_marzo_abril_maio_xuño_xullo_agosto_setembro_outubro_novembro_decembro'.split('_'), - monthsShort : 'xan._feb._mar._abr._mai._xuñ._xul._ago._set._out._nov._dec.'.split('_'), - monthsParseExact: true, - weekdays : 'domingo_luns_martes_mércores_xoves_venres_sábado'.split('_'), - weekdaysShort : 'dom._lun._mar._mér._xov._ven._sáb.'.split('_'), - weekdaysMin : 'do_lu_ma_mé_xo_ve_sá'.split('_'), - weekdaysParseExact : true, - longDateFormat : { - LT : 'H:mm', - LTS : 'H:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D [de] MMMM [de] YYYY', - LLL : 'D [de] MMMM [de] YYYY H:mm', - LLLL : 'dddd, D [de] MMMM [de] YYYY H:mm' - }, - calendar : { - sameDay : function () { - return '[hoxe ' + ((this.hours() !== 1) ? 'ás' : 'á') + '] LT'; - }, - nextDay : function () { - return '[mañá ' + ((this.hours() !== 1) ? 'ás' : 'á') + '] LT'; - }, - nextWeek : function () { - return 'dddd [' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT'; - }, - lastDay : function () { - return '[onte ' + ((this.hours() !== 1) ? 'á' : 'a') + '] LT'; - }, - lastWeek : function () { - return '[o] dddd [pasado ' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT'; - }, - sameElse : 'L' - }, - relativeTime : { - future : function (str) { - if (str.indexOf('un') === 0) { - return 'n' + str; - } - return 'en ' + str; - }, - past : 'hai %s', - s : 'uns segundos', - ss : '%d segundos', - m : 'un minuto', - mm : '%d minutos', - h : 'unha hora', - hh : '%d horas', - d : 'un día', - dd : '%d días', - M : 'un mes', - MM : '%d meses', - y : 'un ano', - yy : '%d anos' - }, - dayOfMonthOrdinalParse : /\d{1,2}º/, - ordinal : '%dº', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); - - //! moment.js locale configuration - - function processRelativeTime$4(number, withoutSuffix, key, isFuture) { - var format = { - 's': ['thodde secondanim', 'thodde second'], - 'ss': [number + ' secondanim', number + ' second'], - 'm': ['eka mintan', 'ek minute'], - 'mm': [number + ' mintanim', number + ' mintam'], - 'h': ['eka horan', 'ek hor'], - 'hh': [number + ' horanim', number + ' horam'], - 'd': ['eka disan', 'ek dis'], - 'dd': [number + ' disanim', number + ' dis'], - 'M': ['eka mhoinean', 'ek mhoino'], - 'MM': [number + ' mhoineanim', number + ' mhoine'], - 'y': ['eka vorsan', 'ek voros'], - 'yy': [number + ' vorsanim', number + ' vorsam'] - }; - return withoutSuffix ? format[key][0] : format[key][1]; - } - - hooks.defineLocale('gom-latn', { - months : 'Janer_Febrer_Mars_Abril_Mai_Jun_Julai_Agost_Setembr_Otubr_Novembr_Dezembr'.split('_'), - monthsShort : 'Jan._Feb._Mars_Abr._Mai_Jun_Jul._Ago._Set._Otu._Nov._Dez.'.split('_'), - monthsParseExact : true, - weekdays : 'Aitar_Somar_Mongllar_Budvar_Brestar_Sukrar_Son\'var'.split('_'), - weekdaysShort : 'Ait._Som._Mon._Bud._Bre._Suk._Son.'.split('_'), - weekdaysMin : 'Ai_Sm_Mo_Bu_Br_Su_Sn'.split('_'), - weekdaysParseExact : true, - longDateFormat : { - LT : 'A h:mm [vazta]', - LTS : 'A h:mm:ss [vazta]', - L : 'DD-MM-YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY A h:mm [vazta]', - LLLL : 'dddd, MMMM[achea] Do, YYYY, A h:mm [vazta]', - llll: 'ddd, D MMM YYYY, A h:mm [vazta]' - }, - calendar : { - sameDay: '[Aiz] LT', - nextDay: '[Faleam] LT', - nextWeek: '[Ieta to] dddd[,] LT', - lastDay: '[Kal] LT', - lastWeek: '[Fatlo] dddd[,] LT', - sameElse: 'L' - }, - relativeTime : { - future : '%s', - past : '%s adim', - s : processRelativeTime$4, - ss : processRelativeTime$4, - m : processRelativeTime$4, - mm : processRelativeTime$4, - h : processRelativeTime$4, - hh : processRelativeTime$4, - d : processRelativeTime$4, - dd : processRelativeTime$4, - M : processRelativeTime$4, - MM : processRelativeTime$4, - y : processRelativeTime$4, - yy : processRelativeTime$4 - }, - dayOfMonthOrdinalParse : /\d{1,2}(er)/, - ordinal : function (number, period) { - switch (period) { - // the ordinal 'er' only applies to day of the month - case 'D': - return number + 'er'; - default: - case 'M': - case 'Q': - case 'DDD': - case 'd': - case 'w': - case 'W': - return number; - } - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - }, - meridiemParse: /rati|sokalli|donparam|sanje/, - meridiemHour : function (hour, meridiem) { - if (hour === 12) { - hour = 0; - } - if (meridiem === 'rati') { - return hour < 4 ? hour : hour + 12; - } else if (meridiem === 'sokalli') { - return hour; - } else if (meridiem === 'donparam') { - return hour > 12 ? hour : hour + 12; - } else if (meridiem === 'sanje') { - return hour + 12; - } - }, - meridiem : function (hour, minute, isLower) { - if (hour < 4) { - return 'rati'; - } else if (hour < 12) { - return 'sokalli'; - } else if (hour < 16) { - return 'donparam'; - } else if (hour < 20) { - return 'sanje'; - } else { - return 'rati'; - } - } - }); - - //! moment.js locale configuration - - var symbolMap$6 = { - '1': '૧', - '2': '૨', - '3': '૩', - '4': '૪', - '5': '૫', - '6': '૬', - '7': '૭', - '8': '૮', - '9': '૯', - '0': '૦' - }, - numberMap$5 = { - '૧': '1', - '૨': '2', - '૩': '3', - '૪': '4', - '૫': '5', - '૬': '6', - '૭': '7', - '૮': '8', - '૯': '9', - '૦': '0' - }; - - hooks.defineLocale('gu', { - months: 'જાન્યુઆરી_ફેબ્રુઆરી_માર્ચ_એપ્રિલ_મે_જૂન_જુલાઈ_ઑગસ્ટ_સપ્ટેમ્બર_ઑક્ટ્બર_નવેમ્બર_ડિસેમ્બર'.split('_'), - monthsShort: 'જાન્યુ._ફેબ્રુ._માર્ચ_એપ્રિ._મે_જૂન_જુલા._ઑગ._સપ્ટે._ઑક્ટ્._નવે._ડિસે.'.split('_'), - monthsParseExact: true, - weekdays: 'રવિવાર_સોમવાર_મંગળવાર_બુધ્વાર_ગુરુવાર_શુક્રવાર_શનિવાર'.split('_'), - weekdaysShort: 'રવિ_સોમ_મંગળ_બુધ્_ગુરુ_શુક્ર_શનિ'.split('_'), - weekdaysMin: 'ર_સો_મં_બુ_ગુ_શુ_શ'.split('_'), - longDateFormat: { - LT: 'A h:mm વાગ્યે', - LTS: 'A h:mm:ss વાગ્યે', - L: 'DD/MM/YYYY', - LL: 'D MMMM YYYY', - LLL: 'D MMMM YYYY, A h:mm વાગ્યે', - LLLL: 'dddd, D MMMM YYYY, A h:mm વાગ્યે' - }, - calendar: { - sameDay: '[આજ] LT', - nextDay: '[કાલે] LT', - nextWeek: 'dddd, LT', - lastDay: '[ગઇકાલે] LT', - lastWeek: '[પાછલા] dddd, LT', - sameElse: 'L' - }, - relativeTime: { - future: '%s મા', - past: '%s પેહલા', - s: 'અમુક પળો', - ss: '%d સેકંડ', - m: 'એક મિનિટ', - mm: '%d મિનિટ', - h: 'એક કલાક', - hh: '%d કલાક', - d: 'એક દિવસ', - dd: '%d દિવસ', - M: 'એક મહિનો', - MM: '%d મહિનો', - y: 'એક વર્ષ', - yy: '%d વર્ષ' - }, - preparse: function (string) { - return string.replace(/[૧૨૩૪૫૬૭૮૯૦]/g, function (match) { - return numberMap$5[match]; - }); - }, - postformat: function (string) { - return string.replace(/\d/g, function (match) { - return symbolMap$6[match]; - }); - }, - // Gujarati notation for meridiems are quite fuzzy in practice. While there exists - // a rigid notion of a 'Pahar' it is not used as rigidly in modern Gujarati. - meridiemParse: /રાત|બપોર|સવાર|સાંજ/, - meridiemHour: function (hour, meridiem) { - if (hour === 12) { - hour = 0; - } - if (meridiem === 'રાત') { - return hour < 4 ? hour : hour + 12; - } else if (meridiem === 'સવાર') { - return hour; - } else if (meridiem === 'બપોર') { - return hour >= 10 ? hour : hour + 12; - } else if (meridiem === 'સાંજ') { - return hour + 12; - } - }, - meridiem: function (hour, minute, isLower) { - if (hour < 4) { - return 'રાત'; - } else if (hour < 10) { - return 'સવાર'; - } else if (hour < 17) { - return 'બપોર'; - } else if (hour < 20) { - return 'સાંજ'; - } else { - return 'રાત'; - } - }, - week: { - dow: 0, // Sunday is the first day of the week. - doy: 6 // The week that contains Jan 6th is the first week of the year. - } - }); - - //! moment.js locale configuration - - hooks.defineLocale('he', { - months : 'ינואר_פברואר_מרץ_אפריל_מאי_יוני_יולי_אוגוסט_ספטמבר_אוקטובר_נובמבר_דצמבר'.split('_'), - monthsShort : 'ינו׳_פבר׳_מרץ_אפר׳_מאי_יוני_יולי_אוג׳_ספט׳_אוק׳_נוב׳_דצמ׳'.split('_'), - weekdays : 'ראשון_שני_שלישי_רביעי_חמישי_שישי_שבת'.split('_'), - weekdaysShort : 'א׳_ב׳_ג׳_ד׳_ה׳_ו׳_ש׳'.split('_'), - weekdaysMin : 'א_ב_ג_ד_ה_ו_ש'.split('_'), - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D [ב]MMMM YYYY', - LLL : 'D [ב]MMMM YYYY HH:mm', - LLLL : 'dddd, D [ב]MMMM YYYY HH:mm', - l : 'D/M/YYYY', - ll : 'D MMM YYYY', - lll : 'D MMM YYYY HH:mm', - llll : 'ddd, D MMM YYYY HH:mm' - }, - calendar : { - sameDay : '[היום ב־]LT', - nextDay : '[מחר ב־]LT', - nextWeek : 'dddd [בשעה] LT', - lastDay : '[אתמול ב־]LT', - lastWeek : '[ביום] dddd [האחרון בשעה] LT', - sameElse : 'L' - }, - relativeTime : { - future : 'בעוד %s', - past : 'לפני %s', - s : 'מספר שניות', - ss : '%d שניות', - m : 'דקה', - mm : '%d דקות', - h : 'שעה', - hh : function (number) { - if (number === 2) { - return 'שעתיים'; - } - return number + ' שעות'; - }, - d : 'יום', - dd : function (number) { - if (number === 2) { - return 'יומיים'; - } - return number + ' ימים'; - }, - M : 'חודש', - MM : function (number) { - if (number === 2) { - return 'חודשיים'; - } - return number + ' חודשים'; - }, - y : 'שנה', - yy : function (number) { - if (number === 2) { - return 'שנתיים'; - } else if (number % 10 === 0 && number !== 10) { - return number + ' שנה'; - } - return number + ' שנים'; - } - }, - meridiemParse: /אחה"צ|לפנה"צ|אחרי הצהריים|לפני הצהריים|לפנות בוקר|בבוקר|בערב/i, - isPM : function (input) { - return /^(אחה"צ|אחרי הצהריים|בערב)$/.test(input); - }, - meridiem : function (hour, minute, isLower) { - if (hour < 5) { - return 'לפנות בוקר'; - } else if (hour < 10) { - return 'בבוקר'; - } else if (hour < 12) { - return isLower ? 'לפנה"צ' : 'לפני הצהריים'; - } else if (hour < 18) { - return isLower ? 'אחה"צ' : 'אחרי הצהריים'; - } else { - return 'בערב'; - } - } - }); - - //! moment.js locale configuration - - var symbolMap$7 = { - '1': '१', - '2': '२', - '3': '३', - '4': '४', - '5': '५', - '6': '६', - '7': '७', - '8': '८', - '9': '९', - '0': '०' - }, - numberMap$6 = { - '१': '1', - '२': '2', - '३': '3', - '४': '4', - '५': '5', - '६': '6', - '७': '7', - '८': '8', - '९': '9', - '०': '0' - }; - - hooks.defineLocale('hi', { - months : 'जनवरी_फ़रवरी_मार्च_अप्रैल_मई_जून_जुलाई_अगस्त_सितम्बर_अक्टूबर_नवम्बर_दिसम्बर'.split('_'), - monthsShort : 'जन._फ़र._मार्च_अप्रै._मई_जून_जुल._अग._सित._अक्टू._नव._दिस.'.split('_'), - monthsParseExact: true, - weekdays : 'रविवार_सोमवार_मंगलवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split('_'), - weekdaysShort : 'रवि_सोम_मंगल_बुध_गुरू_शुक्र_शनि'.split('_'), - weekdaysMin : 'र_सो_मं_बु_गु_शु_श'.split('_'), - longDateFormat : { - LT : 'A h:mm बजे', - LTS : 'A h:mm:ss बजे', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY, A h:mm बजे', - LLLL : 'dddd, D MMMM YYYY, A h:mm बजे' - }, - calendar : { - sameDay : '[आज] LT', - nextDay : '[कल] LT', - nextWeek : 'dddd, LT', - lastDay : '[कल] LT', - lastWeek : '[पिछले] dddd, LT', - sameElse : 'L' - }, - relativeTime : { - future : '%s में', - past : '%s पहले', - s : 'कुछ ही क्षण', - ss : '%d सेकंड', - m : 'एक मिनट', - mm : '%d मिनट', - h : 'एक घंटा', - hh : '%d घंटे', - d : 'एक दिन', - dd : '%d दिन', - M : 'एक महीने', - MM : '%d महीने', - y : 'एक वर्ष', - yy : '%d वर्ष' - }, - preparse: function (string) { - return string.replace(/[१२३४५६७८९०]/g, function (match) { - return numberMap$6[match]; - }); - }, - postformat: function (string) { - return string.replace(/\d/g, function (match) { - return symbolMap$7[match]; - }); - }, - // Hindi notation for meridiems are quite fuzzy in practice. While there exists - // a rigid notion of a 'Pahar' it is not used as rigidly in modern Hindi. - meridiemParse: /रात|सुबह|दोपहर|शाम/, - meridiemHour : function (hour, meridiem) { - if (hour === 12) { - hour = 0; - } - if (meridiem === 'रात') { - return hour < 4 ? hour : hour + 12; - } else if (meridiem === 'सुबह') { - return hour; - } else if (meridiem === 'दोपहर') { - return hour >= 10 ? hour : hour + 12; - } else if (meridiem === 'शाम') { - return hour + 12; - } - }, - meridiem : function (hour, minute, isLower) { - if (hour < 4) { - return 'रात'; - } else if (hour < 10) { - return 'सुबह'; - } else if (hour < 17) { - return 'दोपहर'; - } else if (hour < 20) { - return 'शाम'; - } else { - return 'रात'; - } - }, - week : { - dow : 0, // Sunday is the first day of the week. - doy : 6 // The week that contains Jan 6th is the first week of the year. - } - }); - - //! moment.js locale configuration - - function translate$3(number, withoutSuffix, key) { - var result = number + ' '; - switch (key) { - case 'ss': - if (number === 1) { - result += 'sekunda'; - } else if (number === 2 || number === 3 || number === 4) { - result += 'sekunde'; - } else { - result += 'sekundi'; - } - return result; - case 'm': - return withoutSuffix ? 'jedna minuta' : 'jedne minute'; - case 'mm': - if (number === 1) { - result += 'minuta'; - } else if (number === 2 || number === 3 || number === 4) { - result += 'minute'; - } else { - result += 'minuta'; - } - return result; - case 'h': - return withoutSuffix ? 'jedan sat' : 'jednog sata'; - case 'hh': - if (number === 1) { - result += 'sat'; - } else if (number === 2 || number === 3 || number === 4) { - result += 'sata'; - } else { - result += 'sati'; - } - return result; - case 'dd': - if (number === 1) { - result += 'dan'; - } else { - result += 'dana'; - } - return result; - case 'MM': - if (number === 1) { - result += 'mjesec'; - } else if (number === 2 || number === 3 || number === 4) { - result += 'mjeseca'; - } else { - result += 'mjeseci'; - } - return result; - case 'yy': - if (number === 1) { - result += 'godina'; - } else if (number === 2 || number === 3 || number === 4) { - result += 'godine'; - } else { - result += 'godina'; - } - return result; - } - } - - hooks.defineLocale('hr', { - months : { - format: 'siječnja_veljače_ožujka_travnja_svibnja_lipnja_srpnja_kolovoza_rujna_listopada_studenoga_prosinca'.split('_'), - standalone: 'siječanj_veljača_ožujak_travanj_svibanj_lipanj_srpanj_kolovoz_rujan_listopad_studeni_prosinac'.split('_') - }, - monthsShort : 'sij._velj._ožu._tra._svi._lip._srp._kol._ruj._lis._stu._pro.'.split('_'), - monthsParseExact: true, - weekdays : 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'), - weekdaysShort : 'ned._pon._uto._sri._čet._pet._sub.'.split('_'), - weekdaysMin : 'ne_po_ut_sr_če_pe_su'.split('_'), - weekdaysParseExact : true, - longDateFormat : { - LT : 'H:mm', - LTS : 'H:mm:ss', - L : 'DD.MM.YYYY', - LL : 'D. MMMM YYYY', - LLL : 'D. MMMM YYYY H:mm', - LLLL : 'dddd, D. MMMM YYYY H:mm' - }, - calendar : { - sameDay : '[danas u] LT', - nextDay : '[sutra u] LT', - nextWeek : function () { - switch (this.day()) { - case 0: - return '[u] [nedjelju] [u] LT'; - case 3: - return '[u] [srijedu] [u] LT'; - case 6: - return '[u] [subotu] [u] LT'; - case 1: - case 2: - case 4: - case 5: - return '[u] dddd [u] LT'; - } - }, - lastDay : '[jučer u] LT', - lastWeek : function () { - switch (this.day()) { - case 0: - case 3: - return '[prošlu] dddd [u] LT'; - case 6: - return '[prošle] [subote] [u] LT'; - case 1: - case 2: - case 4: - case 5: - return '[prošli] dddd [u] LT'; - } - }, - sameElse : 'L' - }, - relativeTime : { - future : 'za %s', - past : 'prije %s', - s : 'par sekundi', - ss : translate$3, - m : translate$3, - mm : translate$3, - h : translate$3, - hh : translate$3, - d : 'dan', - dd : translate$3, - M : 'mjesec', - MM : translate$3, - y : 'godinu', - yy : translate$3 - }, - dayOfMonthOrdinalParse: /\d{1,2}\./, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 7th is the first week of the year. - } - }); - - //! moment.js locale configuration - - var weekEndings = 'vasárnap hétfőn kedden szerdán csütörtökön pénteken szombaton'.split(' '); - function translate$4(number, withoutSuffix, key, isFuture) { - var num = number; - switch (key) { - case 's': - return (isFuture || withoutSuffix) ? 'néhány másodperc' : 'néhány másodperce'; - case 'ss': - return num + (isFuture || withoutSuffix) ? ' másodperc' : ' másodperce'; - case 'm': - return 'egy' + (isFuture || withoutSuffix ? ' perc' : ' perce'); - case 'mm': - return num + (isFuture || withoutSuffix ? ' perc' : ' perce'); - case 'h': - return 'egy' + (isFuture || withoutSuffix ? ' óra' : ' órája'); - case 'hh': - return num + (isFuture || withoutSuffix ? ' óra' : ' órája'); - case 'd': - return 'egy' + (isFuture || withoutSuffix ? ' nap' : ' napja'); - case 'dd': - return num + (isFuture || withoutSuffix ? ' nap' : ' napja'); - case 'M': - return 'egy' + (isFuture || withoutSuffix ? ' hónap' : ' hónapja'); - case 'MM': - return num + (isFuture || withoutSuffix ? ' hónap' : ' hónapja'); - case 'y': - return 'egy' + (isFuture || withoutSuffix ? ' év' : ' éve'); - case 'yy': - return num + (isFuture || withoutSuffix ? ' év' : ' éve'); - } - return ''; - } - function week(isFuture) { - return (isFuture ? '' : '[múlt] ') + '[' + weekEndings[this.day()] + '] LT[-kor]'; - } - - hooks.defineLocale('hu', { - months : 'január_február_március_április_május_június_július_augusztus_szeptember_október_november_december'.split('_'), - monthsShort : 'jan_feb_márc_ápr_máj_jún_júl_aug_szept_okt_nov_dec'.split('_'), - weekdays : 'vasárnap_hétfő_kedd_szerda_csütörtök_péntek_szombat'.split('_'), - weekdaysShort : 'vas_hét_kedd_sze_csüt_pén_szo'.split('_'), - weekdaysMin : 'v_h_k_sze_cs_p_szo'.split('_'), - longDateFormat : { - LT : 'H:mm', - LTS : 'H:mm:ss', - L : 'YYYY.MM.DD.', - LL : 'YYYY. MMMM D.', - LLL : 'YYYY. MMMM D. H:mm', - LLLL : 'YYYY. MMMM D., dddd H:mm' - }, - meridiemParse: /de|du/i, - isPM: function (input) { - return input.charAt(1).toLowerCase() === 'u'; - }, - meridiem : function (hours, minutes, isLower) { - if (hours < 12) { - return isLower === true ? 'de' : 'DE'; - } else { - return isLower === true ? 'du' : 'DU'; - } - }, - calendar : { - sameDay : '[ma] LT[-kor]', - nextDay : '[holnap] LT[-kor]', - nextWeek : function () { - return week.call(this, true); - }, - lastDay : '[tegnap] LT[-kor]', - lastWeek : function () { - return week.call(this, false); - }, - sameElse : 'L' - }, - relativeTime : { - future : '%s múlva', - past : '%s', - s : translate$4, - ss : translate$4, - m : translate$4, - mm : translate$4, - h : translate$4, - hh : translate$4, - d : translate$4, - dd : translate$4, - M : translate$4, - MM : translate$4, - y : translate$4, - yy : translate$4 - }, - dayOfMonthOrdinalParse: /\d{1,2}\./, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); - - //! moment.js locale configuration - - hooks.defineLocale('hy-am', { - months : { - format: 'հունվարի_փետրվարի_մարտի_ապրիլի_մայիսի_հունիսի_հուլիսի_օգոստոսի_սեպտեմբերի_հոկտեմբերի_նոյեմբերի_դեկտեմբերի'.split('_'), - standalone: 'հունվար_փետրվար_մարտ_ապրիլ_մայիս_հունիս_հուլիս_օգոստոս_սեպտեմբեր_հոկտեմբեր_նոյեմբեր_դեկտեմբեր'.split('_') - }, - monthsShort : 'հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ'.split('_'), - weekdays : 'կիրակի_երկուշաբթի_երեքշաբթի_չորեքշաբթի_հինգշաբթի_ուրբաթ_շաբաթ'.split('_'), - weekdaysShort : 'կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ'.split('_'), - weekdaysMin : 'կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ'.split('_'), - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD.MM.YYYY', - LL : 'D MMMM YYYY թ.', - LLL : 'D MMMM YYYY թ., HH:mm', - LLLL : 'dddd, D MMMM YYYY թ., HH:mm' - }, - calendar : { - sameDay: '[այսօր] LT', - nextDay: '[վաղը] LT', - lastDay: '[երեկ] LT', - nextWeek: function () { - return 'dddd [օրը ժամը] LT'; - }, - lastWeek: function () { - return '[անցած] dddd [օրը ժամը] LT'; - }, - sameElse: 'L' - }, - relativeTime : { - future : '%s հետո', - past : '%s առաջ', - s : 'մի քանի վայրկյան', - ss : '%d վայրկյան', - m : 'րոպե', - mm : '%d րոպե', - h : 'ժամ', - hh : '%d ժամ', - d : 'օր', - dd : '%d օր', - M : 'ամիս', - MM : '%d ամիս', - y : 'տարի', - yy : '%d տարի' - }, - meridiemParse: /գիշերվա|առավոտվա|ցերեկվա|երեկոյան/, - isPM: function (input) { - return /^(ցերեկվա|երեկոյան)$/.test(input); - }, - meridiem : function (hour) { - if (hour < 4) { - return 'գիշերվա'; - } else if (hour < 12) { - return 'առավոտվա'; - } else if (hour < 17) { - return 'ցերեկվա'; - } else { - return 'երեկոյան'; - } - }, - dayOfMonthOrdinalParse: /\d{1,2}|\d{1,2}-(ին|րդ)/, - ordinal: function (number, period) { - switch (period) { - case 'DDD': - case 'w': - case 'W': - case 'DDDo': - if (number === 1) { - return number + '-ին'; - } - return number + '-րդ'; - default: - return number; - } - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 7th is the first week of the year. - } - }); - - //! moment.js locale configuration - - hooks.defineLocale('id', { - months : 'Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_November_Desember'.split('_'), - monthsShort : 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Agt_Sep_Okt_Nov_Des'.split('_'), - weekdays : 'Minggu_Senin_Selasa_Rabu_Kamis_Jumat_Sabtu'.split('_'), - weekdaysShort : 'Min_Sen_Sel_Rab_Kam_Jum_Sab'.split('_'), - weekdaysMin : 'Mg_Sn_Sl_Rb_Km_Jm_Sb'.split('_'), - longDateFormat : { - LT : 'HH.mm', - LTS : 'HH.mm.ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY [pukul] HH.mm', - LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm' - }, - meridiemParse: /pagi|siang|sore|malam/, - meridiemHour : function (hour, meridiem) { - if (hour === 12) { - hour = 0; - } - if (meridiem === 'pagi') { - return hour; - } else if (meridiem === 'siang') { - return hour >= 11 ? hour : hour + 12; - } else if (meridiem === 'sore' || meridiem === 'malam') { - return hour + 12; - } - }, - meridiem : function (hours, minutes, isLower) { - if (hours < 11) { - return 'pagi'; - } else if (hours < 15) { - return 'siang'; - } else if (hours < 19) { - return 'sore'; - } else { - return 'malam'; - } - }, - calendar : { - sameDay : '[Hari ini pukul] LT', - nextDay : '[Besok pukul] LT', - nextWeek : 'dddd [pukul] LT', - lastDay : '[Kemarin pukul] LT', - lastWeek : 'dddd [lalu pukul] LT', - sameElse : 'L' - }, - relativeTime : { - future : 'dalam %s', - past : '%s yang lalu', - s : 'beberapa detik', - ss : '%d detik', - m : 'semenit', - mm : '%d menit', - h : 'sejam', - hh : '%d jam', - d : 'sehari', - dd : '%d hari', - M : 'sebulan', - MM : '%d bulan', - y : 'setahun', - yy : '%d tahun' - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 7th is the first week of the year. - } - }); - - //! moment.js locale configuration - - function plural$2(n) { - if (n % 100 === 11) { - return true; - } else if (n % 10 === 1) { - return false; - } - return true; - } - function translate$5(number, withoutSuffix, key, isFuture) { - var result = number + ' '; - switch (key) { - case 's': - return withoutSuffix || isFuture ? 'nokkrar sekúndur' : 'nokkrum sekúndum'; - case 'ss': - if (plural$2(number)) { - return result + (withoutSuffix || isFuture ? 'sekúndur' : 'sekúndum'); - } - return result + 'sekúnda'; - case 'm': - return withoutSuffix ? 'mínúta' : 'mínútu'; - case 'mm': - if (plural$2(number)) { - return result + (withoutSuffix || isFuture ? 'mínútur' : 'mínútum'); - } else if (withoutSuffix) { - return result + 'mínúta'; - } - return result + 'mínútu'; - case 'hh': - if (plural$2(number)) { - return result + (withoutSuffix || isFuture ? 'klukkustundir' : 'klukkustundum'); - } - return result + 'klukkustund'; - case 'd': - if (withoutSuffix) { - return 'dagur'; - } - return isFuture ? 'dag' : 'degi'; - case 'dd': - if (plural$2(number)) { - if (withoutSuffix) { - return result + 'dagar'; - } - return result + (isFuture ? 'daga' : 'dögum'); - } else if (withoutSuffix) { - return result + 'dagur'; - } - return result + (isFuture ? 'dag' : 'degi'); - case 'M': - if (withoutSuffix) { - return 'mánuður'; - } - return isFuture ? 'mánuð' : 'mánuði'; - case 'MM': - if (plural$2(number)) { - if (withoutSuffix) { - return result + 'mánuðir'; - } - return result + (isFuture ? 'mánuði' : 'mánuðum'); - } else if (withoutSuffix) { - return result + 'mánuður'; - } - return result + (isFuture ? 'mánuð' : 'mánuði'); - case 'y': - return withoutSuffix || isFuture ? 'ár' : 'ári'; - case 'yy': - if (plural$2(number)) { - return result + (withoutSuffix || isFuture ? 'ár' : 'árum'); - } - return result + (withoutSuffix || isFuture ? 'ár' : 'ári'); - } - } - - hooks.defineLocale('is', { - months : 'janúar_febrúar_mars_apríl_maí_júní_júlí_ágúst_september_október_nóvember_desember'.split('_'), - monthsShort : 'jan_feb_mar_apr_maí_jún_júl_ágú_sep_okt_nóv_des'.split('_'), - weekdays : 'sunnudagur_mánudagur_þriðjudagur_miðvikudagur_fimmtudagur_föstudagur_laugardagur'.split('_'), - weekdaysShort : 'sun_mán_þri_mið_fim_fös_lau'.split('_'), - weekdaysMin : 'Su_Má_Þr_Mi_Fi_Fö_La'.split('_'), - longDateFormat : { - LT : 'H:mm', - LTS : 'H:mm:ss', - L : 'DD.MM.YYYY', - LL : 'D. MMMM YYYY', - LLL : 'D. MMMM YYYY [kl.] H:mm', - LLLL : 'dddd, D. MMMM YYYY [kl.] H:mm' - }, - calendar : { - sameDay : '[í dag kl.] LT', - nextDay : '[á morgun kl.] LT', - nextWeek : 'dddd [kl.] LT', - lastDay : '[í gær kl.] LT', - lastWeek : '[síðasta] dddd [kl.] LT', - sameElse : 'L' - }, - relativeTime : { - future : 'eftir %s', - past : 'fyrir %s síðan', - s : translate$5, - ss : translate$5, - m : translate$5, - mm : translate$5, - h : 'klukkustund', - hh : translate$5, - d : translate$5, - dd : translate$5, - M : translate$5, - MM : translate$5, - y : translate$5, - yy : translate$5 - }, - dayOfMonthOrdinalParse: /\d{1,2}\./, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); - - //! moment.js locale configuration - - hooks.defineLocale('it', { - months : 'gennaio_febbraio_marzo_aprile_maggio_giugno_luglio_agosto_settembre_ottobre_novembre_dicembre'.split('_'), - monthsShort : 'gen_feb_mar_apr_mag_giu_lug_ago_set_ott_nov_dic'.split('_'), - weekdays : 'domenica_lunedì_martedì_mercoledì_giovedì_venerdì_sabato'.split('_'), - weekdaysShort : 'dom_lun_mar_mer_gio_ven_sab'.split('_'), - weekdaysMin : 'do_lu_ma_me_gi_ve_sa'.split('_'), - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd D MMMM YYYY HH:mm' - }, - calendar : { - sameDay: '[Oggi alle] LT', - nextDay: '[Domani alle] LT', - nextWeek: 'dddd [alle] LT', - lastDay: '[Ieri alle] LT', - lastWeek: function () { - switch (this.day()) { - case 0: - return '[la scorsa] dddd [alle] LT'; - default: - return '[lo scorso] dddd [alle] LT'; - } - }, - sameElse: 'L' - }, - relativeTime : { - future : function (s) { - return ((/^[0-9].+$/).test(s) ? 'tra' : 'in') + ' ' + s; - }, - past : '%s fa', - s : 'alcuni secondi', - ss : '%d secondi', - m : 'un minuto', - mm : '%d minuti', - h : 'un\'ora', - hh : '%d ore', - d : 'un giorno', - dd : '%d giorni', - M : 'un mese', - MM : '%d mesi', - y : 'un anno', - yy : '%d anni' - }, - dayOfMonthOrdinalParse : /\d{1,2}º/, - ordinal: '%dº', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); - - //! moment.js locale configuration - - hooks.defineLocale('ja', { - months : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'), - monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'), - weekdays : '日曜日_月曜日_火曜日_水曜日_木曜日_金曜日_土曜日'.split('_'), - weekdaysShort : '日_月_火_水_木_金_土'.split('_'), - weekdaysMin : '日_月_火_水_木_金_土'.split('_'), - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'YYYY/MM/DD', - LL : 'YYYY年M月D日', - LLL : 'YYYY年M月D日 HH:mm', - LLLL : 'YYYY年M月D日 dddd HH:mm', - l : 'YYYY/MM/DD', - ll : 'YYYY年M月D日', - lll : 'YYYY年M月D日 HH:mm', - llll : 'YYYY年M月D日(ddd) HH:mm' - }, - meridiemParse: /午前|午後/i, - isPM : function (input) { - return input === '午後'; - }, - meridiem : function (hour, minute, isLower) { - if (hour < 12) { - return '午前'; - } else { - return '午後'; - } - }, - calendar : { - sameDay : '[今日] LT', - nextDay : '[明日] LT', - nextWeek : function (now) { - if (now.week() < this.week()) { - return '[来週]dddd LT'; - } else { - return 'dddd LT'; - } - }, - lastDay : '[昨日] LT', - lastWeek : function (now) { - if (this.week() < now.week()) { - return '[先週]dddd LT'; - } else { - return 'dddd LT'; - } - }, - sameElse : 'L' - }, - dayOfMonthOrdinalParse : /\d{1,2}日/, - ordinal : function (number, period) { - switch (period) { - case 'd': - case 'D': - case 'DDD': - return number + '日'; - default: - return number; - } - }, - relativeTime : { - future : '%s後', - past : '%s前', - s : '数秒', - ss : '%d秒', - m : '1分', - mm : '%d分', - h : '1時間', - hh : '%d時間', - d : '1日', - dd : '%d日', - M : '1ヶ月', - MM : '%dヶ月', - y : '1年', - yy : '%d年' - } - }); - - //! moment.js locale configuration - - hooks.defineLocale('jv', { - months : 'Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_Nopember_Desember'.split('_'), - monthsShort : 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Ags_Sep_Okt_Nop_Des'.split('_'), - weekdays : 'Minggu_Senen_Seloso_Rebu_Kemis_Jemuwah_Septu'.split('_'), - weekdaysShort : 'Min_Sen_Sel_Reb_Kem_Jem_Sep'.split('_'), - weekdaysMin : 'Mg_Sn_Sl_Rb_Km_Jm_Sp'.split('_'), - longDateFormat : { - LT : 'HH.mm', - LTS : 'HH.mm.ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY [pukul] HH.mm', - LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm' - }, - meridiemParse: /enjing|siyang|sonten|ndalu/, - meridiemHour : function (hour, meridiem) { - if (hour === 12) { - hour = 0; - } - if (meridiem === 'enjing') { - return hour; - } else if (meridiem === 'siyang') { - return hour >= 11 ? hour : hour + 12; - } else if (meridiem === 'sonten' || meridiem === 'ndalu') { - return hour + 12; - } - }, - meridiem : function (hours, minutes, isLower) { - if (hours < 11) { - return 'enjing'; - } else if (hours < 15) { - return 'siyang'; - } else if (hours < 19) { - return 'sonten'; - } else { - return 'ndalu'; - } - }, - calendar : { - sameDay : '[Dinten puniko pukul] LT', - nextDay : '[Mbenjang pukul] LT', - nextWeek : 'dddd [pukul] LT', - lastDay : '[Kala wingi pukul] LT', - lastWeek : 'dddd [kepengker pukul] LT', - sameElse : 'L' - }, - relativeTime : { - future : 'wonten ing %s', - past : '%s ingkang kepengker', - s : 'sawetawis detik', - ss : '%d detik', - m : 'setunggal menit', - mm : '%d menit', - h : 'setunggal jam', - hh : '%d jam', - d : 'sedinten', - dd : '%d dinten', - M : 'sewulan', - MM : '%d wulan', - y : 'setaun', - yy : '%d taun' - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 7th is the first week of the year. - } - }); - - //! moment.js locale configuration - - hooks.defineLocale('ka', { - months : { - standalone: 'იანვარი_თებერვალი_მარტი_აპრილი_მაისი_ივნისი_ივლისი_აგვისტო_სექტემბერი_ოქტომბერი_ნოემბერი_დეკემბერი'.split('_'), - format: 'იანვარს_თებერვალს_მარტს_აპრილის_მაისს_ივნისს_ივლისს_აგვისტს_სექტემბერს_ოქტომბერს_ნოემბერს_დეკემბერს'.split('_') - }, - monthsShort : 'იან_თებ_მარ_აპრ_მაი_ივნ_ივლ_აგვ_სექ_ოქტ_ნოე_დეკ'.split('_'), - weekdays : { - standalone: 'კვირა_ორშაბათი_სამშაბათი_ოთხშაბათი_ხუთშაბათი_პარასკევი_შაბათი'.split('_'), - format: 'კვირას_ორშაბათს_სამშაბათს_ოთხშაბათს_ხუთშაბათს_პარასკევს_შაბათს'.split('_'), - isFormat: /(წინა|შემდეგ)/ - }, - weekdaysShort : 'კვი_ორშ_სამ_ოთხ_ხუთ_პარ_შაბ'.split('_'), - weekdaysMin : 'კვ_ორ_სა_ოთ_ხუ_პა_შა'.split('_'), - longDateFormat : { - LT : 'h:mm A', - LTS : 'h:mm:ss A', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY h:mm A', - LLLL : 'dddd, D MMMM YYYY h:mm A' - }, - calendar : { - sameDay : '[დღეს] LT[-ზე]', - nextDay : '[ხვალ] LT[-ზე]', - lastDay : '[გუშინ] LT[-ზე]', - nextWeek : '[შემდეგ] dddd LT[-ზე]', - lastWeek : '[წინა] dddd LT-ზე', - sameElse : 'L' - }, - relativeTime : { - future : function (s) { - return (/(წამი|წუთი|საათი|წელი)/).test(s) ? - s.replace(/ი$/, 'ში') : - s + 'ში'; - }, - past : function (s) { - if ((/(წამი|წუთი|საათი|დღე|თვე)/).test(s)) { - return s.replace(/(ი|ე)$/, 'ის წინ'); - } - if ((/წელი/).test(s)) { - return s.replace(/წელი$/, 'წლის წინ'); - } - }, - s : 'რამდენიმე წამი', - ss : '%d წამი', - m : 'წუთი', - mm : '%d წუთი', - h : 'საათი', - hh : '%d საათი', - d : 'დღე', - dd : '%d დღე', - M : 'თვე', - MM : '%d თვე', - y : 'წელი', - yy : '%d წელი' - }, - dayOfMonthOrdinalParse: /0|1-ლი|მე-\d{1,2}|\d{1,2}-ე/, - ordinal : function (number) { - if (number === 0) { - return number; - } - if (number === 1) { - return number + '-ლი'; - } - if ((number < 20) || (number <= 100 && (number % 20 === 0)) || (number % 100 === 0)) { - return 'მე-' + number; - } - return number + '-ე'; - }, - week : { - dow : 1, - doy : 7 - } - }); - - //! moment.js locale configuration - - var suffixes$1 = { - 0: '-ші', - 1: '-ші', - 2: '-ші', - 3: '-ші', - 4: '-ші', - 5: '-ші', - 6: '-шы', - 7: '-ші', - 8: '-ші', - 9: '-шы', - 10: '-шы', - 20: '-шы', - 30: '-шы', - 40: '-шы', - 50: '-ші', - 60: '-шы', - 70: '-ші', - 80: '-ші', - 90: '-шы', - 100: '-ші' - }; - - hooks.defineLocale('kk', { - months : 'қаңтар_ақпан_наурыз_сәуір_мамыр_маусым_шілде_тамыз_қыркүйек_қазан_қараша_желтоқсан'.split('_'), - monthsShort : 'қаң_ақп_нау_сәу_мам_мау_шіл_там_қыр_қаз_қар_жел'.split('_'), - weekdays : 'жексенбі_дүйсенбі_сейсенбі_сәрсенбі_бейсенбі_жұма_сенбі'.split('_'), - weekdaysShort : 'жек_дүй_сей_сәр_бей_жұм_сен'.split('_'), - weekdaysMin : 'жк_дй_сй_ср_бй_жм_сн'.split('_'), - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD.MM.YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd, D MMMM YYYY HH:mm' - }, - calendar : { - sameDay : '[Бүгін сағат] LT', - nextDay : '[Ертең сағат] LT', - nextWeek : 'dddd [сағат] LT', - lastDay : '[Кеше сағат] LT', - lastWeek : '[Өткен аптаның] dddd [сағат] LT', - sameElse : 'L' - }, - relativeTime : { - future : '%s ішінде', - past : '%s бұрын', - s : 'бірнеше секунд', - ss : '%d секунд', - m : 'бір минут', - mm : '%d минут', - h : 'бір сағат', - hh : '%d сағат', - d : 'бір күн', - dd : '%d күн', - M : 'бір ай', - MM : '%d ай', - y : 'бір жыл', - yy : '%d жыл' - }, - dayOfMonthOrdinalParse: /\d{1,2}-(ші|шы)/, - ordinal : function (number) { - var a = number % 10, - b = number >= 100 ? 100 : null; - return number + (suffixes$1[number] || suffixes$1[a] || suffixes$1[b]); - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 7th is the first week of the year. - } - }); - - //! moment.js locale configuration - - var symbolMap$8 = { - '1': '១', - '2': '២', - '3': '៣', - '4': '៤', - '5': '៥', - '6': '៦', - '7': '៧', - '8': '៨', - '9': '៩', - '0': '០' - }, numberMap$7 = { - '១': '1', - '២': '2', - '៣': '3', - '៤': '4', - '៥': '5', - '៦': '6', - '៧': '7', - '៨': '8', - '៩': '9', - '០': '0' - }; - - hooks.defineLocale('km', { - months: 'មករា_កុម្ភៈ_មីនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ'.split( - '_' - ), - monthsShort: 'មករា_កុម្ភៈ_មីនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ'.split( - '_' - ), - weekdays: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'), - weekdaysShort: 'អា_ច_អ_ព_ព្រ_សុ_ស'.split('_'), - weekdaysMin: 'អា_ច_អ_ព_ព្រ_សុ_ស'.split('_'), - weekdaysParseExact: true, - longDateFormat: { - LT: 'HH:mm', - LTS: 'HH:mm:ss', - L: 'DD/MM/YYYY', - LL: 'D MMMM YYYY', - LLL: 'D MMMM YYYY HH:mm', - LLLL: 'dddd, D MMMM YYYY HH:mm' - }, - meridiemParse: /ព្រឹក|ល្ងាច/, - isPM: function (input) { - return input === 'ល្ងាច'; - }, - meridiem: function (hour, minute, isLower) { - if (hour < 12) { - return 'ព្រឹក'; - } else { - return 'ល្ងាច'; - } - }, - calendar: { - sameDay: '[ថ្ងៃនេះ ម៉ោង] LT', - nextDay: '[ស្អែក ម៉ោង] LT', - nextWeek: 'dddd [ម៉ោង] LT', - lastDay: '[ម្សិលមិញ ម៉ោង] LT', - lastWeek: 'dddd [សប្តាហ៍មុន] [ម៉ោង] LT', - sameElse: 'L' - }, - relativeTime: { - future: '%sទៀត', - past: '%sមុន', - s: 'ប៉ុន្មានវិនាទី', - ss: '%d វិនាទី', - m: 'មួយនាទី', - mm: '%d នាទី', - h: 'មួយម៉ោង', - hh: '%d ម៉ោង', - d: 'មួយថ្ងៃ', - dd: '%d ថ្ងៃ', - M: 'មួយខែ', - MM: '%d ខែ', - y: 'មួយឆ្នាំ', - yy: '%d ឆ្នាំ' - }, - dayOfMonthOrdinalParse : /ទី\d{1,2}/, - ordinal : 'ទី%d', - preparse: function (string) { - return string.replace(/[១២៣៤៥៦៧៨៩០]/g, function (match) { - return numberMap$7[match]; - }); - }, - postformat: function (string) { - return string.replace(/\d/g, function (match) { - return symbolMap$8[match]; - }); - }, - week: { - dow: 1, // Monday is the first day of the week. - doy: 4 // The week that contains Jan 4th is the first week of the year. - } - }); - - //! moment.js locale configuration - - var symbolMap$9 = { - '1': '೧', - '2': '೨', - '3': '೩', - '4': '೪', - '5': '೫', - '6': '೬', - '7': '೭', - '8': '೮', - '9': '೯', - '0': '೦' - }, - numberMap$8 = { - '೧': '1', - '೨': '2', - '೩': '3', - '೪': '4', - '೫': '5', - '೬': '6', - '೭': '7', - '೮': '8', - '೯': '9', - '೦': '0' - }; - - hooks.defineLocale('kn', { - months : 'ಜನವರಿ_ಫೆಬ್ರವರಿ_ಮಾರ್ಚ್_ಏಪ್ರಿಲ್_ಮೇ_ಜೂನ್_ಜುಲೈ_ಆಗಸ್ಟ್_ಸೆಪ್ಟೆಂಬರ್_ಅಕ್ಟೋಬರ್_ನವೆಂಬರ್_ಡಿಸೆಂಬರ್'.split('_'), - monthsShort : 'ಜನ_ಫೆಬ್ರ_ಮಾರ್ಚ್_ಏಪ್ರಿಲ್_ಮೇ_ಜೂನ್_ಜುಲೈ_ಆಗಸ್ಟ್_ಸೆಪ್ಟೆಂ_ಅಕ್ಟೋ_ನವೆಂ_ಡಿಸೆಂ'.split('_'), - monthsParseExact: true, - weekdays : 'ಭಾನುವಾರ_ಸೋಮವಾರ_ಮಂಗಳವಾರ_ಬುಧವಾರ_ಗುರುವಾರ_ಶುಕ್ರವಾರ_ಶನಿವಾರ'.split('_'), - weekdaysShort : 'ಭಾನು_ಸೋಮ_ಮಂಗಳ_ಬುಧ_ಗುರು_ಶುಕ್ರ_ಶನಿ'.split('_'), - weekdaysMin : 'ಭಾ_ಸೋ_ಮಂ_ಬು_ಗು_ಶು_ಶ'.split('_'), - longDateFormat : { - LT : 'A h:mm', - LTS : 'A h:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY, A h:mm', - LLLL : 'dddd, D MMMM YYYY, A h:mm' - }, - calendar : { - sameDay : '[ಇಂದು] LT', - nextDay : '[ನಾಳೆ] LT', - nextWeek : 'dddd, LT', - lastDay : '[ನಿನ್ನೆ] LT', - lastWeek : '[ಕೊನೆಯ] dddd, LT', - sameElse : 'L' - }, - relativeTime : { - future : '%s ನಂತರ', - past : '%s ಹಿಂದೆ', - s : 'ಕೆಲವು ಕ್ಷಣಗಳು', - ss : '%d ಸೆಕೆಂಡುಗಳು', - m : 'ಒಂದು ನಿಮಿಷ', - mm : '%d ನಿಮಿಷ', - h : 'ಒಂದು ಗಂಟೆ', - hh : '%d ಗಂಟೆ', - d : 'ಒಂದು ದಿನ', - dd : '%d ದಿನ', - M : 'ಒಂದು ತಿಂಗಳು', - MM : '%d ತಿಂಗಳು', - y : 'ಒಂದು ವರ್ಷ', - yy : '%d ವರ್ಷ' - }, - preparse: function (string) { - return string.replace(/[೧೨೩೪೫೬೭೮೯೦]/g, function (match) { - return numberMap$8[match]; - }); - }, - postformat: function (string) { - return string.replace(/\d/g, function (match) { - return symbolMap$9[match]; - }); - }, - meridiemParse: /ರಾತ್ರಿ|ಬೆಳಿಗ್ಗೆ|ಮಧ್ಯಾಹ್ನ|ಸಂಜೆ/, - meridiemHour : function (hour, meridiem) { - if (hour === 12) { - hour = 0; - } - if (meridiem === 'ರಾತ್ರಿ') { - return hour < 4 ? hour : hour + 12; - } else if (meridiem === 'ಬೆಳಿಗ್ಗೆ') { - return hour; - } else if (meridiem === 'ಮಧ್ಯಾಹ್ನ') { - return hour >= 10 ? hour : hour + 12; - } else if (meridiem === 'ಸಂಜೆ') { - return hour + 12; - } - }, - meridiem : function (hour, minute, isLower) { - if (hour < 4) { - return 'ರಾತ್ರಿ'; - } else if (hour < 10) { - return 'ಬೆಳಿಗ್ಗೆ'; - } else if (hour < 17) { - return 'ಮಧ್ಯಾಹ್ನ'; - } else if (hour < 20) { - return 'ಸಂಜೆ'; - } else { - return 'ರಾತ್ರಿ'; - } - }, - dayOfMonthOrdinalParse: /\d{1,2}(ನೇ)/, - ordinal : function (number) { - return number + 'ನೇ'; - }, - week : { - dow : 0, // Sunday is the first day of the week. - doy : 6 // The week that contains Jan 6th is the first week of the year. - } - }); - - //! moment.js locale configuration - - hooks.defineLocale('ko', { - months : '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split('_'), - monthsShort : '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split('_'), - weekdays : '일요일_월요일_화요일_수요일_목요일_금요일_토요일'.split('_'), - weekdaysShort : '일_월_화_수_목_금_토'.split('_'), - weekdaysMin : '일_월_화_수_목_금_토'.split('_'), - longDateFormat : { - LT : 'A h:mm', - LTS : 'A h:mm:ss', - L : 'YYYY.MM.DD.', - LL : 'YYYY년 MMMM D일', - LLL : 'YYYY년 MMMM D일 A h:mm', - LLLL : 'YYYY년 MMMM D일 dddd A h:mm', - l : 'YYYY.MM.DD.', - ll : 'YYYY년 MMMM D일', - lll : 'YYYY년 MMMM D일 A h:mm', - llll : 'YYYY년 MMMM D일 dddd A h:mm' - }, - calendar : { - sameDay : '오늘 LT', - nextDay : '내일 LT', - nextWeek : 'dddd LT', - lastDay : '어제 LT', - lastWeek : '지난주 dddd LT', - sameElse : 'L' - }, - relativeTime : { - future : '%s 후', - past : '%s 전', - s : '몇 초', - ss : '%d초', - m : '1분', - mm : '%d분', - h : '한 시간', - hh : '%d시간', - d : '하루', - dd : '%d일', - M : '한 달', - MM : '%d달', - y : '일 년', - yy : '%d년' - }, - dayOfMonthOrdinalParse : /\d{1,2}(일|월|주)/, - ordinal : function (number, period) { - switch (period) { - case 'd': - case 'D': - case 'DDD': - return number + '일'; - case 'M': - return number + '월'; - case 'w': - case 'W': - return number + '주'; - default: - return number; - } - }, - meridiemParse : /오전|오후/, - isPM : function (token) { - return token === '오후'; - }, - meridiem : function (hour, minute, isUpper) { - return hour < 12 ? '오전' : '오후'; - } - }); - - //! moment.js locale configuration - - var symbolMap$a = { - '1': '١', - '2': '٢', - '3': '٣', - '4': '٤', - '5': '٥', - '6': '٦', - '7': '٧', - '8': '٨', - '9': '٩', - '0': '٠' - }, numberMap$9 = { - '١': '1', - '٢': '2', - '٣': '3', - '٤': '4', - '٥': '5', - '٦': '6', - '٧': '7', - '٨': '8', - '٩': '9', - '٠': '0' - }, - months$6 = [ - 'کانونی دووەم', - 'شوبات', - 'ئازار', - 'نیسان', - 'ئایار', - 'حوزەیران', - 'تەمموز', - 'ئاب', - 'ئەیلوول', - 'تشرینی یەكەم', - 'تشرینی دووەم', - 'كانونی یەکەم' - ]; - - - hooks.defineLocale('ku', { - months : months$6, - monthsShort : months$6, - weekdays : 'یه‌كشه‌ممه‌_دووشه‌ممه‌_سێشه‌ممه‌_چوارشه‌ممه‌_پێنجشه‌ممه‌_هه‌ینی_شه‌ممه‌'.split('_'), - weekdaysShort : 'یه‌كشه‌م_دووشه‌م_سێشه‌م_چوارشه‌م_پێنجشه‌م_هه‌ینی_شه‌ممه‌'.split('_'), - weekdaysMin : 'ی_د_س_چ_پ_ه_ش'.split('_'), - weekdaysParseExact : true, - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd, D MMMM YYYY HH:mm' - }, - meridiemParse: /ئێواره‌|به‌یانی/, - isPM: function (input) { - return /ئێواره‌/.test(input); - }, - meridiem : function (hour, minute, isLower) { - if (hour < 12) { - return 'به‌یانی'; - } else { - return 'ئێواره‌'; - } - }, - calendar : { - sameDay : '[ئه‌مرۆ كاتژمێر] LT', - nextDay : '[به‌یانی كاتژمێر] LT', - nextWeek : 'dddd [كاتژمێر] LT', - lastDay : '[دوێنێ كاتژمێر] LT', - lastWeek : 'dddd [كاتژمێر] LT', - sameElse : 'L' - }, - relativeTime : { - future : 'له‌ %s', - past : '%s', - s : 'چه‌ند چركه‌یه‌ك', - ss : 'چركه‌ %d', - m : 'یه‌ك خوله‌ك', - mm : '%d خوله‌ك', - h : 'یه‌ك كاتژمێر', - hh : '%d كاتژمێر', - d : 'یه‌ك ڕۆژ', - dd : '%d ڕۆژ', - M : 'یه‌ك مانگ', - MM : '%d مانگ', - y : 'یه‌ك ساڵ', - yy : '%d ساڵ' - }, - preparse: function (string) { - return string.replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) { - return numberMap$9[match]; - }).replace(/،/g, ','); - }, - postformat: function (string) { - return string.replace(/\d/g, function (match) { - return symbolMap$a[match]; - }).replace(/,/g, '،'); - }, - week : { - dow : 6, // Saturday is the first day of the week. - doy : 12 // The week that contains Jan 12th is the first week of the year. - } - }); - - //! moment.js locale configuration - - var suffixes$2 = { - 0: '-чү', - 1: '-чи', - 2: '-чи', - 3: '-чү', - 4: '-чү', - 5: '-чи', - 6: '-чы', - 7: '-чи', - 8: '-чи', - 9: '-чу', - 10: '-чу', - 20: '-чы', - 30: '-чу', - 40: '-чы', - 50: '-чү', - 60: '-чы', - 70: '-чи', - 80: '-чи', - 90: '-чу', - 100: '-чү' - }; - - hooks.defineLocale('ky', { - months : 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_'), - monthsShort : 'янв_фев_март_апр_май_июнь_июль_авг_сен_окт_ноя_дек'.split('_'), - weekdays : 'Жекшемби_Дүйшөмбү_Шейшемби_Шаршемби_Бейшемби_Жума_Ишемби'.split('_'), - weekdaysShort : 'Жек_Дүй_Шей_Шар_Бей_Жум_Ише'.split('_'), - weekdaysMin : 'Жк_Дй_Шй_Шр_Бй_Жм_Иш'.split('_'), - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD.MM.YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd, D MMMM YYYY HH:mm' - }, - calendar : { - sameDay : '[Бүгүн саат] LT', - nextDay : '[Эртең саат] LT', - nextWeek : 'dddd [саат] LT', - lastDay : '[Кечээ саат] LT', - lastWeek : '[Өткөн аптанын] dddd [күнү] [саат] LT', - sameElse : 'L' - }, - relativeTime : { - future : '%s ичинде', - past : '%s мурун', - s : 'бирнече секунд', - ss : '%d секунд', - m : 'бир мүнөт', - mm : '%d мүнөт', - h : 'бир саат', - hh : '%d саат', - d : 'бир күн', - dd : '%d күн', - M : 'бир ай', - MM : '%d ай', - y : 'бир жыл', - yy : '%d жыл' - }, - dayOfMonthOrdinalParse: /\d{1,2}-(чи|чы|чү|чу)/, - ordinal : function (number) { - var a = number % 10, - b = number >= 100 ? 100 : null; - return number + (suffixes$2[number] || suffixes$2[a] || suffixes$2[b]); - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 7th is the first week of the year. - } - }); - - //! moment.js locale configuration - - function processRelativeTime$5(number, withoutSuffix, key, isFuture) { - var format = { - 'm': ['eng Minutt', 'enger Minutt'], - 'h': ['eng Stonn', 'enger Stonn'], - 'd': ['een Dag', 'engem Dag'], - 'M': ['ee Mount', 'engem Mount'], - 'y': ['ee Joer', 'engem Joer'] - }; - return withoutSuffix ? format[key][0] : format[key][1]; - } - function processFutureTime(string) { - var number = string.substr(0, string.indexOf(' ')); - if (eifelerRegelAppliesToNumber(number)) { - return 'a ' + string; - } - return 'an ' + string; - } - function processPastTime(string) { - var number = string.substr(0, string.indexOf(' ')); - if (eifelerRegelAppliesToNumber(number)) { - return 'viru ' + string; - } - return 'virun ' + string; - } - /** - * Returns true if the word before the given number loses the '-n' ending. - * e.g. 'an 10 Deeg' but 'a 5 Deeg' - * - * @param number {integer} - * @returns {boolean} - */ - function eifelerRegelAppliesToNumber(number) { - number = parseInt(number, 10); - if (isNaN(number)) { - return false; - } - if (number < 0) { - // Negative Number --> always true - return true; - } else if (number < 10) { - // Only 1 digit - if (4 <= number && number <= 7) { - return true; - } - return false; - } else if (number < 100) { - // 2 digits - var lastDigit = number % 10, firstDigit = number / 10; - if (lastDigit === 0) { - return eifelerRegelAppliesToNumber(firstDigit); - } - return eifelerRegelAppliesToNumber(lastDigit); - } else if (number < 10000) { - // 3 or 4 digits --> recursively check first digit - while (number >= 10) { - number = number / 10; - } - return eifelerRegelAppliesToNumber(number); - } else { - // Anything larger than 4 digits: recursively check first n-3 digits - number = number / 1000; - return eifelerRegelAppliesToNumber(number); - } - } - - hooks.defineLocale('lb', { - months: 'Januar_Februar_Mäerz_Abrëll_Mee_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'), - monthsShort: 'Jan._Febr._Mrz._Abr._Mee_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'), - monthsParseExact : true, - weekdays: 'Sonndeg_Méindeg_Dënschdeg_Mëttwoch_Donneschdeg_Freideg_Samschdeg'.split('_'), - weekdaysShort: 'So._Mé._Dë._Më._Do._Fr._Sa.'.split('_'), - weekdaysMin: 'So_Mé_Dë_Më_Do_Fr_Sa'.split('_'), - weekdaysParseExact : true, - longDateFormat: { - LT: 'H:mm [Auer]', - LTS: 'H:mm:ss [Auer]', - L: 'DD.MM.YYYY', - LL: 'D. MMMM YYYY', - LLL: 'D. MMMM YYYY H:mm [Auer]', - LLLL: 'dddd, D. MMMM YYYY H:mm [Auer]' - }, - calendar: { - sameDay: '[Haut um] LT', - sameElse: 'L', - nextDay: '[Muer um] LT', - nextWeek: 'dddd [um] LT', - lastDay: '[Gëschter um] LT', - lastWeek: function () { - // Different date string for 'Dënschdeg' (Tuesday) and 'Donneschdeg' (Thursday) due to phonological rule - switch (this.day()) { - case 2: - case 4: - return '[Leschten] dddd [um] LT'; - default: - return '[Leschte] dddd [um] LT'; - } - } - }, - relativeTime : { - future : processFutureTime, - past : processPastTime, - s : 'e puer Sekonnen', - ss : '%d Sekonnen', - m : processRelativeTime$5, - mm : '%d Minutten', - h : processRelativeTime$5, - hh : '%d Stonnen', - d : processRelativeTime$5, - dd : '%d Deeg', - M : processRelativeTime$5, - MM : '%d Méint', - y : processRelativeTime$5, - yy : '%d Joer' - }, - dayOfMonthOrdinalParse: /\d{1,2}\./, - ordinal: '%d.', - week: { - dow: 1, // Monday is the first day of the week. - doy: 4 // The week that contains Jan 4th is the first week of the year. - } - }); - - //! moment.js locale configuration - - hooks.defineLocale('lo', { - months : 'ມັງກອນ_ກຸມພາ_ມີນາ_ເມສາ_ພຶດສະພາ_ມິຖຸນາ_ກໍລະກົດ_ສິງຫາ_ກັນຍາ_ຕຸລາ_ພະຈິກ_ທັນວາ'.split('_'), - monthsShort : 'ມັງກອນ_ກຸມພາ_ມີນາ_ເມສາ_ພຶດສະພາ_ມິຖຸນາ_ກໍລະກົດ_ສິງຫາ_ກັນຍາ_ຕຸລາ_ພະຈິກ_ທັນວາ'.split('_'), - weekdays : 'ອາທິດ_ຈັນ_ອັງຄານ_ພຸດ_ພະຫັດ_ສຸກ_ເສົາ'.split('_'), - weekdaysShort : 'ທິດ_ຈັນ_ອັງຄານ_ພຸດ_ພະຫັດ_ສຸກ_ເສົາ'.split('_'), - weekdaysMin : 'ທ_ຈ_ອຄ_ພ_ພຫ_ສກ_ສ'.split('_'), - weekdaysParseExact : true, - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'ວັນdddd D MMMM YYYY HH:mm' - }, - meridiemParse: /ຕອນເຊົ້າ|ຕອນແລງ/, - isPM: function (input) { - return input === 'ຕອນແລງ'; - }, - meridiem : function (hour, minute, isLower) { - if (hour < 12) { - return 'ຕອນເຊົ້າ'; - } else { - return 'ຕອນແລງ'; - } - }, - calendar : { - sameDay : '[ມື້ນີ້ເວລາ] LT', - nextDay : '[ມື້ອື່ນເວລາ] LT', - nextWeek : '[ວັນ]dddd[ໜ້າເວລາ] LT', - lastDay : '[ມື້ວານນີ້ເວລາ] LT', - lastWeek : '[ວັນ]dddd[ແລ້ວນີ້ເວລາ] LT', - sameElse : 'L' - }, - relativeTime : { - future : 'ອີກ %s', - past : '%sຜ່ານມາ', - s : 'ບໍ່ເທົ່າໃດວິນາທີ', - ss : '%d ວິນາທີ' , - m : '1 ນາທີ', - mm : '%d ນາທີ', - h : '1 ຊົ່ວໂມງ', - hh : '%d ຊົ່ວໂມງ', - d : '1 ມື້', - dd : '%d ມື້', - M : '1 ເດືອນ', - MM : '%d ເດືອນ', - y : '1 ປີ', - yy : '%d ປີ' - }, - dayOfMonthOrdinalParse: /(ທີ່)\d{1,2}/, - ordinal : function (number) { - return 'ທີ່' + number; - } - }); - - //! moment.js locale configuration - - var units = { - 'ss' : 'sekundė_sekundžių_sekundes', - 'm' : 'minutė_minutės_minutę', - 'mm': 'minutės_minučių_minutes', - 'h' : 'valanda_valandos_valandą', - 'hh': 'valandos_valandų_valandas', - 'd' : 'diena_dienos_dieną', - 'dd': 'dienos_dienų_dienas', - 'M' : 'mėnuo_mėnesio_mėnesį', - 'MM': 'mėnesiai_mėnesių_mėnesius', - 'y' : 'metai_metų_metus', - 'yy': 'metai_metų_metus' - }; - function translateSeconds(number, withoutSuffix, key, isFuture) { - if (withoutSuffix) { - return 'kelios sekundės'; - } else { - return isFuture ? 'kelių sekundžių' : 'kelias sekundes'; - } - } - function translateSingular(number, withoutSuffix, key, isFuture) { - return withoutSuffix ? forms(key)[0] : (isFuture ? forms(key)[1] : forms(key)[2]); - } - function special(number) { - return number % 10 === 0 || (number > 10 && number < 20); - } - function forms(key) { - return units[key].split('_'); - } - function translate$6(number, withoutSuffix, key, isFuture) { - var result = number + ' '; - if (number === 1) { - return result + translateSingular(number, withoutSuffix, key[0], isFuture); - } else if (withoutSuffix) { - return result + (special(number) ? forms(key)[1] : forms(key)[0]); - } else { - if (isFuture) { - return result + forms(key)[1]; - } else { - return result + (special(number) ? forms(key)[1] : forms(key)[2]); - } - } - } - hooks.defineLocale('lt', { - months : { - format: 'sausio_vasario_kovo_balandžio_gegužės_birželio_liepos_rugpjūčio_rugsėjo_spalio_lapkričio_gruodžio'.split('_'), - standalone: 'sausis_vasaris_kovas_balandis_gegužė_birželis_liepa_rugpjūtis_rugsėjis_spalis_lapkritis_gruodis'.split('_'), - isFormat: /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?|MMMM?(\[[^\[\]]*\]|\s)+D[oD]?/ - }, - monthsShort : 'sau_vas_kov_bal_geg_bir_lie_rgp_rgs_spa_lap_grd'.split('_'), - weekdays : { - format: 'sekmadienį_pirmadienį_antradienį_trečiadienį_ketvirtadienį_penktadienį_šeštadienį'.split('_'), - standalone: 'sekmadienis_pirmadienis_antradienis_trečiadienis_ketvirtadienis_penktadienis_šeštadienis'.split('_'), - isFormat: /dddd HH:mm/ - }, - weekdaysShort : 'Sek_Pir_Ant_Tre_Ket_Pen_Šeš'.split('_'), - weekdaysMin : 'S_P_A_T_K_Pn_Š'.split('_'), - weekdaysParseExact : true, - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'YYYY-MM-DD', - LL : 'YYYY [m.] MMMM D [d.]', - LLL : 'YYYY [m.] MMMM D [d.], HH:mm [val.]', - LLLL : 'YYYY [m.] MMMM D [d.], dddd, HH:mm [val.]', - l : 'YYYY-MM-DD', - ll : 'YYYY [m.] MMMM D [d.]', - lll : 'YYYY [m.] MMMM D [d.], HH:mm [val.]', - llll : 'YYYY [m.] MMMM D [d.], ddd, HH:mm [val.]' - }, - calendar : { - sameDay : '[Šiandien] LT', - nextDay : '[Rytoj] LT', - nextWeek : 'dddd LT', - lastDay : '[Vakar] LT', - lastWeek : '[Praėjusį] dddd LT', - sameElse : 'L' - }, - relativeTime : { - future : 'po %s', - past : 'prieš %s', - s : translateSeconds, - ss : translate$6, - m : translateSingular, - mm : translate$6, - h : translateSingular, - hh : translate$6, - d : translateSingular, - dd : translate$6, - M : translateSingular, - MM : translate$6, - y : translateSingular, - yy : translate$6 - }, - dayOfMonthOrdinalParse: /\d{1,2}-oji/, - ordinal : function (number) { - return number + '-oji'; - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); - - //! moment.js locale configuration - - var units$1 = { - 'ss': 'sekundes_sekundēm_sekunde_sekundes'.split('_'), - 'm': 'minūtes_minūtēm_minūte_minūtes'.split('_'), - 'mm': 'minūtes_minūtēm_minūte_minūtes'.split('_'), - 'h': 'stundas_stundām_stunda_stundas'.split('_'), - 'hh': 'stundas_stundām_stunda_stundas'.split('_'), - 'd': 'dienas_dienām_diena_dienas'.split('_'), - 'dd': 'dienas_dienām_diena_dienas'.split('_'), - 'M': 'mēneša_mēnešiem_mēnesis_mēneši'.split('_'), - 'MM': 'mēneša_mēnešiem_mēnesis_mēneši'.split('_'), - 'y': 'gada_gadiem_gads_gadi'.split('_'), - 'yy': 'gada_gadiem_gads_gadi'.split('_') - }; - /** - * @param withoutSuffix boolean true = a length of time; false = before/after a period of time. - */ - function format$1(forms, number, withoutSuffix) { - if (withoutSuffix) { - // E.g. "21 minūte", "3 minūtes". - return number % 10 === 1 && number % 100 !== 11 ? forms[2] : forms[3]; - } else { - // E.g. "21 minūtes" as in "pēc 21 minūtes". - // E.g. "3 minūtēm" as in "pēc 3 minūtēm". - return number % 10 === 1 && number % 100 !== 11 ? forms[0] : forms[1]; - } - } - function relativeTimeWithPlural$1(number, withoutSuffix, key) { - return number + ' ' + format$1(units$1[key], number, withoutSuffix); - } - function relativeTimeWithSingular(number, withoutSuffix, key) { - return format$1(units$1[key], number, withoutSuffix); - } - function relativeSeconds(number, withoutSuffix) { - return withoutSuffix ? 'dažas sekundes' : 'dažām sekundēm'; - } - - hooks.defineLocale('lv', { - months : 'janvāris_februāris_marts_aprīlis_maijs_jūnijs_jūlijs_augusts_septembris_oktobris_novembris_decembris'.split('_'), - monthsShort : 'jan_feb_mar_apr_mai_jūn_jūl_aug_sep_okt_nov_dec'.split('_'), - weekdays : 'svētdiena_pirmdiena_otrdiena_trešdiena_ceturtdiena_piektdiena_sestdiena'.split('_'), - weekdaysShort : 'Sv_P_O_T_C_Pk_S'.split('_'), - weekdaysMin : 'Sv_P_O_T_C_Pk_S'.split('_'), - weekdaysParseExact : true, - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD.MM.YYYY.', - LL : 'YYYY. [gada] D. MMMM', - LLL : 'YYYY. [gada] D. MMMM, HH:mm', - LLLL : 'YYYY. [gada] D. MMMM, dddd, HH:mm' - }, - calendar : { - sameDay : '[Šodien pulksten] LT', - nextDay : '[Rīt pulksten] LT', - nextWeek : 'dddd [pulksten] LT', - lastDay : '[Vakar pulksten] LT', - lastWeek : '[Pagājušā] dddd [pulksten] LT', - sameElse : 'L' - }, - relativeTime : { - future : 'pēc %s', - past : 'pirms %s', - s : relativeSeconds, - ss : relativeTimeWithPlural$1, - m : relativeTimeWithSingular, - mm : relativeTimeWithPlural$1, - h : relativeTimeWithSingular, - hh : relativeTimeWithPlural$1, - d : relativeTimeWithSingular, - dd : relativeTimeWithPlural$1, - M : relativeTimeWithSingular, - MM : relativeTimeWithPlural$1, - y : relativeTimeWithSingular, - yy : relativeTimeWithPlural$1 - }, - dayOfMonthOrdinalParse: /\d{1,2}\./, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); - - //! moment.js locale configuration - - var translator = { - words: { //Different grammatical cases - ss: ['sekund', 'sekunda', 'sekundi'], - m: ['jedan minut', 'jednog minuta'], - mm: ['minut', 'minuta', 'minuta'], - h: ['jedan sat', 'jednog sata'], - hh: ['sat', 'sata', 'sati'], - dd: ['dan', 'dana', 'dana'], - MM: ['mjesec', 'mjeseca', 'mjeseci'], - yy: ['godina', 'godine', 'godina'] - }, - correctGrammaticalCase: function (number, wordKey) { - return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]); - }, - translate: function (number, withoutSuffix, key) { - var wordKey = translator.words[key]; - if (key.length === 1) { - return withoutSuffix ? wordKey[0] : wordKey[1]; - } else { - return number + ' ' + translator.correctGrammaticalCase(number, wordKey); - } - } - }; - - hooks.defineLocale('me', { - months: 'januar_februar_mart_april_maj_jun_jul_avgust_septembar_oktobar_novembar_decembar'.split('_'), - monthsShort: 'jan._feb._mar._apr._maj_jun_jul_avg._sep._okt._nov._dec.'.split('_'), - monthsParseExact : true, - weekdays: 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'), - weekdaysShort: 'ned._pon._uto._sri._čet._pet._sub.'.split('_'), - weekdaysMin: 'ne_po_ut_sr_če_pe_su'.split('_'), - weekdaysParseExact : true, - longDateFormat: { - LT: 'H:mm', - LTS : 'H:mm:ss', - L: 'DD.MM.YYYY', - LL: 'D. MMMM YYYY', - LLL: 'D. MMMM YYYY H:mm', - LLLL: 'dddd, D. MMMM YYYY H:mm' - }, - calendar: { - sameDay: '[danas u] LT', - nextDay: '[sjutra u] LT', - - nextWeek: function () { - switch (this.day()) { - case 0: - return '[u] [nedjelju] [u] LT'; - case 3: - return '[u] [srijedu] [u] LT'; - case 6: - return '[u] [subotu] [u] LT'; - case 1: - case 2: - case 4: - case 5: - return '[u] dddd [u] LT'; - } - }, - lastDay : '[juče u] LT', - lastWeek : function () { - var lastWeekDays = [ - '[prošle] [nedjelje] [u] LT', - '[prošlog] [ponedjeljka] [u] LT', - '[prošlog] [utorka] [u] LT', - '[prošle] [srijede] [u] LT', - '[prošlog] [četvrtka] [u] LT', - '[prošlog] [petka] [u] LT', - '[prošle] [subote] [u] LT' - ]; - return lastWeekDays[this.day()]; - }, - sameElse : 'L' - }, - relativeTime : { - future : 'za %s', - past : 'prije %s', - s : 'nekoliko sekundi', - ss : translator.translate, - m : translator.translate, - mm : translator.translate, - h : translator.translate, - hh : translator.translate, - d : 'dan', - dd : translator.translate, - M : 'mjesec', - MM : translator.translate, - y : 'godinu', - yy : translator.translate - }, - dayOfMonthOrdinalParse: /\d{1,2}\./, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 7th is the first week of the year. - } - }); - - //! moment.js locale configuration - - hooks.defineLocale('mi', { - months: 'Kohi-tāte_Hui-tanguru_Poutū-te-rangi_Paenga-whāwhā_Haratua_Pipiri_Hōngoingoi_Here-turi-kōkā_Mahuru_Whiringa-ā-nuku_Whiringa-ā-rangi_Hakihea'.split('_'), - monthsShort: 'Kohi_Hui_Pou_Pae_Hara_Pipi_Hōngoi_Here_Mahu_Whi-nu_Whi-ra_Haki'.split('_'), - monthsRegex: /(?:['a-z\u0101\u014D\u016B]+\-?){1,3}/i, - monthsStrictRegex: /(?:['a-z\u0101\u014D\u016B]+\-?){1,3}/i, - monthsShortRegex: /(?:['a-z\u0101\u014D\u016B]+\-?){1,3}/i, - monthsShortStrictRegex: /(?:['a-z\u0101\u014D\u016B]+\-?){1,2}/i, - weekdays: 'Rātapu_Mane_Tūrei_Wenerei_Tāite_Paraire_Hātarei'.split('_'), - weekdaysShort: 'Ta_Ma_Tū_We_Tāi_Pa_Hā'.split('_'), - weekdaysMin: 'Ta_Ma_Tū_We_Tāi_Pa_Hā'.split('_'), - longDateFormat: { - LT: 'HH:mm', - LTS: 'HH:mm:ss', - L: 'DD/MM/YYYY', - LL: 'D MMMM YYYY', - LLL: 'D MMMM YYYY [i] HH:mm', - LLLL: 'dddd, D MMMM YYYY [i] HH:mm' - }, - calendar: { - sameDay: '[i teie mahana, i] LT', - nextDay: '[apopo i] LT', - nextWeek: 'dddd [i] LT', - lastDay: '[inanahi i] LT', - lastWeek: 'dddd [whakamutunga i] LT', - sameElse: 'L' - }, - relativeTime: { - future: 'i roto i %s', - past: '%s i mua', - s: 'te hēkona ruarua', - ss: '%d hēkona', - m: 'he meneti', - mm: '%d meneti', - h: 'te haora', - hh: '%d haora', - d: 'he ra', - dd: '%d ra', - M: 'he marama', - MM: '%d marama', - y: 'he tau', - yy: '%d tau' - }, - dayOfMonthOrdinalParse: /\d{1,2}º/, - ordinal: '%dº', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); - - //! moment.js locale configuration - - hooks.defineLocale('mk', { - months : 'јануари_февруари_март_април_мај_јуни_јули_август_септември_октомври_ноември_декември'.split('_'), - monthsShort : 'јан_фев_мар_апр_мај_јун_јул_авг_сеп_окт_ное_дек'.split('_'), - weekdays : 'недела_понеделник_вторник_среда_четврток_петок_сабота'.split('_'), - weekdaysShort : 'нед_пон_вто_сре_чет_пет_саб'.split('_'), - weekdaysMin : 'нe_пo_вт_ср_че_пе_сa'.split('_'), - longDateFormat : { - LT : 'H:mm', - LTS : 'H:mm:ss', - L : 'D.MM.YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY H:mm', - LLLL : 'dddd, D MMMM YYYY H:mm' - }, - calendar : { - sameDay : '[Денес во] LT', - nextDay : '[Утре во] LT', - nextWeek : '[Во] dddd [во] LT', - lastDay : '[Вчера во] LT', - lastWeek : function () { - switch (this.day()) { - case 0: - case 3: - case 6: - return '[Изминатата] dddd [во] LT'; - case 1: - case 2: - case 4: - case 5: - return '[Изминатиот] dddd [во] LT'; - } - }, - sameElse : 'L' - }, - relativeTime : { - future : 'после %s', - past : 'пред %s', - s : 'неколку секунди', - ss : '%d секунди', - m : 'минута', - mm : '%d минути', - h : 'час', - hh : '%d часа', - d : 'ден', - dd : '%d дена', - M : 'месец', - MM : '%d месеци', - y : 'година', - yy : '%d години' - }, - dayOfMonthOrdinalParse: /\d{1,2}-(ев|ен|ти|ви|ри|ми)/, - ordinal : function (number) { - var lastDigit = number % 10, - last2Digits = number % 100; - if (number === 0) { - return number + '-ев'; - } else if (last2Digits === 0) { - return number + '-ен'; - } else if (last2Digits > 10 && last2Digits < 20) { - return number + '-ти'; - } else if (lastDigit === 1) { - return number + '-ви'; - } else if (lastDigit === 2) { - return number + '-ри'; - } else if (lastDigit === 7 || lastDigit === 8) { - return number + '-ми'; - } else { - return number + '-ти'; - } - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 7th is the first week of the year. - } - }); - - //! moment.js locale configuration - - hooks.defineLocale('ml', { - months : 'ജനുവരി_ഫെബ്രുവരി_മാർച്ച്_ഏപ്രിൽ_മേയ്_ജൂൺ_ജൂലൈ_ഓഗസ്റ്റ്_സെപ്റ്റംബർ_ഒക്ടോബർ_നവംബർ_ഡിസംബർ'.split('_'), - monthsShort : 'ജനു._ഫെബ്രു._മാർ._ഏപ്രി._മേയ്_ജൂൺ_ജൂലൈ._ഓഗ._സെപ്റ്റ._ഒക്ടോ._നവം._ഡിസം.'.split('_'), - monthsParseExact : true, - weekdays : 'ഞായറാഴ്ച_തിങ്കളാഴ്ച_ചൊവ്വാഴ്ച_ബുധനാഴ്ച_വ്യാഴാഴ്ച_വെള്ളിയാഴ്ച_ശനിയാഴ്ച'.split('_'), - weekdaysShort : 'ഞായർ_തിങ്കൾ_ചൊവ്വ_ബുധൻ_വ്യാഴം_വെള്ളി_ശനി'.split('_'), - weekdaysMin : 'ഞാ_തി_ചൊ_ബു_വ്യാ_വെ_ശ'.split('_'), - longDateFormat : { - LT : 'A h:mm -നു', - LTS : 'A h:mm:ss -നു', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY, A h:mm -നു', - LLLL : 'dddd, D MMMM YYYY, A h:mm -നു' - }, - calendar : { - sameDay : '[ഇന്ന്] LT', - nextDay : '[നാളെ] LT', - nextWeek : 'dddd, LT', - lastDay : '[ഇന്നലെ] LT', - lastWeek : '[കഴിഞ്ഞ] dddd, LT', - sameElse : 'L' - }, - relativeTime : { - future : '%s കഴിഞ്ഞ്', - past : '%s മുൻപ്', - s : 'അൽപ നിമിഷങ്ങൾ', - ss : '%d സെക്കൻഡ്', - m : 'ഒരു മിനിറ്റ്', - mm : '%d മിനിറ്റ്', - h : 'ഒരു മണിക്കൂർ', - hh : '%d മണിക്കൂർ', - d : 'ഒരു ദിവസം', - dd : '%d ദിവസം', - M : 'ഒരു മാസം', - MM : '%d മാസം', - y : 'ഒരു വർഷം', - yy : '%d വർഷം' - }, - meridiemParse: /രാത്രി|രാവിലെ|ഉച്ച കഴിഞ്ഞ്|വൈകുന്നേരം|രാത്രി/i, - meridiemHour : function (hour, meridiem) { - if (hour === 12) { - hour = 0; - } - if ((meridiem === 'രാത്രി' && hour >= 4) || - meridiem === 'ഉച്ച കഴിഞ്ഞ്' || - meridiem === 'വൈകുന്നേരം') { - return hour + 12; - } else { - return hour; - } - }, - meridiem : function (hour, minute, isLower) { - if (hour < 4) { - return 'രാത്രി'; - } else if (hour < 12) { - return 'രാവിലെ'; - } else if (hour < 17) { - return 'ഉച്ച കഴിഞ്ഞ്'; - } else if (hour < 20) { - return 'വൈകുന്നേരം'; - } else { - return 'രാത്രി'; - } - } - }); - - //! moment.js locale configuration - - function translate$7(number, withoutSuffix, key, isFuture) { - switch (key) { - case 's': - return withoutSuffix ? 'хэдхэн секунд' : 'хэдхэн секундын'; - case 'ss': - return number + (withoutSuffix ? ' секунд' : ' секундын'); - case 'm': - case 'mm': - return number + (withoutSuffix ? ' минут' : ' минутын'); - case 'h': - case 'hh': - return number + (withoutSuffix ? ' цаг' : ' цагийн'); - case 'd': - case 'dd': - return number + (withoutSuffix ? ' өдөр' : ' өдрийн'); - case 'M': - case 'MM': - return number + (withoutSuffix ? ' сар' : ' сарын'); - case 'y': - case 'yy': - return number + (withoutSuffix ? ' жил' : ' жилийн'); - default: - return number; - } - } - - hooks.defineLocale('mn', { - months : 'Нэгдүгээр сар_Хоёрдугаар сар_Гуравдугаар сар_Дөрөвдүгээр сар_Тавдугаар сар_Зургадугаар сар_Долдугаар сар_Наймдугаар сар_Есдүгээр сар_Аравдугаар сар_Арван нэгдүгээр сар_Арван хоёрдугаар сар'.split('_'), - monthsShort : '1 сар_2 сар_3 сар_4 сар_5 сар_6 сар_7 сар_8 сар_9 сар_10 сар_11 сар_12 сар'.split('_'), - monthsParseExact : true, - weekdays : 'Ням_Даваа_Мягмар_Лхагва_Пүрэв_Баасан_Бямба'.split('_'), - weekdaysShort : 'Ням_Дав_Мяг_Лха_Пүр_Баа_Бям'.split('_'), - weekdaysMin : 'Ня_Да_Мя_Лх_Пү_Ба_Бя'.split('_'), - weekdaysParseExact : true, - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'YYYY-MM-DD', - LL : 'YYYY оны MMMMын D', - LLL : 'YYYY оны MMMMын D HH:mm', - LLLL : 'dddd, YYYY оны MMMMын D HH:mm' - }, - meridiemParse: /ҮӨ|ҮХ/i, - isPM : function (input) { - return input === 'ҮХ'; - }, - meridiem : function (hour, minute, isLower) { - if (hour < 12) { - return 'ҮӨ'; - } else { - return 'ҮХ'; - } - }, - calendar : { - sameDay : '[Өнөөдөр] LT', - nextDay : '[Маргааш] LT', - nextWeek : '[Ирэх] dddd LT', - lastDay : '[Өчигдөр] LT', - lastWeek : '[Өнгөрсөн] dddd LT', - sameElse : 'L' - }, - relativeTime : { - future : '%s дараа', - past : '%s өмнө', - s : translate$7, - ss : translate$7, - m : translate$7, - mm : translate$7, - h : translate$7, - hh : translate$7, - d : translate$7, - dd : translate$7, - M : translate$7, - MM : translate$7, - y : translate$7, - yy : translate$7 - }, - dayOfMonthOrdinalParse: /\d{1,2} өдөр/, - ordinal : function (number, period) { - switch (period) { - case 'd': - case 'D': - case 'DDD': - return number + ' өдөр'; - default: - return number; - } - } - }); - - //! moment.js locale configuration - - var symbolMap$b = { - '1': '१', - '2': '२', - '3': '३', - '4': '४', - '5': '५', - '6': '६', - '7': '७', - '8': '८', - '9': '९', - '0': '०' - }, - numberMap$a = { - '१': '1', - '२': '2', - '३': '3', - '४': '4', - '५': '5', - '६': '6', - '७': '7', - '८': '8', - '९': '9', - '०': '0' - }; - - function relativeTimeMr(number, withoutSuffix, string, isFuture) - { - var output = ''; - if (withoutSuffix) { - switch (string) { - case 's': output = 'काही सेकंद'; break; - case 'ss': output = '%d सेकंद'; break; - case 'm': output = 'एक मिनिट'; break; - case 'mm': output = '%d मिनिटे'; break; - case 'h': output = 'एक तास'; break; - case 'hh': output = '%d तास'; break; - case 'd': output = 'एक दिवस'; break; - case 'dd': output = '%d दिवस'; break; - case 'M': output = 'एक महिना'; break; - case 'MM': output = '%d महिने'; break; - case 'y': output = 'एक वर्ष'; break; - case 'yy': output = '%d वर्षे'; break; - } - } - else { - switch (string) { - case 's': output = 'काही सेकंदां'; break; - case 'ss': output = '%d सेकंदां'; break; - case 'm': output = 'एका मिनिटा'; break; - case 'mm': output = '%d मिनिटां'; break; - case 'h': output = 'एका तासा'; break; - case 'hh': output = '%d तासां'; break; - case 'd': output = 'एका दिवसा'; break; - case 'dd': output = '%d दिवसां'; break; - case 'M': output = 'एका महिन्या'; break; - case 'MM': output = '%d महिन्यां'; break; - case 'y': output = 'एका वर्षा'; break; - case 'yy': output = '%d वर्षां'; break; - } - } - return output.replace(/%d/i, number); - } - - hooks.defineLocale('mr', { - months : 'जानेवारी_फेब्रुवारी_मार्च_एप्रिल_मे_जून_जुलै_ऑगस्ट_सप्टेंबर_ऑक्टोबर_नोव्हेंबर_डिसेंबर'.split('_'), - monthsShort: 'जाने._फेब्रु._मार्च._एप्रि._मे._जून._जुलै._ऑग._सप्टें._ऑक्टो._नोव्हें._डिसें.'.split('_'), - monthsParseExact : true, - weekdays : 'रविवार_सोमवार_मंगळवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split('_'), - weekdaysShort : 'रवि_सोम_मंगळ_बुध_गुरू_शुक्र_शनि'.split('_'), - weekdaysMin : 'र_सो_मं_बु_गु_शु_श'.split('_'), - longDateFormat : { - LT : 'A h:mm वाजता', - LTS : 'A h:mm:ss वाजता', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY, A h:mm वाजता', - LLLL : 'dddd, D MMMM YYYY, A h:mm वाजता' - }, - calendar : { - sameDay : '[आज] LT', - nextDay : '[उद्या] LT', - nextWeek : 'dddd, LT', - lastDay : '[काल] LT', - lastWeek: '[मागील] dddd, LT', - sameElse : 'L' - }, - relativeTime : { - future: '%sमध्ये', - past: '%sपूर्वी', - s: relativeTimeMr, - ss: relativeTimeMr, - m: relativeTimeMr, - mm: relativeTimeMr, - h: relativeTimeMr, - hh: relativeTimeMr, - d: relativeTimeMr, - dd: relativeTimeMr, - M: relativeTimeMr, - MM: relativeTimeMr, - y: relativeTimeMr, - yy: relativeTimeMr - }, - preparse: function (string) { - return string.replace(/[१२३४५६७८९०]/g, function (match) { - return numberMap$a[match]; - }); - }, - postformat: function (string) { - return string.replace(/\d/g, function (match) { - return symbolMap$b[match]; - }); - }, - meridiemParse: /रात्री|सकाळी|दुपारी|सायंकाळी/, - meridiemHour : function (hour, meridiem) { - if (hour === 12) { - hour = 0; - } - if (meridiem === 'रात्री') { - return hour < 4 ? hour : hour + 12; - } else if (meridiem === 'सकाळी') { - return hour; - } else if (meridiem === 'दुपारी') { - return hour >= 10 ? hour : hour + 12; - } else if (meridiem === 'सायंकाळी') { - return hour + 12; - } - }, - meridiem: function (hour, minute, isLower) { - if (hour < 4) { - return 'रात्री'; - } else if (hour < 10) { - return 'सकाळी'; - } else if (hour < 17) { - return 'दुपारी'; - } else if (hour < 20) { - return 'सायंकाळी'; - } else { - return 'रात्री'; - } - }, - week : { - dow : 0, // Sunday is the first day of the week. - doy : 6 // The week that contains Jan 6th is the first week of the year. - } - }); - - //! moment.js locale configuration - - hooks.defineLocale('ms-my', { - months : 'Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember'.split('_'), - monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis'.split('_'), - weekdays : 'Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu'.split('_'), - weekdaysShort : 'Ahd_Isn_Sel_Rab_Kha_Jum_Sab'.split('_'), - weekdaysMin : 'Ah_Is_Sl_Rb_Km_Jm_Sb'.split('_'), - longDateFormat : { - LT : 'HH.mm', - LTS : 'HH.mm.ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY [pukul] HH.mm', - LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm' - }, - meridiemParse: /pagi|tengahari|petang|malam/, - meridiemHour: function (hour, meridiem) { - if (hour === 12) { - hour = 0; - } - if (meridiem === 'pagi') { - return hour; - } else if (meridiem === 'tengahari') { - return hour >= 11 ? hour : hour + 12; - } else if (meridiem === 'petang' || meridiem === 'malam') { - return hour + 12; - } - }, - meridiem : function (hours, minutes, isLower) { - if (hours < 11) { - return 'pagi'; - } else if (hours < 15) { - return 'tengahari'; - } else if (hours < 19) { - return 'petang'; - } else { - return 'malam'; - } - }, - calendar : { - sameDay : '[Hari ini pukul] LT', - nextDay : '[Esok pukul] LT', - nextWeek : 'dddd [pukul] LT', - lastDay : '[Kelmarin pukul] LT', - lastWeek : 'dddd [lepas pukul] LT', - sameElse : 'L' - }, - relativeTime : { - future : 'dalam %s', - past : '%s yang lepas', - s : 'beberapa saat', - ss : '%d saat', - m : 'seminit', - mm : '%d minit', - h : 'sejam', - hh : '%d jam', - d : 'sehari', - dd : '%d hari', - M : 'sebulan', - MM : '%d bulan', - y : 'setahun', - yy : '%d tahun' - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 7th is the first week of the year. - } - }); - - //! moment.js locale configuration - - hooks.defineLocale('ms', { - months : 'Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember'.split('_'), - monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis'.split('_'), - weekdays : 'Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu'.split('_'), - weekdaysShort : 'Ahd_Isn_Sel_Rab_Kha_Jum_Sab'.split('_'), - weekdaysMin : 'Ah_Is_Sl_Rb_Km_Jm_Sb'.split('_'), - longDateFormat : { - LT : 'HH.mm', - LTS : 'HH.mm.ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY [pukul] HH.mm', - LLLL : 'dddd, D MMMM YYYY [pukul] HH.mm' - }, - meridiemParse: /pagi|tengahari|petang|malam/, - meridiemHour: function (hour, meridiem) { - if (hour === 12) { - hour = 0; - } - if (meridiem === 'pagi') { - return hour; - } else if (meridiem === 'tengahari') { - return hour >= 11 ? hour : hour + 12; - } else if (meridiem === 'petang' || meridiem === 'malam') { - return hour + 12; - } - }, - meridiem : function (hours, minutes, isLower) { - if (hours < 11) { - return 'pagi'; - } else if (hours < 15) { - return 'tengahari'; - } else if (hours < 19) { - return 'petang'; - } else { - return 'malam'; - } - }, - calendar : { - sameDay : '[Hari ini pukul] LT', - nextDay : '[Esok pukul] LT', - nextWeek : 'dddd [pukul] LT', - lastDay : '[Kelmarin pukul] LT', - lastWeek : 'dddd [lepas pukul] LT', - sameElse : 'L' - }, - relativeTime : { - future : 'dalam %s', - past : '%s yang lepas', - s : 'beberapa saat', - ss : '%d saat', - m : 'seminit', - mm : '%d minit', - h : 'sejam', - hh : '%d jam', - d : 'sehari', - dd : '%d hari', - M : 'sebulan', - MM : '%d bulan', - y : 'setahun', - yy : '%d tahun' - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 7th is the first week of the year. - } - }); - - //! moment.js locale configuration - - hooks.defineLocale('mt', { - months : 'Jannar_Frar_Marzu_April_Mejju_Ġunju_Lulju_Awwissu_Settembru_Ottubru_Novembru_Diċembru'.split('_'), - monthsShort : 'Jan_Fra_Mar_Apr_Mej_Ġun_Lul_Aww_Set_Ott_Nov_Diċ'.split('_'), - weekdays : 'Il-Ħadd_It-Tnejn_It-Tlieta_L-Erbgħa_Il-Ħamis_Il-Ġimgħa_Is-Sibt'.split('_'), - weekdaysShort : 'Ħad_Tne_Tli_Erb_Ħam_Ġim_Sib'.split('_'), - weekdaysMin : 'Ħa_Tn_Tl_Er_Ħa_Ġi_Si'.split('_'), - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd, D MMMM YYYY HH:mm' - }, - calendar : { - sameDay : '[Illum fil-]LT', - nextDay : '[Għada fil-]LT', - nextWeek : 'dddd [fil-]LT', - lastDay : '[Il-bieraħ fil-]LT', - lastWeek : 'dddd [li għadda] [fil-]LT', - sameElse : 'L' - }, - relativeTime : { - future : 'f’ %s', - past : '%s ilu', - s : 'ftit sekondi', - ss : '%d sekondi', - m : 'minuta', - mm : '%d minuti', - h : 'siegħa', - hh : '%d siegħat', - d : 'ġurnata', - dd : '%d ġranet', - M : 'xahar', - MM : '%d xhur', - y : 'sena', - yy : '%d sni' - }, - dayOfMonthOrdinalParse : /\d{1,2}º/, - ordinal: '%dº', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); - - //! moment.js locale configuration - - var symbolMap$c = { - '1': '၁', - '2': '၂', - '3': '၃', - '4': '၄', - '5': '၅', - '6': '၆', - '7': '၇', - '8': '၈', - '9': '၉', - '0': '၀' - }, numberMap$b = { - '၁': '1', - '၂': '2', - '၃': '3', - '၄': '4', - '၅': '5', - '၆': '6', - '၇': '7', - '၈': '8', - '၉': '9', - '၀': '0' - }; - - hooks.defineLocale('my', { - months: 'ဇန်နဝါရီ_ဖေဖော်ဝါရီ_မတ်_ဧပြီ_မေ_ဇွန်_ဇူလိုင်_သြဂုတ်_စက်တင်ဘာ_အောက်တိုဘာ_နိုဝင်ဘာ_ဒီဇင်ဘာ'.split('_'), - monthsShort: 'ဇန်_ဖေ_မတ်_ပြီ_မေ_ဇွန်_လိုင်_သြ_စက်_အောက်_နို_ဒီ'.split('_'), - weekdays: 'တနင်္ဂနွေ_တနင်္လာ_အင်္ဂါ_ဗုဒ္ဓဟူး_ကြာသပတေး_သောကြာ_စနေ'.split('_'), - weekdaysShort: 'နွေ_လာ_ဂါ_ဟူး_ကြာ_သော_နေ'.split('_'), - weekdaysMin: 'နွေ_လာ_ဂါ_ဟူး_ကြာ_သော_နေ'.split('_'), - - longDateFormat: { - LT: 'HH:mm', - LTS: 'HH:mm:ss', - L: 'DD/MM/YYYY', - LL: 'D MMMM YYYY', - LLL: 'D MMMM YYYY HH:mm', - LLLL: 'dddd D MMMM YYYY HH:mm' - }, - calendar: { - sameDay: '[ယနေ.] LT [မှာ]', - nextDay: '[မနက်ဖြန်] LT [မှာ]', - nextWeek: 'dddd LT [မှာ]', - lastDay: '[မနေ.က] LT [မှာ]', - lastWeek: '[ပြီးခဲ့သော] dddd LT [မှာ]', - sameElse: 'L' - }, - relativeTime: { - future: 'လာမည့် %s မှာ', - past: 'လွန်ခဲ့သော %s က', - s: 'စက္ကန်.အနည်းငယ်', - ss : '%d စက္ကန့်', - m: 'တစ်မိနစ်', - mm: '%d မိနစ်', - h: 'တစ်နာရီ', - hh: '%d နာရီ', - d: 'တစ်ရက်', - dd: '%d ရက်', - M: 'တစ်လ', - MM: '%d လ', - y: 'တစ်နှစ်', - yy: '%d နှစ်' - }, - preparse: function (string) { - return string.replace(/[၁၂၃၄၅၆၇၈၉၀]/g, function (match) { - return numberMap$b[match]; - }); - }, - postformat: function (string) { - return string.replace(/\d/g, function (match) { - return symbolMap$c[match]; - }); - }, - week: { - dow: 1, // Monday is the first day of the week. - doy: 4 // The week that contains Jan 4th is the first week of the year. - } - }); - - //! moment.js locale configuration - - hooks.defineLocale('nb', { - months : 'januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember'.split('_'), - monthsShort : 'jan._feb._mars_april_mai_juni_juli_aug._sep._okt._nov._des.'.split('_'), - monthsParseExact : true, - weekdays : 'søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag'.split('_'), - weekdaysShort : 'sø._ma._ti._on._to._fr._lø.'.split('_'), - weekdaysMin : 'sø_ma_ti_on_to_fr_lø'.split('_'), - weekdaysParseExact : true, - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD.MM.YYYY', - LL : 'D. MMMM YYYY', - LLL : 'D. MMMM YYYY [kl.] HH:mm', - LLLL : 'dddd D. MMMM YYYY [kl.] HH:mm' - }, - calendar : { - sameDay: '[i dag kl.] LT', - nextDay: '[i morgen kl.] LT', - nextWeek: 'dddd [kl.] LT', - lastDay: '[i går kl.] LT', - lastWeek: '[forrige] dddd [kl.] LT', - sameElse: 'L' - }, - relativeTime : { - future : 'om %s', - past : '%s siden', - s : 'noen sekunder', - ss : '%d sekunder', - m : 'ett minutt', - mm : '%d minutter', - h : 'en time', - hh : '%d timer', - d : 'en dag', - dd : '%d dager', - M : 'en måned', - MM : '%d måneder', - y : 'ett år', - yy : '%d år' - }, - dayOfMonthOrdinalParse: /\d{1,2}\./, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); - - //! moment.js locale configuration - - var symbolMap$d = { - '1': '१', - '2': '२', - '3': '३', - '4': '४', - '5': '५', - '6': '६', - '7': '७', - '8': '८', - '9': '९', - '0': '०' - }, - numberMap$c = { - '१': '1', - '२': '2', - '३': '3', - '४': '4', - '५': '5', - '६': '6', - '७': '7', - '८': '8', - '९': '9', - '०': '0' - }; - - hooks.defineLocale('ne', { - months : 'जनवरी_फेब्रुवरी_मार्च_अप्रिल_मई_जुन_जुलाई_अगष्ट_सेप्टेम्बर_अक्टोबर_नोभेम्बर_डिसेम्बर'.split('_'), - monthsShort : 'जन._फेब्रु._मार्च_अप्रि._मई_जुन_जुलाई._अग._सेप्ट._अक्टो._नोभे._डिसे.'.split('_'), - monthsParseExact : true, - weekdays : 'आइतबार_सोमबार_मङ्गलबार_बुधबार_बिहिबार_शुक्रबार_शनिबार'.split('_'), - weekdaysShort : 'आइत._सोम._मङ्गल._बुध._बिहि._शुक्र._शनि.'.split('_'), - weekdaysMin : 'आ._सो._मं._बु._बि._शु._श.'.split('_'), - weekdaysParseExact : true, - longDateFormat : { - LT : 'Aको h:mm बजे', - LTS : 'Aको h:mm:ss बजे', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY, Aको h:mm बजे', - LLLL : 'dddd, D MMMM YYYY, Aको h:mm बजे' - }, - preparse: function (string) { - return string.replace(/[१२३४५६७८९०]/g, function (match) { - return numberMap$c[match]; - }); - }, - postformat: function (string) { - return string.replace(/\d/g, function (match) { - return symbolMap$d[match]; - }); - }, - meridiemParse: /राति|बिहान|दिउँसो|साँझ/, - meridiemHour : function (hour, meridiem) { - if (hour === 12) { - hour = 0; - } - if (meridiem === 'राति') { - return hour < 4 ? hour : hour + 12; - } else if (meridiem === 'बिहान') { - return hour; - } else if (meridiem === 'दिउँसो') { - return hour >= 10 ? hour : hour + 12; - } else if (meridiem === 'साँझ') { - return hour + 12; - } - }, - meridiem : function (hour, minute, isLower) { - if (hour < 3) { - return 'राति'; - } else if (hour < 12) { - return 'बिहान'; - } else if (hour < 16) { - return 'दिउँसो'; - } else if (hour < 20) { - return 'साँझ'; - } else { - return 'राति'; - } - }, - calendar : { - sameDay : '[आज] LT', - nextDay : '[भोलि] LT', - nextWeek : '[आउँदो] dddd[,] LT', - lastDay : '[हिजो] LT', - lastWeek : '[गएको] dddd[,] LT', - sameElse : 'L' - }, - relativeTime : { - future : '%sमा', - past : '%s अगाडि', - s : 'केही क्षण', - ss : '%d सेकेण्ड', - m : 'एक मिनेट', - mm : '%d मिनेट', - h : 'एक घण्टा', - hh : '%d घण्टा', - d : 'एक दिन', - dd : '%d दिन', - M : 'एक महिना', - MM : '%d महिना', - y : 'एक बर्ष', - yy : '%d बर्ष' - }, - week : { - dow : 0, // Sunday is the first day of the week. - doy : 6 // The week that contains Jan 6th is the first week of the year. - } - }); - - //! moment.js locale configuration - - var monthsShortWithDots$1 = 'jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.'.split('_'), - monthsShortWithoutDots$1 = 'jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec'.split('_'); - - var monthsParse$2 = [/^jan/i, /^feb/i, /^maart|mrt.?$/i, /^apr/i, /^mei$/i, /^jun[i.]?$/i, /^jul[i.]?$/i, /^aug/i, /^sep/i, /^okt/i, /^nov/i, /^dec/i]; - var monthsRegex$3 = /^(januari|februari|maart|april|mei|ju[nl]i|augustus|september|oktober|november|december|jan\.?|feb\.?|mrt\.?|apr\.?|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i; - - hooks.defineLocale('nl-be', { - months : 'januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december'.split('_'), - monthsShort : function (m, format) { - if (!m) { - return monthsShortWithDots$1; - } else if (/-MMM-/.test(format)) { - return monthsShortWithoutDots$1[m.month()]; - } else { - return monthsShortWithDots$1[m.month()]; - } - }, - - monthsRegex: monthsRegex$3, - monthsShortRegex: monthsRegex$3, - monthsStrictRegex: /^(januari|februari|maart|april|mei|ju[nl]i|augustus|september|oktober|november|december)/i, - monthsShortStrictRegex: /^(jan\.?|feb\.?|mrt\.?|apr\.?|mei|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i, - - monthsParse : monthsParse$2, - longMonthsParse : monthsParse$2, - shortMonthsParse : monthsParse$2, - - weekdays : 'zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag'.split('_'), - weekdaysShort : 'zo._ma._di._wo._do._vr._za.'.split('_'), - weekdaysMin : 'zo_ma_di_wo_do_vr_za'.split('_'), - weekdaysParseExact : true, - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd D MMMM YYYY HH:mm' - }, - calendar : { - sameDay: '[vandaag om] LT', - nextDay: '[morgen om] LT', - nextWeek: 'dddd [om] LT', - lastDay: '[gisteren om] LT', - lastWeek: '[afgelopen] dddd [om] LT', - sameElse: 'L' - }, - relativeTime : { - future : 'over %s', - past : '%s geleden', - s : 'een paar seconden', - ss : '%d seconden', - m : 'één minuut', - mm : '%d minuten', - h : 'één uur', - hh : '%d uur', - d : 'één dag', - dd : '%d dagen', - M : 'één maand', - MM : '%d maanden', - y : 'één jaar', - yy : '%d jaar' - }, - dayOfMonthOrdinalParse: /\d{1,2}(ste|de)/, - ordinal : function (number) { - return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de'); - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); - - //! moment.js locale configuration - - var monthsShortWithDots$2 = 'jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.'.split('_'), - monthsShortWithoutDots$2 = 'jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec'.split('_'); - - var monthsParse$3 = [/^jan/i, /^feb/i, /^maart|mrt.?$/i, /^apr/i, /^mei$/i, /^jun[i.]?$/i, /^jul[i.]?$/i, /^aug/i, /^sep/i, /^okt/i, /^nov/i, /^dec/i]; - var monthsRegex$4 = /^(januari|februari|maart|april|mei|ju[nl]i|augustus|september|oktober|november|december|jan\.?|feb\.?|mrt\.?|apr\.?|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i; - - hooks.defineLocale('nl', { - months : 'januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december'.split('_'), - monthsShort : function (m, format) { - if (!m) { - return monthsShortWithDots$2; - } else if (/-MMM-/.test(format)) { - return monthsShortWithoutDots$2[m.month()]; - } else { - return monthsShortWithDots$2[m.month()]; - } - }, - - monthsRegex: monthsRegex$4, - monthsShortRegex: monthsRegex$4, - monthsStrictRegex: /^(januari|februari|maart|april|mei|ju[nl]i|augustus|september|oktober|november|december)/i, - monthsShortStrictRegex: /^(jan\.?|feb\.?|mrt\.?|apr\.?|mei|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i, - - monthsParse : monthsParse$3, - longMonthsParse : monthsParse$3, - shortMonthsParse : monthsParse$3, - - weekdays : 'zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag'.split('_'), - weekdaysShort : 'zo._ma._di._wo._do._vr._za.'.split('_'), - weekdaysMin : 'zo_ma_di_wo_do_vr_za'.split('_'), - weekdaysParseExact : true, - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD-MM-YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd D MMMM YYYY HH:mm' - }, - calendar : { - sameDay: '[vandaag om] LT', - nextDay: '[morgen om] LT', - nextWeek: 'dddd [om] LT', - lastDay: '[gisteren om] LT', - lastWeek: '[afgelopen] dddd [om] LT', - sameElse: 'L' - }, - relativeTime : { - future : 'over %s', - past : '%s geleden', - s : 'een paar seconden', - ss : '%d seconden', - m : 'één minuut', - mm : '%d minuten', - h : 'één uur', - hh : '%d uur', - d : 'één dag', - dd : '%d dagen', - M : 'één maand', - MM : '%d maanden', - y : 'één jaar', - yy : '%d jaar' - }, - dayOfMonthOrdinalParse: /\d{1,2}(ste|de)/, - ordinal : function (number) { - return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de'); - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); - - //! moment.js locale configuration - - hooks.defineLocale('nn', { - months : 'januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember'.split('_'), - monthsShort : 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'), - weekdays : 'sundag_måndag_tysdag_onsdag_torsdag_fredag_laurdag'.split('_'), - weekdaysShort : 'sun_mån_tys_ons_tor_fre_lau'.split('_'), - weekdaysMin : 'su_må_ty_on_to_fr_lø'.split('_'), - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD.MM.YYYY', - LL : 'D. MMMM YYYY', - LLL : 'D. MMMM YYYY [kl.] H:mm', - LLLL : 'dddd D. MMMM YYYY [kl.] HH:mm' - }, - calendar : { - sameDay: '[I dag klokka] LT', - nextDay: '[I morgon klokka] LT', - nextWeek: 'dddd [klokka] LT', - lastDay: '[I går klokka] LT', - lastWeek: '[Føregåande] dddd [klokka] LT', - sameElse: 'L' - }, - relativeTime : { - future : 'om %s', - past : '%s sidan', - s : 'nokre sekund', - ss : '%d sekund', - m : 'eit minutt', - mm : '%d minutt', - h : 'ein time', - hh : '%d timar', - d : 'ein dag', - dd : '%d dagar', - M : 'ein månad', - MM : '%d månader', - y : 'eit år', - yy : '%d år' - }, - dayOfMonthOrdinalParse: /\d{1,2}\./, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); - - //! moment.js locale configuration - - var symbolMap$e = { - '1': '੧', - '2': '੨', - '3': '੩', - '4': '੪', - '5': '੫', - '6': '੬', - '7': '੭', - '8': '੮', - '9': '੯', - '0': '੦' - }, - numberMap$d = { - '੧': '1', - '੨': '2', - '੩': '3', - '੪': '4', - '੫': '5', - '੬': '6', - '੭': '7', - '੮': '8', - '੯': '9', - '੦': '0' - }; - - hooks.defineLocale('pa-in', { - // There are months name as per Nanakshahi Calendar but they are not used as rigidly in modern Punjabi. - months : 'ਜਨਵਰੀ_ਫ਼ਰਵਰੀ_ਮਾਰਚ_ਅਪ੍ਰੈਲ_ਮਈ_ਜੂਨ_ਜੁਲਾਈ_ਅਗਸਤ_ਸਤੰਬਰ_ਅਕਤੂਬਰ_ਨਵੰਬਰ_ਦਸੰਬਰ'.split('_'), - monthsShort : 'ਜਨਵਰੀ_ਫ਼ਰਵਰੀ_ਮਾਰਚ_ਅਪ੍ਰੈਲ_ਮਈ_ਜੂਨ_ਜੁਲਾਈ_ਅਗਸਤ_ਸਤੰਬਰ_ਅਕਤੂਬਰ_ਨਵੰਬਰ_ਦਸੰਬਰ'.split('_'), - weekdays : 'ਐਤਵਾਰ_ਸੋਮਵਾਰ_ਮੰਗਲਵਾਰ_ਬੁਧਵਾਰ_ਵੀਰਵਾਰ_ਸ਼ੁੱਕਰਵਾਰ_ਸ਼ਨੀਚਰਵਾਰ'.split('_'), - weekdaysShort : 'ਐਤ_ਸੋਮ_ਮੰਗਲ_ਬੁਧ_ਵੀਰ_ਸ਼ੁਕਰ_ਸ਼ਨੀ'.split('_'), - weekdaysMin : 'ਐਤ_ਸੋਮ_ਮੰਗਲ_ਬੁਧ_ਵੀਰ_ਸ਼ੁਕਰ_ਸ਼ਨੀ'.split('_'), - longDateFormat : { - LT : 'A h:mm ਵਜੇ', - LTS : 'A h:mm:ss ਵਜੇ', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY, A h:mm ਵਜੇ', - LLLL : 'dddd, D MMMM YYYY, A h:mm ਵਜੇ' - }, - calendar : { - sameDay : '[ਅਜ] LT', - nextDay : '[ਕਲ] LT', - nextWeek : '[ਅਗਲਾ] dddd, LT', - lastDay : '[ਕਲ] LT', - lastWeek : '[ਪਿਛਲੇ] dddd, LT', - sameElse : 'L' - }, - relativeTime : { - future : '%s ਵਿੱਚ', - past : '%s ਪਿਛਲੇ', - s : 'ਕੁਝ ਸਕਿੰਟ', - ss : '%d ਸਕਿੰਟ', - m : 'ਇਕ ਮਿੰਟ', - mm : '%d ਮਿੰਟ', - h : 'ਇੱਕ ਘੰਟਾ', - hh : '%d ਘੰਟੇ', - d : 'ਇੱਕ ਦਿਨ', - dd : '%d ਦਿਨ', - M : 'ਇੱਕ ਮਹੀਨਾ', - MM : '%d ਮਹੀਨੇ', - y : 'ਇੱਕ ਸਾਲ', - yy : '%d ਸਾਲ' - }, - preparse: function (string) { - return string.replace(/[੧੨੩੪੫੬੭੮੯੦]/g, function (match) { - return numberMap$d[match]; - }); - }, - postformat: function (string) { - return string.replace(/\d/g, function (match) { - return symbolMap$e[match]; - }); - }, - // Punjabi notation for meridiems are quite fuzzy in practice. While there exists - // a rigid notion of a 'Pahar' it is not used as rigidly in modern Punjabi. - meridiemParse: /ਰਾਤ|ਸਵੇਰ|ਦੁਪਹਿਰ|ਸ਼ਾਮ/, - meridiemHour : function (hour, meridiem) { - if (hour === 12) { - hour = 0; - } - if (meridiem === 'ਰਾਤ') { - return hour < 4 ? hour : hour + 12; - } else if (meridiem === 'ਸਵੇਰ') { - return hour; - } else if (meridiem === 'ਦੁਪਹਿਰ') { - return hour >= 10 ? hour : hour + 12; - } else if (meridiem === 'ਸ਼ਾਮ') { - return hour + 12; - } - }, - meridiem : function (hour, minute, isLower) { - if (hour < 4) { - return 'ਰਾਤ'; - } else if (hour < 10) { - return 'ਸਵੇਰ'; - } else if (hour < 17) { - return 'ਦੁਪਹਿਰ'; - } else if (hour < 20) { - return 'ਸ਼ਾਮ'; - } else { - return 'ਰਾਤ'; - } - }, - week : { - dow : 0, // Sunday is the first day of the week. - doy : 6 // The week that contains Jan 6th is the first week of the year. - } - }); - - //! moment.js locale configuration - - var monthsNominative = 'styczeń_luty_marzec_kwiecień_maj_czerwiec_lipiec_sierpień_wrzesień_październik_listopad_grudzień'.split('_'), - monthsSubjective = 'stycznia_lutego_marca_kwietnia_maja_czerwca_lipca_sierpnia_września_października_listopada_grudnia'.split('_'); - function plural$3(n) { - return (n % 10 < 5) && (n % 10 > 1) && ((~~(n / 10) % 10) !== 1); - } - function translate$8(number, withoutSuffix, key) { - var result = number + ' '; - switch (key) { - case 'ss': - return result + (plural$3(number) ? 'sekundy' : 'sekund'); - case 'm': - return withoutSuffix ? 'minuta' : 'minutę'; - case 'mm': - return result + (plural$3(number) ? 'minuty' : 'minut'); - case 'h': - return withoutSuffix ? 'godzina' : 'godzinę'; - case 'hh': - return result + (plural$3(number) ? 'godziny' : 'godzin'); - case 'MM': - return result + (plural$3(number) ? 'miesiące' : 'miesięcy'); - case 'yy': - return result + (plural$3(number) ? 'lata' : 'lat'); - } - } - - hooks.defineLocale('pl', { - months : function (momentToFormat, format) { - if (!momentToFormat) { - return monthsNominative; - } else if (format === '') { - // Hack: if format empty we know this is used to generate - // RegExp by moment. Give then back both valid forms of months - // in RegExp ready format. - return '(' + monthsSubjective[momentToFormat.month()] + '|' + monthsNominative[momentToFormat.month()] + ')'; - } else if (/D MMMM/.test(format)) { - return monthsSubjective[momentToFormat.month()]; - } else { - return monthsNominative[momentToFormat.month()]; - } - }, - monthsShort : 'sty_lut_mar_kwi_maj_cze_lip_sie_wrz_paź_lis_gru'.split('_'), - weekdays : 'niedziela_poniedziałek_wtorek_środa_czwartek_piątek_sobota'.split('_'), - weekdaysShort : 'ndz_pon_wt_śr_czw_pt_sob'.split('_'), - weekdaysMin : 'Nd_Pn_Wt_Śr_Cz_Pt_So'.split('_'), - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD.MM.YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd, D MMMM YYYY HH:mm' - }, - calendar : { - sameDay: '[Dziś o] LT', - nextDay: '[Jutro o] LT', - nextWeek: function () { - switch (this.day()) { - case 0: - return '[W niedzielę o] LT'; - - case 2: - return '[We wtorek o] LT'; - - case 3: - return '[W środę o] LT'; - - case 6: - return '[W sobotę o] LT'; - - default: - return '[W] dddd [o] LT'; - } - }, - lastDay: '[Wczoraj o] LT', - lastWeek: function () { - switch (this.day()) { - case 0: - return '[W zeszłą niedzielę o] LT'; - case 3: - return '[W zeszłą środę o] LT'; - case 6: - return '[W zeszłą sobotę o] LT'; - default: - return '[W zeszły] dddd [o] LT'; - } - }, - sameElse: 'L' - }, - relativeTime : { - future : 'za %s', - past : '%s temu', - s : 'kilka sekund', - ss : translate$8, - m : translate$8, - mm : translate$8, - h : translate$8, - hh : translate$8, - d : '1 dzień', - dd : '%d dni', - M : 'miesiąc', - MM : translate$8, - y : 'rok', - yy : translate$8 - }, - dayOfMonthOrdinalParse: /\d{1,2}\./, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); - - //! moment.js locale configuration - - hooks.defineLocale('pt-br', { - months : 'janeiro_fevereiro_março_abril_maio_junho_julho_agosto_setembro_outubro_novembro_dezembro'.split('_'), - monthsShort : 'jan_fev_mar_abr_mai_jun_jul_ago_set_out_nov_dez'.split('_'), - weekdays : 'Domingo_Segunda-feira_Terça-feira_Quarta-feira_Quinta-feira_Sexta-feira_Sábado'.split('_'), - weekdaysShort : 'Dom_Seg_Ter_Qua_Qui_Sex_Sáb'.split('_'), - weekdaysMin : 'Do_2ª_3ª_4ª_5ª_6ª_Sá'.split('_'), - weekdaysParseExact : true, - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D [de] MMMM [de] YYYY', - LLL : 'D [de] MMMM [de] YYYY [às] HH:mm', - LLLL : 'dddd, D [de] MMMM [de] YYYY [às] HH:mm' - }, - calendar : { - sameDay: '[Hoje às] LT', - nextDay: '[Amanhã às] LT', - nextWeek: 'dddd [às] LT', - lastDay: '[Ontem às] LT', - lastWeek: function () { - return (this.day() === 0 || this.day() === 6) ? - '[Último] dddd [às] LT' : // Saturday + Sunday - '[Última] dddd [às] LT'; // Monday - Friday - }, - sameElse: 'L' - }, - relativeTime : { - future : 'em %s', - past : 'há %s', - s : 'poucos segundos', - ss : '%d segundos', - m : 'um minuto', - mm : '%d minutos', - h : 'uma hora', - hh : '%d horas', - d : 'um dia', - dd : '%d dias', - M : 'um mês', - MM : '%d meses', - y : 'um ano', - yy : '%d anos' - }, - dayOfMonthOrdinalParse: /\d{1,2}º/, - ordinal : '%dº' - }); - - //! moment.js locale configuration - - hooks.defineLocale('pt', { - months : 'janeiro_fevereiro_março_abril_maio_junho_julho_agosto_setembro_outubro_novembro_dezembro'.split('_'), - monthsShort : 'jan_fev_mar_abr_mai_jun_jul_ago_set_out_nov_dez'.split('_'), - weekdays : 'Domingo_Segunda-feira_Terça-feira_Quarta-feira_Quinta-feira_Sexta-feira_Sábado'.split('_'), - weekdaysShort : 'Dom_Seg_Ter_Qua_Qui_Sex_Sáb'.split('_'), - weekdaysMin : 'Do_2ª_3ª_4ª_5ª_6ª_Sá'.split('_'), - weekdaysParseExact : true, - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D [de] MMMM [de] YYYY', - LLL : 'D [de] MMMM [de] YYYY HH:mm', - LLLL : 'dddd, D [de] MMMM [de] YYYY HH:mm' - }, - calendar : { - sameDay: '[Hoje às] LT', - nextDay: '[Amanhã às] LT', - nextWeek: 'dddd [às] LT', - lastDay: '[Ontem às] LT', - lastWeek: function () { - return (this.day() === 0 || this.day() === 6) ? - '[Último] dddd [às] LT' : // Saturday + Sunday - '[Última] dddd [às] LT'; // Monday - Friday - }, - sameElse: 'L' - }, - relativeTime : { - future : 'em %s', - past : 'há %s', - s : 'segundos', - ss : '%d segundos', - m : 'um minuto', - mm : '%d minutos', - h : 'uma hora', - hh : '%d horas', - d : 'um dia', - dd : '%d dias', - M : 'um mês', - MM : '%d meses', - y : 'um ano', - yy : '%d anos' - }, - dayOfMonthOrdinalParse: /\d{1,2}º/, - ordinal : '%dº', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); - - //! moment.js locale configuration - - function relativeTimeWithPlural$2(number, withoutSuffix, key) { - var format = { - 'ss': 'secunde', - 'mm': 'minute', - 'hh': 'ore', - 'dd': 'zile', - 'MM': 'luni', - 'yy': 'ani' - }, - separator = ' '; - if (number % 100 >= 20 || (number >= 100 && number % 100 === 0)) { - separator = ' de '; - } - return number + separator + format[key]; - } - - hooks.defineLocale('ro', { - months : 'ianuarie_februarie_martie_aprilie_mai_iunie_iulie_august_septembrie_octombrie_noiembrie_decembrie'.split('_'), - monthsShort : 'ian._febr._mart._apr._mai_iun._iul._aug._sept._oct._nov._dec.'.split('_'), - monthsParseExact: true, - weekdays : 'duminică_luni_marți_miercuri_joi_vineri_sâmbătă'.split('_'), - weekdaysShort : 'Dum_Lun_Mar_Mie_Joi_Vin_Sâm'.split('_'), - weekdaysMin : 'Du_Lu_Ma_Mi_Jo_Vi_Sâ'.split('_'), - longDateFormat : { - LT : 'H:mm', - LTS : 'H:mm:ss', - L : 'DD.MM.YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY H:mm', - LLLL : 'dddd, D MMMM YYYY H:mm' - }, - calendar : { - sameDay: '[azi la] LT', - nextDay: '[mâine la] LT', - nextWeek: 'dddd [la] LT', - lastDay: '[ieri la] LT', - lastWeek: '[fosta] dddd [la] LT', - sameElse: 'L' - }, - relativeTime : { - future : 'peste %s', - past : '%s în urmă', - s : 'câteva secunde', - ss : relativeTimeWithPlural$2, - m : 'un minut', - mm : relativeTimeWithPlural$2, - h : 'o oră', - hh : relativeTimeWithPlural$2, - d : 'o zi', - dd : relativeTimeWithPlural$2, - M : 'o lună', - MM : relativeTimeWithPlural$2, - y : 'un an', - yy : relativeTimeWithPlural$2 - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 7th is the first week of the year. - } - }); - - //! moment.js locale configuration - - function plural$4(word, num) { - var forms = word.split('_'); - return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]); - } - function relativeTimeWithPlural$3(number, withoutSuffix, key) { - var format = { - 'ss': withoutSuffix ? 'секунда_секунды_секунд' : 'секунду_секунды_секунд', - 'mm': withoutSuffix ? 'минута_минуты_минут' : 'минуту_минуты_минут', - 'hh': 'час_часа_часов', - 'dd': 'день_дня_дней', - 'MM': 'месяц_месяца_месяцев', - 'yy': 'год_года_лет' - }; - if (key === 'm') { - return withoutSuffix ? 'минута' : 'минуту'; - } - else { - return number + ' ' + plural$4(format[key], +number); - } - } - var monthsParse$4 = [/^янв/i, /^фев/i, /^мар/i, /^апр/i, /^ма[йя]/i, /^июн/i, /^июл/i, /^авг/i, /^сен/i, /^окт/i, /^ноя/i, /^дек/i]; - - // http://new.gramota.ru/spravka/rules/139-prop : § 103 - // Сокращения месяцев: http://new.gramota.ru/spravka/buro/search-answer?s=242637 - // CLDR data: http://www.unicode.org/cldr/charts/28/summary/ru.html#1753 - hooks.defineLocale('ru', { - months : { - format: 'января_февраля_марта_апреля_мая_июня_июля_августа_сентября_октября_ноября_декабря'.split('_'), - standalone: 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_') - }, - monthsShort : { - // по CLDR именно "июл." и "июн.", но какой смысл менять букву на точку ? - format: 'янв._февр._мар._апр._мая_июня_июля_авг._сент._окт._нояб._дек.'.split('_'), - standalone: 'янв._февр._март_апр._май_июнь_июль_авг._сент._окт._нояб._дек.'.split('_') - }, - weekdays : { - standalone: 'воскресенье_понедельник_вторник_среда_четверг_пятница_суббота'.split('_'), - format: 'воскресенье_понедельник_вторник_среду_четверг_пятницу_субботу'.split('_'), - isFormat: /\[ ?[Вв] ?(?:прошлую|следующую|эту)? ?\] ?dddd/ - }, - weekdaysShort : 'вс_пн_вт_ср_чт_пт_сб'.split('_'), - weekdaysMin : 'вс_пн_вт_ср_чт_пт_сб'.split('_'), - monthsParse : monthsParse$4, - longMonthsParse : monthsParse$4, - shortMonthsParse : monthsParse$4, - - // полные названия с падежами, по три буквы, для некоторых, по 4 буквы, сокращения с точкой и без точки - monthsRegex: /^(январ[ья]|янв\.?|феврал[ья]|февр?\.?|марта?|мар\.?|апрел[ья]|апр\.?|ма[йя]|июн[ья]|июн\.?|июл[ья]|июл\.?|августа?|авг\.?|сентябр[ья]|сент?\.?|октябр[ья]|окт\.?|ноябр[ья]|нояб?\.?|декабр[ья]|дек\.?)/i, - - // копия предыдущего - monthsShortRegex: /^(январ[ья]|янв\.?|феврал[ья]|февр?\.?|марта?|мар\.?|апрел[ья]|апр\.?|ма[йя]|июн[ья]|июн\.?|июл[ья]|июл\.?|августа?|авг\.?|сентябр[ья]|сент?\.?|октябр[ья]|окт\.?|ноябр[ья]|нояб?\.?|декабр[ья]|дек\.?)/i, - - // полные названия с падежами - monthsStrictRegex: /^(январ[яь]|феврал[яь]|марта?|апрел[яь]|ма[яй]|июн[яь]|июл[яь]|августа?|сентябр[яь]|октябр[яь]|ноябр[яь]|декабр[яь])/i, - - // Выражение, которое соотвествует только сокращённым формам - monthsShortStrictRegex: /^(янв\.|февр?\.|мар[т.]|апр\.|ма[яй]|июн[ья.]|июл[ья.]|авг\.|сент?\.|окт\.|нояб?\.|дек\.)/i, - longDateFormat : { - LT : 'H:mm', - LTS : 'H:mm:ss', - L : 'DD.MM.YYYY', - LL : 'D MMMM YYYY г.', - LLL : 'D MMMM YYYY г., H:mm', - LLLL : 'dddd, D MMMM YYYY г., H:mm' - }, - calendar : { - sameDay: '[Сегодня, в] LT', - nextDay: '[Завтра, в] LT', - lastDay: '[Вчера, в] LT', - nextWeek: function (now) { - if (now.week() !== this.week()) { - switch (this.day()) { - case 0: - return '[В следующее] dddd, [в] LT'; - case 1: - case 2: - case 4: - return '[В следующий] dddd, [в] LT'; - case 3: - case 5: - case 6: - return '[В следующую] dddd, [в] LT'; - } - } else { - if (this.day() === 2) { - return '[Во] dddd, [в] LT'; - } else { - return '[В] dddd, [в] LT'; - } - } - }, - lastWeek: function (now) { - if (now.week() !== this.week()) { - switch (this.day()) { - case 0: - return '[В прошлое] dddd, [в] LT'; - case 1: - case 2: - case 4: - return '[В прошлый] dddd, [в] LT'; - case 3: - case 5: - case 6: - return '[В прошлую] dddd, [в] LT'; - } - } else { - if (this.day() === 2) { - return '[Во] dddd, [в] LT'; - } else { - return '[В] dddd, [в] LT'; - } - } - }, - sameElse: 'L' - }, - relativeTime : { - future : 'через %s', - past : '%s назад', - s : 'несколько секунд', - ss : relativeTimeWithPlural$3, - m : relativeTimeWithPlural$3, - mm : relativeTimeWithPlural$3, - h : 'час', - hh : relativeTimeWithPlural$3, - d : 'день', - dd : relativeTimeWithPlural$3, - M : 'месяц', - MM : relativeTimeWithPlural$3, - y : 'год', - yy : relativeTimeWithPlural$3 - }, - meridiemParse: /ночи|утра|дня|вечера/i, - isPM : function (input) { - return /^(дня|вечера)$/.test(input); - }, - meridiem : function (hour, minute, isLower) { - if (hour < 4) { - return 'ночи'; - } else if (hour < 12) { - return 'утра'; - } else if (hour < 17) { - return 'дня'; - } else { - return 'вечера'; - } - }, - dayOfMonthOrdinalParse: /\d{1,2}-(й|го|я)/, - ordinal: function (number, period) { - switch (period) { - case 'M': - case 'd': - case 'DDD': - return number + '-й'; - case 'D': - return number + '-го'; - case 'w': - case 'W': - return number + '-я'; - default: - return number; - } - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); - - //! moment.js locale configuration - - var months$7 = [ - 'جنوري', - 'فيبروري', - 'مارچ', - 'اپريل', - 'مئي', - 'جون', - 'جولاءِ', - 'آگسٽ', - 'سيپٽمبر', - 'آڪٽوبر', - 'نومبر', - 'ڊسمبر' - ]; - var days$1 = [ - 'آچر', - 'سومر', - 'اڱارو', - 'اربع', - 'خميس', - 'جمع', - 'ڇنڇر' - ]; - - hooks.defineLocale('sd', { - months : months$7, - monthsShort : months$7, - weekdays : days$1, - weekdaysShort : days$1, - weekdaysMin : days$1, - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd، D MMMM YYYY HH:mm' - }, - meridiemParse: /صبح|شام/, - isPM : function (input) { - return 'شام' === input; - }, - meridiem : function (hour, minute, isLower) { - if (hour < 12) { - return 'صبح'; - } - return 'شام'; - }, - calendar : { - sameDay : '[اڄ] LT', - nextDay : '[سڀاڻي] LT', - nextWeek : 'dddd [اڳين هفتي تي] LT', - lastDay : '[ڪالهه] LT', - lastWeek : '[گزريل هفتي] dddd [تي] LT', - sameElse : 'L' - }, - relativeTime : { - future : '%s پوء', - past : '%s اڳ', - s : 'چند سيڪنڊ', - ss : '%d سيڪنڊ', - m : 'هڪ منٽ', - mm : '%d منٽ', - h : 'هڪ ڪلاڪ', - hh : '%d ڪلاڪ', - d : 'هڪ ڏينهن', - dd : '%d ڏينهن', - M : 'هڪ مهينو', - MM : '%d مهينا', - y : 'هڪ سال', - yy : '%d سال' - }, - preparse: function (string) { - return string.replace(/،/g, ','); - }, - postformat: function (string) { - return string.replace(/,/g, '،'); - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); - - //! moment.js locale configuration - - hooks.defineLocale('se', { - months : 'ođđajagemánnu_guovvamánnu_njukčamánnu_cuoŋománnu_miessemánnu_geassemánnu_suoidnemánnu_borgemánnu_čakčamánnu_golggotmánnu_skábmamánnu_juovlamánnu'.split('_'), - monthsShort : 'ođđj_guov_njuk_cuo_mies_geas_suoi_borg_čakč_golg_skáb_juov'.split('_'), - weekdays : 'sotnabeaivi_vuossárga_maŋŋebárga_gaskavahkku_duorastat_bearjadat_lávvardat'.split('_'), - weekdaysShort : 'sotn_vuos_maŋ_gask_duor_bear_láv'.split('_'), - weekdaysMin : 's_v_m_g_d_b_L'.split('_'), - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD.MM.YYYY', - LL : 'MMMM D. [b.] YYYY', - LLL : 'MMMM D. [b.] YYYY [ti.] HH:mm', - LLLL : 'dddd, MMMM D. [b.] YYYY [ti.] HH:mm' - }, - calendar : { - sameDay: '[otne ti] LT', - nextDay: '[ihttin ti] LT', - nextWeek: 'dddd [ti] LT', - lastDay: '[ikte ti] LT', - lastWeek: '[ovddit] dddd [ti] LT', - sameElse: 'L' - }, - relativeTime : { - future : '%s geažes', - past : 'maŋit %s', - s : 'moadde sekunddat', - ss: '%d sekunddat', - m : 'okta minuhta', - mm : '%d minuhtat', - h : 'okta diimmu', - hh : '%d diimmut', - d : 'okta beaivi', - dd : '%d beaivvit', - M : 'okta mánnu', - MM : '%d mánut', - y : 'okta jahki', - yy : '%d jagit' - }, - dayOfMonthOrdinalParse: /\d{1,2}\./, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); - - //! moment.js locale configuration - - /*jshint -W100*/ - hooks.defineLocale('si', { - months : 'ජනවාරි_පෙබරවාරි_මාර්තු_අප්‍රේල්_මැයි_ජූනි_ජූලි_අගෝස්තු_සැප්තැම්බර්_ඔක්තෝබර්_නොවැම්බර්_දෙසැම්බර්'.split('_'), - monthsShort : 'ජන_පෙබ_මාර්_අප්_මැයි_ජූනි_ජූලි_අගෝ_සැප්_ඔක්_නොවැ_දෙසැ'.split('_'), - weekdays : 'ඉරිදා_සඳුදා_අඟහරුවාදා_බදාදා_බ්‍රහස්පතින්දා_සිකුරාදා_සෙනසුරාදා'.split('_'), - weekdaysShort : 'ඉරි_සඳු_අඟ_බදා_බ්‍රහ_සිකු_සෙන'.split('_'), - weekdaysMin : 'ඉ_ස_අ_බ_බ්‍ර_සි_සෙ'.split('_'), - weekdaysParseExact : true, - longDateFormat : { - LT : 'a h:mm', - LTS : 'a h:mm:ss', - L : 'YYYY/MM/DD', - LL : 'YYYY MMMM D', - LLL : 'YYYY MMMM D, a h:mm', - LLLL : 'YYYY MMMM D [වැනි] dddd, a h:mm:ss' - }, - calendar : { - sameDay : '[අද] LT[ට]', - nextDay : '[හෙට] LT[ට]', - nextWeek : 'dddd LT[ට]', - lastDay : '[ඊයේ] LT[ට]', - lastWeek : '[පසුගිය] dddd LT[ට]', - sameElse : 'L' - }, - relativeTime : { - future : '%sකින්', - past : '%sකට පෙර', - s : 'තත්පර කිහිපය', - ss : 'තත්පර %d', - m : 'මිනිත්තුව', - mm : 'මිනිත්තු %d', - h : 'පැය', - hh : 'පැය %d', - d : 'දිනය', - dd : 'දින %d', - M : 'මාසය', - MM : 'මාස %d', - y : 'වසර', - yy : 'වසර %d' - }, - dayOfMonthOrdinalParse: /\d{1,2} වැනි/, - ordinal : function (number) { - return number + ' වැනි'; - }, - meridiemParse : /පෙර වරු|පස් වරු|පෙ.ව|ප.ව./, - isPM : function (input) { - return input === 'ප.ව.' || input === 'පස් වරු'; - }, - meridiem : function (hours, minutes, isLower) { - if (hours > 11) { - return isLower ? 'ප.ව.' : 'පස් වරු'; - } else { - return isLower ? 'පෙ.ව.' : 'පෙර වරු'; - } - } - }); - - //! moment.js locale configuration - - var months$8 = 'január_február_marec_apríl_máj_jún_júl_august_september_október_november_december'.split('_'), - monthsShort$5 = 'jan_feb_mar_apr_máj_jún_júl_aug_sep_okt_nov_dec'.split('_'); - function plural$5(n) { - return (n > 1) && (n < 5); - } - function translate$9(number, withoutSuffix, key, isFuture) { - var result = number + ' '; - switch (key) { - case 's': // a few seconds / in a few seconds / a few seconds ago - return (withoutSuffix || isFuture) ? 'pár sekúnd' : 'pár sekundami'; - case 'ss': // 9 seconds / in 9 seconds / 9 seconds ago - if (withoutSuffix || isFuture) { - return result + (plural$5(number) ? 'sekundy' : 'sekúnd'); - } else { - return result + 'sekundami'; - } - break; - case 'm': // a minute / in a minute / a minute ago - return withoutSuffix ? 'minúta' : (isFuture ? 'minútu' : 'minútou'); - case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago - if (withoutSuffix || isFuture) { - return result + (plural$5(number) ? 'minúty' : 'minút'); - } else { - return result + 'minútami'; - } - break; - case 'h': // an hour / in an hour / an hour ago - return withoutSuffix ? 'hodina' : (isFuture ? 'hodinu' : 'hodinou'); - case 'hh': // 9 hours / in 9 hours / 9 hours ago - if (withoutSuffix || isFuture) { - return result + (plural$5(number) ? 'hodiny' : 'hodín'); - } else { - return result + 'hodinami'; - } - break; - case 'd': // a day / in a day / a day ago - return (withoutSuffix || isFuture) ? 'deň' : 'dňom'; - case 'dd': // 9 days / in 9 days / 9 days ago - if (withoutSuffix || isFuture) { - return result + (plural$5(number) ? 'dni' : 'dní'); - } else { - return result + 'dňami'; - } - break; - case 'M': // a month / in a month / a month ago - return (withoutSuffix || isFuture) ? 'mesiac' : 'mesiacom'; - case 'MM': // 9 months / in 9 months / 9 months ago - if (withoutSuffix || isFuture) { - return result + (plural$5(number) ? 'mesiace' : 'mesiacov'); - } else { - return result + 'mesiacmi'; - } - break; - case 'y': // a year / in a year / a year ago - return (withoutSuffix || isFuture) ? 'rok' : 'rokom'; - case 'yy': // 9 years / in 9 years / 9 years ago - if (withoutSuffix || isFuture) { - return result + (plural$5(number) ? 'roky' : 'rokov'); - } else { - return result + 'rokmi'; - } - break; - } - } - - hooks.defineLocale('sk', { - months : months$8, - monthsShort : monthsShort$5, - weekdays : 'nedeľa_pondelok_utorok_streda_štvrtok_piatok_sobota'.split('_'), - weekdaysShort : 'ne_po_ut_st_št_pi_so'.split('_'), - weekdaysMin : 'ne_po_ut_st_št_pi_so'.split('_'), - longDateFormat : { - LT: 'H:mm', - LTS : 'H:mm:ss', - L : 'DD.MM.YYYY', - LL : 'D. MMMM YYYY', - LLL : 'D. MMMM YYYY H:mm', - LLLL : 'dddd D. MMMM YYYY H:mm' - }, - calendar : { - sameDay: '[dnes o] LT', - nextDay: '[zajtra o] LT', - nextWeek: function () { - switch (this.day()) { - case 0: - return '[v nedeľu o] LT'; - case 1: - case 2: - return '[v] dddd [o] LT'; - case 3: - return '[v stredu o] LT'; - case 4: - return '[vo štvrtok o] LT'; - case 5: - return '[v piatok o] LT'; - case 6: - return '[v sobotu o] LT'; - } - }, - lastDay: '[včera o] LT', - lastWeek: function () { - switch (this.day()) { - case 0: - return '[minulú nedeľu o] LT'; - case 1: - case 2: - return '[minulý] dddd [o] LT'; - case 3: - return '[minulú stredu o] LT'; - case 4: - case 5: - return '[minulý] dddd [o] LT'; - case 6: - return '[minulú sobotu o] LT'; - } - }, - sameElse: 'L' - }, - relativeTime : { - future : 'za %s', - past : 'pred %s', - s : translate$9, - ss : translate$9, - m : translate$9, - mm : translate$9, - h : translate$9, - hh : translate$9, - d : translate$9, - dd : translate$9, - M : translate$9, - MM : translate$9, - y : translate$9, - yy : translate$9 - }, - dayOfMonthOrdinalParse: /\d{1,2}\./, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); - - //! moment.js locale configuration - - function processRelativeTime$6(number, withoutSuffix, key, isFuture) { - var result = number + ' '; - switch (key) { - case 's': - return withoutSuffix || isFuture ? 'nekaj sekund' : 'nekaj sekundami'; - case 'ss': - if (number === 1) { - result += withoutSuffix ? 'sekundo' : 'sekundi'; - } else if (number === 2) { - result += withoutSuffix || isFuture ? 'sekundi' : 'sekundah'; - } else if (number < 5) { - result += withoutSuffix || isFuture ? 'sekunde' : 'sekundah'; - } else { - result += 'sekund'; - } - return result; - case 'm': - return withoutSuffix ? 'ena minuta' : 'eno minuto'; - case 'mm': - if (number === 1) { - result += withoutSuffix ? 'minuta' : 'minuto'; - } else if (number === 2) { - result += withoutSuffix || isFuture ? 'minuti' : 'minutama'; - } else if (number < 5) { - result += withoutSuffix || isFuture ? 'minute' : 'minutami'; - } else { - result += withoutSuffix || isFuture ? 'minut' : 'minutami'; - } - return result; - case 'h': - return withoutSuffix ? 'ena ura' : 'eno uro'; - case 'hh': - if (number === 1) { - result += withoutSuffix ? 'ura' : 'uro'; - } else if (number === 2) { - result += withoutSuffix || isFuture ? 'uri' : 'urama'; - } else if (number < 5) { - result += withoutSuffix || isFuture ? 'ure' : 'urami'; - } else { - result += withoutSuffix || isFuture ? 'ur' : 'urami'; - } - return result; - case 'd': - return withoutSuffix || isFuture ? 'en dan' : 'enim dnem'; - case 'dd': - if (number === 1) { - result += withoutSuffix || isFuture ? 'dan' : 'dnem'; - } else if (number === 2) { - result += withoutSuffix || isFuture ? 'dni' : 'dnevoma'; - } else { - result += withoutSuffix || isFuture ? 'dni' : 'dnevi'; - } - return result; - case 'M': - return withoutSuffix || isFuture ? 'en mesec' : 'enim mesecem'; - case 'MM': - if (number === 1) { - result += withoutSuffix || isFuture ? 'mesec' : 'mesecem'; - } else if (number === 2) { - result += withoutSuffix || isFuture ? 'meseca' : 'mesecema'; - } else if (number < 5) { - result += withoutSuffix || isFuture ? 'mesece' : 'meseci'; - } else { - result += withoutSuffix || isFuture ? 'mesecev' : 'meseci'; - } - return result; - case 'y': - return withoutSuffix || isFuture ? 'eno leto' : 'enim letom'; - case 'yy': - if (number === 1) { - result += withoutSuffix || isFuture ? 'leto' : 'letom'; - } else if (number === 2) { - result += withoutSuffix || isFuture ? 'leti' : 'letoma'; - } else if (number < 5) { - result += withoutSuffix || isFuture ? 'leta' : 'leti'; - } else { - result += withoutSuffix || isFuture ? 'let' : 'leti'; - } - return result; - } - } - - hooks.defineLocale('sl', { - months : 'januar_februar_marec_april_maj_junij_julij_avgust_september_oktober_november_december'.split('_'), - monthsShort : 'jan._feb._mar._apr._maj._jun._jul._avg._sep._okt._nov._dec.'.split('_'), - monthsParseExact: true, - weekdays : 'nedelja_ponedeljek_torek_sreda_četrtek_petek_sobota'.split('_'), - weekdaysShort : 'ned._pon._tor._sre._čet._pet._sob.'.split('_'), - weekdaysMin : 'ne_po_to_sr_če_pe_so'.split('_'), - weekdaysParseExact : true, - longDateFormat : { - LT : 'H:mm', - LTS : 'H:mm:ss', - L : 'DD.MM.YYYY', - LL : 'D. MMMM YYYY', - LLL : 'D. MMMM YYYY H:mm', - LLLL : 'dddd, D. MMMM YYYY H:mm' - }, - calendar : { - sameDay : '[danes ob] LT', - nextDay : '[jutri ob] LT', - - nextWeek : function () { - switch (this.day()) { - case 0: - return '[v] [nedeljo] [ob] LT'; - case 3: - return '[v] [sredo] [ob] LT'; - case 6: - return '[v] [soboto] [ob] LT'; - case 1: - case 2: - case 4: - case 5: - return '[v] dddd [ob] LT'; - } - }, - lastDay : '[včeraj ob] LT', - lastWeek : function () { - switch (this.day()) { - case 0: - return '[prejšnjo] [nedeljo] [ob] LT'; - case 3: - return '[prejšnjo] [sredo] [ob] LT'; - case 6: - return '[prejšnjo] [soboto] [ob] LT'; - case 1: - case 2: - case 4: - case 5: - return '[prejšnji] dddd [ob] LT'; - } - }, - sameElse : 'L' - }, - relativeTime : { - future : 'čez %s', - past : 'pred %s', - s : processRelativeTime$6, - ss : processRelativeTime$6, - m : processRelativeTime$6, - mm : processRelativeTime$6, - h : processRelativeTime$6, - hh : processRelativeTime$6, - d : processRelativeTime$6, - dd : processRelativeTime$6, - M : processRelativeTime$6, - MM : processRelativeTime$6, - y : processRelativeTime$6, - yy : processRelativeTime$6 - }, - dayOfMonthOrdinalParse: /\d{1,2}\./, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 7th is the first week of the year. - } - }); - - //! moment.js locale configuration - - hooks.defineLocale('sq', { - months : 'Janar_Shkurt_Mars_Prill_Maj_Qershor_Korrik_Gusht_Shtator_Tetor_Nëntor_Dhjetor'.split('_'), - monthsShort : 'Jan_Shk_Mar_Pri_Maj_Qer_Kor_Gus_Sht_Tet_Nën_Dhj'.split('_'), - weekdays : 'E Diel_E Hënë_E Martë_E Mërkurë_E Enjte_E Premte_E Shtunë'.split('_'), - weekdaysShort : 'Die_Hën_Mar_Mër_Enj_Pre_Sht'.split('_'), - weekdaysMin : 'D_H_Ma_Më_E_P_Sh'.split('_'), - weekdaysParseExact : true, - meridiemParse: /PD|MD/, - isPM: function (input) { - return input.charAt(0) === 'M'; - }, - meridiem : function (hours, minutes, isLower) { - return hours < 12 ? 'PD' : 'MD'; - }, - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd, D MMMM YYYY HH:mm' - }, - calendar : { - sameDay : '[Sot në] LT', - nextDay : '[Nesër në] LT', - nextWeek : 'dddd [në] LT', - lastDay : '[Dje në] LT', - lastWeek : 'dddd [e kaluar në] LT', - sameElse : 'L' - }, - relativeTime : { - future : 'në %s', - past : '%s më parë', - s : 'disa sekonda', - ss : '%d sekonda', - m : 'një minutë', - mm : '%d minuta', - h : 'një orë', - hh : '%d orë', - d : 'një ditë', - dd : '%d ditë', - M : 'një muaj', - MM : '%d muaj', - y : 'një vit', - yy : '%d vite' - }, - dayOfMonthOrdinalParse: /\d{1,2}\./, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); - - //! moment.js locale configuration - - var translator$1 = { - words: { //Different grammatical cases - ss: ['секунда', 'секунде', 'секунди'], - m: ['један минут', 'једне минуте'], - mm: ['минут', 'минуте', 'минута'], - h: ['један сат', 'једног сата'], - hh: ['сат', 'сата', 'сати'], - dd: ['дан', 'дана', 'дана'], - MM: ['месец', 'месеца', 'месеци'], - yy: ['година', 'године', 'година'] - }, - correctGrammaticalCase: function (number, wordKey) { - return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]); - }, - translate: function (number, withoutSuffix, key) { - var wordKey = translator$1.words[key]; - if (key.length === 1) { - return withoutSuffix ? wordKey[0] : wordKey[1]; - } else { - return number + ' ' + translator$1.correctGrammaticalCase(number, wordKey); - } - } - }; - - hooks.defineLocale('sr-cyrl', { - months: 'јануар_фебруар_март_април_мај_јун_јул_август_септембар_октобар_новембар_децембар'.split('_'), - monthsShort: 'јан._феб._мар._апр._мај_јун_јул_авг._сеп._окт._нов._дец.'.split('_'), - monthsParseExact: true, - weekdays: 'недеља_понедељак_уторак_среда_четвртак_петак_субота'.split('_'), - weekdaysShort: 'нед._пон._уто._сре._чет._пет._суб.'.split('_'), - weekdaysMin: 'не_по_ут_ср_че_пе_су'.split('_'), - weekdaysParseExact : true, - longDateFormat: { - LT: 'H:mm', - LTS : 'H:mm:ss', - L: 'DD.MM.YYYY', - LL: 'D. MMMM YYYY', - LLL: 'D. MMMM YYYY H:mm', - LLLL: 'dddd, D. MMMM YYYY H:mm' - }, - calendar: { - sameDay: '[данас у] LT', - nextDay: '[сутра у] LT', - nextWeek: function () { - switch (this.day()) { - case 0: - return '[у] [недељу] [у] LT'; - case 3: - return '[у] [среду] [у] LT'; - case 6: - return '[у] [суботу] [у] LT'; - case 1: - case 2: - case 4: - case 5: - return '[у] dddd [у] LT'; - } - }, - lastDay : '[јуче у] LT', - lastWeek : function () { - var lastWeekDays = [ - '[прошле] [недеље] [у] LT', - '[прошлог] [понедељка] [у] LT', - '[прошлог] [уторка] [у] LT', - '[прошле] [среде] [у] LT', - '[прошлог] [четвртка] [у] LT', - '[прошлог] [петка] [у] LT', - '[прошле] [суботе] [у] LT' - ]; - return lastWeekDays[this.day()]; - }, - sameElse : 'L' - }, - relativeTime : { - future : 'за %s', - past : 'пре %s', - s : 'неколико секунди', - ss : translator$1.translate, - m : translator$1.translate, - mm : translator$1.translate, - h : translator$1.translate, - hh : translator$1.translate, - d : 'дан', - dd : translator$1.translate, - M : 'месец', - MM : translator$1.translate, - y : 'годину', - yy : translator$1.translate - }, - dayOfMonthOrdinalParse: /\d{1,2}\./, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 7th is the first week of the year. - } - }); - - //! moment.js locale configuration - - var translator$2 = { - words: { //Different grammatical cases - ss: ['sekunda', 'sekunde', 'sekundi'], - m: ['jedan minut', 'jedne minute'], - mm: ['minut', 'minute', 'minuta'], - h: ['jedan sat', 'jednog sata'], - hh: ['sat', 'sata', 'sati'], - dd: ['dan', 'dana', 'dana'], - MM: ['mesec', 'meseca', 'meseci'], - yy: ['godina', 'godine', 'godina'] - }, - correctGrammaticalCase: function (number, wordKey) { - return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]); - }, - translate: function (number, withoutSuffix, key) { - var wordKey = translator$2.words[key]; - if (key.length === 1) { - return withoutSuffix ? wordKey[0] : wordKey[1]; - } else { - return number + ' ' + translator$2.correctGrammaticalCase(number, wordKey); - } - } - }; - - hooks.defineLocale('sr', { - months: 'januar_februar_mart_april_maj_jun_jul_avgust_septembar_oktobar_novembar_decembar'.split('_'), - monthsShort: 'jan._feb._mar._apr._maj_jun_jul_avg._sep._okt._nov._dec.'.split('_'), - monthsParseExact: true, - weekdays: 'nedelja_ponedeljak_utorak_sreda_četvrtak_petak_subota'.split('_'), - weekdaysShort: 'ned._pon._uto._sre._čet._pet._sub.'.split('_'), - weekdaysMin: 'ne_po_ut_sr_če_pe_su'.split('_'), - weekdaysParseExact : true, - longDateFormat: { - LT: 'H:mm', - LTS : 'H:mm:ss', - L: 'DD.MM.YYYY', - LL: 'D. MMMM YYYY', - LLL: 'D. MMMM YYYY H:mm', - LLLL: 'dddd, D. MMMM YYYY H:mm' - }, - calendar: { - sameDay: '[danas u] LT', - nextDay: '[sutra u] LT', - nextWeek: function () { - switch (this.day()) { - case 0: - return '[u] [nedelju] [u] LT'; - case 3: - return '[u] [sredu] [u] LT'; - case 6: - return '[u] [subotu] [u] LT'; - case 1: - case 2: - case 4: - case 5: - return '[u] dddd [u] LT'; - } - }, - lastDay : '[juče u] LT', - lastWeek : function () { - var lastWeekDays = [ - '[prošle] [nedelje] [u] LT', - '[prošlog] [ponedeljka] [u] LT', - '[prošlog] [utorka] [u] LT', - '[prošle] [srede] [u] LT', - '[prošlog] [četvrtka] [u] LT', - '[prošlog] [petka] [u] LT', - '[prošle] [subote] [u] LT' - ]; - return lastWeekDays[this.day()]; - }, - sameElse : 'L' - }, - relativeTime : { - future : 'za %s', - past : 'pre %s', - s : 'nekoliko sekundi', - ss : translator$2.translate, - m : translator$2.translate, - mm : translator$2.translate, - h : translator$2.translate, - hh : translator$2.translate, - d : 'dan', - dd : translator$2.translate, - M : 'mesec', - MM : translator$2.translate, - y : 'godinu', - yy : translator$2.translate - }, - dayOfMonthOrdinalParse: /\d{1,2}\./, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 7th is the first week of the year. - } - }); - - //! moment.js locale configuration - - hooks.defineLocale('ss', { - months : "Bhimbidvwane_Indlovana_Indlov'lenkhulu_Mabasa_Inkhwekhweti_Inhlaba_Kholwane_Ingci_Inyoni_Imphala_Lweti_Ingongoni".split('_'), - monthsShort : 'Bhi_Ina_Inu_Mab_Ink_Inh_Kho_Igc_Iny_Imp_Lwe_Igo'.split('_'), - weekdays : 'Lisontfo_Umsombuluko_Lesibili_Lesitsatfu_Lesine_Lesihlanu_Umgcibelo'.split('_'), - weekdaysShort : 'Lis_Umb_Lsb_Les_Lsi_Lsh_Umg'.split('_'), - weekdaysMin : 'Li_Us_Lb_Lt_Ls_Lh_Ug'.split('_'), - weekdaysParseExact : true, - longDateFormat : { - LT : 'h:mm A', - LTS : 'h:mm:ss A', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY h:mm A', - LLLL : 'dddd, D MMMM YYYY h:mm A' - }, - calendar : { - sameDay : '[Namuhla nga] LT', - nextDay : '[Kusasa nga] LT', - nextWeek : 'dddd [nga] LT', - lastDay : '[Itolo nga] LT', - lastWeek : 'dddd [leliphelile] [nga] LT', - sameElse : 'L' - }, - relativeTime : { - future : 'nga %s', - past : 'wenteka nga %s', - s : 'emizuzwana lomcane', - ss : '%d mzuzwana', - m : 'umzuzu', - mm : '%d emizuzu', - h : 'lihora', - hh : '%d emahora', - d : 'lilanga', - dd : '%d emalanga', - M : 'inyanga', - MM : '%d tinyanga', - y : 'umnyaka', - yy : '%d iminyaka' - }, - meridiemParse: /ekuseni|emini|entsambama|ebusuku/, - meridiem : function (hours, minutes, isLower) { - if (hours < 11) { - return 'ekuseni'; - } else if (hours < 15) { - return 'emini'; - } else if (hours < 19) { - return 'entsambama'; - } else { - return 'ebusuku'; - } - }, - meridiemHour : function (hour, meridiem) { - if (hour === 12) { - hour = 0; - } - if (meridiem === 'ekuseni') { - return hour; - } else if (meridiem === 'emini') { - return hour >= 11 ? hour : hour + 12; - } else if (meridiem === 'entsambama' || meridiem === 'ebusuku') { - if (hour === 0) { - return 0; - } - return hour + 12; - } - }, - dayOfMonthOrdinalParse: /\d{1,2}/, - ordinal : '%d', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); - - //! moment.js locale configuration - - hooks.defineLocale('sv', { - months : 'januari_februari_mars_april_maj_juni_juli_augusti_september_oktober_november_december'.split('_'), - monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'.split('_'), - weekdays : 'söndag_måndag_tisdag_onsdag_torsdag_fredag_lördag'.split('_'), - weekdaysShort : 'sön_mån_tis_ons_tor_fre_lör'.split('_'), - weekdaysMin : 'sö_må_ti_on_to_fr_lö'.split('_'), - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'YYYY-MM-DD', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY [kl.] HH:mm', - LLLL : 'dddd D MMMM YYYY [kl.] HH:mm', - lll : 'D MMM YYYY HH:mm', - llll : 'ddd D MMM YYYY HH:mm' - }, - calendar : { - sameDay: '[Idag] LT', - nextDay: '[Imorgon] LT', - lastDay: '[Igår] LT', - nextWeek: '[På] dddd LT', - lastWeek: '[I] dddd[s] LT', - sameElse: 'L' - }, - relativeTime : { - future : 'om %s', - past : 'för %s sedan', - s : 'några sekunder', - ss : '%d sekunder', - m : 'en minut', - mm : '%d minuter', - h : 'en timme', - hh : '%d timmar', - d : 'en dag', - dd : '%d dagar', - M : 'en månad', - MM : '%d månader', - y : 'ett år', - yy : '%d år' - }, - dayOfMonthOrdinalParse: /\d{1,2}(e|a)/, - ordinal : function (number) { - var b = number % 10, - output = (~~(number % 100 / 10) === 1) ? 'e' : - (b === 1) ? 'a' : - (b === 2) ? 'a' : - (b === 3) ? 'e' : 'e'; - return number + output; - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); - - //! moment.js locale configuration - - hooks.defineLocale('sw', { - months : 'Januari_Februari_Machi_Aprili_Mei_Juni_Julai_Agosti_Septemba_Oktoba_Novemba_Desemba'.split('_'), - monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ago_Sep_Okt_Nov_Des'.split('_'), - weekdays : 'Jumapili_Jumatatu_Jumanne_Jumatano_Alhamisi_Ijumaa_Jumamosi'.split('_'), - weekdaysShort : 'Jpl_Jtat_Jnne_Jtan_Alh_Ijm_Jmos'.split('_'), - weekdaysMin : 'J2_J3_J4_J5_Al_Ij_J1'.split('_'), - weekdaysParseExact : true, - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD.MM.YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd, D MMMM YYYY HH:mm' - }, - calendar : { - sameDay : '[leo saa] LT', - nextDay : '[kesho saa] LT', - nextWeek : '[wiki ijayo] dddd [saat] LT', - lastDay : '[jana] LT', - lastWeek : '[wiki iliyopita] dddd [saat] LT', - sameElse : 'L' - }, - relativeTime : { - future : '%s baadaye', - past : 'tokea %s', - s : 'hivi punde', - ss : 'sekunde %d', - m : 'dakika moja', - mm : 'dakika %d', - h : 'saa limoja', - hh : 'masaa %d', - d : 'siku moja', - dd : 'masiku %d', - M : 'mwezi mmoja', - MM : 'miezi %d', - y : 'mwaka mmoja', - yy : 'miaka %d' - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 7th is the first week of the year. - } - }); - - //! moment.js locale configuration - - var symbolMap$f = { - '1': '௧', - '2': '௨', - '3': '௩', - '4': '௪', - '5': '௫', - '6': '௬', - '7': '௭', - '8': '௮', - '9': '௯', - '0': '௦' - }, numberMap$e = { - '௧': '1', - '௨': '2', - '௩': '3', - '௪': '4', - '௫': '5', - '௬': '6', - '௭': '7', - '௮': '8', - '௯': '9', - '௦': '0' - }; - - hooks.defineLocale('ta', { - months : 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split('_'), - monthsShort : 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split('_'), - weekdays : 'ஞாயிற்றுக்கிழமை_திங்கட்கிழமை_செவ்வாய்கிழமை_புதன்கிழமை_வியாழக்கிழமை_வெள்ளிக்கிழமை_சனிக்கிழமை'.split('_'), - weekdaysShort : 'ஞாயிறு_திங்கள்_செவ்வாய்_புதன்_வியாழன்_வெள்ளி_சனி'.split('_'), - weekdaysMin : 'ஞா_தி_செ_பு_வி_வெ_ச'.split('_'), - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY, HH:mm', - LLLL : 'dddd, D MMMM YYYY, HH:mm' - }, - calendar : { - sameDay : '[இன்று] LT', - nextDay : '[நாளை] LT', - nextWeek : 'dddd, LT', - lastDay : '[நேற்று] LT', - lastWeek : '[கடந்த வாரம்] dddd, LT', - sameElse : 'L' - }, - relativeTime : { - future : '%s இல்', - past : '%s முன்', - s : 'ஒரு சில விநாடிகள்', - ss : '%d விநாடிகள்', - m : 'ஒரு நிமிடம்', - mm : '%d நிமிடங்கள்', - h : 'ஒரு மணி நேரம்', - hh : '%d மணி நேரம்', - d : 'ஒரு நாள்', - dd : '%d நாட்கள்', - M : 'ஒரு மாதம்', - MM : '%d மாதங்கள்', - y : 'ஒரு வருடம்', - yy : '%d ஆண்டுகள்' - }, - dayOfMonthOrdinalParse: /\d{1,2}வது/, - ordinal : function (number) { - return number + 'வது'; - }, - preparse: function (string) { - return string.replace(/[௧௨௩௪௫௬௭௮௯௦]/g, function (match) { - return numberMap$e[match]; - }); - }, - postformat: function (string) { - return string.replace(/\d/g, function (match) { - return symbolMap$f[match]; - }); - }, - // refer http://ta.wikipedia.org/s/1er1 - meridiemParse: /யாமம்|வைகறை|காலை|நண்பகல்|எற்பாடு|மாலை/, - meridiem : function (hour, minute, isLower) { - if (hour < 2) { - return ' யாமம்'; - } else if (hour < 6) { - return ' வைகறை'; // வைகறை - } else if (hour < 10) { - return ' காலை'; // காலை - } else if (hour < 14) { - return ' நண்பகல்'; // நண்பகல் - } else if (hour < 18) { - return ' எற்பாடு'; // எற்பாடு - } else if (hour < 22) { - return ' மாலை'; // மாலை - } else { - return ' யாமம்'; - } - }, - meridiemHour : function (hour, meridiem) { - if (hour === 12) { - hour = 0; - } - if (meridiem === 'யாமம்') { - return hour < 2 ? hour : hour + 12; - } else if (meridiem === 'வைகறை' || meridiem === 'காலை') { - return hour; - } else if (meridiem === 'நண்பகல்') { - return hour >= 10 ? hour : hour + 12; - } else { - return hour + 12; - } - }, - week : { - dow : 0, // Sunday is the first day of the week. - doy : 6 // The week that contains Jan 6th is the first week of the year. - } - }); - - //! moment.js locale configuration - - hooks.defineLocale('te', { - months : 'జనవరి_ఫిబ్రవరి_మార్చి_ఏప్రిల్_మే_జూన్_జూలై_ఆగస్టు_సెప్టెంబర్_అక్టోబర్_నవంబర్_డిసెంబర్'.split('_'), - monthsShort : 'జన._ఫిబ్ర._మార్చి_ఏప్రి._మే_జూన్_జూలై_ఆగ._సెప్._అక్టో._నవ._డిసె.'.split('_'), - monthsParseExact : true, - weekdays : 'ఆదివారం_సోమవారం_మంగళవారం_బుధవారం_గురువారం_శుక్రవారం_శనివారం'.split('_'), - weekdaysShort : 'ఆది_సోమ_మంగళ_బుధ_గురు_శుక్ర_శని'.split('_'), - weekdaysMin : 'ఆ_సో_మం_బు_గు_శు_శ'.split('_'), - longDateFormat : { - LT : 'A h:mm', - LTS : 'A h:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY, A h:mm', - LLLL : 'dddd, D MMMM YYYY, A h:mm' - }, - calendar : { - sameDay : '[నేడు] LT', - nextDay : '[రేపు] LT', - nextWeek : 'dddd, LT', - lastDay : '[నిన్న] LT', - lastWeek : '[గత] dddd, LT', - sameElse : 'L' - }, - relativeTime : { - future : '%s లో', - past : '%s క్రితం', - s : 'కొన్ని క్షణాలు', - ss : '%d సెకన్లు', - m : 'ఒక నిమిషం', - mm : '%d నిమిషాలు', - h : 'ఒక గంట', - hh : '%d గంటలు', - d : 'ఒక రోజు', - dd : '%d రోజులు', - M : 'ఒక నెల', - MM : '%d నెలలు', - y : 'ఒక సంవత్సరం', - yy : '%d సంవత్సరాలు' - }, - dayOfMonthOrdinalParse : /\d{1,2}వ/, - ordinal : '%dవ', - meridiemParse: /రాత్రి|ఉదయం|మధ్యాహ్నం|సాయంత్రం/, - meridiemHour : function (hour, meridiem) { - if (hour === 12) { - hour = 0; - } - if (meridiem === 'రాత్రి') { - return hour < 4 ? hour : hour + 12; - } else if (meridiem === 'ఉదయం') { - return hour; - } else if (meridiem === 'మధ్యాహ్నం') { - return hour >= 10 ? hour : hour + 12; - } else if (meridiem === 'సాయంత్రం') { - return hour + 12; - } - }, - meridiem : function (hour, minute, isLower) { - if (hour < 4) { - return 'రాత్రి'; - } else if (hour < 10) { - return 'ఉదయం'; - } else if (hour < 17) { - return 'మధ్యాహ్నం'; - } else if (hour < 20) { - return 'సాయంత్రం'; - } else { - return 'రాత్రి'; - } - }, - week : { - dow : 0, // Sunday is the first day of the week. - doy : 6 // The week that contains Jan 6th is the first week of the year. - } - }); - - //! moment.js locale configuration - - hooks.defineLocale('tet', { - months : 'Janeiru_Fevereiru_Marsu_Abril_Maiu_Juñu_Jullu_Agustu_Setembru_Outubru_Novembru_Dezembru'.split('_'), - monthsShort : 'Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez'.split('_'), - weekdays : 'Domingu_Segunda_Tersa_Kuarta_Kinta_Sesta_Sabadu'.split('_'), - weekdaysShort : 'Dom_Seg_Ters_Kua_Kint_Sest_Sab'.split('_'), - weekdaysMin : 'Do_Seg_Te_Ku_Ki_Ses_Sa'.split('_'), - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd, D MMMM YYYY HH:mm' - }, - calendar : { - sameDay: '[Ohin iha] LT', - nextDay: '[Aban iha] LT', - nextWeek: 'dddd [iha] LT', - lastDay: '[Horiseik iha] LT', - lastWeek: 'dddd [semana kotuk] [iha] LT', - sameElse: 'L' - }, - relativeTime : { - future : 'iha %s', - past : '%s liuba', - s : 'minutu balun', - ss : 'minutu %d', - m : 'minutu ida', - mm : 'minutu %d', - h : 'oras ida', - hh : 'oras %d', - d : 'loron ida', - dd : 'loron %d', - M : 'fulan ida', - MM : 'fulan %d', - y : 'tinan ida', - yy : 'tinan %d' - }, - dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/, - ordinal : function (number) { - var b = number % 10, - output = (~~(number % 100 / 10) === 1) ? 'th' : - (b === 1) ? 'st' : - (b === 2) ? 'nd' : - (b === 3) ? 'rd' : 'th'; - return number + output; - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); - - //! moment.js locale configuration - - var suffixes$3 = { - 0: '-ум', - 1: '-ум', - 2: '-юм', - 3: '-юм', - 4: '-ум', - 5: '-ум', - 6: '-ум', - 7: '-ум', - 8: '-ум', - 9: '-ум', - 10: '-ум', - 12: '-ум', - 13: '-ум', - 20: '-ум', - 30: '-юм', - 40: '-ум', - 50: '-ум', - 60: '-ум', - 70: '-ум', - 80: '-ум', - 90: '-ум', - 100: '-ум' - }; - - hooks.defineLocale('tg', { - months : 'январ_феврал_март_апрел_май_июн_июл_август_сентябр_октябр_ноябр_декабр'.split('_'), - monthsShort : 'янв_фев_мар_апр_май_июн_июл_авг_сен_окт_ноя_дек'.split('_'), - weekdays : 'якшанбе_душанбе_сешанбе_чоршанбе_панҷшанбе_ҷумъа_шанбе'.split('_'), - weekdaysShort : 'яшб_дшб_сшб_чшб_пшб_ҷум_шнб'.split('_'), - weekdaysMin : 'яш_дш_сш_чш_пш_ҷм_шб'.split('_'), - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd, D MMMM YYYY HH:mm' - }, - calendar : { - sameDay : '[Имрӯз соати] LT', - nextDay : '[Пагоҳ соати] LT', - lastDay : '[Дирӯз соати] LT', - nextWeek : 'dddd[и] [ҳафтаи оянда соати] LT', - lastWeek : 'dddd[и] [ҳафтаи гузашта соати] LT', - sameElse : 'L' - }, - relativeTime : { - future : 'баъди %s', - past : '%s пеш', - s : 'якчанд сония', - m : 'як дақиқа', - mm : '%d дақиқа', - h : 'як соат', - hh : '%d соат', - d : 'як рӯз', - dd : '%d рӯз', - M : 'як моҳ', - MM : '%d моҳ', - y : 'як сол', - yy : '%d сол' - }, - meridiemParse: /шаб|субҳ|рӯз|бегоҳ/, - meridiemHour: function (hour, meridiem) { - if (hour === 12) { - hour = 0; - } - if (meridiem === 'шаб') { - return hour < 4 ? hour : hour + 12; - } else if (meridiem === 'субҳ') { - return hour; - } else if (meridiem === 'рӯз') { - return hour >= 11 ? hour : hour + 12; - } else if (meridiem === 'бегоҳ') { - return hour + 12; - } - }, - meridiem: function (hour, minute, isLower) { - if (hour < 4) { - return 'шаб'; - } else if (hour < 11) { - return 'субҳ'; - } else if (hour < 16) { - return 'рӯз'; - } else if (hour < 19) { - return 'бегоҳ'; - } else { - return 'шаб'; - } - }, - dayOfMonthOrdinalParse: /\d{1,2}-(ум|юм)/, - ordinal: function (number) { - var a = number % 10, - b = number >= 100 ? 100 : null; - return number + (suffixes$3[number] || suffixes$3[a] || suffixes$3[b]); - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 1th is the first week of the year. - } - }); - - //! moment.js locale configuration - - hooks.defineLocale('th', { - months : 'มกราคม_กุมภาพันธ์_มีนาคม_เมษายน_พฤษภาคม_มิถุนายน_กรกฎาคม_สิงหาคม_กันยายน_ตุลาคม_พฤศจิกายน_ธันวาคม'.split('_'), - monthsShort : 'ม.ค._ก.พ._มี.ค._เม.ย._พ.ค._มิ.ย._ก.ค._ส.ค._ก.ย._ต.ค._พ.ย._ธ.ค.'.split('_'), - monthsParseExact: true, - weekdays : 'อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัสบดี_ศุกร์_เสาร์'.split('_'), - weekdaysShort : 'อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัส_ศุกร์_เสาร์'.split('_'), // yes, three characters difference - weekdaysMin : 'อา._จ._อ._พ._พฤ._ศ._ส.'.split('_'), - weekdaysParseExact : true, - longDateFormat : { - LT : 'H:mm', - LTS : 'H:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY เวลา H:mm', - LLLL : 'วันddddที่ D MMMM YYYY เวลา H:mm' - }, - meridiemParse: /ก่อนเที่ยง|หลังเที่ยง/, - isPM: function (input) { - return input === 'หลังเที่ยง'; - }, - meridiem : function (hour, minute, isLower) { - if (hour < 12) { - return 'ก่อนเที่ยง'; - } else { - return 'หลังเที่ยง'; - } - }, - calendar : { - sameDay : '[วันนี้ เวลา] LT', - nextDay : '[พรุ่งนี้ เวลา] LT', - nextWeek : 'dddd[หน้า เวลา] LT', - lastDay : '[เมื่อวานนี้ เวลา] LT', - lastWeek : '[วัน]dddd[ที่แล้ว เวลา] LT', - sameElse : 'L' - }, - relativeTime : { - future : 'อีก %s', - past : '%sที่แล้ว', - s : 'ไม่กี่วินาที', - ss : '%d วินาที', - m : '1 นาที', - mm : '%d นาที', - h : '1 ชั่วโมง', - hh : '%d ชั่วโมง', - d : '1 วัน', - dd : '%d วัน', - M : '1 เดือน', - MM : '%d เดือน', - y : '1 ปี', - yy : '%d ปี' - } - }); - - //! moment.js locale configuration - - hooks.defineLocale('tl-ph', { - months : 'Enero_Pebrero_Marso_Abril_Mayo_Hunyo_Hulyo_Agosto_Setyembre_Oktubre_Nobyembre_Disyembre'.split('_'), - monthsShort : 'Ene_Peb_Mar_Abr_May_Hun_Hul_Ago_Set_Okt_Nob_Dis'.split('_'), - weekdays : 'Linggo_Lunes_Martes_Miyerkules_Huwebes_Biyernes_Sabado'.split('_'), - weekdaysShort : 'Lin_Lun_Mar_Miy_Huw_Biy_Sab'.split('_'), - weekdaysMin : 'Li_Lu_Ma_Mi_Hu_Bi_Sab'.split('_'), - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'MM/D/YYYY', - LL : 'MMMM D, YYYY', - LLL : 'MMMM D, YYYY HH:mm', - LLLL : 'dddd, MMMM DD, YYYY HH:mm' - }, - calendar : { - sameDay: 'LT [ngayong araw]', - nextDay: '[Bukas ng] LT', - nextWeek: 'LT [sa susunod na] dddd', - lastDay: 'LT [kahapon]', - lastWeek: 'LT [noong nakaraang] dddd', - sameElse: 'L' - }, - relativeTime : { - future : 'sa loob ng %s', - past : '%s ang nakalipas', - s : 'ilang segundo', - ss : '%d segundo', - m : 'isang minuto', - mm : '%d minuto', - h : 'isang oras', - hh : '%d oras', - d : 'isang araw', - dd : '%d araw', - M : 'isang buwan', - MM : '%d buwan', - y : 'isang taon', - yy : '%d taon' - }, - dayOfMonthOrdinalParse: /\d{1,2}/, - ordinal : function (number) { - return number; - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); - - //! moment.js locale configuration - - var numbersNouns = 'pagh_wa’_cha’_wej_loS_vagh_jav_Soch_chorgh_Hut'.split('_'); - - function translateFuture(output) { - var time = output; - time = (output.indexOf('jaj') !== -1) ? - time.slice(0, -3) + 'leS' : - (output.indexOf('jar') !== -1) ? - time.slice(0, -3) + 'waQ' : - (output.indexOf('DIS') !== -1) ? - time.slice(0, -3) + 'nem' : - time + ' pIq'; - return time; - } - - function translatePast(output) { - var time = output; - time = (output.indexOf('jaj') !== -1) ? - time.slice(0, -3) + 'Hu’' : - (output.indexOf('jar') !== -1) ? - time.slice(0, -3) + 'wen' : - (output.indexOf('DIS') !== -1) ? - time.slice(0, -3) + 'ben' : - time + ' ret'; - return time; - } - - function translate$a(number, withoutSuffix, string, isFuture) { - var numberNoun = numberAsNoun(number); - switch (string) { - case 'ss': - return numberNoun + ' lup'; - case 'mm': - return numberNoun + ' tup'; - case 'hh': - return numberNoun + ' rep'; - case 'dd': - return numberNoun + ' jaj'; - case 'MM': - return numberNoun + ' jar'; - case 'yy': - return numberNoun + ' DIS'; - } - } - - function numberAsNoun(number) { - var hundred = Math.floor((number % 1000) / 100), - ten = Math.floor((number % 100) / 10), - one = number % 10, - word = ''; - if (hundred > 0) { - word += numbersNouns[hundred] + 'vatlh'; - } - if (ten > 0) { - word += ((word !== '') ? ' ' : '') + numbersNouns[ten] + 'maH'; - } - if (one > 0) { - word += ((word !== '') ? ' ' : '') + numbersNouns[one]; - } - return (word === '') ? 'pagh' : word; - } - - hooks.defineLocale('tlh', { - months : 'tera’ jar wa’_tera’ jar cha’_tera’ jar wej_tera’ jar loS_tera’ jar vagh_tera’ jar jav_tera’ jar Soch_tera’ jar chorgh_tera’ jar Hut_tera’ jar wa’maH_tera’ jar wa’maH wa’_tera’ jar wa’maH cha’'.split('_'), - monthsShort : 'jar wa’_jar cha’_jar wej_jar loS_jar vagh_jar jav_jar Soch_jar chorgh_jar Hut_jar wa’maH_jar wa’maH wa’_jar wa’maH cha’'.split('_'), - monthsParseExact : true, - weekdays : 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split('_'), - weekdaysShort : 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split('_'), - weekdaysMin : 'lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj'.split('_'), - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD.MM.YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd, D MMMM YYYY HH:mm' - }, - calendar : { - sameDay: '[DaHjaj] LT', - nextDay: '[wa’leS] LT', - nextWeek: 'LLL', - lastDay: '[wa’Hu’] LT', - lastWeek: 'LLL', - sameElse: 'L' - }, - relativeTime : { - future : translateFuture, - past : translatePast, - s : 'puS lup', - ss : translate$a, - m : 'wa’ tup', - mm : translate$a, - h : 'wa’ rep', - hh : translate$a, - d : 'wa’ jaj', - dd : translate$a, - M : 'wa’ jar', - MM : translate$a, - y : 'wa’ DIS', - yy : translate$a - }, - dayOfMonthOrdinalParse: /\d{1,2}\./, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); - - var suffixes$4 = { - 1: '\'inci', - 5: '\'inci', - 8: '\'inci', - 70: '\'inci', - 80: '\'inci', - 2: '\'nci', - 7: '\'nci', - 20: '\'nci', - 50: '\'nci', - 3: '\'üncü', - 4: '\'üncü', - 100: '\'üncü', - 6: '\'ncı', - 9: '\'uncu', - 10: '\'uncu', - 30: '\'uncu', - 60: '\'ıncı', - 90: '\'ıncı' - }; - - hooks.defineLocale('tr', { - months : 'Ocak_Şubat_Mart_Nisan_Mayıs_Haziran_Temmuz_Ağustos_Eylül_Ekim_Kasım_Aralık'.split('_'), - monthsShort : 'Oca_Şub_Mar_Nis_May_Haz_Tem_Ağu_Eyl_Eki_Kas_Ara'.split('_'), - weekdays : 'Pazar_Pazartesi_Salı_Çarşamba_Perşembe_Cuma_Cumartesi'.split('_'), - weekdaysShort : 'Paz_Pts_Sal_Çar_Per_Cum_Cts'.split('_'), - weekdaysMin : 'Pz_Pt_Sa_Ça_Pe_Cu_Ct'.split('_'), - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD.MM.YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd, D MMMM YYYY HH:mm' - }, - calendar : { - sameDay : '[bugün saat] LT', - nextDay : '[yarın saat] LT', - nextWeek : '[gelecek] dddd [saat] LT', - lastDay : '[dün] LT', - lastWeek : '[geçen] dddd [saat] LT', - sameElse : 'L' - }, - relativeTime : { - future : '%s sonra', - past : '%s önce', - s : 'birkaç saniye', - ss : '%d saniye', - m : 'bir dakika', - mm : '%d dakika', - h : 'bir saat', - hh : '%d saat', - d : 'bir gün', - dd : '%d gün', - M : 'bir ay', - MM : '%d ay', - y : 'bir yıl', - yy : '%d yıl' - }, - ordinal: function (number, period) { - switch (period) { - case 'd': - case 'D': - case 'Do': - case 'DD': - return number; - default: - if (number === 0) { // special case for zero - return number + '\'ıncı'; - } - var a = number % 10, - b = number % 100 - a, - c = number >= 100 ? 100 : null; - return number + (suffixes$4[a] || suffixes$4[b] || suffixes$4[c]); - } - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 7th is the first week of the year. - } - }); - - //! moment.js locale configuration - - // After the year there should be a slash and the amount of years since December 26, 1979 in Roman numerals. - // This is currently too difficult (maybe even impossible) to add. - hooks.defineLocale('tzl', { - months : 'Januar_Fevraglh_Març_Avrïu_Mai_Gün_Julia_Guscht_Setemvar_Listopäts_Noemvar_Zecemvar'.split('_'), - monthsShort : 'Jan_Fev_Mar_Avr_Mai_Gün_Jul_Gus_Set_Lis_Noe_Zec'.split('_'), - weekdays : 'Súladi_Lúneçi_Maitzi_Márcuri_Xhúadi_Viénerçi_Sáturi'.split('_'), - weekdaysShort : 'Súl_Lún_Mai_Már_Xhú_Vié_Sát'.split('_'), - weekdaysMin : 'Sú_Lú_Ma_Má_Xh_Vi_Sá'.split('_'), - longDateFormat : { - LT : 'HH.mm', - LTS : 'HH.mm.ss', - L : 'DD.MM.YYYY', - LL : 'D. MMMM [dallas] YYYY', - LLL : 'D. MMMM [dallas] YYYY HH.mm', - LLLL : 'dddd, [li] D. MMMM [dallas] YYYY HH.mm' - }, - meridiemParse: /d\'o|d\'a/i, - isPM : function (input) { - return 'd\'o' === input.toLowerCase(); - }, - meridiem : function (hours, minutes, isLower) { - if (hours > 11) { - return isLower ? 'd\'o' : 'D\'O'; - } else { - return isLower ? 'd\'a' : 'D\'A'; - } - }, - calendar : { - sameDay : '[oxhi à] LT', - nextDay : '[demà à] LT', - nextWeek : 'dddd [à] LT', - lastDay : '[ieiri à] LT', - lastWeek : '[sür el] dddd [lasteu à] LT', - sameElse : 'L' - }, - relativeTime : { - future : 'osprei %s', - past : 'ja%s', - s : processRelativeTime$7, - ss : processRelativeTime$7, - m : processRelativeTime$7, - mm : processRelativeTime$7, - h : processRelativeTime$7, - hh : processRelativeTime$7, - d : processRelativeTime$7, - dd : processRelativeTime$7, - M : processRelativeTime$7, - MM : processRelativeTime$7, - y : processRelativeTime$7, - yy : processRelativeTime$7 - }, - dayOfMonthOrdinalParse: /\d{1,2}\./, - ordinal : '%d.', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); - - function processRelativeTime$7(number, withoutSuffix, key, isFuture) { - var format = { - 's': ['viensas secunds', '\'iensas secunds'], - 'ss': [number + ' secunds', '' + number + ' secunds'], - 'm': ['\'n míut', '\'iens míut'], - 'mm': [number + ' míuts', '' + number + ' míuts'], - 'h': ['\'n þora', '\'iensa þora'], - 'hh': [number + ' þoras', '' + number + ' þoras'], - 'd': ['\'n ziua', '\'iensa ziua'], - 'dd': [number + ' ziuas', '' + number + ' ziuas'], - 'M': ['\'n mes', '\'iens mes'], - 'MM': [number + ' mesen', '' + number + ' mesen'], - 'y': ['\'n ar', '\'iens ar'], - 'yy': [number + ' ars', '' + number + ' ars'] - }; - return isFuture ? format[key][0] : (withoutSuffix ? format[key][0] : format[key][1]); - } - - //! moment.js locale configuration - - hooks.defineLocale('tzm-latn', { - months : 'innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir'.split('_'), - monthsShort : 'innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir'.split('_'), - weekdays : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'), - weekdaysShort : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'), - weekdaysMin : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'), - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd D MMMM YYYY HH:mm' - }, - calendar : { - sameDay: '[asdkh g] LT', - nextDay: '[aska g] LT', - nextWeek: 'dddd [g] LT', - lastDay: '[assant g] LT', - lastWeek: 'dddd [g] LT', - sameElse: 'L' - }, - relativeTime : { - future : 'dadkh s yan %s', - past : 'yan %s', - s : 'imik', - ss : '%d imik', - m : 'minuḍ', - mm : '%d minuḍ', - h : 'saɛa', - hh : '%d tassaɛin', - d : 'ass', - dd : '%d ossan', - M : 'ayowr', - MM : '%d iyyirn', - y : 'asgas', - yy : '%d isgasn' - }, - week : { - dow : 6, // Saturday is the first day of the week. - doy : 12 // The week that contains Jan 12th is the first week of the year. - } - }); - - //! moment.js locale configuration - - hooks.defineLocale('tzm', { - months : 'ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ'.split('_'), - monthsShort : 'ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ'.split('_'), - weekdays : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'), - weekdaysShort : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'), - weekdaysMin : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'), - longDateFormat : { - LT : 'HH:mm', - LTS: 'HH:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd D MMMM YYYY HH:mm' - }, - calendar : { - sameDay: '[ⴰⵙⴷⵅ ⴴ] LT', - nextDay: '[ⴰⵙⴽⴰ ⴴ] LT', - nextWeek: 'dddd [ⴴ] LT', - lastDay: '[ⴰⵚⴰⵏⵜ ⴴ] LT', - lastWeek: 'dddd [ⴴ] LT', - sameElse: 'L' - }, - relativeTime : { - future : 'ⴷⴰⴷⵅ ⵙ ⵢⴰⵏ %s', - past : 'ⵢⴰⵏ %s', - s : 'ⵉⵎⵉⴽ', - ss : '%d ⵉⵎⵉⴽ', - m : 'ⵎⵉⵏⵓⴺ', - mm : '%d ⵎⵉⵏⵓⴺ', - h : 'ⵙⴰⵄⴰ', - hh : '%d ⵜⴰⵙⵙⴰⵄⵉⵏ', - d : 'ⴰⵙⵙ', - dd : '%d oⵙⵙⴰⵏ', - M : 'ⴰⵢoⵓⵔ', - MM : '%d ⵉⵢⵢⵉⵔⵏ', - y : 'ⴰⵙⴳⴰⵙ', - yy : '%d ⵉⵙⴳⴰⵙⵏ' - }, - week : { - dow : 6, // Saturday is the first day of the week. - doy : 12 // The week that contains Jan 12th is the first week of the year. - } - }); - - //! moment.js language configuration - - hooks.defineLocale('ug-cn', { - months: 'يانۋار_فېۋرال_مارت_ئاپرېل_ماي_ئىيۇن_ئىيۇل_ئاۋغۇست_سېنتەبىر_ئۆكتەبىر_نويابىر_دېكابىر'.split( - '_' - ), - monthsShort: 'يانۋار_فېۋرال_مارت_ئاپرېل_ماي_ئىيۇن_ئىيۇل_ئاۋغۇست_سېنتەبىر_ئۆكتەبىر_نويابىر_دېكابىر'.split( - '_' - ), - weekdays: 'يەكشەنبە_دۈشەنبە_سەيشەنبە_چارشەنبە_پەيشەنبە_جۈمە_شەنبە'.split( - '_' - ), - weekdaysShort: 'يە_دۈ_سە_چا_پە_جۈ_شە'.split('_'), - weekdaysMin: 'يە_دۈ_سە_چا_پە_جۈ_شە'.split('_'), - longDateFormat: { - LT: 'HH:mm', - LTS: 'HH:mm:ss', - L: 'YYYY-MM-DD', - LL: 'YYYY-يىلىM-ئاينىڭD-كۈنى', - LLL: 'YYYY-يىلىM-ئاينىڭD-كۈنى، HH:mm', - LLLL: 'dddd، YYYY-يىلىM-ئاينىڭD-كۈنى، HH:mm' - }, - meridiemParse: /يېرىم كېچە|سەھەر|چۈشتىن بۇرۇن|چۈش|چۈشتىن كېيىن|كەچ/, - meridiemHour: function (hour, meridiem) { - if (hour === 12) { - hour = 0; - } - if ( - meridiem === 'يېرىم كېچە' || - meridiem === 'سەھەر' || - meridiem === 'چۈشتىن بۇرۇن' - ) { - return hour; - } else if (meridiem === 'چۈشتىن كېيىن' || meridiem === 'كەچ') { - return hour + 12; - } else { - return hour >= 11 ? hour : hour + 12; - } - }, - meridiem: function (hour, minute, isLower) { - var hm = hour * 100 + minute; - if (hm < 600) { - return 'يېرىم كېچە'; - } else if (hm < 900) { - return 'سەھەر'; - } else if (hm < 1130) { - return 'چۈشتىن بۇرۇن'; - } else if (hm < 1230) { - return 'چۈش'; - } else if (hm < 1800) { - return 'چۈشتىن كېيىن'; - } else { - return 'كەچ'; - } - }, - calendar: { - sameDay: '[بۈگۈن سائەت] LT', - nextDay: '[ئەتە سائەت] LT', - nextWeek: '[كېلەركى] dddd [سائەت] LT', - lastDay: '[تۆنۈگۈن] LT', - lastWeek: '[ئالدىنقى] dddd [سائەت] LT', - sameElse: 'L' - }, - relativeTime: { - future: '%s كېيىن', - past: '%s بۇرۇن', - s: 'نەچچە سېكونت', - ss: '%d سېكونت', - m: 'بىر مىنۇت', - mm: '%d مىنۇت', - h: 'بىر سائەت', - hh: '%d سائەت', - d: 'بىر كۈن', - dd: '%d كۈن', - M: 'بىر ئاي', - MM: '%d ئاي', - y: 'بىر يىل', - yy: '%d يىل' - }, - - dayOfMonthOrdinalParse: /\d{1,2}(-كۈنى|-ئاي|-ھەپتە)/, - ordinal: function (number, period) { - switch (period) { - case 'd': - case 'D': - case 'DDD': - return number + '-كۈنى'; - case 'w': - case 'W': - return number + '-ھەپتە'; - default: - return number; - } - }, - preparse: function (string) { - return string.replace(/،/g, ','); - }, - postformat: function (string) { - return string.replace(/,/g, '،'); - }, - week: { - // GB/T 7408-1994《数据元和交换格式·信息交换·日期和时间表示法》与ISO 8601:1988等效 - dow: 1, // Monday is the first day of the week. - doy: 7 // The week that contains Jan 1st is the first week of the year. - } - }); - - //! moment.js locale configuration - - function plural$6(word, num) { - var forms = word.split('_'); - return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]); - } - function relativeTimeWithPlural$4(number, withoutSuffix, key) { - var format = { - 'ss': withoutSuffix ? 'секунда_секунди_секунд' : 'секунду_секунди_секунд', - 'mm': withoutSuffix ? 'хвилина_хвилини_хвилин' : 'хвилину_хвилини_хвилин', - 'hh': withoutSuffix ? 'година_години_годин' : 'годину_години_годин', - 'dd': 'день_дні_днів', - 'MM': 'місяць_місяці_місяців', - 'yy': 'рік_роки_років' - }; - if (key === 'm') { - return withoutSuffix ? 'хвилина' : 'хвилину'; - } - else if (key === 'h') { - return withoutSuffix ? 'година' : 'годину'; - } - else { - return number + ' ' + plural$6(format[key], +number); - } - } - function weekdaysCaseReplace(m, format) { - var weekdays = { - 'nominative': 'неділя_понеділок_вівторок_середа_четвер_п’ятниця_субота'.split('_'), - 'accusative': 'неділю_понеділок_вівторок_середу_четвер_п’ятницю_суботу'.split('_'), - 'genitive': 'неділі_понеділка_вівторка_середи_четверга_п’ятниці_суботи'.split('_') - }; - - if (!m) { - return weekdays['nominative']; - } - - var nounCase = (/(\[[ВвУу]\]) ?dddd/).test(format) ? - 'accusative' : - ((/\[?(?:минулої|наступної)? ?\] ?dddd/).test(format) ? - 'genitive' : - 'nominative'); - return weekdays[nounCase][m.day()]; - } - function processHoursFunction(str) { - return function () { - return str + 'о' + (this.hours() === 11 ? 'б' : '') + '] LT'; - }; - } - - hooks.defineLocale('uk', { - months : { - 'format': 'січня_лютого_березня_квітня_травня_червня_липня_серпня_вересня_жовтня_листопада_грудня'.split('_'), - 'standalone': 'січень_лютий_березень_квітень_травень_червень_липень_серпень_вересень_жовтень_листопад_грудень'.split('_') - }, - monthsShort : 'січ_лют_бер_квіт_трав_черв_лип_серп_вер_жовт_лист_груд'.split('_'), - weekdays : weekdaysCaseReplace, - weekdaysShort : 'нд_пн_вт_ср_чт_пт_сб'.split('_'), - weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'), - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD.MM.YYYY', - LL : 'D MMMM YYYY р.', - LLL : 'D MMMM YYYY р., HH:mm', - LLLL : 'dddd, D MMMM YYYY р., HH:mm' - }, - calendar : { - sameDay: processHoursFunction('[Сьогодні '), - nextDay: processHoursFunction('[Завтра '), - lastDay: processHoursFunction('[Вчора '), - nextWeek: processHoursFunction('[У] dddd ['), - lastWeek: function () { - switch (this.day()) { - case 0: - case 3: - case 5: - case 6: - return processHoursFunction('[Минулої] dddd [').call(this); - case 1: - case 2: - case 4: - return processHoursFunction('[Минулого] dddd [').call(this); - } - }, - sameElse: 'L' - }, - relativeTime : { - future : 'за %s', - past : '%s тому', - s : 'декілька секунд', - ss : relativeTimeWithPlural$4, - m : relativeTimeWithPlural$4, - mm : relativeTimeWithPlural$4, - h : 'годину', - hh : relativeTimeWithPlural$4, - d : 'день', - dd : relativeTimeWithPlural$4, - M : 'місяць', - MM : relativeTimeWithPlural$4, - y : 'рік', - yy : relativeTimeWithPlural$4 - }, - // M. E.: those two are virtually unused but a user might want to implement them for his/her website for some reason - meridiemParse: /ночі|ранку|дня|вечора/, - isPM: function (input) { - return /^(дня|вечора)$/.test(input); - }, - meridiem : function (hour, minute, isLower) { - if (hour < 4) { - return 'ночі'; - } else if (hour < 12) { - return 'ранку'; - } else if (hour < 17) { - return 'дня'; - } else { - return 'вечора'; - } - }, - dayOfMonthOrdinalParse: /\d{1,2}-(й|го)/, - ordinal: function (number, period) { - switch (period) { - case 'M': - case 'd': - case 'DDD': - case 'w': - case 'W': - return number + '-й'; - case 'D': - return number + '-го'; - default: - return number; - } - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 7th is the first week of the year. - } - }); - - //! moment.js locale configuration - - var months$9 = [ - 'جنوری', - 'فروری', - 'مارچ', - 'اپریل', - 'مئی', - 'جون', - 'جولائی', - 'اگست', - 'ستمبر', - 'اکتوبر', - 'نومبر', - 'دسمبر' - ]; - var days$2 = [ - 'اتوار', - 'پیر', - 'منگل', - 'بدھ', - 'جمعرات', - 'جمعہ', - 'ہفتہ' - ]; - - hooks.defineLocale('ur', { - months : months$9, - monthsShort : months$9, - weekdays : days$2, - weekdaysShort : days$2, - weekdaysMin : days$2, - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd، D MMMM YYYY HH:mm' - }, - meridiemParse: /صبح|شام/, - isPM : function (input) { - return 'شام' === input; - }, - meridiem : function (hour, minute, isLower) { - if (hour < 12) { - return 'صبح'; - } - return 'شام'; - }, - calendar : { - sameDay : '[آج بوقت] LT', - nextDay : '[کل بوقت] LT', - nextWeek : 'dddd [بوقت] LT', - lastDay : '[گذشتہ روز بوقت] LT', - lastWeek : '[گذشتہ] dddd [بوقت] LT', - sameElse : 'L' - }, - relativeTime : { - future : '%s بعد', - past : '%s قبل', - s : 'چند سیکنڈ', - ss : '%d سیکنڈ', - m : 'ایک منٹ', - mm : '%d منٹ', - h : 'ایک گھنٹہ', - hh : '%d گھنٹے', - d : 'ایک دن', - dd : '%d دن', - M : 'ایک ماہ', - MM : '%d ماہ', - y : 'ایک سال', - yy : '%d سال' - }, - preparse: function (string) { - return string.replace(/،/g, ','); - }, - postformat: function (string) { - return string.replace(/,/g, '،'); - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); - - //! moment.js locale configuration - - hooks.defineLocale('uz-latn', { - months : 'Yanvar_Fevral_Mart_Aprel_May_Iyun_Iyul_Avgust_Sentabr_Oktabr_Noyabr_Dekabr'.split('_'), - monthsShort : 'Yan_Fev_Mar_Apr_May_Iyun_Iyul_Avg_Sen_Okt_Noy_Dek'.split('_'), - weekdays : 'Yakshanba_Dushanba_Seshanba_Chorshanba_Payshanba_Juma_Shanba'.split('_'), - weekdaysShort : 'Yak_Dush_Sesh_Chor_Pay_Jum_Shan'.split('_'), - weekdaysMin : 'Ya_Du_Se_Cho_Pa_Ju_Sha'.split('_'), - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'D MMMM YYYY, dddd HH:mm' - }, - calendar : { - sameDay : '[Bugun soat] LT [da]', - nextDay : '[Ertaga] LT [da]', - nextWeek : 'dddd [kuni soat] LT [da]', - lastDay : '[Kecha soat] LT [da]', - lastWeek : '[O\'tgan] dddd [kuni soat] LT [da]', - sameElse : 'L' - }, - relativeTime : { - future : 'Yaqin %s ichida', - past : 'Bir necha %s oldin', - s : 'soniya', - ss : '%d soniya', - m : 'bir daqiqa', - mm : '%d daqiqa', - h : 'bir soat', - hh : '%d soat', - d : 'bir kun', - dd : '%d kun', - M : 'bir oy', - MM : '%d oy', - y : 'bir yil', - yy : '%d yil' - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 7th is the first week of the year. - } - }); - - //! moment.js locale configuration - - hooks.defineLocale('uz', { - months : 'январ_феврал_март_апрел_май_июн_июл_август_сентябр_октябр_ноябр_декабр'.split('_'), - monthsShort : 'янв_фев_мар_апр_май_июн_июл_авг_сен_окт_ноя_дек'.split('_'), - weekdays : 'Якшанба_Душанба_Сешанба_Чоршанба_Пайшанба_Жума_Шанба'.split('_'), - weekdaysShort : 'Якш_Душ_Сеш_Чор_Пай_Жум_Шан'.split('_'), - weekdaysMin : 'Як_Ду_Се_Чо_Па_Жу_Ша'.split('_'), - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'D MMMM YYYY, dddd HH:mm' - }, - calendar : { - sameDay : '[Бугун соат] LT [да]', - nextDay : '[Эртага] LT [да]', - nextWeek : 'dddd [куни соат] LT [да]', - lastDay : '[Кеча соат] LT [да]', - lastWeek : '[Утган] dddd [куни соат] LT [да]', - sameElse : 'L' - }, - relativeTime : { - future : 'Якин %s ичида', - past : 'Бир неча %s олдин', - s : 'фурсат', - ss : '%d фурсат', - m : 'бир дакика', - mm : '%d дакика', - h : 'бир соат', - hh : '%d соат', - d : 'бир кун', - dd : '%d кун', - M : 'бир ой', - MM : '%d ой', - y : 'бир йил', - yy : '%d йил' - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 7 // The week that contains Jan 4th is the first week of the year. - } - }); - - //! moment.js locale configuration - - hooks.defineLocale('vi', { - months : 'tháng 1_tháng 2_tháng 3_tháng 4_tháng 5_tháng 6_tháng 7_tháng 8_tháng 9_tháng 10_tháng 11_tháng 12'.split('_'), - monthsShort : 'Th01_Th02_Th03_Th04_Th05_Th06_Th07_Th08_Th09_Th10_Th11_Th12'.split('_'), - monthsParseExact : true, - weekdays : 'chủ nhật_thứ hai_thứ ba_thứ tư_thứ năm_thứ sáu_thứ bảy'.split('_'), - weekdaysShort : 'CN_T2_T3_T4_T5_T6_T7'.split('_'), - weekdaysMin : 'CN_T2_T3_T4_T5_T6_T7'.split('_'), - weekdaysParseExact : true, - meridiemParse: /sa|ch/i, - isPM : function (input) { - return /^ch$/i.test(input); - }, - meridiem : function (hours, minutes, isLower) { - if (hours < 12) { - return isLower ? 'sa' : 'SA'; - } else { - return isLower ? 'ch' : 'CH'; - } - }, - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'DD/MM/YYYY', - LL : 'D MMMM [năm] YYYY', - LLL : 'D MMMM [năm] YYYY HH:mm', - LLLL : 'dddd, D MMMM [năm] YYYY HH:mm', - l : 'DD/M/YYYY', - ll : 'D MMM YYYY', - lll : 'D MMM YYYY HH:mm', - llll : 'ddd, D MMM YYYY HH:mm' - }, - calendar : { - sameDay: '[Hôm nay lúc] LT', - nextDay: '[Ngày mai lúc] LT', - nextWeek: 'dddd [tuần tới lúc] LT', - lastDay: '[Hôm qua lúc] LT', - lastWeek: 'dddd [tuần rồi lúc] LT', - sameElse: 'L' - }, - relativeTime : { - future : '%s tới', - past : '%s trước', - s : 'vài giây', - ss : '%d giây' , - m : 'một phút', - mm : '%d phút', - h : 'một giờ', - hh : '%d giờ', - d : 'một ngày', - dd : '%d ngày', - M : 'một tháng', - MM : '%d tháng', - y : 'một năm', - yy : '%d năm' - }, - dayOfMonthOrdinalParse: /\d{1,2}/, - ordinal : function (number) { - return number; - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); - - //! moment.js locale configuration - - hooks.defineLocale('x-pseudo', { - months : 'J~áñúá~rý_F~ébrú~árý_~Márc~h_Áp~ríl_~Máý_~Júñé~_Júl~ý_Áú~gúst~_Sép~témb~ér_Ó~ctób~ér_Ñ~óvém~bér_~Décé~mbér'.split('_'), - monthsShort : 'J~áñ_~Féb_~Már_~Ápr_~Máý_~Júñ_~Júl_~Áúg_~Sép_~Óct_~Ñóv_~Déc'.split('_'), - monthsParseExact : true, - weekdays : 'S~úñdá~ý_Mó~ñdáý~_Túé~sdáý~_Wéd~ñésd~áý_T~húrs~dáý_~Fríd~áý_S~átúr~dáý'.split('_'), - weekdaysShort : 'S~úñ_~Móñ_~Túé_~Wéd_~Thú_~Frí_~Sát'.split('_'), - weekdaysMin : 'S~ú_Mó~_Tú_~Wé_T~h_Fr~_Sá'.split('_'), - weekdaysParseExact : true, - longDateFormat : { - LT : 'HH:mm', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY HH:mm', - LLLL : 'dddd, D MMMM YYYY HH:mm' - }, - calendar : { - sameDay : '[T~ódá~ý át] LT', - nextDay : '[T~ómó~rró~w át] LT', - nextWeek : 'dddd [át] LT', - lastDay : '[Ý~ést~érdá~ý át] LT', - lastWeek : '[L~ást] dddd [át] LT', - sameElse : 'L' - }, - relativeTime : { - future : 'í~ñ %s', - past : '%s á~gó', - s : 'á ~féw ~sécó~ñds', - ss : '%d s~écóñ~ds', - m : 'á ~míñ~úté', - mm : '%d m~íñú~tés', - h : 'á~ñ hó~úr', - hh : '%d h~óúrs', - d : 'á ~dáý', - dd : '%d d~áýs', - M : 'á ~móñ~th', - MM : '%d m~óñt~hs', - y : 'á ~ýéár', - yy : '%d ý~éárs' - }, - dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/, - ordinal : function (number) { - var b = number % 10, - output = (~~(number % 100 / 10) === 1) ? 'th' : - (b === 1) ? 'st' : - (b === 2) ? 'nd' : - (b === 3) ? 'rd' : 'th'; - return number + output; - }, - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); - - //! moment.js locale configuration - - hooks.defineLocale('yo', { - months : 'Sẹ́rẹ́_Èrèlè_Ẹrẹ̀nà_Ìgbé_Èbibi_Òkùdu_Agẹmo_Ògún_Owewe_Ọ̀wàrà_Bélú_Ọ̀pẹ̀̀'.split('_'), - monthsShort : 'Sẹ́r_Èrl_Ẹrn_Ìgb_Èbi_Òkù_Agẹ_Ògú_Owe_Ọ̀wà_Bél_Ọ̀pẹ̀̀'.split('_'), - weekdays : 'Àìkú_Ajé_Ìsẹ́gun_Ọjọ́rú_Ọjọ́bọ_Ẹtì_Àbámẹ́ta'.split('_'), - weekdaysShort : 'Àìk_Ajé_Ìsẹ́_Ọjr_Ọjb_Ẹtì_Àbá'.split('_'), - weekdaysMin : 'Àì_Aj_Ìs_Ọr_Ọb_Ẹt_Àb'.split('_'), - longDateFormat : { - LT : 'h:mm A', - LTS : 'h:mm:ss A', - L : 'DD/MM/YYYY', - LL : 'D MMMM YYYY', - LLL : 'D MMMM YYYY h:mm A', - LLLL : 'dddd, D MMMM YYYY h:mm A' - }, - calendar : { - sameDay : '[Ònì ni] LT', - nextDay : '[Ọ̀la ni] LT', - nextWeek : 'dddd [Ọsẹ̀ tón\'bọ] [ni] LT', - lastDay : '[Àna ni] LT', - lastWeek : 'dddd [Ọsẹ̀ tólọ́] [ni] LT', - sameElse : 'L' - }, - relativeTime : { - future : 'ní %s', - past : '%s kọjá', - s : 'ìsẹjú aayá die', - ss :'aayá %d', - m : 'ìsẹjú kan', - mm : 'ìsẹjú %d', - h : 'wákati kan', - hh : 'wákati %d', - d : 'ọjọ́ kan', - dd : 'ọjọ́ %d', - M : 'osù kan', - MM : 'osù %d', - y : 'ọdún kan', - yy : 'ọdún %d' - }, - dayOfMonthOrdinalParse : /ọjọ́\s\d{1,2}/, - ordinal : 'ọjọ́ %d', - week : { - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); - - //! moment.js locale configuration - - hooks.defineLocale('zh-cn', { - months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'), - monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'), - weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'), - weekdaysShort : '周日_周一_周二_周三_周四_周五_周六'.split('_'), - weekdaysMin : '日_一_二_三_四_五_六'.split('_'), - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'YYYY/MM/DD', - LL : 'YYYY年M月D日', - LLL : 'YYYY年M月D日Ah点mm分', - LLLL : 'YYYY年M月D日ddddAh点mm分', - l : 'YYYY/M/D', - ll : 'YYYY年M月D日', - lll : 'YYYY年M月D日 HH:mm', - llll : 'YYYY年M月D日dddd HH:mm' - }, - meridiemParse: /凌晨|早上|上午|中午|下午|晚上/, - meridiemHour: function (hour, meridiem) { - if (hour === 12) { - hour = 0; - } - if (meridiem === '凌晨' || meridiem === '早上' || - meridiem === '上午') { - return hour; - } else if (meridiem === '下午' || meridiem === '晚上') { - return hour + 12; - } else { - // '中午' - return hour >= 11 ? hour : hour + 12; - } - }, - meridiem : function (hour, minute, isLower) { - var hm = hour * 100 + minute; - if (hm < 600) { - return '凌晨'; - } else if (hm < 900) { - return '早上'; - } else if (hm < 1130) { - return '上午'; - } else if (hm < 1230) { - return '中午'; - } else if (hm < 1800) { - return '下午'; - } else { - return '晚上'; - } - }, - calendar : { - sameDay : '[今天]LT', - nextDay : '[明天]LT', - nextWeek : '[下]ddddLT', - lastDay : '[昨天]LT', - lastWeek : '[上]ddddLT', - sameElse : 'L' - }, - dayOfMonthOrdinalParse: /\d{1,2}(日|月|周)/, - ordinal : function (number, period) { - switch (period) { - case 'd': - case 'D': - case 'DDD': - return number + '日'; - case 'M': - return number + '月'; - case 'w': - case 'W': - return number + '周'; - default: - return number; - } - }, - relativeTime : { - future : '%s内', - past : '%s前', - s : '几秒', - ss : '%d 秒', - m : '1 分钟', - mm : '%d 分钟', - h : '1 小时', - hh : '%d 小时', - d : '1 天', - dd : '%d 天', - M : '1 个月', - MM : '%d 个月', - y : '1 年', - yy : '%d 年' - }, - week : { - // GB/T 7408-1994《数据元和交换格式·信息交换·日期和时间表示法》与ISO 8601:1988等效 - dow : 1, // Monday is the first day of the week. - doy : 4 // The week that contains Jan 4th is the first week of the year. - } - }); - - //! moment.js locale configuration - - hooks.defineLocale('zh-hk', { - months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'), - monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'), - weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'), - weekdaysShort : '週日_週一_週二_週三_週四_週五_週六'.split('_'), - weekdaysMin : '日_一_二_三_四_五_六'.split('_'), - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'YYYY/MM/DD', - LL : 'YYYY年M月D日', - LLL : 'YYYY年M月D日 HH:mm', - LLLL : 'YYYY年M月D日dddd HH:mm', - l : 'YYYY/M/D', - ll : 'YYYY年M月D日', - lll : 'YYYY年M月D日 HH:mm', - llll : 'YYYY年M月D日dddd HH:mm' - }, - meridiemParse: /凌晨|早上|上午|中午|下午|晚上/, - meridiemHour : function (hour, meridiem) { - if (hour === 12) { - hour = 0; - } - if (meridiem === '凌晨' || meridiem === '早上' || meridiem === '上午') { - return hour; - } else if (meridiem === '中午') { - return hour >= 11 ? hour : hour + 12; - } else if (meridiem === '下午' || meridiem === '晚上') { - return hour + 12; - } - }, - meridiem : function (hour, minute, isLower) { - var hm = hour * 100 + minute; - if (hm < 600) { - return '凌晨'; - } else if (hm < 900) { - return '早上'; - } else if (hm < 1130) { - return '上午'; - } else if (hm < 1230) { - return '中午'; - } else if (hm < 1800) { - return '下午'; - } else { - return '晚上'; - } - }, - calendar : { - sameDay : '[今天]LT', - nextDay : '[明天]LT', - nextWeek : '[下]ddddLT', - lastDay : '[昨天]LT', - lastWeek : '[上]ddddLT', - sameElse : 'L' - }, - dayOfMonthOrdinalParse: /\d{1,2}(日|月|週)/, - ordinal : function (number, period) { - switch (period) { - case 'd' : - case 'D' : - case 'DDD' : - return number + '日'; - case 'M' : - return number + '月'; - case 'w' : - case 'W' : - return number + '週'; - default : - return number; - } - }, - relativeTime : { - future : '%s內', - past : '%s前', - s : '幾秒', - ss : '%d 秒', - m : '1 分鐘', - mm : '%d 分鐘', - h : '1 小時', - hh : '%d 小時', - d : '1 天', - dd : '%d 天', - M : '1 個月', - MM : '%d 個月', - y : '1 年', - yy : '%d 年' - } - }); - - //! moment.js locale configuration - - hooks.defineLocale('zh-tw', { - months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'), - monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'), - weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'), - weekdaysShort : '週日_週一_週二_週三_週四_週五_週六'.split('_'), - weekdaysMin : '日_一_二_三_四_五_六'.split('_'), - longDateFormat : { - LT : 'HH:mm', - LTS : 'HH:mm:ss', - L : 'YYYY/MM/DD', - LL : 'YYYY年M月D日', - LLL : 'YYYY年M月D日 HH:mm', - LLLL : 'YYYY年M月D日dddd HH:mm', - l : 'YYYY/M/D', - ll : 'YYYY年M月D日', - lll : 'YYYY年M月D日 HH:mm', - llll : 'YYYY年M月D日dddd HH:mm' - }, - meridiemParse: /凌晨|早上|上午|中午|下午|晚上/, - meridiemHour : function (hour, meridiem) { - if (hour === 12) { - hour = 0; - } - if (meridiem === '凌晨' || meridiem === '早上' || meridiem === '上午') { - return hour; - } else if (meridiem === '中午') { - return hour >= 11 ? hour : hour + 12; - } else if (meridiem === '下午' || meridiem === '晚上') { - return hour + 12; - } - }, - meridiem : function (hour, minute, isLower) { - var hm = hour * 100 + minute; - if (hm < 600) { - return '凌晨'; - } else if (hm < 900) { - return '早上'; - } else if (hm < 1130) { - return '上午'; - } else if (hm < 1230) { - return '中午'; - } else if (hm < 1800) { - return '下午'; - } else { - return '晚上'; - } - }, - calendar : { - sameDay : '[今天] LT', - nextDay : '[明天] LT', - nextWeek : '[下]dddd LT', - lastDay : '[昨天] LT', - lastWeek : '[上]dddd LT', - sameElse : 'L' - }, - dayOfMonthOrdinalParse: /\d{1,2}(日|月|週)/, - ordinal : function (number, period) { - switch (period) { - case 'd' : - case 'D' : - case 'DDD' : - return number + '日'; - case 'M' : - return number + '月'; - case 'w' : - case 'W' : - return number + '週'; - default : - return number; - } - }, - relativeTime : { - future : '%s內', - past : '%s前', - s : '幾秒', - ss : '%d 秒', - m : '1 分鐘', - mm : '%d 分鐘', - h : '1 小時', - hh : '%d 小時', - d : '1 天', - dd : '%d 天', - M : '1 個月', - MM : '%d 個月', - y : '1 年', - yy : '%d 年' - } - }); - - hooks.locale('en'); - - return hooks; - -}))); diff --git a/assets/python/save_random_numbers.py b/assets/python/save_random_numbers.py new file mode 100644 index 00000000..c1c26dac --- /dev/null +++ b/assets/python/save_random_numbers.py @@ -0,0 +1,28 @@ +import numpy as np +from pathlib import Path +import csv + + +def save_random_numbers( + size: int, seed: int = 87653546, save_as: Union[str, Path] = "./random_numbers.txt" +) -> None: + """Save a list of random numbers (floats) to the given file. + + The stated number of random numbers will be saved to the given target file, if the directory structure + doesn't exist it will be created. Output will by default be over-written. + + Parameters + ---------- + size : int + Number of random numbers to generate + seed: int + Seed for random number generation + save_as : Union[str, Path] + Directory/file to save numbers to. + """ + rng = np.random.default_rng() + random_numbers = rng.random(size) + + with Path(save_as).open("w") as out: + writer = csv.write(out) + writer.writerows(random_numbers) diff --git a/assets/slides/2022-03-17-lb-hep/ATLAS_4M_MT.pdf b/assets/slides/2022-03-17-lb-hep/ATLAS_4M_MT.pdf new file mode 100644 index 00000000..31f23779 Binary files /dev/null and b/assets/slides/2022-03-17-lb-hep/ATLAS_4M_MT.pdf differ diff --git a/assets/slides/2022-03-17-lb-hep/LunchBytes_mhodgkin_2022.pdf b/assets/slides/2022-03-17-lb-hep/LunchBytes_mhodgkin_2022.pdf new file mode 100644 index 00000000..09a67e9e Binary files /dev/null and b/assets/slides/2022-03-17-lb-hep/LunchBytes_mhodgkin_2022.pdf differ diff --git a/assets/slides/2022-07-21-workflow-lb/LunchBytes 2022-07-21_ the trouble with scripts_ motivation for .pdf b/assets/slides/2022-07-21-workflow-lb/LunchBytes 2022-07-21_ the trouble with scripts_ motivation for .pdf new file mode 100644 index 00000000..fddc20b8 Binary files /dev/null and b/assets/slides/2022-07-21-workflow-lb/LunchBytes 2022-07-21_ the trouble with scripts_ motivation for .pdf differ diff --git a/assets/slides/2022-07-21-workflow-lb/Nextflow.pptx b/assets/slides/2022-07-21-workflow-lb/Nextflow.pptx new file mode 100644 index 00000000..abf68d4a Binary files /dev/null and b/assets/slides/2022-07-21-workflow-lb/Nextflow.pptx differ diff --git a/assets/slides/2022-07-21-workflow-lb/Workflow managers for research IT.pdf b/assets/slides/2022-07-21-workflow-lb/Workflow managers for research IT.pdf new file mode 100644 index 00000000..a998e126 Binary files /dev/null and b/assets/slides/2022-07-21-workflow-lb/Workflow managers for research IT.pdf differ diff --git a/assets/slides/2121-10-13_LB_MATLAB/LunchBytes 13 October 2021 Fred Sonnenwald v1.1.pptx b/assets/slides/2121-10-13_LB_MATLAB/LunchBytes 13 October 2021 Fred Sonnenwald v1.1.pptx new file mode 100644 index 00000000..fae09a1e Binary files /dev/null and b/assets/slides/2121-10-13_LB_MATLAB/LunchBytes 13 October 2021 Fred Sonnenwald v1.1.pptx differ diff --git a/assets/slides/2121-10-13_LB_MATLAB/Sheffield_Lunch_Croucher.zip b/assets/slides/2121-10-13_LB_MATLAB/Sheffield_Lunch_Croucher.zip new file mode 100644 index 00000000..045519d8 Binary files /dev/null and b/assets/slides/2121-10-13_LB_MATLAB/Sheffield_Lunch_Croucher.zip differ diff --git a/assets/slides/2121-10-13_LB_MATLAB/lunchbytes_parallel_classes_TR.pdf b/assets/slides/2121-10-13_LB_MATLAB/lunchbytes_parallel_classes_TR.pdf new file mode 100644 index 00000000..1261822d Binary files /dev/null and b/assets/slides/2121-10-13_LB_MATLAB/lunchbytes_parallel_classes_TR.pdf differ diff --git a/blog/index.html b/blog/index.html new file mode 100644 index 00000000..59002120 --- /dev/null +++ b/blog/index.html @@ -0,0 +1,53 @@ +--- +layout: page +title: RSE Sheffield Blog +--- + + +{% for post in paginator.posts %} + +

{{ post.title }}

+{% if post.author %} +
+ +
{{ post.author }}
+
+{% endif %} + +{% if post.date %} +
+ +
{{ post.date | date: "%-d %B %Y %H:%M" }}
+
+{% endif %} + +
+ {{ post.excerpt }} +
+ + {% if post != paginator.posts.last %} +
+ {% endif %} + +{% endfor %} + + +
+ +
diff --git a/pages/blog.md b/pages/blog.md deleted file mode 100644 index 9a39883c..00000000 --- a/pages/blog.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -title: Blog -layout: page -permalink: /blog/ ---- - -
- -{% include post_list.html %} diff --git a/pages/service/activities/activities.md b/pages/collaboration/activities/activities.md similarity index 89% rename from pages/service/activities/activities.md rename to pages/collaboration/activities/activities.md index d5762542..669e1ed2 100644 --- a/pages/service/activities/activities.md +++ b/pages/collaboration/activities/activities.md @@ -1,6 +1,6 @@ --- title: Research Software Engineering Sheffield - what we do -permalink: /service/activities/ +permalink: /collaboration/activities/ slug: index type: text --- @@ -118,3 +118,21 @@ The group is involved in a range of training and outreach activities including Code Cafe, Software Carpentry and a full module in [Parallel computing with GPUs](). + +## Expertise + +Areas of expertise within the team include: + +* code optimisation and performance +* reproducibility and embedding good software engineering practice with your project or team +* GPU computing and Deep Learning +* statistical analysis and data visualisation +* High Performance Computing for local/national/international/cloud systems +* general software development +* development of impact case studies +* consultancy +* training +* education delivery and support + +Our list of specialist expertise is constantly changing and improving so +please [contact us](/contact) if you are unsure if we can support your research software needs or read more on [what we do](./activities). \ No newline at end of file diff --git a/pages/collaboration/funding/costing.md b/pages/collaboration/funding/costing.md new file mode 100644 index 00000000..f78b8714 --- /dev/null +++ b/pages/collaboration/funding/costing.md @@ -0,0 +1,37 @@ +--- +title: Costing +permalink: /collaboration/costing +slug: costing +type: text +--- + +RSE time is typically funded via internal or external grants, not through overheads. Most UKRI funders are aware of the role of RSEs and actively encourage their deployment on grants. + +## RSE costing (grant-funded) + +Outside of the free activities which we organise, RSE time must be paid for from internal or external sources. +In many cases this will require you to budget for RSE time as part of your grant application. +The RSE Team can assist with this an advice you as to what is appropriate for your needs. +Enquiries should be made to . + +We can provide staffing for your grants (charged as 'directly incurred' costs) for anything from 1 day to 50% of a FTE, although **provision of an RSE is subject to availability** and as such **enquiries must be made before grant submission** to allow us to schedule our staff resources. + +If you require a dedicated 100% role for your team or project then you should recruit this directly. +We can help you with this by assisting with recruitment and by supporting your RSE within the Sheffield RSE community. + +## RSE "service" costing + +If you require paid RSE support which cannot be budgeted into a research grant then we provide an different mechanism for buying RSE support. In this case we charge an internal RSE "service" day rate of £384 for internal grants and £605+VAT for external partners and industry (rate expires 31/7/2023, from when the new rate will be £665+VAT). + +The service rate is based on an average cost of an RSE in our team and has a faculty administration cost. + +## Contributing to the RSE team (underwriting a RSE role) + +If you have a considerable requirement for RSE staff you may consider underwriting an RSE staff member with the team. +By doing so you will ensure that a member of staff will exist with the specific skills which you require for your research. +You will also be given the opportunity to join our strategy group to influence how free RSE time should be allocated. +Underwriting a post does not guarantee that the staff member will be available to you 100% of the time. +The staff member will be costed onto grants (benefiting you are your research group) in the normal way. +Our method of cost recovery will allow us to recover up to 75% of the staff costs which will be reimbursed annually. +Cost recovery will be reported on at each RSE strategy group meeting which you will be invited to attend as a contributor to the group. +Examples of current contributors include The Department of Computer Science and IT Services. diff --git a/pages/collaboration/guide/guide.md b/pages/collaboration/guide/guide.md new file mode 100644 index 00000000..3f71ff74 --- /dev/null +++ b/pages/collaboration/guide/guide.md @@ -0,0 +1,239 @@ +--- +title: RSE Collaboration Guide (RSE Working Practice) +permalink: /collaboration/guide/ +slug: index +type: text +--- + +## What is this Handbook for? + +Good software comes less from genius software engineers than from good practices, processes and relationships. The information here sets out what this means for projects involving the University of Sheffield RSE Team. Every project is different, and everyone we work with is different. Different approaches, values and levels of expertise. The purpose of this information is to articulate approaches that we know can be very successful and to inform our collaborators of how to get the best out of working with our team. + +There’s no way we’ve got this right first time! This is a working document and we welcome feedback via any of our team members or to [rse@sheffield.ac.uk](mailto:rse@sheffield.ac.uk) where your message will be received by the RSE Team management. + + +## Before a project starts {#before-a-project-starts} + + +### Project management strategy {#project-management-strategy} + +Once an RSE is allocated to your project the project PI will ultimately be responsible for how the RSE is deployed as a resource. As such it is essential that thought is given to a strategy for project management. Having a project management process will ensure that the RSE has agreed priorities for work, is able to meet agreed deadlines and can provide feedback to the project PI on progress. The project management approach may be to include the RSE in an existing process including postdocs or it could be to adopt a new process unique to the tasks the RSE is to undertake. There are different project management approaches but the RSE can help to define a process if you do not already have one. As a minimum you should think about and then agree on the items in the section [Kick off meetings](#kick-off-meetings). + +The RSE team has a fairly standardised process for working on code which uses GitHub projects and issues and this can be incorporated into your project management approach early on if required (see section [During the Project](#during-the-project)). + + +### Instructions for delivery of necessary materials to initiate project {#instructions-for-delivery-of-necessary-materials-to-initiate-project} + +Before work begins, it is likely that we will need to inspect existing materials. This may include code, example data, database schema etc. + + +### Code {#code} + +The RSE team delivers code according to best practices using a collaborative version control system (preferably GitHub, but equivalent tools such as GitLab or Bitbucket can be used for established projects). At the outset of the project initial code can be provided on a secure shared resource like Google Drive however we would expect to migrate this to version control to make any changes. The RSE team can help you to do this. If you already use version control and have a private repository, you will need to add the allocated RSE as a collaborator. + + +### Data {#data} + +Along with code, or for completely new software projects, it may also be necessary to provide data. Providing access to all data required by the project as soon as possible would ensure any software developed takes into consideration edge cases. Should your data be sensitive, ensure it is appropriately anonymised or that appropriate dummy data has been provided. A[ data management plan](https://www.sheffield.ac.uk/library/rdm/dmp) should be in place and is the responsibility of the project PI. The RSE team can assist you in completing one or advise on certain aspects. + + +### Sensitive materials {#sensitive-materials} + +It may be that the work will require access to sensitive materials which will require an NDA being in place. Please ensure you consider whether this will be required and take steps as soon as possible to initiate the process so as to avoid delaying the beginning of the project at this stage. As employees of the University of Sheffield, RSE team members are often covered by existing NDAs or research agreements, which are typically between the whole organisation and an external one. + + +### Licensing {#licensing} + +The RSE team recognises research software as a first class research output and is committed to obtaining maximum value from it via sharing. Options for licensing software should be considered at the earliest opportunity and the default position is that **code should be made available under a permissive open source licence** as it is developed (i.e. right now!), in keeping with the [University of Sheffield Statement on Open Research](https://www.sheffield.ac.uk/openresearch/university-statement-open-research). + +Exceptions to this include: + + + +* Restrictions on background IP (e.g. the project extends software which cannot be made open source). +* Legal agreements around project funding (e.g. NDAs, ownership of foreground IP is shared under a research agreement) +* Collaborators outside the University of Sheffield will not release copyright. +* The research team has contacted the research services commercialisation team and plans to commercialise the software in a manner that precludes open source licensing. +* The software contains confidential information. + + +### Sustainability plan - software/data maintenance plan {#sustainability-plan-software-data-maintenance-plan} + +RSE effort on a project is for a fixed period of time, usually associated with specific research funding. For software to continue to do its job beyond this scope, ongoing maintenance will be required. Current research funding models do not usually acknowledge this. Bug fixes and updates in dependencies and operating systems, beyond the control of the project, are a key driver of the need for maintenance. As mitigation, prior to starting the project the following should be considered: + + + +* Is the software required to operate after the end of this project? +* If so, who will maintain it? Will they need training within the scope of the project to enable them to do this? +* If so, does it require any infrastructure (e.g. web servers, databases)? +* Consider doing an online [Software Sustainability Review](https://www.software.ac.uk/resources/online-sustainability-evaluation). Not all of the criteria are universal. The project RSE will advise on appropriateness of specific criteria. + +As part of your project design you should consider and plan for sustainability (see After the Project). Many research proposals benefit greatly from defining the plans for sustainability within the case for support. + + +### Good Practice {#good-practice} + +Whilst collaborating with researchers, the RSE team endeavours to follow good practice throughout with the objective of crafting a software project that is reproducible, sustainable and produces accountable results. Ultimately, following good practice in a research software project will result in a more impactful piece of software which outlasts the project itself. + +In practice, this means using tools and techniques such as: + + + +* Version control (almost always via `git`) +* Shared repositories +* Software testing +* Documentation (version controlled) + +"Best practices" are not universally agreed upon in the software engineering community and will change over time. A thorough list of good practices for [free open source software](https://bestpractices.coreinfrastructure.org/en/criteria/0) has been produced, additionally ISO standards for quality assurance exist for [Systems and software engineering](https://committee.iso.org/sites/jtc1sc7/home/projects/flagship-standards/iso-25000-square-series.html). These can be quite daunting and a pragmatic approach must be adapted to balance compliance with project value. + + +### Kick off meetings {#kick-off-meetings} + +Once a project is funded (congratulations!) and an RSE is allocated, at or before the beginning of the work, a kick-off meeting should be held with the PI, researchers and RSE(s) involved to make decisions on the priorities, scope and working methods as described here. + +Notes should be taken in a document that everyone has access to, which can be referred to during the project. Use a team Google Drive or GitHub/GitLab repository for this. + +Checklist for kick-off meetings: + + + +1. Meeting cadence +2. Personnel, their roles and fractional allocation/working times +3. Primary contact for setting development priorities +4. Agree access and technologies to work with code and data +5. Issue tracking and communication +6. Where project information will be kept (e.g. GitHub, Google Drive) +7. Project scope, duration, priorities, milestones +8. Deliverables +9. Maintenance +10. Handover + + +## During the project {#during-the-project} + + +### Use of Version control {#use-of-version-control} + +All software by RSEs will be managed as a repository using version control software, most likely `git`. This represents fundamental software engineering best practice and ensures the evolution of the project is captured and allows for navigation through the history of project development which will always be available, even after handover. Any non software activities should utilise tools and storage agreed as part of the kick off meeting. + +All our projects will also be shared online via online repository hosting sites (e.g GitHub). This method provides a number of features that aid development, access to materials, collaboration and project management and communication: + + + +* Code is version controlled and saved on redundant storage +* Code is easily accessible by collaborators +* Facilitates collaboration through formal management of contributions. +* Continuous Integration testing improves robustness of contributions +* Provides user friendly task management functionality. +* Communication, planning and task management remains associated with the project. + +Repositories hosted online can be made private where necessary. In rare circumstances where the work involves materials that cannot be shared online at all, we will discuss with you and develop more secure custom arrangements. + + +### Communication {#communication} + +It is important to manage communication between stakeholders and RSEs in a software project and as a team we have developed a set of recommendations over the course of many projects for getting the most out of collaborating together. + +These concepts are intended as guidance and each individual project may require its own tweaks to this framework. + +PIs, Researchers and RSEs should agree on a communication strategy for the project. + +As a starting point, we recommend: + + + +* Regular (but not too regular) focused meetings to prioritise work to be carried out. +* Agreeing on an instant messaging platform for quick discussions, e.g. Google Chat, Slack or Skype - this is particularly useful in our current remote/hybrid working model. +* Use of issues and pull requests, described in more detail below. + +We encourage the use of instant messaging (for quick discussions) or slack for throwaway conversation. As a general rule we suggest that you should not expect or require anyone to read messages on an instant messaging service (e.g slack, google chat, etc) unless they are specifically tagged (either individually or via a channel). We also need decisions to always be recorded. Notes or decision making around particular development tasks should always be recorded in an agreed location (e.g. GitHub Issues, or a Google Drive folder) rather than via email history. + + +### Issues and Project Boards {#issues-and-project-boards} + +GitHub and GitLab, alongside acting as an online hosting platform for code, also provide a useful set of project management tools. Other cloud based tools such as Jira also provide project management but without close coupling to Issues. + +Each task on the project should be described in an 'issue'. Each issue can be assigned a team member, associated with a project milestone and also acts as a discussion thread to communicate over the specifics. + +Issues don't only have to be used for code, but can be used to track all tasks in a project. + +Code-related issues can also be associated with pull requests (see below) so that when code is implemented to address an issue, the issue can be automatically closed. + +Project boards (GitHub, known as issue boards on GitLab) are a useful and efficient way to track the progress of tasks within a project and to prioritise work. + +We encourage PIs to engage with the project board during a project, particularly during regular meetings as a way of seeing the progress of the project in one place as well as prioritising tasks. + +Issues can be added to the project board as well as task cards (which do not relate to an issue). + + +### Contributing to Coding {#contributing-to-coding} + +A set of [contribution guidelines](https://mozillascience.github.io/working-open-workshop/contributing/) should be agreed and held either in the repository or in the project Google Drive. + +When code is contributed to a project, it should be committed to the project repository via a git workflow that is agreed by everyone. E.g. It could be committed to its own branch (or fork) and a pull request made against another branch (often `main`, `master` or `dev`). + +If you are unfamiliar with the use of version control and collaborative platforms such as GitHub and GitLab and will be contributing code to the project, the RSE(s) collaborating with you will be happy to provide guidance. + +Pull requests are a useful tool for discussion of code changes and draft pull requests are often the most efficient place for team members to decide on how best to address an issue. + +Team members should agree on a particular process for merging pull requests. Ideally pull requests should use reviewing. However, due to the flexible nature of research software in most cases, it is advisable to merge code even if it is not perfect, as long as it doesn't break an existing feature. This keeps the project from stagnating and improvements can be made later on. + +It is advisable to implement testing to ensure that existing features are not broken in development. This can be automated via a continuous integration pipeline which will ensure that code being added to the principal branch functions correctly. + + +### Recognising the contribution of your RSE + +An RSE is a collaborator within the research process and should be recognised as such. If an RSE has made a contribution to work underpinning a research paper you should consider naming them as a co-author and highlighting what their contribution has been according to the journal's guidance. If the contribution of the RSE is less significant then you should provide an acknowledgement in the acknowledgements section of the paper if it has one. + +Outside of research outputs, if an RSE has made an exceptional contribution to your work then please feed this back to the RSE management team ([rse@sheffield.ac.uk](mailto:rse@sheffield.ac.uk)). You can also consider making a recommendation for a recognition award via [The Deal](https://staff.sheffield.ac.uk/reward-recognition) which is a nice way to recognise any staff contribution. + + +## After the project (sustainability) {#after-the-project-sustainability} + + +### Handover {#handover} + +Outputs are specific to projects and vary greatly by programming language, but have some core themes. The RSE team aspires to produce software that can be further developed with minimal or no input from the original engineer. To facilitate this we prioritise including the following in our repositories: + + + +* Developer and user documentation: How to build / run the software, how it is organised, what conventions have been used, what developer tools are needed e.g. to run tests. +* Execution environment and dependencies: What operating systems will the software run on, is what other software / libraries / modules are needed, what versions, how the execution environment is described. E.g. through containerisation. +* Appropriate automated tests: Uunit, regression, integration. + +We aim to empower the project team to be able to maintain and modify the software by sharing skills and explaining these throughout the project, or at a final handover meeting. + + +### FAIR Open Access {#fair-open-access} + +We strongly prefer outputs that are FAIR open access. [FAIR](https://www.go-fair.org/fair-principles/) means that a research output is **Findable**, **Accessible**, **Interoperable** and **Reusable**. This was initially conceived for data but is in the process of being adapted to research software ([FAIR4RS](https://www.rd-alliance.org/groups/fair-research-software-fair4rs-wg)). + +Making code available via a collaborative version control site such as GitHub is a fantastic step towards realising this. However, additionally pushing software releases to ORDA (preferred for University of Sheffield researchers) or Zenodo confers some important additional benefits: + + + +* Guaranteed long-term archiving +* DOIs for direct citation of software releases (*software releases in this context are snapshots of the source code, and possibly also "builds" or executable files*). A means of [automatically pushing software releases to ORDA](https://github.com/RSE-Sheffield/release_to_ORDA) is being developed. +* Tagging releases with metadata to aid findability + +FAIR outputs can lead to more citations and more transparent, trustworthy, research (see [SSI benefits reference list](https://github.com/softwaresaved/useful-references/blob/master/benefits.bib)). + + +### Ongoing software maintenance {#ongoing-software-maintenance} + +Software maintenance is poorly supported by research funding which is generally for a fixed term. The lifecycle of software and infrastructure/services may very well be expected to run beyond the end of the research project. With respect to software maintenance the use of software best practice plays a vital role in ensuring that your software is maintainable. As part of the development activity on your project you should expect your RSE to leave the code in a state where a future developer is able to contribute in future funding rounds or when maintenance is required. Generally the team tries to work under the assumption that at any period they may need to drop a coding project and it should be possible for another developer to pick up where they left off. This is important for reducing the so-called bus factor of a project and we will work with you to ensure that aspects such as documentation, tests, contribution guidelines and up to date issues are in place. If your code is open source (which we encourage) then ensuring the code has contribution guidelines gives your software the possibility of broader maintenance and feature contributions from the open source community. + +As a team we do not take on specific maintenance contracts but if your code has been developed with us or following our guidance we may be able to undertake short pieces of work on code (subject to staff availability). + + +### Infrastructure and Service Maintenance {#infrastructure-and-service-maintenance} + +Similarly to software development the deployment of infrastructure and services (usually web services or cloud infrastructure) are difficult to support beyond the end of a project's funding cycle. We encourage you to consider these factors when proposing your research proposal and plan for how maintenance will be undertaken. All software and services have a lifecycle and it is not feasible to expect them to live persistently forever without an investment in their maintenance. Generally if the development of services or infrastructure is required as an RSE task on a project then we will put in place processes and documentation to ensure you or your researchers are able to perform basic maintenance after our time on a project has finished. It will then be your responsibility to maintain it. Performing updates to dependencies on web services is not something which the team has capacity to undertake. The exception to this is that where we have deployed particular pieces of infrastructure we will engage with IT services to encourage them to run hosted services where there is common demand. This greatly simplifies the maintenance of particular workflows. + + +### Additional Resources {#additional-resources} + + +* [UCL RSE Ways of Working](https://www.ucl.ac.uk/advanced-research-computing/services/research-software-development/ways-working) +* Turing Way [contributing.md](https://github.com/alan-turing-institute/the-turing-way/blob/main/CONTRIBUTING.md) +* [The RSE Toolkit](https://rsetoolkit.github.io/) (Work in progress) diff --git a/pages/collaboration/index.md b/pages/collaboration/index.md new file mode 100644 index 00000000..eaab33d8 --- /dev/null +++ b/pages/collaboration/index.md @@ -0,0 +1,46 @@ +--- +title: Why work with us? +permalink: /collaboration/ +slug: index +type: text +--- + +The Research Software Engineering (RSE) team at the University of Sheffield strives to: +- Enhance the University’s capacity for producing high quality, efficient and sustainable +research software and thus increasing research impact and decreasing time to publication. +- Provide a range of research software engineering services via a pool of staff to support +research grants, thereby increasing the capability of research units and helping to meet the +requirements and expectations of funders. +- Champion the role of the RSE locally, nationally and internationally and to support the +career development of RSE professionals. +- Act as the hub of a university community that supports good practice in research software. + +The RSE team can collaborate with you to help improve your research software. +We have a pool of [expert staff](/contact/team) to ensure that you can deliver excellent research software engineering on your research projects (see [example projects](/collaboration/projects/) and [testimonials](/collaboration/testimonials/)). +Supporting the entire University, we have collaborators in every faculty and have supported researchers in a range of subject areas including engineering, mathematics, computer science, biology, linguistics, physics, chemistry and geography. + +Please contact us () to arrange a [scoping meeting](/collaboration/provision). + +### Why work with the RSE Team + +The RSE Team allows you to get dedicated help for professional software engineers. +Recruitment of such skills is very difficult on research projects, +especially when you only require short term expertise. +UKRI (and most other UK and EU funding agencies) understand what an import part RSEs have on research and +would like to see that they are being offered sustainable careers with academia. +The RSE Team provides this through underwritten roles and by allowing RSEs to work to a unique job description. +If you want to deliver software engineering as part of your grant application then +there is a good chance that you will be required to demonstrate how this will be done sustainability. +The RSE Team is an excellent way to provide this evidence to your funders. + +## Collaborative research software development + +The aim of the RSE team is to provide staff to support software engineering for research. +This is always done as a collaborative exercise. +In most cases where an RSE is required, the novel research is facilitated by software and the RSE rather than the development of software being novel in its own right. + +If you wish to undertake a collaborative software engineering project where the focus is on *novel software engineering research* then +this can be provided by our director or academics associated with the RSE team. +As part of this you may also cost RSE time. +The RSE director for example, holds an academic position in the Department of Computer Science and +delivers collaborative research around novel high-performance computing. diff --git a/pages/service/projects/projects.md b/pages/collaboration/projects/projects.md similarity index 65% rename from pages/service/projects/projects.md rename to pages/collaboration/projects/projects.md index 696baed2..028c638f 100644 --- a/pages/service/projects/projects.md +++ b/pages/collaboration/projects/projects.md @@ -1,6 +1,6 @@ --- title: Projects -permalink: /service/projects/ +permalink: /collaboration/projects/ slug: projects type: text --- @@ -26,10 +26,13 @@ The Research Software Engineering team at Sheffield has worked on projects invol {% assign proj_tags = proj.tech_methods | split: ", " %} {% assign all_tags = all_tags | concat: proj_tags %} {% endfor %} -{{ all_tags | sort_natural | uniq | join: " · " }} +{% assign all_tags = all_tags | sort_natural | uniq %} +{% for tag in all_tags %}{{ tag | replace: " ", " "}}{% if tag != all_tags.last %} · {% endif %}{% endfor %} Some projects we have worked on (not a comprehensive list): +Filter: All · Active · Completed + {% assign levels = site.data.projects | where: 'show',1 | group_by: 'level' | sort: 'name' %} {% assign project_descriptions = site.project_descriptions %} {% assign today_date = 'now' | date: '%s' %} @@ -44,7 +47,8 @@ Some projects we have worked on (not a comprehensive list): {% else %} {% assign current = false %} {% endif %} -
+ {% assign proj_tags = project.tech_methods | split: ", " %} +
{{project.long_title}} {% if current %} (Active project) @@ -71,4 +75,13 @@ Some projects we have worked on (not a comprehensive list):
{% endfor %}
- + diff --git a/pages/collaboration/provision/provision.md b/pages/collaboration/provision/provision.md new file mode 100644 index 00000000..f668ff10 --- /dev/null +++ b/pages/collaboration/provision/provision.md @@ -0,0 +1,32 @@ +--- +title: How We Work +permalink: /collaboration/provision/ +slug: index +type: text +--- + +Initial enquiries for RSE collaborations can be made by contacting . + +We will get back to you and arrange a scoping meeting where a senior member of the RSE team will provide guidance on the RSE service and discuss the project. We will gather information at this meeting including: + +- Planned start and end dates +- What skills and programming languages are needed +- How the project is being funded +- How much RSE time might be needed + +If your project is within the RSE Team remit (have a look at [What We Do](/collaboration/activities)), we will advise you on how to cost RSE time on the project. We will also assist with relevant parts of grant writing (such as justification of resources and software delivery plans). + +## RSE line management + +Once an RSE has been allocated they will engage and collaborate with you and your team directly. Line management of the RSE will remain within the RSE Team. + +A senior RSE will have already assisted you in scoping the project during the grant-writing stage. +If you need more dedicated involvement of a senior RSE then consider making one our our senior RSEs a co-investigator in your grant. +They will then be able to provide additional intellectual guidance for your project and any RSE staff members during the delivery stage. + +If at any stage you need to change direction within your grant or are unhappy with the staff member then +this should be raised with the senior RSE member who assisted you in grant preparation or in designing the work schedule. + +## Provision of RSE team members + +Once your grant is funded we will review available staff and projects and allocate staffing to meet your needs, as best we can. Our pool of around 14 RSEs work on a total of around 40 projects each year, and managing this is a complex task. Funding applications are not always sucessful, which makes predicting staff availability difficult. We can normally provide RSE effort with the right skills exactly as planning in our scoping meeting, but sometimes we need to ask for compromise on start and end dates, or proportions of staff time allocated to a project. Our collaborators typically find this kind of request for flexibility less onerous than direct recruitment. If priorties shift during a project, we can potentially re-allocate staff with different skills. diff --git a/pages/service/testimonials/testimonials.md b/pages/collaboration/testimonials/testimonials.md similarity index 98% rename from pages/service/testimonials/testimonials.md rename to pages/collaboration/testimonials/testimonials.md index 6a16deb6..eb7345b3 100644 --- a/pages/service/testimonials/testimonials.md +++ b/pages/collaboration/testimonials/testimonials.md @@ -1,11 +1,11 @@ --- title: Testimonials -permalink: /service/testimonials/ +permalink: /collaboration/testimonials/ slug: index type: text --- -Once you've seen [What we do](/service/activities/), you might wonder how well we do it. Here is a selection of testimonials from academics we have collaborated with +Once you've seen [What we do](/collaboration/activities/), you might wonder how well we do it. Here is a selection of testimonials from academics we have collaborated with GPU Computing ------------- diff --git a/pages/collaboration/tier2/tier2.md b/pages/collaboration/tier2/tier2.md new file mode 100644 index 00000000..6c595559 --- /dev/null +++ b/pages/collaboration/tier2/tier2.md @@ -0,0 +1,70 @@ +--- +title: Tier 2 Embedded Support +permalink: /collaboration/tier2/ +slug: index +type: text +--- + +# Open Call: Funding for Embedded support for High Performance Computing and Machine Learning + + +## Context + +High performance computing (HPC) is the processing of data and performing of computing calculations at high speeds. When surveyed (as part of the Sheffield Research Software survey 2020), roughly a quarter of researchers from all faculties at Sheffield expressed an interest in using HPC in the future. It may not be as difficult as you would think to do so! The barrier to entry for using specialist HPC facilities such as Graphics Processing Units (GPUs) has been significantly lowered by the emergence of software to facilitate Machine Learning (ML) and AI. The purpose of this open call is to provide funding to support skilled Research Software Engineers (RSEs) to assist researchers in migrating their research workflows to suitable HPC systems. RSE support will be provided from the [Sheffield RSE group](https://rse.shef.ac.uk/). The RSE group is a team of 12 who provide collaborative embedded support for research across the whole of the university. + +Aside from the universities own HPC systems. The University of Sheffield is a partner organisation in two EPSRC Tier 2 HPC facilities; [JADE II](https://docs.hpc.shef.ac.uk/en/latest/other-uk-hpc-resources/jade2.html) and [Bede](https://docs.hpc.shef.ac.uk/en/latest/other-uk-hpc-resources/bede.html). As such we have a percentage share of the system available for University of Sheffield research. Both systems are large GPU compute clusters which have been designed to perform large scale computations in a broad range of domains. JADE II is specifically designed to support Machine Learning and Bede to support more general GPU computation spanning multiple compute nodes. All members of the university can access these facilities free of charge even if their work falls outside of EPSRCs domain. + +This call will specifically aim to enable researchers to use the Tier 2 HPC systems by providing funding for embedded support within research teams or with individual researchers. Embedded support will be provided by the Research Software Engineering group, a team of ~12 software engineering experts who work collaboratively across the entire university supporting [~40 active projects](https://rse.shef.ac.uk/collaboration/projects/) worth over £12M to the university. The call is keen to support researchers from a diverse research background, particularly those who are not traditional HPC users. + +There are a number themes which are support in this call; + + +* **Support for scaling up of Machine Learning/AI workflows**: Assisting researchers to migrate workflows for ML/AI running on their laptops/desktops to running on the Tier 2 facilities. This level of collaborative support is ideal for those unfamiliar with HPC requiring a low barrier method of achieving higher computational performance. +* **Research Software Engineering Consultancy**: Collaborative support to work with you on your research software to provide a mechanism to embed parallel libraries/APIs or to directly accelerate your code's performance and allow it to utilise the HPC systems effectively. This may include first steps into parallelisation through to application profiling and optimisation or configuration of software and libraries within a HPC environment, This level of collaborative support is ideal for research developers who are looking to improve the performance of their research code and target GPUs. +* **Machine Learning/AI Consultancy**: AI Problems can vary and include image, time series data, text, speech and any other structured data. We can help you to decide on what methods are the most feasible for applying to your research. This level of collaborative support is ideal for novice users of ML/AI but who have interesting datasets and a desire to learn more about ML/AI methods by working with us to create a proof of concept. +* **Lowering the barrier of entry for HPC Usage**: Support to create mechanisms which lower the barriers to entry for you or your research team in using the HPC systems. This may include things like configuring interactive notebooks to allow you to use the facilities with a minimal change to your existing research practice. + +Each of these activities is underpinned by the RSE groups ethos in good quality software engineering practice and reproducible research. + + +## Example Case Study + +**Project Title**: Migrating Lung Segmentation + +**Application Theme**: Support for scaling up of Machine Learning/AI workflows + +**Project Details**: We worked with Bilal Tahir’s group to migrate a lung segmentation workflow to JADE. The work required the use of Niftynet a Tensor Flow based open source platform for research in medical image analysis and image-guided therapy. Niftynet uses convolutional neural networks (CNNs) and was therefore good fit to GPU acceleration on JADE. The Niftynet software was not able to be installed on JADE using a conventional approach as the installation process requires an outgoing internet connection which is unavailable with JADE for security reasons. The RSE on this project helped create a singularity container (a form of software execution environment) which packages Niftynet and all required software for use on the JADE cluster. The end result was that sears within the team could run large scale medical image analysis workflows without having complex software installations to navigate. + + +## Eligibility and What is on Offer + +This call is open to all research staff but with some conditions imposed by the Tier 2 facilities. Postdocs must have at least one year left on their contract (else should apply via their PI). Doctoral research students must have support from their supervisor. + +This call is specifically to facilitate uptake in the use of the Tier 2 resources. Collaborative support for use of the University HPC resources (e.g. Bessemer, ShARC) is within remit providing there is an ambition to later migrate workflows to the Tier 2 systems. + +This call will fund upto £5,000 of embedded RSE time which is roughly 12 days of RSE support. There is no cash alternative available. Funding must be spent on embedded RSE time. As part of the review of your application a suitable member of the RSE team will be allocated to your project so you do not have to identify a particular team member. + +Applications should not be submitted for short pieces of consultancy work which can be completed in less than a day. Instead such requests should be submitted to the [Code Clinic](https://rse.shef.ac.uk/support/code-clinic/), a free consultancy service run by the RSE and Research IT teams. Alternatively for support requests you can raise a [ticket via ITS](https://shef.topdesk.net/solutions/forms/eeb223ec-fd1a-4436-b3fb-3c8414f9903b?token=5b2cdc96-fa45-48b7-b756-58c68884ebd2). Requests for embedded support beyond the 12 day limit will also not be considered. You should however discuss with the RSE team management about how to support your research [through grant funding](https://rse.shef.ac.uk/collaboration/) if a larger investment of specialist staff time is required. + +If you are unsure about eligibility of scope then please contact [rse@sheffield.ac.uk](mailto:rse@sheffield.ac.uk) or book a code clinic session to discuss your project ideas. + + +## How Your Application will be Assessed + +Your application will be assessed on the following criteria; + + +* **Suitability of your application to make effective use of one of the Tier 2 systems (50%)**. This will include the potential for your research work to utilise the GPU equipment effectively. You do not have to identify which system you would like to target only which theme you are applying for. Criteria will be assessed by considering the software or data which you are using as part of your research. +* **Impact of the project on research work (25%)**. This is not a measure of the research quality but an assessment of the impact in which the embedded support will advance the research work. You should clarify how the activities of this project will advance your research. +* **Availability of resources and future ambitions (25%)**. You must identify researchers or members of your research team to work with the RSE over a period of time. It is vital that this activity is undertaken as a collaboration in order to get the maximum value from the embedded staff member. This criteria will also consider the current (and proposed) availability of software and data as well as availability of RSE team members to undertake the work. + + +## Application Process + +You should apply via the provided expression of interest google form below. This is an **open call** and applications will be reviewed on a first-come-first-served basis. + +Application form + +On receiving a completed application form we will contact you to arrange a short (less than 30 minutes) online consultation to gather any additional technical information required to understand your project. The application form is purposefully short to ensure that we can discuss your requirements rather than expect you to provide all of these in the written application. + +After review the projects will be ranked and estimates given as to when RSE time can be allocated. At the conclusion of your project a brief post-project report will be required. diff --git a/pages/community/code_of_conduct.md b/pages/community/code_of_conduct.md new file mode 100644 index 00000000..6c2383b1 --- /dev/null +++ b/pages/community/code_of_conduct.md @@ -0,0 +1,120 @@ +--- +title: Code of Conduct +permalink: /community/code_of_conduct +type: text +--- + +The RSE Team runs and participates in a range of online and in-person activities, including collaborative projects, [LunchBytes](lunch-bytes), Slack conversations and in-person seminars. Participants are mostly University of Sheffield staff / students, but sometimes include our external friends and collaborators. + +University of Sheffield staff and students conduct is governed by the terms of their employment / study which can be found on the [University website](https://www.sheffield.ac.uk) alongside reporting procedures. We have a code of conduct for those not staff or students at The University of Sheffield. + +## Code of Conduct for External Participants + +The RSE Team at The University of Sheffield have a Code of Conduct which is set out below. It defines the standards and +behaviour you can expect from all participants of our community and in turn that we expect from you when you participate +and engage with others in the community. They are based on the [Contributor Covenant][homepage] (see +[Attribution](#Attribution) for further details). + +### Our Pledge + +We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for +everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity +and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, caste, +color, religion, or sexual identity and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community. + +### Our Standards + +Examples of behavior that contributes to a positive environment for our community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience +* Focusing on what is best not just for us as individuals, but for the overall community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or advances of any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email address, without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a professional setting + +### Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take +appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, +issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +### Scope + +This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing +the community in public spaces. Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed representative at an online or offline event. + +### Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible +for enforcement at [p.richmond@sheffield.ac.uk ](mailto:p.richmond@sheffield.ac.uk) or [r.d.turner@sheffield.ac.uk](mailto:r.d.turner@sheffield.ac.uk). All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the reporter of any incident. + +### Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem +in violation of this Code of Conduct: + +#### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the +community. + +**Consequence**: A private, written warning from community leaders, providing clarity around the nature of the violation +and an explanation of why the behaviour was inappropriate. A public apology may be requested. + +#### 2. Warning + +**Community Impact**: A violation through a single incident or series of actions. + +**Consequence**: A warning with consequences for continued behavior. No interaction with the people involved, including +unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding +interactions in community spaces as well as external channels like social media. Violating these terms may lead to a +temporary or permanent ban. + +#### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including sustained inappropriate behaviour. + +**Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified +period of time. No public or private interaction with the people involved, including unsolicited interaction with those +enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban. + +#### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate +behaviour, harassment of an individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within the community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.1, available at +[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. + +Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder][Mozilla CoC]. + +For answers to common questions about this code of conduct, see the FAQ at +[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at +[https://www.contributor-covenant.org/translations][translations]. + +[homepage]: https://www.contributor-covenant.org +[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html +[Mozilla CoC]: https://github.com/mozilla/diversity +[FAQ]: https://www.contributor-covenant.org/faq +[translations]: https://www.contributor-covenant.org/translations diff --git a/pages/community/lunch-bytes.md b/pages/community/lunch-bytes.md index 232de5ba..42feabf4 100644 --- a/pages/community/lunch-bytes.md +++ b/pages/community/lunch-bytes.md @@ -1,5 +1,5 @@ --- -title: Lunch Bytes talks +title: LunchBytes talks permalink: /community/lunch-bytes/ slug: lunch-bytes type: text @@ -16,29 +16,37 @@ use/manage research data and use/manage research infrastructure. We hope through these talks we will come together as a community to discuss best practices and useful methods/tools. -For those familiar with the [RSE seminar series](/community/seminars/), LunchBytes has replaced it but is different in flavour: -each session features several related short talks on a theme (each being ~10 mins) rather than one longer talk. +Each LunchBytes session typically features several related short talks on a theme (each being ~10 mins) rather than one longer talk - followed by a discussion. ## Notifications about future events -To hear about future events and be notified of Blackboard Collaborate joining instructions -sign up to the RSE team's mailing list ([a Google Group](/community) to +To hear about future events and be notified of joining instructions +sign up to the ([RSE team's mailing list](/community) to receive the periodic [University of Sheffield RSE community newsletter](/newsletters/). ## Getting involved -You’ll notice that all presenters are from IT Services or the RSE team; -in future we hope that people from the research community feel able to: +LunchBytes is a series by and for the Sheffield Research Software community and as such we're always open to offers from members of the community to: * Suggest themes for talks; * Request specific LunchBytes talks from others; +* Curate talks on topics of their choice; * Offer LunchBytes talks on topics they find interesting. +### Suggesting LunchBytes topics Please add requests/offers of LunchBytes talks to [this JamBoard](https://jamboard.google.com/d/1-51cRf0pwZl8O10CnLeJGAqKcnbww-QGaYjszFK-H38/) (using Sticky Notes): - - For requests: a brief note for why you think this would be useful would be helpful - - For offers: please note your email address in addition to your talk idea + - For __requests__: a brief note for why you think this would be useful would be helpful + - For __offers__: please note your email address in addition to your talk idea - If you want to up-vote a request/offer use the Pen tool to annotate a Sticky Note with **+1**. +## Recordings of previous LunchBytes +Each LunchBytes session is recorded and uploaded to the [University of Sheffield Digital Media channel](https://digitalmedia.sheffield.ac.uk/channel/LunchBytes%2Btalks/181886171) +* [Writing (safer) Python code](https://digitalmedia.sheffield.ac.uk/media/LunchBytes+talks+1A+writing+safer+%28Python%29+code/1_muuuuhoj/181886171) +* [Jupyter Notebooks - pros and cons](https://digitalmedia.sheffield.ac.uk/media/lunchBytes+2+-+Jupyter+Notebooks+-+pros+and+cons/1_3qv4p0mw/181886171) +* [Beyond Static Data Visualisation](https://digitalmedia.sheffield.ac.uk/media/Lunchbytes+4A+Beyond+Static+Data+Viz/1_847riyp6/181886171) +* [Making GPU Programming More Portable](https://digitalmedia.sheffield.ac.uk/media/Lunch+bytes+5+Making+GPU+Programming+More+Portable/1_lldycy2n/181886171) +* [High Performance Computing (HPC) at Sheffield and Beyond](https://digitalmedia.sheffield.ac.uk/media/LunchBytesA+High+Performance+Computing+%28HPC%29+at+Sheffield+and+Beyond/1_yqkgcmh2) + diff --git a/pages/community/slack.md b/pages/community/slack.md new file mode 100644 index 00000000..c94d6128 --- /dev/null +++ b/pages/community/slack.md @@ -0,0 +1,15 @@ +--- +title: Slack +permalink: /community/slack +type: text +--- + +We have a **[Slack workspace](https://join.slack.com/t/RSE-UoS/signup)** for people involved with research code / software at The University of Sheffield, with a few users not currently staff or students. + +The Slack channel is not an approved IT resource for private communications. University of Sheffield staff and students should take rules on protecting personal and research data into account when posting. It's best to consider all posts as public like other types of social media (e.g. Twitter or Facebook). Interactions in the Slack workspace are covered by the [Code of Conduct](code_of_conduct). + +If you are a University of Sheffield researcher, and have an email address ending in `@sheffield.ac.uk`, you can [join the workspace via this link](https://join.slack.com/t/RSE-UoS/signup). Otherwise, please email [rse@sheffield.ac.uk](mailto:rse@sheffield.ac.uk) and ask to join. + +Please introduce yourself in the **#general** channel after joining! + +The [RSE Society Slack workspace](https://society-rse.org/join-us/) is a better place to connect with the national and international RSE community. diff --git a/pages/newsletters.md b/pages/newsletters.md index 75447a2d..77513079 100644 --- a/pages/newsletters.md +++ b/pages/newsletters.md @@ -4,4 +4,17 @@ layout: page permalink: /newsletters/ --- +The University of Sheffield Research Software Engineering team curates a monthly newsletter of +information, activities and events related to research software/computing. +It typically features information and links to: +news, interesting blog posts, future events, recent events, job/volunteer opportunities and tutorials. + +Let us know if you'd like something to be included in the newsletter by: + +* completing [this short form](https://forms.gle/YyQiNjg79tXaLZHq8) (University of Sheffield staff and students) *or* +* by emailing `rse@sheffield.ac.uk` (for people outside the University) + +We can't promise that we'll publish everything that's proposed but +we are keen to feature submissions from the research community at the University of Sheffield. + {% include newsletters_list.html %} diff --git a/pages/service/index.md b/pages/service/index.md deleted file mode 100644 index e266ad66..00000000 --- a/pages/service/index.md +++ /dev/null @@ -1,102 +0,0 @@ ---- -title: RSE Service -permalink: /service/ -slug: index -type: text ---- - -The RSE team aims to collaborate with you to help improve your research software. -We can provide dedicated staff to ensure that you can deliver excellent research software engineering on your research projects -(see [example projects](/service/projects/) and [testimonials](/service/testimonials/)). -Supporting the entire University, -we have collaborators in every faculty -and have supported researchers in a range of subject areas including -engineering, mathematics, computer science, biology, linguistics, physics, chemistry and geography. - -The RSE team provides a mixture of - -* Paid service via grant funding (as percentages of an RSE FTE) -* Paid service for departments and core accounts (as percentages of an RSE FTE) -* Limited free at point of use support (via [community](../community) activities, [training](../training) and the [Code Clinic](../support/code-clinic) service we co-run with IT Services Research and Innovation IT). - -Areas of expertise within the team include: - -* code optimisation and performance -* reproducibility and embedding good software engineering practice with your project or team -* GPU computing and Deep Learning -* statistical analysis and data visualisation -* High Performance Computing for local/national/international/cloud systems -* general software development -* development of impact case studies -* consultancy -* training -* education delivery and support - -Our list of specialist expertise is constantly changing and improving so -please [contact us](/contact) if you are unsure if we can support your research software needs or read more on [what we do](./activities). - -### Why use the RSE service - -The RSE service allows you to get dedicated help for professional software engineers. -Recruitment of such skills is very difficult on research projects, -especially when you only require short term expertise. -UKRI (and most other UK and EU funding agencies) understand what an import part RSEs have on research and -would like to see that they are being offered sustainable careers with academia. -The RSE team provides this through underwritten roles and by allowing RSEs to work to a unique job description. -If you want to deliver software engineering as part of your grant application then -there is a good chance that you will be required to demonstrate how this will be done sustainability. -The RSE team is an excellent way to provide this evidence to your funders. - -## How to use the paid RSE service - -The RSE service is typically via a grant costed service (see below). -For more information on how our service is provided please see the [provision](provision) of RSE staff page. - -### Normal RSE service usage (grant-costed service) - -Outside of the free activities which we organise, -the RSE service is a paid service. -In many cases this will require you to budget for the RSE service as part of your grant application. -The RSE team can assist with this an advice you as to what is appropriate for your needs. -Enquiries should be made to `rse@sheffield.ac.uk`. - -We can provide staffing for your grants (charged as 'directly incurred' costs) for anything from 1 day to 50% of a FTE, -although provision of an RSE is subject to availability and as such -enquiries should be made before grant submission to allow us to schedule our staff resources. - -If you require a dedicated 100% role for your team or project then you should recruit this directly. -We can help you with this by assisting with recruitment and by supporting your RSE within the Sheffield RSE community. - -### RSE service charge - -If you require paid RSE support which cannot be budgeted into a research grant then -we provide an different mechanism for buying RSE support. -In this case we charge -an internal RSE service day rate of £324 (2020) / £384 (2021) for internal grants and -£585+VAT (2020/2021) for external partners and industry. - -The service rate is based on an average cost of an RSE in our team -and has a 10% faculty administration cost. - -### Collaborative research software development - -The aim of the RSE team is to provide staff to support software engineering for research. -This is aways done as a collaborative exercise. -In most cases where an RSE is required, the novel research is facilitated by software and the RSE rather than the development of software being novel in its own right. - -If you wish to undertake a collaborative software engineering project where the focus is on *novel software engineering research* then -this can be provided by our director or academics associated with the RSE team. -As part of this you may also cost RSE time. -The RSE director for example, holds an academic position in the Department of Computer Science and -delivers collaborative research around novel high-performance computing. - -## Contributing to the RSE team (underwriting a RSE role) - -If you have a considerable requirement for RSE staff you may consider underwriting an RSE staff member with the team. -By doing so you will ensure that a member of staff will exist with the specific skills which you require for your research. -You will also be given the opportunity to join our strategy group to influence how free RSE time should be allocated. -Underwriting a post does not guarantee that the staff member will be available to you 100% of the time. -The staff member will be costed onto grants (benefiting you are your research group) in the normal way. -Our method of cost recovery will allow us to recover up to 75% of the staff costs which will be reimbursed annually. -Cost recovery will be reported on at each RSE strategy group meeting which you will be invited to attend as a contributor to the group. -Examples of current contributors include The Department of Computer Science and IT Services. diff --git a/pages/service/provision/provision.md b/pages/service/provision/provision.md deleted file mode 100644 index dd657ac0..00000000 --- a/pages/service/provision/provision.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -title: RSE Service Provision -permalink: /service/provision/ -slug: index -type: text ---- - -Initial enquiries for RSE service should be made by first [contacting us](/contact/). -If you attend one of the [Code Clinics](/support/code-clinic/) sessions (that we co-run with IT Services' Research and Innovation IT team) -you may also be referred through to the paid RSE service for dedicated help if this is something which is required. - -During your initial consultation a senior member of the RSE team will provide guidance on the RSE service and discuss your needs. -If your project is within scope of what we can help with then we will work with you to agree a delivery plan. -As part of this we can assist with relevant parts of grant writing -(such as justification of resources and software delivery plans). -Please see the flow chart below for our service provision model. - -## RSE line management - -Once an RSE has been allocated they will engage and collaborate with you and your team directly. Line management of the RSE will remain within the RSE team. - -A senior RSE will have already assisted you in the specification of the work schedule during the grant-writing stage. -If you need more dedicated involvement of a senior RSE then -consider making one our our senior RSEs a collaborator in your grant. -They will then be able to provide additional intellectual guidance for your project and any RSE staff members during the delivery stage. - -If at any stage you need to change direction within your grant or are unhappy with the staff member then -this should be raised with the senior RSE member who assisted you in grant preparation or in designing the work schedule. - -## Provision of RSE team members - -Once your grant is funded we will agree appropriate staffing to meet your needs and review this as necessary. -Most UKRI funders are aware of the role of RSEs and actively encourage their deployment on grants. -Some funders (e.g. Leverhulme) require a C.V. to be submitted. -We can arrange this for you during grant submission. - -![RSE Service Model Provision](/assets/images/service_model.png){: .img-fluid} - - - diff --git a/pages/support/code-clinic.md b/pages/support/code-clinic.md index edc82680..aa3aeeea 100644 --- a/pages/support/code-clinic.md +++ b/pages/support/code-clinic.md @@ -6,20 +6,12 @@ slug: code-clinic type: text --- -**Code clinics will be done online using Google Hangouts for the foreseeable future due to the current Covid-19 situation**. - ### Stop wasting valuable time trying to fix issues on your own. -Code Clinics are **fortnightly support sessions** -run by the **RSE** team -and IT Services' [Research and Innovation IT](https://www.sheffield.ac.uk/it-services/research) (ITS R&I) team. -They are open to **anyone at TUOS writing code for research** to -get help with programming problems and general advice on best practice. +Code Clinics are **fortnightly support sessions** run by the [RSE team](https://rse.shef.ac.uk) (which is supported by the [Department of Computer Science](https://www.sheffield.ac.uk/dcs) and [IT Services](https://www.sheffield.ac.uk/departments/it-services)) and IT Services' [Research IT and support](https://www.sheffield.ac.uk/it-services/research) team. +They are open to **anyone at TUOS writing code for research** to get help with programming problems and general advice on best practice. -At each session, **members of the RSE and/or ITS R&I teams will be available to -review code, -advise, -troubleshoot and +At each session, **members of the RSE and/or Research IT and support teams will be available to review code, advise, troubleshoot and suggest ways to improve your computational workflows**. ### Where? @@ -47,29 +39,16 @@ Every second Wednesday (13:30 - 15:30). ### Book a slot Clinic sessions are split into 3 half-hourly slots, bookable for consultation. -To book, please **fill in this [brief form](https://goo.gl/forms/5MVy0jM6xQhWlpmn1).** -Note that **slots can only be booked 48 hours or more before the scheduled time**. + +Book a code clinic session now + +**Note that slots can only be booked 48 hours or more before the scheduled time**. ### Preparing for your session - - **Organise** and **annotate** your code with **clarifying comments**. - - Try and restrict any materials you show us to those related to the specific matter at hand. - Consider stripping your code or data down to a **small reproducible example** of your problem. - - If helping with the problem requires us to understand your data, - please include at the very least a **[README file](https://en.wikipedia.org/wiki/README)** - with descriptions of data attributes. - - Please **test your microphone** before joining the Google Meet. - - If you think it would be useful for you to **share your screen** with a helper then - please install [Chrome Remote Desktop](https://remotedesktop.google.com/) in advance - (setup instructions [here](https://support.google.com/chrome/answer/1649523?co=GENIE.Platform%3DDesktop&hl=en)). - We ask that if you do choose to share your screen with a helper that - you consider in advance whether you will be exposing confidential data/code/information - that helpers are not permitted to view. - Note that Google Remote Desktop is not covered with the University's *Google for Educators* licence - so any confidential information shared over this medium - is only covered by Google's standard privacy policy. - If you have any questions regarding the information security implications of sharing your screen - please contact the TUOS Information Security team via it-servicedesk@sheffield.ac.uk +- Please provide examples of the code you are working on, if possible. Often the best way to do this is via a “Minimal, Reproducible Example” () but sometimes this isn’t possible. It is good software engineering practice to share code using collaborative version control (e.g. GitHub) and it is good open research practice to do this publicly, although these practices are not always possible. +- Sometimes helping with the problem requires us to understand your data. Sharing data is not always possible. A readme or data dictionary is particularly useful in these situations. +- Please provide any information you can on the hardware, operating system, packages you are using. ### On the day @@ -78,17 +57,22 @@ Note that **slots can only be booked 48 hours or more before the scheduled time* We will always try and help as best as possible. The overarching aim of the sessions is to better equip you to solve your own computational problems. -This may include directing you to relevant documentation, -appropriate online forums and resources, +This may include directing you to relevant documentation, appropriate online forums and resources, relevant upcoming training sessions, etc. ### Cancelling your session -If you cannot attend the session, -please give a **No** response on the calendar invite -so we can proceed to remove your booking from the system. +If you cannot attend the session, please give a **No** response on the calendar invite and email the code clinic helpers at +[`code-clinic-helpers-group@sheffield.ac.uk`](mailto:) so we can proceed to remove your booking from the system to cancel your session +and free it up for someone else. + +### Any questions before your session? + +In the first instance please contact the helper assigned to your request (see your Google Calendar appointment event for details) +or if a helper hasn't been assigned yet please contact . + +Please do not reply directly to auto-generated emails received after booking a Code Clinic session - the associated mailbox is not monitored. ### Interested in getting involved? -If you would like to get involved as a helper, -please contact [Will Furnass or Anna Krystalli in the RSE team](/contact). +If you would like to get involved as a helper, please contact . diff --git a/pages/training/com4521/hpc-sharc.md b/pages/training/com4521/hpc-sharc.md new file mode 100644 index 00000000..1c1f1804 --- /dev/null +++ b/pages/training/com4521/hpc-sharc.md @@ -0,0 +1,297 @@ +--- +title: "COM4521/COM6521: Using ShARC (HPC)" +slug: com4521-hpc-sharc +layout: page +permalink: /training/com4521/hpc-sharc +date: 2023-03-03 17:00:00 UTC +tags: +category: +link: +description: +type: text +--- + +This page documents how the [ShARC](https://docs.hpc.shef.ac.uk/en/latest/sharc/index.html) HPC cluster can be used by COM4521/COM6521 students, this is predominantly to enable remote work on the assignment during the Easter break, however lab solutions are provided with a makefile which could be updated to work on HPC too. + +This guide applies to [ShARC](https://docs.hpc.shef.ac.uk/en/latest/sharc/index.html) which uses the SGE (Sun Grid Engine) scheduler, much of the guidance is not suitable for other university HPC systems such as [Bessemer](https://docs.hpc.shef.ac.uk/en/latest/bessemer/index.html) and Stanage as those use a difference scheduler. + +**Contents** + +* [Prerequisites](#prerequisites) +* [Logging In](#logging-in) +* [Transferring Files](#transferring-files) +* [Your Assignment](#your-assignment) + * [Compiling](#compiling) + * [Running](#running) + * [Profiling](#profiling) + * [Debugging](#debugging) + +## Prerequisites + +Connecting to HPC has four requirements: + +1. University HPC Account +2. Connected to the university VPN or on campus network +3. University MFA +4. SSH Client + +Additionally, you will likely want to use a graphical SFTP (FTP over SSH) client to transfer files between your computer and the HPC system. Alternatively, `scp` can be used directly from your terminal or `git` can be used once logged into ShARC. + +**University HPC Account** + +To use university HPC you must first complete the [HPC Driving License](https://infosecurity.shef.ac.uk/) (VPN required), online training/test. + +After completing the HPC Driving License notify me (r.chisholm(at)sheffield.ac.uk), and I can request a HPC account on your behalf. It normally takes 1-2 working days for HPC accounts to be created and granted access to DCS private hardware. + +**University VPN** + +In order to connect to the HPC cluster you will either need to be connected to the [university VPN](https://students.sheffield.ac.uk/it-services/get-connected/vpn) or on the campus network (e.g. wifi). This is the same requirement as many other digital campus-only resources. + +**University MFA** + +HPC authentication uses the [university's multifactor authentication](https://sites.google.com/sheffield.ac.uk/mfa/home). + +You will be prompted to enter a one-time code or send a push notification to your MFA device after entering your username and password. You should already have MFA setup, as it is now required for all university accounts and VPN access. + +**SSH Client** + +Typically Linux, MacOS and Windows (10+) all have `ssh` available via the command line. You may use other SSH clients if you have a preference. + +**SFTP Client** + +The below guide explains how to use [FileZilla](https://filezilla-project.org), a cross-platform graphical SFTP client. + +## Logging In + +To login enter the following command in your terminal, replacing `$USER` with your university username e.g. `acb12de`. + + +``` +ssh $USER@sharc.shef.ac.uk +``` + +You will then be prompted to enter you password + +``` +Password: +``` + +On password confirmation you will be prompted to select a MFA option. + +Either enter a passcode directly from the Duo mobile app, or enter `1` and respond to the push notification. + +``` +Duo two-factor login for $USER + +Enter a passcode or select one of the following options: + + 1. Duo Push to $PHONE_NUMBER + +Passcode or option (1-1): +``` + +If login was successful you should see a success message and login welcome. + +``` +Success. Logging you in... +***************************************************************************** +* ShARC (Sheffield Advanced Research Computer) HPC cluster * +* The University Of Sheffield * +* https://docs.hpc.shef.ac.uk * +* * +* Unauthorised use of this system is prohibited. * +***************************************************************************** + +[$USER@sharc-login2 ~]$ +``` + +*[Official HPC Connection Docs](https://docs.hpc.shef.ac.uk/en/latest/hpc/connecting.html#connecting-to-a-cluster-using-ssh)* + +## Transferring Files + +Download and install the FileZilla **client** from [https://filezilla-project.org](https://filezilla-project.org). + +When you first open FileZilla you need to create a site. + +* Select Site Manager from the menu bar: `File -> Site Manager..`. +* Click `New site`, and enter the name `ShARC`. +* Enter the following properties in the right-hand panel: + * General + * **Protocol**: SFTP - SSH File Transfer Protocol + * **Host**: `sharc.shef.ac.uk` + * **Logon Type**: Interactive + * **User**: Your username (e.g. `acb12de`) + * Transfer Settings + * **Limit number of simultaneous connections**: Should be ticked (true) +* Now you can click `Open` to connect to ShARC. + +*When opening FileZilla in future, you can either select the `ShARC` site via the site-manager drop down (arrow next to the left-most icon in the icon bar), or reopen the site manager and double click `ShARC` to connect.* + +When you connect, the interactive logon prompt will open, this works the same as logging into SSH. First you will be requested to enter your password, followed by a Duo passcode or `1` to use a push notification. + +*[Official HPC Transferring Files Docs](https://docs.hpc.shef.ac.uk/en/latest/hpc/transferring-files.html)* + +## Your Assignment + +The [assignment handout code](https://github.com/RSE-Sheffield/COMCUDA_particle_assignment/archive/master.zip) has been updated to include an updated `Makefile` and a directory `scripts/sharc` with job scripts you may want to use. + +*[Official Using GPUs on ShARC Docs](https://docs.hpc.shef.ac.uk/en/latest/sharc/GPUComputingShARC.html)* + +### Compiling + +**Interactive Session** + +To compile your code on ShARC you must connect to an interactive session, interactive sessions do not have GPUs so can only be used for compilation. + +You can request an interactive session with the `qrshx` command. + +On success you should see the prompt change from `@sharc-login` to `@sharc-node`. + +To leave the interactive session you can call `exit`. + +``` +[$USER@sharc-login2 ~]$ qrshx +[$USER@sharc-node009 ~]$ exit +exit +[$USER@sharc-login2 ~]$ +``` + +**Loading Modules** + +Lots of software is installed on the HPC system, therefore to prevent conflicts it is necessary to manually load the required software. + +``` +module load libs/CUDA/11.6.0/binary +module load dev/gcc/8.2 +``` + +If you add these 2 lines to `.bashrc` (in your home directory), they will be automatically loaded every time you login to ShARC. Otherwise you will need to call them manually after each login as required. + +**Building The Assignment** + +If you navigate to where you have uploaded your assignment code (e.g. `cd com4521_assignment`) you now be should be able to call `make` to compile your project. *(Make sure you have updated the `Makefile` in the handout code.)* + +`make` will produce a **Release build**, if you wish to produce a **Debug build** (e.g. for additional validation checks) you should instead call `make debug`. + +*The output below is normal for compilation success, it merely shows the commands passed to the two compilers.* + +``` +[$user@sharc-node009 com4521_assignment]$ make +nvcc -c -o build/release/src/main.cu.o src/main.cu -gencode arch=compute_35,code=sm_35 -gencode arch=compute_60,code=sm_60 -gencode arch=compute_60,code=compute_60 -I. -Isrc -Wno-deprecated-gpu-targets -lineinfo -O3 -DNDEBUG -Xcompiler -fopenmp -Xcompiler -I. -Xcompiler -Isrc -Xcompiler -Wall -Xcompiler -O3 -Xcompiler -DNDEBUG +gcc -c -o build/release/src/helper.c.o src/helper.c -fopenmp -I. -Isrc -Wall -O3 -DNDEBUG +gcc -c -o build/release/src/cpu.c.o src/cpu.c -fopenmp -I. -Isrc -Wall -O3 -DNDEBUG +gcc -c -o build/release/src/openmp.c.o src/openmp.c -fopenmp -I. -Isrc -Wall -O3 -DNDEBUG +nvcc -c -o build/release/src/cuda.cu.o src/cuda.cu -gencode arch=compute_35,code=sm_35 -gencode arch=compute_60,code=sm_60 -gencode arch=compute_60,code=compute_60 -I. -Isrc -Wno-deprecated-gpu-targets -lineinfo -O3 -DNDEBUG -Xcompiler -fopenmp -Xcompiler -I. -Xcompiler -Isrc -Xcompiler -Wall -Xcompiler -O3 -Xcompiler -DNDEBUG +nvcc -o bin/release/Particles build/release/src/main.cu.o build/release/src/helper.c.o build/release/src/cpu.c.o build/release/src/openmp.c.o build/release/src/cuda.cu.o -gencode arch=compute_35,code=sm_35 -gencode arch=compute_60,code=sm_60 -gencode arch=compute_60,code=compute_60 -I. -Isrc -Wno-deprecated-gpu-targets -lineinfo -O3 -DNDEBUG -Xcompiler -fopenmp -Xcompiler -I. -Xcompiler -Isrc -Xcompiler -Wall -Xcompiler -O3 -Xcompiler -DNDEBUG +[$user@sharc-node009 com4521_assignment]$ +``` + +Errors and warnings take the below form. The exact messages may differ from those you receive in Visual Studio, but the code you are working with should remain cross-platform. + +``` +src/cuda.cu(45): error: expected a ";" +``` + +### Running + +**Note:** These sample job scripts do **NOT** include commands to compile your project. You may have to wait for a batch job to run, so you don't want it to fail due to compilation (see [Compiling](#compiling)). + +Two sample job scripts `scripts/sharc/run.sh` and `scripts/sharc/run_debug.sh` have been provided for running your code. **You will need to modify copies of these scripts to specify different runtime argument for your application.** + +The header of the job script contains a large number of parameters which can be modified to change things such as the requested job time, job name and email address to send job status updates to. + + +**Note:** The scheduler used (Sun Grid Engine) is unaware of GPUs, hence the number of GPUs requested is multiplied by the number of CPU cores requested. Therefore, you will find requesting more than 7 cores (the number of GPUs available) causes a job to queue indefinitely. Likewise, requesting 1 CPU core for non-OpenMP jobs should decrease queue times. + +To submit the default job scripts call the desired command below from the root of your project: + +``` +qsub scripts/sharc/run.sh +qsub scripts/sharc/run_debug.sh +``` + +You can then use `qstat` to check the status of your job. + +Once your job has completed, two log files e.g `com4521_run.sh.o12345` `com4521_run.sh.e12345` will have been created. These contain the output and error streams from your job. You should check these to ensure that your job ran successfully and to recover any important output such as timing and validation data. + +The sample run jobs should also output the image `output_image.png` which you can download to check. + +### Profiling + +In order to profile code on HPC it is necessary to submit a job to generate timeline and analysis files which can be imported into visual profiler. + +It is necessary to install the Visual Profiler to view these outputs. It can be installed on a machine without an Nvidia GPU by using the [command line silent flag](https://docs.nvidia.com/cuda/cuda-installation-guide-microsoft-windows/#id3) (e.g. `cuda_installer.exe -s visual_profiler_12.1` if using the CUDA 12.1 installer). Visual Profiler also requires the [64-bit Java Runtime Environment](https://www.java.com/en/download/manual.jsp) to be installed, otherwise it will fail at launch. + +To submit the default profiling job script call the below command from the root of your project: + +``` +qsub scripts/sharc/profile.sh +``` + +You can then use `qstat` to check the status of your job. + +Once your job has completed, two log files e.g `com4521_profile.sh.o12345` `com4521_profile.sh.e12345` will have been created. These contain the output and error streams from your job. You should check these to ensure that your job ran successfully and to recover any important output such as timing and validation data. + + +**Note:** Profiling can be slow, therefore it's possible the default 10 minute job time will be exceeded and the job will fail. This can be checked by running `qstat -j ` and checking the output's `exit_status` to see whether it was killed. + +The profiler will have created two output files `timeline.nvprof` and `analysis.nvprof`, you can download and import them into the Visual Profiler GUI. + +* `File -> Import` +* Select Nvprof +* Select Single process +* Select `timeline.nvvp` for Timeline data file +* Add `analysis.nvprof` to Event/Metric data files +* Click Finish + + + +### CUDA Memory Checker + +Compute sanitizer is available on HPC similar to the managed desktops, it can be executed with the sample job script to memory check Debug builds of your code. As before, **you will need to modify a copy of this script to specify different runtime argument to your application**. + +``` +qsub scripts/sharc/cudamemchk.sh +``` + +On completion, Compute sanitizer's output will be found in the two output files e.g `com4521_cudamemchk.sh.o12345` `com4521_cudamemchk.sh.e12345`. + +### Debugging + +In order to interactively debug your code on HPC it is necessary to get an interactive GPU session. This will only be possible when there are free GPU nodes. + +**Note:** `gdb` and `cuda-gdb` are complex and powerful applications, you may wish to attempt debugging with `printf()` first. + +An interactive GPU session, can be requested with the below command: + +``` +qrshx -l gpu=1 -P rse -q rse-interactive.q +``` + +If this succeeds, and you have loaded the same two modules required for compilation, you should then be able to use `cuda-gdb` to interactively debug your application. + +``` +cuda-gdb --args "bin/debug/Particles" CUDA 100 512x512 output_image.png +``` + +Refer to the [`gdb`](https://sourceware.org/gdb/current/onlinedocs/gdb.html/) and [`cuda-gdb`](https://docs.nvidia.com/cuda/cuda-gdb/index.html) documentation respectively (`cuda-gdb` is an extension of `gdb` so `gdb` information is transferable if you do not require the CUDA debugging features). diff --git a/pages/training/com4521/index.md b/pages/training/com4521/index.md new file mode 100644 index 00000000..4740e516 --- /dev/null +++ b/pages/training/com4521/index.md @@ -0,0 +1,462 @@ +--- +title: "COM4521/COM6521: Parallel Computing with Graphical Processing Units (GPUs)" +slug: com4521 +layout: page +permalink: /training/com4521/ +date: 2023-02-01 17:00:00 UTC +tags: +category: +link: +description: +type: text +--- + + +## Course Information + +Welcome to the 2022/2023 module page for COM4521/COM6521 Parallel Computing with GPUs. + +Accelerator architectures are discrete processing units which supplement a base processor with the objective of providing advanced performance at lower energy cost. Performance is gained by a design which favours a high number of parallel compute cores at the expense of imposing significant software challenges. This module looks at accelerated computing from multi-core CPUs to GPU accelerators with many TFlops of theoretical performance. The module will give insight into how to write high performance code with specific emphasis on GPU programming with NVIDIA CUDA GPUs. A key aspect of the module will be understanding what the implications of program code are on the underlying hardware so that it can be optimised. + +The modules aims, objectives and assessment details are available on the [module's public teaching page](http://www.dcs.shef.ac.uk/intranet/teaching/public/modules/level4/com4521.html). + +The module was first developed by [Professor Paul Richmond](https://www.sheffield.ac.uk/dcs/people/academic/paul-richmond). His previous webpage for the module can be found [here](https://paulrichmond.shef.ac.uk/teaching/COM4521/). + +## Software for the Module + +The module's programming exercises are designed to be completed on PCs in the Diamond compute labs. All Diamond compute lab machines have Visual Studio 2022 and CUDA 11.7.1 If you intend to use your own machine for programming exercises (on the CUDA part of the module) then you **must** install the latest Community version of Visual Studio 2022 **before** you install the CUDA toolkit. Lab and assignment code should work with other recent versions of CUDA, however may require changing the targeted version of CUDA when opening the Visual Studio project. + +If you want to complete the exercises in Linux then example Makefiles will be provided with the lab (and assignment) starting code and solutions. It is not possible to build Linux CUDA programs on PCs in the Diamond compute labs. + + +## Computers & Labs Available + +As the module requires access to a machine with a GPU the following have been made available to you. + +* All diamond Compute Labs (other than High spec lab) - All diamond 'all in one' machines have an NVIDIA GTX1050 (Pascal generation) GPUs. Dedicated lab classes are available most weeks, reserving these machines. You can find machine availability outside of lab times by using [Find a PC](https://www.sheffield.ac.uk/findapc) +* Diamond High Spec Lab - These are higher spec machines with NVIDIA Quadro 5200 (Pascal generation) GPUs. +* Other University Machines - As of 2021 the following buildings have computer labs containing machines with GPUs: Heartspace, IC, Hicks, Firth Court, Elmfield. It may be necessary to install Visual Studio and the CUDA toolkit on these machines on first use. +* Your own Windows/Linux machine - Follow the instructions under "software for this module". +* University HPC - For more information refer to [dedicated guide](./hpc-sharc). + +## Course Attendance Monitoring + +A register may be taken during some lab classes for [attendance monitoring](https://www.sheffield.ac.uk/new-students/attendance-monitoring), additionally a register will be collected (based on UCards) at each Blackboard quiz. + +Important Note: **It is not possible to properly understand the course material without completing the labs and reviewing the solutions.** If you do not complete the labs then you will find the assignment difficult. The first lecture will provide some insight into how course engagement affects assessment performance. + +## Lectures + +It is recommended that all students attend the first lecture in person. Subsequent lectures will be delivered in-person, and made available using the flip classroom approach. Attending the lectures has the benefit that there will often be time for questions to be answered. The flip classroom lecture content has been pre-recorded into bite sized chunks of ~10-15m each by the previous lecturer (Prof. Paul Richmond). If you choose not to attend the in-person lectures, you are expected to listen to each week's flip classroom lectures **in advance** of the corresponding lab. + +## In Person Lab Classes + +The lab sessions occur weekly in the Diamond's Computer Room 1 from 09:00-11:00 on Tuesdays. +These lab sessions are attended by myself and a number of graduate teaching assistants (GTA) able to answer questions and provide support in understanding the module's content. + +The lab classes have been designed to re-enforce the material which you will observe in the lectures by applying the techniques and approaches to specific problems. You should aim to attempt the lab classes exercises **prior** to attending the lab class (i.e. the week before) and use the labs to obtain help in understanding and applying the taught content. The lab class solutions are commented to provide insight. The solutions are available in advance of the lab so if you are stuck on a particular exercise then review these to move on and seek help in understanding the problem and solution in the lab class. Within the labs, pair programming or work within small groups is encouraged but left to personal preference. Discussion is encouraged. + +During the lab class there will be an opportunity to discuss and review lecture content, lecture examples and lab solutions. Guided walkthroughs of certain parts of the lab solutions may be provided. + +Although the labs are structured around the lecture material each week you can (and should) ask for help regarding any of the labs during the scheduled lab time. The labs are also used for assignment help. You should start this early. + +## Course Assessment + +In response to student feedback the number of assignments has been reduced to a single assignment which reflects the reduced number of learning objectives for the module. The assignment will be released Monday the 27th February (week 4) and is due 17:00 on Friday 19th May (week 12). The assignment forms 80% of your mark. You are expected to ask for feedback on your assignment work during the scheduled lab classes. + +The remaining 20% of the module mark is from two Blackboard quizzes which must be completed under exam conditions. e.g. Within the specified locations with the lockdown browser under invigilation from demonstrators. + +These Blackboard quizzes replace the lab classes of weeks 5 and 10. + +* Week 5 - 09:00 on the 7th March in Diamond Computer Room 1 + * Quiz content covers lectures from weeks 1-3 (inclusive). +* Week 10 - 09:00 on the 2nd May in Diamond Computer Room 1 + * Quiz content covers lectures from weeks 4-9 (inclusive). + +Quizzes will take 45m (must be completed within the hour) and consist of 25 multiple choice questions. + + +## DDP students & Staff Candidates + +PhD students and staff are able to take the module subject to capacity limitations (taught students have priority). + +PhD students and research/academic staff are not required to undertake assessment but DDP students are expected to attend labs as evidence of participation in the module. You should ensure that you enroll for the course via DDP to ensure that you have access to the Blackboard. + +If you are a member of staff wishing to attend the module, please contact the Computer Science teaching admins (com-teaching(at)sheffield.ac.uk) so that they can process your request. + +## Discussion, Announcements and Requests for Help + +A [Google group](https://groups.google.com/a/sheffield.ac.uk/d/forum/com4521-group) has been created for announcements, help and discussion. Any important announcements relating to the module will be made via this group. All students enrolled on the module on the 2nd February 2023 have been added to this group already. Likewise staff and PhD students who expressed an interest in the course via the Google form have been added. If you have transferred via Add/Drop then you will need to manually join the group yourself. The group is monitored by staff (including lab assistants) who can provide help. The purpose of the mailing list is to ask for general support and guidance with the course material (e.g. with concepts and ideas) rather than posting your own code. **You should not post your assignment code on this forum**. If you require personal assistance with your assignment code then you should request this during the lab hours. Any lab class can be used for assignment help in addition to the lab exercises which are set each week. + +[https://groups.google.com/a/sheffield.ac.uk/d/forum/com4521-group](https://groups.google.com/a/sheffield.ac.uk/d/forum/com4521-group) + + +# Course Material + +In-person lectures will be delivered from 10:00-12:00 on Mondays in [Broad Lane](https://ssid.sheffield.ac.uk/campus-map/?location=broad-lane-block) Lecture Theatre 2 (accessed via either [Mappin](https://ssid.sheffield.ac.uk/campus-map/?location=sir-frederick-mappin-building) or [Pam Liversidge](https://ssid.sheffield.ac.uk/campus-map/?location=pam-liversidge)). +Due to the national bank holidays, normal lectures in weeks 10 and 11 are not possible. Therefore, an additional lecture has been added at 09:00-11:00 on Friday of week 10 in [Pam Liversidge's](https://ssid.sheffield.ac.uk/campus-map/?location=pam-liversidge) Lecture Theatre 1. + +Additionally, the week 12 lecture has been replaced with an additional assignment help lab class in Diamond Computer Room 2. + +Pre-recorded lectures from the previous lecturer are available on the [COM4521 Parallel Computing with Graphical Processing Unit's Kaltura Channel](https://digitalmedia.sheffield.ac.uk/channel/COM4521+Parallel+Computing+with+Graphical+Processing+Units/201133333) or as downloadable pdfs on [Google Drive](https://drive.google.com/drive/folders/1XxXJdrzSP6XFwrzzEnNv1BLptfsgZOXu?usp=sharing). These cover the same content as the in-person lectures, required for the Blackboard quizzes and assignment. + +Each week's practical activities (the labs) follow the ideas presented in the lectures so it is important that you follow the lecture and lab timetable below. + +## Week 1 + +### Lecture 1 + +*Monday 10:00 Broad Lane LT2* + +* Course Introduction & Overview ([pdf](https://drive.google.com/file/d/1wb3OYH7b1Y7ptAbo4UVo88dqX0ILct77/view?usp=share_link), [pdf with notes](https://drive.google.com/file/d/1wksBhlYw8VUU-zdJBW0LRtPqL7zqV1YL/view?usp=share_link)) +* Introduction to C ([pdf](https://drive.google.com/file/d/1347oK2tUB1nzoCcBdnkedMTIpZRhv7tE/view?usp=share_link), [pdf with notes](https://drive.google.com/file/d/19h9MNDiOJsKc-j3ThFQvkgoJHEDMSkkw/view?usp=share_link)) + +#### Flip Classroom Pre-recorded Lectures + +* ~~Module Details~~ (Not available, please attend in person or check Encore) +* Course Context ([pdf](https://drive.google.com/open?id=1E0291GtCX_s_5QVHZllq1e6FJaHPorv8), [recording](https://digitalmedia.sheffield.ac.uk/media/Lecture+01+-+Part+01+-+Course+Context/1_4ozidnx3)) +* Supercomputing and Software ([pdf](https://drive.google.com/open?id=1E87UUwB1eZAsoCvBfTN00BEcTj9Grq0E), [recording](https://digitalmedia.sheffield.ac.uk/media/Lecture+01+-+Part+02+-+Super+Computing+and+Software/1_3cae6aog)) +* Introducing C ([pdf](https://drive.google.com/file/d/1_mL4lhg2sb7Ez4-BzFEele6MXggXBiUK/view?usp=sharing), [recording](https://digitalmedia.sheffield.ac.uk/media/Lecture+02+-+Part+01+-+Introducing+C/1_eakd0424)) +* Functions and Scoping ([pdf](https://drive.google.com/file/d/1tM_1D7w0WuVcvzU8QrdaEaZIf7-cgs6R/view?usp=sharing), [recording](https://digitalmedia.sheffield.ac.uk/media/Lecture+02+-+Part+02+-+Functions+and+Scoping/1_cf4tnuln)) +* Arrays, Strings and IO ([pdf](https://drive.google.com/file/d/1KqpjzKsc5QjPq-qDKueT1EQBaP8ZCZeJ/view?usp=sharing), [recording](https://digitalmedia.sheffield.ac.uk/media/Lecture+02+-+Part+03+-+Arrays+Strings+and+IO/1_60zchnsf)) + +### Lab 1 - Introduction to Visual Studio & C Programming + +*Tuesday 9:00 Diamond CR1* + +* [Getting Started with Visual Studio 2022 Overview](https://drive.google.com/file/d/1XkZcJ5LPdq5IDI4hG7z0HNEdwyZ7yuB9/view?usp=share_link) +* [Lab Sheet](https://drive.google.com/file/d/1BC7kDWk0za9ljbEUPK-RTgSyGIWT_t5y/view?usp=share_link) +* [Starting Code](https://github.com/RSE-Sheffield/COMCUDA_labs/archive/Lab01_src.zip) +* [Solution](https://github.com/RSE-Sheffield/COMCUDA_labs/archive/Lab01_sln.zip) +* [Frequently Asked Questions](./labs/1) + +-------------------- + +## Week 2 + +### Lecture 2 + +*Monday 10:00 Broad Lane LT2* + +* Memory ([pdf](https://drive.google.com/file/d/1Q3SPHDw-yKYEpnScqV6fSMmataXOIu5w/view?usp=share_link), [pdf with notes](https://drive.google.com/file/d/1ANbbpze6znQfaIyjknz-ZS6Thki8jsW-/view?usp=share_link)) +* Optimisation ([pdf](https://drive.google.com/file/d/1hB7s7RtsGnX-LCQs9H0xvxisekWSg0cd/view?usp=share_link), [pdf with notes](https://drive.google.com/file/d/1YsfnQOHh1m_JvwDISpHfrg4c3314NcFL/view?usp=share_link)) + +#### Flip Classroom Pre-recorded Lectures + +* Pointers ([pdf](https://drive.google.com/file/d/1ek2YjPLMDwdtRJVlUrmPZ31SV6E7UWbV/view?usp=sharing), [recording](https://digitalmedia.sheffield.ac.uk/media/Lecture+03+-+Part+01+-+Pointers/1_2lxp7wyb)) +* Advanced use of Pointers ([pdf](https://drive.google.com/file/d/1TuHaiow_oGjXOWvTy05CFY3lw0bwKh2Y/view?usp=sharing), [recording](https://digitalmedia.sheffield.ac.uk/media/Lecture+03+-+Part+02+-+Advanced+Pointers/1_v4x7d5sr)) +* Dynamically Managed Memory ([pdf](https://drive.google.com/file/d/1tnGYCG48XOYMhUf78dJT-VT1kT4d6lFp/view?usp=sharing), [recording](https://digitalmedia.sheffield.ac.uk/media/Lecture+03+-+Part+03+-+Manual+Memory+Management/1_4j49qhoj)) +* Structures and Binary Files ([pdf](https://drive.google.com/file/d/1Pl_wx-H9dDXfGfKEprxs6jg3RzrTSnVq/view?usp=sharing), [recording](https://digitalmedia.sheffield.ac.uk/media/Lecture+03+-+Part+04+-+Structures+and+Binary+Files/1_38omyxrt)) +* Optimisation Overview ([pdf](https://drive.google.com/file/d/1wVdzbq9DL0S-qK0K1np084Mc8mF7CWNb/view?usp=sharing), [recording](https://digitalmedia.sheffield.ac.uk/media/Lecture+04+-+Part+01+-+Optmisation+Overview/1_z09qnv7q)) +* Compute Bound Code ([pdf](https://drive.google.com/file/d/17xQZlwihTvo2vEEWPpb5k8EWOqXezz3U/view?usp=sharing), [recording](https://digitalmedia.sheffield.ac.uk/media/Lecture+04+-+Part+02+-+Compute+Bound+Code/1_t74gjrqg)) +* Memory Bound Code ([pdf](https://drive.google.com/file/d/1pi7FnfWd_0YcMouXTnktV7Pu4BDXoEOh/view?usp=sharing), [recording](https://digitalmedia.sheffield.ac.uk/media/Lecture+04+-+Part+03+-+Memory+Bound+Code/1_eaa6z5dh)) + +### Lab 2 - Memory & Performance + +*Tuesday 9:00 Diamond CR1* + +* [Lab Sheet](https://drive.google.com/file/d/1CPVT4mY909_srrhuGMmlsSZ6BAZGLPTY/view?usp=sharing) +* [Starting Code](https://github.com/RSE-Sheffield/COMCUDA_labs/archive/Lab02_src.zip) +* [Solution](https://github.com/RSE-Sheffield/COMCUDA_labs/archive/Lab02_sln.zip) +* [Frequently Asked Questions](./labs/2) + +-------------------- + +## Week 3 + +### Lecture 3 + +*Monday 10:00 Broad Lane LT2* + +* OpenMP ([pdf](https://drive.google.com/file/d/1ytyu8o4o1MlIfZWBugMT65UiOiPN-Cuc/view?usp=share_link), [pdf with notes](https://drive.google.com/file/d/1fJJxAi9eZ0g-mOSFlPEF_q7t0pRcnYGQ/view?usp=share_link)) + +#### Flip Classroom Pre-recorded Lectures + +* OpenMP Overview ([pdf](https://drive.google.com/file/d/1Y9EUh835wkh8bwMHyNhu0fzFQGlygGl1/view?usp=sharing), [recording](https://digitalmedia.sheffield.ac.uk/media/Lecture+05+-+Part+01+-+OpenMP+Overview/1_tr35veym)) +* Loops and Critical Sections ([pdf](https://drive.google.com/file/d/1adfofgTWGOGqUwOuDgTS9OW_nVDeBS3n/view?usp=sharing), [recording](https://digitalmedia.sheffield.ac.uk/media/Lecture+05+-+Part+02+-+Loops+and+Critical+Sections/1_j4mfsl94)) +* Scoping and Tasks ([pdf](https://drive.google.com/file/d/14RxdZl6x2GYiCjbbi_1g1j5B5GhlXfzA/view?usp=sharing), [recording](https://digitalmedia.sheffield.ac.uk/media/Lecture+05+-+Part+03+-+Scoping+and+Tasks/1_tfgpqt3a)) +* Parallel Reduction ([pdf](https://drive.google.com/file/d/1DhPA-mFid4mFkUkFsRacIjzrPPvqpQs2/view?usp=sharing), [recording](https://digitalmedia.sheffield.ac.uk/media/Lecture+06+-+Part+01+-+Parallel+Reductions/1_0wfcdxdy)) +* Scheduling ([pdf](https://drive.google.com/file/d/1n86lfK9u96e6VaqxONkqFg0yTqbIqET-/view?usp=sharing), [recording](https://digitalmedia.sheffield.ac.uk/media/Lecture+06+-+Part+02+-+Scheduling/1_jbiq6pkl)) +* Nesting and Summary ([pdf](https://drive.google.com/file/d/1V-ufrzqwAZPvIs6bXl0zt9wE6uJ9KUeT/view?usp=sharing), [recording](https://digitalmedia.sheffield.ac.uk/media/Lecture+06+-+Part+03+-+Nesting+and+Summary/1_m9hddu82)) + +### Lab 3 - OpenMP + +*Tuesday 9:00 Diamond CR1* + +* [Lab Sheet](https://drive.google.com/file/d/1CQ3LXJd_P1C14C8N5edAAYKu_LxukjLw/view?usp=share_link) +* [Starting Code](https://github.com/RSE-Sheffield/COMCUDA_labs/archive/Lab03_src.zip) +* [Solution](https://github.com/RSE-Sheffield/COMCUDA_labs/archive/Lab03_sln.zip) +* [Frequently Asked Questions](./labs/3) + +-------------------- + +## Week 4 + +### Lecture 4 + +*Monday 10:00 Broad Lane LT2* + +* GPU Architecture ([pdf](https://drive.google.com/file/d/1XyDFYjiV29u6aZjo_02fYJ8i8PLhgrcM/view?usp=share_link), [pdf with notes](https://drive.google.com/file/d/1y-A2sW9hXoUcX9gMjvmFKnTw0lDiPXVO/view?usp=share_link)) +* Introduction to CUDA ([pdf](https://drive.google.com/file/d/1ArIiA6khSXZeBdSzV0u4vxrybZiDHoMR/view?usp=share_link), [pdf with notes](https://drive.google.com/file/d/1VZyKLnzLLqW5_GOCJAKfBP0rY7itu7ij/view?usp=share_link)) + +#### Flip Classroom Pre-recorded Lectures + +* Introduction to GPUs ([pdf](https://drive.google.com/file/d/1cGZgGCB27m6zBkqR7-P1Lo0Ce8z7LzYx/view?usp=sharing), [recording](https://digitalmedia.sheffield.ac.uk/media/Lecture+07+-+Part+01+-+Introduction+to+GPUs/1_p7q41uvc)) +* Programming GPUs ([pdf](https://drive.google.com/file/d/13G5k7JxXWYkmKdf_f3m34173Z4QQZNNb/view?usp=sharing), [recording](https://digitalmedia.sheffield.ac.uk/media/Lecture+07+-+Part+02+-+Programming+GPUs/1_76m5dhjm)) +* GPU Hardware ([pdf](https://drive.google.com/file/d/1Q5YBM8GZqXp4P3FR1yDSPKSN9LP3yFTk/view?usp=sharing), [recording](https://digitalmedia.sheffield.ac.uk/media/Lecture+07+-+Part+03+-+GPU+Hardware/1_t7dweiyp)) +* The CUDA Programming Model ([pdf](https://drive.google.com/file/d/1p50MnSqyC-U1lls08GhVX-mW8TEuXqLb/view?usp=sharing), [recording](https://digitalmedia.sheffield.ac.uk/media/Lecture+08+-+Part+01+-+CUDA+Programming+Model/1_kbdt8jns)) +* CUDA Device Code ([pdf](https://drive.google.com/file/d/1he_iuEuyo5nONhM9DtkMmVdQ1Zat1s86/view?usp=sharing), [recording](https://digitalmedia.sheffield.ac.uk/media/Lecture+08+-+Part+02+-+CUDA+Device+Code/1_q8zijjv4)) +* CUDA Host Code and Memory Management ([pdf](https://drive.google.com/file/d/1-PPKh4g2-Pe8jITUsLbUO0A0SxwIGXtU/view?usp=sharing), [recording](https://digitalmedia.sheffield.ac.uk/media/Lecture+08+-+Part+03+-+CUDA+Host+Code+and+Memory+Management/1_g4zl8te4)) + +### Assignment Handout + +The assignment will be handed out via Blackboard after Monday's lecture. + +### Lab 4 - Introduction to CUDA + +*Tuesday 9:00 Diamond CR1* + +* [Lab Sheet](https://drive.google.com/file/d/1CWh9jFA9psV5yhRwAYf1uMXt0x6H2Akt/view?usp=share_link) +* [Starting Code](https://github.com/RSE-Sheffield/COMCUDA_labs/archive/Lab04_src.zip) +* [Solution](https://github.com/RSE-Sheffield/COMCUDA_labs/archive/Lab04_sln.zip) +* [Using CUDA with Visual Studio 2022 Guide](https://drive.google.com/file/d/145bvUng0QPsFLmQEPjPj1AYVgZQ45xXy/view?usp=share_link) +* [Frequently Asked Questions](./labs/4) +* [cudamemchk.bat](https://drive.google.com/file/d/1D6U3vaVC41ZuI37p3EdBiHp3Ae4v3KD3/view?usp=share_link) *(You may need to update the path to Compute Sanitizer if using a different version of CUDA)* + + +-------------------- + +## Week 5 + +*No Lecture* + +### Blackboard Quiz 1 + +*Tuesday 9:00 Diamond CR1* + +This quiz held during the normal lab timeslot, covers the content from lectures 1-3 and **must** be attended in person as it will be held in exam conditions with invigilation. + +The quiz consists of 25 multiple choice questions, and must be completed within 45 minutes. + +-------------------- + +## Week 6 + +### Lecture 5 + +*Monday 10:00 Broad Lane LT2* + +* CUDA Memory ([pdf](https://drive.google.com/file/d/1rO_QesLjgZTanG7x1kvx6P62zkn-2PAV/view?usp=share_link), [pdf with notes](https://drive.google.com/file/d/1PEHKzrElKZTOlBa5WSiftzRWnT9PtAjS/view?usp=share_link)) + +#### Flip Classroom Pre-recorded Lectures + +* Memory Overview ([pdf](https://drive.google.com/file/d/1BxiovKdODm1OsRTsLzW0LyOj1CfBYVQX/view?usp=sharing), [recording](https://digitalmedia.sheffield.ac.uk/media/Lecture+09+-+Part+01+-+Memory+Overview/1_0pa748z1)) +* Global & Constant Memory ([pdf](https://drive.google.com/file/d/1ZvdLGJJ3D_-DrEFsR6Sai-sA5WN-uuWT/view?usp=sharing), [recording](https://digitalmedia.sheffield.ac.uk/media/Lecture+09+-+Part+02+-+Global+and+Constant+Memory/1_fl15aonq)) +* Read Only & Texture Memory ([pdf](https://drive.google.com/file/d/1bSk8km76Y0CXAcBhBypwknl8OGoXb0VT/view?usp=sharing), [recording](https://digitalmedia.sheffield.ac.uk/media/Lecture+09+-+Part+03+-+Read-Only+and+Texture+Memory/1_kiodtb5l)) *(Covers old texture API)* + + + +### Lab 5 - CUDA Memory + +*Tuesday 9:00 Diamond CR1* + +* [Lab Sheet](https://drive.google.com/file/d/1CaMvSfO_GT-WfbqdSnoQry2ypNcBOzQU/view?usp=share_link) +* [Starting Code](https://github.com/RSE-Sheffield/COMCUDA_labs/archive/Lab05_src.zip) +* [Solution](https://github.com/RSE-Sheffield/COMCUDA_labs/archive/Lab05_sln.zip) + +-------------------- + +## Week 7 + +### Lecture 6 + +*Monday 10:00 Broad Lane LT2* + +* CUDA Shared Memory ([pdf](https://drive.google.com/file/d/1lpZQB_3YBhfrM60oJD-p4KnNHduAeA9H/view?usp=share_link), [pdf with notes](https://drive.google.com/file/d/1ym6kfSL7vnEdkHtKFhRzg87yO3J3XJVM/view?usp=share_link), [shared mem spreadsheet](https://docs.google.com/spreadsheets/d/1xXlE1CCb6QrsU6XUyrd8rBQkn8cPlg7j/edit?usp=share_link&ouid=103785091663071688487&rtpof=true&sd=true)) +* CUDA Performance ([pdf](https://drive.google.com/file/d/1mdpdngX2rIxQANvnusiucDt3JmPusjo2/view?usp=share_link), [pdf with notes](https://drive.google.com/file/d/1Ni3N-s423d2i4huk5aGRmwoLq1oEEykx/view?usp=share_link)) + +#### Flip Classroom Pre-recorded Lectures + +* Introduction to Shared Memory ([pdf](https://drive.google.com/file/d/1EjnE7xi5wo8HEJ3hUA74N9WMUZOudcV5/view?usp=sharing), [recording](https://digitalmedia.sheffield.ac.uk/media/Lecture+10+-+Part+01+-+Introduction+to+Shared+Memory/1_rd20qeup)) +* Shared Memory Bank Conflicts ([pdf](https://drive.google.com/file/d/1-VKri93MTBbUMmlIYd-LiK6iMYphg3w9/view?usp=sharing), [recording](https://digitalmedia.sheffield.ac.uk/media/Lecture+10+-+Part+02+-+Shared+Memory+Bank+Conflicts/1_69yoldfs)) +* Boundary Conditions ([pdf](https://drive.google.com/file/d/1C4h9_Y0lh2M2k09avtqtqo_1Rw677JUV/view?usp=sharing), [recording](https://digitalmedia.sheffield.ac.uk/media/Lecture+10+-+Part+03+-+Boundary+Conditions/1_5g9cwokq)) +* Shared Memory Bank Conflict Calculator ([xlxs file](https://drive.google.com/file/d/1pHTvo-X02_xp8OHCobJ-zFaZ0Vq2mtKK/view?usp=sharing)) +* Memory Coalescing ([pdf](https://drive.google.com/file/d/1vDqsfjl_hRbyG1jBkllSIwNLlbycyjlz/view?usp=sharing), [recording](https://digitalmedia.sheffield.ac.uk/media/Lecture+11+-+Part+01+-+Memory+Coalescing/1_o0kfb3ux)) +* The L1 Cache ([pdf](https://drive.google.com/file/d/13lSuEalXcMGrX8orbW6HUbXZFj3OqbuH/view?usp=sharing), [recording](https://digitalmedia.sheffield.ac.uk/media/Lecture+11+-+Part+02+-+The+L1+Cache/1_94wtt4kb)) +* Occupancy ([pdf](https://drive.google.com/file/d/1ClFMjcO2IDjsCZ7irgSKjaUeKW4yAEev/view?usp=sharing), [recording](https://digitalmedia.sheffield.ac.uk/media/Lecture+11+-+Part+03+-+Occupancy/1_dweyffyn)) + + +### Lab 6 - Shared Memory + +*Tuesday 9:00 Diamond CR1* + +* [Lab Sheet](https://drive.google.com/file/d/1CrHWsJsCUuCt1lkyTaq635Qucp7XDNTT/view?usp=share_link) +* [Starting Code](https://github.com/RSE-Sheffield/COMCUDA_labs/archive/Lab06_src.zip) +* [Solution](https://github.com/RSE-Sheffield/COMCUDA_labs/archive/Lab06_sln.zip) +* [Solution Further Explanation](https://drive.google.com/file/d/1Covnx8QjwJ7MgI-NUfDe41IW5d83nm84/view?usp=share_link) + +-------------------- + +## Week 8 + +### Lecture 7 + +*Monday 10:00 Broad Lane LT2* + +* Warp Level CUDA & Atomics ([pdf](https://drive.google.com/file/d/1_v4KIobtPWs72ZBCCQ3jiImjpPJbRGjR/view?usp=share_link), [pdf with notes](https://drive.google.com/file/d/18-7aMNU44Z7L-x2IzvdHUBdIyVOwuh54/view?usp=share_link)) +* CUDA Parallel Patterns ([pdf](https://drive.google.com/file/d/16IXvCSsKmYifA1W90BOhW3xuIzQo_gBM/view?usp=share_link), [pdf with notes](https://drive.google.com/file/d/16nXSIhmMRJow4-JS47GOd7oW5Nxv8gqp/view?usp=share_link)) + +#### Flip Classroom Pre-recorded Lectures + +* Scheduling and Divergence ([pdf](https://drive.google.com/file/d/1QeI551TNSpKVRZN7tq6N6-VjTp4ch0Wp/view?usp=sharing), [recording](https://digitalmedia.sheffield.ac.uk/media/Lecture+12+-+Part+01+-+Scheduling+and+Divergence/1_z4pi18mz)) +* Advanced Divergence ([pdf](https://drive.google.com/file/d/1LAUmDC1WkaauNJahWbdAkVi37xo7sVzd/view?usp=sharing), [recording](https://digitalmedia.sheffield.ac.uk/media/Lecture+12+-+Part+02+-+Advanced+Divergence/1_ddlggmc7)) +* Atomic and Warp Operations ([pdf](https://drive.google.com/file/d/17goRBO5osS5mbZHRd48A6TU8BZyT-wse/view?usp=sharing), [recording](https://digitalmedia.sheffield.ac.uk/media/Lecture+12+-+Part+03+-+Atomics+and+Warp+Operations/1_ais622f9)) +* Parallel Patterns Overview ([pdf](https://drive.google.com/file/d/1gJfnZjQzlB1GzV4BgnaQNXU4aAWyfFIX/view?usp=sharing), [recording](https://digitalmedia.sheffield.ac.uk/media/Lecture+13+-+Part+01+-+Parallel+Patterns+Overview/1_a0nt7yyq)) +* Reduction ([pdf](https://drive.google.com/file/d/1mbFSXVTUKmvNZTPmBlLMRIfNjQbpuFDr/view?usp=sharing), [recording](https://digitalmedia.sheffield.ac.uk/media/Lecture+13+-+Part+02+-+Reduction/1_c12ixy0e)) +* Scan ([pdf](https://drive.google.c5-8om/file/d/1IUDNWjkWDOHtIgg5emo-UgnbyU1xboED/view?usp=sharing), [recording](https://digitalmedia.sheffield.ac.uk/media/Lecture+13+-+Part+03+-+Scan/1_pfrawiuc)) + +### Lab 7 - Atomics & Primitives + +*Tuesday 9:00 Diamond CR1* + +* [Lab Sheet](https://drive.google.com/file/d/1CrQ-Zp9N10s3L3sVN61aPBEvs9xa1sx7/view?usp=share_link) +* [Starting Code](https://github.com/RSE-Sheffield/COMCUDA_labs/archive/Lab07_src.zip) +* [Solution](https://github.com/RSE-Sheffield/COMCUDA_labs/archive/Lab07_sln.zip) + +-------------------- + +## EASTER VACATION + +-------------------- + +## Week 9 + +### Lecture 8 + +*Monday 10:00 Broad Lane LT2* + +* CUDA Performance Profiling ([pdf](https://drive.google.com/file/d/1IsE7KAKSi-jtDKULPFSlf2Gh9bRvllXV/view?usp=share_link), [pdf with notes](https://drive.google.com/file/d/1QZ1PKXaE0iyQ8LJayuHzYOC3j-sp6uWA/view?usp=share_link)) + + +#### Nsight Systems & Nsight Compute + +If you wish to profile on your personal computer (or HPC) with a GPU newer than the Pascal architecture, you will need to instead use the newer profiling tools Nsight Systems/Nsight Compute. We do not currently provide a lecture for these, as they are not supported by the teaching hardware (managed desktops), however Nvidia's documentation and a couple of talks by Nvidia staff may be of value. + +* Nsight Systems ([Documentation](https://docs.nvidia.com/nsight-systems/index.html), [Video Guide](https://vimeo.com/398838139)): Nvidia's modern timeline profiler. +* Nsight Compute ([Documentation](https://docs.nvidia.com/nsight-compute/index.html), [Video Guide](https://vimeo.com/398929189)): Nvidia's modern kernel profiler. + + +#### Flip Classroom Pre-recorded Lectures + +* Performance Profiling - Guest Lecture by Dr Robert Chisholm ([pdf](https://drive.google.com/file/d/1fwo_kuB2hVBPTcJg7FViPt67MrKHS6H0/view?usp=sharing), [recording](https://digitalmedia.sheffield.ac.uk/media/Lecture+14+%26+15+Profiling/1_dn7xvs3k)) + +### Lab 8 - CUDA Profiling + +*Tuesday 9:00 Diamond CR1* + +* [Profile Lecture Example Code](https://github.com/RSE-Sheffield/COMCUDA_labs/archive/Lab08_sln.zip) +There is no lab sheet for this lab. Examine the source code and try changing the `STEP` macro to compile different iterations of the code to run through the profiler. + +*Please Note:* Currently in order to open the Visual Profiler on managed desktops you need to run the command `nvvp -vm "C:\Program Files\Java\jdk-1.8\jre\bin\java"` in a console window. + +-------------------- + +## Week 10 + +### Blackboard Quiz 2 + +*Tuesday 9:00 Diamond CR1* + +This quiz held during the normal lab timeslot, covers the content from lectures 4-8 and **must** be attended in person as it will be held in exam conditions with invigilation. + +The quiz consists of 25 multiple choice questions, and must be completed within 45 minutes. + +### Lecture 9 (Different Time/Location) + +*Friday 9:00 Pam Liversidge LT1* + +* Sorting & Libraries ([pdf](https://drive.google.com/file/d/13PpCFOZzcML24Rbd1xsUbdQCb7zsrszt/view?usp=share_link), [pdf with notes](https://drive.google.com/file/d/1Z4ukaCJiAoWjxY-p_QJ5H9SthJe2Bx8J/view?usp=share_link)) +* CUDA Streams ([pdf](https://drive.google.com/file/d/1jfs0s3sw6YSWuP5-NWC6vLCvYDBBF13U/view?usp=share_link), [pdf with notes](https://drive.google.com/file/d/1DINSvckHn3Kvh8pxHuFAl-1asZirH1-U/view?usp=share_link)) + +#### Flip Classroom Pre-recorded Lectures + +* Sorting (Networks) ([pdf](https://drive.google.com/file/d/1P-ove2cxmDTb4J6eqCNE6T5zSKnEwpaG/view?usp=sharing), [recording](https://digitalmedia.sheffield.ac.uk/media/Lecture+16+-+Part+01+-+Sorting/1_xre37phi)) +* Libraries and Thrust ([pdf](https://drive.google.com/file/d/1HI19ikicGWw3_2zNlK-pZixWcH6qNryM/view?usp=sharing), [recording](https://digitalmedia.sheffield.ac.uk/media/Lecture+16+-+Part+02+-+Libraries/1_twyysk9a)) +* Applications of GPU Sort ([pdf](https://drive.google.com/file/d/1xkv4Zw6g86W6lzF3bs2ZEQLGci7FvLKd/view?usp=sharing), [recording](https://digitalmedia.sheffield.ac.uk/media/Lecture+16+-+Part+03+-+Applications+of+Sort/1_ur7qxhff)) +* Synchronous and Asynchronous Execution ([pdf](https://drive.google.com/file/d/1grdnZs88EvybgW1vydR7FaVgpglbZiCO/view?usp=sharing), [recording](https://digitalmedia.sheffield.ac.uk/media/Lecture+17+-+Part+01+-+Synchronous+and+Asynchronous+Execution/1_d6b13ebk)) +* CUDA Streams ([pdf](https://drive.google.com/file/d/113W7x70o-KcuRZ2gK6drp7QM2XvUWff8/view?usp=sharing), [recording](https://digitalmedia.sheffield.ac.uk/media/Lecture+17+-+Part+02+-+CUDA+Streams/1_4jsxnwiz)) +* Synchronisation ([pdf](https://drive.google.com/file/d/1Ejnt2KKrydP8AJRy36ZSwIKauruKiLkj/view?usp=sharing), [recording](https://digitalmedia.sheffield.ac.uk/media/Lecture+17+-+Part+03+-+Synchronisation/1_zftp0xht)) +* Multi GPU Programming ([pdf](https://drive.google.com/file/d/1Ejnt2KKrydP8AJRy36ZSwIKauruKiLkj/view?usp=sharing), [recording](https://digitalmedia.sheffield.ac.uk/media/Lecture+17+-+Part+04+-+Multi+GPU+Programming/1_k75fi901)) + +-------------------- + +## Week 11 + +*No Lecture (Bank Holiday)* + +### TellUS - Module Feedback + +Please complete the module feedback survey for all modules you have taken this semester. + +Your feedback is crucial to guiding the development of modules, by highlighting what you felt worked within the module and how you think that your experience and understanding could be improved. +It also enables you to highlight the achievements or failures of teaching staff. + +If you have more urgent feedback, you can get in contact with your student staff liaison committee representative, or me directly (at a lab class or via email r.chisholm(at)sheffield.ac.uk). + +Tell US can be accessed [here](https://tellus.shef.ac.uk/tellus/), or via the left-hand menu within Blackboard. + +### Lab 9 - Libraries & Streams + +*Tuesday 9:00 Diamond CR1* + +* [Lab Sheet](https://drive.google.com/file/d/1CtDI6p4P1IzGeiniVWf_B3vZYfQsAG6n/view?usp=share_link) +* [Starting Code](https://github.com/RSE-Sheffield/COMCUDA_labs/archive/Lab09_src.zip) +* [Solution](https://github.com/RSE-Sheffield/COMCUDA_labs/archive/Lab09_sln.zip) + + +### Previous On Demand Invited Lectures (Optional) + +Please Find below a list of previous invited lectures which may be of interest. + +* [Accelerating Road Network Simulations using GPUs](https://echo360.org.uk/media/de75ffe6-c839-49de-af50-ddb270dd529f/public) +* [Optimising Pedestrian Simulations](https://echo360.org.uk/media/6f8ed7dd-f3d8-4c25-acf2-03c36e40ea9e/public) + +-------------------- + +## Week 12: + +### Lab 10 - Assignment Help 1 + +*Monday 10:00 Diamond CR2* + +This additional lab is in the lecture slot for week 12, please note it is held in a different computer room within the Diamond to normal labs. + +### Lab 11 - Assignment Help 2 + +*Tuesday 9:00 Diamond CR1* + + +# Recommended Reading + +The following are useful resources but not required reading. + +* Edward Kandrot, Jason Sanders, "CUDA by Example: An Introduction to General-Purpose GPU Programming", Addison Wesley 2010. +* Brian Kernighan, Dennis Ritchie, “The C Programming Language (2nd Edition)”, Prentice Hall 1988. +* NVIDIA, [CUDA C Programming Guide](http://docs.nvidia.com/cuda/cuda-c-programming-guide/) + +## Tertiary Blogs etc. + +C is a programming language with many quirks, if you find them interesting you might enjoy these web pages. + +* [The Lost Art of Structure Packing](http://www.catb.org/esr/structure-packing/) +* [Falsehoods Programmers Believe About Undefined Behaviour](https://predr.ag/blog/falsehoods-programmers-believe-about-undefined-behavior/) +* [Reflections on Trusting Trust](https://www.cs.cmu.edu/~rdriley/487/papers/Thompson_1984_ReflectionsonTrustingTrust.pdf) +* [Godbolt Compiler Explorer](https://godbolt.org/) diff --git a/pages/training/com4521/labs/1.md b/pages/training/com4521/labs/1.md new file mode 100644 index 00000000..7a1e93d4 --- /dev/null +++ b/pages/training/com4521/labs/1.md @@ -0,0 +1,112 @@ +--- +title: "COM4521/COM6521: Lab 1 FAQ" +slug: com4521-lab1 +layout: page +permalink: /training/com4521/labs/1 +date: 2023-02-09 17:00:00 UTC +tags: +category: +link: +description: +type: text +--- + +# Lab 1 - FAQ +These are some common questions that come up during this lab. + +## The compiler cannot find random.h + +Files listed within Visual Studio's Solution Explorer do not correspond to the file structure on disk. Therefore, it is likely you have added an existing file to your project which is not located within the project's folder (this operation does not copy or move the file). + +There are 4 locations Visual Studio looks for include files: + +**System headers** + +Any include in the form `#include ` (with the chevrons `< >`) is considered a system header, so will only work for system headers. Your own files should be included as `#include "random.h"` with double quotes instead. + +**Your project's directory** + +You can locate the project's folder, by right clicking your project in the Solution Explorer and selecting "Open Folder in File Explorer". + +It's recommended that you move all your source files into this folder or a subdirectory, and specify all includes relative to this directory. + +**Relative to the source file being compiled** + +If the header you are including is in the same directory as the source file, you can include it by name, irrespective of where both are on disk. This is not recommended, and considered bad practice, as you are encouraged to specify the full path to headers relative to the root of the project's source/include directories. + +**Additional include directories** + +Within the project settings (`Project Properties > C/C++ > General > Additional Include Directories`), you can specify additional directories that the compiler will look for include files. You probably don't need to use this, it primarily exists for 3rd party dependencies that sit outside of the project's own source. + +## \#define isn't working + +The C preprocessor is a bit different to C itself, when you use `#define` you only need the symbol and the value it should be replaced by. + +```c +#define FOO 12 // Correct +#define FOO 12; // Incorrect +#define FOO=12 // Incorrect +``` + +## printf() outputs junk or memory access violation + +`printf()` expects the first argument to be a character array (technically it expects a pointer to a null-terminated e.g. `\0` character array/buffer). + +If you pass anything other than a character array, it will interpret that value as a pointer to a location in memory and start reading from there until it hits a null-terminating character. Hence, you might get random data stored in memory printed to console, or your program might crash with an access violation for reading something inaccessible. + +```c +int foo = 12; +printf("My Num: %d\n", foo); // Correct +printf("%d\n", foo); // Correct +printf("%f", (float)foo); // Correct +printf(foo); // Incorrect +printf(foo, "\n"); // Incorrect +``` + +If you're confused by format specifiers, you can find official documentation [here](https://cplusplus.com/reference/cstdio/printf/). There are hundreds of combinations but you will mostly require `%f`, `%d`, `%u`, `%lld`, `%llu`, `%s` with the occasional precision specifier e.g. `%.2f`. + +## Ex 2: The numbers printed to console are wrong + +This a common issue people have with the exercise, normally it is a result of incorrect types and the implicit casts which result from them. This can be subtle to spot, therefore I would recommend you carefully compare your solution to the [lab's solution code](https://github.com/RSE-Sheffield/COMCUDA_labs/tree/Lab01_sln/Lab01_Exercise02), and carefully check the types used. + +You also may have problems if you are using the incorrect format specifiers, a number stored in an `unsigned long long` which exceeds the max value of `int`, will print incorrectly if using the `%d` format specifier instead of the `%llu` format specifier. + +## `_CRT_SECURE_NO_WARNINGS` + +The IO functions provided by `stdio.h` are considered 'unsafe' as they take buffers without knowing the buffer's length, which may allow the function to write beyond the end of the buffer. + +Microsoft has safe version of these functions, which it enforces use of by default, however they are not cross-platform (compatible with Linux/GCC) so we don't use them. + +There are 3 ways to suppress this warning/error: + +* Add `_CRT_SECURE_NO_WARNINGS` to `Project Properties > Configuration Properties > C/C++ > Preprocessor -> Preprocessor Definitions`. +* Define the macro before including `stdio.h`. + +```c +#define _CRT_SECURE_NO_WARNINGS +#include +... +``` + +* Tell the compiler to disable the warning by using `#pragma warning` before including `stdio.h`. + +```c +#pragma warning (disable : 4996) +#include +... +``` + +## Access Denied / CrowdStrike + +As of the 2023 the managed desktops have a new AntiVirus "CrowdStrike Falcon Sensor", however it's rather overzealous and regularly raises false positives for even basic C/C++ code. + +It's currently a work in progress finding an appropriate solution to this, however we have a workaround: + +Three requirements must be met for your executable to not be blocked: +1. You must be using a managed desktop inside Diamond CR1, Diamond CR2 or Heartspace E001. +2. The compiled binary must be located within a subdirectory of `u:/com4521` (case-insensitive). +3. The compiled binary must be named either `particles.exe` or `Lab##_Exercise##.exe` e.g. `Lab01_Exercise01.exe` (case-insensitive). + +You can update the compiled binary's name via `Project Properties > General > Target Name` (`.exe` should not be included). + +This is a live issue and I'm hoping a smoother resolution can be found in the near future. \ No newline at end of file diff --git a/pages/training/com4521/labs/2.md b/pages/training/com4521/labs/2.md new file mode 100644 index 00000000..4a93564c --- /dev/null +++ b/pages/training/com4521/labs/2.md @@ -0,0 +1,63 @@ +--- +title: "COM4521/COM6521: Lab 2 FAQ" +slug: com4521-lab2 +layout: page +permalink: /training/com4521/labs/2 +date: 2023-02-16 17:00:00 UTC +tags: +category: +link: +description: +type: text +--- + +# Lab 2 - FAQ +These are some common questions that come up during this lab. + +## `_CRT_SECURE_NO_WARNINGS` + +The IO functions provided by `stdio.h` are considered 'unsafe' as they take buffers without knowing the buffer's length, which may allow the function to write beyond the end of the buffer. + +Microsoft has safe version of these functions, which it enforces use of by default, however they are not cross-platform (compatible with Linux/GCC) so we don't use them. + +There are 3 ways to suppress this warning/error: + +* Add `_CRT_SECURE_NO_WARNINGS` to `Project Properties > Configuration Properties > C/C++ > Preprocessor -> Preprocessor Definitions`. +* Define the macro before including `stdio.h`. + +```c +#define _CRT_SECURE_NO_WARNINGS +#include +... +``` + +* Tell the compiler to disable the warning by using `#pragma warning` before including `stdio.h`. + +```c +#pragma warning (disable : 4996) +#include +... +``` + +## students.bin was not found + +Files listed within Visual Studio's Solution Explorer do not correspond to the file structure on disk. If you are specifying a file location with a relative path e.g. `"students.bin"`, at runtime your code will only look in the working directory. + +By default visual studio uses your project's directory as the working directory. You can locate the project's folder, by right clicking your project in the Solution Explorer and selecting "Open Folder in File Explorer". + +It's also recommended that you move all your source files into this folder or a subdirectory, and specify all includes relative to this directory. + + +## Ex 2: The values are loaded incorrectly + +As the binary file is structured: + +1. Forename Length (`unsigned int`) +2. Forename (`char` array of variable length) +3. Surname Length (`unsigned int`) +4. Surname (`char` array of variable length) +5. Module mark (`float`) +6. *Repeated per student* + +It's important to read all 5 components, per student, in order. If you only read the forename and surname, then the file reading will be out of sync, meaning that all data read after the first surname will be misaligned. This could lead to the data read into the `char` arrays not containing a null terminating character, which may cause any access violation when attempting to print it. + diff --git a/pages/training/com4521/labs/3.md b/pages/training/com4521/labs/3.md new file mode 100644 index 00000000..cb960c0a --- /dev/null +++ b/pages/training/com4521/labs/3.md @@ -0,0 +1,23 @@ +--- +title: "COM4521/COM6521: Lab 3 FAQ" +slug: com4521-lab3 +layout: page +permalink: /training/com4521/labs/3 +date: 2023-02-23 17:00:00 UTC +tags: +category: +link: +description: +type: text +--- + +# Lab 3 - FAQ +These are some common questions that come up during this lab. + +## C/C++ is not in the project properties + +Visual studio will only show the C/C++ compiler settings if the project contains a C/C++ file. + +## Exercise 1A - Access Violation/Crash + +If you only parallelise the outer loop with `#pragma omp parallel for`, the variables `j` and `k` are shared by every thread. This can lead to them exceeding `N`, and hence accessing the array out of bounds. \ No newline at end of file diff --git a/pages/training/com4521/labs/4.md b/pages/training/com4521/labs/4.md new file mode 100644 index 00000000..4003f699 --- /dev/null +++ b/pages/training/com4521/labs/4.md @@ -0,0 +1,140 @@ +--- +title: "COM4521/COM6521: Lab 4 FAQ" +slug: com4521-lab4 +layout: page +permalink: /training/com4521/labs/4 +date: 2023-02-30 17:00:00 UTC +tags: +category: +link: +description: +type: text +--- + +# Lab 4 - FAQ +These are some common questions that come up during this lab. + +# Unsupported PTX Toolchain + +For an unknown reason, the default CUDA project (within Visual Studio) is not currently compatible with the managed desktops. + +This can be resolved by targeting CUDA compilation to the architecture of the managed desktops' GPU. + +Open: `Project Properties -> CUDA C/C++ -> Device` + +Update `Code Generation` to `compute_61,sm_61` + +If you are affected on your personal machine you may need to change this to a different value based on your GPU, refer to [this week's lecture notes](https://drive.google.com/file/d/1ArIiA6khSXZeBdSzV0u4vxrybZiDHoMR/view?usp=share_link) (slide 44). + +#Intellisense Errors (Red Lines Under Code) +Visual Studio's Intellisense (static analysis tool), which suggests when your code is incorrect prior to compilation, does not understand CUDA. Hence, it regularly complains about components of CUDA (for example the `<<<` notation that is used to launch kernels). + +You should ignore Intellisense errors related to CUDA syntax, and only pay attention to compilation errors and warnings. + +The "Error List" panel within Visual Studio has a drop down set to `Build + Intellisense`, this can be changed to `Build` to prevent Intellisense errors from being listed alongside compilation warnings and errors. It's not possible to disable the red lines. + +# Exercise 2.3: Enable CUDA Memory Checker + +*The lab sheet was out of date, and has now been updated.* + +NSight debugger no longer has a built in memory checker, instead the standalone command line tool Compute Sanitizer (which installs alongside CUDA) must be used. + +The assignment handout code comes with a `.bat`, that can be downloaded [here](https://drive.google.com/file/d/1D6U3vaVC41ZuI37p3EdBiHp3Ae4v3KD3/view?usp=share_link), which helps with using Compute Sanitizer. + +Call the below command, in a command window (outside of visual studio), specifying the path to your application and any required arguments. + +```sh +cudamemchk.bat "" +``` + +For example: + +```sh +cudamemchk.bat "x64\Debug\Lab04_Exercise01.exe" +``` + +*If you are working on a personal machine with a different version of CUDA you may need to update the path to Compute Sanitizer within `cudamemchk.bat`.* + +This should produce a log similar to that below, explaining the first memory error detected. + +``` +========= COMPUTE-SANITIZER +========= Invalid __global__ write of size 4 bytes +========= at 0x3c8 in U:/com4521/Lab04_Exercise01/exercise01_sln.cu:42:affine_decrypt_multiblock(int*,int*) +========= by thread (0,0,0) in block (0,0,0) +========= Address 0x4 is out of bounds +========= Saved host backtrace up to driver entry point at kernel launch time +========= Host Frame:GlobalInitializer [0x7ff8b9c080d4] +========= in C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.1\compute-sanitizer\sanitizer-collection.dll +========= Host Frame:GlobalInitializer [0x7ff8b9bc3fc7] +========= in C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.1\compute-sanitizer\sanitizer-collection.dll +========= Host Frame: [0x7ff8b9bac9b5] +========= in C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.1\compute-sanitizer\sanitizer-collection.dll +========= Host Frame: [0x7ff8b9bb39c8] +========= in C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.1\compute-sanitizer\sanitizer-collection.dll +========= Host Frame: [0x7ff8d6af79e0] +========= in C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.1\compute-sanitizer\sanitizer-public.dll +========= Host Frame:sanitizerUnsubscribe [0x7ff8d6afe1f1] +========= in C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.1\compute-sanitizer\sanitizer-public.dll +========= Host Frame: [0x7ff8b6fccde5] +========= in C:\Windows\system32\DriverStore\FileRepository\nv_dispui.inf_amd64_bf0f2e72ecc4a6c6\nvcuda64.dll +========= Host Frame:cuProfilerStop [0x7ff8b7162342] +========= in C:\Windows\system32\DriverStore\FileRepository\nv_dispui.inf_amd64_bf0f2e72ecc4a6c6\nvcuda64.dll +========= Host Frame: [0x7ff8b6e982fd] +========= in C:\Windows\system32\DriverStore\FileRepository\nv_dispui.inf_amd64_bf0f2e72ecc4a6c6\nvcuda64.dll +========= Host Frame: [0x7ff8b6e987ec] +========= in C:\Windows\system32\DriverStore\FileRepository\nv_dispui.inf_amd64_bf0f2e72ecc4a6c6\nvcuda64.dll +========= Host Frame: [0x7ff8b6e98ac4] +========= in C:\Windows\system32\DriverStore\FileRepository\nv_dispui.inf_amd64_bf0f2e72ecc4a6c6\nvcuda64.dll +========= Host Frame:cuLaunchKernel [0x7ff8b7060e14] +========= in C:\Windows\system32\DriverStore\FileRepository\nv_dispui.inf_amd64_bf0f2e72ecc4a6c6\nvcuda64.dll +========= Host Frame: [0x7ff8d6b8a5fa] +========= in U:\com4521\x64\Debug\cudart64_110.dll +========= Host Frame: [0x7ff8d6b8a4a6] +========= in U:\com4521\x64\Debug\cudart64_110.dll +========= Host Frame:cudaLaunchKernel [0x7ff8d6bad1c4] +========= in U:\com4521\x64\Debug\cudart64_110.dll +========= Host Frame:C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.1\include\cuda_runtime.h:211:cudaLaunchKernel [0x7ff769fe221f] +========= in U:\com4521\x64\Debug\Lab04_Exercise01.exe +========= Host Frame:C:\Users\ac1rch\AppData\Local\Temp\tmpxft_000040a0_00000000-7_exercise01_sln.cudafe1.stub.c:9:__device_stub__Z25affine_decrypt_multiblockPiS_ [0x7ff769fe200d] +========= in U:\com4521\x64\Debug\Lab04_Exercise01.exe +========= Host Frame:C:\Users\ac1rch\AppData\Local\Temp\tmpxft_000040a0_00000000-7_exercise01_sln.cudafe1.stub.c:12:affine_decrypt_multiblock [0x7ff769fe1992] +========= in U:\com4521\x64\Debug\Lab04_Exercise01.exe +========= Host Frame:U:\com4521\Lab04_Exercise01\exercise01_sln.cu:78:main [0x7ff769fe1af0] +========= in U:\com4521\x64\Debug\Lab04_Exercise01.exe +========= Host Frame:D:\agent\_work\9\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:79:invoke_main [0x7ff769fe4879] +========= in U:\com4521\x64\Debug\Lab04_Exercise01.exe +========= Host Frame:D:\agent\_work\9\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288:__scrt_common_main_seh [0x7ff769fe475e] +========= in U:\com4521\x64\Debug\Lab04_Exercise01.exe +========= Host Frame:D:\agent\_work\9\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:331:__scrt_common_main [0x7ff769fe461e] +========= in U:\com4521\x64\Debug\Lab04_Exercise01.exe +========= Host Frame:D:\agent\_work\9\s\src\vctools\crt\vcstartup\src\startup\exe_main.cpp:17:mainCRTStartup [0x7ff769fe4909] +========= in U:\com4521\x64\Debug\Lab04_Exercise01.exe +========= Host Frame:BaseThreadInitThunk [0x7ff901ec7c24] +========= in C:\Windows\System32\KERNEL32.DLL +========= Host Frame:RtlUserThreadStart [0x7ff902eed721] +========= in C:\Windows\SYSTEM32\ntdll.dll +========= +========= Target application returned an error +========= ERROR SUMMARY: 1026 errors +``` + +Only the first few lines are really important + +``` +========= Invalid __global__ write of size 4 bytes +``` + +There was an invalid read from global device memory (something allocated with `cudaMalloc()` or at compile time using `__device__`). +``` +========= at 0x3c8 in U:/com4521/Lab04_Exercise01/exercise01_sln.cu:42:affine_decrypt_multiblock(int*,int*) +``` +It occurred at line 42 of `exercise01_sln.cu` in the kernel/function with prototype `affine_decrypt_multiblock(int*,int*)` +``` +========= by thread (0,0,0) in block (0,0,0) +``` +It first occurred in thread 0 of block 0. (Without requesting 1 error, this whole error stack would be repeated for every thread with an error, possibly thousands of times). +``` +========= Address 0x4 is out of bounds +``` +The bad address in this case was `0x4` (e.g. I forced an error by writing `int *test=0;` `test[1]=12;`). diff --git a/pages/training/courses/ACCE.md b/pages/training/courses/ACCE.md new file mode 100644 index 00000000..fd4a4ad0 --- /dev/null +++ b/pages/training/courses/ACCE.md @@ -0,0 +1,20 @@ +--- +title: Reproducible Research Data and Project Management in R +layout: page +type: text +--- + +**Prerequisite skills:** Degree in a quantitative discipline, or equivalent. + +**Learning Objectives** + +- Understand the basics of good research data management and be able to produce clean datasets with appropriate metadata. +- Manage computational projects for reproducibility, reuse and collaboration. +- Use version control to track the evolution of research projects. +- Use R tools and conventions to document code and analyses and produce reproducible reports. +- Be able to publish, share materials and collaborate through the web. +- Understand why this all matters! + +**Duration:** 4 days (including introduction to R) + +**Course material:** \ No newline at end of file diff --git a/pages/training/courses/Intro_DL.md b/pages/training/courses/Intro_DL.md new file mode 100644 index 00000000..925fd8e1 --- /dev/null +++ b/pages/training/courses/Intro_DL.md @@ -0,0 +1,23 @@ +--- +title: Introduction to Deep Learning +layout: page +type: text +--- + +Can be delivered for **Python** or **R**. + +**Prerequisite skills:** Basic **Python** or **R**. + +**Learning Objectives** + +- Implement common deep learning workflows using Tensorflow Keras framework. +- Experiment with data, training parameters, network structure, and other strategies to increase performance and capability. +- Deploy your neural networks to start solving real-world problems. + +**Duration:** One day + +**Course material:** + +## Courses + +{% include events_list_upcoming.html category="dltraining" %} diff --git a/pages/training/courses/Open_Source.md b/pages/training/courses/Open_Source.md new file mode 100644 index 00000000..6b505003 --- /dev/null +++ b/pages/training/courses/Open_Source.md @@ -0,0 +1,17 @@ +--- +title: Contributing to Open Source Software +layout: page +type: text +--- + +**Prerequisite skills:** Basic **git** / **GitHub** use via **RStudio**, **GitKraken** or **command line**. + +**Learning Objectives** + +- Understand the meaning and importance of open source software. +- Be aware of how people and processes interact to produce open source software. +- Use git and GitHub functionality to practice contributing to an open source project: forking, cloning, and pull requests, merging, sync upstream. + +**Duration:** One hour + +**Course material:** \ No newline at end of file diff --git a/pages/training/courses/git_Hero.md b/pages/training/courses/git_Hero.md new file mode 100644 index 00000000..e9f04863 --- /dev/null +++ b/pages/training/courses/git_Hero.md @@ -0,0 +1,22 @@ +--- +title: git & GitHub through GitKraken - from Zero to Hero! +layout: page +type: text +--- + +**Prerequisite skills:** Some programming experience. + +**Learning Objectives** + +- Version controlling your own project through Git & GitHub. +- Basic collaboration through forks on GitHub. +- Advanced team collaboration through branches on GitHub. +- Using the GitKraken GUI for a smooth version control experience. + +**Duration:** One day + +**Course material:** + +## Courses + +{% include events_list_upcoming.html category="gitzerohero" %} diff --git a/pages/training/courses/good_soft.md b/pages/training/courses/good_soft.md new file mode 100644 index 00000000..40d8ea86 --- /dev/null +++ b/pages/training/courses/good_soft.md @@ -0,0 +1,17 @@ +--- +title: Write better research software (in Python) +layout: page +type: text +--- + +**Prerequisite skills:** Some python programming experience. + +**Learning Objectives** + +* Add documentation directly into python code using “docstrings” +* How and when to make your code open source +* Write tests (using pytest) so you can update your code with confidence + +**Duration:** Half a day + +**Course material:** \ No newline at end of file diff --git a/pages/training/deeplearning/index.md b/pages/training/deeplearning/index.md index 69f19dc4..aa5e6542 100644 --- a/pages/training/deeplearning/index.md +++ b/pages/training/deeplearning/index.md @@ -5,13 +5,15 @@ slug: index type: text --- -In conjunction with [Nvidia Deep Learning Institue (DLI)](https://www.nvidia.com/dli), RSES offers various practical workshops on how to apply deep learning to your research. Details for these events will be posted on this page and shared via the [RSE announcement mailing list](/community/). +*This is intended to be a living document and will be added to and corrected over time.* -## Current DLI Certified Instructors +## Sheffield Data Science and AI Community -* [Twin Karmakharm](/contact/twin-karmakharm) (RSE Sheffield) +The [Sheffield Data Science and AI Community](https://sheffieldai.github.io/) connects researchers with an interest inData Science and Artificial Intelligence across the University of Sheffield. -{% include events_list.html category="dltraining" %} +## Artificial Intelligence and Machine Learning Training + +In addition to training run by the RSE Team on [Deep Learning](../courses/Intro_DL.md), our colleagues in [IT Services][its] offer a range of [free training courses][its-courses] which include topics on Machine Learning. ## Online Deep Learning Resource @@ -72,3 +74,8 @@ If you would like to contribute to the list, please get in touch with Twin at [t * [deeplearning.net](http://deeplearning.net/) * Deep Learning on UoS's ShARC cluster * [Neural network online resources blog post by Desmond Ryan](https://sites.google.com/a/sheffield.ac.uk/rcg/notes/neuralnetworks-onlineresource) + + + +[its-courses]: https://www.sheffield.ac.uk/it-services/research/one-day-sessions +[its]: https://www.sheffield.ac.uk/it-services/research diff --git a/pages/training/index.md b/pages/training/index.md index f91e5bf3..14d63985 100644 --- a/pages/training/index.md +++ b/pages/training/index.md @@ -1,45 +1,49 @@ --- -title: Support & Training +title: Training layout: page slug: index type: text permalink: /training/ --- -We offer a "free at the point of use" support service: -[code clinics](../support/code-clinic.md) which allow researchers to spend time with RSEs working on problems. -More general software support within the University of Sheffield is provided by [IT Services][its], -who also offer a range of [free training courses][its-courses]. - -The RSE team can deliver of a range of training courses. -Several members of the team are certified ["Carpentry"][carpentries] instructors -and we can tailor and deliver these courses. -[Software Carpentry][soft-carp] and [Data Carpentry][data-carp] are -training programmes designed to equip researchers -with the computing skills they need to get more done in less time and with less pain. -A Carpentry workshop is a hands-on, (typically) two-day event that covers -the core computing skills needed to be productive in a small research team. -Short tutorials alternate with practical exercises, and -all instruction is done via live coding. - -We have recently delivered training commissioned by Doctoral Training Centres on ["Reproducible Research Data & Project Management in R"][repro-res-r] and -on [use of the Linux shell for accessing HPC systems][hpc-carp-shell]. - -Some example topics in which we have expertise include: - -- Python -- R -- MATLAB -- Reproducible research -- C and C++ -- git and GitHub -- Linux shell -- High Performance Computing -- GPU Computing -- Systems administration inc. Docker and Ansible - -Our team has a very broad range of skills and we are passionate about passing them on. We can develop bespoke training courses to suit your department, research group or team. If you are interested in training, please [contact us](../contact/index.md). +People working with code for research, whether they are writing their first script to managing a complex software project need skills that academic training might not provide. The RSE Team's aspiration is that all researchers who need these skills should be given the opportunity to learn them, either from the RSE Team, our University of Sheffield colleagues or other sources. +### Regular RSE Team Training + +The RSE Team focusses on training in version control as this is a key skill for reproducible research and collaborative software development. We also offer training in Deep Learning to improve and facilitate update of AI. These courses are run on a regular basis. If there are not courses currently advertised, check back soon, or [join our mailing](https://groups.google.com/a/sheffield.ac.uk/g/rse-group) list to find out when new courses are advertised. + +- [git & GitHub through GitKraken - from Zero to Hero!](courses/git_Hero.md) +- [Introduction to Deep Learning](courses/Intro_DL.md) + +### IT Services Training + +Our colleagues in [IT Services][its] offer a range of [free training courses][its-courses]. This is a good place to look if you want to learn how to code, but there are a wide range of other courses there as well. + +### Responsive RSE Team Training + +The RSE Team run training in response to the needs of groups of researchers. However, we usually need to seek funding from an organisation, department, research group, institute or doctoral training centre. The costs of running a course are our [staff time][service] plus venue and infrastructure costs. This allows us to customise or develop new training for specific audiences. + +We have recently run these courses: + +- [Reproducible Research Data and Project Management in R](courses/ACCE.md) +- [Contributing to Open Source Software](courses/Open_Source.md) +- [Write better research software (in Python)](courses/good_soft.md) + +Our expertise for bespoke training development includes Python, R, MATLAB, Reproducible research, C and C++, git and GitHub, Linux shell, High Performance Computing, GPU Computing, Systems administration inc. Docker and Ansible. + +We can run courses where material is made openly available by others (e.g. [The Carpentries](https://carpentries.org)). + +If you're interested in us running similar courses for your learners, please contact . + +### Statement on free at point of use training + +We are delighted to be able to make free at point of use training available to the research community, to enable better software and more open, reproducible research. However, **free at point of use training is not free**. The cost of a course can easily run to thousands of pounds, if preparation costs are taken into account. + +**If you sign up for a course, please make sure you either attend or cancel your booking.** Bookings can usually be cancelled using [eventbrite.com](https://www.eventbrite.com) or, failing that, by emailing [rse@sheffield.ac.uk](mailto:rse@sheffield.ac.uk). + +Running courses that are not fully attended wastes our funding (which is provided by taxpayers, charities and students, amongst others) and reduces our collective capacity to improve research outputs and researcher experiences. + +Persistent failure to attend booked courses might result in you being excluded from future training opportunities. [carpentries]: https://carpentries.org/ [data-carp]: https://datacarpentry.org/ @@ -48,3 +52,5 @@ Our team has a very broad range of skills and we are passionate about passing th [its]: https://www.sheffield.ac.uk/it-services/research [repro-res-r]: https://annakrystalli.me/rrresearchACCE20/ [soft-carp]: https://software-carpentry.org/ +[events]: ../events.md +[service]: ../service/index.md \ No newline at end of file diff --git a/pages/training/programming/index.md b/pages/training/programming/index.md index 6b64c363..61a2d3d0 100644 --- a/pages/training/programming/index.md +++ b/pages/training/programming/index.md @@ -6,9 +6,13 @@ type: text permalink: /training/programming --- +*This is intended to be a living document and will be added to and corrected over time.* + A certain amount of technical ability is required as a modern researcher. From running simulations, running large calculations, applying data transformation and analysis or even automating mundane tasks such as renaming and moving data files, learning to program can really help improve your workflow and productivity. -This page is a compilation of resources and learning materials that starts with learning to program from scratch to using the University’s High Performance Computing (HPC) clusters. +This page is a compilation of resources and learning materials that can help with learning the skills researchers need. + +Like anything technical, programming is full of terminology and jargon which can make it hard to get started. Sarah from the [Lyndhurst STEM club](https://lyndhurststem.org/) found [this great article](https://www.qualtrics.com/blog/glossary-of-coding-and-programming-terms/) which explains a lot of terminology to help you get started. * Do not remove this line (it will not be displayed) {:toc} @@ -67,16 +71,16 @@ There are Python IDEs with data science focus such as [Rodeo](https://rodeo.yhat Here’s a demonstration of a notebook which is used to illustrate working through a machine learning exercise: [https://nbviewer.jupyter.org/github/jdwittenauer/ipython-notebooks/blob/master/notebooks/ml/ML-Exercise1.ipynb](https://nbviewer.jupyter.org/github/jdwittenauer/ipython-notebooks/blob/master/notebooks/ml/ML-Exercise1.ipynb) -### IT Services Training Courses -IT Services run a number of [half-day training sessions][1] in topics such as: - * Introduction to Linux - * Linux Shell Scripting Tutorial - * Introduction to Running Software on the HPC - * Introduction to Matlab - * Introduction/Intermediate/Advanced Python Programming - * Python for Data Science - * Introduction to Machine Learning with Python +### MATLAB + +#### Reproducibility +On the RSE Sheffield blog: [A concise guide to reproducible MATLAB projects](/blog/2022-05-05-concise-guide-to-reproducible-matlab/) + +#### MATLAB Academy +Online, self-paced MATLAB training is available to all at TUoS via the [MATLAB Academy](https://matlabacademy.mathworks.com/). There are courses on more specific topics such as image processing and deep learning in addition to the fundamentals of MATLAB. +#### Best Practices in Toolbox Development +Comprehensive guidance on developing your own toolbox and the best way to do it: ### LinkedIn Learning Courses @@ -95,11 +99,6 @@ However, there are great courses on almost any topic in research computing. Why **Note**: You'll need to be on the [university VPN](https://www.sheffield.ac.uk/it-services/vpn) to get access. - -### MATLAB Academy -Online, self-paced MATLAB training is available to all at TUoS via the [MATLAB Academy](https://matlabacademy.mathworks.com/). There are courses on more specific topics such as image processing and deep learning in addition to the fundamentals of MATLAB. - - --- # Best Practice in Writing Research Code @@ -131,6 +130,10 @@ Familiarity with the command-line interface is required as git is a command-line * [Git - the simple guide](https://rogerdudler.github.io/git-guide/), more of a reference than a full tutorial. It quickly goes through the commands used in basic git operations. * [Git tutorial by Atlassian](https://www.atlassian.com/git/tutorials/tutorials/what-is-version-control), a more in-depth guide to git. * [Git immersion](https://gitimmersion.com/index.html), demonstrates the use of git through code along examples and exercises. +* [Visualizing Git Concepts](https://onlywei.github.io/explain-git-with-d3/) - online simulator to help visualize how git works. +* [Introducing Version Control with Git](https://chryswoods.com/introducing_git/) - Chrys Woods (RSE @ Bristol Uni) walks through how to use git at the command line, including walkthrough videos and written instructions +* [Git for Collaboration](https://chryswoods.com/git_collaboration/) - Following on from his intro course above, Chrys takes you through using GitHub for collaborative research software development. + ### On-line Git repository hosting @@ -197,12 +200,10 @@ HPC clusters use a job scheduler to make sure everyone has a chance to run their * HPC Carpentry series [https://hpc-carpentry.github.io/](https://hpc-carpentry.github.io/) * Linux and the command line * Ubuntu’s terminal tutorial [https://ubuntu.com/tutorials/command-line-for-beginners#1-overview](https://ubuntu.com/tutorials/command-line-for-beginners#1-overview) -* [IT Services Training Courses][1] - * Introduction to Linux - * Linux Shell Scripting Tutorial - * Introduction to Running Software on the HPC +## Coding for Virtual Reality +* [The Technology Behind Virtual Reality - Coding and Design](https://vr.space/news/education/vr-coding-design/) [1]: https://www.sheffield.ac.uk/it-services/research/one-day-sessions